[vlc-commits] sout: sdi: add packet helper

Francois Cartegnie git at videolan.org
Mon May 6 20:31:46 CEST 2019


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon May  6 12:13:59 2019 +0200| [568440faa2e0923356dbbd3aa13be6f30a5a9c88] | committer: Francois Cartegnie

sout: sdi: add packet helper

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=568440faa2e0923356dbbd3aa13be6f30a5a9c88
---

 modules/stream_out/sdi/Ancillary.cpp | 196 +++++++++++++++--------------------
 modules/stream_out/sdi/Ancillary.hpp |  33 ++++++
 2 files changed, 117 insertions(+), 112 deletions(-)

diff --git a/modules/stream_out/sdi/Ancillary.cpp b/modules/stream_out/sdi/Ancillary.cpp
index cbb4e16b20..e260044a4d 100644
--- a/modules/stream_out/sdi/Ancillary.cpp
+++ b/modules/stream_out/sdi/Ancillary.cpp
@@ -28,6 +28,36 @@
 
 using namespace sdi;
 
+static inline uint16_t withparitybit(uint16_t v)
+{
+    return v | (vlc_parity(v) ? 0x100 : 0x200);
+}
+
+Ancillary::Data10bitPacket::Data10bitPacket(uint8_t did, uint8_t sdid,
+                                            const AbstractPacket<uint8_t> &other)
+{
+    payload.reserve(6 + 1 + other.size());
+    payload.resize(6);
+    payload[0] = 0x000;
+    payload[1] = 0x3ff;
+    payload[2] = 0x3ff;
+    payload[3] = withparitybit(did);
+    payload[4] = withparitybit(sdid);
+    payload[5] = withparitybit(other.size());
+    for(std::size_t i = 0; i<other.size(); i++)
+        payload.push_back(withparitybit(other.data()[i]));
+    uint16_t sum = 0;
+    for(std::size_t i = 3; i<payload.size(); i++)
+        sum = (sum + payload[i]) & 0x1ff;
+    payload.push_back(sum | ((~sum & 0x100) << 1));
+}
+
+void Ancillary::Data10bitPacket::pad()
+{
+    while(payload.size() % V210::ALIGNMENT_U16)
+        payload.push_back(0x40); /* padding */
+}
+
 AFD::AFD(uint8_t afdcode, uint8_t ar)
 {
     this->afdcode = afdcode;
@@ -45,60 +75,70 @@ static inline void put_le32(uint8_t **p, uint32_t d)
     (*p) += 4;
 }
 
-void AFD::FillBuffer(uint8_t *p_buf, size_t i_buf)
+AFD::AFDData::AFDData(uint8_t code, uint8_t ar)
 {
-    const size_t len = 6 /* vanc header */ + 8 /* AFD data */ + 1 /* csum */;
-    const size_t s = ((len + 5) / 6) * 6; // align for v210
-
-    if(s * 6 >= i_buf / 16)
-        return;
-
-    uint16_t afd[s];
-
-    afd[0] = 0x000;
-    afd[1] = 0x3ff;
-    afd[2] = 0x3ff;
-    afd[3] = 0x41; // DID
-    afd[4] = 0x05; // SDID
-    afd[5] = 8; // Data Count
+    payload.resize(8);
 
     int bar_data_flags = 0;
     int bar_data_val1 = 0;
     int bar_data_val2 = 0;
 
-    afd[ 6] = ((afdcode & 0x0F) << 3) | ((ar & 0x01) << 2); /* SMPTE 2016-1 */
-    afd[ 7] = 0; // reserved
-    afd[ 8] = 0; // reserved
-    afd[ 9] = bar_data_flags << 4;
-    afd[10] = bar_data_val1 << 8;
-    afd[11] = bar_data_val1 & 0xff;
-    afd[12] = bar_data_val2 << 8;
-    afd[13] = bar_data_val2 & 0xff;
-
-    /* parity bit */
-    for (size_t i = 3; i < len - 1; i++)
-        afd[i] |= vlc_parity((unsigned)afd[i]) ? 0x100 : 0x200;
-
-    /* vanc checksum */
-    uint16_t vanc_sum = 0;
-    for (size_t i = 3; i < len - 1; i++) {
-        vanc_sum += afd[i];
-        vanc_sum &= 0x1ff;
-    }
+    payload[0] = ((code & 0x0F) << 3) | ((ar & 0x01) << 2); /* SMPTE 2016-1 */
+    payload[1] = 0; // reserved
+    payload[2] = 0; // reserved
+    payload[3] = bar_data_flags << 4;
+    payload[4] = bar_data_val1 << 8;
+    payload[5] = bar_data_val1 & 0xff;
+    payload[6] = bar_data_val2 << 8;
+    payload[7] = bar_data_val2 & 0xff;
+}
 
