Browse code

RTMP packets with one-byte header use previous packet timestamp difference, so track timestamp difference as well. Patch by Sergiy (mail.composeAddress("piratfm","gmail.com"))

Originally committed as revision 20714 to svn://svn.ffmpeg.org/ffmpeg/trunk

Sergiy authored on 2009/12/03 15:40:37
Showing 2 changed files
... ...
@@ -93,7 +93,7 @@ int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
93 93
 
94 94
     hdr >>= 6;
95 95
     if (hdr == RTMP_PS_ONEBYTE) {
96
-        timestamp = prev_pkt[channel_id].timestamp;
96
+        timestamp = prev_pkt[channel_id].ts_delta;
97 97
     } else {
98 98
         if (url_read_complete(h, buf, 3) != 3)
99 99
             return AVERROR(EIO);
... ...
@@ -116,9 +116,10 @@ int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
116 116
                 return AVERROR(EIO);
117 117
             timestamp = AV_RB32(buf);
118 118
         }
119
-        if (hdr != RTMP_PS_TWELVEBYTES)
120
-            timestamp += prev_pkt[channel_id].timestamp;
121 119
     }
120
+    if (hdr != RTMP_PS_TWELVEBYTES)
121
+        timestamp += prev_pkt[channel_id].timestamp;
122
+
122 123
     if (ff_rtmp_packet_create(p, channel_id, type, timestamp, data_size))
123 124
         return -1;
124 125
     p->extra = extra;
... ...
@@ -126,6 +127,7 @@ int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
126 126
     prev_pkt[channel_id].channel_id = channel_id;
127 127
     prev_pkt[channel_id].type       = type;
128 128
     prev_pkt[channel_id].data_size  = data_size;
129
+    prev_pkt[channel_id].ts_delta   = timestamp - prev_pkt[channel_id].timestamp;
129 130
     prev_pkt[channel_id].timestamp  = timestamp;
130 131
     prev_pkt[channel_id].extra      = extra;
131 132
     while (data_size > 0) {
... ...
@@ -151,6 +153,7 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
151 151
     uint8_t pkt_hdr[16], *p = pkt_hdr;
152 152
     int mode = RTMP_PS_TWELVEBYTES;
153 153
     int off = 0;
154
+    pkt->ts_delta = pkt->timestamp - prev_pkt[pkt->channel_id].timestamp;
154 155
 
155 156
     //TODO: header compression
156 157
     if (pkt->channel_id < 64) {
... ...
@@ -165,7 +168,7 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
165 165
     if (mode != RTMP_PS_ONEBYTE) {
166 166
         uint32_t timestamp = pkt->timestamp;
167 167
         if (mode != RTMP_PS_TWELVEBYTES)
168
-            timestamp -= prev_pkt[pkt->channel_id].timestamp;
168
+            timestamp = pkt->ts_delta;
169 169
         bytestream_put_be24(&p, timestamp >= 0xFFFFFF ? 0xFFFFFF : timestamp);
170 170
         if (mode != RTMP_PS_FOURBYTES) {
171 171
             bytestream_put_be24(&p, pkt->data_size);
... ...
@@ -200,6 +203,7 @@ int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type,
200 200
     pkt->type       = type;
201 201
     pkt->timestamp  = timestamp;
202 202
     pkt->extra      = 0;
203
+    pkt->ts_delta   = 0;
203 204
 
204 205
     return 0;
205 206
 }
... ...
@@ -75,7 +75,8 @@ enum RTMPPacketSize {
75 75
 typedef struct RTMPPacket {
76 76
     uint8_t        channel_id; ///< RTMP channel ID (nothing to do with audio/video channels though)
77 77
     RTMPPacketType type;       ///< packet payload type
78
-    uint32_t       timestamp;  ///< packet full timestamp or timestamp increment to the previous one in milliseconds (latter only for media packets)
78
+    uint32_t       timestamp;  ///< packet full timestamp
79
+    uint32_t       ts_delta;   ///< timestamp increment to the previous one in milliseconds (latter only for media packets)
79 80
     uint32_t       extra;      ///< probably an additional channel ID used during streaming data
80 81
     uint8_t        *data;      ///< packet payload
81 82
     int            data_size;  ///< packet payload size