[vlc-commits] [Git][videolan/vlc][master] 2 commits: codec: cc: extract captions from CDP

Steve Lhomme (@robUx4) gitlab at videolan.org
Sat Nov 30 07:20:48 UTC 2024



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
63850144 by François Cartegnie at 2024-11-30T07:04:21+00:00
codec: cc: extract captions from CDP

- - - - -
678847b2 by François Cartegnie at 2024-11-30T07:04:21+00:00
demux: mp4: handle CDP in CEA708

Another Qtff violation by FinalCut
Could have been done properly with registration,
but who cares...

- - - - -


2 changed files:

- modules/codec/cc.h
- modules/demux/mp4/mp4.c


Changes:

=====================================
modules/codec/cc.h
=====================================
@@ -37,6 +37,7 @@ enum cc_payload_type_e
     CC_PAYLOAD_DVD,
     CC_PAYLOAD_REPLAYTV,
     CC_PAYLOAD_SCTE20,
+    CC_PAYLOAD_CDP,
 };
 typedef struct
 {
@@ -336,7 +337,7 @@ static inline void cc_Extract( cc_data_t *c, enum cc_payload_type_e i_payload_ty
         }
         c->b_reorder = false;
     }
-    else /* CC_PAYLOAD_SCTE20 */
+    else if( i_payload_type == CC_PAYLOAD_SCTE20 )
     {
         /* user_data(2)
          *          (u32 stripped earlier)
@@ -383,6 +384,68 @@ static inline void cc_Extract( cc_data_t *c, enum cc_payload_type_e i_payload_ty
         }
         c->b_reorder = true;
     }
+    else // CC_PAYLOAD_CDP
+    {
+#       define CDP_FLAG_TIME_CODE_PRESENT  (1<<7)
+#       define CDP_FLAG_CC_DATA_PRESENT    (1<<6)
+#       define CDP_FLAG_SVC_INFO_PRESENT   (1<<5)
+#       define CDP_FLAG_SVC_INFO_START     (1<<4)
+#       define CDP_FLAG_SVC_INFO_CHANGE    (1<<3)
+#       define CDP_FLAG_SVC_INFO_COMPLETE  (1<<2)
+#       define CDP_FLAG_CAPTION_SVC_ACTIVE (1<<1)
+
+        if(i_src < 7)
+            return;
+
+        /* ST334-2 5.2 cdp_header() */
+        uint8_t cdp_length = p_src[2];
+        if(cdp_length < 8 || cdp_length > i_src)
+            return;
+        uint8_t cdp_flags = p_src[4];
+
+        /* skip header */
+        p_src += 7; i_src -= 7;
+
+        /* 5.3 time_code_section() */
+        if( cdp_flags & CDP_FLAG_TIME_CODE_PRESENT )
+        {
+            if( i_src < 5 ) // Shall be 5 bytes
+                return;
+            p_src += 5; i_src += 5;
+        }
+        /* 5.4 ccdata_section */
+        if( cdp_flags & CDP_FLAG_CC_DATA_PRESENT )
+        {
+            /* ccdata_section()
+             *      u8 0x72
+             *      u3 marker bits(111)
+             *      u5 cc_count
+             *      for cc_count
+             *          u5 marker bits(1111 1)
+             *          u1 cc_valid
+             *          u2 cc_type
+             *          u8 cc_data_1
+             *          u8 cc_data_2
+             */
+            if( i_src < 2 || p_src[0] != 0x72 ) // marker
+                return;
+
+            const uint8_t *cc = &p_src[1];
+            const int i_count_cc = cc[0]&0x1f;
+
+            if( i_src - 2 < i_count_cc*3 )  // broken packet
+                return;
+            cc += 1;
+            for( int i = 0; i < i_count_cc; i++, cc += 3 )
+            {
+                if( c->i_data + 3 > CC_MAX_DATA_SIZE )
+                    break;
+                cc_AppendData( c, cc[0], &cc[1] );
+            }
+        }
+        /* remaining data */
+        c->b_reorder = false;
+    }
 }
 
 
@@ -429,6 +492,10 @@ static inline void cc_ProbeAndExtract( cc_data_t *c, bool b_top_field_first, con
         i_src -= 2;
         p_src += 2;
     }
+    else if (p_src[0] == 0x96 && p_src[1] == 0x69) /* CDP */
+    {
+        i_payload_type = CC_PAYLOAD_CDP;
+    }
     else
     {
 #if 0


=====================================
modules/demux/mp4/mp4.c
=====================================
@@ -721,6 +721,32 @@ static int CreateTracks( demux_t *p_demux, unsigned i_tracks )
     return VLC_SUCCESS;
 }
 
+static block_t * MP4_CDP_Convert( block_t *p_block )
+{
+    /* FinalCut ST334-2 CDP put inside CC violation */
+    if (p_block->i_buffer < 8 + 7)
+        goto out;
+
+    if(memcmp(&p_block->p_buffer[4], "ccdp", 4))
+        goto out;
+
+    uint_fast32_t ccdp_size = GetDWBE(p_block->p_buffer);
+    if (ccdp_size > p_block->i_buffer || ccdp_size < 8)
+        goto out;
+
+    p_block->p_buffer += 8;
+    p_block->i_buffer = ccdp_size - 8;
+    /* Let cc.h handle extraction */
+    cc_data_t cc;
+    cc_Init(&cc);
+    cc_Extract(&cc, CC_PAYLOAD_CDP, true, p_block->p_buffer, p_block->i_buffer);
+    memcpy(p_block->p_buffer, cc.p_data, cc.i_data);
+    p_block->i_buffer = cc.i_data;
+
+out:
+    return p_block;
+}
+
 static block_t * MP4_EIA608_Convert( block_t * p_block )
 {
     /* Rebuild codec data from encap */
@@ -731,6 +757,9 @@ static block_t * MP4_EIA608_Convert( block_t * p_block )
     if (p_block->i_buffer < 8)
         goto out;
 
+    if(!memcmp(&p_block->p_buffer[4], "ccdp", 4))
+        return MP4_CDP_Convert(p_block);
+
     uint_fast32_t cdat_size = GetDWBE(p_block->p_buffer) - 8;
     if (cdat_size > p_block->i_buffer)
         goto out;



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c36363081cba965e6ae13de14a43920e5385d344...678847b2a8572538ce6d4af7d8ff19d85515d746

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c36363081cba965e6ae13de14a43920e5385d344...678847b2a8572538ce6d4af7d8ff19d85515d746
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list