Coverage Report

Created: 2025-07-18 07:04

/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
0
#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
0
{
79
0
    c->i_608channels = 0;
80
0
    c->i_708channels = 0;
81
0
    c->i_data = 0;
82
0
    c->b_reorder = false;
83
0
    c->cea708.pktsize = 0;
84
0
    c->cea708.seq = 0;
85
0
    c->cea708.sid_bs = 0;
86
0
    c->cea708.state = CEA708_PKT_END;
87
0
    c->i_payload_type = CC_PAYLOAD_NONE;
88
0
    c->i_payload_other_count = 0;
89
0
}
Unexecuted instantiation: mp4.c:cc_Init
Unexecuted instantiation: ty.c:cc_Init
Unexecuted instantiation: hxxx_common.c:cc_Init
Unexecuted instantiation: mpegvideo.c:cc_Init
Unexecuted instantiation: vc1.c:cc_Init
90
static inline void cc_Exit( cc_data_t *c )
91
0
{
92
0
    VLC_UNUSED(c);
93
0
    return;
94
0
}
Unexecuted instantiation: mp4.c:cc_Exit
Unexecuted instantiation: ty.c:cc_Exit
Unexecuted instantiation: hxxx_common.c:cc_Exit
Unexecuted instantiation: mpegvideo.c:cc_Exit
Unexecuted instantiation: vc1.c:cc_Exit
95
static inline void cc_Flush( cc_data_t *c )
96
0
{
97
0
    c->i_data = 0;
98
0
    c->cea708.state = CEA708_PKT_END;
99
0
}
Unexecuted instantiation: mp4.c:cc_Flush
Unexecuted instantiation: ty.c:cc_Flush
Unexecuted instantiation: hxxx_common.c:cc_Flush
Unexecuted instantiation: mpegvideo.c:cc_Flush
Unexecuted instantiation: vc1.c:cc_Flush
100
101
static inline void cc_ProbeCEA708OneByte( cc_data_t *c, bool b_start, const uint8_t cc )
102
0
{
103
0
    if( b_start )
104
0
    {
105
0
        const uint8_t i_pkt_sequence = cc >> 6;
106
0
        if( i_pkt_sequence > 0 && ((c->cea708.seq + 1) % 4) != i_pkt_sequence )
107
0
        {
108
0
            c->cea708.pktsize = 0;
109
0
            c->cea708.seq = i_pkt_sequence;
110
0
            c->cea708.state = CEA708_PKT_END;
111
0
        }
112
0
        else
113
0
        {
114
0
            c->cea708.seq = i_pkt_sequence;
115
0
            c->cea708.pktsize = cc & 63;
116
0
            if( c->cea708.pktsize == 0 )
117
0
                c->cea708.pktsize = 127;
118
0
            else
119
0
                c->cea708.pktsize = c->cea708.pktsize * 2 - 1;
120
0
            c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
121
0
        }
122
0
    }
123
0
    else if( c->cea708.pktsize == 0 ) /* empty pkt reading service blocks */
124
0
    {
125
0
        c->cea708.state = CEA708_PKT_END;
126
0
    }
127
0
    else if( c->cea708.state != CEA708_PKT_END )
128
0
    {
129
0
        switch( c->cea708.state )
130
0
        {
131
0
            case CEA708_PKT_WAIT_BLOCK_HEADER: /* Byte is service block header */
132
0
            {
133
0
                uint8_t i_sid = cc >> 5;
134
0
                c->cea708.sid_bs = cc & 0x1F;
135
0
                if( i_sid != 0x00 && c->cea708.sid_bs != 0 )
136
0
                {
137
0
                    if( i_sid != 0x07 )
138
0
                    {
139
0
                        const uint8_t mask = (1 << --i_sid);
140
0
                        c->i_708channels |= (mask + (mask - 1));
141
0
                        c->cea708.state = CEA708_PKT_IN_BLOCK;
142
0
                    }
143
0
                    else if( c->cea708.sid_bs < 2 )
144
0
                    {
145
0
                        c->cea708.state = CEA708_PKT_END;
146
0
                    }
147
0
                    else
148
0
                    {
149
                        /* need to look up next byte in next pkt */
150
0
                        c->cea708.state = CEA708_PKT_WAIT_EXT_BLOCK_HEADER;
151
0
                    }
152
0
                }
153
0
                else c->cea708.state = CEA708_PKT_END;
154
0
            } break;
155
156
0
            case CEA708_PKT_WAIT_EXT_BLOCK_HEADER:
157
0
            {
158
0
                uint8_t i_extsid = cc & 0x3F;
159
0
                if( i_extsid >= 0x07 )
160
0
                {
161
0
                    const uint8_t mask = (1 << --i_extsid);
162
0
                    c->i_708channels |= (mask + (mask - 1));
163
0
                }
164
0
                if( c->cea708.sid_bs == 0 )
165
0
                    c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
166
0
                else
167
0
                    c->cea708.state = CEA708_PKT_IN_BLOCK;
168
0
            } break;
169
170
0
            case CEA708_PKT_IN_BLOCK:
171
0
            {
172
0
                c->cea708.sid_bs--;
173
0
                if( c->cea708.sid_bs == 0 )
174
0
                    c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
175
0
            } break;
176
177
0
            default:
178
0
                vlc_assert_unreachable();
179
0
                break;
180
0
        }
181
0
        c->cea708.pktsize--;
182
183
0
        if(c->cea708.pktsize == 0)
184
0
            c->cea708.state = CEA708_PKT_END;
185
0
    }
186
0
}
Unexecuted instantiation: mp4.c:cc_ProbeCEA708OneByte
Unexecuted instantiation: ty.c:cc_ProbeCEA708OneByte
Unexecuted instantiation: hxxx_common.c:cc_ProbeCEA708OneByte
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
0
{
190
0
    if( i_field == 3 ) /* DTVCC_PACKET_START */
191
0
        cc_ProbeCEA708OneByte( c, true,  cc[0] );
192
0
    else /* DTVCC_PACKET_DATA */
193
0
        cc_ProbeCEA708OneByte( c, false, cc[0] );
194
0
    cc_ProbeCEA708OneByte( c, false, cc[1] );
195
0
}
Unexecuted instantiation: mp4.c:cc_ProbeCEA708
Unexecuted instantiation: ty.c:cc_ProbeCEA708
Unexecuted instantiation: hxxx_common.c:cc_ProbeCEA708
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
0
{
199
0
    if (c->i_data + 3 > ARRAY_SIZE(c->p_data))
200
0
        return false;
201
202
0
    const uint8_t i_field = cc_preamble & 0x03;
203
0
    if( i_field == 0 || i_field == 1 ) /* NTSC_CC_FIELD_1 NTSC_CC_FIELD_2 */
204
0
    {
205
0
        c->i_608channels |= (3 << (2 * i_field));
206
0
    }
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
0
    c->p_data[c->i_data++] = cc_preamble;
215
0
    c->p_data[c->i_data++] = cc[0];
216
0
    c->p_data[c->i_data++] = cc[1];
217
0
    return true;
218
0
}
Unexecuted instantiation: mp4.c:cc_AppendData
Unexecuted instantiation: ty.c:cc_AppendData
Unexecuted instantiation: hxxx_common.c:cc_AppendData
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
0
{
223
0
    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
0
    c->i_payload_type        = i_payload_type;
230
0
    c->i_payload_other_count = 0;
231
232
0
    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
0
    else if( i_payload_type == CC_PAYLOAD_GA94 )
243
0
    {
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
0
        const uint8_t *cc = &p_src[0];
265
0
        const int i_count_cc = cc[0]&0x1f;
266
0
        int i;
267
268
0
        if( !(cc[0]&0x40) ) // process flag
269
0
            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
0
}
Unexecuted instantiation: mp4.c:cc_Extract
Unexecuted instantiation: ty.c:cc_Extract
Unexecuted instantiation: hxxx_common.c:cc_Extract
Unexecuted instantiation: mpegvideo.c:cc_Extract
Unexecuted instantiation: vc1.c:cc_Extract
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
0
{
444
0
    static const uint8_t p_cc_ga94[4] = { 0x47, 0x41, 0x39, 0x34 };
445
0
    static const uint8_t p_cc_dvd[4] = { 0x43, 0x43, 0x01, 0xf8 }; /* ascii 'CC', type_code, cc_block_size */
446
0
    static const uint8_t p_cc_replaytv4a[2] = { 0xbb, 0x02 };/* RTV4K, BB02xxxxCC02 */
447
0
    static const uint8_t p_cc_replaytv4b[2] = { 0xcc, 0x02 };/* see DVR-ClosedCaption in samples */
448
0
    static const uint8_t p_cc_replaytv5a[2] = { 0x99, 0x02 };/* RTV5K, 9902xxxxAA02 */
449
0
    static const uint8_t p_cc_replaytv5b[2] = { 0xaa, 0x02 };/* see DVR-ClosedCaption in samples */
450
0
    static const uint8_t p_cc_scte20[2] = { 0x03, 0x81 };    /* user_data_type_code, SCTE 20 */
451
0
    static const uint8_t p_cc_scte20_old[2] = { 0x03, 0x01 };/* user_data_type_code, old, Note 1 */
452
453
0
    if( i_src < 4 )
454
0
        return;
455
456
0
    enum cc_payload_type_e i_payload_type;
457
0
    if( !memcmp( p_cc_ga94, p_src, 4 ) && i_src >= 5+1+1+1 && p_src[4] == 0x03 )
458
0
    {
459
        /* CC from DVB/ATSC TS */
460
0
        i_payload_type = CC_PAYLOAD_GA94;
461
0
        i_src -= 5;
462
0
        p_src += 5;
463
0
    }
464
0
    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
0
    else if( i_src >= 2+2 + 2+2 &&
469
0
             ( ( !memcmp( p_cc_replaytv4a, &p_src[0], 2 ) && !memcmp( p_cc_replaytv4b, &p_src[4], 2 ) ) ||
470
0
               ( !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
0
    else if( ( !memcmp( p_cc_scte20, p_src, 2 ) ||
475
0
               !memcmp( p_cc_scte20_old, p_src, 2 ) ) && i_src > 2 )
476
0
    {
477
0
        i_payload_type = CC_PAYLOAD_SCTE20;
478
0
    }
479
0
    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
0
    else if (p_src[0] == 0x96 && p_src[1] == 0x69) /* CDP */
486
0
    {
487
0
        i_payload_type = CC_PAYLOAD_CDP;
488
0
    }
489
0
    else
490
0
    {
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
0
        return;
502
0
    }
503
504
0
    cc_Extract( c, i_payload_type, b_top_field_first, p_src, i_src );
505
0
}
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
Unexecuted instantiation: vc1.c:cc_ProbeAndExtract
506
507
#endif /* _CC_H */
508