Coverage Report

Created: 2026-03-07 07:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/modules/packetizer/hxxx_sei.c
Line
Count
Source
1
/*****************************************************************************
2
 * hxxx_sei.c: AVC/HEVC packetizers SEI handling
3
 *****************************************************************************
4
 * Copyright (C) 2001-2016 VLC authors and VideoLAN
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU Lesser General Public License as published by
8
 * the Free Software Foundation; either version 2.1 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this program; if not, write to the Free Software Foundation,
18
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19
 *****************************************************************************/
20
#ifdef HAVE_CONFIG_H
21
# include "config.h"
22
#endif
23
24
#include <vlc_common.h>
25
#include <vlc_block.h>
26
#include <vlc_bits.h>
27
28
#include "hxxx_sei.h"
29
#include "hxxx_nal.h"
30
#include "hxxx_ep3b.h"
31
32
void HxxxParse_AnnexB_SEI(const uint8_t *p_buf, size_t i_buf,
33
                          uint8_t i_header, pf_hxxx_sei_callback cb, void *cbdata)
34
282k
{
35
282k
    if( hxxx_strip_AnnexB_startcode( &p_buf, &i_buf ) )
36
282k
        HxxxParseSEI(p_buf, i_buf, i_header, cb, cbdata);
37
282k
}
38
39
void HxxxParseSEI(const uint8_t *p_buf, size_t i_buf,
40
                  uint8_t i_header, pf_hxxx_sei_callback pf_callback, void *cbdata)
