From 79459a2b43f41ac44a2ec001139bcb7b1b8f7497 Mon Sep 17 00:00:00 2001 From: Martin Panter Date: Wed, 18 Sep 2013 11:58:01 +1000 Subject: [PATCH] Extended timestamp field may be present in type 3 chunk headers MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit As described in Adobe’s RTMP specification dated 21 Dec 2012; also: * RTMPY ticket #107, “Compressed headers also can have an extended timestamp”, http://web.archive.org/web/20120624031323/http://dev.rtmpy.org/ticket/107 * https://rarut.wordpress.com/2012/03/21/announcing-nginx-rtmp-module/ This resolves intermittent hangs, segfaults and crashes I was seeing when starting ABC News 24 streams, e.g.: rtmpdump -r rtmp://cp81899.live.edgefcs.net/live/news24-med@28772 --live Some of the packets seemed to contain junk timestamp fields, which often required the extended field. --- librtmp/rtmp.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c index 2693b65..6e788bb 100644 --- a/librtmp/rtmp.c +++ b/librtmp/rtmp.c @@ -3573,6 +3573,7 @@ RTMP_ReadPacket(RTMP *r, RTMPPacket *packet) char *header = (char *)hbuf; int nSize, hSize, nToRead, nChunk; int didAlloc = FALSE; + int extendedTimestamp; RTMP_Log(RTMP_LOGDEBUG2, "%s: fd=%d", __FUNCTION__, r->m_sb.sb_socket); @@ -3675,17 +3676,19 @@ RTMP_ReadPacket(RTMP *r, RTMPPacket *packet) packet->m_nInfoField2 = DecodeInt32LE(header + 7); } } - if (packet->m_nTimeStamp == 0xffffff) + } + + extendedTimestamp = packet->m_nTimeStamp == 0xffffff; + if (extendedTimestamp) + { + if (ReadN(r, header + nSize, 4) != 4) { - if (ReadN(r, header + nSize, 4) != 4) - { - RTMP_Log(RTMP_LOGERROR, "%s, failed to read extended timestamp", - __FUNCTION__); - return FALSE; - } - packet->m_nTimeStamp = AMF_DecodeInt32(header + nSize); - hSize += 4; + RTMP_Log(RTMP_LOGERROR, "%s, failed to read extended timestamp", + __FUNCTION__); + return FALSE; } + packet->m_nTimeStamp = AMF_DecodeInt32(header + nSize); + hSize += 4; } RTMP_LogHexString(RTMP_LOGDEBUG2, (uint8_t *)hbuf, hSize); @@ -3730,6 +3733,10 @@ RTMP_ReadPacket(RTMP *r, RTMPPacket *packet) if (!r->m_vecChannelsIn[packet->m_nChannel]) r->m_vecChannelsIn[packet->m_nChannel] = malloc(sizeof(RTMPPacket)); memcpy(r->m_vecChannelsIn[packet->m_nChannel], packet, sizeof(RTMPPacket)); + if (extendedTimestamp) + { + r->m_vecChannelsIn[packet->m_nChannel]->m_nTimeStamp = 0xffffff; + } if (RTMPPacket_IsReady(packet)) { -- 2.11.4.GIT