On Tue, 17 Sep 2013, Luca Barbato wrote:

On 17/09/13 08:58, Josh Allmann wrote:
A given packet won't always come in contiguously; sometimes
they may be broken up on chunk boundaries by packets of another
channel.

This support primarily involves tracking information about the
data that's been read, so the reader can pick up where it left
off for a given channel.

As a side effect, we no longer over-report the bytes read if
(toread = MIN(size, chunk_size)) == size
---
 libavformat/rtmppkt.c   |   55 ++++++++++++++++++++++++++++++++++++-----------
 libavformat/rtmppkt.h   |   14 ++++++++++--
 libavformat/rtmpproto.c |    9 +++++---
 3 files changed, 60 insertions(+), 18 deletions(-)

diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 8f39122..7619d28 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -130,28 +130,32 @@ int ff_amf_read_null(GetByteContext *bc)
 }

 int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
-                        int chunk_size, RTMPPacket *prev_pkt)
+                        int chunk_size, RTMPPacket *prev_pkt,
+                        int *retry_header)
 {
     uint8_t hdr;

-    if (ffurl_read(h, &hdr, 1) != 1)
+    if (*retry_header >= 0) {
+        hdr = *retry_header & 0xFF;
+        *retry_header = -1;
+    } else if (ffurl_read(h, &hdr, 1) != 1)
         return AVERROR(EIO);

-    return ff_rtmp_packet_read_internal(h, p, chunk_size, prev_pkt, hdr);
+    return ff_rtmp_packet_read_internal(h, p, chunk_size, prev_pkt, hdr, 
retry_header);
 }

 int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
-                                 RTMPPacket *prev_pkt, uint8_t hdr)
+                                 RTMPPacket *prev_pkt, uint8_t hdr,
+                                 int* retry_header)
 {

     uint8_t t, buf[16];
-    int channel_id, timestamp, size, offset = 0;
+    int channel_id, timestamp, size;
     uint32_t extra = 0;
     enum RTMPPacketType type;
     int written = 0;
     int ret;

-    written++;
     channel_id = hdr & 0x3F;

     if (channel_id < 2) { //special case for channel number >= 64
@@ -198,9 +202,26 @@ int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket 
*p, int chunk_size,
     if (hdr != RTMP_PS_TWELVEBYTES)
         timestamp += prev_pkt[channel_id].timestamp;

+    if (!prev_pkt[channel_id].read) {
     if ((ret = ff_rtmp_packet_create(p, channel_id, type, timestamp,
                                      size)) < 0)
         return ret;
+        // include 1-byte header from ff_rtmp_packet_read
+        p->read = written + 1;
+        p->offset = 0;
+    } else {
+        // previous packet in this channel hasn't completed reading
+        RTMPPacket *prev = &prev_pkt[channel_id];
+        p->data          = prev->data;
+        p->size          = prev->size;
+        p->channel_id    = prev->channel_id;
+        p->type          = prev->type;
+        p->ts_delta      = prev->ts_delta;
+        p->extra         = prev->extra;
+        p->offset        = prev->offset;
+        p->read          = prev->read + written;


+        prev->data       = NULL;

Why?

Since we take ownership of that data pointer in the local variable p, just as if we had allocated it (with ff_rtmp_packet_create above).

What happens when you fail below?

Then it's freed by ff_rtmp_packet_destroy(&p) below I guess.

However if there are half-read packets when we close the context, they will be leaked - this should be fixed.

// Martin
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to