Coverage Report

Created: 2025-11-14 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/modules/codec/cc.h
Line
Count
Source
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
15.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
61.4k
{
79
61.4k
    c->i_608channels = 0;
80
61.4k
    c->i_708channels = 0;
81
61.4k
    c->i_data = 0;
82
61.4k
    c->b_reorder = false;
83
61.4k
    c->cea708.pktsize = 0;
84
61.4k
    c->cea708.seq = 0;
85
61.4k
    c->cea708.sid_bs = 0;
86
61.4k
    c->cea708.state = CEA708_PKT_END;
87
61.4k
    c->i_payload_type = CC_PAYLOAD_NONE;
88
61.4k
    c->i_payload_other_count = 0;
89
61.4k
}
Unexecuted instantiation: mp4.c:cc_Init
ty.c:cc_Init
Line
Count
Source
78
366
{
79
366
    c->i_608channels = 0;
80
366
    c->i_708channels = 0;
81
366
    c->i_data = 0;
82
    c->b_reorder = false;
83
366
    c->cea708.pktsize = 0;
84
366
    c->cea708.seq = 0;
85
366
    c->cea708.sid_bs = 0;
86
366
    c->cea708.state = CEA708_PKT_END;
87
366
    c->i_payload_type = CC_PAYLOAD_NONE;
88
366
    c->i_payload_other_count = 0;
89
366
}
hxxx_common.c:cc_Init
Line
Count
Source
78
55.7k
{
79
55.7k
    c->i_608channels = 0;
80
55.7k
    c->i_708channels = 0;
81
55.7k
    c->i_data = 0;
82
    c->b_reorder = false;
83
55.7k
    c->cea708.pktsize = 0;
84
55.7k
    c->cea708.seq = 0;
85
55.7k
    c->cea708.sid_bs = 0;
86
55.7k
    c->cea708.state = CEA708_PKT_END;
87
55.7k
    c->i_payload_type = CC_PAYLOAD_NONE;
88
55.7k
    c->i_payload_other_count = 0;
89
55.7k
}
mpegvideo.c:cc_Init
Line
Count
Source
78
3.84k
{
79
3.84k
    c->i_608channels = 0;
80
3.84k
    c->i_708channels = 0;
81
3.84k
    c->i_data = 0;
82
    c->b_reorder = false;
83
3.84k
    c->cea708.pktsize = 0;
84
3.84k
    c->cea708.seq = 0;
85
3.84k
    c->cea708.sid_bs = 0;
86
3.84k
    c->cea708.state = CEA708_PKT_END;
87
3.84k
    c->i_payload_type = CC_PAYLOAD_NONE;
88
3.84k
    c->i_payload_other_count = 0;
89
3.84k
}
vc1.c:cc_Init
Line
Count
Source
78
1.55k
{
79
1.55k
    c->i_608channels = 0;
80
1.55k
    c->i_708channels = 0;
81
1.55k
    c->i_data = 0;
82
    c->b_reorder = false;
83
1.55k
    c->cea708.pktsize = 0;
84
1.55k
    c->cea708.seq = 0;
85
1.55k
    c->cea708.sid_bs = 0;
86
1.55k
    c->cea708.state = CEA708_PKT_END;
87
1.55k
    c->i_payload_type = CC_PAYLOAD_NONE;
88
1.55k
    c->i_payload_other_count = 0;
89
1.55k
}
90
static inline void cc_Exit( cc_data_t *c )
91
57.6k
{
92
57.6k
    VLC_UNUSED(c);
93
57.6k
    return;
94
57.6k
}
Unexecuted instantiation: mp4.c:cc_Exit
ty.c:cc_Exit
Line
Count
Source
91
366
{
92
366
    VLC_UNUSED(c);
93
366
    return;
94
366
}
hxxx_common.c:cc_Exit
Line
Count
Source
91
55.7k
{
92
55.7k
    VLC_UNUSED(c);
93
55.7k
    return;
94
55.7k
}
Unexecuted instantiation: mpegvideo.c:cc_Exit
vc1.c:cc_Exit
Line
Count
Source
91
1.55k
{
92
1.55k
    VLC_UNUSED(c);
93
1.55k
    return;
94
1.55k
}
95
static inline void cc_Flush( cc_data_t *c )
96
1.00M
{
97
1.00M
    c->i_data = 0;
98
1.00M
    c->cea708.state = CEA708_PKT_END;
99
1.00M
}
Unexecuted instantiation: mp4.c:cc_Flush
ty.c:cc_Flush
Line
Count
Source
96
1.02k
{
97
1.02k
    c->i_data = 0;
98
1.02k
    c->cea708.state = CEA708_PKT_END;
99
1.02k
}
hxxx_common.c:cc_Flush
Line
Count
Source
96
1.00M
{
97
1.00M
    c->i_data = 0;
98
1.00M
    c->cea708.state = CEA708_PKT_END;
99
1.00M
}
Unexecuted instantiation: mpegvideo.c:cc_Flush
vc1.c:cc_Flush
Line
Count
Source
96
1.28k
{
97
1.28k
    c->i_data = 0;
98
1.28k
    c->cea708.state = CEA708_PKT_END;
99
1.28k
}
100
101
static inline void cc_ProbeCEA708OneByte( cc_data_t *c, bool b_start, const uint8_t cc )
102
125k
{
103
125k
    if( b_start )
104
31.2k
    {
105
31.2k
        const uint8_t i_pkt_sequence = cc >> 6;
106
31.2k
        if( i_pkt_sequence > 0 && ((c->cea708.seq + 1) % 4) != i_pkt_sequence )
107
16.2k
        {
108
16.2k
            c->cea708.pktsize = 0;
109
16.2k
            c->cea708.seq = i_pkt_sequence;
110
16.2k
            c->cea708.state = CEA708_PKT_END;
111
16.2k
        }
112
15.0k
        else
113
15.0k
        {
114
15.0k
            c->cea708.seq = i_pkt_sequence;
115
15.0k
            c->cea708.pktsize = cc & 63;
116
15.0k
            if( c->cea708.pktsize == 0 )
117
5.86k
                c->cea708.pktsize = 127;
118
9.15k
            else
119
9.15k
                c->cea708.pktsize = c->cea708.pktsize * 2 - 1;
120
15.0k
            c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
121
15.0k
        }
122
31.2k
    }
123
94.1k
    else if( c->cea708.pktsize == 0 ) /* empty pkt reading service blocks */
124
46.2k
    {
125
46.2k
        c->cea708.state = CEA708_PKT_END;
126
46.2k
    }
127
47.9k
    else if( c->cea708.state != CEA708_PKT_END )
128
41.3k
    {
129
41.3k
        switch( c->cea708.state )
130
41.3k
        {
131
17.8k
            case CEA708_PKT_WAIT_BLOCK_HEADER: /* Byte is service block header */
132
17.8k
            {
133
17.8k
                uint8_t i_sid = cc >> 5;
134
17.8k
                c->cea708.sid_bs = cc & 0x1F;
135
17.8k
                if( i_sid != 0x00 && c->cea708.sid_bs != 0 )
136
12.5k
                {
137
12.5k
                    if( i_sid != 0x07 )
138
7.57k
                    {
139
7.57k
                        const uint8_t mask = (1 << --i_sid);
140
7.57k
                        c->i_708channels |= (mask + (mask - 1));
141
7.57k
                        c->cea708.state = CEA708_PKT_IN_BLOCK;
142
7.57k
                    }
143
4.98k
                    else if( c->cea708.sid_bs < 2 )
144
594
                    {
145
594
                        c->cea708.state = CEA708_PKT_END;
146
594
                    }
147
4.38k
                    else
148
4.38k
                    {
149
                        /* need to look up next byte in next pkt */
150
4.38k
                        c->cea708.state = CEA708_PKT_WAIT_EXT_BLOCK_HEADER;
151
4.38k
                    }
152
12.5k
                }
153
5.33k
                else c->cea708.state = CEA708_PKT_END;
154
17.8k
            } break;
155
156
2.31k
            case CEA708_PKT_WAIT_EXT_BLOCK_HEADER:
157
2.31k
            {
158
2.31k
                uint8_t i_extsid = cc & 0x3F;
159
2.31k
                if( i_extsid >= 0x07 )
160
1.00k
                {
161
1.00k
                    const uint64_t mask = (INT64_C(1) << --i_extsid);
162
1.00k
                    c->i_708channels |= (mask + (mask - 1));
163
1.00k
                }
164
2.31k
                if( c->cea708.sid_bs == 0 )
165
0
                    c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
166
2.31k
                else
167
2.31k
                    c->cea708.state = CEA708_PKT_IN_BLOCK;
168
2.31k
            } break;
169
170
21.1k
            case CEA708_PKT_IN_BLOCK:
171
21.1k
            {
172
21.1k
                c->cea708.sid_bs--;
173
21.1k
                if( c->cea708.sid_bs == 0 )
174
4.01k
                    c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
175
21.1k
            } break;
176
177
0
            default:
178
0
                vlc_assert_unreachable();
179
0
                break;
180
41.3k
        }
181
41.3k
        c->cea708.pktsize--;
182
183
41.3k
        if(c->cea708.pktsize == 0)
184
852
            c->cea708.state = CEA708_PKT_END;
185
41.3k
    }
186
125k
}
Unexecuted instantiation: mp4.c:cc_ProbeCEA708OneByte
Unexecuted instantiation: ty.c:cc_ProbeCEA708OneByte
hxxx_common.c:cc_ProbeCEA708OneByte
Line
Count
Source
102
125k
{
103
125k
    if( b_start )
104
31.2k
    {
105
31.2k
        const uint8_t i_pkt_sequence = cc >> 6;
106
31.2k
        if( i_pkt_sequence > 0 && ((c->cea708.seq + 1) % 4) != i_pkt_sequence )
107
16.2k
        {
108
16.2k
            c->cea708.pktsize = 0;
109
16.2k
            c->cea708.seq = i_pkt_sequence;
110
16.2k
            c->cea708.state = CEA708_PKT_END;
111
16.2k
        }
112
15.0k
        else
113
15.0k
        {
114
15.0k
            c->cea708.seq = i_pkt_sequence;
115
15.0k
            c->cea708.pktsize = cc & 63;
116
15.0k
            if( c->cea708.pktsize == 0 )
117
5.86k
                c->cea708.pktsize = 127;
118
9.15k
            else
119
9.15k
                c->cea708.pktsize = c->cea708.pktsize * 2 - 1;
120
15.0k
            c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
121
15.0k
        }
122
31.2k
    }
123
94.1k
    else if( c->cea708.pktsize == 0 ) /* empty pkt reading service blocks */
124
46.2k
    {
125
46.2k
        c->cea708.state = CEA708_PKT_END;
126
46.2k
    }
127
47.9k
    else if( c->cea708.state != CEA708_PKT_END )
128
41.3k
    {
129
41.3k
        switch( c->cea708.state )
130
41.3k
        {
131
17.8k
            case CEA708_PKT_WAIT_BLOCK_HEADER: /* Byte is service block header */
132
17.8k
            {
133
17.8k
                uint8_t i_sid = cc >> 5;
134
17.8k
                c->cea708.sid_bs = cc & 0x1F;
135
17.8k
                if( i_sid != 0x00 && c->cea708.sid_bs != 0 )
136
12.5k
                {
137
12.5k
                    if( i_sid != 0x07 )
138
7.57k
                    {
139
7.57k
                        const uint8_t mask = (1 << --i_sid);
140
7.57k
                        c->i_708channels |= (mask + (mask - 1));
141
7.57k
                        c->cea708.state = CEA708_PKT_IN_BLOCK;
142
7.57k
                    }
143
4.98k
                    else if( c->cea708.sid_bs < 2 )
144
594
                    {
145
594
                        c->cea708.state = CEA708_PKT_END;
146
594
                    }
147
4.38k
                    else
148
4.38k
                    {
149
                        /* need to look up next byte in next pkt */
150
4.38k
                        c->cea708.state = CEA708_PKT_WAIT_EXT_BLOCK_HEADER;
151
4.38k
                    }
152
12.5k
                }
153
5.33k
                else c->cea708.state = CEA708_PKT_END;
154
17.8k
            } break;
155
156
2.31k
            case CEA708_PKT_WAIT_EXT_BLOCK_HEADER:
157
2.31k
            {
158
2.31k
                uint8_t i_extsid = cc & 0x3F;
159
2.31k
                if( i_extsid >= 0x07 )
160
1.00k
                {
161
1.00k
                    const uint64_t mask = (INT64_C(1) << --i_extsid);
162
1.00k
                    c->i_708channels |= (mask + (mask - 1));
163
1.00k
                }
164
2.31k
                if( c->cea708.sid_bs == 0 )
165
0
                    c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
166
2.31k
                else
167
2.31k
                    c->cea708.state = CEA708_PKT_IN_BLOCK;
168
2.31k
            } break;
169
170
21.1k
            case CEA708_PKT_IN_BLOCK:
171
21.1k
            {
172
21.1k
                c->cea708.sid_bs--;
173
21.1k
                if( c->cea708.sid_bs == 0 )
174
4.01k
                    c->cea708.state = CEA708_PKT_WAIT_BLOCK_HEADER;
175
21.1k
            } break;
176
177
0
            default:
178
0
                vlc_assert_unreachable();
179
0
                break;
180
41.3k
        }
181
41.3k
        c->cea708.pktsize--;
182
183
41.3k
        if(c->cea708.pktsize == 0)
184
852
            c->cea708.state = CEA708_PKT_END;
185
41.3k
    }
186
125k
}
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
62.7k
{
190
62.7k
    if( i_field == 3 ) /* DTVCC_PACKET_START */
191
31.2k
        cc_ProbeCEA708OneByte( c, true,  cc[0] );
192
31.4k
    else /* DTVCC_PACKET_DATA */
193
31.4k
        cc_ProbeCEA708OneByte( c, false, cc[0] );
194
62.7k
    cc_ProbeCEA708OneByte( c, false, cc[1] );
195
62.7k
}
Unexecuted instantiation: mp4.c:cc_ProbeCEA708
Unexecuted instantiation: ty.c:cc_ProbeCEA708
hxxx_common.c:cc_ProbeCEA708
Line
Count
Source
189
62.7k
{
190
62.7k
    if( i_field == 3 ) /* DTVCC_PACKET_START */
191
31.2k
        cc_ProbeCEA708OneByte( c, true,  cc[0] );
192
31.4k
    else /* DTVCC_PACKET_DATA */
193
31.4k
        cc_ProbeCEA708OneByte( c, false, cc[0] );
194
    cc_ProbeCEA708OneByte( c, false, cc[1] );
195
62.7k
}
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
91.5k
{
199
91.5k
    if (c->i_data + 3 > ARRAY_SIZE(c->p_data))
200
916
        return false;
201
202
90.6k
    const uint8_t i_field = cc_preamble & 0x03;
203
90.6k
    if( i_field == 0 || i_field == 1 ) /* NTSC_CC_FIELD_1 NTSC_CC_FIELD_2 */
204
27.9k
    {
205
27.9k
        c->i_608channels |= (3 << (2 * i_field));
206
27.9k
    }
207
62.7k
    else
208
62.7k
    {
209
62.7k
        cc_ProbeCEA708( c, i_field, cc );
210
        /* By default enable at least channel 1 */
211
62.7k
        c->i_708channels |= 1;
212
62.7k
    }
213
214
90.6k
    c->p_data[c->i_data++] = cc_preamble;
215
90.6k
    c->p_data[c->i_data++] = cc[0];
216
90.6k
    c->p_data[c->i_data++] = cc[1];
217
90.6k
    return true;
218
91.5k
}
Unexecuted instantiation: mp4.c:cc_AppendData
ty.c:cc_AppendData
Line
Count
Source
198
15.9k
{
199
15.9k
    if (c->i_data + 3 > ARRAY_SIZE(c->p_data))
200
0
        return false;
201
202
15.9k
    const uint8_t i_field = cc_preamble & 0x03;
203
15.9k
    if( i_field == 0 || i_field == 1 ) /* NTSC_CC_FIELD_1 NTSC_CC_FIELD_2 */
204
15.9k
    {
205
15.9k
        c->i_608channels |= (3 << (2 * i_field));
206
15.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
15.9k
    c->p_data[c->i_data++] = cc_preamble;
215
15.9k
    c->p_data[c->i_data++] = cc[0];
216
15.9k
    c->p_data[c->i_data++] = cc[1];
217
    return true;
218
15.9k
}
hxxx_common.c:cc_AppendData
Line
Count
Source
198
75.5k
{
199
75.5k
    if (c->i_data + 3 > ARRAY_SIZE(c->p_data))
200
916
        return false;
201
202
74.6k
    const uint8_t i_field = cc_preamble & 0x03;
203
74.6k
    if( i_field == 0 || i_field == 1 ) /* NTSC_CC_FIELD_1 NTSC_CC_FIELD_2 */
204
11.9k
    {
205
11.9k
        c->i_608channels |= (3 << (2 * i_field));
206
11.9k
    }
207
62.7k
    else
208
62.7k
    {
209
62.7k
        cc_ProbeCEA708( c, i_field, cc );
210
        /* By default enable at least channel 1 */
211
62.7k
        c->i_708channels |= 1;
212
62.7k
    }
213
214
74.6k
    c->p_data[c->i_data++] = cc_preamble;
215
74.6k
    c->p_data[c->i_data++] = cc[0];
216
74.6k
    c->p_data[c->i_data++] = cc[1];
217
    return true;
218
75.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
29.6k
{
223
29.6k
    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
29.6k
    c->i_payload_type        = i_payload_type;
230
29.6k
    c->i_payload_other_count = 0;
231
232
29.6k
    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
29.6k
    else if( i_payload_type == CC_PAYLOAD_GA94 )
243
29.6k
    {
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
29.6k
        if(i_src < 1)
265
693
            return;
266
28.9k
        const uint8_t *cc = &p_src[0];
267
28.9k
        const int i_count_cc = cc[0]&0x1f;
268
28.9k
        int i;
269
270
28.9k
        if( !(cc[0]&0x40) ) // process flag
271
1.28k
            return;
272
27.6k
        if( i_src < 1+1 + i_count_cc*3 + 1)  // broken packet
273
991
            return;
274
26.7k
        if( i_count_cc <= 0 )   // no cc present
275
487
            return;
276
26.2k
        if( cc[2+i_count_cc * 3] != 0xff )  // marker absent
277
1.84k
            return;
278
24.3k
        cc += 2;
279
280
99.0k
        for( i = 0; i < i_count_cc; i++, cc += 3 )
281
75.5k
        {
282
75.5k
            if (!cc_AppendData( c, cc[0], &cc[1] ))
283
916
                break;
284
75.5k
        }
285
24.3k
        c->b_reorder = true;
286
24.3k
    }
287
0
    else if( i_payload_type == CC_PAYLOAD_DVD )
288
0
    {
289
        /* user_data
290
         *          (u32 stripped earlier)
291
         *          u32 (0x43 0x43 0x01 0xf8)
292
         *          u1 caption_odd_field_first (CC1/CC2)
293
         *          u1 caption_filler
294
         *          u5 cc_block_count  (== cc_count / 2)
295
         *          u1 caption_extra_field_added (because odd cc_count)
296
         *          for cc_block_count * 2 + caption_extra_field_added
297
         *              u7 cc_filler_1
298
         *              u1 cc_field_is_odd
299
         *              u8 cc_data_1
300
         *              u8 cc_data_2
301
         */
302
0
        if(i_src < 6)
303
0
            return;
304
0
        const int b_truncate = p_src[4] & 0x01;
305
0
        const int i_count_cc2 = ((p_src[4] >> 1) & 0x1f);
306
0
        const uint8_t *cc = &p_src[5];
307
0
        i_src -= 5;
308
0
        int i;
309
310
0
#define CC_ALIGNMENT_TEST   (0x7f)
311
312
0
        for( i = 0; i < 2*i_count_cc2 + b_truncate && i_src >= 3; i++, cc+=3 )
313
0
        {
314
0
            if( (cc[0] >> 1) == CC_ALIGNMENT_TEST )
315
0
            {
316
0
                const bool even_field = (cc[0] & 0x01) ? 0 : 1;
317
0
                if (!cc_AppendData( c, CC_PKT_BYTE0(even_field), &cc[1] ))
318
0
                    break;
319
0
            }
320
0
            i_src -= 3;
321
0
        }
322
0
        c->b_reorder = false;
323
0
    }
324
0
    else if( i_payload_type == CC_PAYLOAD_REPLAYTV )
325
0
    {
326
0
        if(i_src < 1)
327
0
            return;
328
0
        const uint8_t *cc = &p_src[0];
329
0
        for( int i_cc_count = i_src >> 2; i_cc_count > 0;
330
0
             i_cc_count--, cc += 4 )
331
0
        {
332
0
            uint8_t i_field = (cc[0] & 0x02) >> 1;
333
0
            if (!cc_AppendData( c, CC_PKT_BYTE0(i_field), &cc[2] ))
334
0
                return;
335
0
        }
336
0
        c->b_reorder = false;
337
0
    }
338
0
    else if( i_payload_type == CC_PAYLOAD_SCTE20 )
339
0
    {
340
        /* user_data(2)
341
         *          (u32 stripped earlier)
342
         *          u16 p_cc_scte20
343
         *          u5 cc_count
344
         *          for cc_count
345
         *              u2 cc_priority
346
         *              u2 cc_field_num
347
         *              u5 cc_line_offset
348
         *              u8 cc_data_1[1:8]
349
         *              u8 cc_data_2[1:8]
350
         *              u1 marker bit
351
         *          un additional_realtimevideodata
352
         *          un reserved
353
         */
354
0
        if(i_src < 2)
355
0
            return;
356
0
        bs_t s;
357
0
        bs_init( &s, &p_src[2], i_src - 2 );
358
0
        const int i_cc_count = bs_read( &s, 5 );
359
0
        for( int i = 0; i < i_cc_count; i++ )
360
0
        {
361
0
            bs_skip( &s, 2 );
362
0
            const int i_field_idx = bs_read( &s, 2 );
363
0
            bs_skip( &s, 5 );
364
0
            uint8_t cc[2];
365
0
            for( int j = 0; j < 2; j++ )
366
0
            {
367
0
                cc[j] = 0;
368
0
                for( int k = 0; k < 8; k++ )
369
0
                    cc[j] |= bs_read( &s, 1 ) << k;
370
0
            }
371
0
            bs_skip( &s, 1 );
372
373
0
            if( i_field_idx == 0 )
374
0
                continue;
375
376
            /* 1,2,3 -> 0,1,0. I.E. repeated field 3 is merged with field 1 */
377
0
            int i_field = ((i_field_idx - 1) & 1);
378
0
            if (!b_top_field_first)
379
0
                i_field ^= 1;
380
381
0
            if (!cc_AppendData( c, CC_PKT_BYTE0(i_field), &cc[0] ))
382
0
                continue;
383
0
        }
384
0
        c->b_reorder = true;
385
0
    }
386
0
    else // CC_PAYLOAD_CDP
387
0
    {
388
0
#       define CDP_FLAG_TIME_CODE_PRESENT  (1<<7)
389
0
#       define CDP_FLAG_CC_DATA_PRESENT    (1<<6)
390
0
#       define CDP_FLAG_SVC_INFO_PRESENT   (1<<5)
391
0
#       define CDP_FLAG_SVC_INFO_START     (1<<4)
392
0
#       define CDP_FLAG_SVC_INFO_CHANGE    (1<<3)
393
0
#       define CDP_FLAG_SVC_INFO_COMPLETE  (1<<2)
394
0
#       define CDP_FLAG_CAPTION_SVC_ACTIVE (1<<1)
395
396
0
        if(i_src < 7)
397
0
            return;
398
399
        /* ST334-2 5.2 cdp_header() */
400
0
        uint8_t cdp_length = p_src[2];
401
0
        if(cdp_length < 8 || cdp_length > i_src)
402
0
            return;
403
0
        uint8_t cdp_flags = p_src[4];
404
405
        /* skip header */
406
0
        p_src += 7; i_src -= 7;
407
408
        /* 5.3 time_code_section() */
409
0
        if( cdp_flags & CDP_FLAG_TIME_CODE_PRESENT )
410
0
        {
411
0
            if( i_src < 5 ) // Shall be 5 bytes
412
0
                return;
413
0
            p_src += 5; i_src += 5;
414
0
        }
415
        /* 5.4 ccdata_section */
416
0
        if( cdp_flags & CDP_FLAG_CC_DATA_PRESENT )
417
0
        {
418
            /* ccdata_section()
419
             *      u8 0x72
420
             *      u3 marker bits(111)
421
             *      u5 cc_count
422
             *      for cc_count
423
             *          u5 marker bits(1111 1)
424
             *          u1 cc_valid
425
             *          u2 cc_type
426
             *          u8 cc_data_1
427
             *          u8 cc_data_2
428
             */
429
0
            if( i_src < 2 || p_src[0] != 0x72 ) // marker
430
0
                return;
431
432
0
            const uint8_t *cc = &p_src[1];
433
0
            const int i_count_cc = cc[0]&0x1f;
434
435
0
            if( i_src - 2 < i_count_cc*3 )  // broken packet
436
0
                return;
437
0
            cc += 1;
438
0
            for( int i = 0; i < i_count_cc; i++, cc += 3 )
439
0
            {
440
0
                if (!cc_AppendData( c, cc[0], &cc[1] ))
441
0
                    break;
442
0
            }
443
0
        }
444
        /* remaining data */
445
0
        c->b_reorder = false;
446
0
    }
447
29.6k
}
Unexecuted instantiation: mp4.c:cc_Extract
Unexecuted instantiation: ty.c:cc_Extract
hxxx_common.c:cc_Extract
Line
Count
Source
222
29.6k
{
223
29.6k
    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
29.6k
    c->i_payload_type        = i_payload_type;
230
29.6k
    c->i_payload_other_count = 0;
231
232
29.6k
    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
29.6k
    else if( i_payload_type == CC_PAYLOAD_GA94 )
243
29.6k
    {
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
29.6k
        if(i_src < 1)
265
693
            return;
266
28.9k
        const uint8_t *cc = &p_src[0];
267
28.9k
        const int i_count_cc = cc[0]&0x1f;
268
28.9k
        int i;
269
270
28.9k
        if( !(cc[0]&0x40) ) // process flag
271
1.26k
            return;
272
27.6k
        if( i_src < 1+1 + i_count_cc*3 + 1)  // broken packet
273
991
            return;
274
26.7k
        if( i_count_cc <= 0 )   // no cc present
275
487
            return;
276
26.2k
        if( cc[2+i_count_cc * 3] != 0xff )  // marker absent
277
1.83k
            return;
278
24.3k
        cc += 2;
279
280
99.0k
        for( i = 0; i < i_count_cc; i++, cc += 3 )
281
75.5k
        {
282
75.5k
            if (!cc_AppendData( c, cc[0], &cc[1] ))
283
916
                break;
284
75.5k
        }
285
24.3k
        c->b_reorder = true;
286
24.3k
    }
287
0
    else if( i_payload_type == CC_PAYLOAD_DVD )
288
0
    {
289
        /* user_data
290
         *          (u32 stripped earlier)
291
         *          u32 (0x43 0x43 0x01 0xf8)
292
         *          u1 caption_odd_field_first (CC1/CC2)
293
         *          u1 caption_filler
294
         *          u5 cc_block_count  (== cc_count / 2)
295
         *          u1 caption_extra_field_added (because odd cc_count)
296
         *          for cc_block_count * 2 + caption_extra_field_added
297
         *              u7 cc_filler_1
298
         *              u1 cc_field_is_odd
299
         *              u8 cc_data_1
300
         *              u8 cc_data_2
301
         */
302
0
        if(i_src < 6)
303
0
            return;
304
0
        const int b_truncate = p_src[4] & 0x01;
305
0
        const int i_count_cc2 = ((p_src[4] >> 1) & 0x1f);
306
0
        const uint8_t *cc = &p_src[5];
307
0
        i_src -= 5;
308
0
        int i;
309
310
0
#define CC_ALIGNMENT_TEST   (0x7f)
311
312
0
        for( i = 0; i < 2*i_count_cc2 + b_truncate && i_src >= 3; i++, cc+=3 )
313
0
        {
314
0
            if( (cc[0] >> 1) == CC_ALIGNMENT_TEST )
315
0
            {
316
0
                const bool even_field = (cc[0] & 0x01) ? 0 : 1;
317
0
                if (!cc_AppendData( c, CC_PKT_BYTE0(even_field), &cc[1] ))
318
0
                    break;
319
0
            }
320
0
            i_src -= 3;
321
0
        }
322
0
        c->b_reorder = false;
323
0
    }
324
0
    else if( i_payload_type == CC_PAYLOAD_REPLAYTV )
325
0
    {
326
0
        if(i_src < 1)
327
0
            return;
328
0
        const uint8_t *cc = &p_src[0];
329
0
        for( int i_cc_count = i_src >> 2; i_cc_count > 0;
330
0
             i_cc_count--, cc += 4 )
331
0
        {
332
0
            uint8_t i_field = (cc[0] & 0x02) >> 1;
333
0
            if (!cc_AppendData( c, CC_PKT_BYTE0(i_field), &cc[2] ))
334
0
                return;
335
0
        }
336
0
        c->b_reorder = false;
337
0
    }
338
0
    else if( i_payload_type == CC_PAYLOAD_SCTE20 )
339
0
    {
340
        /* user_data(2)
341
         *          (u32 stripped earlier)
342
         *          u16 p_cc_scte20
343
         *          u5 cc_count
344
         *          for cc_count
345
         *              u2 cc_priority
346
         *              u2 cc_field_num
347
         *              u5 cc_line_offset
348
         *              u8 cc_data_1[1:8]
349
         *              u8 cc_data_2[1:8]
350
         *              u1 marker bit
351
         *          un additional_realtimevideodata
352
         *          un reserved
353
         */
354
0
        if(i_src < 2)
355
0
            return;
356
0
        bs_t s;
357
0
        bs_init( &s, &p_src[2], i_src - 2 );
358
0
        const int i_cc_count = bs_read( &s, 5 );
359
0
        for( int i = 0; i < i_cc_count; i++ )
360
0
        {
361
0
            bs_skip( &s, 2 );
362
0
            const int i_field_idx = bs_read( &s, 2 );
363
0
            bs_skip( &s, 5 );
364
0
            uint8_t cc[2];
365
0
            for( int j = 0; j < 2; j++ )
366
0
            {
367
0
                cc[j] = 0;
368
0
                for( int k = 0; k < 8; k++ )
369
0
                    cc[j] |= bs_read( &s, 1 ) << k;
370
0
            }
371
0
            bs_skip( &s, 1 );
372
373
0
            if( i_field_idx == 0 )
374
0
                continue;
375
376
            /* 1,2,3 -> 0,1,0. I.E. repeated field 3 is merged with field 1 */
377
0
            int i_field = ((i_field_idx - 1) & 1);
378
0
            if (!b_top_field_first)
379
0
                i_field ^= 1;
380
381
0
            if (!cc_AppendData( c, CC_PKT_BYTE0(i_field), &cc[0] ))
382
0
                continue;
383
0
        }
384
0
        c->b_reorder = true;
385
0
    }
386
0
    else // CC_PAYLOAD_CDP
387
0
    {
388
0
#       define CDP_FLAG_TIME_CODE_PRESENT  (1<<7)
389
0
#       define CDP_FLAG_CC_DATA_PRESENT    (1<<6)
390
0
#       define CDP_FLAG_SVC_INFO_PRESENT   (1<<5)
391
0
#       define CDP_FLAG_SVC_INFO_START     (1<<4)
392
0
#       define CDP_FLAG_SVC_INFO_CHANGE    (1<<3)
393
0
#       define CDP_FLAG_SVC_INFO_COMPLETE  (1<<2)
394
0
#       define CDP_FLAG_CAPTION_SVC_ACTIVE (1<<1)
395
396
0
        if(i_src < 7)
397
0
            return;
398
399
        /* ST334-2 5.2 cdp_header() */
400
0
        uint8_t cdp_length = p_src[2];
401
0
        if(cdp_length < 8 || cdp_length > i_src)
402
0
            return;
403
0
        uint8_t cdp_flags = p_src[4];
404
405
        /* skip header */
406
0
        p_src += 7; i_src -= 7;
407
408
        /* 5.3 time_code_section() */
409
0
        if( cdp_flags & CDP_FLAG_TIME_CODE_PRESENT )
410
0
        {
411
0
            if( i_src < 5 ) // Shall be 5 bytes
412
0
                return;
413
0
            p_src += 5; i_src += 5;
414
0
        }
415
        /* 5.4 ccdata_section */
416
0
        if( cdp_flags & CDP_FLAG_CC_DATA_PRESENT )
417
0
        {
418
            /* ccdata_section()
419
             *      u8 0x72
420
             *      u3 marker bits(111)
421
             *      u5 cc_count
422
             *      for cc_count
423
             *          u5 marker bits(1111 1)
424
             *          u1 cc_valid
425
             *          u2 cc_type
426
             *          u8 cc_data_1
427
             *          u8 cc_data_2
428
             */
429
0
            if( i_src < 2 || p_src[0] != 0x72 ) // marker
430
0
                return;
431
432
0
            const uint8_t *cc = &p_src[1];
433
0
            const int i_count_cc = cc[0]&0x1f;
434
435
0
            if( i_src - 2 < i_count_cc*3 )  // broken packet
436
0
                return;
437
0
            cc += 1;
438
0
            for( int i = 0; i < i_count_cc; i++, cc += 3 )
439
0
            {
440
0
                if (!cc_AppendData( c, cc[0], &cc[1] ))
441
0
                    break;
442
0
            }
443
0
        }
444
        /* remaining data */
445
0
        c->b_reorder = false;
446
0
    }
447
29.6k
}
Unexecuted instantiation: mpegvideo.c:cc_Extract
vc1.c:cc_Extract
Line
Count
Source
222
21
{
223
21
    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
21
    c->i_payload_type        = i_payload_type;
230
21
    c->i_payload_other_count = 0;
231
232
21
    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
21
    else if( i_payload_type == CC_PAYLOAD_GA94 )
243
21
    {
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
21
        if(i_src < 1)
265
0
            return;
266
21
        const uint8_t *cc = &p_src[0];
267
21
        const int i_count_cc = cc[0]&0x1f;
268
21
        int i;
269
270
21
        if( !(cc[0]&0x40) ) // process flag
271
20
            return;
272
1
        if( i_src < 1+1 + i_count_cc*3 + 1)  // broken packet
273
0
            return;
274
1
        if( i_count_cc <= 0 )   // no cc present
275
0
            return;
276
1
        if( cc[2+i_count_cc * 3] != 0xff )  // marker absent
277
1
            return;
278
0
        cc += 2;
279
280
0
        for( i = 0; i < i_count_cc; i++, cc += 3 )
281
0
        {
282
0
            if (!cc_AppendData( c, cc[0], &cc[1] ))
283
0
                break;
284
0
        }
285
0
        c->b_reorder = true;
286
0
    }
287
0
    else if( i_payload_type == CC_PAYLOAD_DVD )
288
0
    {
289
        /* user_data
290
         *          (u32 stripped earlier)
291
         *          u32 (0x43 0x43 0x01 0xf8)
292
         *          u1 caption_odd_field_first (CC1/CC2)
293
         *          u1 caption_filler
294
         *          u5 cc_block_count  (== cc_count / 2)
295
         *          u1 caption_extra_field_added (because odd cc_count)
296
         *          for cc_block_count * 2 + caption_extra_field_added
297
         *              u7 cc_filler_1
298
         *              u1 cc_field_is_odd
299
         *              u8 cc_data_1
300
         *              u8 cc_data_2
301
         */
302
0
        if(i_src < 6)
303
0
            return;
304
0
        const int b_truncate = p_src[4] & 0x01;
305
0
        const int i_count_cc2 = ((p_src[4] >> 1) & 0x1f);
306
0
        const uint8_t *cc = &p_src[5];
307
0
        i_src -= 5;
308
0
        int i;
309
310
0
#define CC_ALIGNMENT_TEST   (0x7f)
311
312
0
        for( i = 0; i < 2*i_count_cc2 + b_truncate && i_src >= 3; i++, cc+=3 )
313
0
        {
314
0
            if( (cc[0] >> 1) == CC_ALIGNMENT_TEST )
315
0
            {
316
0
                const bool even_field = (cc[0] & 0x01) ? 0 : 1;
317
0
                if (!cc_AppendData( c, CC_PKT_BYTE0(even_field), &cc[1] ))
318
0
                    break;
319
0
            }
320
0
            i_src -= 3;
321
0
        }
322
0
        c->b_reorder = false;
323
0
    }
324
0
    else if( i_payload_type == CC_PAYLOAD_REPLAYTV )
325
0
    {
326
0
        if(i_src < 1)
327
0
            return;
328
0
        const uint8_t *cc = &p_src[0];
329
0
        for( int i_cc_count = i_src >> 2; i_cc_count > 0;
330
0
             i_cc_count--, cc += 4 )
331
0
        {
332
0
            uint8_t i_field = (cc[0] & 0x02) >> 1;
333
0
            if (!cc_AppendData( c, CC_PKT_BYTE0(i_field), &cc[2] ))
334
0
                return;
335
0
        }
336
0
        c->b_reorder = false;
337
0
    }
338
0
    else if( i_payload_type == CC_PAYLOAD_SCTE20 )
339
0
    {
340
        /* user_data(2)
341
         *          (u32 stripped earlier)
342
         *          u16 p_cc_scte20
343
         *          u5 cc_count
344
         *          for cc_count
345
         *              u2 cc_priority
346
         *              u2 cc_field_num
347
         *              u5 cc_line_offset
348
         *              u8 cc_data_1[1:8]
349
         *              u8 cc_data_2[1:8]
350
         *              u1 marker bit
351
         *          un additional_realtimevideodata
352
         *          un reserved
353
         */
354
0
        if(i_src < 2)
355
0
            return;
356
0
        bs_t s;
357
0
        bs_init( &s, &p_src[2], i_src - 2 );
358
0
        const int i_cc_count = bs_read( &s, 5 );
359
0
        for( int i = 0; i < i_cc_count; i++ )
360
0
        {
361
0
            bs_skip( &s, 2 );
362
0
            const int i_field_idx = bs_read( &s, 2 );
363
0
            bs_skip( &s, 5 );
364
0
            uint8_t cc[2];
365
0
            for( int j = 0; j < 2; j++ )
366
0
            {
367
0
                cc[j] = 0;
368
0
                for( int k = 0; k < 8; k++ )
369
0
                    cc[j] |= bs_read( &s, 1 ) << k;
370
0
            }
371
0
            bs_skip( &s, 1 );
372
373
0
            if( i_field_idx == 0 )
374
0
                continue;
375
376
            /* 1,2,3 -> 0,1,0. I.E. repeated field 3 is merged with field 1 */
377
0
            int i_field = ((i_field_idx - 1) & 1);
378
0
            if (!b_top_field_first)
379
0
                i_field ^= 1;
380
381
0
            if (!cc_AppendData( c, CC_PKT_BYTE0(i_field), &cc[0] ))
382
0
                continue;
383
0
        }
384
0
        c->b_reorder = true;
385
0
    }
386
0
    else // CC_PAYLOAD_CDP
387
0
    {
388
0
#       define CDP_FLAG_TIME_CODE_PRESENT  (1<<7)
389
0
#       define CDP_FLAG_CC_DATA_PRESENT    (1<<6)
390
0
#       define CDP_FLAG_SVC_INFO_PRESENT   (1<<5)
391
0
#       define CDP_FLAG_SVC_INFO_START     (1<<4)
392
0
#       define CDP_FLAG_SVC_INFO_CHANGE    (1<<3)
393
0
#       define CDP_FLAG_SVC_INFO_COMPLETE  (1<<2)
394
0
#       define CDP_FLAG_CAPTION_SVC_ACTIVE (1<<1)
395
396
0
        if(i_src < 7)
397
0
            return;
398
399
        /* ST334-2 5.2 cdp_header() */
400
0
        uint8_t cdp_length = p_src[2];
401
0
        if(cdp_length < 8 || cdp_length > i_src)
402
0
            return;
403
0
        uint8_t cdp_flags = p_src[4];
404
405
        /* skip header */
406
0
        p_src += 7; i_src -= 7;
407
408
        /* 5.3 time_code_section() */
409
0
        if( cdp_flags & CDP_FLAG_TIME_CODE_PRESENT )
410
0
        {
411
0
            if( i_src < 5 ) // Shall be 5 bytes
412
0
                return;
413
0
            p_src += 5; i_src += 5;
414
0
        }
415
        /* 5.4 ccdata_section */
416
0
        if( cdp_flags & CDP_FLAG_CC_DATA_PRESENT )
417
0
        {
418
            /* ccdata_section()
419
             *      u8 0x72
420
             *      u3 marker bits(111)
421
             *      u5 cc_count
422
             *      for cc_count
423
             *          u5 marker bits(1111 1)
424
             *          u1 cc_valid
425
             *          u2 cc_type
426
             *          u8 cc_data_1
427
             *          u8 cc_data_2
428
             */
429
0
            if( i_src < 2 || p_src[0] != 0x72 ) // marker
430
0
                return;
431
432
0
            const uint8_t *cc = &p_src[1];
433
0
            const int i_count_cc = cc[0]&0x1f;
434
435
0
            if( i_src - 2 < i_count_cc*3 )  // broken packet
436
0
                return;
437
0
            cc += 1;
438
0
            for( int i = 0; i < i_count_cc; i++, cc += 3 )
439
0
            {
440
0
                if (!cc_AppendData( c, cc[0], &cc[1] ))
441
0
                    break;
442
0
            }
443
0
        }
444
        /* remaining data */
445
0
        c->b_reorder = false;
446
0
    }
447
21
}
448
449
450
static inline void cc_ProbeAndExtract( cc_data_t *c, bool b_top_field_first, const uint8_t *p_src, int i_src )
451
80
{
452
80
    static const uint8_t p_cc_ga94[4] = { 0x47, 0x41, 0x39, 0x34 };
453
80
    static const uint8_t p_cc_dvd[4] = { 0x43, 0x43, 0x01, 0xf8 }; /* ascii 'CC', type_code, cc_block_size */
454
80
    static const uint8_t p_cc_replaytv4a[2] = { 0xbb, 0x02 };/* RTV4K, BB02xxxxCC02 */
455
80
    static const uint8_t p_cc_replaytv4b[2] = { 0xcc, 0x02 };/* see DVR-ClosedCaption in samples */
456
80
    static const uint8_t p_cc_replaytv5a[2] = { 0x99, 0x02 };/* RTV5K, 9902xxxxAA02 */
457
80
    static const uint8_t p_cc_replaytv5b[2] = { 0xaa, 0x02 };/* see DVR-ClosedCaption in samples */
458
80
    static const uint8_t p_cc_scte20[2] = { 0x03, 0x81 };    /* user_data_type_code, SCTE 20 */
459
80
    static const uint8_t p_cc_scte20_old[2] = { 0x03, 0x01 };/* user_data_type_code, old, Note 1 */
460
461
80
    if( i_src < 4 )
462
0
        return;
463
464
80
    enum cc_payload_type_e i_payload_type;
465
80
    if( !memcmp( p_cc_ga94, p_src, 4 ) && i_src >= 5+1+1+1 && p_src[4] == 0x03 )
466
21
    {
467
        /* CC from DVB/ATSC TS */
468
21
        i_payload_type = CC_PAYLOAD_GA94;
469
21
        i_src -= 5;
470
21
        p_src += 5;
471
21
    }
472
59
    else if( !memcmp( p_cc_dvd, p_src, 4 ) && i_src > 4+1 )
473
0
    {
474
0
        i_payload_type = CC_PAYLOAD_DVD;
475
0
    }
476
59
    else if( i_src >= 2+2 + 2+2 &&
477
40
             ( ( !memcmp( p_cc_replaytv4a, &p_src[0], 2 ) && !memcmp( p_cc_replaytv4b, &p_src[4], 2 ) ) ||
478
40
               ( !memcmp( p_cc_replaytv5a, &p_src[0], 2 ) && !memcmp( p_cc_replaytv5b, &p_src[4], 2 ) ) ) )
479
0
    {
480
0
        i_payload_type = CC_PAYLOAD_REPLAYTV;
481
0
    }
482
59
    else if( ( !memcmp( p_cc_scte20, p_src, 2 ) ||
483
59
               !memcmp( p_cc_scte20_old, p_src, 2 ) ) && i_src > 2 )
484
0
    {
485
0
        i_payload_type = CC_PAYLOAD_SCTE20;
486
0
    }
487
59
    else if (p_src[0] == 0x03 && p_src[1] == i_src - 2) /* DIRECTV */
488
0
    {
489
0
        i_payload_type = CC_PAYLOAD_GA94;
490
0
        i_src -= 2;
491
0
        p_src += 2;
492
0
    }
493
59
    else if (p_src[0] == 0x96 && p_src[1] == 0x69) /* CDP */
494
0
    {
495
0
        i_payload_type = CC_PAYLOAD_CDP;
496
0
    }
497
59
    else
498
59
    {
499
#if 0
500
#define V(x) ( ( x < 0x20 || x >= 0x7f ) ? '?' : x )
501
        fprintf( stderr, "-------------- unknown user data " );
502
        for( int i = 0; i < i_src; i++ )
503
            fprintf( stderr, "%2.2x ", p_src[i] );
504
        for( int i = 0; i < i_src; i++ )
505
            fprintf( stderr, "%c ", V(p_src[i]) );
506
        fprintf( stderr, "\n" );
507
#undef V
508
#endif
509
59
        return;
510
59
    }
511
512
21
    cc_Extract( c, i_payload_type, b_top_field_first, p_src, i_src );
513
21
}
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
451
80
{
452
80
    static const uint8_t p_cc_ga94[4] = { 0x47, 0x41, 0x39, 0x34 };
453
80
    static const uint8_t p_cc_dvd[4] = { 0x43, 0x43, 0x01, 0xf8 }; /* ascii 'CC', type_code, cc_block_size */
454
80
    static const uint8_t p_cc_replaytv4a[2] = { 0xbb, 0x02 };/* RTV4K, BB02xxxxCC02 */
455
80
    static const uint8_t p_cc_replaytv4b[2] = { 0xcc, 0x02 };/* see DVR-ClosedCaption in samples */
456
80
    static const uint8_t p_cc_replaytv5a[2] = { 0x99, 0x02 };/* RTV5K, 9902xxxxAA02 */
457
80
    static const uint8_t p_cc_replaytv5b[2] = { 0xaa, 0x02 };/* see DVR-ClosedCaption in samples */
458
80
    static const uint8_t p_cc_scte20[2] = { 0x03, 0x81 };    /* user_data_type_code, SCTE 20 */
459
80
    static const uint8_t p_cc_scte20_old[2] = { 0x03, 0x01 };/* user_data_type_code, old, Note 1 */
460
461
80
    if( i_src < 4 )
462
0
        return;
463
464
80
    enum cc_payload_type_e i_payload_type;
465
80
    if( !memcmp( p_cc_ga94, p_src, 4 ) && i_src >= 5+1+1+1 && p_src[4] == 0x03 )
466
21
    {
467
        /* CC from DVB/ATSC TS */
468
21
        i_payload_type = CC_PAYLOAD_GA94;
469
21
        i_src -= 5;
470
21
        p_src += 5;
471
21
    }
472
59
    else if( !memcmp( p_cc_dvd, p_src, 4 ) && i_src > 4+1 )
473
0
    {
474
0
        i_payload_type = CC_PAYLOAD_DVD;
475
0
    }
476
59
    else if( i_src >= 2+2 + 2+2 &&
477
40
             ( ( !memcmp( p_cc_replaytv4a, &p_src[0], 2 ) && !memcmp( p_cc_replaytv4b, &p_src[4], 2 ) ) ||
478
40
               ( !memcmp( p_cc_replaytv5a, &p_src[0], 2 ) && !memcmp( p_cc_replaytv5b, &p_src[4], 2 ) ) ) )
479
0
    {
480
0
        i_payload_type = CC_PAYLOAD_REPLAYTV;
481
0
    }
482
59
    else if( ( !memcmp( p_cc_scte20, p_src, 2 ) ||
483
59
               !memcmp( p_cc_scte20_old, p_src, 2 ) ) && i_src > 2 )
484
0
    {
485
0
        i_payload_type = CC_PAYLOAD_SCTE20;
486
0
    }
487
59
    else if (p_src[0] == 0x03 && p_src[1] == i_src - 2) /* DIRECTV */
488
0
    {
489
0
        i_payload_type = CC_PAYLOAD_GA94;
490
0
        i_src -= 2;
491
0
        p_src += 2;
492
0
    }
493
59
    else if (p_src[0] == 0x96 && p_src[1] == 0x69) /* CDP */
494
0
    {
495
0
        i_payload_type = CC_PAYLOAD_CDP;
496
0
    }
497
59
    else
498
59
    {
499
#if 0
500
#define V(x) ( ( x < 0x20 || x >= 0x7f ) ? '?' : x )
501
        fprintf( stderr, "-------------- unknown user data " );
502
        for( int i = 0; i < i_src; i++ )
503
            fprintf( stderr, "%2.2x ", p_src[i] );
504
        for( int i = 0; i < i_src; i++ )
505
            fprintf( stderr, "%c ", V(p_src[i]) );
506
        fprintf( stderr, "\n" );
507
#undef V
508
#endif
509
59
        return;
510
59
    }
511
512
21
    cc_Extract( c, i_payload_type, b_top_field_first, p_src, i_src );
513
21
}
514
515
#endif /* _CC_H */
516