From d98f14fa041265242895324c8e5668c033c6a6cf Mon Sep 17 00:00:00 2001 From: Thulinma Date: Tue, 5 Aug 2014 02:47:43 +0200 Subject: [PATCH] Fixed RTMP packet timestamp delta handling. --- lib/rtmpchunks.cpp | 17 +++++++++++++---- lib/rtmpchunks.h | 1 + 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/rtmpchunks.cpp b/lib/rtmpchunks.cpp index 997874b5..e3627670 100644 --- a/lib/rtmpchunks.cpp +++ b/lib/rtmpchunks.cpp @@ -283,7 +283,7 @@ std::string & RTMPStream::Chunk::Pack() { if (len == prev.len) { if (msg_type_id == prev.msg_type_id) { chtype = 0x80; //do not send len and msg_type_id - if (timestamp == prev.timestamp) { + if (timestamp - prev.timestamp == prev.ts_delta) { chtype = 0xC0; //do not send timestamp } } @@ -314,6 +314,7 @@ std::string & RTMPStream::Chunk::Pack() { } else { tmpi = timestamp - prev.timestamp; } + ts_delta = tmpi; if (tmpi >= 0x00ffffff) { ntime = tmpi; tmpi = 0x00ffffff; @@ -543,6 +544,7 @@ bool RTMPStream::Chunk::Parse(std::string & indata) { timestamp = indata[i++ ] * 256 * 256; timestamp += indata[i++ ] * 256; timestamp += indata[i++ ]; + ts_delta = timestamp; len = indata[i++ ] * 256 * 256; len += indata[i++ ] * 256; len += indata[i++ ]; @@ -562,7 +564,8 @@ bool RTMPStream::Chunk::Parse(std::string & indata) { timestamp += indata[i++ ] * 256; timestamp += indata[i++ ]; if (timestamp != 0x00ffffff) { - timestamp += prev.timestamp; + ts_delta = timestamp; + timestamp = prev.timestamp + ts_delta; } len = indata[i++ ] * 256 * 256; len += indata[i++ ] * 256; @@ -580,7 +583,8 @@ bool RTMPStream::Chunk::Parse(std::string & indata) { timestamp += indata[i++ ] * 256; timestamp += indata[i++ ]; if (timestamp != 0x00ffffff) { - timestamp += prev.timestamp; + ts_delta = timestamp; + timestamp = prev.timestamp + ts_delta; } len = prev.len; len_left = prev.len_left; @@ -591,9 +595,13 @@ bool RTMPStream::Chunk::Parse(std::string & indata) { if (!allow_short) { DEBUG_MSG(DLVL_WARN, "Warning: Header type 0xC0 with no valid previous chunk!"); } - timestamp = prev.timestamp; + timestamp = prev.timestamp + prev.ts_delta; + ts_delta = prev.ts_delta; len = prev.len; len_left = prev.len_left; + if (len_left > 0){ + timestamp = prev.timestamp; + } msg_type_id = prev.msg_type_id; msg_stream_id = prev.msg_stream_id; break; @@ -616,6 +624,7 @@ bool RTMPStream::Chunk::Parse(std::string & indata) { timestamp += indata[i++ ] * 256 * 256; timestamp += indata[i++ ] * 256; timestamp += indata[i++ ]; + ts_delta = timestamp; } //read data if length > 0, and allocate it diff --git a/lib/rtmpchunks.h b/lib/rtmpchunks.h index 6d825dbb..bbf6b360 100644 --- a/lib/rtmpchunks.h +++ b/lib/rtmpchunks.h @@ -35,6 +35,7 @@ namespace RTMPStream { unsigned char headertype; ///< For input chunks, the type of header. This is calculated automatically for output chunks. unsigned int cs_id; ///< ContentStream ID unsigned int timestamp; ///< Timestamp of this chunk. + unsigned int ts_delta; ///< Last timestamp delta. unsigned int len; ///< Length of the complete chunk. unsigned int real_len; ///< Length of this particular part of it. unsigned int len_left; ///< Length not yet received, out of complete chunk.