[SCM] libav/experimental: rtmppkt: Handle extended timestamp field even for one-byte header

siretart at users.alioth.debian.org siretart at users.alioth.debian.org
Sun Aug 10 16:01:50 UTC 2014


The following commit has been merged in the experimental branch:
commit 5b2ad78f97d43299adcb038c04346999fe9b196c
Author: Martin Panter <vadmium at gmail.com>
Date:   Wed Mar 5 04:04:39 2014 +0000

    rtmppkt: Handle extended timestamp field even for one-byte header
    
    Related fix in "rtmpdump":
    https://repo.or.cz/w/rtmpdump.git/commitdiff/79459a2
    
    Adobe's RTMP specification (21 Dec 2012), section 5.3.1.3 ("Extended
    Timestamp"), says "this field is present in Type 3 chunks". Type 3 chunks are
    those with the one-byte header size.
    
    This resolves intermittent hangs and segfaults caused by the read function,
    and also includes an untested fix for the write function.
    
    The read function was tested with ABC (Australia) News 24 streams, however
    they are probably restricted to only Australian internet addresses. Some of
    the packets at the start of these streams seem to contain junk timestamp
    fields, often requiring the extended field. Test command:
    
    avplay rtmp://cp81899.live.edgefcs.net/live/news24-med@28772
    
    Signed-off-by: Martin Storsjö <martin at martin.st>

diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 81621b1..fb3726b 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 7121d7e..3ccc6b4 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

-- 
Libav/FFmpeg packaging



More information about the pkg-multimedia-commits mailing list