Originally committed as revision 20714 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -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 |