diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c index 81621b1a99..fb3726bdd3 100644 --- a/libavformat/rtmppkt.c +++ b/libavformat/rtmppkt.c @@ -169,6 +169,7 @@ static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p, 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; @@ -195,12 +196,12 @@ static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p, hdr >>= 6; if (hdr == RTMP_PS_ONEBYTE) { - timestamp = prev_pkt[channel_id].ts_delta; + ts_field = prev_pkt[channel_id].ts_delta; } else { if (ffurl_read_complete(h, buf, 3) != 3) return AVERROR(EIO); written += 3; - timestamp = AV_RB24(buf); + ts_field = AV_RB24(buf); if (hdr != RTMP_PS_FOURBYTES) { if (ffurl_read_complete(h, buf, 3) != 3) return AVERROR(EIO); @@ -217,11 +218,13 @@ static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p, extra = AV_RL32(buf); } } - if (timestamp == 0xFFFFFF) { - if (ffurl_read_complete(h, buf, 4) != 4) - return AVERROR(EIO); - timestamp = AV_RB32(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; @@ -232,8 +235,7 @@ static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p, return ret; p->read = written; p->offset = 0; - prev_pkt[channel_id].ts_delta = timestamp - - prev_pkt[channel_id].timestamp; + prev_pkt[channel_id].ts_delta = ts_field; prev_pkt[channel_id].timestamp = timestamp; } else { // previous packet in this channel hasn't completed reading diff --git a/libavformat/rtmppkt.h b/libavformat/rtmppkt.h index 7121d7e268..3ccc6b4110 100644 --- a/libavformat/rtmppkt.h +++ b/libavformat/rtmppkt.h @@ -78,7 +78,7 @@ typedef struct RTMPPacket { int channel_id; ///< RTMP channel ID (nothing to do with audio/video channels though) RTMPPacketType type; ///< packet payload type uint32_t timestamp; ///< packet full timestamp - uint32_t ts_delta; ///< timestamp increment to the previous one in milliseconds (latter only for media packets) + uint32_t ts_delta; ///< 24-bit timestamp or increment to the previous one, in milliseconds (latter only for media packets). Clipped to a maximum of 0xFFFFFF, indicating an extended timestamp field. uint32_t extra; ///< probably an additional channel ID used during streaming data uint8_t *data; ///< packet payload int size; ///< packet payload size