diff --git a/lib/rtmpchunks.cpp b/lib/rtmpchunks.cpp index a06a435b..d8160fff 100644 --- a/lib/rtmpchunks.cpp +++ b/lib/rtmpchunks.cpp @@ -76,7 +76,7 @@ std::string &RTMPStream::Chunk::Pack(){ output.clear(); bool allow_short = lastsend.count(cs_id); RTMPStream::Chunk prev = lastsend[cs_id]; - unsigned int tmpi; + uint64_t tmpi; unsigned char chtype = 0x00; if (allow_short && (prev.cs_id == cs_id)){ if (msg_stream_id == prev.msg_stream_id){ @@ -106,7 +106,7 @@ std::string &RTMPStream::Chunk::Pack(){ output += (unsigned char)((cs_id - 64) / 256); } } - unsigned int ntime = 0; + uint64_t ntime = 0; if (chtype != 0xC0){ // timestamp or timestamp diff if (chtype == 0x00){ @@ -458,7 +458,7 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer &buffer){ timestamp += indata[i++] * 256; timestamp = indata[i++]; ts_delta = timestamp; - DONTEVEN_MSG("Extended timestamp: %u", timestamp); + DONTEVEN_MSG("Extended timestamp: %" PRIu64, timestamp); } // read data if length > 0, and allocate it diff --git a/lib/rtmpchunks.h b/lib/rtmpchunks.h index f307bbd9..66ddd4bb 100644 --- a/lib/rtmpchunks.h +++ b/lib/rtmpchunks.h @@ -51,9 +51,9 @@ 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 ts_header; ///< Last header timestamp without extensions or deltas. + uint64_t timestamp; ///< Timestamp of this chunk. + uint32_t ts_delta; ///< Last timestamp delta. + uint64_t ts_header; ///< Last header timestamp without extensions or deltas. 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. diff --git a/src/output/output_rtmp.cpp b/src/output/output_rtmp.cpp index a2ff32ae..d295d5a9 100644 --- a/src/output/output_rtmp.cpp +++ b/src/output/output_rtmp.cpp @@ -1427,21 +1427,16 @@ namespace Mist{ } tagTime += rtmpOffset; uint64_t <t = lastTagTime[reTrack]; - // Check for decreasing timestamps - this is a connection error. - // We allow wrapping around the 32 bits maximum value if the most significant 8 bits are set. - /// \TODO Provide time continuity for wrap-around. - if (ltt && tagTime < ltt && ltt < 0xFF000000ull){ - FAIL_MSG("Timestamps went from %" PRIu64 " to %" PRIu64 " (decreased): disconnecting!", ltt, tagTime); - onFinish(); - break; - } - // Check if we went more than 10 minutes into the future - if (ltt && tagTime > ltt + 600000){ - FAIL_MSG("Timestamps went from %" PRIu64 " to %" PRIu64 - " (> 10m in future): disconnecting!", - ltt, tagTime); - onFinish(); - break; + if (tagTime < ltt){ + WARN_MSG("Timestamps went from %" PRIu64 " to %" PRIu64 " (decreased): rewriting timestamps for continuity", ltt, tagTime); + rtmpOffset += (ltt-tagTime) + 1; + tagTime += (ltt-tagTime) + 1; + }else{ + if (tagTime > ltt + 600000){ + WARN_MSG("Timestamps went from %" PRIu64 " to %" PRIu64 " (increased): rewriting timestamps for continuity", ltt, tagTime); + rtmpOffset -= (tagTime - ltt) - 1; + tagTime -= (tagTime - ltt) - 1; + } } uint64_t idx = reTrackToID[reTrack]; if (idx != INVALID_TRACK_ID && !userSelect.count(idx)){