Browse Source

librtmp: Fix incorrect usage of type 3 chunks

Per [1] type 3 chunks/RTMP_PACKET_SIZE_MINIMUM always use
the previously sent (delta) timestamp as their _delta_ timestamp,
so we need to inspect whatever was previously sent, rather than just
looking at the previous packet's absolute timestamp. I.e., type 3
chunks are only permissible in this case if the previously encoded
(delta) timestamp equals the current delta timestamp.

[1] https://rtmp.veriskope.com/docs/spec/#53124-type-3
Ruwen Hahn 1 year ago
parent
commit
c419465137
2 changed files with 13 additions and 2 deletions
  1. 12 2
      plugins/obs-outputs/librtmp/rtmp.c
  2. 1 0
      plugins/obs-outputs/librtmp/rtmp.h

+ 12 - 2
plugins/obs-outputs/librtmp/rtmp.c

@@ -4123,8 +4123,17 @@ RTMP_SendPacket(RTMP *r, RTMPPacket *packet, int queue)
                 && packet->m_headerType == RTMP_PACKET_SIZE_MEDIUM)
             packet->m_headerType = RTMP_PACKET_SIZE_SMALL;
 
-        if (prevPacket->m_nTimeStamp == packet->m_nTimeStamp
-                && packet->m_headerType == RTMP_PACKET_SIZE_SMALL)
+        /* Per https://rtmp.veriskope.com/docs/spec/#53124-type-3 type 3 chunks/RTMP_PACKET_SIZE_MINIMUM
+         * always use the previously sent (delta) timestamp as their _delta_ timestamp, so we need to inspect
+         * whatever was previously sent, rather than just looking at the previous packet's absolute timestamp.
+         *
+         * The type 3 chunks/RTMP_PACKET_SIZE_MINIMUM packets produced here specify the beginning of a new
+         * message as opposed to message continuation type 3 chunks that are handled in the loop further down
+         * in this function.
+         */
+        uint32_t delta = packet->m_nTimeStamp - prevPacket->m_nTimeStamp;
+        if (delta == prevPacket->m_nLastWireTimeStamp
+            && packet->m_headerType == RTMP_PACKET_SIZE_SMALL)
             packet->m_headerType = RTMP_PACKET_SIZE_MINIMUM;
         last = prevPacket->m_nTimeStamp;
     }
@@ -4140,6 +4149,7 @@ RTMP_SendPacket(RTMP *r, RTMPPacket *packet, int queue)
     hSize = nSize;
     cSize = 0;
     t = packet->m_nTimeStamp - last;
+    packet->m_nLastWireTimeStamp = t;
 
     if (packet->m_body)
     {

+ 1 - 0
plugins/obs-outputs/librtmp/rtmp.h

@@ -256,6 +256,7 @@ extern "C"
         uint8_t m_hasAbsTimestamp;	/* timestamp absolute or relative? */
         int m_nChannel;
         uint32_t m_nTimeStamp;	/* timestamp */
+        uint32_t m_nLastWireTimeStamp; /* timestamp that was encoded when sending */
         int32_t m_nInfoField2;	/* last 4 bytes in a long header */
         uint32_t m_nBodySize;
         uint32_t m_nBytesRead;