-    afd[len - 1] = vanc_sum | ((~vanc_sum & 0x100) << 1);
+void AFD::FillBuffer(uint8_t *p_buf, size_t i_buf)
+{
+    AFDData afd(afdcode, ar);
 
-    /* pad */
-    for (size_t i = len; i < s; i++)
-        afd[i] = 0x040;
+    Data10bitPacket packet(0x41, 0x05, afd);
+    packet.pad();
+
+    if(packet.size() > i_buf)
+        return;
 
     /* convert to v210 and write into VANC */
-    V210::Convert(afd, s, p_buf);
+    V210::Convert((uint16_t *)packet.data(), packet.size() / 2, p_buf);
+}
+
+Captions::CDP::CDP(const uint8_t * buf, std::size_t bufsize,
+                   uint8_t rate, uint16_t cdp_counter)
+{
+    std::size_t cc_count = bufsize / 3;
+    payload.reserve(9 + cc_count * 3 + 3 + 1);
+    payload.resize(9);
+    payload[0] = 0x96; // header id
+    payload[1] = 0x69;
+    payload[2] = 9 + 3 + 1 + cc_count * 3; // len
+    payload[3] = ((rate << 4) | 0x0f);
+    payload[4] = 0x43; // cc_data_present | caption_service_active | reserved
+    payload[5] = cdp_counter >> 8;
+    payload[6] = cdp_counter & 0xff;
+    payload[7] = 0x72; // ccdata_id
+    payload[8] = 0xe0 | cc_count; // cc_count
+    // cc data
+    for(std::size_t i=0; i<cc_count * 3; i++)
+        payload.push_back(buf[i]);
+    // cdp footer
+    payload.push_back(0x74); // footer id
+    payload.push_back(cdp_counter >> 8);
+    payload.push_back(cdp_counter & 0xff);
+    uint16_t sum = 0;
+    for(std::size_t i=0; i<payload.size(); i++)
+        sum = (sum + payload[i]) & 0xff;
+    payload.push_back(sum ? 256 - sum : sum); /* cdpsum */
 }
 
 Captions::Captions(const uint8_t *p, size_t s,
                    unsigned num, unsigned den)
 {
+    cdp_counter = 0;
     p_data = p;
     i_data = s;
     vlc_ureduce(&num, &den, num, den, 0);
@@ -134,82 +174,14 @@ void Captions::FillBuffer(uint8_t *p_buf, size_t i_buf)
     if (cc_count == 0)
         return;
 
-    uint16_t len = 6 /* vanc header */ + 9 /* cdp header */ + 3 * cc_count +/* cc_data */
-        4 /* cdp footer */ + 1 /* vanc checksum */;
+    CDP cdp(p_data, i_data, rate, cdp_counter++);
 
-    static uint16_t hdr = 0; /* cdp counter */
-    size_t s = ((len + 5) / 6) * 6; /* align to 6 for v210 conversion */
+    Data10bitPacket packet(0x61, 0x01, cdp);
+    packet.pad();
 
-    if(i_buf < s / 6 * 16)
+    if(packet.size() > i_buf)
         return;
 
-    uint16_t *cdp = new uint16_t[s];
-
-    uint16_t cdp_header[6+9] = {
-        /* VANC header = 6 words */
-        0x000, 0x3ff, 0x3ff, /* Ancillary Data Flag */
-
-        /* following words need parity bits */
-
-        0x61, /* Data ID */
-        0x01, /* Secondary Data I D= CEA-708 */
-        (uint16_t)(len - 6 - 1), /* Data Count (not including VANC header) */
-
-        /* cdp header */
-
-        0x96, // header id
-        0x69,
-        (uint16_t)(len - 6 - 1),
-        (uint16_t)((rate << 4) | 0x0f),
-        0x43, // cc_data_present | caption_service_active | reserved
-        (uint16_t)(hdr >> 8),
-        (uint16_t)(hdr & 0xff),
-        0x72, // ccdata_id
-        (uint16_t)(0xe0 | cc_count), // cc_count
-    };
-
-    /* cdp header */
-    memcpy(cdp, cdp_header, sizeof(cdp_header));
-
-    /* cdp data */
-    for (size_t i = 0; i < cc_count; i++) { // copy cc_data
-        cdp[6+9+3*i+0] = p_data[3*i+0] /*| 0xfc*/; // marker bits + cc_valid
-        cdp[6+9+3*i+1] = p_data[3*i+1];
-        cdp[6+9+3*i+2] = p_data[3*i+2];
-    }
-
-    /* cdp footer */
-    cdp[len-5] = 0x74; // footer id
-    cdp[len-4] = hdr >> 8;
-    cdp[len-3] = hdr & 0xff;
-    hdr++;
-
-    /* cdp checksum */
-    uint8_t sum = 0;
-    for (uint16_t i = 6; i < len - 2; i++) {
-        sum += cdp[i];
-        sum &= 0xff;
-    }
-    cdp[len-2] = sum ? 256 - sum : 0;
-
-    /* parity bit */
-    for (uint16_t i = 3; i < len - 1; i++)
-        cdp[i] |= vlc_parity(cdp[i]) ? 0x100 : 0x200;
-
-    /* vanc checksum */
-    uint16_t vanc_sum = 0;
-    for (uint16_t i = 3; i < len - 1; i++) {
-        vanc_sum += cdp[i];
-        vanc_sum &= 0x1ff;
-    }
-    cdp[len - 1] = vanc_sum | ((~vanc_sum & 0x100) << 1);
-
-    /* pad */
-    for (size_t i = len; i < s; i++)
-        cdp[i] = 0x040;
-
     /* convert to v210 and write into VBI line 15 of VANC */
-    V210::Convert(cdp, s, p_buf);
-
-    delete[] cdp;
+    V210::Convert((uint16_t *)packet.data(), packet.size() / 2, p_buf);
 }
