summaryrefslogtreecommitdiff
path: root/libavformat/rtmpproto.c
diff options
context:
space:
mode:
authorLuca Barbato <lu_zero@gentoo.org>2013-09-21 11:10:41 +0200
committerLuca Barbato <lu_zero@gentoo.org>2013-09-22 01:09:33 +0200
commit5840473890440dbe0bd2cce530ebb3d93e187ae6 (patch)
tree17c9611b20f8a13c932722a6b3447ef7464519e4 /libavformat/rtmpproto.c
parente40a0e822801d2485e4e555909d7a82713fa86a5 (diff)
rtmp: Rewrite embedded flv handling
Use update_offset() as done for rtmp audio, video and notifications and read update and write the fields instead of replacing them in the rtmp packet and then memcpying it to the output buffer.
Diffstat (limited to 'libavformat/rtmpproto.c')
-rw-r--r--libavformat/rtmpproto.c70
1 files changed, 42 insertions, 28 deletions
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index 88fa175c95..f4b0c25509 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -2181,6 +2181,47 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
return 0;
}
+static int handle_metadata(RTMPContext *rt, RTMPPacket *pkt)
+{
+ int ret, old_flv_size, type;
+ const uint8_t *next;
+ uint8_t *p;
+ uint32_t size;
+ uint32_t ts, cts, pts = 0;
+
+ old_flv_size = update_offset(rt, pkt->size);
+
+ if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0)
+ return ret;
+
+ next = pkt->data;
+ p = rt->flv_data + old_flv_size;
+
+ /* copy data while rewriting timestamps */
+ ts = pkt->timestamp;
+
+ while (next - pkt->data < pkt->size - 11) {
+ type = bytestream_get_byte(&next);
+ size = bytestream_get_be24(&next);
+ cts = bytestream_get_be24(&next);
+ cts |= bytestream_get_byte(&next) << 24;
+ if (!pts)
+ pts = cts;
+ ts += cts - pts;
+ pts = cts;
+ bytestream_put_byte(&p, type);
+ bytestream_put_be24(&p, size);
+ bytestream_put_be24(&p, ts);
+ bytestream_put_byte(&p, ts >> 24);
+ memcpy(p, next, size + 3 + 4);
+ next += size + 3 + 4;
+ p += size + 3 + 4;
+ }
+ memcpy(p, next, 11);
+
+ return 0;
+}
+
/**
* Interact with the server by receiving and sending RTMP packets until
* there is some significant data (media data or expected status notification).
@@ -2196,10 +2237,6 @@ static int get_packet(URLContext *s, int for_header)
{
RTMPContext *rt = s->priv_data;
int ret;
- uint8_t *p;
- const uint8_t *next;
- uint32_t size;
- uint32_t ts, cts, pts=0;
if (rt->state == STATE_STOPPED)
return AVERROR_EOF;
@@ -2266,30 +2303,7 @@ static int get_packet(URLContext *s, int for_header)
ff_rtmp_packet_destroy(&rpkt);
return ret;
} else if (rpkt.type == RTMP_PT_METADATA) {
- int err;
- // we got raw FLV data, make it available for FLV demuxer
- rt->flv_off = 0;
- rt->flv_size = rpkt.size;
- if ((err = av_reallocp(&rt->flv_data, rt->flv_size)) < 0)
- return err;
- /* rewrite timestamps */
- next = rpkt.data;
- ts = rpkt.timestamp;
- while (next - rpkt.data < rpkt.size - 11) {
- next++;
- size = bytestream_get_be24(&next);
- p=next;
- cts = bytestream_get_be24(&next);
- cts |= bytestream_get_byte(&next) << 24;
- if (pts==0)
- pts=cts;
- ts += cts - pts;
- pts = cts;
- bytestream_put_be24(&p, ts);
- bytestream_put_byte(&p, ts >> 24);
- next += size + 3 + 4;
- }
- memcpy(rt->flv_data, rpkt.data, rpkt.size);
+ ret = handle_metadata(rt, &rpkt);
ff_rtmp_packet_destroy(&rpkt);
return 0;
}