mp4: fix PADB parsing
[vlc.git] / modules / packetizer / hxxx_sei.c
blob15791c3750df59a8164fd7209b2314fc2c779744
1 /*****************************************************************************
2 * hxxx_sei.c: AVC/HEVC packetizers SEI handling
3 *****************************************************************************
4 * Copyright (C) 2001-2016 VLC authors and VideoLAN
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.
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.
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
24 #include <vlc_common.h>
25 #include <vlc_bits.h>
26 #include <vlc_block.h>
28 #include "hxxx_sei.h"
29 #include "hxxx_nal.h"
31 void HxxxParse_AnnexB_SEI(const uint8_t *p_buf, size_t i_buf,
32 uint8_t i_header, pf_hxxx_sei_callback cb, void *cbdata)
34 if( hxxx_strip_AnnexB_startcode( &p_buf, &i_buf ) )
35 HxxxParseSEI(p_buf, i_buf, i_header, cb, cbdata);
38 void HxxxParseSEI(const uint8_t *p_buf, size_t i_buf,
39 uint8_t i_header, pf_hxxx_sei_callback pf_callback, void *cbdata)
41 bs_t s;
42 unsigned i_bitflow = 0;
43 bool b_continue = true;
45 if( i_buf <= i_header )
46 return;
48 bs_init( &s, &p_buf[i_header], i_buf - i_header ); /* skip nal unit header */
49 s.p_fwpriv = &i_bitflow;
50 s.pf_forward = hxxx_bsfw_ep3b_to_rbsp; /* Does the emulated 3bytes conversion to rbsp */
52 while( bs_remain( &s ) >= 8 && bs_aligned( &s ) && b_continue )
54 /* Read type */
55 unsigned i_type = 0;
56 while( bs_remain( &s ) >= 8 )
58 const uint8_t i_byte = bs_read( &s, 8 );
59 i_type += i_byte;
60 if( i_byte != 0xff )
61 break;
64 /* Read size */
65 unsigned i_size = 0;
66 while( bs_remain( &s ) >= 8 )
68 const uint8_t i_byte = bs_read( &s, 8 );
69 i_size += i_byte;
70 if( i_byte != 0xff )
71 break;
74 /* Check room */
75 if( bs_remain( &s ) < 8 )
76 break;
78 hxxx_sei_data_t sei_data;
79 sei_data.i_type = i_type;
81 /* Save start offset */
82 const unsigned i_start_bit_pos = bs_pos( &s );
83 switch( i_type )
85 /* Look for pic timing, do not decode locally */
86 case HXXX_SEI_PIC_TIMING:
88 sei_data.p_bs = &s;
89 b_continue = pf_callback( &sei_data, cbdata );
90 } break;
92 /* Look for user_data_registered_itu_t_t35 */
93 case HXXX_SEI_USER_DATA_REGISTERED_ITU_T_T35:
95 size_t i_t35;
96 uint8_t *p_t35 = malloc( i_size );
97 if( !p_t35 )
98 break;
100 for( i_t35 = 0; i_t35<i_size && bs_remain( &s ) >= 8; i_t35++ )
101 p_t35[i_t35] = bs_read( &s, 8 );
103 /* TS 101 154 Auxiliary Data and H264/AVC video */
104 if( i_t35 > 4 && p_t35[0] == 0xb5 /* United States */ )
106 if( p_t35[1] == 0x00 && p_t35[2] == 0x31 && /* US provider code for ATSC / DVB1 */
107 i_t35 > 7 )
109 switch( VLC_FOURCC(p_t35[3],p_t35[4],p_t35[5],p_t35[6]) )
111 case VLC_FOURCC('G', 'A', '9', '4'):
112 if( p_t35[7] == 0x03 )
114 sei_data.itu_t35.type = HXXX_ITU_T35_TYPE_CC;
115 sei_data.itu_t35.u.cc.i_data = i_t35 - 8;
116 sei_data.itu_t35.u.cc.p_data = &p_t35[8];
117 b_continue = pf_callback( &sei_data, cbdata );
119 break;
120 default:
121 break;
124 else if( p_t35[1] == 0x00 && p_t35[2] == 0x2f && /* US provider code for DirecTV */
125 p_t35[3] == 0x03 && i_t35 > 5 )
127 /* DirecTV does not use GA94 user_data identifier */
128 sei_data.itu_t35.type = HXXX_ITU_T35_TYPE_CC;
129 sei_data.itu_t35.u.cc.i_data = i_t35 - 5;
130 sei_data.itu_t35.u.cc.p_data = &p_t35[5];
131 b_continue = pf_callback( &sei_data, cbdata );
135 free( p_t35 );
136 } break;
138 case HXXX_SEI_FRAME_PACKING_ARRANGEMENT:
140 bs_read_ue( &s );
141 if ( !bs_read1( &s ) )
143 sei_data.frame_packing.type = bs_read( &s, 7 );
144 bs_read( &s, 1 );
145 if( bs_read( &s, 6 ) == 2 ) /*intpr type*/
146 sei_data.frame_packing.b_left_first = false;
147 else
148 sei_data.frame_packing.b_left_first = true;
149 sei_data.frame_packing.b_flipped = bs_read1( &s );
150 sei_data.frame_packing.b_fields = bs_read1( &s );
151 sei_data.frame_packing.b_frame0 = bs_read1( &s );
153 else sei_data.frame_packing.type = FRAME_PACKING_CANCEL;
155 } break;
157 /* Look for SEI recovery point */
158 case HXXX_SEI_RECOVERY_POINT:
160 sei_data.recovery.i_frames = bs_read_ue( &s );
161 //bool b_exact_match = bs_read( &s, 1 );
162 //bool b_broken_link = bs_read( &s, 1 );
163 //int i_changing_slice_group = bs_read( &s, 2 );
164 b_continue = pf_callback( &sei_data, cbdata );
165 } break;
167 case HXXX_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
169 if ( bs_remain( &s ) < (16*6+16*2+32+32) )
170 /* not enough data */
171 break;
172 for ( size_t i = 0; i < 6 ; ++i)
173 sei_data.colour_volume.primaries[i] = bs_read( &s, 16 );
174 for ( size_t i = 0; i < 2 ; ++i)
175 sei_data.colour_volume.white_point[i] = bs_read( &s, 16 );
176 sei_data.colour_volume.max_luminance = bs_read( &s, 32 );
177 sei_data.colour_volume.min_luminance = bs_read( &s, 32 );
178 b_continue = pf_callback( &sei_data, cbdata );
179 } break;
181 case HXXX_SEI_CONTENT_LIGHT_LEVEL:
183 if ( bs_remain( &s ) < (16+16) )
184 /* not enough data */
185 break;
186 sei_data.content_light_lvl.MaxCLL = bs_read( &s, 16 );
187 sei_data.content_light_lvl.MaxFALL = bs_read( &s, 16 );
188 b_continue = pf_callback( &sei_data, cbdata );
189 } break;
191 default:
192 /* Will skip */
193 break;
195 const unsigned i_end_bit_pos = bs_pos( &s );
197 /* Skip unsparsed content */
198 if( i_end_bit_pos - i_start_bit_pos > i_size * 8 ) /* Something went wrong with _ue reads */
199 break;
200 bs_skip( &s, i_size * 8 - ( i_end_bit_pos - i_start_bit_pos ) );