Coverage Report

Created: 2025-08-29 07:30

/src/vlc/modules/codec/cc.h
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************
2
 * cc.h
3
 *****************************************************************************
4
 * Copyright (C) 2007 Laurent Aimar
5
 *
6
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7
 *
8
 * This program is free software; you can redistribute it and/or modify it
9
 * under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation; either version 2.1 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
 * GNU Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program; if not, write to the Free Software Foundation,
20
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21
 *****************************************************************************/
22
23
#ifndef VLC_CC_H_
24
#define VLC_CC_H_
25
26
#include <vlc_bits.h>
27
28
14.9k
#define CC_PKT_BYTE0(field) (0xFC | (0x03 & field))
29
30
/* CC have a maximum rate of 9600 bit/s (per field?) */
31
#define CC_MAX_DATA_SIZE (2 * 3*600)
32
enum cc_payload_type_e
33
{
34
    CC_PAYLOAD_NONE,
35
    CC_PAYLOAD_RAW,
36
    CC_PAYLOAD_GA94,
37
    CC_PAYLOAD_DVD,
38
    CC_PAYLOAD_REPLAYTV,
39
    CC_PAYLOAD_SCTE20,
40
    CC_PAYLOAD_CDP,
41
};
42
typedef struct
43
{
44
    /* Which channel are present */
45
    uint64_t i_708channels;
46
    uint8_t  i_608channels;
47
48
    /* */
49
    bool b_reorder;
50
    struct
51
    {
52
        uint8_t pktsize;
53
        uint8_t seq;
54
        uint8_t sid_bs;
55
        enum
56
        {
57
            CEA708_PKT_END,
58
            CEA708_PKT_WAIT_BLOCK_HEADER,
59
            CEA708_PKT_WAIT_EXT_BLOCK_HEADER,
60
            CEA708_PKT_IN_BLOCK,
61
        } state;
62
    } cea708;
63
64
    /* */
65
    enum cc_payload_type_e i_payload_type;
66
    int i_payload_other_count;
67
68
    /* CC data per field
69
     *  byte[x+0]: field (0/1)
70
     *  byte[x+1]: cc data 1
71
     *  byte[x+2]: cc data 2
72
     */
73
    size_t  i_data;
74
    uint8_t p_data[CC_MAX_DATA_SIZE];
75
} cc_data_t;
76
77
static inline void cc_Init( cc_data_t *c )
78
51.5k
{
79
51.5k
    c->i_608channels = 0;
80
51.5k
    c->i_708channels = 0;
81
51.5k
    c->i_data = 0;
82
51.5k
    c->b_reorder = false;
83
51.5k
    c->cea708.pktsize = 0;
84
51.5k
    c->cea708.seq = 0;
85
51.5k
    c->cea708.sid_bs = 0;
86
51.5k
    c->cea708.state = CEA708_PKT_END;
87
51.5k
    c->i_payload_type = CC_PAYLOAD_NONE;
88
51.5k
    c->i_payload_other_count = 0;
89
51.5k
}
Unexecuted instantiation: mp4.c:cc_Init
ty.c:cc_Init
Line
Count
Source
78
391
{
79
391
    c->i_608channels = 0;
80
391
    c->i_708channels = 0;
81
391
    c->i_data = 0;
82
391
    c->b_reorder = false;
83
391
    c->cea708.pktsize = 0;
84
391
    c->cea708.seq = 0;
85
391
    c->cea708.sid_bs = 0;
86
391
    c->cea708.state = CEA708_PKT_END;
87
391
    c->i_payload_type = CC_PAYLOAD_NONE;
88
391
    c->i_payload_other_count = 0;
89
391
}
hxxx_common.c:cc_Init
Line
Count
Source
78
48.4k
{
79
48.4k
    c->i_608channels = 0;
80
48.4k
    c->i_708channels = 0;
81
48.4k
    c->i_data = 0;
82
48.4k
    c->b_reorder = false;
83
48.4k
    c->cea708.pktsize = 0;
84
48.4k
    c->cea708.seq = 0;
85
48.4k
    c->cea708.sid_bs = 0;
86
48.4k
    c->cea708.state = CEA708_PKT_END;
87
48.4k
    c->i_payload_type = CC_PAYLOAD_NONE;
88
48.4k
    c->i_payload_other_count = 0;
89
48.4k
}
mpegvideo.c:cc_Init
Line
Count
Source
78
1.49k
{
79
1.49k
    c->i_608channels = 0;
80
1.49k
    c->i_708channels = 0;
81
1.49k
    c->i_data = 0;
82
1.49k
    c->b_reorder = false;
83
1.49k
    c->cea708.pktsize = 0;
84
1.49k
    c->cea708.seq = 0;
85
1.49k
    c->cea708.sid_bs = 0;
86
1.49k
    c->cea708.state = CEA708_PKT_END;
87
1.49k
    c->i_payload_type = CC_PAYLOAD_NONE;
88
1.49k
    c->i_payload_other_count = 0;
89
1.49k
}
vc1.c:cc_Init
Line
Count
Source
78
1.16k
{
79
1.16k
    c->i_608channels = 0;
80
1.16k
    c->i_708channels = 0;
81
1.16k
    c->i_data = 0;
82
1.16k
    c->b_reorder = false;
83
1.16k
    c->cea708.pktsize = 0;
84
1.16k
    c->cea708.seq = 0;
85
1.16k
    c->cea708.sid_bs = 0;
86
1.16k
    c->cea708.state = CEA708_PKT_END;
87
1.16k
    c->i_payload_type = CC_PAYLOAD_NONE;
88
1.16k
    c->i_payload_other_count = 0;
89
1.16k
}
90
static inline void cc_Exit( cc_data_t *c )
91
50.0k
{
92
50.0k
    VLC_UNUSED(c);
93
50.0k
    return;
94
50.0k
}
Unexecuted instantiation: mp4.c:cc_Exit
ty.c:cc_Exit
Line
Count
Source
91
391
{
92
391
    VLC_UNUSED(c);
93
391
    return;
94
391
}
hxxx_common.c:cc_Exit
Line
Count
Source
91
48.4k
{
92
48.4k
    VLC_UNUSED(c);
93
48.4k
    return;
94
48.4k
}
Unexecuted instantiation: mpegvideo.c:cc_Exit
vc1.c:cc_Exit
Line
Count
Source
91
1.16k
{
92
1.16k
    VLC_UNUSED(c);
93
1.16k
    return;
94
1.16k
}
95
static inline void cc_Flush( cc_data_t *c )
96
661k
{
97
661k
    c->i_data = 0;
98
661k
    c->cea708.state = CEA708_PKT_END;
99
661k
}
Unexecuted instantiation: mp4.c:cc_Flush
ty.c:cc_Flush
Line
Count
Source
96
1.17k
{
97
1.17k
    c->i_data = 0;
98
1.17k
    c->cea708.state = CEA708_PKT_END;
99
1.17k
}
hxxx_common.c:cc_Flush
Line
Count
Source
96
659k
{
97
659k
    c->i_data = 0;
98
659k
    c->cea708.state = CEA708_PKT_END;
99
659k
}
Unexecuted instantiation: mpegvideo.c:cc_Flush
vc1.c:cc_Flush
Line
Count
Source
96
875
{
97
875
    c->i_data = 0;
98
875
    c->cea708.state = CEA708_PKT_END;
99
875
}
100
101
static inline void cc_ProbeCEA708OneByte( cc_data_t *c, bool b_start, const uint8_t cc )
102
56.4k
{
103
56.4k
    if( b_start )
104
18.0k
    {
105
18.0k
        const uint8_t i_pkt_sequence = cc >> 6;
106
18.0k
        if( i_pkt_sequence > 0 && ((c->cea708.seq + 1) % 4) != i_pkt_sequence )
107
11.1k
        {
108
11.1k
            c->cea708.pktsize = 0;
109
11.1k
            c->cea708.seq = i_pkt_sequence;
110
11.1k
            c->cea708.state = CEA708_PKT_END;
111
11.1k
        }
112
6.90k
        else
113
6.90k
        {
114
6.90k
            c->cea708.seq = i_pkt_sequence;
115
6.90k
            c->cea708.pktsize = cc & 63;
116
6.90k
            if( c->cea708.pktsize == 0 )
117
2.77k
                c->cea708.pktsize = 127;
118
4.12k
            else
119
4.12k
                c->cea708.pktsize = c->cea708.pktsize * 2 - 1;
120
6.90k
            c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
121
6.90k
        }
122
18.0k
    }
123
38.3k
    else if( c->cea708.pktsize == 0 ) /* empty pkt reading service blocks */
124
13.9k
    {
125
13.9k
        c->cea708.state = CEA708_PKT_END;
126
13.9k
    }
127
24.3k
    else if( c->cea708.state != CEA708_PKT_END )
128
17.6k
    {
129
17.6k
        switch( c->cea708.state )
130
17.6k
        {
131
7.80k
            case CEA708_PKT_WAIT_BLOCK_HEADER: /* Byte is service block header */
132
7.80k
            {
133
7.80k
                uint8_t i_sid = cc >> 5;
134
7.80k
                c->cea708.sid_bs = cc & 0x1F;
135
7.80k
                if( i_sid != 0x00 && c->cea708.sid_bs != 0 )
136
5.30k
                {
137
5.30k
                    if( i_sid != 0x07 )
138
2.82k
                    {
139
2.82k
                        const uint8_t mask = (1 << --i_sid);
140
2.82k
                        c->i_708channels |= (mask + (mask - 1));
141
2.82k
                        c->cea708.state = CEA708_PKT_IN_BLOCK;
142
2.82k
                    }
143
2.47k
                    else if( c->cea708.sid_bs < 2 )
144
331
                    {
145
331
                        c->cea708.state = CEA708_PKT_END;
146
331
                    }
147
2.14k
                    else
148
2.14k
                    {
149
                        /* need to look up next byte in next pkt */
150
2.14k
                        c->cea708.state = CEA708_PKT_WAIT_EXT_BLOCK_HEADER;
151
2.14k
                    }
152
5.30k
                }
153
2.50k
                else c->cea708.state = CEA708_PKT_END;
154
7.80k
            } break;
155
156
938
            case CEA708_PKT_WAIT_EXT_BLOCK_HEADER:
157
938
            {
158
938
                uint8_t i_extsid = cc & 0x3F;
159
938
                if( i_extsid >= 0x07 )
160
658
                {
161
658
                    const uint64_t mask = (INT64_C(1) << --i_extsid);
162
658
                    c->i_708channels |= (mask + (mask - 1));
163
658
                }
164
938
                if( c->cea708.sid_bs == 0 )
165
0
                    c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
166
938
                else
167
938
                    c->cea708.state = CEA708_PKT_IN_BLOCK;
168
938
            } break;
169
170
8.92k
            case CEA708_PKT_IN_BLOCK:
171
8.92k
            {
172
8.92k
                c->cea708.sid_bs--;
173
8.92k
                if( c->cea708.sid_bs == 0 )
174
1.16k
                    c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
175
8.92k
            } break;
176
177
0
            default:
178
0
                vlc_assert_unreachable();
179
0
                break;
180
17.6k
        }
181
17.6k
        c->cea708.pktsize--;
182
183
17.6k
        if(c->cea708.pktsize == 0)
184
354
            c->cea708.state = CEA708_PKT_END;
185
17.6k
    }
186
56.4k
}
Unexecuted instantiation: mp4.c:cc_ProbeCEA708OneByte
Unexecuted instantiation: ty.c:cc_ProbeCEA708OneByte
hxxx_common.c:cc_ProbeCEA708OneByte
Line
Count
Source
102
56.4k
{
103
56.4k
    if( b_start )
104
18.0k
    {
105
18.0k
        const uint8_t i_pkt_sequence = cc >> 6;
106
18.0k
        if( i_pkt_sequence > 0 && ((c->cea708.seq + 1) % 4) != i_pkt_sequence )
107
11.1k
        {
108
11.1k
            c->cea708.pktsize = 0;
109
11.1k
            c->cea708.seq = i_pkt_sequence;
110
11.1k
            c->cea708.state = CEA708_PKT_END;
111
11.1k
        }
112
6.90k
        else
113
6.90k
        {
114
6.90k
            c->cea708.seq = i_pkt_sequence;
115
6.90k
            c->cea708.pktsize = cc & 63;
116
6.90k
            if( c->cea708.pktsize == 0 )
117
2.77k
                c->cea708.pktsize = 127;
118
4.12k
            else
119
4.12k
                c->cea708.pktsize = c->cea708.pktsize * 2 - 1;
120
6.90k
            c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
121
6.90k
        }
122
18.0k
    }
123
38.3k
    else if( c->cea708.pktsize == 0 ) /* empty pkt reading service blocks */
124
13.9k
    {
125
13.9k
        c->cea708.state = CEA708_PKT_END;
126
13.9k
    }
127
24.3k
    else if( c->cea708.state != CEA708_PKT_END )
128
17.6k
    {
129
17.6k
        switch( c->cea708.state )
130
17.6k
        {
131
7.80k
            case CEA708_PKT_WAIT_BLOCK_HEADER: /* Byte is service block header */
132
7.80k
            {
133
7.80k
                uint8_t i_sid = cc >> 5;
134
7.80k
                c->cea708.sid_bs = cc & 0x1F;
135
7.80k
                if( i_sid != 0x00 && c->cea708.sid_bs != 0 )
136
5.30k
                {
137
5.30k
                    if( i_sid != 0x07 )
138
2.82k
                    {
139
2.82k
                        const uint8_t mask = (1 << --i_sid);
140
2.82k
                        c->i_708channels |= (mask + (mask - 1));
141
2.82k
                        c->cea708.state = CEA708_PKT_IN_BLOCK;
142
2.82k
                    }
143
2.47k
                    else if( c->cea708.sid_bs < 2 )
144
331
                    {
145
331
                        c->cea708.state = CEA708_PKT_END;
146
331
                    }
147
2.14k
                    else
148
2.14k
                    {
149
                        /* need to look up next byte in next pkt */
150
2.14k
                        c->cea708.state = CEA708_PKT_WAIT_EXT_BLOCK_HEADER;
151
2.14k
                    }
152
5.30k
                }
153
2.50k
                else c->cea708.state = CEA708_PKT_END;
154
7.80k
            } break;
155
156
938
            case CEA708_PKT_WAIT_EXT_BLOCK_HEADER:
157
938
            {
158
938
                uint8_t i_extsid = cc & 0x3F;
159
938
                if( i_extsid >= 0x07 )
160
658
                {
161
658
                    const uint64_t mask = (INT64_C(1) << --i_extsid);
162
658
                    c->i_708channels |= (mask + (mask - 1));
163
658
                }
164
938
                if( c->cea708.sid_bs == 0 )
165
0
                    c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
166
938
                else
167
938
                    c->cea708.state = CEA708_PKT_IN_BLOCK;
168
938
            } break;
169
170
8.92k
            case CEA708_PKT_IN_BLOCK:
171
8.92k
            {
172
8.92k
                c->cea708.sid_bs--;
173
8.92k
                if( c->cea708.sid_bs == 0 )
174
1.16k
                    c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
175
8.92k
            } break;
176
177
0
            default:
178
0
                vlc_assert_unreachable();
179
0
                break;
180
17.6k
        }
181
17.6k
        c->cea708.pktsize--;
182
183
17.6k
        if(c->cea708.pktsize == 0)
184
354
            c->cea708.state = CEA708_PKT_END;
185
17.6k
    }
186
56.4k
}
Unexecuted instantiation: mpegvideo.c:cc_ProbeCEA708OneByte
Unexecuted instantiation: vc1.c:cc_ProbeCEA708OneByte
187
188
static inline void cc_ProbeCEA708( cc_data_t *c, uint8_t i_field, const uint8_t cc[2] )
189
28.2k
{
190
28.2k
    if( i_field == 3 ) /* DTVCC_PACKET_START */
191
18.0k
        cc_ProbeCEA708OneByte( c, true,  cc[0] );
192
10.1k
    else /* DTVCC_PACKET_DATA */
193
10.1k
        cc_ProbeCEA708OneByte( c, false, cc[0] );
194
28.2k
    cc_ProbeCEA708OneByte( c, false, cc[1] );
195
28.2k
}
Unexecuted instantiation: mp4.c:cc_ProbeCEA708
Unexecuted instantiation: ty.c:cc_ProbeCEA708
hxxx_common.c:cc_ProbeCEA708
Line
Count
Source
189
28.2k
{
190
28.2k
    if( i_field == 3 ) /* DTVCC_PACKET_START */
191
18.0k
        cc_ProbeCEA708OneByte( c, true,  cc[0] );
192
10.1k
    else /* DTVCC_PACKET_DATA */
193
10.1k
        cc_ProbeCEA708OneByte( c, false, cc[0] );
194
28.2k
    cc_ProbeCEA708OneByte( c, false, cc[1] );
195
28.2k
}
Unexecuted instantiation: mpegvideo.c:cc_ProbeCEA708
Unexecuted instantiation: vc1.c:cc_ProbeCEA708
196
197
static inline bool cc_AppendData( cc_data_t *c, uint8_t cc_preamble, const uint8_t cc[2] )
198
51.5k
{
199
51.5k
    if (c->i_data + 3 > ARRAY_SIZE(c->p_data))
200
239
        return false;
201
202
51.2k
    const uint8_t i_field = cc_preamble & 0x03;
203
51.2k
    if( i_field == 0 || i_field == 1 ) /* NTSC_CC_FIELD_1 NTSC_CC_FIELD_2 */
204
23.0k
    {
205
23.0k
        c->i_608channels |= (3 << (2 * i_field));
206
23.0k
    }
207
28.2k
    else
208
28.2k
    {
209
28.2k
        cc_ProbeCEA708( c, i_field, cc );
210
        /* By default enable at least channel 1 */
211
28.2k
        c->i_708channels |= 1;
212
28.2k
    }
213
214
51.2k
    c->p_data[c->i_data++] = cc_preamble;
215
51.2k
    c->p_data[c->i_data++] = cc[0];
216
51.2k
    c->p_data[c->i_data++] = cc[1];
217
51.2k
    return true;
218
51.5k
}
Unexecuted instantiation: mp4.c:cc_AppendData
ty.c:cc_AppendData
Line
Count
Source
198
14.9k
{
199
14.9k
    if (c->i_data + 3 > ARRAY_SIZE(c->p_data))
200
0
        return false;
201
202
14.9k
    const uint8_t i_field = cc_preamble & 0x03;
203
14.9k
    if( i_field == 0 || i_field == 1 ) /* NTSC_CC_FIELD_1 NTSC_CC_FIELD_2 */
204
14.9k
    {
205
14.9k
        c->i_608channels |= (3 << (2 * i_field));
206
14.9k
    }
207
0
    else
208
0
    {
209
0
        cc_ProbeCEA708( c, i_field, cc );
210
        /* By default enable at least channel 1 */
211
0
        c->i_708channels |= 1;
212
0
    }
213
214
14.9k
    c->p_data[c->i_data++] = cc_preamble;
215
14.9k
    c->p_data[c->i_data++] = cc[0];
216
14.9k
    c->p_data[c->i_data++] = cc[1];
217
14.9k
    return true;
218
14.9k
}
hxxx_common.c:cc_AppendData
Line
Count
Source
198
36.5k
{
199
36.5k
    if (c->i_data + 3 > ARRAY_SIZE(c->p_data))
200
239
        return false;
201
202
36.2k
    const uint8_t i_field = cc_preamble & 0x03;
203
36.2k
    if( i_field == 0 || i_field == 1 ) /* NTSC_CC_FIELD_1 NTSC_CC_FIELD_2 */
204
8.07k
    {
205
8.07k
        c->i_608channels |= (3 << (2 * i_field));
206
8.07k
    }
207
28.2k
    else
208
28.2k
    {
209
28.2k
        cc_ProbeCEA708( c, i_field, cc );
210
        /* By default enable at least channel 1 */
211
28.2k
        c->i_708channels |= 1;
212
28.2k
    }
213
214
36.2k
    c->p_data[c->i_data++] = cc_preamble;
215
36.2k
    c->p_data[c->i_data++] = cc[0];
216
36.2k
    c->p_data[c->i_data++] = cc[1];
217
36.2k
    return true;
218
36.5k
}
Unexecuted instantiation: mpegvideo.c:cc_AppendData
Unexecuted instantiation: vc1.c:cc_AppendData
219
220
static inline void cc_Extract( cc_data_t *c, enum cc_payload_type_e i_payload_type,
221
                               bool b_top_field_first, const uint8_t *p_src, int i_src )
