xref: /aosp_15_r20/external/libavc/encoder/svc/isvce_encode_header.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
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