41
282k
{
42
282k
    bs_t s;
43
282k
    bool b_continue = true;
44
45
282k
    if( i_buf <= i_header )
46
9.79k
        return;
47
48
272k
    struct hxxx_bsfw_ep3b_ctx_s bsctx;
49
272k
    hxxx_bsfw_ep3b_ctx_init( &bsctx );
50
272k
    bs_init_custom( &s, &p_buf[i_header], i_buf - i_header, /* skip nal unit header */
51
272k
                    &hxxx_bsfw_ep3b_callbacks, &bsctx );
52
53
54
11.9M
    while( !bs_eof( &s ) && bs_aligned( &s ) && b_continue )
55
11.8M
    {
56
        /* Read type */
57
11.8M
        unsigned i_type = 0;
58
12.1M
        while( !bs_eof( &s ) )
59
12.1M
        {
60
12.1M
            const uint8_t i_byte = bs_read( &s, 8 );
61
12.1M
            i_type += i_byte;
62
12.1M
            if( i_byte != 0xff )
63
11.8M
                break;
64
12.1M
        }
65
66
11.8M
        if( bs_error( &s ) )
67
0
            return;
68
69
        /* Read size */
70
11.8M
        unsigned i_size = 0;
71
12.5M
        while( !bs_eof( &s ) )
72
12.4M
        {
73
12.4M
            const uint8_t i_byte = bs_read( &s, 8 );
74
12.4M
            i_size += i_byte;
75
12.4M
            if( i_byte != 0xff )
76
11.7M
                break;
77
12.4M
        }
78
79
11.8M
        if( bs_error( &s ) )
80
0
            return;
81
82
        /* Check room */
83
11.8M
        if( bs_eof( &s ) )
84
114k
            break;
85
86
11.7M
        hxxx_sei_data_t sei_data;
87
11.7M
        sei_data.i_type = i_type;
88
89
        /* Save start offset */
90
11.7M
        const unsigned i_start_bit_pos = bs_pos( &s );
91
11.7M
        switch( i_type )
92
11.7M
        {
93
            /* Look for pic timing, do not decode locally */
94
47.2k
            case HXXX_SEI_PIC_TIMING:
95
47.2k
            {
96
47.2k
                sei_data.p_bs = &s;
97
47.2k
                b_continue = pf_callback( &sei_data, cbdata );
98
47.2k
            } break;
99
100
            /* Look for user_data_registered_itu_t_t35 */
101
75.6k
            case HXXX_SEI_USER_DATA_REGISTERED_ITU_T_T35:
102
75.6k
            {
103
75.6k
                size_t i_t35;
104
75.6k
                uint8_t *p_t35 = malloc( i_size );
105
75.6k
                if( !p_t35 )
106
0
                    break;
107
108
2.08M
                for( i_t35 = 0; i_t35<i_size && !bs_eof( &s ); i_t35++ )
109
2.00M
                    p_t35[i_t35] = bs_read( &s, 8 );
110
111
75.6k
                if( bs_error( &s ) )
112
0
                {
113
0
                    free( p_t35 );
114
0
                    break;
115
0
                }
116
117
                /* TS 101 154 Auxiliary Data and H264/AVC video */
118
75.6k
                if( i_t35 > 4 && p_t35[0] == 0xb5 /* United States */ )
119
53.9k
                {
120
53.9k
                    if( p_t35[1] == 0x00 && p_t35[2] == 0x31 && /* US provider code for ATSC / DVB1 */
121
35.7k
                        i_t35 > 7 )
122
35.1k
                    {
123
35.1k
                        switch( VLC_FOURCC(p_t35[3],p_t35[4],p_t35[5],p_t35[6]) )
124
35.1k
                        {
125
29.1k
                            case VLC_FOURCC('G', 'A', '9', '4'):
126
29.1k
                                if( p_t35[7] == 0x03 )
127
28.1k
                                {
128
28.1k
                                    sei_data.itu_t35.type = HXXX_ITU_T35_TYPE_CC;
129
28.1k
                                    sei_data.itu_t35.u.cc.i_data = i_t35 - 8;
130
28.1k
                                    sei_data.itu_t35.u.cc.p_data = &p_t35[8];
131
28.1k
                                    b_continue = pf_callback( &sei_data, cbdata );
132
28.1k
                                }
133
29.1k
                                break;
134
6.05k
                            default:
135
6.05k
                                break;
136
35.1k
                        }
137
35.1k
                    }
138
18.8k
                    else if( p_t35[1] == 0x00 && p_t35[2] == 0x2f && /* US provider code for DirecTV */
139
14.7k
                             p_t35[3] == 0x03 && i_t35 > 5 )
140
13.6k
                    {
141
                        /* DirecTV does not use GA94 user_data identifier */
142
13.6k
                        sei_data.itu_t35.type = HXXX_ITU_T35_TYPE_CC;
143
13.6k
                        sei_data.itu_t35.u.cc.i_data = i_t35 - 5;
144
13.6k
                        sei_data.itu_t35.u.cc.p_data = &p_t35[5];
145
13.6k
                        b_continue = pf_callback( &sei_data, cbdata );
146
13.6k
                    }
147
53.9k
                }
148
149
75.6k
                free( p_t35 );
150
75.6k
            } break;
151
152
92.8k
            case HXXX_SEI_FRAME_PACKING_ARRANGEMENT:
153
92.8k
            {
154
92.8k
                bs_read_ue( &s );
155
92.8k
                if ( !bs_read1( &s ) )
156
90.1k
                {
157
90.1k
                    sei_data.frame_packing.type = bs_read( &s, 7 );
158
90.1k
                    bs_read( &s, 1 );
159
90.1k
                    if( bs_read( &s, 6 ) == 2 ) /*intpr type*/
160
705
                        sei_data.frame_packing.b_left_first = false;
161
89.4k
                    else
162
89.4k
                        sei_data.frame_packing.b_left_first = true;
163
90.1k
                    sei_data.frame_packing.b_flipped = bs_read1( &s );
164
90.1k
                    sei_data.frame_packing.b_fields = bs_read1( &s );
165
90.1k
                    sei_data.frame_packing.b_frame0 = bs_read1( &s );
166
90.1k
                }
167
2.69k
                else sei_data.frame_packing.type = FRAME_PACKING_CANCEL;
168
169
92.8k
            } break;
170
171
            /* Look for SEI recovery point */
172
8.17k
            case HXXX_SEI_RECOVERY_POINT:
173
8.17k
            {
174
8.17k
                sei_data.p_bs = &s;
175
8.17k
                b_continue = pf_callback( &sei_data, cbdata );
176
8.17k
            } break;
177
178
11.6k
            case HXXX_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
179
11.6k
            {
180
81.3k
                for ( size_t i = 0; i < 6 ; ++i)
181
69.7k
                    sei_data.colour_volume.primaries[i] = bs_read( &s, 16 );
182
34.8k
                for ( size_t i = 0; i < 2 ; ++i)
183
23.2k
                    sei_data.colour_volume.white_point[i] = bs_read( &s, 16 );
184
11.6k
                sei_data.colour_volume.max_luminance = bs_read( &s, 32 );
185
11.6k
                sei_data.colour_volume.min_luminance = bs_read( &s, 32 );
186
11.6k
                if( bs_error( &s ) ) /* not enough data */
187
9.64k
                    break;
188
1.97k
                b_continue = pf_callback( &sei_data, cbdata );
189
1.97k
            } break;
190
191
4.77k
            case HXXX_SEI_CONTENT_LIGHT_LEVEL:
192
4.77k
            {
193
4.77k
                sei_data.content_light_lvl.MaxCLL = bs_read( &s, 16 );
194
4.77k
                sei_data.content_light_lvl.MaxFALL = bs_read( &s, 16 );
195
4.77k
                if( bs_error( &s ) ) /* not enough data */
196
2.55k
                    break;
197
2.22k
                b_continue = pf_callback( &sei_data, cbdata );
198
2.22k
            } break;
199
200
11.5M
            default:
201
                /* Will skip */
202
11.5M
                break;
203
11.7M
        }
204
11.7M
        const unsigned i_end_bit_pos = bs_pos( &s );
205
206
        /* Skip unsparsed content */
207
11.7M
        if( i_end_bit_pos - i_start_bit_pos > i_size * 8 ) /* Something went wrong with _ue reads */
208
90.7k
            break;
209
11.6M
        bs_skip( &s, i_size * 8 - ( i_end_bit_pos - i_start_bit_pos ) );
210
11.6M
    }
211
272k
}