Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * set: header writing |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2003-2025 x264 project |
5 | | * |
6 | | * Authors: Laurent Aimar <fenrir@via.ecp.fr> |
7 | | * Loren Merritt <lorenm@u.washington.edu> |
8 | | * |
9 | | * This program is free software; you can redistribute it and/or modify |
10 | | * it under the terms of the GNU General Public License as published by |
11 | | * the Free Software Foundation; either version 2 of the License, or |
12 | | * (at your option) any later version. |
13 | | * |
14 | | * This program is distributed in the hope that it will be useful, |
15 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | | * GNU General Public License for more details. |
18 | | * |
19 | | * You should have received a copy of the GNU General Public License |
20 | | * along with this program; if not, write to the Free Software |
21 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. |
22 | | * |
23 | | * This program is also available under a commercial proprietary license. |
24 | | * For more information, contact us at licensing@x264.com. |
25 | | *****************************************************************************/ |
26 | | |
27 | | #include "common/common.h" |
28 | | #include "set.h" |
29 | | |
30 | 0 | #define bs_write_ue bs_write_ue_big |
31 | | |
32 | | // Indexed by pic_struct values |
33 | | static const uint8_t num_clock_ts[10] = { 0, 1, 1, 1, 2, 2, 3, 3, 2, 3 }; |
34 | | static const uint8_t avcintra_uuid[] = {0xF7, 0x49, 0x3E, 0xB3, 0xD4, 0x00, 0x47, 0x96, 0x86, 0x86, 0xC9, 0x70, 0x7B, 0x64, 0x37, 0x2A}; |
35 | | |
36 | | static void transpose( uint8_t *buf, int w ) |
37 | 0 | { |
38 | 0 | for( int i = 0; i < w; i++ ) |
39 | 0 | for( int j = 0; j < i; j++ ) |
40 | 0 | XCHG( uint8_t, buf[w*i+j], buf[w*j+i] ); |
41 | 0 | } |
42 | | |
43 | | static void scaling_list_write( bs_t *s, x264_sps_t *sps, int idx ) |
44 | 0 | { |
45 | 0 | const int len = idx<4 ? 16 : 64; |
46 | 0 | const uint8_t *zigzag = idx<4 ? x264_zigzag_scan4[0] : x264_zigzag_scan8[0]; |
47 | 0 | const uint8_t *list = sps->scaling_list[idx]; |
48 | 0 | const uint8_t *def_list = (idx==CQM_4IC) ? sps->scaling_list[CQM_4IY] |
49 | 0 | : (idx==CQM_4PC) ? sps->scaling_list[CQM_4PY] |
50 | 0 | : (idx==CQM_8IC+4) ? sps->scaling_list[CQM_8IY+4] |
51 | 0 | : (idx==CQM_8PC+4) ? sps->scaling_list[CQM_8PY+4] |
52 | 0 | : x264_cqm_jvt[idx]; |
53 | 0 | if( !memcmp( list, def_list, len ) ) |
54 | 0 | bs_write1( s, 0 ); // scaling_list_present_flag |
55 | 0 | else if( !memcmp( list, x264_cqm_jvt[idx], len ) ) |
56 | 0 | { |
57 | 0 | bs_write1( s, 1 ); // scaling_list_present_flag |
58 | 0 | bs_write_se( s, -8 ); // use jvt list |
59 | 0 | } |
60 | 0 | else |
61 | 0 | { |
62 | 0 | int run; |
63 | 0 | bs_write1( s, 1 ); // scaling_list_present_flag |
64 | | |
65 | | // try run-length compression of trailing values |
66 | 0 | for( run = len; run > 1; run-- ) |
67 | 0 | if( list[zigzag[run-1]] != list[zigzag[run-2]] ) |
68 | 0 | break; |
69 | 0 | if( run < len && len - run < bs_size_se( (int8_t)-list[zigzag[run]] ) ) |
70 | 0 | run = len; |
71 | |
|
72 | 0 | for( int j = 0; j < run; j++ ) |
73 | 0 | bs_write_se( s, (int8_t)(list[zigzag[j]] - (j>0 ? list[zigzag[j-1]] : 8)) ); // delta |
74 | |
|
75 | 0 | if( run < len ) |
76 | 0 | bs_write_se( s, (int8_t)-list[zigzag[run]] ); |
77 | 0 | } |
78 | 0 | } |
79 | | |
80 | | void x264_sei_write( bs_t *s, uint8_t *payload, int payload_size, int payload_type ) |
81 | 0 | { |
82 | 0 | int i; |
83 | |
|
84 | 0 | bs_realign( s ); |
85 | |
|
86 | 0 | for( i = 0; i <= payload_type-255; i += 255 ) |
87 | 0 | bs_write( s, 8, 255 ); |
88 | 0 | bs_write( s, 8, payload_type-i ); |
89 | |
|
90 | 0 | for( i = 0; i <= payload_size-255; i += 255 ) |
91 | 0 | bs_write( s, 8, 255 ); |
92 | 0 | bs_write( s, 8, payload_size-i ); |
93 | |
|
94 | 0 | for( i = 0; i < payload_size; i++ ) |
95 | 0 | bs_write( s, 8, payload[i] ); |
96 | |
|
97 | 0 | bs_rbsp_trailing( s ); |
98 | 0 | bs_flush( s ); |
99 | 0 | } Unexecuted instantiation: x264_8_sei_write Unexecuted instantiation: x264_10_sei_write |
100 | | |
101 | | void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param ) |
102 | 0 | { |
103 | 0 | int csp = param->i_csp & X264_CSP_MASK; |
104 | |
|
105 | 0 | sps->i_id = i_id; |
106 | 0 | sps->i_mb_width = ( param->i_width + 15 ) / 16; |
107 | 0 | sps->i_mb_height= ( param->i_height + 15 ) / 16; |
108 | 0 | sps->b_frame_mbs_only = !(param->b_interlaced || param->b_fake_interlaced); |
109 | 0 | if( !sps->b_frame_mbs_only ) |
110 | 0 | sps->i_mb_height = ( sps->i_mb_height + 1 ) & ~1; |
111 | 0 | sps->i_chroma_format_idc = csp >= X264_CSP_I444 ? CHROMA_444 : |
112 | 0 | csp >= X264_CSP_I422 ? CHROMA_422 : |
113 | 0 | csp >= X264_CSP_I420 ? CHROMA_420 : CHROMA_400; |
114 | |
|
115 | 0 | sps->b_qpprime_y_zero_transform_bypass = param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant == 0; |
116 | 0 | if( sps->b_qpprime_y_zero_transform_bypass || sps->i_chroma_format_idc == CHROMA_444 ) |
117 | 0 | sps->i_profile_idc = PROFILE_HIGH444_PREDICTIVE; |
118 | 0 | else if( sps->i_chroma_format_idc == CHROMA_422 ) |
119 | 0 | sps->i_profile_idc = PROFILE_HIGH422; |
120 | 0 | else if( BIT_DEPTH > 8 ) |
121 | 0 | sps->i_profile_idc = PROFILE_HIGH10; |
122 | 0 | else if( param->analyse.b_transform_8x8 || param->i_cqm_preset != X264_CQM_FLAT || sps->i_chroma_format_idc == CHROMA_400 ) |
123 | 0 | sps->i_profile_idc = PROFILE_HIGH; |
124 | 0 | else if( param->b_cabac || param->i_bframe > 0 || param->b_interlaced || param->b_fake_interlaced || param->analyse.i_weighted_pred > 0 ) |
125 | 0 | sps->i_profile_idc = PROFILE_MAIN; |
126 | 0 | else |
127 | 0 | sps->i_profile_idc = PROFILE_BASELINE; |
128 | |
|
129 | 0 | sps->b_constraint_set0 = sps->i_profile_idc == PROFILE_BASELINE; |
130 | | /* x264 doesn't support the features that are in Baseline and not in Main, |
131 | | * namely arbitrary_slice_order and slice_groups. */ |
132 | 0 | sps->b_constraint_set1 = sps->i_profile_idc <= PROFILE_MAIN; |
133 | | /* Never set constraint_set2, it is not necessary and not used in real world. */ |
134 | 0 | sps->b_constraint_set2 = 0; |
135 | 0 | sps->b_constraint_set3 = 0; |
136 | |
|
137 | 0 | sps->i_level_idc = param->i_level_idc; |
138 | 0 | if( param->i_level_idc == 9 && ( sps->i_profile_idc == PROFILE_BASELINE || sps->i_profile_idc == PROFILE_MAIN ) ) |
139 | 0 | { |
140 | 0 | sps->b_constraint_set3 = 1; /* level 1b with Baseline or Main profile is signalled via constraint_set3 */ |
141 | 0 | sps->i_level_idc = 11; |
142 | 0 | } |
143 | | /* Intra profiles */ |
144 | 0 | if( param->i_keyint_max == 1 && sps->i_profile_idc >= PROFILE_HIGH ) |
145 | 0 | sps->b_constraint_set3 = 1; |
146 | |
|
147 | 0 | sps->vui.i_num_reorder_frames = param->i_bframe_pyramid ? 2 : param->i_bframe ? 1 : 0; |
148 | | /* extra slot with pyramid so that we don't have to override the |
149 | | * order of forgetting old pictures */ |
150 | 0 | sps->vui.i_max_dec_frame_buffering = |
151 | 0 | sps->i_num_ref_frames = X264_MIN(X264_REF_MAX, X264_MAX4(param->i_frame_reference, 1 + sps->vui.i_num_reorder_frames, |
152 | 0 | param->i_bframe_pyramid ? 4 : 1, param->i_dpb_size)); |
153 | 0 | sps->i_num_ref_frames -= param->i_bframe_pyramid == X264_B_PYRAMID_STRICT; |
154 | 0 | if( param->i_keyint_max == 1 ) |
155 | 0 | { |
156 | 0 | sps->i_num_ref_frames = 0; |
157 | 0 | sps->vui.i_max_dec_frame_buffering = 0; |
158 | 0 | } |
159 | | |
160 | | /* number of refs + current frame */ |
161 | 0 | int max_frame_num = sps->vui.i_max_dec_frame_buffering * (!!param->i_bframe_pyramid+1) + 1; |
162 | | /* Intra refresh cannot write a recovery time greater than max frame num-1 */ |
163 | 0 | if( param->b_intra_refresh ) |
164 | 0 | { |
165 | 0 | int time_to_recovery = X264_MIN( sps->i_mb_width - 1, param->i_keyint_max ) + param->i_bframe - 1; |
166 | 0 | max_frame_num = X264_MAX( max_frame_num, time_to_recovery+1 ); |
167 | 0 | } |
168 | |
|
169 | 0 | sps->i_log2_max_frame_num = 4; |
170 | 0 | while( (1 << sps->i_log2_max_frame_num) <= max_frame_num ) |
171 | 0 | sps->i_log2_max_frame_num++; |
172 | |
|
173 | 0 | sps->i_poc_type = param->i_bframe || param->b_interlaced || param->i_avcintra_class ? 0 : 2; |
174 | 0 | if( sps->i_poc_type == 0 ) |
175 | 0 | { |
176 | 0 | int max_delta_poc = (param->i_bframe + 2) * (!!param->i_bframe_pyramid + 1) * 2; |
177 | 0 | sps->i_log2_max_poc_lsb = 4; |
178 | 0 | while( (1 << sps->i_log2_max_poc_lsb) <= max_delta_poc * 2 ) |
179 | 0 | sps->i_log2_max_poc_lsb++; |
180 | 0 | } |
181 | |
|
182 | 0 | sps->b_vui = 1; |
183 | |
|
184 | 0 | sps->b_gaps_in_frame_num_value_allowed = 0; |
185 | 0 | sps->b_mb_adaptive_frame_field = param->b_interlaced; |
186 | 0 | sps->b_direct8x8_inference = 1; |
187 | |
|
188 | 0 | x264_sps_init_reconfigurable( sps, param ); |
189 | |
|
190 | 0 | sps->vui.b_overscan_info_present = param->vui.i_overscan > 0 && param->vui.i_overscan <= 2; |
191 | 0 | if( sps->vui.b_overscan_info_present ) |
192 | 0 | sps->vui.b_overscan_info = ( param->vui.i_overscan == 2 ? 1 : 0 ); |
193 | |
|
194 | 0 | sps->vui.b_signal_type_present = 0; |
195 | 0 | sps->vui.i_vidformat = ( param->vui.i_vidformat >= 0 && param->vui.i_vidformat <= 5 ? param->vui.i_vidformat : 5 ); |
196 | 0 | sps->vui.b_fullrange = ( param->vui.b_fullrange >= 0 && param->vui.b_fullrange <= 1 ? param->vui.b_fullrange : |
197 | 0 | ( csp >= X264_CSP_BGR ? 1 : 0 ) ); |
198 | 0 | sps->vui.b_color_description_present = 0; |
199 | |
|
200 | 0 | sps->vui.i_colorprim = ( param->vui.i_colorprim >= 0 && param->vui.i_colorprim <= 12 ? param->vui.i_colorprim : 2 ); |
201 | 0 | sps->vui.i_transfer = ( param->vui.i_transfer >= 0 && param->vui.i_transfer <= 18 ? param->vui.i_transfer : 2 ); |
202 | 0 | sps->vui.i_colmatrix = ( param->vui.i_colmatrix >= 0 && param->vui.i_colmatrix <= 14 ? param->vui.i_colmatrix : |
203 | 0 | ( csp >= X264_CSP_BGR ? 0 : 2 ) ); |
204 | 0 | if( sps->vui.i_colorprim != 2 || sps->vui.i_transfer != 2 || sps->vui.i_colmatrix != 2 ) |
205 | 0 | sps->vui.b_color_description_present = 1; |
206 | |
|
207 | 0 | if( sps->vui.i_vidformat != 5 || sps->vui.b_fullrange || sps->vui.b_color_description_present ) |
208 | 0 | sps->vui.b_signal_type_present = 1; |
209 | | |
210 | | /* FIXME: not sufficient for interlaced video */ |
211 | 0 | sps->vui.b_chroma_loc_info_present = param->vui.i_chroma_loc > 0 && param->vui.i_chroma_loc <= 5 && |
212 | 0 | sps->i_chroma_format_idc == CHROMA_420; |
213 | 0 | if( sps->vui.b_chroma_loc_info_present ) |
214 | 0 | { |
215 | 0 | sps->vui.i_chroma_loc_top = param->vui.i_chroma_loc; |
216 | 0 | sps->vui.i_chroma_loc_bottom = param->vui.i_chroma_loc; |
217 | 0 | } |
218 | |
|
219 | 0 | sps->vui.b_timing_info_present = param->i_timebase_num > 0 && param->i_timebase_den > 0; |
220 | |
|
221 | 0 | if( sps->vui.b_timing_info_present ) |
222 | 0 | { |
223 | 0 | sps->vui.i_num_units_in_tick = param->i_timebase_num; |
224 | 0 | sps->vui.i_time_scale = param->i_timebase_den * 2; |
225 | 0 | sps->vui.b_fixed_frame_rate = !param->b_vfr_input; |
226 | 0 | } |
227 | |
|
228 | 0 | sps->vui.b_vcl_hrd_parameters_present = 0; // we don't support VCL HRD |
229 | 0 | sps->vui.b_nal_hrd_parameters_present = !!param->i_nal_hrd; |
230 | 0 | sps->vui.b_pic_struct_present = param->b_pic_struct; |
231 | | |
232 | | // NOTE: HRD related parts of the SPS are initialised in x264_ratecontrol_init_reconfigurable |
233 | |
|
234 | 0 | sps->vui.b_bitstream_restriction = !(sps->b_constraint_set3 && sps->i_profile_idc >= PROFILE_HIGH); |
235 | 0 | if( sps->vui.b_bitstream_restriction ) |
236 | 0 | { |
237 | 0 | sps->vui.b_motion_vectors_over_pic_boundaries = 1; |
238 | 0 | sps->vui.i_max_bytes_per_pic_denom = 0; |
239 | 0 | sps->vui.i_max_bits_per_mb_denom = 0; |
240 | 0 | sps->vui.i_log2_max_mv_length_horizontal = |
241 | 0 | sps->vui.i_log2_max_mv_length_vertical = (int)log2f( X264_MAX( 1, param->analyse.i_mv_range*4-1 ) ) + 1; |
242 | 0 | } |
243 | |
|
244 | 0 | sps->b_avcintra_hd = param->i_avcintra_class && param->i_avcintra_class <= 200; |
245 | 0 | sps->b_avcintra_4k = param->i_avcintra_class > 200; |
246 | 0 | sps->i_cqm_preset = param->i_cqm_preset; |
247 | 0 | } Unexecuted instantiation: x264_8_sps_init Unexecuted instantiation: x264_10_sps_init |
248 | | |
249 | | void x264_sps_init_reconfigurable( x264_sps_t *sps, x264_param_t *param ) |
250 | 0 | { |
251 | 0 | sps->crop.i_left = param->crop_rect.i_left; |
252 | 0 | sps->crop.i_top = param->crop_rect.i_top; |
253 | 0 | sps->crop.i_right = param->crop_rect.i_right + sps->i_mb_width*16 - param->i_width; |
254 | 0 | sps->crop.i_bottom = param->crop_rect.i_bottom + sps->i_mb_height*16 - param->i_height; |
255 | 0 | sps->b_crop = sps->crop.i_left || sps->crop.i_top || |
256 | 0 | sps->crop.i_right || sps->crop.i_bottom; |
257 | |
|
258 | 0 | sps->vui.b_aspect_ratio_info_present = 0; |
259 | 0 | if( param->vui.i_sar_width > 0 && param->vui.i_sar_height > 0 ) |
260 | 0 | { |
261 | 0 | sps->vui.b_aspect_ratio_info_present = 1; |
262 | 0 | sps->vui.i_sar_width = param->vui.i_sar_width; |
263 | 0 | sps->vui.i_sar_height= param->vui.i_sar_height; |
264 | 0 | } |
265 | 0 | } Unexecuted instantiation: x264_8_sps_init_reconfigurable Unexecuted instantiation: x264_10_sps_init_reconfigurable |
266 | | |
267 | | void x264_sps_init_scaling_list( x264_sps_t *sps, x264_param_t *param ) |
268 | 0 | { |
269 | 0 | switch( sps->i_cqm_preset ) |
270 | 0 | { |
271 | 0 | case X264_CQM_FLAT: |
272 | 0 | for( int i = 0; i < 8; i++ ) |
273 | 0 | sps->scaling_list[i] = x264_cqm_flat16; |
274 | 0 | break; |
275 | 0 | case X264_CQM_JVT: |
276 | 0 | for( int i = 0; i < 8; i++ ) |
277 | 0 | sps->scaling_list[i] = x264_cqm_jvt[i]; |
278 | 0 | break; |
279 | 0 | case X264_CQM_CUSTOM: |
280 | | /* match the transposed DCT & zigzag */ |
281 | 0 | transpose( param->cqm_4iy, 4 ); |
282 | 0 | transpose( param->cqm_4py, 4 ); |
283 | 0 | transpose( param->cqm_4ic, 4 ); |
284 | 0 | transpose( param->cqm_4pc, 4 ); |
285 | 0 | transpose( param->cqm_8iy, 8 ); |
286 | 0 | transpose( param->cqm_8py, 8 ); |
287 | 0 | transpose( param->cqm_8ic, 8 ); |
288 | 0 | transpose( param->cqm_8pc, 8 ); |
289 | 0 | sps->scaling_list[CQM_4IY] = param->cqm_4iy; |
290 | 0 | sps->scaling_list[CQM_4PY] = param->cqm_4py; |
291 | 0 | sps->scaling_list[CQM_4IC] = param->cqm_4ic; |
292 | 0 | sps->scaling_list[CQM_4PC] = param->cqm_4pc; |
293 | 0 | sps->scaling_list[CQM_8IY+4] = param->cqm_8iy; |
294 | 0 | sps->scaling_list[CQM_8PY+4] = param->cqm_8py; |
295 | 0 | sps->scaling_list[CQM_8IC+4] = param->cqm_8ic; |
296 | 0 | sps->scaling_list[CQM_8PC+4] = param->cqm_8pc; |
297 | 0 | for( int i = 0; i < 8; i++ ) |
298 | 0 | for( int j = 0; j < (i < 4 ? 16 : 64); j++ ) |
299 | 0 | if( sps->scaling_list[i][j] == 0 ) |
300 | 0 | sps->scaling_list[i] = x264_cqm_jvt[i]; |
301 | 0 | break; |
302 | 0 | } |
303 | 0 | } Unexecuted instantiation: x264_8_sps_init_scaling_list Unexecuted instantiation: x264_10_sps_init_scaling_list |
304 | | |
305 | | void x264_sps_write( bs_t *s, x264_sps_t *sps ) |
306 | 0 | { |
307 | 0 | bs_realign( s ); |
308 | 0 | bs_write( s, 8, sps->i_profile_idc ); |
309 | 0 | bs_write1( s, sps->b_constraint_set0 ); |
310 | 0 | bs_write1( s, sps->b_constraint_set1 ); |
311 | 0 | bs_write1( s, sps->b_constraint_set2 ); |
312 | 0 | bs_write1( s, sps->b_constraint_set3 ); |
313 | |
|
314 | 0 | bs_write( s, 4, 0 ); /* reserved */ |
315 | |
|
316 | 0 | bs_write( s, 8, sps->i_level_idc ); |
317 | |
|
318 | 0 | bs_write_ue( s, sps->i_id ); |
319 | |
|
320 | 0 | if( sps->i_profile_idc >= PROFILE_HIGH ) |
321 | 0 | { |
322 | 0 | bs_write_ue( s, sps->i_chroma_format_idc ); |
323 | 0 | if( sps->i_chroma_format_idc == CHROMA_444 ) |
324 | 0 | bs_write1( s, 0 ); // separate_colour_plane_flag |
325 | 0 | bs_write_ue( s, BIT_DEPTH-8 ); // bit_depth_luma_minus8 |
326 | 0 | bs_write_ue( s, BIT_DEPTH-8 ); // bit_depth_chroma_minus8 |
327 | 0 | bs_write1( s, sps->b_qpprime_y_zero_transform_bypass ); |
328 | | /* Exactly match the AVC-Intra bitstream */ |
329 | 0 | bs_write1( s, sps->b_avcintra_hd ); // seq_scaling_matrix_present_flag |
330 | 0 | if( sps->b_avcintra_hd ) |
331 | 0 | { |
332 | 0 | scaling_list_write( s, sps, CQM_4IY ); |
333 | 0 | scaling_list_write( s, sps, CQM_4IC ); |
334 | 0 | scaling_list_write( s, sps, CQM_4IC ); |
335 | 0 | bs_write1( s, 0 ); // no inter |
336 | 0 | bs_write1( s, 0 ); // no inter |
337 | 0 | bs_write1( s, 0 ); // no inter |
338 | 0 | scaling_list_write( s, sps, CQM_8IY+4 ); |
339 | 0 | bs_write1( s, 0 ); // no inter |
340 | 0 | if( sps->i_chroma_format_idc == CHROMA_444 ) |
341 | 0 | { |
342 | 0 | scaling_list_write( s, sps, CQM_8IC+4 ); |
343 | 0 | bs_write1( s, 0 ); // no inter |
344 | 0 | scaling_list_write( s, sps, CQM_8IC+4 ); |
345 | 0 | bs_write1( s, 0 ); // no inter |
346 | 0 | } |
347 | 0 | } |
348 | 0 | } |
349 | |
|
350 | 0 | bs_write_ue( s, sps->i_log2_max_frame_num - 4 ); |
351 | 0 | bs_write_ue( s, sps->i_poc_type ); |
352 | 0 | if( sps->i_poc_type == 0 ) |
353 | 0 | bs_write_ue( s, sps->i_log2_max_poc_lsb - 4 ); |
354 | 0 | bs_write_ue( s, sps->i_num_ref_frames ); |
355 | 0 | bs_write1( s, sps->b_gaps_in_frame_num_value_allowed ); |
356 | 0 | bs_write_ue( s, sps->i_mb_width - 1 ); |
357 | 0 | bs_write_ue( s, (sps->i_mb_height >> !sps->b_frame_mbs_only) - 1); |
358 | 0 | bs_write1( s, sps->b_frame_mbs_only ); |
359 | 0 | if( !sps->b_frame_mbs_only ) |
360 | 0 | bs_write1( s, sps->b_mb_adaptive_frame_field ); |
361 | 0 | bs_write1( s, sps->b_direct8x8_inference ); |
362 | |
|
363 | 0 | bs_write1( s, sps->b_crop ); |
364 | 0 | if( sps->b_crop ) |
365 | 0 | { |
366 | 0 | int h_shift = sps->i_chroma_format_idc == CHROMA_420 || sps->i_chroma_format_idc == CHROMA_422; |
367 | 0 | int v_shift = (sps->i_chroma_format_idc == CHROMA_420) + !sps->b_frame_mbs_only; |
368 | 0 | bs_write_ue( s, sps->crop.i_left >> h_shift ); |
369 | 0 | bs_write_ue( s, sps->crop.i_right >> h_shift ); |
370 | 0 | bs_write_ue( s, sps->crop.i_top >> v_shift ); |
371 | 0 | bs_write_ue( s, sps->crop.i_bottom >> v_shift ); |
372 | 0 | } |
373 | |
|
374 | 0 | bs_write1( s, sps->b_vui ); |
375 | 0 | if( sps->b_vui ) |
376 | 0 | { |
377 | 0 | bs_write1( s, sps->vui.b_aspect_ratio_info_present ); |
378 | 0 | if( sps->vui.b_aspect_ratio_info_present ) |
379 | 0 | { |
380 | 0 | int i; |
381 | 0 | static const struct { uint8_t w, h, sar; } sar[] = |
382 | 0 | { |
383 | | // aspect_ratio_idc = 0 -> unspecified |
384 | 0 | { 1, 1, 1 }, { 12, 11, 2 }, { 10, 11, 3 }, { 16, 11, 4 }, |
385 | 0 | { 40, 33, 5 }, { 24, 11, 6 }, { 20, 11, 7 }, { 32, 11, 8 }, |
386 | 0 | { 80, 33, 9 }, { 18, 11, 10}, { 15, 11, 11}, { 64, 33, 12}, |
387 | 0 | {160, 99, 13}, { 4, 3, 14}, { 3, 2, 15}, { 2, 1, 16}, |
388 | | // aspect_ratio_idc = [17..254] -> reserved |
389 | 0 | { 0, 0, 255 } |
390 | 0 | }; |
391 | 0 | for( i = 0; sar[i].sar != 255; i++ ) |
392 | 0 | { |
393 | 0 | if( sar[i].w == sps->vui.i_sar_width && |
394 | 0 | sar[i].h == sps->vui.i_sar_height ) |
395 | 0 | break; |
396 | 0 | } |
397 | 0 | bs_write( s, 8, sar[i].sar ); |
398 | 0 | if( sar[i].sar == 255 ) /* aspect_ratio_idc (extended) */ |
399 | 0 | { |
400 | 0 | bs_write( s, 16, sps->vui.i_sar_width ); |
401 | 0 | bs_write( s, 16, sps->vui.i_sar_height ); |
402 | 0 | } |
403 | 0 | } |
404 | |
|
405 | 0 | bs_write1( s, sps->vui.b_overscan_info_present ); |
406 | 0 | if( sps->vui.b_overscan_info_present ) |
407 | 0 | bs_write1( s, sps->vui.b_overscan_info ); |
408 | |
|
409 | 0 | bs_write1( s, sps->vui.b_signal_type_present ); |
410 | 0 | if( sps->vui.b_signal_type_present ) |
411 | 0 | { |
412 | 0 | bs_write( s, 3, sps->vui.i_vidformat ); |
413 | 0 | bs_write1( s, sps->vui.b_fullrange ); |
414 | 0 | bs_write1( s, sps->vui.b_color_description_present ); |
415 | 0 | if( sps->vui.b_color_description_present ) |
416 | 0 | { |
417 | 0 | bs_write( s, 8, sps->vui.i_colorprim ); |
418 | 0 | bs_write( s, 8, sps->vui.i_transfer ); |
419 | 0 | bs_write( s, 8, sps->vui.i_colmatrix ); |
420 | 0 | } |
421 | 0 | } |
422 | |
|
423 | 0 | bs_write1( s, sps->vui.b_chroma_loc_info_present ); |
424 | 0 | if( sps->vui.b_chroma_loc_info_present ) |
425 | 0 | { |
426 | 0 | bs_write_ue( s, sps->vui.i_chroma_loc_top ); |
427 | 0 | bs_write_ue( s, sps->vui.i_chroma_loc_bottom ); |
428 | 0 | } |
429 | |
|
430 | 0 | bs_write1( s, sps->vui.b_timing_info_present ); |
431 | 0 | if( sps->vui.b_timing_info_present ) |
432 | 0 | { |
433 | 0 | bs_write32( s, sps->vui.i_num_units_in_tick ); |
434 | 0 | bs_write32( s, sps->vui.i_time_scale ); |
435 | 0 | bs_write1( s, sps->vui.b_fixed_frame_rate ); |
436 | 0 | } |
437 | |
|
438 | 0 | bs_write1( s, sps->vui.b_nal_hrd_parameters_present ); |
439 | 0 | if( sps->vui.b_nal_hrd_parameters_present ) |
440 | 0 | { |
441 | 0 | bs_write_ue( s, sps->vui.hrd.i_cpb_cnt - 1 ); |
442 | 0 | bs_write( s, 4, sps->vui.hrd.i_bit_rate_scale ); |
443 | 0 | bs_write( s, 4, sps->vui.hrd.i_cpb_size_scale ); |
444 | |
|
445 | 0 | bs_write_ue( s, sps->vui.hrd.i_bit_rate_value - 1 ); |
446 | 0 | bs_write_ue( s, sps->vui.hrd.i_cpb_size_value - 1 ); |
447 | |
|
448 | 0 | bs_write1( s, sps->vui.hrd.b_cbr_hrd ); |
449 | |
|
450 | 0 | bs_write( s, 5, sps->vui.hrd.i_initial_cpb_removal_delay_length - 1 ); |
451 | 0 | bs_write( s, 5, sps->vui.hrd.i_cpb_removal_delay_length - 1 ); |
452 | 0 | bs_write( s, 5, sps->vui.hrd.i_dpb_output_delay_length - 1 ); |
453 | 0 | bs_write( s, 5, sps->vui.hrd.i_time_offset_length ); |
454 | 0 | } |
455 | |
|
456 | 0 | bs_write1( s, sps->vui.b_vcl_hrd_parameters_present ); |
457 | |
|
458 | 0 | if( sps->vui.b_nal_hrd_parameters_present || sps->vui.b_vcl_hrd_parameters_present ) |
459 | 0 | bs_write1( s, 0 ); /* low_delay_hrd_flag */ |
460 | |
|
461 | 0 | bs_write1( s, sps->vui.b_pic_struct_present ); |
462 | 0 | bs_write1( s, sps->vui.b_bitstream_restriction ); |
463 | 0 | if( sps->vui.b_bitstream_restriction ) |
464 | 0 | { |
465 | 0 | bs_write1( s, sps->vui.b_motion_vectors_over_pic_boundaries ); |
466 | 0 | bs_write_ue( s, sps->vui.i_max_bytes_per_pic_denom ); |
467 | 0 | bs_write_ue( s, sps->vui.i_max_bits_per_mb_denom ); |
468 | 0 | bs_write_ue( s, sps->vui.i_log2_max_mv_length_horizontal ); |
469 | 0 | bs_write_ue( s, sps->vui.i_log2_max_mv_length_vertical ); |
470 | 0 | bs_write_ue( s, sps->vui.i_num_reorder_frames ); |
471 | 0 | bs_write_ue( s, sps->vui.i_max_dec_frame_buffering ); |
472 | 0 | } |
473 | 0 | } |
474 | |
|
475 | 0 | bs_rbsp_trailing( s ); |
476 | 0 | bs_flush( s ); |
477 | 0 | } Unexecuted instantiation: x264_8_sps_write Unexecuted instantiation: x264_10_sps_write |
478 | | |
479 | | void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *sps ) |
480 | 0 | { |
481 | 0 | pps->i_id = i_id; |
482 | 0 | pps->i_sps_id = sps->i_id; |
483 | 0 | pps->b_cabac = param->b_cabac; |
484 | |
|
485 | 0 | pps->b_pic_order = !param->i_avcintra_class && param->b_interlaced; |
486 | 0 | pps->i_num_slice_groups = 1; |
487 | |
|
488 | 0 | pps->i_num_ref_idx_l0_default_active = param->i_frame_reference; |
489 | 0 | pps->i_num_ref_idx_l1_default_active = 1; |
490 | |
|
491 | 0 | pps->b_weighted_pred = param->analyse.i_weighted_pred > 0; |
492 | 0 | pps->b_weighted_bipred = param->analyse.b_weighted_bipred ? 2 : 0; |
493 | |
|
494 | 0 | pps->i_pic_init_qp = param->rc.i_rc_method == X264_RC_ABR || param->b_stitchable ? 26 + QP_BD_OFFSET : SPEC_QP( param->rc.i_qp_constant ); |
495 | 0 | pps->i_pic_init_qs = 26 + QP_BD_OFFSET; |
496 | |
|
497 | 0 | pps->i_chroma_qp_index_offset = param->analyse.i_chroma_qp_offset; |
498 | 0 | pps->b_deblocking_filter_control = 1; |
499 | 0 | pps->b_constrained_intra_pred = param->b_constrained_intra; |
500 | 0 | pps->b_redundant_pic_cnt = 0; |
501 | |
|
502 | 0 | pps->b_transform_8x8_mode = param->analyse.b_transform_8x8 ? 1 : 0; |
503 | 0 | } Unexecuted instantiation: x264_8_pps_init Unexecuted instantiation: x264_10_pps_init |
504 | | |
505 | | void x264_pps_write( bs_t *s, x264_sps_t *sps, x264_pps_t *pps ) |
506 | 0 | { |
507 | 0 | bs_realign( s ); |
508 | 0 | bs_write_ue( s, pps->i_id ); |
509 | 0 | bs_write_ue( s, pps->i_sps_id ); |
510 | |
|
511 | 0 | bs_write1( s, pps->b_cabac ); |
512 | 0 | bs_write1( s, pps->b_pic_order ); |
513 | 0 | bs_write_ue( s, pps->i_num_slice_groups - 1 ); |
514 | |
|
515 | 0 | bs_write_ue( s, pps->i_num_ref_idx_l0_default_active - 1 ); |
516 | 0 | bs_write_ue( s, pps->i_num_ref_idx_l1_default_active - 1 ); |
517 | 0 | bs_write1( s, pps->b_weighted_pred ); |
518 | 0 | bs_write( s, 2, pps->b_weighted_bipred ); |
519 | |
|
520 | 0 | bs_write_se( s, pps->i_pic_init_qp - 26 - QP_BD_OFFSET ); |
521 | 0 | bs_write_se( s, pps->i_pic_init_qs - 26 - QP_BD_OFFSET ); |
522 | 0 | bs_write_se( s, pps->i_chroma_qp_index_offset ); |
523 | |
|
524 | 0 | bs_write1( s, pps->b_deblocking_filter_control ); |
525 | 0 | bs_write1( s, pps->b_constrained_intra_pred ); |
526 | 0 | bs_write1( s, pps->b_redundant_pic_cnt ); |
527 | |
|
528 | 0 | int b_scaling_list = !sps->b_avcintra_hd && sps->i_cqm_preset != X264_CQM_FLAT; |
529 | 0 | if( pps->b_transform_8x8_mode || b_scaling_list ) |
530 | 0 | { |
531 | 0 | bs_write1( s, pps->b_transform_8x8_mode ); |
532 | 0 | bs_write1( s, b_scaling_list ); |
533 | 0 | if( b_scaling_list ) |
534 | 0 | { |
535 | 0 | scaling_list_write( s, sps, CQM_4IY ); |
536 | 0 | scaling_list_write( s, sps, CQM_4IC ); |
537 | 0 | if( sps->b_avcintra_4k ) |
538 | 0 | { |
539 | 0 | scaling_list_write( s, sps, CQM_4IC ); |
540 | 0 | bs_write1( s, 0 ); // no inter |
541 | 0 | bs_write1( s, 0 ); // no inter |
542 | 0 | bs_write1( s, 0 ); // no inter |
543 | 0 | } |
544 | 0 | else |
545 | 0 | { |
546 | 0 | bs_write1( s, 0 ); // Cr = Cb |
547 | 0 | scaling_list_write( s, sps, CQM_4PY ); |
548 | 0 | scaling_list_write( s, sps, CQM_4PC ); |
549 | 0 | bs_write1( s, 0 ); // Cr = Cb |
550 | 0 | } |
551 | 0 | if( pps->b_transform_8x8_mode ) |
552 | 0 | { |
553 | 0 | scaling_list_write( s, sps, CQM_8IY+4 ); |
554 | 0 | if( sps->b_avcintra_4k ) |
555 | 0 | bs_write1( s, 0 ); // no inter |
556 | 0 | else |
557 | 0 | scaling_list_write( s, sps, CQM_8PY+4 ); |
558 | 0 | if( sps->i_chroma_format_idc == CHROMA_444 ) |
559 | 0 | { |
560 | 0 | scaling_list_write( s, sps, CQM_8IC+4 ); |
561 | 0 | scaling_list_write( s, sps, CQM_8PC+4 ); |
562 | 0 | bs_write1( s, 0 ); // Cr = Cb |
563 | 0 | bs_write1( s, 0 ); // Cr = Cb |
564 | 0 | } |
565 | 0 | } |
566 | 0 | } |
567 | 0 | bs_write_se( s, pps->i_chroma_qp_index_offset ); |
568 | 0 | } |
569 | |
|
570 | 0 | bs_rbsp_trailing( s ); |
571 | 0 | bs_flush( s ); |
572 | 0 | } Unexecuted instantiation: x264_8_pps_write Unexecuted instantiation: x264_10_pps_write |
573 | | |
574 | | void x264_sei_recovery_point_write( x264_t *h, bs_t *s, int recovery_frame_cnt ) |
575 | 0 | { |
576 | 0 | bs_t q; |
577 | 0 | ALIGNED_4( uint8_t tmp_buf[100] ); |
578 | 0 | M32( tmp_buf ) = 0; // shut up gcc |
579 | 0 | bs_init( &q, tmp_buf, 100 ); |
580 | |
|
581 | 0 | bs_realign( &q ); |
582 | |
|
583 | 0 | bs_write_ue( &q, recovery_frame_cnt ); // recovery_frame_cnt |
584 | 0 | bs_write1( &q, 1 ); //exact_match_flag 1 |
585 | 0 | bs_write1( &q, 0 ); //broken_link_flag 0 |
586 | 0 | bs_write( &q, 2, 0 ); //changing_slice_group 0 |
587 | |
|
588 | 0 | bs_align_10( &q ); |
589 | |
|
590 | 0 | x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_RECOVERY_POINT ); |
591 | 0 | } Unexecuted instantiation: x264_8_sei_recovery_point_write Unexecuted instantiation: x264_10_sei_recovery_point_write |
592 | | |
593 | | int x264_sei_version_write( x264_t *h, bs_t *s ) |
594 | 0 | { |
595 | | // random ID number generated according to ISO-11578 |
596 | 0 | static const uint8_t uuid[16] = |
597 | 0 | { |
598 | 0 | 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, |
599 | 0 | 0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee, 0xef |
600 | 0 | }; |
601 | 0 | char *opts = x264_param2string( &h->param, 0 ); |
602 | 0 | char *payload; |
603 | 0 | int length; |
604 | |
|
605 | 0 | if( !opts ) |
606 | 0 | return -1; |
607 | 0 | CHECKED_MALLOC( payload, 200 + strlen( opts ) ); |
608 | | |
609 | 0 | memcpy( payload, uuid, 16 ); |
610 | 0 | sprintf( payload+16, "x264 - core %d%s - H.264/MPEG-4 AVC codec - " |
611 | 0 | "Copy%s 2003-2025 - http://www.videolan.org/x264.html - options: %s", |
612 | 0 | X264_BUILD, X264_VERSION, HAVE_GPL?"left":"right", opts ); |
613 | 0 | length = strlen(payload)+1; |
614 | |
|
615 | 0 | x264_sei_write( s, (uint8_t *)payload, length, SEI_USER_DATA_UNREGISTERED ); |
616 | |
|
617 | 0 | x264_free( opts ); |
618 | 0 | x264_free( payload ); |
619 | 0 | return 0; |
620 | 0 | fail: |
621 | 0 | x264_free( opts ); |
622 | 0 | return -1; |
623 | 0 | } Unexecuted instantiation: x264_8_sei_version_write Unexecuted instantiation: x264_10_sei_version_write |
624 | | |
625 | | void x264_sei_buffering_period_write( x264_t *h, bs_t *s ) |
626 | 0 | { |
627 | 0 | x264_sps_t *sps = h->sps; |
628 | 0 | bs_t q; |
629 | 0 | ALIGNED_4( uint8_t tmp_buf[100] ); |
630 | 0 | M32( tmp_buf ) = 0; // shut up gcc |
631 | 0 | bs_init( &q, tmp_buf, 100 ); |
632 | |
|
633 | 0 | bs_realign( &q ); |
634 | 0 | bs_write_ue( &q, sps->i_id ); |
635 | |
|
636 | 0 | if( sps->vui.b_nal_hrd_parameters_present ) |
637 | 0 | { |
638 | 0 | bs_write( &q, sps->vui.hrd.i_initial_cpb_removal_delay_length, h->initial_cpb_removal_delay ); |
639 | 0 | bs_write( &q, sps->vui.hrd.i_initial_cpb_removal_delay_length, h->initial_cpb_removal_delay_offset ); |
640 | 0 | } |
641 | |
|
642 | 0 | bs_align_10( &q ); |
643 | |
|
644 | 0 | x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_BUFFERING_PERIOD ); |
645 | 0 | } Unexecuted instantiation: x264_8_sei_buffering_period_write Unexecuted instantiation: x264_10_sei_buffering_period_write |
646 | | |
647 | | void x264_sei_pic_timing_write( x264_t *h, bs_t *s ) |
648 | 0 | { |
649 | 0 | x264_sps_t *sps = h->sps; |
650 | 0 | bs_t q; |
651 | 0 | ALIGNED_4( uint8_t tmp_buf[100] ); |
652 | 0 | M32( tmp_buf ) = 0; // shut up gcc |
653 | 0 | bs_init( &q, tmp_buf, 100 ); |
654 | |
|
655 | 0 | bs_realign( &q ); |
656 | |
|
657 | 0 | if( sps->vui.b_nal_hrd_parameters_present || sps->vui.b_vcl_hrd_parameters_present ) |
658 | 0 | { |
659 | 0 | bs_write( &q, sps->vui.hrd.i_cpb_removal_delay_length, h->fenc->i_cpb_delay - h->i_cpb_delay_pir_offset ); |
660 | 0 | bs_write( &q, sps->vui.hrd.i_dpb_output_delay_length, h->fenc->i_dpb_output_delay ); |
661 | 0 | } |
662 | |
|
663 | 0 | if( sps->vui.b_pic_struct_present ) |
664 | 0 | { |
665 | 0 | bs_write( &q, 4, h->fenc->i_pic_struct-1 ); // We use index 0 for "Auto" |
666 | | |
667 | | // These clock timestamps are not standardised so we don't set them |
668 | | // They could be time of origin, capture or alternative ideal display |
669 | 0 | for( int i = 0; i < num_clock_ts[h->fenc->i_pic_struct]; i++ ) |
670 | 0 | bs_write1( &q, 0 ); // clock_timestamp_flag |
671 | 0 | } |
672 | |
|
673 | 0 | bs_align_10( &q ); |
674 | |
|
675 | 0 | x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_PIC_TIMING ); |
676 | 0 | } Unexecuted instantiation: x264_8_sei_pic_timing_write Unexecuted instantiation: x264_10_sei_pic_timing_write |
677 | | |
678 | | void x264_sei_frame_packing_write( x264_t *h, bs_t *s ) |
679 | 0 | { |
680 | 0 | int quincunx_sampling_flag = h->param.i_frame_packing == 0; |
681 | 0 | bs_t q; |
682 | 0 | ALIGNED_4( uint8_t tmp_buf[100] ); |
683 | 0 | M32( tmp_buf ) = 0; // shut up gcc |
684 | 0 | bs_init( &q, tmp_buf, 100 ); |
685 | |
|
686 | 0 | bs_realign( &q ); |
687 | |
|
688 | 0 | bs_write_ue( &q, 0 ); // frame_packing_arrangement_id |
689 | 0 | bs_write1( &q, 0 ); // frame_packing_arrangement_cancel_flag |
690 | 0 | bs_write ( &q, 7, h->param.i_frame_packing ); // frame_packing_arrangement_type |
691 | 0 | bs_write1( &q, quincunx_sampling_flag ); // quincunx_sampling_flag |
692 | | |
693 | | // 0: views are unrelated, 1: left view is on the left, 2: left view is on the right |
694 | 0 | bs_write ( &q, 6, h->param.i_frame_packing != 6 ); // content_interpretation_type |
695 | |
|
696 | 0 | bs_write1( &q, 0 ); // spatial_flipping_flag |
697 | 0 | bs_write1( &q, 0 ); // frame0_flipped_flag |
698 | 0 | bs_write1( &q, 0 ); // field_views_flag |
699 | 0 | bs_write1( &q, h->param.i_frame_packing == 5 && !(h->fenc->i_frame&1) ); // current_frame_is_frame0_flag |
700 | 0 | bs_write1( &q, 0 ); // frame0_self_contained_flag |
701 | 0 | bs_write1( &q, 0 ); // frame1_self_contained_flag |
702 | 0 | if( quincunx_sampling_flag == 0 && h->param.i_frame_packing != 5 ) |
703 | 0 | { |
704 | 0 | bs_write( &q, 4, 0 ); // frame0_grid_position_x |
705 | 0 | bs_write( &q, 4, 0 ); // frame0_grid_position_y |
706 | 0 | bs_write( &q, 4, 0 ); // frame1_grid_position_x |
707 | 0 | bs_write( &q, 4, 0 ); // frame1_grid_position_y |
708 | 0 | } |
709 | 0 | bs_write( &q, 8, 0 ); // frame_packing_arrangement_reserved_byte |
710 | | // "frame_packing_arrangement_repetition_period equal to 1 specifies that the frame packing arrangement SEI message persists in output" |
711 | | // for (i_frame_packing == 5) this will undermine current_frame_is_frame0_flag which must alternate every view sequence |
712 | 0 | bs_write_ue( &q, h->param.i_frame_packing != 5 ); // frame_packing_arrangement_repetition_period |
713 | 0 | bs_write1( &q, 0 ); // frame_packing_arrangement_extension_flag |
714 | |
|
715 | 0 | bs_align_10( &q ); |
716 | |
|
717 | 0 | x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_FRAME_PACKING ); |
718 | 0 | } Unexecuted instantiation: x264_8_sei_frame_packing_write Unexecuted instantiation: x264_10_sei_frame_packing_write |
719 | | |
720 | | void x264_sei_mastering_display_write( x264_t *h, bs_t *s ) |
721 | 0 | { |
722 | 0 | bs_t q; |
723 | 0 | ALIGNED_4( uint8_t tmp_buf[100] ); |
724 | 0 | M32( tmp_buf ) = 0; // shut up gcc |
725 | 0 | bs_init( &q, tmp_buf, 100 ); |
726 | |
|
727 | 0 | bs_realign( &q ); |
728 | |
|
729 | 0 | bs_write( &q, 16, h->param.mastering_display.i_green_x ); |
730 | 0 | bs_write( &q, 16, h->param.mastering_display.i_green_y ); |
731 | 0 | bs_write( &q, 16, h->param.mastering_display.i_blue_x ); |
732 | 0 | bs_write( &q, 16, h->param.mastering_display.i_blue_y ); |
733 | 0 | bs_write( &q, 16, h->param.mastering_display.i_red_x ); |
734 | 0 | bs_write( &q, 16, h->param.mastering_display.i_red_y ); |
735 | 0 | bs_write( &q, 16, h->param.mastering_display.i_white_x ); |
736 | 0 | bs_write( &q, 16, h->param.mastering_display.i_white_y ); |
737 | 0 | bs_write32( &q, h->param.mastering_display.i_display_max ); |
738 | 0 | bs_write32( &q, h->param.mastering_display.i_display_min ); |
739 | |
|
740 | 0 | bs_align_10( &q ); |
741 | |
|
742 | 0 | x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_MASTERING_DISPLAY ); |
743 | 0 | } Unexecuted instantiation: x264_8_sei_mastering_display_write Unexecuted instantiation: x264_10_sei_mastering_display_write |
744 | | |
745 | | void x264_sei_content_light_level_write( x264_t *h, bs_t *s ) |
746 | 0 | { |
747 | 0 | bs_t q; |
748 | 0 | ALIGNED_4( uint8_t tmp_buf[100] ); |
749 | 0 | M32( tmp_buf ) = 0; // shut up gcc |
750 | 0 | bs_init( &q, tmp_buf, 100 ); |
751 | |
|
752 | 0 | bs_realign( &q ); |
753 | |
|
754 | 0 | bs_write( &q, 16, h->param.content_light_level.i_max_cll ); |
755 | 0 | bs_write( &q, 16, h->param.content_light_level.i_max_fall ); |
756 | |
|
757 | 0 | bs_align_10( &q ); |
758 | |
|
759 | 0 | x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_CONTENT_LIGHT_LEVEL ); |
760 | 0 | } Unexecuted instantiation: x264_8_sei_content_light_level_write Unexecuted instantiation: x264_10_sei_content_light_level_write |
761 | | |
762 | | void x264_sei_alternative_transfer_write( x264_t *h, bs_t *s ) |
763 | 0 | { |
764 | 0 | bs_t q; |
765 | 0 | ALIGNED_4( uint8_t tmp_buf[100] ); |
766 | 0 | M32( tmp_buf ) = 0; // shut up gcc |
767 | 0 | bs_init( &q, tmp_buf, 100 ); |
768 | |
|
769 | 0 | bs_realign( &q ); |
770 | |
|
771 | 0 | bs_write ( &q, 8, h->param.i_alternative_transfer ); // preferred_transfer_characteristics |
772 | |
|
773 | 0 | bs_align_10( &q ); |
774 | |
|
775 | 0 | x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_ALTERNATIVE_TRANSFER ); |
776 | 0 | } Unexecuted instantiation: x264_8_sei_alternative_transfer_write Unexecuted instantiation: x264_10_sei_alternative_transfer_write |
777 | | |
778 | | void x264_filler_write( x264_t *h, bs_t *s, int filler ) |
779 | 0 | { |
780 | 0 | bs_realign( s ); |
781 | |
|
782 | 0 | for( int i = 0; i < filler; i++ ) |
783 | 0 | bs_write( s, 8, 0xff ); |
784 | |
|
785 | 0 | bs_rbsp_trailing( s ); |
786 | 0 | bs_flush( s ); |
787 | 0 | } Unexecuted instantiation: x264_8_filler_write Unexecuted instantiation: x264_10_filler_write |
788 | | |
789 | | void x264_sei_dec_ref_pic_marking_write( x264_t *h, bs_t *s ) |
790 | 0 | { |
791 | 0 | x264_slice_header_t *sh = &h->sh_backup; |
792 | 0 | bs_t q; |
793 | 0 | ALIGNED_4( uint8_t tmp_buf[100] ); |
794 | 0 | M32( tmp_buf ) = 0; // shut up gcc |
795 | 0 | bs_init( &q, tmp_buf, 100 ); |
796 | |
|
797 | 0 | bs_realign( &q ); |
798 | | |
799 | | /* We currently only use this for repeating B-refs, as required by Blu-ray. */ |
800 | 0 | bs_write1( &q, 0 ); //original_idr_flag |
801 | 0 | bs_write_ue( &q, sh->i_frame_num ); //original_frame_num |
802 | 0 | if( !h->sps->b_frame_mbs_only ) |
803 | 0 | bs_write1( &q, 0 ); //original_field_pic_flag |
804 | |
|
805 | 0 | bs_write1( &q, sh->i_mmco_command_count > 0 ); |
806 | 0 | if( sh->i_mmco_command_count > 0 ) |
807 | 0 | { |
808 | 0 | for( int i = 0; i < sh->i_mmco_command_count; i++ ) |
809 | 0 | { |
810 | 0 | bs_write_ue( &q, 1 ); |
811 | 0 | bs_write_ue( &q, sh->mmco[i].i_difference_of_pic_nums - 1 ); |
812 | 0 | } |
813 | 0 | bs_write_ue( &q, 0 ); |
814 | 0 | } |
815 | |
|
816 | 0 | bs_align_10( &q ); |
817 | |
|
818 | 0 | x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_DEC_REF_PIC_MARKING ); |
819 | 0 | } Unexecuted instantiation: x264_8_sei_dec_ref_pic_marking_write Unexecuted instantiation: x264_10_sei_dec_ref_pic_marking_write |
820 | | |
821 | | int x264_sei_avcintra_umid_write( x264_t *h, bs_t *s ) |
822 | 0 | { |
823 | 0 | uint8_t data[512]; |
824 | 0 | const char *msg = "UMID"; |
825 | 0 | const int len = 497; |
826 | |
|
827 | 0 | memset( data, 0xff, len ); |
828 | 0 | memcpy( data, avcintra_uuid, sizeof(avcintra_uuid) ); |
829 | 0 | memcpy( data+16, msg, strlen(msg) ); |
830 | |
|
831 | 0 | data[20] = 0x13; |
832 | | /* These bytes appear to be some sort of frame/seconds counter in certain applications, |
833 | | * but others jump around, so leave them as zero for now */ |
834 | 0 | data[22] = data[23] = data[25] = data[26] = 0; |
835 | 0 | data[28] = 0x14; |
836 | 0 | data[30] = data[31] = data[33] = data[34] = 0; |
837 | 0 | data[36] = 0x60; |
838 | 0 | data[41] = 0x22; /* Believed to be some sort of end of basic UMID identifier */ |
839 | 0 | data[60] = 0x62; |
840 | 0 | data[62] = data[63] = data[65] = data[66] = 0; |
841 | 0 | data[68] = 0x63; |
842 | 0 | data[70] = data[71] = data[73] = data[74] = 0; |
843 | |
|
844 | 0 | x264_sei_write( &h->out.bs, data, len, SEI_USER_DATA_UNREGISTERED ); |
845 | |
|
846 | 0 | return 0; |
847 | 0 | } Unexecuted instantiation: x264_8_sei_avcintra_umid_write Unexecuted instantiation: x264_10_sei_avcintra_umid_write |
848 | | |
849 | | int x264_sei_avcintra_vanc_write( x264_t *h, bs_t *s, int len ) |
850 | 0 | { |
851 | 0 | uint8_t data[6000]; |
852 | 0 | const char *msg = "VANC"; |
853 | 0 | if( len < 0 || (unsigned)len > sizeof(data) ) |
854 | 0 | { |
855 | 0 | x264_log( h, X264_LOG_ERROR, "AVC-Intra SEI is too large (%d)\n", len ); |
856 | 0 | return -1; |
857 | 0 | } |
858 | | |
859 | 0 | memset( data, 0xff, len ); |
860 | 0 | memcpy( data, avcintra_uuid, sizeof(avcintra_uuid) ); |
861 | 0 | memcpy( data+16, msg, strlen(msg) ); |
862 | |
|
863 | 0 | x264_sei_write( &h->out.bs, data, len, SEI_USER_DATA_UNREGISTERED ); |
864 | |
|
865 | 0 | return 0; |
866 | 0 | } Unexecuted instantiation: x264_8_sei_avcintra_vanc_write Unexecuted instantiation: x264_10_sei_avcintra_vanc_write |
867 | | |
868 | | #undef ERROR |
869 | 0 | #define ERROR(...)\ |
870 | 0 | {\ |
871 | 0 | if( verbose )\ |
872 | 0 | x264_log( h, X264_LOG_WARNING, __VA_ARGS__ );\ |
873 | 0 | ret = 1;\ |
874 | 0 | } |
875 | | |
876 | | int x264_validate_levels( x264_t *h, int verbose ) |
877 | 0 | { |
878 | 0 | int ret = 0; |
879 | 0 | int mbs = h->sps->i_mb_width * h->sps->i_mb_height; |
880 | 0 | int dpb = mbs * h->sps->vui.i_max_dec_frame_buffering; |
881 | 0 | int cbp_factor = h->sps->i_profile_idc>=PROFILE_HIGH422 ? 16 : |
882 | 0 | h->sps->i_profile_idc==PROFILE_HIGH10 ? 12 : |
883 | 0 | h->sps->i_profile_idc==PROFILE_HIGH ? 5 : 4; |
884 | |
|
885 | 0 | const x264_level_t *l = x264_levels; |
886 | 0 | while( l->level_idc != 0 && l->level_idc != h->param.i_level_idc ) |
887 | 0 | l++; |
888 | |
|
889 | 0 | if( l->frame_size < mbs |
890 | 0 | || l->frame_size*8 < h->sps->i_mb_width * h->sps->i_mb_width |
891 | 0 | || l->frame_size*8 < h->sps->i_mb_height * h->sps->i_mb_height ) |
892 | 0 | ERROR( "frame MB size (%dx%d) > level limit (%d)\n", |
893 | 0 | h->sps->i_mb_width, h->sps->i_mb_height, l->frame_size ); |
894 | 0 | if( dpb > l->dpb ) |
895 | 0 | ERROR( "DPB size (%d frames, %d mbs) > level limit (%d frames, %d mbs)\n", |
896 | 0 | h->sps->vui.i_max_dec_frame_buffering, dpb, l->dpb / mbs, l->dpb ); |
897 | |
|
898 | 0 | #define CHECK( name, limit, val ) \ |
899 | 0 | if( (val) > (limit) ) \ |
900 | 0 | ERROR( name " (%"PRId64") > level limit (%d)\n", (int64_t)(val), (limit) ); |
901 | |
|
902 | 0 | CHECK( "VBV bitrate", (l->bitrate * cbp_factor) / 4, h->param.rc.i_vbv_max_bitrate ); |
903 | 0 | CHECK( "VBV buffer", (l->cpb * cbp_factor) / 4, h->param.rc.i_vbv_buffer_size ); |
904 | 0 | CHECK( "MV range", l->mv_range, h->param.analyse.i_mv_range ); |
905 | 0 | CHECK( "interlaced", !l->frame_only, h->param.b_interlaced ); |
906 | 0 | CHECK( "fake interlaced", !l->frame_only, h->param.b_fake_interlaced ); |
907 | |
|
908 | 0 | if( h->param.i_fps_den > 0 ) |
909 | 0 | CHECK( "MB rate", l->mbps, (int64_t)mbs * h->param.i_fps_num / h->param.i_fps_den ); |
910 | | |
911 | | /* TODO check the rest of the limits */ |
912 | 0 | return ret; |
913 | 0 | } Unexecuted instantiation: x264_8_validate_levels Unexecuted instantiation: x264_10_validate_levels |