]> git.sesse.net Git - nageru/commitdiff
Add Metacube timestamping to every keyframe, for easier detection of streams not...
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 16 Jul 2016 15:16:06 +0000 (17:16 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 19 Jul 2016 11:07:58 +0000 (13:07 +0200)
Works with the new timestamp feature of Cubemap 1.3.1. Will be
ignored (save for some logging) in older Cubemap versions.

httpd.cpp
metacube2.cpp
metacube2.h

index c6a233deae66f6dca2eecc5476ec275a5928ca98..6f94409f3a55fea4244dd441d1fd466f8250d92f 100644 (file)
--- a/httpd.cpp
+++ b/httpd.cpp
@@ -1,5 +1,6 @@
 #include <arpa/inet.h>
 #include <assert.h>
+#include <endian.h>
 #include <microhttpd.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -174,6 +175,26 @@ void HTTPD::Stream::add_data(const char *buf, size_t buf_size, HTTPD::Stream::Da
                buffered_data.emplace_back((char *)&hdr, sizeof(hdr));
        }
        buffered_data.emplace_back(buf, buf_size);
+
+       // Send a Metacube2 timestamp every keyframe.
+       if (framing == FRAMING_METACUBE && data_type == DATA_TYPE_KEYFRAME) {
+               timespec now;
+               clock_gettime(CLOCK_REALTIME, &now);
+
+               metacube2_timestamp_packet packet;
+               packet.type = htobe64(METACUBE_METADATA_TYPE_ENCODER_TIMESTAMP);
+               packet.tv_sec = htobe64(now.tv_sec);
+               packet.tv_nsec = htobe64(now.tv_nsec);
+
+               metacube2_block_header hdr;
+               memcpy(hdr.sync, METACUBE2_SYNC, sizeof(hdr.sync));
+               hdr.size = htonl(sizeof(packet));
+               hdr.flags = htons(METACUBE_FLAGS_METADATA);
+               hdr.csum = htons(metacube2_compute_crc(&hdr));
+               buffered_data.emplace_back((char *)&hdr, sizeof(hdr));
+               buffered_data.emplace_back((char *)&packet, sizeof(packet));
+       }
+
        has_buffered_data.notify_all(); 
 }
 
index 1bf9efb8a1cb7bfa941c1f386ab93be5a6b06f27..666355d16867524422b72de72853723725554e88 100644 (file)
@@ -7,6 +7,8 @@
 
 #include "metacube2.h"
 
+#include <arpa/inet.h>
+
 /*
  * https://www.ece.cmu.edu/~koopman/pubs/KoopmanCRCWebinar9May2012.pdf
  * recommends this for messages as short as ours (see table at page 34).
@@ -44,5 +46,14 @@ uint16_t metacube2_compute_crc(const struct metacube2_block_header *hdr)
                }
        }
 
+       /*
+        * Invert the checksum for metadata packets, so that clients that
+        * don't understand metadata will ignore it as broken. There will
+        * probably be logging, but apart from that, it's harmless.
+        */
+       if (ntohs(hdr->flags) & METACUBE_FLAGS_METADATA) {
+               crc ^= 0xffff;
+       }
+
        return crc;
 }
index 43de8b7480de172fe621d5865df053cb8ebf1e68..5b6077e8ae4d08d232cd8840f119c7ac5ac41f6b 100644 (file)
 #define METACUBE_FLAGS_HEADER 0x1
 #define METACUBE_FLAGS_NOT_SUITABLE_FOR_STREAM_START 0x2
 
+/*
+ * Metadata packets; should not be counted as data, but rather
+ * parsed (or ignored if you don't understand them).
+ *
+ * Metadata packets start with a uint64_t (network byte order)
+ * that describe the type; the rest is defined by the type.
+ */
+#define METACUBE_FLAGS_METADATA 0x4
+
 struct metacube2_block_header {
        char sync[8];    /* METACUBE2_SYNC */
        uint32_t size;   /* Network byte order. Does not include header. */
        uint16_t flags;  /* Network byte order. METACUBE_FLAGS_*. */
-       uint16_t csum;   /* Network byte order. CRC16 of size and flags. */
+       uint16_t csum;   /* Network byte order. CRC16 of size and flags.
+                            If METACUBE_FLAGS_METADATA is set, inverted
+                            so that older clients will ignore it as broken. */
 };
 
 uint16_t metacube2_compute_crc(const struct metacube2_block_header *hdr);
 
+/*
+ * The only currently defined metadata type. Set by the encoder,
+ * and can be measured for latency purposes (e.g., if the network
+ * can't keep up, the latency will tend to increase.
+ */
+#define METACUBE_METADATA_TYPE_ENCODER_TIMESTAMP 0x1
+
+struct metacube2_timestamp_packet {
+       uint64_t type;  /* METACUBE_METADATA_TYPE_ENCODER_TIMESTAMP, in network byte order. */
+
+       /*
+        * Time since the UTC epoch. Basically a struct timespec.
+        * Both are in network byte order.
+        */
+       uint64_t tv_sec;
+       uint64_t tv_nsec;
+};
+
 #endif  /* !defined(_METACUBE_H) */