1 /******************************************************************************
2 *
3 * Copyright (C) 2022 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20
21 /**
22 *******************************************************************************
23 * @file
24 * isvce_encode_header.c
25 *
26 * @brief
27 * This file contains function definitions related to header encoding.
28 *
29 * @author
30 * ittiam
31 *
32 * @par List of Functions:
33 * - isvce_generate_sps()
34 * - isvce_generate_pps()
35 * - isvce_generate_slice_header()
36 * - isvce_populate_sps()
37 * - isvce_populate_pps()
38 * - isvce_populate_slice_header()
39 *
40 *******************************************************************************
41 */
42
43 #include "ih264_typedefs.h"
44 #include "ih264_debug.h"
45
46 /* Dependencies of ih264e_bitstream.h */
47 #include "ih264e_error.h"
48
49 #include "ih264e_bitstream.h"
50
51 #include "isvce_encode_header.h"
52 #include "isvce_utils.h"
53
isvce_generate_nal_unit_header(bitstrm_t * ps_bitstrm,WORD32 nal_unit_type,WORD32 nal_ref_idc)54 static FORCEINLINE IH264E_ERROR_T isvce_generate_nal_unit_header(bitstrm_t *ps_bitstrm,
55 WORD32 nal_unit_type,
56 WORD32 nal_ref_idc)
57 {
58 WORD32 return_status = IH264E_SUCCESS;
59
60 if(!((nal_unit_type > 0) && (nal_unit_type < 32)))
61 {
62 return IH264E_FAIL;
63 }
64
65 /* forbidden_zero_bit + nal_ref_idc + nal_unit_type */
66 PUT_BITS(ps_bitstrm, ((nal_ref_idc << 5) + nal_unit_type),
67 (1 + 2 + 5), /*1 forbidden zero bit + 2 nal_ref_idc + 5 nal_unit_type */
68 return_status, "nal_unit_header");
69
70 return return_status;
71 }
72
73 /**
74 ******************************************************************************
75 *
76 * @brief Generates SPS (Sequence Parameter Set)
77 *
78 * @par Description
79 * This function generates Sequence Parameter Set header as per the spec
80 *
81 * @param[in] ps_bitstrm
82 * pointer to bitstream context (handle)
83 *
84 * @param[in] ps_sps
85 * pointer to structure containing SPS data
86 *
87 * @param[in] ps_vui
88 * pointer to structure containing VUI data
89 *
90 * @return success or failure error code
91 *
92 ******************************************************************************
93 */
isvce_generate_sps(bitstrm_t * ps_bitstrm,sps_t * ps_sps,NAL_UNIT_TYPE_T nal_type)94 WORD32 isvce_generate_sps(bitstrm_t *ps_bitstrm, sps_t *ps_sps, NAL_UNIT_TYPE_T nal_type)
95 {
96 WORD32 return_status = IH264E_SUCCESS;
97 WORD32 i;
98 WORD8 i1_nal_ref_idc = 3;
99 vui_t *ps_vui = &ps_sps->s_vui_parameters;
100
101 /* Insert Start Code */
102 return_status = ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
103 if(return_status != IH264E_SUCCESS)
104 {
105 return return_status;
106 }
107 /* Insert Nal Unit Header */
108 return_status = isvce_generate_nal_unit_header(ps_bitstrm, nal_type, i1_nal_ref_idc);
109 if(return_status != IH264E_SUCCESS)
110 {
111 return return_status;
112 }
113
114 /* profile_idc */
115 PUT_BITS(ps_bitstrm, ps_sps->u1_profile_idc, 8, return_status, "profile_idc");
116
117 /* constrained_set_flags */
118 PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set0_flag, 1, return_status,
119 "constrained_set0_flag");
120 PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set1_flag, 1, return_status,
121 "constrained_set1_flag");
122 PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set2_flag, 1, return_status,
123 "constrained_set2_flag");
124 PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set3_flag, 1, return_status,
125 "constrained_set3_flag");
126
127 /* reserved_zero_four_bits */
128 PUT_BITS(ps_bitstrm, 0, 4, return_status, "reserved_zero_four_bits");
129
130 /* level_idc */
131 PUT_BITS(ps_bitstrm, ps_sps->u1_level_idc, 8, return_status, "level_idc");
132
133 /* seq_parameter_set_id */
134 PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_sps_id, return_status, "seq_parameter_set_id");
135
136 if((ps_sps->u1_profile_idc == IH264_SCALABLE_BASELINE) ||
137 (ps_sps->u1_profile_idc >= IH264_PROFILE_HIGH))
138 {
139 /* chroma_format_idc */
140 PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_chroma_format_idc, return_status, "chroma_format_idc");
141
142 if(ps_sps->u1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
143 {
144 /* i1_residual_colour_transform_flag */
145 PUT_BITS(ps_bitstrm, ps_sps->i1_residual_colour_transform_flag, 1, return_status,
146 "i1_residual_colour_transform_flag");
147 }
148
149 /* bit_depth_luma_minus8 */
150 PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_bit_depth_luma - 8), return_status,
151 "bit_depth_luma_minus8");
152
153 /* bit_depth_chroma_minus8 */
154 PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_bit_depth_chroma - 8), return_status,
155 "bit_depth_chroma_minus8");
156
157 /* qpprime_y_zero_transform_bypass_flag */
158 PUT_BITS(ps_bitstrm, ps_sps->i1_qpprime_y_zero_transform_bypass_flag, 1, return_status,
159 "qpprime_y_zero_transform_bypass_flag");
160
161 /* seq_scaling_matrix_present_flag */
162 PUT_BITS(ps_bitstrm, ps_sps->i1_seq_scaling_matrix_present_flag, 1, return_status,
163 "seq_scaling_matrix_present_flag");
164
165 /* seq_scaling_list */
166 if(ps_sps->i1_seq_scaling_matrix_present_flag)
167 {
168 /* TODO_LATER: Will be enabled once scaling list support is added */
169 }
170 }
171
172 /* log2_max_frame_num_minus4 */
173 PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_log2_max_frame_num - 4), return_status,
174 "log2_max_frame_num_minus4");
175
176 /* pic_order_cnt_type */
177 PUT_BITS_UEV(ps_bitstrm, ps_sps->i1_pic_order_cnt_type, return_status, "pic_order_cnt_type");
178
179 if(ps_sps->i1_pic_order_cnt_type == 0)
180 {
181 /* log2_max_pic_order_cnt_lsb_minus4 */
182 PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_log2_max_pic_order_cnt_lsb - 4), return_status,
183 "log2_max_pic_order_cnt_lsb_minus4");
184 }
185 else if(ps_sps->i1_pic_order_cnt_type == 1)
186 {
187 /* delta_pic_order_always_zero_flag */
188 PUT_BITS(ps_bitstrm, ps_sps->i1_delta_pic_order_always_zero_flag, 1, return_status,
189 "delta_pic_order_always_zero_flag");
190
191 /* offset_for_non_ref_pic */
192 PUT_BITS_SEV(ps_bitstrm, ps_sps->i4_offset_for_non_ref_pic, return_status,
193 "offset_for_non_ref_pic");
194
195 /* offset_for_top_to_bottom_field */
196 PUT_BITS_SEV(ps_bitstrm, ps_sps->i4_offset_for_top_to_bottom_field, return_status,
197 "offset_for_top_to_bottom_field");
198
199 /* num_ref_frames_in_pic_order_cnt_cycle */
200 PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_num_ref_frames_in_pic_order_cnt_cycle, return_status,
201 "num_ref_frames_in_pic_order_cnt_cycle");
202
203 /* Offset for ref frame */
204 for(i = 0; i < ps_sps->u1_num_ref_frames_in_pic_order_cnt_cycle; i++)
205 {
206 /* offset_for_ref_frame */
207 PUT_BITS_SEV(ps_bitstrm, ps_sps->ai4_offset_for_ref_frame[i], return_status,
208 "offset_for_ref_frame");
209 }
210 }
211
212 /* num_ref_frames */
213 PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_max_num_ref_frames, return_status, "num_ref_frames");
214
215 /* gaps_in_frame_num_value_allowed_flag */
216 PUT_BITS(ps_bitstrm, ps_sps->i1_gaps_in_frame_num_value_allowed_flag, 1, return_status,
217 "gaps_in_frame_num_value_allowed_flag");
218
219 /* pic_width_in_mbs_minus1 */
220 PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_pic_width_in_mbs_minus1, return_status,
221 "pic_width_in_mbs_minus1");
222
223 /* pic_height_in_map_units_minus1 */
224 PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_pic_height_in_map_units_minus1, return_status,
225 "pic_height_in_map_units_minus1");
226
227 /* frame_mbs_only_flag */
228 PUT_BITS(ps_bitstrm, ps_sps->i1_frame_mbs_only_flag, 1, return_status, "frame_mbs_only_flag");
229
230 if(!ps_sps->i1_frame_mbs_only_flag)
231 {
232 /* mb_adaptive_frame_field_flag */
233 PUT_BITS(ps_bitstrm, ps_sps->i1_mb_adaptive_frame_field_flag, 1, return_status,
234 "mb_adaptive_frame_field_flag");
235 }
236
237 /* direct_8x8_inference_flag */
238 PUT_BITS(ps_bitstrm, ps_sps->i1_direct_8x8_inference_flag, 1, return_status,
239 "direct_8x8_inference_flag");
240
241 /* frame_cropping_flag */
242 PUT_BITS(ps_bitstrm, ps_sps->i1_frame_cropping_flag, 1, return_status, "frame_cropping_flag");
243
244 if(ps_sps->i1_frame_cropping_flag)
245 {
246 /* frame_crop_left_offset */
247 PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_left_offset, return_status,
248 "frame_crop_left_offset");
249
250 /* frame_crop_right_offset */
251 PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_right_offset, return_status,
252 "frame_crop_right_offset");
253
254 /* frame_crop_top_offset */
255 PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_top_offset, return_status,
256 "frame_crop_top_offset");
257
258 /* frame_crop_bottom_offset */
259 PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_bottom_offset, return_status,
260 "frame_crop_bottom_offset");
261 }
262
263 /* vui_parameters_present_flag */
264 PUT_BITS(ps_bitstrm, ps_sps->i1_vui_parameters_present_flag, 1, return_status,
265 "vui_parameters_present_flag");
266
267 if(ps_sps->i1_vui_parameters_present_flag)
268 {
269 /* Add vui parameters to the bitstream */;
270 return_status = ih264e_generate_vui(ps_bitstrm, ps_vui);
271 if(return_status != IH264E_SUCCESS)
272 {
273 return return_status;
274 }
275 }
276
277 if(nal_type != NAL_SUBSET_SPS)
278 {
279 /* rbsp trailing bits */
280 return_status = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
281 }
282
283 return return_status;
284 }
285
286 /**
287 ******************************************************************************
288 *
289 * @brief Generates PPS (Picture Parameter Set)
290 *
291 * @par Description
292 * Generate Picture Parameter Set as per Section 7.3.2.2
293 *
294 * @param[in] ps_bitstrm
295 * pointer to bitstream context (handle)
296 *
297 * @param[in] ps_pps
298 * pointer to structure containing PPS data
299 *
300 * @return success or failure error code
301 *
302 ******************************************************************************
303 */
isvce_generate_pps(bitstrm_t * ps_bitstrm,pps_t * ps_pps,sps_t * ps_sps)304 WORD32 isvce_generate_pps(bitstrm_t *ps_bitstrm, pps_t *ps_pps, sps_t *ps_sps)
305 {
306 WORD32 return_status = IH264E_SUCCESS;
307
308 /* Insert the NAL start code */
309 return_status = ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
310 if(return_status != IH264E_SUCCESS)
311 {
312 return return_status;
313 }
314
315 /* Insert Nal Unit Header */
316 PUT_BITS(ps_bitstrm, NAL_PPS_FIRST_BYTE, 8, return_status, "pps_header");
317
318 /* pic_parameter_set_id */
319 PUT_BITS_UEV(ps_bitstrm, ps_pps->u1_pps_id, return_status, "pic_parameter_set_id");
320
321 /* seq_parameter_set_id */
322 PUT_BITS_UEV(ps_bitstrm, ps_pps->u1_sps_id, return_status, "seq_parameter_set_id");
323
324 /* Entropy coding : 0-VLC; 1 - CABAC */
325 PUT_BITS(ps_bitstrm, ps_pps->u1_entropy_coding_mode_flag, 1, return_status,
326 "Entropy coding : 0-VLC; 1 - CABAC");
327
328 /* Pic order present flag */
329 PUT_BITS(ps_bitstrm, ps_pps->u1_pic_order_present_flag, 1, return_status,
330 "Pic order present flag");
331
332 /* Number of slice groups */
333 PUT_BITS_UEV(ps_bitstrm, ps_pps->u1_num_slice_groups - 1, return_status,
334 "Number of slice groups");
335
336 if(ps_pps->u1_num_slice_groups > 1)
337 {
338 /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
339 * If this is not the case, we have to add Slice group map type to the bit
340 * stream*/
341 }
342
343 /* num_ref_idx_l0_default_active_minus1 */
344 PUT_BITS_UEV(ps_bitstrm, ps_pps->i1_num_ref_idx_l0_default_active - 1, return_status,
345 "num_ref_idx_l0_default_active_minus1");
346
347 /* num_ref_idx_l1_default_active_minus1 */
348 PUT_BITS_UEV(ps_bitstrm, ps_pps->i1_num_ref_idx_l1_default_active - 1, return_status,
349 "num_ref_idx_l1_default_active_minus1");
350
351 /* weighted_pred_flag */
352 PUT_BITS(ps_bitstrm, ps_pps->i1_weighted_pred_flag, 1, return_status, "weighted_pred_flag");
353
354 /* weighted_bipred_flag */
355 PUT_BITS(ps_bitstrm, ps_pps->i1_weighted_bipred_idc, 2, return_status, "weighted_bipred_idc");
356
357 /* pic_init_qp_minus26 */
358 PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_pic_init_qp - 26, return_status, "pic_init_qp_minus26");
359
360 /* pic_init_qs_minus26 */
361 PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_pic_init_qs - 26, return_status, "pic_init_qs_minus26");
362
363 /* chroma_qp_index_offset */
364 PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_chroma_qp_index_offset, return_status,
365 "chroma_qp_index_offset");
366
367 /* deblocking_filter_control_present_flag */
368 PUT_BITS(ps_bitstrm, ps_pps->i1_deblocking_filter_control_present_flag, 1, return_status,
369 "deblocking_filter_control_present_flag");
370
371 /* constrained_intra_pred_flag */
372 PUT_BITS(ps_bitstrm, ps_pps->i1_constrained_intra_pred_flag, 1, return_status,
373 "constrained_intra_pred_flag");
374
375 /*redundant_pic_cnt_present_flag */
376 PUT_BITS(ps_bitstrm, ps_pps->i1_redundant_pic_cnt_present_flag, 1, return_status,
377 "redundant_pic_cnt_present_flag");
378
379 if(ps_sps->u1_profile_idc >= IH264_PROFILE_HIGH)
380 {
381 /* transform_8x8_mode_flag */
382 PUT_BITS(ps_bitstrm, ps_pps->i1_transform_8x8_mode_flag, 1, return_status,
383 "transform_8x8_mode_flag");
384
385 /* pic_scaling_matrix_present_flag */
386 PUT_BITS(ps_bitstrm, ps_pps->i1_pic_scaling_matrix_present_flag, 1, return_status,
387 "pic_scaling_matrix_present_flag");
388
389 if(ps_pps->i1_pic_scaling_matrix_present_flag)
390 {
391 /* TODO_LATER: Will be enabled once scaling list support is added */
392 }
393
394 /* Second chroma QP offset */
395 PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_second_chroma_qp_index_offset, return_status,
396 "Second chroma QP offset");
397 }
398
399 return_status = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
400
401 return return_status;
402 }
403
404 /**
405 ******************************************************************************
406 *
407 * @brief Generates Slice Header
408 *
409 * @par Description
410 * Generate Slice Header as per Section 7.3.5.1
411 *
412 * @param[inout] ps_bitstrm
413 * pointer to bitstream context for generating slice header
414 *
415 * @param[in] ps_slice_hdr
416 * pointer to slice header params
417 *
418 * @param[in] ps_pps
419 * pointer to pps params referred by slice
420 *
421 * @param[in] ps_sps
422 * pointer to sps params referred by slice
423 *
424 * @param[out] ps_dup_bit_strm_ent_offset
425 * Bitstream struct to store bitstream state
426 *
427 * @param[out] pu4_first_slice_start_offset
428 * first slice offset is returned
429 *
430 * @return success or failure error code
431 *
432 ******************************************************************************
433 */
isvce_generate_slice_header(bitstrm_t * ps_bitstrm,slice_header_t * ps_slice_hdr,pps_t * ps_pps,sps_t * ps_sps,UWORD8 u1_idr_flag)434 WORD32 isvce_generate_slice_header(bitstrm_t *ps_bitstrm, slice_header_t *ps_slice_hdr,
435 pps_t *ps_pps, sps_t *ps_sps, UWORD8 u1_idr_flag)
436 {
437 WORD32 return_status = IH264E_SUCCESS;
438 UWORD8 u1_slice_type;
439
440 /* Insert start code */
441 return_status = ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
442 if(return_status != IH264E_SUCCESS)
443 {
444 return return_status;
445 }
446 /* Insert Nal Unit Header */
447 return_status = isvce_generate_nal_unit_header(ps_bitstrm, ps_slice_hdr->i1_nal_unit_type,
448 ps_slice_hdr->i1_nal_unit_idc);
449 if(return_status != IH264E_SUCCESS)
450 {
451 return return_status;
452 }
453 /* first_mb_in_slice */
454 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u2_first_mb_in_slice, return_status,
455 "first_mb_in_slice");
456
457 /* slice_type */
458 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_slice_type, return_status, "slice_type");
459
460 /* pic_parameter_set_id */
461 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_pps_id, return_status, "pic_parameter_set_id");
462
463 /* frame_num */
464 PUT_BITS(ps_bitstrm, ps_slice_hdr->i4_frame_num, ps_sps->i1_log2_max_frame_num, return_status,
465 "frame_num");
466
467 if(!ps_sps->i1_frame_mbs_only_flag)
468 {
469 /* field_pic_flag */
470 PUT_BITS(ps_bitstrm, ps_slice_hdr->i1_field_pic_flag, 1, return_status, "field_pic_flag");
471
472 if(ps_slice_hdr->i1_field_pic_flag)
473 {
474 /* bottom_field_flag */
475 PUT_BITS(ps_bitstrm, ps_slice_hdr->i1_bottom_field_flag, 1, return_status,
476 "bottom_field_flag");
477 }
478 }
479
480 if(u1_idr_flag == 1)
481 {
482 /* u2_idr_pic_id */
483 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u2_idr_pic_id, return_status, "idr_pic_id");
484 }
485
486 if(ps_sps->i1_pic_order_cnt_type == 0)
487 {
488 /* pic_order_cnt_lsb */
489 PUT_BITS(ps_bitstrm, ps_slice_hdr->i4_pic_order_cnt_lsb,
490 ps_sps->i1_log2_max_pic_order_cnt_lsb, return_status, "pic_order_cnt_lsb");
491
492 if(ps_pps->u1_pic_order_present_flag && !ps_slice_hdr->i1_field_pic_flag)
493 {
494 /* delta_pic_order_cnt_bottom */
495 PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i4_delta_pic_order_cnt_bottom, return_status,
496 "delta_pic_order_cnt_bottom");
497 }
498 }
499
500 if(ps_sps->i1_pic_order_cnt_type == 1 && !ps_sps->i1_delta_pic_order_always_zero_flag)
501 {
502 /* delta_pic_order_cnt[0] */
503 PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->ai4_delta_pic_order_cnt[0], return_status,
504 "delta_pic_order_cnt[0]");
505
506 if(ps_pps->u1_pic_order_present_flag && !ps_slice_hdr->i1_field_pic_flag)
507 {
508 /* delta_pic_order_cnt[1] */
509 PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->ai4_delta_pic_order_cnt[1], return_status,
510 "delta_pic_order_cnt[1]");
511 }
512 }
513
514 if(ps_pps->i1_redundant_pic_cnt_present_flag)
515 {
516 /* redundant_pic_cnt */
517 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_redundant_pic_cnt, return_status,
518 "redundant_pic_cnt");
519 }
520
521 u1_slice_type = ps_slice_hdr->u1_slice_type % EPSLICE;
522
523 if(u1_slice_type == BSLICE)
524 {
525 /* direct_spatial_mv_pred_flag */
526 PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_direct_spatial_mv_pred_flag, 1, return_status,
527 "direct_spatial_mv_pred_flag");
528 }
529
530 if(u1_slice_type == PSLICE || u1_slice_type == SPSLICE || u1_slice_type == BSLICE)
531 {
532 /* num_ref_idx_active_override_flag */
533 PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_num_ref_idx_active_override_flag, 1, return_status,
534 "num_ref_idx_active_override_flag");
535
536 if(ps_slice_hdr->u1_num_ref_idx_active_override_flag)
537 {
538 /* num_ref_idx_l0_active_minus1 */
539 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_num_ref_idx_l0_active - 1, return_status,
540 "num_ref_idx_l0_active_minus1");
541
542 if(u1_slice_type == BSLICE)
543 {
544 /* num_ref_idx_l1_active_minus1 */
545 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_num_ref_idx_l1_active - 1, return_status,
546 "num_ref_idx_l1_active_minus1");
547 }
548 }
549 }
550
551 /* ref_pic_list_modification */
552 if((u1_slice_type != ISLICE) && (u1_slice_type != SISLICE))
553 {
554 /* ref_pic_list_modification_flag_l0 */
555 PUT_BITS(ps_bitstrm, ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l0, 1,
556 return_status, "ref_pic_list_modification_flag_l0");
557
558 if(ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l0)
559 {
560 UWORD8 i = 0;
561
562 WORD8 *pi1_modification_of_pic_nums_idc_l0 =
563 ps_slice_hdr->s_rplm.i1_modification_of_pic_nums_idc_l0;
564 UWORD32 *pu4_abs_diff_pic_num_minus1_l0 =
565 ps_slice_hdr->s_rplm.u4_abs_diff_pic_num_minus1_l0;
566 UWORD8 *pu1_long_term_pic_num_l0 = ps_slice_hdr->s_rplm.u1_long_term_pic_num_l0;
567
568 do
569 {
570 /* modification_of_pic_nums_idc */
571 PUT_BITS_UEV(ps_bitstrm, pi1_modification_of_pic_nums_idc_l0[i], return_status,
572 "modification_of_pic_nums_idc");
573
574 if((0 == pi1_modification_of_pic_nums_idc_l0[i]) ||
575 (1 == pi1_modification_of_pic_nums_idc_l0[i]))
576 {
577 /* abs_diff_pic_num_minus1 */
578 PUT_BITS_UEV(ps_bitstrm, pu4_abs_diff_pic_num_minus1_l0[0], return_status,
579 "abs_diff_pic_num_minus1");
580
581 pu4_abs_diff_pic_num_minus1_l0++;
582 }
583 else if(2 == pi1_modification_of_pic_nums_idc_l0[i])
584 {
585 /* long_term_pic_num */
586 PUT_BITS_UEV(ps_bitstrm, pu1_long_term_pic_num_l0[0], return_status,
587 "abs_diff_pic_num_minus1");
588
589 pu1_long_term_pic_num_l0++;
590 }
591 } while(pi1_modification_of_pic_nums_idc_l0[i++] != 3);
592 }
593 }
594
595 if(u1_slice_type == BSLICE)
596 {
597 /* ref_pic_list_modification_flag_l1 */
598 PUT_BITS(ps_bitstrm, ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l1, 1,
599 return_status, "ref_pic_list_modification_flag_l1");
600
601 if(ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l1)
602 {
603 UWORD8 i = 0;
604
605 WORD8 *pi1_modification_of_pic_nums_idc_l1 =
606 ps_slice_hdr->s_rplm.i1_modification_of_pic_nums_idc_l1;
607 UWORD32 *pu4_abs_diff_pic_num_minus1_l1 =
608 ps_slice_hdr->s_rplm.u4_abs_diff_pic_num_minus1_l1;
609 UWORD8 *pu1_long_term_pic_num_l1 = ps_slice_hdr->s_rplm.u1_long_term_pic_num_l1;
610
611 do
612 {
613 /* modification_of_pic_nums_idc */
614 PUT_BITS_UEV(ps_bitstrm, pi1_modification_of_pic_nums_idc_l1[i], return_status,
615 "modification_of_pic_nums_idc");
616
617 if((0 == pi1_modification_of_pic_nums_idc_l1[i]) ||
618 (1 == pi1_modification_of_pic_nums_idc_l1[i]))
619 {
620 /* abs_diff_pic_num_minus1 */
621 PUT_BITS_UEV(ps_bitstrm, pu4_abs_diff_pic_num_minus1_l1[0], return_status,
622 "abs_diff_pic_num_minus1");
623
624 pu4_abs_diff_pic_num_minus1_l1++;
625 }
626 else if(2 == pi1_modification_of_pic_nums_idc_l1[i])
627 {
628 /* long_term_pic_num */
629 PUT_BITS_UEV(ps_bitstrm, pu1_long_term_pic_num_l1[0], return_status,
630 "abs_diff_pic_num_minus1");
631
632 pu1_long_term_pic_num_l1++;
633 }
634 } while(pi1_modification_of_pic_nums_idc_l1[i++] != 3);
635 }
636 }
637
638 if((ps_pps->i1_weighted_pred_flag && u1_slice_type == PSLICE) ||
639 (u1_slice_type == BSLICE && ps_pps->i1_weighted_bipred_idc == 1))
640 {
641 /* TODO_LATER: Currently there is no support for weighted prediction.
642 This needs to be updated when the support is added */
643 }
644
645 if(ps_slice_hdr->i1_nal_unit_idc != 0)
646 {
647 if(u1_idr_flag == 1)
648 {
649 /* no_output_of_prior_pics_flag */
650 PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_no_output_of_prior_pics_flag, 1, return_status,
651 "no_output_of_prior_pics_flag ");
652
653 /* long_term_reference_flag */
654 PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_long_term_reference_flag, 1, return_status,
655 "long_term_reference_flag ");
656 }
657 else
658 {
659 /* adaptive_ref_pic_marking_mode_flag */
660 PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag, 1,
661 return_status, "adaptive_ref_pic_marking_mode_flag ");
662
663 if(ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag)
664 {
665 /* TODO: if the reference picture marking mode is adaptive
666 add these fields in the bit-stream */
667 }
668 }
669 }
670
671 if(ps_slice_hdr->u1_entropy_coding_mode_flag && u1_slice_type != ISLICE &&
672 u1_slice_type != SISLICE)
673 {
674 /* cabac_init_idc */
675 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_cabac_init_idc, return_status, "cabac_init_idc");
676 }
677
678 /* slice_qp_delta */
679 PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_qp - ps_pps->i1_pic_init_qp, return_status,
680 "slice_qp_delta");
681
682 if(ps_slice_hdr->u1_slice_type == SPSLICE || ps_slice_hdr->u1_slice_type == SISLICE)
683 {
684 if(ps_slice_hdr->u1_slice_type == SPSLICE)
685 {
686 /* sp_for_switch_flag */
687 PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_sp_for_switch_flag, 1, return_status,
688 "sp_for_switch_flag");
689 }
690 /* slice_qs_delta */
691 PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->u1_slice_qs - ps_pps->i1_pic_init_qs, return_status,
692 "slice_qs_delta");
693 }
694
695 if(ps_pps->i1_deblocking_filter_control_present_flag)
696 {
697 /* disable_deblocking_filter_idc */
698 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_disable_deblocking_filter_idc, return_status,
699 "disable_deblocking_filter_idc");
700
701 if(ps_slice_hdr->u1_disable_deblocking_filter_idc != 1)
702 {
703 /* slice_alpha_c0_offset_div2 */
704 PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_alpha_c0_offset_div2, return_status,
705 "slice_alpha_c0_offset_div2");
706
707 /* slice_beta_offset_div2 */
708 PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_beta_offset_div2, return_status,
709 "slice_beta_offset_div2");
710 }
711 }
712
713 if(ps_slice_hdr->u1_num_slice_groups_minus1 > 0 && ps_pps->u1_slice_group_map_type >= 3 &&
714 ps_pps->u1_slice_group_map_type <= 5)
715 {
716 /* slice_group_change_cycle */
717 /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
718 * If this is not the case, we have to add Slice group map type to the bit
719 * stream */
720 }
721
722 return return_status;
723 }
724
725 /**
726 ******************************************************************************
727 *
728 * @brief Populates VUI structure
729 *
730 * @par Description
731 * Populates VUI structure for its use in header generation
732 *
733 * @param[in] ps_codec
734 * pointer to encoder context
735 *
736 * @return success or failure error code
737 *
738 ******************************************************************************
739 */
isvce_populate_vui(isvce_codec_t * ps_codec,sps_t * ps_sps)740 static IH264E_ERROR_T isvce_populate_vui(isvce_codec_t *ps_codec, sps_t *ps_sps)
741 {
742 vui_t *ps_vui = &ps_sps->s_vui_parameters;
743
744 ps_vui->u1_nal_hrd_parameters_present_flag = 0;
745 ps_vui->u1_vcl_hrd_parameters_present_flag = 0;
746
747 ps_vui->u1_bitstream_restriction_flag = 1;
748 ps_vui->u1_motion_vectors_over_pic_boundaries_flag = 1;
749 ps_vui->u1_max_bytes_per_pic_denom = 0;
750 ps_vui->u1_max_bits_per_mb_denom = 0;
751 ps_vui->u1_log2_max_mv_length_horizontal = 16;
752 ps_vui->u1_log2_max_mv_length_vertical = 16;
753
754 if(ps_codec->s_cfg.u4_num_bframes == 0)
755 {
756 ps_vui->u1_num_reorder_frames = 0;
757 }
758 else
759 {
760 ps_vui->u1_num_reorder_frames = 1;
761 }
762
763 ps_vui->u1_max_dec_frame_buffering = ps_sps->u1_max_num_ref_frames;
764
765 return 0;
766 }
767
768 /**
769 ******************************************************************************
770 *
771 * @brief Populates sps structure
772 *
773 * @par Description
774 * Populates sps structure for its use in header generation
775 *
776 * @param[in] ps_codec
777 * pointer to encoder context
778 *
779 * @param[out] ps_sps
780 * pointer to sps params that needs to be populated
781 *
782 * @return success or failure error code
783 *
784 ******************************************************************************
785 */
isvce_populate_sps(isvce_codec_t * ps_codec,sps_t * ps_sps,UWORD8 u1_sps_id,UWORD8 u1_profile_idc,isvce_inp_buf_t * ps_inp_buf,UWORD8 u1_spatial_layer_id)786 IH264E_ERROR_T isvce_populate_sps(isvce_codec_t *ps_codec, sps_t *ps_sps, UWORD8 u1_sps_id,
787 UWORD8 u1_profile_idc, isvce_inp_buf_t *ps_inp_buf,
788 UWORD8 u1_spatial_layer_id)
789 {
790 /* active config parameters */
791 isvce_cfg_params_t *ps_cfg = &(ps_codec->s_cfg);
792
793 // /* level */
794 // IH264_LEVEL_T level_idc;
795
796 /* error_status */
797 IH264E_ERROR_T i4_err_code = IH264E_FAIL;
798
799 /* profile */
800 /*
801 * Baseline profile supports, 8 bits per sample, 4:2:0 format, CAVLC.
802 * B frames are not allowed. Further, Flexible mb ordering, Redundant slices,
803 * Arbitrary slice ordering are supported. The constrained baseline profile is
804 * baseline profile minus ASO, FMO and redundant slices. To the constrained
805 * baseline profile if we add support for B slices, support for encoding
806 * interlaced frames, support for weighted prediction and introduce CABAC
807 * entropy coding then we have Main Profile.
808 */
809 ps_sps->u1_profile_idc = u1_profile_idc;
810
811 /* level */
812 ps_sps->u1_level_idc = MAX(
813 ps_cfg->u4_max_level, (UWORD32) ih264e_get_min_level(ps_cfg->u4_max_wd, ps_cfg->u4_max_ht));
814
815 /* constrained flags */
816 /*
817 * baseline profile automatically implies set 0 flag
818 */
819 ps_sps->u1_constraint_set0_flag = (ps_sps->u1_profile_idc == IH264_PROFILE_BASELINE);
820 /*
821 * main profile automatically implies set 1 flag
822 * Although the encoder says it supports Baseline profile it actually supports
823 * constrained baseline profile as ASO, FMO and redundant slices are not
824 * supported
825 */
826 ps_sps->u1_constraint_set1_flag = (ps_sps->u1_profile_idc <= IH264_PROFILE_MAIN);
827 /*
828 * extended profile is not supported
829 */
830 ps_sps->u1_constraint_set2_flag = 0x00;
831 /*
832 * level 1b or level 11
833 */
834 if(ps_sps->u1_level_idc == IH264_LEVEL_1B)
835 {
836 ps_sps->u1_constraint_set3_flag = 0;
837 ps_sps->u1_level_idc = IH264_LEVEL_11;
838 }
839 else
840 {
841 ps_sps->u1_constraint_set3_flag = 0;
842 }
843
844 /* active sps id */
845 ps_sps->u1_sps_id = u1_sps_id;
846
847 if((ps_sps->u1_profile_idc == IH264_SCALABLE_BASELINE) ||
848 (ps_sps->u1_profile_idc >= IH264_PROFILE_HIGH))
849 {
850 /* chroma format idc */
851 ps_sps->u1_chroma_format_idc = CHROMA_FMT_IDC_YUV420;
852
853 /* residual_colour_transform_flag */
854 ps_sps->i1_residual_colour_transform_flag = 0;
855
856 /* luma bit depth 8 */
857 ps_sps->i1_bit_depth_luma = 8;
858
859 /* chroma bit depth 8 */
860 ps_sps->i1_bit_depth_chroma = 8;
861
862 /* qpprime_y_zero_transform_bypass_flag */
863 ps_sps->i1_qpprime_y_zero_transform_bypass_flag = 0;
864
865 /* seq_scaling_matrix_present_flag */
866 ps_sps->i1_seq_scaling_matrix_present_flag = 0;
867
868 if(ps_sps->i1_seq_scaling_matrix_present_flag)
869 {
870 /* TODO_LATER: Will be enabled once scaling list support is added */
871 }
872 }
873
874 /* log2_max_frame_num_minus4 */
875 ps_sps->i1_log2_max_frame_num = LOG2_MAX_FRAME_NUM_MINUS4 + 4;
876
877 /* pic_order_cnt_type */
878 ps_sps->i1_pic_order_cnt_type = 2;
879
880 if(ps_codec->i4_non_ref_frames_in_stream)
881 {
882 ps_sps->i1_pic_order_cnt_type = 0;
883 }
884
885 /* log2_max_pic_order_cnt_lsb_minus4 */
886 ps_sps->i1_log2_max_pic_order_cnt_lsb = 8;
887
888 /* TODO : add support for other poc types */
889 if(ps_sps->i1_pic_order_cnt_type == 0)
890 {
891 }
892 else if(ps_sps->i1_pic_order_cnt_type == 1)
893 {
894 }
895
896 ps_sps->u1_max_num_ref_frames = ps_codec->i4_max_num_reference_frames;
897
898 /* gaps_in_frame_num_value_allowed_flag */
899 ps_sps->i1_gaps_in_frame_num_value_allowed_flag = 0;
900
901 /* pic width in mb - 1 */
902 ps_sps->i2_pic_width_in_mbs_minus1 =
903 (ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_width >> 4) - 1;
904
905 /* pic height in mb - 1 */
906 ps_sps->i2_pic_height_in_map_units_minus1 =
907 (ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_height >> 4) - 1;
908
909 /* frame_mbs_only_flag, no support for interlace encoding */
910 ps_sps->i1_frame_mbs_only_flag = 1;
911
912 /* mb_adaptive_frame_field_flag */
913 if(ps_sps->i1_frame_mbs_only_flag == 0)
914 {
915 ps_sps->i1_mb_adaptive_frame_field_flag = 0;
916 }
917
918 /* direct_8x8_inference_flag */
919 if(ps_sps->u1_level_idc < IH264_LEVEL_30)
920 {
921 ps_sps->i1_direct_8x8_inference_flag = 0;
922 }
923 else
924 {
925 ps_sps->i1_direct_8x8_inference_flag = 1;
926 }
927
928 /* cropping params */
929 /*NOTE : Cropping values depend on the chroma format
930 * For our case ,decoder interprets the cropping values as 2*num pixels
931 * Hence the difference in the disp width and width must be halved before
932 * sending to get the expected results
933 */
934 ps_sps->i1_frame_cropping_flag = 0;
935 ps_sps->i2_frame_crop_left_offset = 0;
936 ps_sps->i2_frame_crop_right_offset = (ps_codec->s_cfg.u4_wd - ps_codec->s_cfg.u4_disp_wd) >> 1;
937 ps_sps->i2_frame_crop_top_offset = 0;
938 ps_sps->i2_frame_crop_bottom_offset = (ps_codec->s_cfg.u4_ht - ps_codec->s_cfg.u4_disp_ht) >> 1;
939
940 if(ps_sps->i2_frame_crop_left_offset || ps_sps->i2_frame_crop_right_offset ||
941 ps_sps->i2_frame_crop_top_offset || ps_sps->i2_frame_crop_bottom_offset)
942 {
943 ps_sps->i1_frame_cropping_flag = 1;
944 }
945
946 /* vui params */
947 ps_sps->i1_vui_parameters_present_flag = !(ps_cfg->u4_disable_vui);
948
949 if(!ps_sps->i1_vui_parameters_present_flag)
950 {
951 /* populate vui params */
952 isvce_populate_vui(ps_codec, ps_sps);
953 }
954 else
955 {
956 ps_sps->s_vui_parameters = ps_cfg->s_vui;
957 }
958
959 return i4_err_code;
960 }
961
962 /**
963 ******************************************************************************
964 *
965 * @brief Populates pps structure
966 *
967 * @par Description
968 * Populates pps structure for its use in header generation
969 *
970 * @param[in] ps_codec
971 * pointer to encoder context
972 *
973 * @param[out] ps_pps
974 * pointer to pps params that needs to be populated
975 *
976 * @return success or failure error code
977 *
978 ******************************************************************************
979 */
isvce_populate_pps(isvce_codec_t * ps_codec,pps_t * ps_pps,UWORD8 u1_sps_id,UWORD8 u1_pps_id,UWORD8 u1_spatial_layer_id)980 IH264E_ERROR_T isvce_populate_pps(isvce_codec_t *ps_codec, pps_t *ps_pps, UWORD8 u1_sps_id,
981 UWORD8 u1_pps_id, UWORD8 u1_spatial_layer_id)
982 {
983 /* seq_parameter_set_id */
984 ps_pps->u1_sps_id = u1_sps_id;
985
986 /* pic_parameter_set_id */
987 ps_pps->u1_pps_id = u1_pps_id;
988
989 /* entropy_coding_mode */
990 ps_pps->u1_entropy_coding_mode_flag =
991 ((ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers > 1) && (0 == u1_spatial_layer_id))
992 ? CAVLC
993 : ps_codec->s_cfg.u4_entropy_coding_mode;
994
995 /* pic_order_present_flag is unset if we don't have feilds */
996 ps_pps->u1_pic_order_present_flag = 0;
997
998 /* Currently number of slice groups supported are 1 */
999 ps_pps->u1_num_slice_groups = 1;
1000
1001 if(ps_pps->u1_num_slice_groups - 1)
1002 {
1003 /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
1004 * If this is not the case, we have to add Slice group map type to the bit
1005 * stream*/
1006 }
1007
1008 /* number of reference frames for list 0 */
1009 /* FIXME : fix this hard coded value */
1010 ps_pps->i1_num_ref_idx_l0_default_active = 1;
1011
1012 /* number of reference frames for list 1 */
1013 ps_pps->i1_num_ref_idx_l1_default_active = 1;
1014
1015 /* weighted prediction for now is disabled */
1016 ps_pps->i1_weighted_pred_flag = 0;
1017 ps_pps->i1_weighted_bipred_idc = 0;
1018
1019 /* The intent is to not signal qp from pps. Rather send the same in slice
1020 * headers */
1021 ps_pps->i1_pic_init_qp = 0;
1022
1023 /* The intent is to not signal qp from pps. Rather send the same in slice
1024 * headers */
1025 ps_pps->i1_pic_init_qs = 0;
1026
1027 /* The intent is to not signal qp from pps. Rather send the same in slice
1028 * headers */
1029 ps_pps->i1_chroma_qp_index_offset = 0;
1030
1031 /* deblocking filter flags present in slice header */
1032 ps_pps->i1_deblocking_filter_control_present_flag = 1;
1033
1034 /* constrained intra prediction */
1035 ps_pps->i1_constrained_intra_pred_flag =
1036 ps_codec->au4_constrained_intra_pred[u1_spatial_layer_id];
1037
1038 /* sending redundant slices is not supported for now */
1039 ps_pps->i1_redundant_pic_cnt_present_flag = 0;
1040
1041 ps_pps->u1_slice_group_map_type = 0;
1042
1043 return IH264E_SUCCESS;
1044 }
1045
1046 /**
1047 ******************************************************************************
1048 *
1049 * @brief Populates slice header structure
1050 *
1051 * @par Description
1052 * Populates slice header structure for its use in header generation
1053 *
1054 * @param[in] ps_proc
1055 * pointer to proc context
1056 *
1057 * @param[out] ps_slice_hdr
1058 * pointer to slice header structure that needs to be populated
1059 *
1060 * @param[in] ps_pps
1061 * pointer to pps params structure referred by the slice
1062 *
1063 * @param[in] ps_sps
1064 * pointer to sps params referred by the pps
1065 *
1066 * @return success or failure error code
1067 *
1068 ******************************************************************************
1069 */
isvce_populate_slice_header(isvce_process_ctxt_t * ps_proc,slice_header_t * ps_slice_hdr,pps_t * ps_pps,sps_t * ps_sps,UWORD8 u1_is_idr)1070 WORD32 isvce_populate_slice_header(isvce_process_ctxt_t *ps_proc, slice_header_t *ps_slice_hdr,
1071 pps_t *ps_pps, sps_t *ps_sps, UWORD8 u1_is_idr)
1072 {
1073 /* entropy context */
1074 isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
1075
1076 isvce_codec_t *ps_codec = ps_proc->ps_codec;
1077
1078 if(ps_codec->u4_is_curr_frm_ref)
1079 {
1080 ps_slice_hdr->i1_nal_unit_idc = 3;
1081 }
1082 else
1083 {
1084 ps_slice_hdr->i1_nal_unit_idc = 0;
1085 }
1086
1087 /* start mb address */
1088 ps_slice_hdr->u2_first_mb_in_slice = ps_entropy->i4_mb_start_add;
1089
1090 /* slice type */
1091 ps_slice_hdr->u1_slice_type = ps_proc->i4_slice_type;
1092
1093 /* pic_parameter_set_id */
1094 ps_slice_hdr->u1_pps_id = ps_pps->u1_pps_id;
1095
1096 /* Separate color plane flag is 0,
1097 * hence the syntax element color_plane_id not included */
1098
1099 /* frame num */
1100 ps_slice_hdr->i4_frame_num = ps_proc->i4_frame_num;
1101
1102 /* frame_mbs_only_flag, no support for interlace encoding */
1103 if(!ps_sps->i1_frame_mbs_only_flag)
1104 {
1105 ps_slice_hdr->i1_field_pic_flag = 0;
1106
1107 if(ps_slice_hdr->i1_field_pic_flag)
1108 {
1109 ps_slice_hdr->i1_bottom_field_flag = 0;
1110 }
1111 }
1112
1113 /* idr pic id */
1114 if(u1_is_idr)
1115 {
1116 ps_slice_hdr->u2_idr_pic_id = ps_proc->u4_idr_pic_id;
1117 ps_slice_hdr->i1_nal_unit_type = NAL_SLICE_IDR;
1118 }
1119 else
1120 {
1121 ps_slice_hdr->i1_nal_unit_type = NAL_SLICE_NON_IDR;
1122 }
1123
1124 if(ps_proc->u1_spatial_layer_id > 0)
1125 {
1126 ps_slice_hdr->i1_nal_unit_type = NAL_CODED_SLICE_EXTENSION;
1127 }
1128
1129 if(ps_sps->i1_pic_order_cnt_type == 0)
1130 {
1131 WORD32 i4_poc;
1132 i4_poc = ps_codec->i4_poc;
1133 i4_poc %= (1 << ps_sps->i1_log2_max_pic_order_cnt_lsb);
1134 ps_slice_hdr->i4_pic_order_cnt_lsb = i4_poc;
1135 }
1136 /* TODO add support for poc type 1 */
1137 else if(ps_sps->i1_pic_order_cnt_type == 1)
1138 {
1139 }
1140
1141 /*
1142 * redundant slices are not currently supported.
1143 * Hence the syntax element redundant slice cnt is not initialized
1144 */
1145 if(ps_pps->i1_redundant_pic_cnt_present_flag)
1146 {
1147 }
1148
1149 /* direct spatial mv pred flag */
1150 if(ps_proc->i4_slice_type == BSLICE)
1151 {
1152 ps_slice_hdr->u1_direct_spatial_mv_pred_flag = 1;
1153 }
1154
1155 if(ps_proc->i4_slice_type == PSLICE || ps_proc->i4_slice_type == SPSLICE ||
1156 ps_proc->i4_slice_type == BSLICE)
1157 {
1158 /* num_ref_idx_active_override_flag */
1159 ps_slice_hdr->u1_num_ref_idx_active_override_flag = 0;
1160
1161 if(ps_slice_hdr->u1_num_ref_idx_active_override_flag)
1162 {
1163 /* num_ref_idx_l0_active_minus1 */
1164
1165 if(ps_proc->i4_slice_type == BSLICE)
1166 {
1167 /* num_ref_idx_l1_active_minus1 */
1168 }
1169 }
1170 }
1171
1172 /* ref_pic_list_modification */
1173 if((ps_proc->i4_slice_type != ISLICE) && (ps_proc->i4_slice_type != SISLICE))
1174 {
1175 /* ref_pic_list_modification_flag_l0 */
1176 ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l0 = 1;
1177
1178 if(ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l0)
1179 {
1180 ps_slice_hdr->s_rplm.i1_modification_of_pic_nums_idc_l0[0] = 0;
1181 ps_slice_hdr->s_rplm.i1_modification_of_pic_nums_idc_l0[1] = 3;
1182
1183 if((ps_codec->i4_frame_num - ps_proc->aps_ref_pic[L0]->i4_frame_num) < 1)
1184 {
1185 return IH264E_FAIL;
1186 }
1187
1188 ps_slice_hdr->s_rplm.u4_abs_diff_pic_num_minus1_l0[0] =
1189 ps_codec->i4_frame_num - ps_proc->aps_ref_pic[L0]->i4_frame_num - 1;
1190 }
1191 }
1192
1193 if(ps_proc->i4_slice_type == BSLICE)
1194 {
1195 /* ref_pic_list_modification_flag_l1 */
1196 ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l1 = 0;
1197
1198 if(ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l1)
1199 {
1200 }
1201 }
1202
1203 /* Currently we do not support weighted pred */
1204 /* ps_slice_hdr->u1_weighted_bipred_idc = 0; */
1205
1206 if((ps_pps->i1_weighted_pred_flag &&
1207 (ps_proc->i4_slice_type == PSLICE || ps_proc->i4_slice_type == SPSLICE)) ||
1208 (ps_proc->i4_slice_type == BSLICE && ps_pps->i1_weighted_bipred_idc == 1))
1209 {
1210 /* TODO_LATER: Currently there is no support for weighted prediction.
1211 This needs to be updated when the support is added */
1212 }
1213
1214 if(ps_slice_hdr->i1_nal_unit_idc != 0)
1215 {
1216 if(u1_is_idr)
1217 {
1218 /* no_output_of_prior_pics_flag */
1219 ps_slice_hdr->u1_no_output_of_prior_pics_flag = 0;
1220
1221 /* long_term_reference_flag */
1222 ps_slice_hdr->u1_long_term_reference_flag = 0;
1223 }
1224 else
1225 {
1226 /* adaptive_ref_pic_marking_mode_flag */
1227 ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag = 0;
1228
1229 if(ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag)
1230 {
1231 /* TODO: if the reference picture marking mode is adaptive
1232 add these fields in the bit-stream */
1233 }
1234 }
1235 }
1236
1237 /* entropy coding mode flag */
1238 ps_slice_hdr->u1_entropy_coding_mode_flag = ps_entropy->u1_entropy_coding_mode_flag;
1239
1240 if(ps_slice_hdr->u1_entropy_coding_mode_flag && ps_proc->i4_slice_type != ISLICE &&
1241 ps_proc->i4_slice_type != SISLICE)
1242 {
1243 /* cabac_init_idc */
1244 ps_slice_hdr->i1_cabac_init_idc = CABAC_INIT_IDC;
1245 }
1246
1247 /* slice qp */
1248 ps_slice_hdr->i1_slice_qp = ps_proc->u1_frame_qp;
1249
1250 if(ps_proc->i4_slice_type == SPSLICE || ps_proc->i4_slice_type == SISLICE)
1251 {
1252 if(ps_proc->i4_slice_type == SPSLICE)
1253 {
1254 /* sp_for_switch_flag */
1255 }
1256 /* slice_qs_delta */
1257 }
1258
1259 if(ps_pps->i1_deblocking_filter_control_present_flag)
1260 {
1261 /* disable_deblocking_filter_idc */
1262 ps_slice_hdr->u1_disable_deblocking_filter_idc = ps_proc->u4_disable_deblock_level;
1263
1264 if(ps_slice_hdr->u1_disable_deblocking_filter_idc != 1)
1265 {
1266 /* slice_alpha_c0_offset_div2 */
1267 ps_slice_hdr->i1_slice_alpha_c0_offset_div2 = 0;
1268
1269 /* slice_beta_offset_div2 */
1270 ps_slice_hdr->i1_slice_beta_offset_div2 = 0;
1271 }
1272 }
1273 ps_slice_hdr->u1_num_slice_groups_minus1 = 0;
1274 if(ps_slice_hdr->u1_num_slice_groups_minus1 > 0 && ps_pps->u1_slice_group_map_type >= 3 &&
1275 ps_pps->u1_slice_group_map_type <= 5)
1276 {
1277 /* slice_group_change_cycle */
1278 /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
1279 * If this is not the case, we have to add Slice group map type to the bit
1280 * stream */
1281 }
1282
1283 ps_slice_hdr->i1_cabac_init_idc = CABAC_INIT_IDC;
1284
1285 return IH264E_SUCCESS;
1286 }
1287
1288 /**
1289 ******************************************************************************
1290 *
1291 * @brief Populates svc_nalu_ext structure
1292 *
1293 * @par Description
1294 * Populates svc_nalu_ext structure for its use in header generation
1295 *
1296 * @param[in] ps_proc
1297 * pointer to proc context
1298 *
1299 * @param[out] ps_slice_hdr
1300 * pointer to slice header structure that needs to be populated
1301 *
1302 * @param[in] ps_pps
1303 * pointer to pps params structure referred by the slice
1304 *
1305 * @param[in] ps_sps
1306 * pointer to sps params referred by the pps
1307 *
1308 * @return success or failure error code
1309 *
1310 ******************************************************************************
1311 */
isvce_populate_svc_nalu_extension(isvce_process_ctxt_t * ps_proc,svc_nalu_ext_t * ps_svc_nalu_ext,NAL_UNIT_TYPE_T nalu_type,UWORD8 u1_idr_flag)1312 WORD32 isvce_populate_svc_nalu_extension(isvce_process_ctxt_t *ps_proc,
1313 svc_nalu_ext_t *ps_svc_nalu_ext, NAL_UNIT_TYPE_T nalu_type,
1314 UWORD8 u1_idr_flag)
1315 {
1316 isvce_codec_t *ps_codec = ps_proc->ps_codec;
1317
1318 ps_svc_nalu_ext->u1_idr_flag = u1_idr_flag;
1319
1320 ps_svc_nalu_ext->u1_priority_id = 0;
1321
1322 ps_svc_nalu_ext->u1_no_inter_layer_pred_flag = ((nalu_type == NAL_PREFIX) ? 1 : 0);
1323
1324 ps_svc_nalu_ext->u1_dependency_id =
1325 ((nalu_type == NAL_PREFIX) ? 0 : ps_proc->u1_spatial_layer_id);
1326
1327 ps_svc_nalu_ext->u1_temporal_id = ps_proc->ps_cur_pic->i1_temporal_id;
1328
1329 ps_svc_nalu_ext->u1_quality_id = 0;
1330
1331 ps_svc_nalu_ext->u1_use_ref_base_pic_flag = 0;
1332
1333 ps_svc_nalu_ext->u1_discardable_flag = 0;
1334
1335 ps_svc_nalu_ext->u1_output_flag = 1;
1336
1337 ps_svc_nalu_ext->u1_reserved_three_2bits = 3;
1338
1339 ps_svc_nalu_ext->s_nalu_header.u1_nal_ref_idc = ps_codec->u4_is_curr_frm_ref ? 3 : 0;
1340
1341 ps_svc_nalu_ext->s_nalu_header.u1_nal_unit_type = nalu_type;
1342
1343 return IH264E_SUCCESS;
1344 }
1345
isvce_populate_subset_sps(isvce_codec_t * ps_codec,subset_sps_t * ps_subset_sps,UWORD8 u1_sps_id,isvce_inp_buf_t * ps_inp_buf,UWORD8 u1_spatial_layer_id)1346 WORD32 isvce_populate_subset_sps(isvce_codec_t *ps_codec, subset_sps_t *ps_subset_sps,
1347 UWORD8 u1_sps_id, isvce_inp_buf_t *ps_inp_buf,
1348 UWORD8 u1_spatial_layer_id)
1349 {
1350 sps_t *ps_sps = &ps_subset_sps->s_sps;
1351
1352 isvce_populate_sps(ps_codec, ps_sps, u1_sps_id, IH264_SCALABLE_BASELINE, ps_inp_buf,
1353 u1_spatial_layer_id);
1354
1355 ps_subset_sps->s_sps_svc_ext.u1_inter_layer_deblocking_filter_control_present_flag = 1;
1356
1357 ps_subset_sps->s_sps_svc_ext.i1_slice_header_restriction_flag = 1;
1358
1359 ps_subset_sps->s_sps_svc_ext.u1_extended_spatial_scalability_idc = 0;
1360
1361 ps_subset_sps->s_sps_svc_ext.i1_seq_tcoeff_level_prediction_flag = 0;
1362
1363 ps_subset_sps->i1_svc_vui_parameters_present_flag = 0;
1364
1365 ps_subset_sps->i1_additional_extension2_flag = 0;
1366
1367 ps_subset_sps->s_sps_svc_ext.u1_chroma_phase_x_plus1 = 1;
1368
1369 ps_subset_sps->s_sps_svc_ext.u1_chroma_phase_y_plus1 = 1;
1370
1371 ps_subset_sps->s_sps_svc_ext.i1_adaptive_tcoeff_level_prediction_flag = 0;
1372
1373 return IH264E_SUCCESS;
1374 }
1375
isvce_populate_svc_slice(isvce_process_ctxt_t * ps_proc,svc_slice_header_t * ps_svc_slice_hdr,pps_t * ps_pps,subset_sps_t * ps_subset_sps,svc_nalu_ext_t * ps_svc_nalu_ext)1376 WORD32 isvce_populate_svc_slice(isvce_process_ctxt_t *ps_proc, svc_slice_header_t *ps_svc_slice_hdr,
1377 pps_t *ps_pps, subset_sps_t *ps_subset_sps,
1378 svc_nalu_ext_t *ps_svc_nalu_ext)
1379 {
1380 WORD32 i4_return_status;
1381
1382 i4_return_status =
1383 isvce_populate_slice_header(ps_proc, &ps_svc_slice_hdr->s_slice_header, ps_pps,
1384 &ps_subset_sps->s_sps, ps_svc_nalu_ext->u1_idr_flag);
1385
1386 if(IH264E_SUCCESS != i4_return_status)
1387 {
1388 return IH264E_FAIL;
1389 }
1390
1391 ps_svc_slice_hdr->i1_slice_skip_flag = 0;
1392 ps_svc_slice_hdr->i1_adaptive_residual_prediction_flag = ENABLE_RESIDUAL_PREDICTION;
1393 ps_svc_slice_hdr->i1_default_residual_prediction_flag = 0;
1394 ps_svc_slice_hdr->i1_adaptive_base_mode_flag = ENABLE_ILP_MV || ENABLE_IBL_MODE;
1395 ps_svc_slice_hdr->i1_default_base_mode_flag = 0;
1396 ps_svc_slice_hdr->i1_tcoeff_level_prediction_flag = 0;
1397 ps_svc_slice_hdr->i1_constrained_intra_resampling_flag = 0;
1398 ps_svc_slice_hdr->i1_adaptive_motion_prediction_flag = USE_ILP_MV_AS_MVP;
1399 ps_svc_slice_hdr->i1_default_motion_prediction_flag = 0;
1400 ps_svc_slice_hdr->u4_disable_inter_layer_deblocking_filter_idc =
1401 !ENABLE_INTRA_BASE_DEBLOCK || ps_proc->u4_disable_deblock_level;
1402
1403 if(ps_svc_slice_hdr->u4_disable_inter_layer_deblocking_filter_idc != 1)
1404 {
1405 /* slice_alpha_c0_offset_div2 */
1406 ps_svc_slice_hdr->i4_inter_layer_slice_alpha_c0_offset_div2 = 0;
1407
1408 /* slice_beta_offset_div2 */
1409 ps_svc_slice_hdr->i4_inter_layer_slice_beta_offset_div2 = 0;
1410 }
1411
1412 if((ps_svc_nalu_ext->u1_quality_id == 0) && (ps_svc_nalu_ext->u1_no_inter_layer_pred_flag == 0))
1413 {
1414 ps_svc_slice_hdr->u4_ref_layer_dq_id = (ps_proc->u1_spatial_layer_id - 1) << 4;
1415 }
1416
1417 return IH264E_SUCCESS;
1418 }
1419
1420 /**
1421 ******************************************************************************
1422 *
1423 * @brief Signals prefix_nal_unit_rbsp
1424 *
1425 * @par Description
1426 * prefix_nal_unit_rbsp as per Section G.7.3.2.12
1427 *
1428 * @param[inout] ps_bitstrm
1429 * pointer to bitstream context for generating slice header
1430 *
1431 * @param[in] svc_nalu_ext
1432 * pointer to svc NAL unit structure
1433 *
1434 * @param[in] ps_slice_header
1435 * pointer to slice header
1436 *
1437 * @return success or failure error code
1438 *
1439 ******************************************************************************
1440 */
isvce_generate_prefix_nal(bitstrm_t * ps_bitstrm,svc_nalu_ext_t * ps_svc_nalu_ext,slice_header_t * ps_slice_header,UWORD8 u1_max_num_ref_frames,UWORD8 u1_num_spatial_layers)1441 WORD32 isvce_generate_prefix_nal(bitstrm_t *ps_bitstrm, svc_nalu_ext_t *ps_svc_nalu_ext,
1442 slice_header_t *ps_slice_header, UWORD8 u1_max_num_ref_frames,
1443 UWORD8 u1_num_spatial_layers)
1444 {
1445 WORD32 return_status = IH264E_SUCCESS;
1446
1447 WORD32 i4_store_ref_base_pic_flag = 0;
1448 WORD32 i4_additional_prefix_nal_unit_extension_flag = 0;
1449
1450 if(ps_svc_nalu_ext->u1_dependency_id == (u1_num_spatial_layers - 1))
1451 {
1452 i4_store_ref_base_pic_flag = 1;
1453 if(u1_max_num_ref_frames < 2)
1454 {
1455 i4_store_ref_base_pic_flag = 0;
1456 }
1457 }
1458
1459 /* store_ref_base_pic_flag */
1460 if(ps_svc_nalu_ext->s_nalu_header.u1_nal_ref_idc != 0)
1461 {
1462 PUT_BITS(ps_bitstrm, i4_store_ref_base_pic_flag, 1, return_status,
1463 "store_ref_base_pic_flag");
1464
1465 if((ps_svc_nalu_ext->u1_use_ref_base_pic_flag || i4_store_ref_base_pic_flag) &&
1466 !ps_svc_nalu_ext->u1_idr_flag)
1467 {
1468 PUT_BITS(ps_bitstrm, ps_slice_header->u1_adaptive_ref_pic_marking_mode_flag, 1,
1469 return_status, "DPRM: adaptive_ref_base_pic_marking_mode_flag");
1470 }
1471
1472 PUT_BITS(ps_bitstrm, i4_additional_prefix_nal_unit_extension_flag, 1, return_status,
1473 "additional_prefix_nal_unit_extension_flag");
1474 }
1475
1476 /* rbsp trailing bits */
1477 return_status = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
1478
1479 return return_status;
1480 }
1481
isvce_generate_slice_header_svc(bitstrm_t * ps_bitstrm,pps_t * ps_pps,svc_nalu_ext_t * ps_svc_nalu_ext,svc_slice_header_t * ps_svc_slice_hdr,subset_sps_t * ps_subset_sps)1482 WORD32 isvce_generate_slice_header_svc(bitstrm_t *ps_bitstrm, pps_t *ps_pps,
1483 svc_nalu_ext_t *ps_svc_nalu_ext,
1484 svc_slice_header_t *ps_svc_slice_hdr,
1485 subset_sps_t *ps_subset_sps)
1486 {
1487 WORD32 return_status = IH264E_SUCCESS;
1488
1489 UWORD8 u1_slice_type;
1490 sps_t *ps_sps = &ps_subset_sps->s_sps;
1491 slice_header_t *ps_slice_hdr = &ps_svc_slice_hdr->s_slice_header;
1492
1493 /* first_mb_in_slice */
1494 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u2_first_mb_in_slice, return_status,
1495 "SH: first_mb_in_slice");
1496
1497 /* slice_type */
1498 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_slice_type, return_status, "SH: slice_type");
1499
1500 /* pic_parameter_set_id */
1501 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_pps_id, return_status, "SH: pic_parameter_set_id");
1502
1503 /* frame_num */
1504 PUT_BITS(ps_bitstrm, ps_slice_hdr->i4_frame_num, ps_sps->i1_log2_max_frame_num, return_status,
1505 "SH: frame_num");
1506
1507 if(!ps_sps->i1_frame_mbs_only_flag)
1508 {
1509 /* field_pic_flag */
1510 PUT_BITS(ps_bitstrm, ps_slice_hdr->i1_field_pic_flag, 1, return_status,
1511 "SH: field_pic_flag");
1512
1513 if(ps_slice_hdr->i1_field_pic_flag)
1514 {
1515 /* bottom_field_flag */
1516 PUT_BITS(ps_bitstrm, ps_slice_hdr->i1_bottom_field_flag, 1, return_status,
1517 "SH: bottom_field_flag");
1518 }
1519 }
1520
1521 if(ps_svc_nalu_ext->u1_idr_flag == 1)
1522 {
1523 /* u2_idr_pic_id */
1524 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u2_idr_pic_id, return_status, "SH: idr_pic_id");
1525 }
1526
1527 if(ps_sps->i1_pic_order_cnt_type == 0)
1528 {
1529 /* pic_order_cnt_lsb */
1530 PUT_BITS(ps_bitstrm, ps_slice_hdr->i4_pic_order_cnt_lsb,
1531 ps_sps->i1_log2_max_pic_order_cnt_lsb, return_status, "SH: pic_order_cnt_lsb");
1532
1533 if(ps_pps->u1_pic_order_present_flag && !ps_slice_hdr->i1_field_pic_flag)
1534 {
1535 /* delta_pic_order_cnt_bottom */
1536 PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i4_delta_pic_order_cnt_bottom, return_status,
1537 "SH: delta_pic_order_cnt_bottom");
1538 }
1539 }
1540
1541 if(ps_sps->i1_pic_order_cnt_type == 1 && !ps_sps->i1_delta_pic_order_always_zero_flag)
1542 {
1543 /* delta_pic_order_cnt[0] */
1544 PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->ai4_delta_pic_order_cnt[0], return_status,
1545 "SH: delta_pic_order_cnt[0]");
1546
1547 if(ps_pps->u1_pic_order_present_flag && !ps_slice_hdr->i1_field_pic_flag)
1548 {
1549 /* delta_pic_order_cnt[1] */
1550 PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->ai4_delta_pic_order_cnt[1], return_status,
1551 "SH: delta_pic_order_cnt[1]");
1552 }
1553 }
1554
1555 if(ps_pps->i1_redundant_pic_cnt_present_flag)
1556 {
1557 /* redundant_pic_cnt */
1558 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_redundant_pic_cnt, return_status,
1559 "SH: redundant_pic_cnt");
1560 }
1561
1562 u1_slice_type = ps_slice_hdr->u1_slice_type % EPSLICE;
1563
1564 if(ps_svc_nalu_ext->u1_quality_id == 0)
1565 {
1566 if(u1_slice_type == BSLICE)
1567 {
1568 /* direct_spatial_mv_pred_flag */
1569 PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_direct_spatial_mv_pred_flag, 1, return_status,
1570 "SH: direct_spatial_mv_pred_flag");
1571 }
1572
1573 if(u1_slice_type == PSLICE || u1_slice_type == BSLICE)
1574 {
1575 /* num_ref_idx_active_override_flag */
1576 PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_num_ref_idx_active_override_flag, 1,
1577 return_status, "SH: num_ref_idx_active_override_flag");
1578
1579 if(ps_slice_hdr->u1_num_ref_idx_active_override_flag)
1580 {
1581 /* num_ref_idx_l0_active_minus1 */
1582 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_num_ref_idx_l0_active - 1, return_status,
1583 "SH: num_ref_idx_l0_active_minus1");
1584
1585 if(u1_slice_type == BSLICE)
1586 {
1587 /* num_ref_idx_l1_active_minus1 */
1588 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_num_ref_idx_l1_active - 1,
1589 return_status, "SH: num_ref_idx_l1_active_minus1");
1590 }
1591 }
1592 }
1593
1594 /* ref_pic_list_modification */
1595 if((u1_slice_type != ISLICE) && (u1_slice_type != SISLICE))
1596 {
1597 /* ref_pic_list_modification_flag_l0 */
1598 PUT_BITS(ps_bitstrm, ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l0, 1,
1599 return_status, "RPLR: ref_pic_list_reordering_flag");
1600
1601 if(ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l0)
1602 {
1603 UWORD8 i = 0;
1604
1605 WORD8 *pi1_modification_of_pic_nums_idc_l0 =
1606 ps_slice_hdr->s_rplm.i1_modification_of_pic_nums_idc_l0;
1607 UWORD32 *pu4_abs_diff_pic_num_minus1_l0 =
1608 ps_slice_hdr->s_rplm.u4_abs_diff_pic_num_minus1_l0;
1609 UWORD8 *pu1_long_term_pic_num_l0 = ps_slice_hdr->s_rplm.u1_long_term_pic_num_l0;
1610
1611 do
1612 {
1613 /* modification_of_pic_nums_idc */
1614 PUT_BITS_UEV(ps_bitstrm, pi1_modification_of_pic_nums_idc_l0[i], return_status,
1615 "RPLR: reordering_of_pic_nums_idc");
1616
1617 if((0 == pi1_modification_of_pic_nums_idc_l0[i]) ||
1618 (1 == pi1_modification_of_pic_nums_idc_l0[i]))
1619 {
1620 /* abs_diff_pic_num_minus1 */
1621 PUT_BITS_UEV(ps_bitstrm, pu4_abs_diff_pic_num_minus1_l0[0], return_status,
1622 "RPLR: abs_diff_pic_num_minus1");
1623
1624 pu4_abs_diff_pic_num_minus1_l0++;
1625 }
1626 else if(2 == pi1_modification_of_pic_nums_idc_l0[i])
1627 {
1628 /* long_term_pic_num */
1629 PUT_BITS_UEV(ps_bitstrm, pu1_long_term_pic_num_l0[0], return_status,
1630 "RPLR: long_term_pic_num");
1631
1632 pu1_long_term_pic_num_l0++;
1633 }
1634 } while(pi1_modification_of_pic_nums_idc_l0[i++] != 3);
1635 }
1636 }
1637
1638 if(u1_slice_type == BSLICE)
1639 {
1640 /* ref_pic_list_modification_flag_l1 */
1641 PUT_BITS(ps_bitstrm, ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l1, 1,
1642 return_status, "SH: ref_pic_list_modification_flag_l1");
1643
1644 if(ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l1)
1645 {
1646 UWORD8 i = 0;
1647
1648 WORD8 *pi1_modification_of_pic_nums_idc_l1 =
1649 ps_slice_hdr->s_rplm.i1_modification_of_pic_nums_idc_l1;
1650 UWORD32 *pu4_abs_diff_pic_num_minus1_l1 =
1651 ps_slice_hdr->s_rplm.u4_abs_diff_pic_num_minus1_l1;
1652 UWORD8 *pu1_long_term_pic_num_l1 = ps_slice_hdr->s_rplm.u1_long_term_pic_num_l1;
1653
1654 do
1655 {
1656 /* modification_of_pic_nums_idc */
1657 PUT_BITS_UEV(ps_bitstrm, pi1_modification_of_pic_nums_idc_l1[i], return_status,
1658 "SH: modification_of_pic_nums_idc");
1659
1660 if((0 == pi1_modification_of_pic_nums_idc_l1[i]) ||
1661 (1 == pi1_modification_of_pic_nums_idc_l1[i]))
1662 {
1663 /* abs_diff_pic_num_minus1 */
1664 PUT_BITS_UEV(ps_bitstrm, pu4_abs_diff_pic_num_minus1_l1[0], return_status,
1665 "SH: abs_diff_pic_num_minus1");
1666
1667 pu4_abs_diff_pic_num_minus1_l1++;
1668 }
1669 else if(2 == pi1_modification_of_pic_nums_idc_l1[i])
1670 {
1671 /* long_term_pic_num */
1672 PUT_BITS_UEV(ps_bitstrm, pu1_long_term_pic_num_l1[0], return_status,
1673 "SH: abs_diff_pic_num_minus1");
1674
1675 pu1_long_term_pic_num_l1++;
1676 }
1677 } while(pi1_modification_of_pic_nums_idc_l1[i++] != 3);
1678 }
1679 }
1680
1681 if((ps_pps->i1_weighted_pred_flag && u1_slice_type == PSLICE) ||
1682 (u1_slice_type == BSLICE && ps_pps->i1_weighted_bipred_idc == 1))
1683 {
1684 /* TODO_LATER: Currently there is no support for weighted prediction.
1685 This needs to be updated when the support is added */
1686 }
1687
1688 if(ps_slice_hdr->i1_nal_unit_idc != 0)
1689 {
1690 if(ps_svc_nalu_ext->u1_idr_flag)
1691 {
1692 /* no_output_of_prior_pics_flag */
1693 PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_no_output_of_prior_pics_flag, 1,
1694 return_status, "DRPM: no_output_of_prior_pics_flag ");
1695
1696 /* long_term_reference_flag */
1697 PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_long_term_reference_flag, 1, return_status,
1698 "DRPM: long_term_reference_flag ");
1699 }
1700 else
1701 {
1702 /* adaptive_ref_pic_marking_mode_flag */
1703 PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag, 1,
1704 return_status, "DPRM: adaptive_ref_pic_marking_mode_flag ");
1705
1706 if(ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag)
1707 {
1708 /* TODO: if the reference picture marking mode is adaptive
1709 add these fields in the bit-stream */
1710 }
1711 }
1712 if(ps_subset_sps->s_sps_svc_ext.i1_slice_header_restriction_flag == 0)
1713 {
1714 WORD32 i4_store_ref_base_pic_flag = 0;
1715
1716 if(ps_sps->u1_max_num_ref_frames >= 2)
1717 {
1718 i4_store_ref_base_pic_flag = 1;
1719 }
1720
1721 /* store_ref_base_pic_flag */
1722 PUT_BITS(ps_bitstrm, i4_store_ref_base_pic_flag, 1, return_status,
1723 "SH: store_ref_base_pic_flag");
1724
1725 if((ps_svc_nalu_ext->u1_use_ref_base_pic_flag || i4_store_ref_base_pic_flag) &&
1726 (!ps_svc_nalu_ext->u1_idr_flag))
1727 {
1728 PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag, 1,
1729 return_status, "SH: adaptive_ref_base_pic_marking_mode_flag");
1730 }
1731 }
1732 }
1733 }
1734
1735 if(ps_slice_hdr->u1_entropy_coding_mode_flag && u1_slice_type != ISLICE)
1736 {
1737 /* cabac_init_idc */
1738 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_cabac_init_idc, return_status,
1739 "SH: cabac_init_idc");
1740 }
1741
1742 /* slice_qp_delta */
1743 PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_qp - ps_pps->i1_pic_init_qp, return_status,
1744 "SH: slice_qp_delta");
1745
1746 if(ps_pps->i1_deblocking_filter_control_present_flag)
1747 {
1748 /* disable_deblocking_filter_idc */
1749 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_disable_deblocking_filter_idc, return_status,
1750 "SH: disable_deblocking_filter_idc");
1751
1752 if(ps_slice_hdr->u1_disable_deblocking_filter_idc != 1)
1753 {
1754 /* slice_alpha_c0_offset_div2 */
1755 PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_alpha_c0_offset_div2, return_status,
1756 "SH: slice_alpha_c0_offset_div2");
1757
1758 /* slice_beta_offset_div2 */
1759 PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_beta_offset_div2, return_status,
1760 "SH: slice_beta_offset_div2");
1761 }
1762 }
1763
1764 if(ps_slice_hdr->u1_num_slice_groups_minus1 > 0 && ps_pps->u1_slice_group_map_type >= 3 &&
1765 ps_pps->u1_slice_group_map_type <= 5)
1766 {
1767 /* slice_group_change_cycle */
1768 /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
1769 * If this is not the case, we have to add Slice group map type to the bit
1770 * stream */
1771 }
1772
1773 if((ps_svc_nalu_ext->u1_no_inter_layer_pred_flag == 0) && (ps_svc_nalu_ext->u1_quality_id == 0))
1774 {
1775 PUT_BITS_UEV(ps_bitstrm, ps_svc_slice_hdr->u4_ref_layer_dq_id, return_status,
1776 "SH: ref_layer_dq_id");
1777 if(ps_subset_sps->s_sps_svc_ext.u1_inter_layer_deblocking_filter_control_present_flag)
1778 {
1779 PUT_BITS_UEV(ps_bitstrm, ps_svc_slice_hdr->u4_disable_inter_layer_deblocking_filter_idc,
1780 return_status, "SH: disable_inter_layer_deblocking_filter_idc");
1781 if(ps_svc_slice_hdr->u4_disable_inter_layer_deblocking_filter_idc != 1)
1782 {
1783 PUT_BITS_SEV(ps_bitstrm,
1784 ps_svc_slice_hdr->i4_inter_layer_slice_alpha_c0_offset_div2,
1785 return_status, "SH: inter_layer_slice_alpha_c0_offset_div2");
1786 PUT_BITS_SEV(ps_bitstrm, ps_svc_slice_hdr->i4_inter_layer_slice_beta_offset_div2,
1787 return_status, "SH: inter_layer_slice_beta_offset_div2");
1788 }
1789 }
1790 PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_constrained_intra_resampling_flag, 1,
1791 return_status, "SH: constrained_intra_resampling_flag");
1792 if(ps_subset_sps->s_sps_svc_ext.u1_extended_spatial_scalability_idc == 2)
1793 {
1794 if(ps_sps->u1_chroma_format_idc > 0)
1795 {
1796 PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_ref_layer_chroma_phase_x_plus1_flag, 1,
1797 return_status, "SH: ref_layer_chroma_phase_x_plus1_flag");
1798 PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_ref_layer_chroma_phase_y_plus1, 2,
1799 return_status, "SH: ref_layer_chroma_phase_y_plus1");
1800 }
1801 PUT_BITS_SEV(ps_bitstrm, ps_svc_slice_hdr->i4_scaled_ref_layer_left, return_status,
1802 "SH: scaled_ref_layer_left_offset");
1803 PUT_BITS_SEV(ps_bitstrm, ps_svc_slice_hdr->i4_scaled_ref_layer_top, return_status,
1804 "SH: scaled_ref_layer_top_offset");
1805 PUT_BITS_SEV(ps_bitstrm, ps_svc_slice_hdr->i4_scaled_ref_layer_right, return_status,
1806 "SH: scaled_ref_layer_right_offset");
1807 PUT_BITS_SEV(ps_bitstrm, ps_svc_slice_hdr->i4_scaled_ref_layer_bottom, return_status,
1808 "SH: scaled_ref_layer_bottom_offset");
1809 }
1810 }
1811
1812 if(!ps_svc_nalu_ext->u1_no_inter_layer_pred_flag)
1813 {
1814 PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_slice_skip_flag, 1, return_status,
1815 "SH: slice_skip_flag");
1816 if(ps_svc_slice_hdr->i1_slice_skip_flag)
1817 {
1818 PUT_BITS_UEV(ps_bitstrm, ps_svc_slice_hdr->u4_num_mbs_in_slice_minus1, return_status,
1819 "SH: num_mbs_in_slice_minus1");
1820 }
1821 else
1822 {
1823 PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_adaptive_base_mode_flag, 1, return_status,
1824 "SH: adaptive_base_mode_flag");
1825 if(!ps_svc_slice_hdr->i1_adaptive_base_mode_flag)
1826 PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_default_base_mode_flag, 1, return_status,
1827 "SH: default_base_mode_flag");
1828
1829 if(!ps_svc_slice_hdr->i1_default_base_mode_flag)
1830 {
1831 PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_adaptive_motion_prediction_flag, 1,
1832 return_status, "SH: adaptive_motion_prediction_flag");
1833 if(!ps_svc_slice_hdr->i1_adaptive_motion_prediction_flag)
1834 PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_default_motion_prediction_flag, 1,
1835 return_status, "SH: default_motion_prediction_flag");
1836 }
1837 PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_adaptive_residual_prediction_flag, 1,
1838 return_status, "SH: adaptive_residual_prediction_flag");
1839 if(!ps_svc_slice_hdr->i1_adaptive_residual_prediction_flag)
1840 PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_default_residual_prediction_flag, 1,
1841 return_status, "SH: default_residual_prediction_flag");
1842 }
1843
1844 if(ps_subset_sps->s_sps_svc_ext.i1_adaptive_tcoeff_level_prediction_flag)
1845 {
1846 PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_tcoeff_level_prediction_flag, 1,
1847 return_status, "SH: tcoeff_level_prediction_flag");
1848 }
1849 }
1850
1851 if(!ps_subset_sps->s_sps_svc_ext.i1_slice_header_restriction_flag &&
1852 !ps_svc_slice_hdr->i1_slice_skip_flag)
1853 {
1854 PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->u4_scan_idx_start, 4, return_status,
1855 "SH: scan_idx_start");
1856 PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->u4_scan_idx_end, 4, return_status,
1857 "SH: scan_idx_end");
1858 }
1859
1860 return return_status;
1861 }
1862
isvce_seq_parameter_set_svc_extension(bitstrm_t * ps_bitstrm,subset_sps_t * ps_sub_sps,UWORD8 u1_chroma_format_idc)1863 WORD32 isvce_seq_parameter_set_svc_extension(bitstrm_t *ps_bitstrm, subset_sps_t *ps_sub_sps,
1864 UWORD8 u1_chroma_format_idc)
1865 {
1866 WORD32 return_status = IH264E_SUCCESS;
1867
1868 /* inter_layer_deblocking_filter_control_present_flag */
1869 PUT_BITS(ps_bitstrm,
1870 ps_sub_sps->s_sps_svc_ext.u1_inter_layer_deblocking_filter_control_present_flag, 1,
1871 return_status, "SPS: inter_layer_deblocking_filter_control_present_flag");
1872
1873 /* extended_spatial_scalability */
1874 PUT_BITS(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.u1_extended_spatial_scalability_idc, 2,
1875 return_status, "SPS: extended_spatial_scalability");
1876
1877 if(u1_chroma_format_idc == 1 || u1_chroma_format_idc == 2)
1878 {
1879 /* chroma_phase_x_plus1_flag */
1880 PUT_BITS(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.u1_chroma_phase_x_plus1, 1, return_status,
1881 "SPS: chroma_phase_x_plus1_flag");
1882 }
1883
1884 if(u1_chroma_format_idc == 1)
1885 {
1886 /* chroma_phase_y_plus1 */
1887 PUT_BITS(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.u1_chroma_phase_y_plus1, 2, return_status,
1888 "SPS: chroma_phase_y_plus1");
1889 }
1890
1891 if(ps_sub_sps->s_sps_svc_ext.u1_extended_spatial_scalability_idc == 1)
1892 {
1893 if(u1_chroma_format_idc > 0)
1894 {
1895 /* seq_ref_layer_chroma_phase_x_plus1_flag */
1896 PUT_BITS(ps_bitstrm,
1897 ps_sub_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_x_plus1_flag, 1,
1898 return_status, "SPS: seq_ref_layer_chroma_phase_x_plus1_flag");
1899
1900 /* seq_ref_layer_chroma_phase_y_plus1 */
1901 PUT_BITS(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_y_plus1, 2,
1902 return_status, "SPS: seq_ref_layer_chroma_phase_y_plus1");
1903 }
1904 /* seq_scaled_ref_layer_left_offset */
1905 PUT_BITS_SEV(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_left_offset,
1906 return_status, "SPS: seq_scaled_ref_layer_left_offset");
1907
1908 /* seq_scaled_ref_layer_top_offset */
1909 PUT_BITS_SEV(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_top_offset,
1910 return_status, "SPS: seq_scaled_ref_layer_top_offset");
1911
1912 /* seq_scaled_ref_layer_right_offset */
1913 PUT_BITS_SEV(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_right_offset,
1914 return_status, "SPS: seq_scaled_ref_layer_right_offset");
1915
1916 /* seq_scaled_ref_layer_bottom_offset */
1917 PUT_BITS_SEV(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_bottom_offset,
1918 return_status, "SPS: seq_scaled_ref_layer_bottom_offset");
1919 }
1920
1921 /* seq_tcoeff_level_prediction_flag */
1922 PUT_BITS(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.i1_seq_tcoeff_level_prediction_flag, 1,
1923 return_status, "SPS: seq_tcoeff_level_prediction_flag");
1924
1925 if(ps_sub_sps->s_sps_svc_ext.i1_seq_tcoeff_level_prediction_flag)
1926 {
1927 /* adaptive_tcoeff_level_prediction_flag */
1928 PUT_BITS(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.i1_adaptive_tcoeff_level_prediction_flag, 1,
1929 return_status, "SPS: adaptive_tcoeff_level_prediction_flag");
1930 }
1931
1932 /* slice_header_restriction_flag */
1933 PUT_BITS(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.i1_slice_header_restriction_flag, 1,
1934 return_status, "SPS: slice_header_restriction_flag");
1935
1936 return return_status;
1937 }
1938
isvce_svc_vui_parameters_extension(bitstrm_t * ps_bitstrm,svc_vui_ext_t * ps_svc_vui)1939 WORD32 isvce_svc_vui_parameters_extension(bitstrm_t *ps_bitstrm, svc_vui_ext_t *ps_svc_vui)
1940 {
1941 WORD32 return_status = IH264E_SUCCESS;
1942 UWORD32 i;
1943
1944 PUT_BITS_UEV(ps_bitstrm, ps_svc_vui->u4_vui_ext_num_entries_minus1, return_status,
1945 "num_layers_minus1");
1946
1947 for(i = 0; i < ps_svc_vui->u4_vui_ext_num_entries_minus1; i++)
1948 {
1949 /* dependency_id */
1950 PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_dependency_id[i], 3, return_status,
1951 "dependency_id");
1952
1953 /* quality_id */
1954 PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_quality_id[i], 4, return_status, "quality_id");
1955
1956 /* temporal_id */
1957 PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_temporal_id[i], 3, return_status,
1958 "temporal_id");
1959
1960 /* timing_info_present_flag */
1961 PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_timing_info_present_flag[i], 1, return_status,
1962 "timing_info_present_flag");
1963
1964 if(ps_svc_vui->u1_vui_ext_timing_info_present_flag[i])
1965 {
1966 /* num_units_in_tick */
1967 PUT_BITS(ps_bitstrm, ps_svc_vui->u4_vui_ext_num_units_in_tick[i], 32, return_status,
1968 "num_units_in_tick");
1969
1970 /* time_scale */
1971 PUT_BITS(ps_bitstrm, ps_svc_vui->u4_vui_ext_time_scale[i], 32, return_status,
1972 "time_scale");
1973
1974 /* fixed_frame_rate_flag */
1975 PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_fixed_frame_rate_flag[i], 1, return_status,
1976 "fixed_frame_rate_flag");
1977 }
1978
1979 /* nal_hrd_parameters_present_flag */
1980 PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_nal_hrd_params_present_flag[i], 1,
1981 return_status, "nal_hrd_parameters_present_flag");
1982
1983 if(ps_svc_vui->u1_vui_ext_nal_hrd_params_present_flag[i])
1984 {
1985 }
1986
1987 /* nal_hrd_parameters_present_flag */
1988 PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_vcl_hrd_params_present_flag[i], 1,
1989 return_status, "vcl_hrd_parameters_present_flag");
1990
1991 if(ps_svc_vui->u1_vui_ext_vcl_hrd_params_present_flag[i])
1992 {
1993 }
1994
1995 if(ps_svc_vui->u1_vui_ext_nal_hrd_params_present_flag[i] ||
1996 ps_svc_vui->u1_vui_ext_vcl_hrd_params_present_flag[i])
1997 {
1998 /* low_delay_hrd_flag */
1999 PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_low_delay_hrd_flag[i], 1, return_status,
2000 "low_delay_hrd_flag");
2001 }
2002
2003 /* pic_struct_present_flag */
2004 PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_pic_struct_present_flag[i], 1, return_status,
2005 "pic_struct_present_flag");
2006 }
2007
2008 return return_status;
2009 }
2010
isvce_generate_subset_sps(bitstrm_t * ps_bitstrm,subset_sps_t * ps_subset_sps)2011 WORD32 isvce_generate_subset_sps(bitstrm_t *ps_bitstrm, subset_sps_t *ps_subset_sps)
2012 {
2013 WORD32 return_status = IH264E_SUCCESS;
2014 sps_t *ps_sps = &ps_subset_sps->s_sps;
2015 return_status = isvce_generate_sps(ps_bitstrm, &ps_subset_sps->s_sps, NAL_SUBSET_SPS);
2016
2017 /* generate subset sps */
2018 if(ps_sps->u1_profile_idc == IH264_SCALABLE_BASELINE ||
2019 ps_sps->u1_profile_idc == IH264_SCALABLE_HIGH_PROFILE)
2020 {
2021 isvce_seq_parameter_set_svc_extension(ps_bitstrm, ps_subset_sps,
2022 ps_sps->u1_chroma_format_idc);
2023
2024 /* svc_vui_parameters_present_flag */
2025 PUT_BITS(ps_bitstrm, ps_subset_sps->i1_svc_vui_parameters_present_flag, 1, return_status,
2026 "SPS: svc_vui_parameters_present_flag");
2027
2028 if(ps_subset_sps->i1_svc_vui_parameters_present_flag == 1)
2029 {
2030 svc_vui_ext_t *ps_svc_vui = NULL;
2031 isvce_svc_vui_parameters_extension(ps_bitstrm, ps_svc_vui);
2032 }
2033
2034 /* additional_extension2_flag */
2035 PUT_BITS(ps_bitstrm, ps_subset_sps->i1_additional_extension2_flag, 1, return_status,
2036 "SPS: additional_extension2_flag");
2037 }
2038
2039 /* rbsp trailing bits */
2040 return_status = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
2041
2042 return return_status;
2043 }
2044 /**
2045 ******************************************************************************
2046 *
2047 * @brief Generates svc_nalu_ext
2048 *
2049 * @par Description
2050 * Generate svc_nalu_ext as per Section G.7.3.1.1
2051 *
2052 * @param[inout] ps_bitstrm
2053 * pointer to bitstream context for generating slice header
2054 *
2055 * @param[in] ps_svc_nalu_ext
2056 * pointer to svc_nalu_ext struct
2057 *
2058 * @return success or failure error code
2059 *
2060 ******************************************************************************
2061 */
isvce_generate_svc_nalu_extension(bitstrm_t * ps_bitstrm,svc_nalu_ext_t * ps_svc_nalu_ext,UWORD8 u1_nalu_id)2062 WORD32 isvce_generate_svc_nalu_extension(bitstrm_t *ps_bitstrm, svc_nalu_ext_t *ps_svc_nalu_ext,
2063 UWORD8 u1_nalu_id)
2064 {
2065 WORD32 return_status = IH264E_SUCCESS;
2066
2067 /* Insert start code */
2068 return_status = ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
2069
2070 if(return_status != IH264E_SUCCESS)
2071 {
2072 return return_status;
2073 }
2074
2075 /* Insert Nal Unit Header */
2076 return_status = isvce_generate_nal_unit_header(ps_bitstrm, u1_nalu_id, 3);
2077
2078 if(return_status != IH264E_SUCCESS)
2079 {
2080 return return_status;
2081 }
2082
2083 /* reserved_one_bit */
2084 PUT_BITS(ps_bitstrm, 1, 1, return_status, "NAL unit header: reserved_one_bit");
2085
2086 /* idr_flag */
2087 PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_idr_flag, 1, return_status,
2088 "NAL unit header: idr_flag");
2089
2090 /* priority_id */
2091 PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_priority_id, 6, return_status,
2092 "NAL unit header: priority_id");
2093
2094 /* no_inter_layer_pred_flag */
2095 PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_no_inter_layer_pred_flag, 1, return_status,
2096 "NAL unit header: no_inter_layer_pred_flag");
2097
2098 /* dependency_id */
2099 PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_dependency_id, 3, return_status,
2100 "NAL unit header: dependency_id");
2101
2102 /* quality_id */
2103 PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_quality_id, 4, return_status,
2104 "NAL unit header: quality_id");
2105
2106 /* temporal_id */
2107 PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_temporal_id, 3, return_status,
2108 "NAL unit header: temporal_id");
2109
2110 /* use_ref_base_pic_flag */
2111 PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_use_ref_base_pic_flag, 1, return_status,
2112 "NAL unit header: use_ref_base_pic_flag");
2113
2114 /* discardable_flag */
2115 PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_discardable_flag, 1, return_status,
2116 "NAL unit header: discardable_flag");
2117
2118 /* output_flag */
2119 PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_output_flag, 1, return_status,
2120 "NAL unit header: output_flag");
2121
2122 /* reserved_three_2bits */
2123 PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_reserved_three_2bits, 2, return_status,
2124 "NAL unit header: reserved_three_2bits");
2125
2126 return return_status;
2127 }
2128