1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

rtmppkt: Properly handle extended timestamps when writing

Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
Martin Panter 2014-03-05 16:02:18 +02:00 committed by Martin Storsjö
parent 48cfb5f411
commit 8bbb02ae4f

View File

@ -305,18 +305,30 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
int written = 0; int written = 0;
int ret; int ret;
RTMPPacket *prev_pkt; RTMPPacket *prev_pkt;
int use_delta; // flag if using timestamp delta, not RTMP_PS_TWELVEBYTES
uint32_t timestamp; // full 32-bit timestamp or delta value
if ((ret = ff_rtmp_check_alloc_array(prev_pkt_ptr, nb_prev_pkt, if ((ret = ff_rtmp_check_alloc_array(prev_pkt_ptr, nb_prev_pkt,
pkt->channel_id)) < 0) pkt->channel_id)) < 0)
return ret; return ret;
prev_pkt = *prev_pkt_ptr; prev_pkt = *prev_pkt_ptr;
pkt->ts_delta = pkt->timestamp - prev_pkt[pkt->channel_id].timestamp;
//if channel_id = 0, this is first presentation of prev_pkt, send full hdr. //if channel_id = 0, this is first presentation of prev_pkt, send full hdr.
if (prev_pkt[pkt->channel_id].channel_id && use_delta = prev_pkt[pkt->channel_id].channel_id &&
pkt->extra == prev_pkt[pkt->channel_id].extra && pkt->extra == prev_pkt[pkt->channel_id].extra &&
pkt->timestamp >= prev_pkt[pkt->channel_id].timestamp) { pkt->timestamp >= prev_pkt[pkt->channel_id].timestamp;
timestamp = pkt->timestamp;
if (use_delta) {
timestamp -= prev_pkt[pkt->channel_id].timestamp;
}
if (timestamp >= 0xFFFFFF) {
pkt->ts_delta = 0xFFFFFF;
} else {
pkt->ts_delta = timestamp;
}
if (use_delta) {
if (pkt->type == prev_pkt[pkt->channel_id].type && if (pkt->type == prev_pkt[pkt->channel_id].type &&
pkt->size == prev_pkt[pkt->channel_id].size) { pkt->size == prev_pkt[pkt->channel_id].size) {
mode = RTMP_PS_FOURBYTES; mode = RTMP_PS_FOURBYTES;
@ -337,29 +349,22 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
bytestream_put_le16(&p, pkt->channel_id - 64); bytestream_put_le16(&p, pkt->channel_id - 64);
} }
if (mode != RTMP_PS_ONEBYTE) { if (mode != RTMP_PS_ONEBYTE) {
uint32_t timestamp = pkt->timestamp; bytestream_put_be24(&p, pkt->ts_delta);
if (mode != RTMP_PS_TWELVEBYTES)
timestamp = pkt->ts_delta;
bytestream_put_be24(&p, timestamp >= 0xFFFFFF ? 0xFFFFFF : timestamp);
if (mode != RTMP_PS_FOURBYTES) { if (mode != RTMP_PS_FOURBYTES) {
bytestream_put_be24(&p, pkt->size); bytestream_put_be24(&p, pkt->size);
bytestream_put_byte(&p, pkt->type); bytestream_put_byte(&p, pkt->type);
if (mode == RTMP_PS_TWELVEBYTES) if (mode == RTMP_PS_TWELVEBYTES)
bytestream_put_le32(&p, pkt->extra); bytestream_put_le32(&p, pkt->extra);
} }
if (timestamp >= 0xFFFFFF)
bytestream_put_be32(&p, timestamp);
} }
if (pkt->ts_delta == 0xFFFFFF)
bytestream_put_be32(&p, timestamp);
// save history // save history
prev_pkt[pkt->channel_id].channel_id = pkt->channel_id; prev_pkt[pkt->channel_id].channel_id = pkt->channel_id;
prev_pkt[pkt->channel_id].type = pkt->type; prev_pkt[pkt->channel_id].type = pkt->type;
prev_pkt[pkt->channel_id].size = pkt->size; prev_pkt[pkt->channel_id].size = pkt->size;
prev_pkt[pkt->channel_id].timestamp = pkt->timestamp; prev_pkt[pkt->channel_id].timestamp = pkt->timestamp;
if (mode != RTMP_PS_TWELVEBYTES) { prev_pkt[pkt->channel_id].ts_delta = pkt->ts_delta;
prev_pkt[pkt->channel_id].ts_delta = pkt->ts_delta;
} else {
prev_pkt[pkt->channel_id].ts_delta = pkt->timestamp;
}
prev_pkt[pkt->channel_id].extra = pkt->extra; prev_pkt[pkt->channel_id].extra = pkt->extra;
if ((ret = ffurl_write(h, pkt_hdr, p - pkt_hdr)) < 0) if ((ret = ffurl_write(h, pkt_hdr, p - pkt_hdr)) < 0)