diff --git a/modules/stream_out/sdi/Ancillary.hpp b/modules/stream_out/sdi/Ancillary.hpp
index e2c18c73c2..0f23f6e197 100644
--- a/modules/stream_out/sdi/Ancillary.hpp
+++ b/modules/stream_out/sdi/Ancillary.hpp
@@ -22,6 +22,7 @@
 #define ANCILLARY_HPP
 
 #include <vlc_common.h>
+#include <vector>
 
 namespace sdi
 {
@@ -30,6 +31,27 @@ namespace sdi
     {
         public:
             virtual void FillBuffer(uint8_t *, size_t) = 0;
+
+            template <typename T>
+            class AbstractPacket
+            {
+                public:
+                    std::size_t size() const
+                        { return payload.size() * sizeof(payload[0]); }
+                    const uint8_t * data() const
+                        { return reinterpret_cast<const uint8_t *>(payload.data()); }
+
+                protected:
+                    std::vector<T> payload;
+            };
+
+            class Data10bitPacket : public AbstractPacket<uint16_t>
+            {
+                public:
+                    Data10bitPacket(uint8_t did, uint8_t sdid,
+                                    const AbstractPacket<uint8_t> &);
+                    void pad();
+            };
     };
 
     class AFD : public Ancillary
@@ -40,6 +62,11 @@ namespace sdi
             virtual void FillBuffer(uint8_t *, size_t);
 
         private:
+            class AFDData : public AbstractPacket<uint8_t>
+            {
+                public:
+                    AFDData(uint8_t afdcode, uint8_t ar);
+            };
             uint8_t afdcode;
             uint8_t ar;
     };
@@ -52,9 +79,15 @@ namespace sdi
             virtual void FillBuffer(uint8_t *, size_t);
 
         private:
+            class CDP : public AbstractPacket<uint8_t>
+            {
+                public:
+                    CDP(const uint8_t *, std::size_t, uint8_t, uint16_t);
+            };
             const uint8_t *p_data;
             size_t i_data;
             unsigned rate;
+            uint16_t cdp_counter;
     };
 }
 



More information about the vlc-commits mailing list