222
14.5k
{
223
14.5k
    if( c->i_payload_type != CC_PAYLOAD_NONE && c->i_payload_type != i_payload_type )
224
1
    {
225
1
        c->i_payload_other_count++;
226
1
        if( c->i_payload_other_count < 50 )
227
0
            return;
228
1
    }
229
14.5k
    c->i_payload_type        = i_payload_type;
230
14.5k
    c->i_payload_other_count = 0;
231
232
14.5k
    if( i_payload_type == CC_PAYLOAD_RAW )
233
0
    {
234
0
        for( int i = 0; i + 2 < i_src; i += 3 )
235
0
        {
236
0
            const uint8_t *cc = &p_src[i];
237
0
            if (!cc_AppendData( c, cc[0], &cc[1] ))
238
0
                break;
239
0
        }
240
0
        c->b_reorder = true;
241
0
    }
242
14.5k
    else if( i_payload_type == CC_PAYLOAD_GA94 )
243
14.5k
    {
244
        /* cc_data()
245
         *          u1 reserved(1)
246
         *          u1 process_cc_data_flag
247
         *          u1 additional_data_flag
248
         *          u5 cc_count
249
         *          u8 reserved(1111 1111)
250
         *          for cc_count
251
         *              u5 marker bit(1111 1)
252
         *              u1 cc_valid
253
         *              u2 cc_type
254
         *              u8 cc_data_1
255
         *              u8 cc_data_2
256
         *          u8 marker bit(1111 1111)
257
         *          if additional_data_flag
258
         *              unknown
259
         */
260
        /* cc_type:
261
         *  0x00: field 1
262
         *  0x01: field 2
263
         */
264
14.5k
        const uint8_t *cc = &p_src[0];
265
14.5k
        const int i_count_cc = cc[0]&0x1f;
266
14.5k
        int i;
267
268
14.5k
        if( !(cc[0]&0x40) ) // process flag
269
1.23k
            return;
270
13.3k
        if( i_src < 1+1 + i_count_cc*3 + 1)  // broken packet
271
725
            return;
272
12.6k
        if( i_count_cc <= 0 )   // no cc present
273
477
            return;
274
12.1k
        if( cc[2+i_count_cc * 3] != 0xff )  // marker absent
275
1.39k
            return;
276
10.7k
        cc += 2;
277
278
47.0k
        for( i = 0; i < i_count_cc; i++, cc += 3 )
279
36.5k
        {
280
36.5k
            if (!cc_AppendData( c, cc[0], &cc[1] ))
281
239
                break;
282
36.5k
        }
283
10.7k
        c->b_reorder = true;
284
10.7k
    }
285
0
    else if( i_payload_type == CC_PAYLOAD_DVD )
286
0
    {
287
        /* user_data
288
         *          (u32 stripped earlier)
289
         *          u32 (0x43 0x43 0x01 0xf8)
290
         *          u1 caption_odd_field_first (CC1/CC2)
291
         *          u1 caption_filler
292
         *          u5 cc_block_count  (== cc_count / 2)
293
         *          u1 caption_extra_field_added (because odd cc_count)
294
         *          for cc_block_count * 2 + caption_extra_field_added
295
         *              u7 cc_filler_1
296
         *              u1 cc_field_is_odd
297
         *              u8 cc_data_1
298
         *              u8 cc_data_2
299
         */
300
0
        const int b_truncate = p_src[4] & 0x01;
301
0
        const int i_count_cc2 = ((p_src[4] >> 1) & 0x1f);
302
0
        const uint8_t *cc = &p_src[5];
303
0
        i_src -= 5;
304
0
        int i;
305
306
0
#define CC_ALIGNMENT_TEST   (0x7f)
307
308
0
        for( i = 0; i < 2*i_count_cc2 + b_truncate && i_src >= 3; i++, cc+=3 )
309
0
        {
310
0
            if( (cc[0] >> 1) == CC_ALIGNMENT_TEST )
311
0
            {
312
0
                const bool even_field = (cc[0] & 0x01) ? 0 : 1;
313
0
                if (!cc_AppendData( c, CC_PKT_BYTE0(even_field), &cc[1] ))
314
0
                    break;
315
0
            }
316
0
            i_src -= 3;
317
0
        }
318
0
        c->b_reorder = false;
319
0
    }
320
0
    else if( i_payload_type == CC_PAYLOAD_REPLAYTV )
321
0
    {
322
0
        const uint8_t *cc = &p_src[0];
323
0
        for( int i_cc_count = i_src >> 2; i_cc_count > 0;
324
0
             i_cc_count--, cc += 4 )
325
0
        {
326
0
            uint8_t i_field = (cc[0] & 0x02) >> 1;
327
0
            if (!cc_AppendData( c, CC_PKT_BYTE0(i_field), &cc[2] ))
328
0
                return;
329
0
        }
330
0
        c->b_reorder = false;
331
0
    }
332
0
    else if( i_payload_type == CC_PAYLOAD_SCTE20 )
333
0
    {
334
        /* user_data(2)
335
         *          (u32 stripped earlier)
336
         *          u16 p_cc_scte20
337
         *          u5 cc_count
338
         *          for cc_count
339
         *              u2 cc_priority
340
         *              u2 cc_field_num
341
         *              u5 cc_line_offset
342
         *              u8 cc_data_1[1:8]
343
         *              u8 cc_data_2[1:8]
344
         *              u1 marker bit
345
         *          un additional_realtimevideodata
346
         *          un reserved
347
         */
348
0
        bs_t s;
349
0
        bs_init( &s, &p_src[2], i_src - 2 );
350
0
        const int i_cc_count = bs_read( &s, 5 );
351
0
        for( int i = 0; i < i_cc_count; i++ )
352
0
        {
353
0
            bs_skip( &s, 2 );
354
0
            const int i_field_idx = bs_read( &s, 2 );
355
0
            bs_skip( &s, 5 );
356
0
            uint8_t cc[2];
357
0
            for( int j = 0; j < 2; j++ )
358
0
            {
359
0
                cc[j] = 0;
360
0
                for( int k = 0; k < 8; k++ )
361
0
                    cc[j] |= bs_read( &s, 1 ) << k;
362
0
            }
363
0
            bs_skip( &s, 1 );
364
365
0
            if( i_field_idx == 0 )
366
0
                continue;
367
368
            /* 1,2,3 -> 0,1,0. I.E. repeated field 3 is merged with field 1 */
369
0
            int i_field = ((i_field_idx - 1) & 1);
370
0
            if (!b_top_field_first)
371
0
                i_field ^= 1;
372
373
0
            if (!cc_AppendData( c, CC_PKT_BYTE0(i_field), &cc[0] ))
374
0
                continue;
375
0
        }
376
0
        c->b_reorder = true;
377
0
    }
378
0
    else // CC_PAYLOAD_CDP
379
0
    {
380
0
#       define CDP_FLAG_TIME_CODE_PRESENT  (1<<7)
381
0
#       define CDP_FLAG_CC_DATA_PRESENT    (1<<6)
382
0
#       define CDP_FLAG_SVC_INFO_PRESENT   (1<<5)
383
0
#       define CDP_FLAG_SVC_INFO_START     (1<<4)
384
0
#       define CDP_FLAG_SVC_INFO_CHANGE    (1<<3)
385
0
#       define CDP_FLAG_SVC_INFO_COMPLETE  (1<<2)
386
0
#       define CDP_FLAG_CAPTION_SVC_ACTIVE (1<<1)
387
388
0
        if(i_src < 7)
389
0
            return;
390
391
        /* ST334-2 5.2 cdp_header() */
392
0
        uint8_t cdp_length = p_src[2];
393
0
        if(cdp_length < 8 || cdp_length > i_src)
394
0
            return;
395
0
        uint8_t cdp_flags = p_src[4];
396
397
        /* skip header */
398
0
        p_src += 7; i_src -= 7;
399
400
        /* 5.3 time_code_section() */
401
0
        if( cdp_flags & CDP_FLAG_TIME_CODE_PRESENT )
402
0
        {
403
0
            if( i_src < 5 ) // Shall be 5 bytes
404
0
                return;
405
0
            p_src += 5; i_src += 5;
406
0
        }
407
        /* 5.4 ccdata_section */
408
0
        if( cdp_flags & CDP_FLAG_CC_DATA_PRESENT )
409
0
        {
410
            /* ccdata_section()
411
             *      u8 0x72
412
             *      u3 marker bits(111)
413
             *      u5 cc_count
414
             *      for cc_count
415
             *          u5 marker bits(1111 1)
416
             *          u1 cc_valid
417
             *          u2 cc_type
418
             *          u8 cc_data_1
419
             *          u8 cc_data_2
420
             */
421
0
            if( i_src < 2 || p_src[0] != 0x72 ) // marker
422
0
                return;
423
424
0
            const uint8_t *cc = &p_src[1];
425
0
            const int i_count_cc = cc[0]&0x1f;
426
427
0
            if( i_src - 2 < i_count_cc*3 )  // broken packet
428
0
                return;
429
0
            cc += 1;
430
0
            for( int i = 0; i < i_count_cc; i++, cc += 3 )
431
0
            {
432
0
                if (!cc_AppendData( c, cc[0], &cc[1] ))
433
0
                    break;
434
0
            }
435
0
        }
436
        /* remaining data */
437
0
        c->b_reorder = false;
438
0
    }
439
14.5k
}
Unexecuted instantiation: mp4.c:cc_Extract
Unexecuted instantiation: ty.c:cc_Extract
hxxx_common.c:cc_Extract
Line
Count
Source
222
14.5k
{
223
14.5k
    if( c->i_payload_type != CC_PAYLOAD_NONE && c->i_payload_type != i_payload_type )
224
0
    {
225
0
        c->i_payload_other_count++;
226
0
        if( c->i_payload_other_count < 50 )
227
0
            return;
228
0
    }
229
14.5k
    c->i_payload_type        = i_payload_type;
230
14.5k
    c->i_payload_other_count = 0;
231
232
14.5k
    if( i_payload_type == CC_PAYLOAD_RAW )
233
0
    {
234
0
        for( int i = 0; i + 2 < i_src; i += 3 )
235
0
        {
236
0
            const uint8_t *cc = &p_src[i];
237
0
            if (!cc_AppendData( c, cc[0], &cc[1] ))
238
0
                break;
239
0
        }
240
0
        c->b_reorder = true;
241
0
    }
242
14.5k
    else if( i_payload_type == CC_PAYLOAD_GA94 )
243
14.5k
    {
244
        /* cc_data()
245
         *          u1 reserved(1)
246
         *          u1 process_cc_data_flag
247
         *          u1 additional_data_flag
248
         *          u5 cc_count
249
         *          u8 reserved(1111 1111)
250
         *          for cc_count
251
         *              u5 marker bit(1111 1)
252
         *              u1 cc_valid
253
         *              u2 cc_type
254
         *              u8 cc_data_1
255
         *              u8 cc_data_2
256
         *          u8 marker bit(1111 1111)
257
         *          if additional_data_flag
258
         *              unknown
259
         */
260
        /* cc_type:
261
         *  0x00: field 1
262
         *  0x01: field 2
263
         */
264
14.5k
        const uint8_t *cc = &p_src[0];
265
14.5k
        const int i_count_cc = cc[0]&0x1f;
266
14.5k
        int i;
267
268
14.5k
        if( !(cc[0]&0x40) ) // process flag
269
1.21k
            return;
270
13.3k
        if( i_src < 1+1 + i_count_cc*3 + 1)  // broken packet
271
725
            return;
272
12.6k
        if( i_count_cc <= 0 )   // no cc present
273
477
            return;
274
12.1k
        if( cc[2+i_count_cc * 3] != 0xff )  // marker absent
275
1.39k
            return;
276
10.7k
        cc += 2;
277
278
47.0k
        for( i = 0; i < i_count_cc; i++, cc += 3 )
279
36.5k
        {
280
36.5k
            if (!cc_AppendData( c, cc[0], &cc[1] ))
281
239
                break;
282
36.5k
        }
283
10.7k
        c->b_reorder = true;
284
10.7k
    }
285
0
    else if( i_payload_type == CC_PAYLOAD_DVD )
286
0
    {
287
        /* user_data
288
         *          (u32 stripped earlier)
289
         *          u32 (0x43 0x43 0x01 0xf8)
290
         *          u1 caption_odd_field_first (CC1/CC2)
291
         *          u1 caption_filler
292
         *          u5 cc_block_count  (== cc_count / 2)
293
         *          u1 caption_extra_field_added (because odd cc_count)
294
         *          for cc_block_count * 2 + caption_extra_field_added
295
         *              u7 cc_filler_1
296
         *              u1 cc_field_is_odd
297
         *              u8 cc_data_1
298
         *              u8 cc_data_2
299
         */
300
0
        const int b_truncate = p_src[4] & 0x01;
301
0
        const int i_count_cc2 = ((p_src[4] >> 1) & 0x1f);
302
0
        const uint8_t *cc = &p_src[5];
303
0
        i_src -= 5;
304
0
        int i;
305
306
0
#define CC_ALIGNMENT_TEST   (0x7f)
307
308
0
        for( i = 0; i < 2*i_count_cc2 + b_truncate && i_src >= 3; i++, cc+=3 )
309
0
        {
310
0
            if( (cc[0] >> 1) == CC_ALIGNMENT_TEST )
311
0
            {
312
0
                const bool even_field = (cc[0] & 0x01) ? 0 : 1;
313
0
                if (!cc_AppendData( c, CC_PKT_BYTE0(even_field), &cc[1] ))
314
0
                    break;
315
0
            }
316
0
            i_src -= 3;
317
0
        }
318
0
        c->b_reorder = false;
319
0
    }
320
0
    else if( i_payload_type == CC_PAYLOAD_REPLAYTV )
321
0
    {
322
0
        const uint8_t *cc = &p_src[0];
323
0
        for( int i_cc_count = i_src >> 2; i_cc_count > 0;
324
0
             i_cc_count--, cc += 4 )
325
0
        {
326
0
            uint8_t i_field = (cc[0] & 0x02) >> 1;
327
0
            if (!cc_AppendData( c, CC_PKT_BYTE0(i_field), &cc[2] ))
328
0
                return;
329
0
        }
330
0
        c->b_reorder = false;
331
0
    }
332
0
    else if( i_payload_type == CC_PAYLOAD_SCTE20 )
333
0
    {
334
        /* user_data(2)
335
         *          (u32 stripped earlier)
336
         *          u16 p_cc_scte20
337
         *          u5 cc_count
338
         *          for cc_count
339
         *              u2 cc_priority
340
         *              u2 cc_field_num
341
         *              u5 cc_line_offset
342
         *              u8 cc_data_1[1:8]
343
         *              u8 cc_data_2[1:8]
344
         *              u1 marker bit
345
         *          un additional_realtimevideodata
346
         *          un reserved
347
         */
348
0
        bs_t s;
349
0
        bs_init( &s, &p_src[2], i_src - 2 );
350
0
        const int i_cc_count = bs_read( &s, 5 );
351
0
        for( int i = 0; i < i_cc_count; i++ )
352
0
        {
353
0
            bs_skip( &s, 2 );
354
0
            const int i_field_idx = bs_read( &s, 2 );
355
0
            bs_skip( &s, 5 );
356
0
            uint8_t cc[2];
357
0
            for( int j = 0; j < 2; j++ )
358
0
            {
359
0
                cc[j] = 0;
360
0
                for( int k = 0; k < 8; k++ )
361
0
                    cc[j] |= bs_read( &s, 1 ) << k;
362
0
            }
363
0
            bs_skip( &s, 1 );
364
365
0
            if( i_field_idx == 0 )
366
0
                continue;
367
368
            /* 1,2,3 -> 0,1,0. I.E. repeated field 3 is merged with field 1 */
369
0
            int i_field = ((i_field_idx - 1) & 1);
370
0
            if (!b_top_field_first)
371
0
                i_field ^= 1;
372
373
0
            if (!cc_AppendData( c, CC_PKT_BYTE0(i_field), &cc[0] ))
374
0
                continue;
375
0
        }
376
0
        c->b_reorder = true;
377
0
    }
378
0
    else // CC_PAYLOAD_CDP
379
0
    {
380
0
#       define CDP_FLAG_TIME_CODE_PRESENT  (1<<7)
381
0
#       define CDP_FLAG_CC_DATA_PRESENT    (1<<6)
382
0
#       define CDP_FLAG_SVC_INFO_PRESENT   (1<<5)
383
0
#       define CDP_FLAG_SVC_INFO_START     (1<<4)
384
0
#       define CDP_FLAG_SVC_INFO_CHANGE    (1<<3)
385
0
#       define CDP_FLAG_SVC_INFO_COMPLETE  (1<<2)
386
0
#       define CDP_FLAG_CAPTION_SVC_ACTIVE (1<<1)
387
388
0
        if(i_src < 7)
389
0
            return;
390
391
        /* ST334-2 5.2 cdp_header() */
392
0
        uint8_t cdp_length = p_src[2];
393
0
        if(cdp_length < 8 || cdp_length > i_src)
394
0
            return;
395
0
        uint8_t cdp_flags = p_src[4];
396
397
        /* skip header */
398
0
        p_src += 7; i_src -= 7;
399
400
        /* 5.3 time_code_section() */
401
0
        if( cdp_flags & CDP_FLAG_TIME_CODE_PRESENT )
402
0
        {
403
0
            if( i_src < 5 ) // Shall be 5 bytes
404
0
                return;
405
0
            p_src += 5; i_src += 5;
406
0
        }
407
        /* 5.4 ccdata_section */
408
0
        if( cdp_flags & CDP_FLAG_CC_DATA_PRESENT )
409
0
        {
410
            /* ccdata_section()
411
             *      u8 0x72
412
             *      u3 marker bits(111)
413
             *      u5 cc_count
414
             *      for cc_count
415
             *          u5 marker bits(1111 1)
416
             *          u1 cc_valid
417
             *          u2 cc_type
418
             *          u8 cc_data_1
419
             *          u8 cc_data_2
420
             */
421
0
            if( i_src < 2 || p_src[0] != 0x72 ) // marker
422
0
                return;
423
424
0
            const uint8_t *cc = &p_src[1];
425
0
            const int i_count_cc = cc[0]&0x1f;
426
427
0
            if( i_src - 2 < i_count_cc*3 )  // broken packet
428
0
                return;
429
0
            cc += 1;
430
0
            for( int i = 0; i < i_count_cc; i++, cc += 3 )
431
0
            {
432
0
                if (!cc_AppendData( c, cc[0], &cc[1] ))
433
0
                    break;
434
0
            }
435
0
        }
436
        /* remaining data */
437
0
        c->b_reorder = false;
438
0
    }
439
14.5k
}
Unexecuted instantiation: mpegvideo.c:cc_Extract
vc1.c:cc_Extract
Line
Count
Source
222
14
{
223
14
    if( c->i_payload_type != CC_PAYLOAD_NONE && c->i_payload_type != i_payload_type )
224
1
    {
225
1
        c->i_payload_other_count++;
226
1
        if( c->i_payload_other_count < 50 )
227
0
            return;
228
1
    }
229
14
    c->i_payload_type        = i_payload_type;
230
14
    c->i_payload_other_count = 0;
231
232
14
    if( i_payload_type == CC_PAYLOAD_RAW )
233
0
    {
234
0
        for( int i = 0; i + 2 < i_src; i += 3 )
235
0
        {
236
0
            const uint8_t *cc = &p_src[i];
237
0
            if (!cc_AppendData( c, cc[0], &cc[1] ))
238
0
                break;
239
0
        }
240
0
        c->b_reorder = true;
241
0
    }
242
14
    else if( i_payload_type == CC_PAYLOAD_GA94 )
243
14
    {
244
        /* cc_data()
245
         *          u1 reserved(1)
246
         *          u1 process_cc_data_flag
247
         *          u1 additional_data_flag
248
         *          u5 cc_count
249
         *          u8 reserved(1111 1111)
250
         *          for cc_count
251
         *              u5 marker bit(1111 1)
252
         *              u1 cc_valid
253
         *              u2 cc_type
254
         *              u8 cc_data_1
255
         *              u8 cc_data_2
256
         *          u8 marker bit(1111 1111)
257
         *          if additional_data_flag
258
         *              unknown
259
         */
260
        /* cc_type:
261
         *  0x00: field 1
262
         *  0x01: field 2
263
         */
264
14
        const uint8_t *cc = &p_src[0];
265
14
        const int i_count_cc = cc[0]&0x1f;
266
14
        int i;
267
268
14
        if( !(cc[0]&0x40) ) // process flag
269
14
            return;
270
0
        if( i_src < 1+1 + i_count_cc*3 + 1)  // broken packet
271
0
            return;
272
0
        if( i_count_cc <= 0 )   // no cc present
273
0
            return;
274
0
        if( cc[2+i_count_cc * 3] != 0xff )  // marker absent
275
0
            return;
276
0
        cc += 2;
277
278
0
        for( i = 0; i < i_count_cc; i++, cc += 3 )
279
0
        {
280
0
            if (!cc_AppendData( c, cc[0], &cc[1] ))
281
0
                break;
282
0
        }
283
0
        c->b_reorder = true;
284
0
    }
285
0
    else if( i_payload_type == CC_PAYLOAD_DVD )
286
0
    {
287
        /* user_data
288
         *          (u32 stripped earlier)
289
         *          u32 (0x43 0x43 0x01 0xf8)
290
         *          u1 caption_odd_field_first (CC1/CC2)
291
         *          u1 caption_filler
292
         *          u5 cc_block_count  (== cc_count / 2)
293
         *          u1 caption_extra_field_added (because odd cc_count)
294
         *          for cc_block_count * 2 + caption_extra_field_added
295
         *              u7 cc_filler_1
296
         *              u1 cc_field_is_odd
297
         *              u8 cc_data_1
298
         *              u8 cc_data_2
299
         */
300
0
        const int b_truncate = p_src[4] & 0x01;
301
0
        const int i_count_cc2 = ((p_src[4] >> 1) & 0x1f);
302
0
        const uint8_t *cc = &p_src[5];
303
0
        i_src -= 5;
304
0
        int i;
305
306
0
#define CC_ALIGNMENT_TEST   (0x7f)
307
308
0
        for( i = 0; i < 2*i_count_cc2 + b_truncate && i_src >= 3; i++, cc+=3 )
309
0
        {
310
0
            if( (cc[0] >> 1) == CC_ALIGNMENT_TEST )
311
0
            {
312
0
                const bool even_field = (cc[0] & 0x01) ? 0 : 1;
313
0
                if (!cc_AppendData( c, CC_PKT_BYTE0(even_field), &cc[1] ))
314
0
                    break;
315
0
            }
316
0
            i_src -= 3;
317
0
        }
318
0
        c->b_reorder = false;
319
0
    }
320
0
    else if( i_payload_type == CC_PAYLOAD_REPLAYTV )
321
0
    {
322
0
        const uint8_t *cc = &p_src[0];
323
0
        for( int i_cc_count = i_src >> 2; i_cc_count > 0;
324
0
             i_cc_count--, cc += 4 )
325
0
        {
326
0
            uint8_t i_field = (cc[0] & 0x02) >> 1;
327
0
            if (!cc_AppendData( c, CC_PKT_BYTE0(i_field), &cc[2] ))
328
0
                return;
329
0
        }
330
0
        c->b_reorder = false;
331
0
    }
332
0
    else if( i_payload_type == CC_PAYLOAD_SCTE20 )
333
0
    {
334
        /* user_data(2)
335
         *          (u32 stripped earlier)
336
         *          u16 p_cc_scte20
337
         *          u5 cc_count
338
         *          for cc_count
339
         *              u2 cc_priority
340
         *              u2 cc_field_num
341
         *              u5 cc_line_offset
342
         *              u8 cc_data_1[1:8]
343
         *              u8 cc_data_2[1:8]
344
         *              u1 marker bit
345
         *          un additional_realtimevideodata
346
         *          un reserved
347
         */
348
0
        bs_t s;
349
0
        bs_init( &s, &p_src[2], i_src - 2 );
350
0
        const int i_cc_count = bs_read( &s, 5 );
351
0
        for( int i = 0; i < i_cc_count; i++ )
352
0
        {
353
0
            bs_skip( &s, 2 );
354
0
            const int i_field_idx = bs_read( &s, 2 );
355
0
            bs_skip( &s, 5 );
356
0
            uint8_t cc[2];
357
0
            for( int j = 0; j < 2; j++ )
358
0
            {
359
0
                cc[j] = 0;
360
0
                for( int k = 0; k < 8; k++ )
361
0
                    cc[j] |= bs_read( &s, 1 ) << k;
362
0
            }
363
0
            bs_skip( &s, 1 );
364
365
0
            if( i_field_idx == 0 )
366
0
                continue;
367
368
            /* 1,2,3 -> 0,1,0. I.E. repeated field 3 is merged with field 1 */
369
0
            int i_field = ((i_field_idx - 1) & 1);
370
0
            if (!b_top_field_first)
371
0
                i_field ^= 1;
372
373
0
            if (!cc_AppendData( c, CC_PKT_BYTE0(i_field), &cc[0] ))
374
0
                continue;
375
0
        }
376
0
        c->b_reorder = true;
377
0
    }
378
0
    else // CC_PAYLOAD_CDP
379
0
    {
380
0
#       define CDP_FLAG_TIME_CODE_PRESENT  (1<<7)
381
0
#       define CDP_FLAG_CC_DATA_PRESENT    (1<<6)
382
0
#       define CDP_FLAG_SVC_INFO_PRESENT   (1<<5)
383
0
#       define CDP_FLAG_SVC_INFO_START     (1<<4)
384
0
#       define CDP_FLAG_SVC_INFO_CHANGE    (1<<3)
385
0
#       define CDP_FLAG_SVC_INFO_COMPLETE  (1<<2)
386
0
#       define CDP_FLAG_CAPTION_SVC_ACTIVE (1<<1)
387
388
0
        if(i_src < 7)
389
0
            return;
390
391
        /* ST334-2 5.2 cdp_header() */
392
0
        uint8_t cdp_length = p_src[2];
393
0
        if(cdp_length < 8 || cdp_length > i_src)
394
0
            return;
395
0
        uint8_t cdp_flags = p_src[4];
396
397
        /* skip header */
398
0
        p_src += 7; i_src -= 7;
399
400
        /* 5.3 time_code_section() */
401
0
        if( cdp_flags & CDP_FLAG_TIME_CODE_PRESENT )
402
0
        {
403
0
            if( i_src < 5 ) // Shall be 5 bytes
404
0
                return;
405
0
            p_src += 5; i_src += 5;
406
0
        }
407
        /* 5.4 ccdata_section */
408
0
        if( cdp_flags & CDP_FLAG_CC_DATA_PRESENT )
409
0
        {
410
            /* ccdata_section()
411
             *      u8 0x72
412
             *      u3 marker bits(111)
413
             *      u5 cc_count
414
             *      for cc_count
415
             *          u5 marker bits(1111 1)
416
             *          u1 cc_valid
417
             *          u2 cc_type
418
             *          u8 cc_data_1
419
             *          u8 cc_data_2
420
             */
421
0
            if( i_src < 2 || p_src[0] != 0x72 ) // marker
422
0
                return;
423
424
0
            const uint8_t *cc = &p_src[1];
425
0
            const int i_count_cc = cc[0]&0x1f;
426
427
0
            if( i_src - 2 < i_count_cc*3 )  // broken packet
428
0
                return;
429
0
            cc += 1;
430
0
            for( int i = 0; i < i_count_cc; i++, cc += 3 )
431
0
            {
432
0
                if (!cc_AppendData( c, cc[0], &cc[1] ))
433
0
                    break;
434
0
            }
435
0
        }
436
        /* remaining data */
437
0
        c->b_reorder = false;
438
0
    }
439
14
}
440
441
442
static inline void cc_ProbeAndExtract( cc_data_t *c, bool b_top_field_first, const uint8_t *p_src, int i_src )
443
52
{
444
52
    static const uint8_t p_cc_ga94[4] = { 0x47, 0x41, 0x39, 0x34 };
445
52
    static const uint8_t p_cc_dvd[4] = { 0x43, 0x43, 0x01, 0xf8 }; /* ascii 'CC', type_code, cc_block_size */
446
52
    static const uint8_t p_cc_replaytv4a[2] = { 0xbb, 0x02 };/* RTV4K, BB02xxxxCC02 */
447
52
    static const uint8_t p_cc_replaytv4b[2] = { 0xcc, 0x02 };/* see DVR-ClosedCaption in samples */
448
52
    static const uint8_t p_cc_replaytv5a[2] = { 0x99, 0x02 };/* RTV5K, 9902xxxxAA02 */
449
52
    static const uint8_t p_cc_replaytv5b[2] = { 0xaa, 0x02 };/* see DVR-ClosedCaption in samples */
450
52
    static const uint8_t p_cc_scte20[2] = { 0x03, 0x81 };    /* user_data_type_code, SCTE 20 */
451
52
    static const uint8_t p_cc_scte20_old[2] = { 0x03, 0x01 };/* user_data_type_code, old, Note 1 */
452
453
52
    if( i_src < 4 )
454
0
        return;
455
456
52
    enum cc_payload_type_e i_payload_type;
457
52
    if( !memcmp( p_cc_ga94, p_src, 4 ) && i_src >= 5+1+1+1 && p_src[4] == 0x03 )
458
14
    {
459
        /* CC from DVB/ATSC TS */
460
14
        i_payload_type = CC_PAYLOAD_GA94;
461
14
        i_src -= 5;
462
14
        p_src += 5;
463
14
    }
464
38
    else if( !memcmp( p_cc_dvd, p_src, 4 ) && i_src > 4+1 )
465
0
    {
466
0
        i_payload_type = CC_PAYLOAD_DVD;
467
0
    }
468
38
    else if( i_src >= 2+2 + 2+2 &&
469
38
             ( ( !memcmp( p_cc_replaytv4a, &p_src[0], 2 ) && !memcmp( p_cc_replaytv4b, &p_src[4], 2 ) ) ||
470
20
               ( !memcmp( p_cc_replaytv5a, &p_src[0], 2 ) && !memcmp( p_cc_replaytv5b, &p_src[4], 2 ) ) ) )
471
0
    {
472
0
        i_payload_type = CC_PAYLOAD_REPLAYTV;
473
0
    }
474
38
    else if( ( !memcmp( p_cc_scte20, p_src, 2 ) ||
475
38
               !memcmp( p_cc_scte20_old, p_src, 2 ) ) && i_src > 2 )
476
0
    {
477
0
        i_payload_type = CC_PAYLOAD_SCTE20;
478
0
    }
479
38
    else if (p_src[0] == 0x03 && p_src[1] == i_src - 2) /* DIRECTV */
480
0
    {
481
0
        i_payload_type = CC_PAYLOAD_GA94;
482
0
        i_src -= 2;
483
0
        p_src += 2;
484
0
    }
485
38
    else if (p_src[0] == 0x96 && p_src[1] == 0x69) /* CDP */
486
0
    {
487
0
        i_payload_type = CC_PAYLOAD_CDP;
488
0
    }
489
38
    else
490
38
    {
491
#if 0
492
#define V(x) ( ( x < 0x20 || x >= 0x7f ) ? '?' : x )
493
        fprintf( stderr, "-------------- unknown user data " );
494
        for( int i = 0; i < i_src; i++ )
495
            fprintf( stderr, "%2.2x ", p_src[i] );
496
        for( int i = 0; i < i_src; i++ )
497
            fprintf( stderr, "%c ", V(p_src[i]) );
498
        fprintf( stderr, "\n" );
499
#undef V
500
#endif
501
38
        return;
502
38
    }
503
504
14
    cc_Extract( c, i_payload_type, b_top_field_first, p_src, i_src );
505
14
}
Unexecuted instantiation: mp4.c:cc_ProbeAndExtract
Unexecuted instantiation: ty.c:cc_ProbeAndExtract
Unexecuted instantiation: hxxx_common.c:cc_ProbeAndExtract
Unexecuted instantiation: mpegvideo.c:cc_ProbeAndExtract
vc1.c:cc_ProbeAndExtract
Line
Count
Source
443
52
{
444
52
    static const uint8_t p_cc_ga94[4] = { 0x47, 0x41, 0x39, 0x34 };
445
52
    static const uint8_t p_cc_dvd[4] = { 0x43, 0x43, 0x01, 0xf8 }; /* ascii 'CC', type_code, cc_block_size */
446
52
    static const uint8_t p_cc_replaytv4a[2] = { 0xbb, 0x02 };/* RTV4K, BB02xxxxCC02 */
447
52
    static const uint8_t p_cc_replaytv4b[2] = { 0xcc, 0x02 };/* see DVR-ClosedCaption in samples */
448
52
    static const uint8_t p_cc_replaytv5a[2] = { 0x99, 0x02 };/* RTV5K, 9902xxxxAA02 */
449
52
    static const uint8_t p_cc_replaytv5b[2] = { 0xaa, 0x02 };/* see DVR-ClosedCaption in samples */
450
52
    static const uint8_t p_cc_scte20[2] = { 0x03, 0x81 };    /* user_data_type_code, SCTE 20 */
451
52
    static const uint8_t p_cc_scte20_old[2] = { 0x03, 0x01 };/* user_data_type_code, old, Note 1 */
452
453
52
    if( i_src < 4 )
454
0
        return;
455
456
52
    enum cc_payload_type_e i_payload_type;
457
52
    if( !memcmp( p_cc_ga94, p_src, 4 ) && i_src >= 5+1+1+1 && p_src[4] == 0x03 )
458
14
    {
459
        /* CC from DVB/ATSC TS */
460
14
        i_payload_type = CC_PAYLOAD_GA94;
461
14
        i_src -= 5;
462
14
        p_src += 5;
463
14
    }
464
38
    else if( !memcmp( p_cc_dvd, p_src, 4 ) && i_src > 4+1 )
465
0
    {
466
0
        i_payload_type = CC_PAYLOAD_DVD;
467
0
    }
468
38
    else if( i_src >= 2+2 + 2+2 &&
469
38
             ( ( !memcmp( p_cc_replaytv4a, &p_src[0], 2 ) && !memcmp( p_cc_replaytv4b, &p_src[4], 2 ) ) ||
470
20
               ( !memcmp( p_cc_replaytv5a, &p_src[0], 2 ) && !memcmp( p_cc_replaytv5b, &p_src[4], 2 ) ) ) )
471
0
    {
472
0
        i_payload_type = CC_PAYLOAD_REPLAYTV;
473
0
    }
474
38
    else if( ( !memcmp( p_cc_scte20, p_src, 2 ) ||
475
38
               !memcmp( p_cc_scte20_old, p_src, 2 ) ) && i_src > 2 )
476
0
    {
477
0
        i_payload_type = CC_PAYLOAD_SCTE20;
478
0
    }
479
38
    else if (p_src[0] == 0x03 && p_src[1] == i_src - 2) /* DIRECTV */
480
0
    {
481
0
        i_payload_type = CC_PAYLOAD_GA94;
482
0
        i_src -= 2;
483
0
        p_src += 2;
484
0
    }
485
38
    else if (p_src[0] == 0x96 && p_src[1] == 0x69) /* CDP */
486
0
    {
487
0
        i_payload_type = CC_PAYLOAD_CDP;
488
0
    }
489
38
    else
490
38
    {
491
#if 0
492
#define V(x) ( ( x < 0x20 || x >= 0x7f ) ? '?' : x )
493
        fprintf( stderr, "-------------- unknown user data " );
494
        for( int i = 0; i < i_src; i++ )
495
            fprintf( stderr, "%2.2x ", p_src[i] );
496
        for( int i = 0; i < i_src; i++ )
497
            fprintf( stderr, "%c ", V(p_src[i]) );
498
        fprintf( stderr, "\n" );
499
#undef V
500
#endif
501
38
        return;
502
38
    }
503
504
14
    cc_Extract( c, i_payload_type, b_top_field_first, p_src, i_src );
505
14
}
506
507
#endif /* _CC_H */
508