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 *****************************************************************************/
24 #include <vlc_common.h>
26 #include <vlc_block.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
)
42 unsigned i_bitflow
= 0;
43 bool b_continue
= true;
45 if( i_buf
<= i_header
)
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
)
56 while( bs_remain( &s
) >= 8 )
58 const uint8_t i_byte
= bs_read( &s
, 8 );
66 while( bs_remain( &s
) >= 8 )
68 const uint8_t i_byte
= bs_read( &s
, 8 );
75 if( bs_remain( &s
) < 8 )
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
);
85 /* Look for pic timing, do not decode locally */
86 case HXXX_SEI_PIC_TIMING
:
89 b_continue
= pf_callback( &sei_data
, cbdata
);
92 /* Look for user_data_registered_itu_t_t35 */
93 case HXXX_SEI_USER_DATA_REGISTERED_ITU_T_T35
:
96 uint8_t *p_t35
= malloc( i_size
);
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 */
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
);
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
);
138 case HXXX_SEI_FRAME_PACKING_ARRANGEMENT
:
141 if ( !bs_read1( &s
) )
143 sei_data
.frame_packing
.type
= bs_read( &s
, 7 );
145 if( bs_read( &s
, 6 ) == 2 ) /*intpr type*/
146 sei_data
.frame_packing
.b_left_first
= false;
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
;
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
);
167 case HXXX_SEI_MASTERING_DISPLAY_COLOUR_VOLUME
:
169 if ( bs_remain( &s
) < (16*6+16*2+32+32) )
170 /* not enough data */
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
);
181 case HXXX_SEI_CONTENT_LIGHT_LEVEL
:
183 if ( bs_remain( &s
) < (16+16) )
184 /* not enough data */
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
);
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 */
200 bs_skip( &s
, i_size
* 8 - ( i_end_bit_pos
- i_start_bit_pos
) );