Hello Martin, I have tested these four patches on the ABC stream, and verified it fixes the issue. Also, good catch for my mistake in the write function; your version looks good to me.
On 5 March 2014 14:11, Martin Storsjö <[email protected]> wrote: > From: Martin Panter <[email protected]> I can live with you using my email address like this for these patches, though I do avoid posting it like that in general. > Related fix in "rtmpdump": > https://repo.or.cz/w/rtmpdump.git/commitdiff/79459a2 > > Adobe's RTMP specification (21 Dec 2012), section 5.3.1.3 ("Extended > Timestamp"), says "this field is present in Type 3 chunks". Type 3 chunks are > those with the one-byte header size. > > This resolves intermittent hangs and segfaults caused by the read function, > and also includes an untested fix for the write function. > > The read function was tested with ABC (Australia) News 24 streams, however > they are probably restricted to only Australian internet addresses. Some of > the packets at the start of these streams seem to contain junk timestamp > fields, often requiring the extended field. Test command: > > ffplay rtmp://cp81899.live.edgefcs.net/live/news24-med@28772 > --- > libavformat/rtmppkt.c | 20 +++++++++++--------- > libavformat/rtmppkt.h | 2 +- > 2 files changed, 12 insertions(+), 10 deletions(-) > > diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c > index 81621b1..fb3726b 100644 > --- a/libavformat/rtmppkt.c > +++ b/libavformat/rtmppkt.c > @@ -169,6 +169,7 @@ static int rtmp_packet_read_one_chunk(URLContext *h, > RTMPPacket *p, > > uint8_t buf[16]; > int channel_id, timestamp, size; > + uint32_t ts_field; // non-extended timestamp or delta field > uint32_t extra = 0; > enum RTMPPacketType type; > int written = 0; > @@ -195,12 +196,12 @@ static int rtmp_packet_read_one_chunk(URLContext *h, > RTMPPacket *p, > > hdr >>= 6; > if (hdr == RTMP_PS_ONEBYTE) { > - timestamp = prev_pkt[channel_id].ts_delta; > + ts_field = prev_pkt[channel_id].ts_delta; > } else { > if (ffurl_read_complete(h, buf, 3) != 3) > return AVERROR(EIO); > written += 3; > - timestamp = AV_RB24(buf); > + ts_field = AV_RB24(buf); > if (hdr != RTMP_PS_FOURBYTES) { > if (ffurl_read_complete(h, buf, 3) != 3) > return AVERROR(EIO); > @@ -217,11 +218,13 @@ static int rtmp_packet_read_one_chunk(URLContext *h, > RTMPPacket *p, > extra = AV_RL32(buf); > } > } > - if (timestamp == 0xFFFFFF) { > - if (ffurl_read_complete(h, buf, 4) != 4) > - return AVERROR(EIO); > - timestamp = AV_RB32(buf); > - } > + } > + if (ts_field == 0xFFFFFF) { > + if (ffurl_read_complete(h, buf, 4) != 4) > + return AVERROR(EIO); > + timestamp = AV_RB32(buf); > + } else { > + timestamp = ts_field; > } > if (hdr != RTMP_PS_TWELVEBYTES) > timestamp += prev_pkt[channel_id].timestamp; > @@ -232,8 +235,7 @@ static int rtmp_packet_read_one_chunk(URLContext *h, > RTMPPacket *p, > return ret; > p->read = written; > p->offset = 0; > - prev_pkt[channel_id].ts_delta = timestamp - > - prev_pkt[channel_id].timestamp; > + prev_pkt[channel_id].ts_delta = ts_field; > prev_pkt[channel_id].timestamp = timestamp; > } else { > // previous packet in this channel hasn't completed reading > diff --git a/libavformat/rtmppkt.h b/libavformat/rtmppkt.h > index 7121d7e..3ccc6b4 100644 > --- a/libavformat/rtmppkt.h > +++ b/libavformat/rtmppkt.h > @@ -78,7 +78,7 @@ typedef struct RTMPPacket { > int channel_id; ///< RTMP channel ID (nothing to do with > audio/video channels though) > RTMPPacketType type; ///< packet payload type > uint32_t timestamp; ///< packet full timestamp > - uint32_t ts_delta; ///< timestamp increment to the previous one > in milliseconds (latter only for media packets) > + uint32_t ts_delta; ///< 24-bit timestamp or increment to the > previous one, in milliseconds (latter only for media packets). Clipped to a > maximum of 0xFFFFFF, indicating an extended timestamp field. > uint32_t extra; ///< probably an additional channel ID used > during streaming data > uint8_t *data; ///< packet payload > int size; ///< packet payload size > -- > 1.8.3.4 (Apple Git-47) _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
