func: static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p,
                                        int chunk_size, RTMPPacket **prev_pkt_ptr,
                                        int *nb_prev_pkt, uint8_t hdr)
  {
      uint8_t buf[16];
      int channel_id, timestamp, size;
      uint32_t ts_field; // non-extended timestamp or delta field
      uint32_t extra = 0;
      enum RTMPPacketType type;
      int written = 0;
      int ret, toread;
      RTMPPacket *prev_pkt;
      written++;
      channel_id = hdr & 0x3F;
      if (channel_id < 2) { //special case for channel number >= 64
          buf[1] = 0;
          if (ffurl_read_complete(h, buf, channel_id + 1) != channel_id + 1)
              return AVERROR(EIO);
          written += channel_id + 1;
          channel_id = AV_RL16(buf) + 64;
      if ((ret = ff_rtmp_check_alloc_array(prev_pkt_ptr, nb_prev_pkt,
                                           channel_id)) < 0)
          return ret;
      prev_pkt = *prev_pkt_ptr;
      size  = prev_pkt[channel_id].size;
      type  = prev_pkt[channel_id].type;
      extra = prev_pkt[channel_id].extra;
      hdr >>= 6; // header size indicator
      if (hdr == RTMP_PS_ONEBYTE) {
          ts_field = prev_pkt[channel_id].ts_field;
      } else {
          if (ffurl_read_complete(h, buf, 3) != 3)
              return AVERROR(EIO);
          written += 3;
          ts_field = AV_RB24(buf);
          if (hdr != RTMP_PS_FOURBYTES) {
              if (ffurl_read_complete(h, buf, 3) != 3)
                  return AVERROR(EIO);
              written += 3;
              size = AV_RB24(buf);
              if (ffurl_read_complete(h, buf, 1) != 1)
                  return AVERROR(EIO);
              written++;
              type = buf[0];
              if (hdr == RTMP_PS_TWELVEBYTES) {
                  if (ffurl_read_complete(h, buf, 4) != 4)
                      return AVERROR(EIO);
                  written += 4;
                  extra = AV_RL32(buf);
      if (ts_field == 0xFFFFFF) {
          if (ffurl_read_complete(h, buf, 4) != 4)
              return AVERROR(EIO);
          timestamp = AV_RB32(buf);
      } else {
          timestamp = ts_field;
      if (hdr != RTMP_PS_TWELVEBYTES)
          timestamp += prev_pkt[channel_id].timestamp;
      if (!prev_pkt[channel_id].read) {
          if ((ret = ff_rtmp_packet_create(p, channel_id, type, timestamp,
                                           size)) < 0)
              return ret;
          p->read = written;
          p->offset = 0;
          prev_pkt[channel_id].ts_field   = ts_field;
          prev_pkt[channel_id].timestamp  = timestamp;
      } else {
          // previous packet in this channel hasn't completed reading
          RTMPPacket *prev = &prev_pkt[channel_id];
          p->data          = prev->data;
          p->size          = prev->size;
          p->channel_id    = prev->channel_id;
          p->type          = prev->type;
          p->ts_field      = prev->ts_field;
          p->extra         = prev->extra;
          p->offset        = prev->offset;
          p->read          = prev->read + written;
          p->timestamp     = prev->timestamp;
          prev->data       = NULL;
      p->extra = extra;
      // save history
      prev_pkt[channel_id].channel_id = channel_id;
      prev_pkt[channel_id].type       = type;
      prev_pkt[channel_id].size       = size;
      prev_pkt[channel_id].extra      = extra;
      size = size - p->offset;
      toread = FFMIN(size, chunk_size);
      if (ffurl_read_complete(h, p->data + p->offset, toread) != toread) {
          ff_rtmp_packet_destroy(p);
          return AVERROR(EIO);
      size      -= toread;
      p->read   += toread;
      p->offset += toread;
      if (size > 0) {
         RTMPPacket *prev = &prev_pkt[channel_id];
         prev->data = p->data;
         prev->read = p->read;
         prev->offset = p->offset;
         return AVERROR(EAGAIN);
      prev_pkt[channel_id].read = 0; // read complete; reset if needed
      return p->read;