[vlc-commits] codec: cc: extract CEA708 service ids
Francois Cartegnie
git at videolan.org
Wed Feb 12 11:31:11 CET 2020
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Feb 11 14:42:55 2020 +0100| [ff7bc36dd6ce6dcbda8c3484f5e545584a317001] | committer: Francois Cartegnie
codec: cc: extract CEA708 service ids
refs #23691
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ff7bc36dd6ce6dcbda8c3484f5e545584a317001
---
modules/codec/cc.h | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 123 insertions(+), 2 deletions(-)
diff --git a/modules/codec/cc.h b/modules/codec/cc.h
index a5fc8c3c0a..3698372c1c 100644
--- a/modules/codec/cc.h
+++ b/modules/codec/cc.h
@@ -46,6 +46,19 @@ typedef struct
/* */
bool b_reorder;
+ struct
+ {
+ uint8_t pktsize;
+ uint8_t seq;
+ uint8_t sid_bs;
+ enum
+ {
+ CEA708_PKT_END,
+ CEA708_PKT_WAIT_BLOCK_HEADER,
+ CEA708_PKT_WAIT_EXT_BLOCK_HEADER,
+ CEA708_PKT_IN_BLOCK,
+ } state;
+ } cea708;
/* */
enum cc_payload_type_e i_payload_type;
@@ -66,6 +79,10 @@ static inline void cc_Init( cc_data_t *c )
c->i_708channels = 0;
c->i_data = 0;
c->b_reorder = false;
+ c->cea708.pktsize = 0;
+ c->cea708.seq = 0;
+ c->cea708.sid_bs = 0;
+ c->cea708.state = CEA708_PKT_END;
c->i_payload_type = CC_PAYLOAD_NONE;
c->i_payload_other_count = 0;
}
@@ -77,15 +94,119 @@ static inline void cc_Exit( cc_data_t *c )
static inline void cc_Flush( cc_data_t *c )
{
c->i_data = 0;
+ c->cea708.state = CEA708_PKT_END;
+}
+
+static inline void cc_ProbeCEA708OneByte( cc_data_t *c, bool b_start, const uint8_t cc )
+{
+ if( b_start )
+ {
+ const uint8_t i_pkt_sequence = cc >> 6;
+ if( i_pkt_sequence > 0 && ((c->cea708.seq + 1) % 4) != i_pkt_sequence )
+ {
+ c->cea708.pktsize = 0;
+ c->cea708.seq = i_pkt_sequence;
+ c->cea708.state = CEA708_PKT_END;
+ }
+ else
+ {
+ c->cea708.seq = i_pkt_sequence;
+ c->cea708.pktsize = cc & 63;
+ if( c->cea708.pktsize == 0 )
+ c->cea708.pktsize = 127;
+ else
+ c->cea708.pktsize = c->cea708.pktsize * 2 - 1;
+ c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
+ printf("NEW PKT SIZE %d\n", c->cea708.pktsize);
+ }
+ }
+ else if( c->cea708.pktsize == 0 ) /* empty pkt reading service blocks */
+ {
+ c->cea708.state = CEA708_PKT_END;
+ }
+ else if( c->cea708.state != CEA708_PKT_END )
+ {
+ switch( c->cea708.state )
+ {
+ case CEA708_PKT_WAIT_BLOCK_HEADER: /* Byte is service block header */
+ {
+ uint8_t i_sid = cc >> 5;
+ c->cea708.sid_bs = cc & 0x1F;
+ if( i_sid != 0x00 && c->cea708.sid_bs != 0 )
+ {
+ if( i_sid != 0x07 )
+ {
+ const uint8_t mask = (1 << --i_sid);
+ c->i_708channels |= (mask + (mask - 1));
+ c->cea708.state = CEA708_PKT_IN_BLOCK;
+ }
+ else if( c->cea708.sid_bs < 2 )
+ {
+ c->cea708.state = CEA708_PKT_END;
+ }
+ else
+ {
+ /* need to look up next byte in next pkt */
+ c->cea708.state = CEA708_PKT_WAIT_EXT_BLOCK_HEADER;
+ }
+ }
+ else c->cea708.state = CEA708_PKT_END;
+ } break;
+
+ case CEA708_PKT_WAIT_EXT_BLOCK_HEADER:
+ {
+ uint8_t i_extsid = cc & 0x3F;
+ if( i_extsid >= 0x07 )
+ {
+ const uint8_t mask = (1 << --i_extsid);
+ c->i_708channels |= (mask + (mask - 1));
+ }
+ if( c->cea708.sid_bs == 0 )
+ c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
+ else
+ c->cea708.state = CEA708_PKT_IN_BLOCK;
+ } break;
+
+ case CEA708_PKT_IN_BLOCK:
+ {
+ c->cea708.sid_bs--;
+ if( c->cea708.sid_bs == 0 )
+ c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
+ } break;
+
+ default:
+ vlc_assert_unreachable();
+ break;
+ }
+ c->cea708.pktsize--;
+
+ if(c->cea708.pktsize == 0)
+ c->cea708.state = CEA708_PKT_END;
+ }
+}
+
+static inline void cc_ProbeCEA708( cc_data_t *c, uint8_t i_field, const uint8_t cc[2] )
+{
+ if( i_field == 3 ) /* DTVCC_PACKET_START */
+ cc_ProbeCEA708OneByte( c, true, cc[0] );
+ else /* DTVCC_PACKET_DATA */
+ cc_ProbeCEA708OneByte( c, false, cc[0] );
+ cc_ProbeCEA708OneByte( c, false, cc[1] );
}
static inline void cc_AppendData( cc_data_t *c, uint8_t cc_preamble, const uint8_t cc[2] )
{
- uint8_t i_field = cc_preamble & 0x03;
- if( i_field == 0 || i_field == 1 )
+ const uint8_t i_field = cc_preamble & 0x03;
+ if( i_field == 0 || i_field == 1 ) /* NTSC_CC_FIELD_1 NTSC_CC_FIELD_2 */
+ {
c->i_608channels |= (3 << (2 * i_field));
+ }
else
+ {
+ cc_ProbeCEA708( c, i_field, cc );
+ /* By default enable at least channel 1 */
c->i_708channels |= 1;
+ }
c->p_data[c->i_data++] = cc_preamble;
c->p_data[c->i_data++] = cc[0];
More information about the vlc-commits
mailing list