xref: /aosp_15_r20/external/libavc/encoder/ih264e_encode_header.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1 /******************************************************************************
2  *
3  * Copyright (C) 2015 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 *  ih264e_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 *  - ih264e_generate_nal_unit_header
34 *  - ih264e_generate_vui
35 *  - ih264e_generate_aud
36 *  - ih264e_generate_sps
37 *  - ih264e_generate_pps
38 *  - ih264e_generate_slice_header
39 *  - ih264e_populate_vui
40 *  - ih264e_populate_sps
41 *  - ih264e_populate_pps
42 *  - ih264e_populate_slice_header
43 *  - ih264e_add_filler_nal_unit
44 *
45 * @remarks
46 *  none
47 *
48 *******************************************************************************
49 */
50 
51 /*****************************************************************************/
52 /* File Includes                                                             */
53 /*****************************************************************************/
54 
55 /* System Include Files */
56 #include <stdio.h>
57 #include <stddef.h>
58 #include <stdlib.h>
59 #include <string.h>
60 #include <assert.h>
61 
62 /* User Include Files */
63 #include "ih264e_config.h"
64 #include "ih264_typedefs.h"
65 #include "iv2.h"
66 #include "ive2.h"
67 #include "ithread.h"
68 
69 #include "ih264_debug.h"
70 #include "ih264_macros.h"
71 #include "ih264_error.h"
72 #include "ih264_defs.h"
73 #include "ih264_mem_fns.h"
74 #include "ih264_padding.h"
75 #include "ih264_structs.h"
76 #include "ih264_trans_quant_itrans_iquant.h"
77 #include "ih264_inter_pred_filters.h"
78 #include "ih264_intra_pred_filters.h"
79 #include "ih264_deblk_edge_filters.h"
80 #include "ih264_common_tables.h"
81 #include "ih264_cabac_tables.h"
82 
83 #include "ime_defs.h"
84 #include "ime_distortion_metrics.h"
85 #include "ime_structs.h"
86 
87 #include "irc_cntrl_param.h"
88 #include "irc_frame_info_collector.h"
89 
90 #include "ih264e.h"
91 #include "ih264e_error.h"
92 #include "ih264e_defs.h"
93 #include "ih264e_rate_control.h"
94 #include "ih264e_bitstream.h"
95 #include "ih264e_cabac_structs.h"
96 #include "ih264e_structs.h"
97 #include "ih264e_utils.h"
98 #include "ih264e_sei.h"
99 #include "ih264e_encode_header.h"
100 #include "ih264e_trace.h"
101 
102 
103 /*****************************************************************************/
104 /* Function Definitions                                                      */
105 /*****************************************************************************/
106 
107 /**
108 ******************************************************************************
109 *
110 * @brief Generate nal unit header in the stream as per section 7.4.1
111 *
112 * @par   Description
113 *  Inserts Nal unit header syntax as per section 7.4.1
114 *
115 * @param[inout]   ps_bitstrm
116 *  pointer to bitstream context (handle)
117 *
118 * @param[in]   nal_unit_type
119 *  nal type to be inserted
120 *
121 * @param[in]   nal_ref_idc
122 *  nal ref idc to be inserted
123 *
124 * @return      success or failure error code
125 *
126 ******************************************************************************
127 */
ih264e_generate_nal_unit_header(bitstrm_t * ps_bitstrm,WORD32 nal_unit_type,WORD32 nal_ref_idc)128 static WORD32 ih264e_generate_nal_unit_header(bitstrm_t *ps_bitstrm,
129                                               WORD32 nal_unit_type,
130                                               WORD32 nal_ref_idc)
131 {
132     WORD32 return_status = IH264E_SUCCESS;
133 
134     /* sanity checks */
135     ASSERT((nal_unit_type > 0) && (nal_unit_type < 32));
136 
137     /* forbidden_zero_bit + nal_ref_idc + nal_unit_type */
138     PUT_BITS(ps_bitstrm,
139              ((nal_ref_idc << 5) + nal_unit_type),
140              (1+2+5), /*1 forbidden zero bit + 2 nal_ref_idc + 5 nal_unit_type */
141              return_status,
142              "nal_unit_header");
143 
144     return(return_status);
145 }
146 /**
147 ******************************************************************************
148 *
149 * @brief Generates VUI (Video usability information)
150 *
151 * @par   Description
152 *  This function generates VUI header as per the spec
153 *
154 * @param[in]   ps_bitstrm
155 *  pointer to bitstream context (handle)
156 *
157 * @param[in]   ps_vui
158 *  pointer to structure containing VUI data
159 
160 *
161 * @return      success or failure error code
162 *
163 ******************************************************************************
164 */
ih264e_generate_vui(bitstrm_t * ps_bitstrm,vui_t * ps_vui)165 WORD32 ih264e_generate_vui(bitstrm_t *ps_bitstrm, vui_t *ps_vui)
166 {
167     WORD32 return_status = IH264E_SUCCESS;
168 
169     /* aspect_ratio_info_present_flag */
170     PUT_BITS(ps_bitstrm, ps_vui->u1_aspect_ratio_info_present_flag, 1,
171              return_status, "aspect_ratio_info_present_flag");
172 
173     if(ps_vui->u1_aspect_ratio_info_present_flag)
174     { /* aspect_ratio_idc */
175         PUT_BITS(ps_bitstrm, ps_vui->u1_aspect_ratio_idc, 8, return_status,
176                  "aspect_ratio_idc");
177         if(255 == ps_vui->u1_aspect_ratio_idc) /* Extended_SAR */
178         { /* sar_width */
179             PUT_BITS(ps_bitstrm, ps_vui->u2_sar_width, 16, return_status,
180                      "sar_width");
181             /* sar_height */
182             PUT_BITS(ps_bitstrm, ps_vui->u2_sar_height, 16, return_status,
183                      "sar_height");
184         }
185 
186     }
187     /* overscan_info_present_flag */
188     PUT_BITS(ps_bitstrm, ps_vui->u1_overscan_info_present_flag, 1,
189              return_status, "overscan_info_present_flag");
190 
191     if(ps_vui->u1_overscan_info_present_flag)
192     {
193         /* overscan_appropriate_flag */
194         PUT_BITS(ps_bitstrm, ps_vui->u1_overscan_appropriate_flag, 1,
195                  return_status, "overscan_appropriate_flag");
196 
197     }
198     /* video_signal_type_present_flag */
199     PUT_BITS(ps_bitstrm, ps_vui->u1_video_signal_type_present_flag, 1,
200              return_status, "video_signal_type_present_flag");
201 
202     if(ps_vui->u1_video_signal_type_present_flag)
203     { /* video_format */
204         PUT_BITS(ps_bitstrm, ps_vui->u1_video_format, 3, return_status,
205                  "video_format");
206 
207         /* video_full_range_flag */
208         PUT_BITS(ps_bitstrm, ps_vui->u1_video_full_range_flag, 1, return_status,
209                  "video_full_range_flag");
210 
211         /* colour_description_present_flag */
212         PUT_BITS(ps_bitstrm, ps_vui->u1_colour_description_present_flag, 1,
213                  return_status, "colour_description_present_flag");
214 
215         if(ps_vui->u1_colour_description_present_flag)
216         {
217             /* colour_primaries */
218             PUT_BITS(ps_bitstrm, ps_vui->u1_colour_primaries, 8, return_status,
219                      "colour_primaries");
220 
221             /* transfer_characteristics */
222             PUT_BITS(ps_bitstrm, ps_vui->u1_transfer_characteristics, 8,
223                      return_status, "transfer_characteristics");
224 
225             /* matrix_coefficients */
226             PUT_BITS(ps_bitstrm, ps_vui->u1_matrix_coefficients, 8,
227                      return_status, "matrix_coefficients");
228         }
229 
230     }
231 
232     /* chroma_loc_info_present_flag */
233     PUT_BITS(ps_bitstrm, ps_vui->u1_chroma_loc_info_present_flag, 1,
234              return_status, "chroma_loc_info_present_flag");
235 
236     if(ps_vui->u1_chroma_loc_info_present_flag)
237     {
238         /* chroma_sample_loc_type_top_field */
239         PUT_BITS_UEV(ps_bitstrm, ps_vui->u1_chroma_sample_loc_type_top_field,
240                      return_status, "chroma_sample_loc_type_top_field");
241 
242         /* chroma_sample_loc_type_bottom_field */
243         PUT_BITS_UEV(ps_bitstrm, ps_vui->u1_chroma_sample_loc_type_bottom_field,
244                      return_status, "chroma_sample_loc_type_bottom_field");
245     }
246 
247     /* timing_info_present_flag */
248     PUT_BITS(ps_bitstrm, ps_vui->u1_vui_timing_info_present_flag, 1,
249              return_status, "timing_info_present_flag");
250 
251     if(ps_vui->u1_vui_timing_info_present_flag)
252     {
253         /* num_units_in_tick */
254         PUT_BITS(ps_bitstrm, ps_vui->u4_vui_num_units_in_tick, 32,
255                  return_status, "num_units_in_tick");
256 
257         /* time_scale */
258         PUT_BITS(ps_bitstrm, ps_vui->u4_vui_time_scale, 32, return_status,
259                  "time_scale");
260 
261         /* fixed_frame_rate_flag */
262         PUT_BITS(ps_bitstrm, ps_vui->u1_fixed_frame_rate_flag, 1, return_status,
263                  "fixed_frame_rate_flag");
264 
265     }
266 
267     /* nal_hrd_parameters_present_flag */
268     PUT_BITS(ps_bitstrm, ps_vui->u1_nal_hrd_parameters_present_flag, 1,
269              return_status, "nal_hrd_parameters_present_flag");
270 
271     if(ps_vui->u1_nal_hrd_parameters_present_flag)
272     {
273         hrd_params_t * ps_hrd_params = &ps_vui->s_nal_hrd_parameters;
274         WORD32 i;
275         /* cpb_cnt_minus1 */
276         PUT_BITS_UEV(ps_bitstrm, ps_hrd_params->u1_cpb_cnt_minus1,
277                      return_status, "cpb_cnt_minus1");
278 
279         /* bit_rate_scale */
280         PUT_BITS(ps_bitstrm, ps_hrd_params->u4_bit_rate_scale, 4, return_status,
281                  "bit_rate_scale");
282 
283         /* cpb_size_scale */
284         PUT_BITS(ps_bitstrm, ps_hrd_params->u4_cpb_size_scale, 4, return_status,
285                  "cpb_size_scale");
286         for(i = 0; i < ps_hrd_params->u1_cpb_cnt_minus1; i++)
287         {
288             /* bit_rate_value_minus1[SchedSelIdx] */
289             PUT_BITS_UEV(ps_bitstrm,
290                          ps_hrd_params->au4_bit_rate_value_minus1[i],
291                          return_status, "bit_rate_value_minus1[SchedSelIdx]");
292 
293             /* cpb_size_value_minus1[SchedSelIdx] */
294             PUT_BITS_UEV(ps_bitstrm,
295                          ps_hrd_params->au4_cpb_size_value_minus1[i],
296                          return_status, "cpb_size_value_minus1[SchedSelIdx]");
297 
298             /* cbr_flag[SchedSelIdx] */
299             PUT_BITS(ps_bitstrm, ps_hrd_params->au1_cbr_flag[i], 1,
300                      return_status, "cbr_flag[SchedSelIdx]");
301         }
302 
303         /* initial_cpb_removal_delay_length_minus1 */
304         PUT_BITS(ps_bitstrm,
305                  ps_hrd_params->u1_initial_cpb_removal_delay_length_minus1, 5,
306                  return_status, "initial_cpb_removal_delay_length_minus1");
307 
308         /* cpb_removal_delay_length_minus1 */
309         PUT_BITS(ps_bitstrm, ps_hrd_params->u1_cpb_removal_delay_length_minus1,
310                  5, return_status, "cpb_removal_delay_length_minus1");
311 
312         /* dpb_output_delay_length_minus1 */
313         PUT_BITS(ps_bitstrm, ps_hrd_params->u1_dpb_output_delay_length_minus1,
314                  5, return_status, "dpb_output_delay_length_minus1");
315 
316         /* time_offset_length */
317         PUT_BITS(ps_bitstrm, ps_hrd_params->u1_time_offset_length, 5,
318                  return_status, "time_offset_length");
319     }
320 
321     /* vcl_hrd_parameters_present_flag */
322     PUT_BITS(ps_bitstrm, ps_vui->u1_vcl_hrd_parameters_present_flag, 1,
323              return_status, "vcl_hrd_parameters_present_flag");
324 
325     if(ps_vui->u1_vcl_hrd_parameters_present_flag)
326     {
327         hrd_params_t * ps_hrd_params = &ps_vui->s_vcl_hrd_parameters;
328         WORD32 i;
329         /* cpb_cnt_minus1 */
330         PUT_BITS_UEV(ps_bitstrm, ps_hrd_params->u1_cpb_cnt_minus1,
331                      return_status, "cpb_cnt_minus1");
332 
333         /* bit_rate_scale */
334         PUT_BITS(ps_bitstrm, ps_hrd_params->u4_bit_rate_scale, 4, return_status,
335                  "bit_rate_scale");
336 
337         /* cpb_size_scale */
338         PUT_BITS(ps_bitstrm, ps_hrd_params->u4_cpb_size_scale, 4, return_status,
339                  "cpb_size_scale");
340         for(i = 0; i < ps_hrd_params->u1_cpb_cnt_minus1; i++)
341         {
342             /* bit_rate_value_minus1[SchedSelIdx] */
343             PUT_BITS_UEV(ps_bitstrm,
344                          ps_hrd_params->au4_bit_rate_value_minus1[i],
345                          return_status, "bit_rate_value_minus1[SchedSelIdx]");
346 
347             /* cpb_size_value_minus1[SchedSelIdx] */
348             PUT_BITS_UEV(ps_bitstrm,
349                          ps_hrd_params->au4_cpb_size_value_minus1[i],
350                          return_status, "cpb_size_value_minus1[SchedSelIdx]");
351 
352             /* cbr_flag[SchedSelIdx] */
353             PUT_BITS(ps_bitstrm, ps_hrd_params->au1_cbr_flag[i], 1,
354                      return_status, "cbr_flag[SchedSelIdx]");
355         }
356 
357         /* initial_cpb_removal_delay_length_minus1 */
358         PUT_BITS(ps_bitstrm,
359                  ps_hrd_params->u1_initial_cpb_removal_delay_length_minus1, 5,
360                  return_status, "initial_cpb_removal_delay_length_minus1");
361 
362         /* cpb_removal_delay_length_minus1 */
363         PUT_BITS(ps_bitstrm, ps_hrd_params->u1_cpb_removal_delay_length_minus1,
364                  5, return_status, "cpb_removal_delay_length_minus1");
365 
366         /* dpb_output_delay_length_minus1 */
367         PUT_BITS(ps_bitstrm, ps_hrd_params->u1_dpb_output_delay_length_minus1,
368                  5, return_status, "dpb_output_delay_length_minus1");
369 
370         /* time_offset_length */
371         PUT_BITS(ps_bitstrm, ps_hrd_params->u1_time_offset_length, 5,
372                  return_status, "time_offset_length");
373     }
374 
375     if(ps_vui->u1_nal_hrd_parameters_present_flag
376                     || ps_vui->u1_vcl_hrd_parameters_present_flag)
377     {
378         /* low_delay_hrd_flag */
379         PUT_BITS(ps_bitstrm, ps_vui->u1_low_delay_hrd_flag, 1, return_status,
380                  "low_delay_hrd_flag");
381     }
382     /* pic_struct_present_flag */
383     PUT_BITS(ps_bitstrm, ps_vui->u1_pic_struct_present_flag, 1, return_status,
384              "pic_struct_present_flag");
385 
386     /* bitstream_restriction_flag */
387     PUT_BITS(ps_bitstrm, ps_vui->u1_bitstream_restriction_flag, 1,
388              return_status, "bitstream_restriction_flag");
389 
390     if(ps_vui->u1_bitstream_restriction_flag == 1)
391     {
392         /* motion_vectors_over_pic_boundaries_flag */
393         PUT_BITS(ps_bitstrm, ps_vui->u1_motion_vectors_over_pic_boundaries_flag,
394                  1, return_status, "motion_vectors_over_pic_boundaries_flag");
395 
396         /* max_bytes_per_pic_denom */
397         PUT_BITS_UEV(ps_bitstrm, ps_vui->u1_max_bytes_per_pic_denom,
398                      return_status, "max_bytes_per_pic_denom");
399 
400         /* max_bits_per_mb_denom */
401         PUT_BITS_UEV(ps_bitstrm, ps_vui->u1_max_bits_per_mb_denom,
402                      return_status, "max_bits_per_mb_denom");
403 
404         /* log2_max_mv_length_horizontal */
405         PUT_BITS_UEV(ps_bitstrm, ps_vui->u1_log2_max_mv_length_horizontal,
406                      return_status, "log2_max_mv_length_horizontal");
407 
408         /* log2_max_mv_length_vertical */
409         PUT_BITS_UEV(ps_bitstrm, ps_vui->u1_log2_max_mv_length_vertical,
410                      return_status, "log2_max_mv_length_vertical");
411 
412         /* max_num_reorder_frames */
413         PUT_BITS_UEV(ps_bitstrm, ps_vui->u1_num_reorder_frames, return_status,
414                      "max_num_reorder_frames");
415 
416         /* max_dec_frame_buffering */
417         PUT_BITS_UEV(ps_bitstrm, ps_vui->u1_max_dec_frame_buffering,
418                      return_status, "max_dec_frame_buffering");
419     }
420 
421     return return_status;
422 }
423 
424 /**
425 ******************************************************************************
426 *
427 * @brief Generates SPS (Sequence Parameter Set)
428 *
429 * @par   Description
430 *  This function generates Sequence Parameter Set header as per the spec
431 *
432 * @param[in]   ps_bitstrm
433 *  pointer to bitstream context (handle)
434 *
435 * @param[in]   ps_sps
436 *  pointer to structure containing SPS data
437 *
438 * @param[in]   ps_vui
439 *  pointer to structure containing VUI data
440 *
441 * @return      success or failure error code
442 *
443 ******************************************************************************
444 */
ih264e_generate_sps(bitstrm_t * ps_bitstrm,sps_t * ps_sps,vui_t * ps_vui)445 WORD32 ih264e_generate_sps(bitstrm_t *ps_bitstrm, sps_t *ps_sps, vui_t *ps_vui)
446 {
447     WORD32 return_status = IH264E_SUCCESS;
448     WORD32 i;
449     WORD8  i1_nal_unit_type = 7;
450     WORD8  i1_nal_ref_idc = 3;
451 
452     /* Insert Start Code */
453     return_status = ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
454     if(return_status != IH264E_SUCCESS)
455     {
456         return return_status;
457     }
458     /* Insert Nal Unit Header */
459     return_status = ih264e_generate_nal_unit_header(ps_bitstrm, i1_nal_unit_type, i1_nal_ref_idc);
460     if(return_status != IH264E_SUCCESS)
461     {
462         return return_status;
463     }
464     /* profile_idc */
465     PUT_BITS(ps_bitstrm, ps_sps->u1_profile_idc, 8, return_status, "profile_idc");
466 
467     /* constrained_set_flags */
468     PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set0_flag, 1, return_status, "constrained_set0_flag");
469     PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set1_flag, 1, return_status, "constrained_set1_flag");
470     PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set2_flag, 1, return_status, "constrained_set2_flag");
471     PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set3_flag, 1, return_status, "constrained_set3_flag");
472 
473     /* reserved_zero_four_bits */
474     PUT_BITS(ps_bitstrm, 0, 4, return_status, "reserved_zero_four_bits");
475 
476     /* level_idc */
477     PUT_BITS(ps_bitstrm, ps_sps->u1_level_idc, 8, return_status, "level_idc");
478 
479     /* seq_parameter_set_id */
480     PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_sps_id, return_status, "seq_parameter_set_id");
481 
482     if (ps_sps->u1_profile_idc >= IH264_PROFILE_HIGH)
483     {
484         /* chroma_format_idc */
485         PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_chroma_format_idc, return_status, "chroma_format_idc");
486 
487         if (ps_sps->u1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
488         {
489             /* i1_residual_colour_transform_flag */
490             PUT_BITS(ps_bitstrm, ps_sps->i1_residual_colour_transform_flag, 1, return_status, "i1_residual_colour_transform_flag");
491         }
492 
493         /* bit_depth_luma_minus8 */
494         PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_bit_depth_luma - 8), return_status, "bit_depth_luma_minus8");
495 
496         /* bit_depth_chroma_minus8 */
497         PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_bit_depth_chroma - 8), return_status, "bit_depth_chroma_minus8");
498 
499         /* qpprime_y_zero_transform_bypass_flag */
500         PUT_BITS(ps_bitstrm, ps_sps->i1_qpprime_y_zero_transform_bypass_flag, 1, return_status, "qpprime_y_zero_transform_bypass_flag");
501 
502         /* seq_scaling_matrix_present_flag */
503         PUT_BITS(ps_bitstrm, ps_sps->i1_seq_scaling_matrix_present_flag, 1, return_status, "seq_scaling_matrix_present_flag");
504 
505         /* seq_scaling_list */
506         if (ps_sps->i1_seq_scaling_matrix_present_flag)
507         {
508             /* TODO_LATER: Will be enabled once scaling list support is added */
509         }
510     }
511 
512     /* log2_max_frame_num_minus4 */
513     PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_log2_max_frame_num - 4), return_status, "log2_max_frame_num_minus4");
514 
515     /* pic_order_cnt_type */
516     PUT_BITS_UEV(ps_bitstrm, ps_sps->i1_pic_order_cnt_type, return_status, "pic_order_cnt_type");
517 
518     if (ps_sps->i1_pic_order_cnt_type == 0)
519     {
520         /* log2_max_pic_order_cnt_lsb_minus4 */
521         PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_log2_max_pic_order_cnt_lsb - 4), return_status, "log2_max_pic_order_cnt_lsb_minus4");
522     }
523     else if (ps_sps->i1_pic_order_cnt_type == 1)
524     {
525         /* delta_pic_order_always_zero_flag */
526         PUT_BITS(ps_bitstrm, ps_sps->i1_delta_pic_order_always_zero_flag, 1, return_status, "delta_pic_order_always_zero_flag");
527 
528         /* offset_for_non_ref_pic */
529         PUT_BITS_SEV(ps_bitstrm, ps_sps->i4_offset_for_non_ref_pic, return_status, "offset_for_non_ref_pic");
530 
531         /* offset_for_top_to_bottom_field */
532         PUT_BITS_SEV(ps_bitstrm, ps_sps->i4_offset_for_top_to_bottom_field, return_status, "offset_for_top_to_bottom_field");
533 
534         /* num_ref_frames_in_pic_order_cnt_cycle */
535         PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_num_ref_frames_in_pic_order_cnt_cycle, return_status, "num_ref_frames_in_pic_order_cnt_cycle");
536 
537         /* Offset for ref frame */
538         for (i=0; i<ps_sps->u1_num_ref_frames_in_pic_order_cnt_cycle; i++)
539         {
540             /* offset_for_ref_frame */
541             PUT_BITS_SEV(ps_bitstrm, ps_sps->ai4_offset_for_ref_frame[i], return_status, "offset_for_ref_frame");
542         }
543     }
544 
545     /* num_ref_frames */
546     PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_max_num_ref_frames, return_status, "num_ref_frames");
547 
548     /* gaps_in_frame_num_value_allowed_flag */
549     PUT_BITS(ps_bitstrm, ps_sps->i1_gaps_in_frame_num_value_allowed_flag, 1, return_status, "gaps_in_frame_num_value_allowed_flag");
550 
551     /* pic_width_in_mbs_minus1 */
552     PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_pic_width_in_mbs_minus1, return_status, "pic_width_in_mbs_minus1");
553 
554     /* pic_height_in_map_units_minus1 */
555     PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_pic_height_in_map_units_minus1, return_status, "pic_height_in_map_units_minus1");
556 
557     /* frame_mbs_only_flag */
558     PUT_BITS(ps_bitstrm, ps_sps->i1_frame_mbs_only_flag, 1, return_status, "frame_mbs_only_flag");
559 
560     if (!ps_sps->i1_frame_mbs_only_flag)
561     {
562         /* mb_adaptive_frame_field_flag */
563         PUT_BITS(ps_bitstrm, ps_sps->i1_mb_adaptive_frame_field_flag, 1, return_status, "mb_adaptive_frame_field_flag");
564     }
565 
566     /* direct_8x8_inference_flag */
567     PUT_BITS(ps_bitstrm, ps_sps->i1_direct_8x8_inference_flag, 1, return_status, "direct_8x8_inference_flag");
568 
569     /* frame_cropping_flag */
570     PUT_BITS(ps_bitstrm, ps_sps->i1_frame_cropping_flag, 1, return_status, "frame_cropping_flag");
571 
572     if (ps_sps->i1_frame_cropping_flag)
573     {
574         /* frame_crop_left_offset */
575         PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_left_offset, return_status, "frame_crop_left_offset");
576 
577         /* frame_crop_right_offset */
578         PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_right_offset, return_status, "frame_crop_right_offset");
579 
580         /* frame_crop_top_offset */
581         PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_top_offset, return_status, "frame_crop_top_offset");
582 
583         /* frame_crop_bottom_offset */
584         PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_bottom_offset, return_status, "frame_crop_bottom_offset");
585     }
586 
587     /* vui_parameters_present_flag */
588     PUT_BITS(ps_bitstrm, ps_sps->i1_vui_parameters_present_flag, 1, return_status, "vui_parameters_present_flag");
589 
590     if (ps_sps->i1_vui_parameters_present_flag)
591     {
592         /* Add vui parameters to the bitstream */;
593         return_status = ih264e_generate_vui(ps_bitstrm, ps_vui);
594         if(return_status != IH264E_SUCCESS)
595         {
596             return return_status;
597         }
598     }
599 
600     /* rbsp trailing bits */
601     return_status = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
602 
603     return return_status;
604 }
605 
606 /**
607 ******************************************************************************
608 *
609 * @brief Generates PPS (Picture Parameter Set)
610 *
611 * @par   Description
612 *  Generate Picture Parameter Set as per Section 7.3.2.2
613 *
614 * @param[in]   ps_bitstrm
615 *  pointer to bitstream context (handle)
616 *
617 * @param[in]   ps_pps
618 *  pointer to structure containing PPS data
619 *
620 * @return      success or failure error code
621 *
622 ******************************************************************************
623 */
ih264e_generate_pps(bitstrm_t * ps_bitstrm,pps_t * ps_pps,sps_t * ps_sps)624 WORD32 ih264e_generate_pps(bitstrm_t *ps_bitstrm, pps_t *ps_pps, sps_t *ps_sps)
625 {
626     WORD32 return_status = IH264E_SUCCESS;
627 
628     /* Insert the NAL start code */
629     return_status = ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
630     if(return_status != IH264E_SUCCESS)
631     {
632         return return_status;
633     }
634 
635     /* Insert Nal Unit Header */
636     PUT_BITS(ps_bitstrm, NAL_PPS_FIRST_BYTE, 8, return_status, "pps_header");
637 
638     /* pic_parameter_set_id */
639     PUT_BITS_UEV(ps_bitstrm, ps_pps->u1_pps_id, return_status, "pic_parameter_set_id");
640 
641     /* seq_parameter_set_id */
642     PUT_BITS_UEV(ps_bitstrm, ps_pps->u1_sps_id, return_status, "seq_parameter_set_id");
643 
644     /* Entropy coding : 0-VLC; 1 - CABAC */
645     PUT_BITS(ps_bitstrm, ps_pps->u1_entropy_coding_mode_flag, 1, return_status, "Entropy coding : 0-VLC; 1 - CABAC");
646 
647     /* Pic order present flag */
648     PUT_BITS(ps_bitstrm, ps_pps->u1_pic_order_present_flag, 1, return_status, "Pic order present flag");
649 
650     /* Number of slice groups */
651     PUT_BITS_UEV(ps_bitstrm, ps_pps->u1_num_slice_groups - 1, return_status, "Number of slice groups");
652 
653     if (ps_pps->u1_num_slice_groups > 1)
654     {
655         /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
656          * If this is not the case, we have to add Slice group map type to the bit stream*/
657     }
658 
659     /* num_ref_idx_l0_default_active_minus1 */
660     PUT_BITS_UEV(ps_bitstrm, ps_pps->i1_num_ref_idx_l0_default_active - 1, return_status, "num_ref_idx_l0_default_active_minus1");
661 
662     /* num_ref_idx_l1_default_active_minus1 */
663     PUT_BITS_UEV(ps_bitstrm, ps_pps->i1_num_ref_idx_l1_default_active - 1, return_status, "num_ref_idx_l1_default_active_minus1");
664 
665     /* weighted_pred_flag */
666     PUT_BITS(ps_bitstrm, ps_pps->i1_weighted_pred_flag, 1, return_status, "weighted_pred_flag");
667 
668     /* weighted_bipred_flag */
669     PUT_BITS(ps_bitstrm, ps_pps->i1_weighted_bipred_idc, 2, return_status, "weighted_bipred_idc");
670 
671     /* pic_init_qp_minus26 */
672     PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_pic_init_qp - 26, return_status, "pic_init_qp_minus26");
673 
674     /* pic_init_qs_minus26 */
675     PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_pic_init_qs - 26, return_status, "pic_init_qs_minus26");
676 
677     /* chroma_qp_index_offset */
678     PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_chroma_qp_index_offset, return_status, "chroma_qp_index_offset");
679 
680     /* deblocking_filter_control_present_flag */
681     PUT_BITS(ps_bitstrm, ps_pps->i1_deblocking_filter_control_present_flag, 1, return_status, "deblocking_filter_control_present_flag");
682 
683     /* constrained_intra_pred_flag */
684     PUT_BITS(ps_bitstrm, ps_pps->i1_constrained_intra_pred_flag, 1, return_status, "constrained_intra_pred_flag");
685 
686     /*redundant_pic_cnt_present_flag */
687     PUT_BITS(ps_bitstrm, ps_pps->i1_redundant_pic_cnt_present_flag, 1, return_status, "redundant_pic_cnt_present_flag");
688 
689     if (ps_sps->u1_profile_idc >= IH264_PROFILE_HIGH)
690     {
691         /* transform_8x8_mode_flag */
692         PUT_BITS(ps_bitstrm, ps_pps->i1_transform_8x8_mode_flag, 1, return_status, "transform_8x8_mode_flag");
693 
694         /* pic_scaling_matrix_present_flag */
695         PUT_BITS(ps_bitstrm, ps_pps->i1_pic_scaling_matrix_present_flag, 1, return_status, "pic_scaling_matrix_present_flag");
696 
697         if(ps_pps->i1_pic_scaling_matrix_present_flag)
698         {
699             /* TODO_LATER: Will be enabled once scaling list support is added */
700         }
701 
702         /* Second chroma QP offset */
703         PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_second_chroma_qp_index_offset, return_status, "Second chroma QP offset");
704     }
705 
706     return_status = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
707 
708     return return_status;
709 }
710 
711 /**
712 ******************************************************************************
713 *
714 * @brief Generates SEI (Supplemental Enhancement Information)
715 *
716 * @par   Description
717 *  This function generates Supplemental Enhancement Information header as per the spec
718 *
719 * @param[in]   ps_bitstrm
720 *  pointer to bitstream context (handle)
721 *
722 * @param[in]   ps_sei
723 *  pointer to structure containing SEI data
724 *
725 * @return      success or failure error code
726 *
727 ******************************************************************************
728 */
ih264e_generate_sei(bitstrm_t * ps_bitstrm,sei_params_t * ps_sei,UWORD32 u4_insert_per_idr)729 IH264E_ERROR_T ih264e_generate_sei(bitstrm_t *ps_bitstrm, sei_params_t *ps_sei,
730                                                         UWORD32 u4_insert_per_idr)
731 {
732     WORD32 return_status = IH264E_SUCCESS;
733     WORD8  i1_nal_unit_type = NAL_SEI;
734     WORD8  i1_nal_ref_idc = 0;
735 
736     /* Insert Start Code */
737     return_status = ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
738     if(return_status != IH264E_SUCCESS)
739     {
740         return return_status;
741     }
742 
743     /* Insert Nal Unit Header */
744     return_status = ih264e_generate_nal_unit_header(ps_bitstrm,
745                                                     i1_nal_unit_type, i1_nal_ref_idc);
746     if(return_status != IH264E_SUCCESS)
747     {
748         return return_status;
749     }
750     /* Mastering Display Color SEI */
751     if(1 == ps_sei->u1_sei_mdcv_params_present_flag && u4_insert_per_idr)
752     {
753         return_status = ih264e_put_sei_msg(IH264_SEI_MASTERING_DISP_COL_VOL,
754                                             ps_sei, ps_bitstrm);
755         if(return_status != IH264E_SUCCESS)
756         {
757             return return_status;
758         }
759     }
760 
761     /* Content Light Level Information*/
762     if(1 == ps_sei->u1_sei_cll_params_present_flag && u4_insert_per_idr)
763     {
764         return_status = ih264e_put_sei_msg(IH264_SEI_CONTENT_LIGHT_LEVEL_DATA,
765                                             ps_sei, ps_bitstrm);
766         if(return_status != IH264E_SUCCESS)
767         {
768             return return_status;
769         }
770     }
771 
772     /* Ambient viewing environment SEI */
773     if(1 == ps_sei->u1_sei_ave_params_present_flag && u4_insert_per_idr)
774     {
775         return_status = ih264e_put_sei_msg(IH264_SEI_AMBIENT_VIEWING_ENVIRONMENT,
776                                             ps_sei, ps_bitstrm);
777         if(return_status != IH264E_SUCCESS)
778         {
779             return return_status;
780         }
781     }
782 
783     /* Content color volume Information*/
784     if(1 == ps_sei->u1_sei_ccv_params_present_flag)
785     {
786         return_status = ih264e_put_sei_msg(IH264_SEI_CONTENT_COLOR_VOLUME,
787                                             ps_sei, ps_bitstrm);
788         if(return_status != IH264E_SUCCESS)
789         {
790             return return_status;
791         }
792     }
793 
794     /* Shutter Interval Information*/
795     if(1 == ps_sei->u1_sei_sii_params_present_flag)
796     {
797         return_status = ih264e_put_sei_msg(IH264_SEI_SHUTTER_INTERVAL_INFO, ps_sei, ps_bitstrm);
798         if(return_status != IH264E_SUCCESS)
799         {
800             return return_status;
801         }
802     }
803 
804     /* rbsp trailing bits */
805     return_status = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
806 
807     return return_status;
808 }
809 
810 /**
811 ******************************************************************************
812 *
813 * @brief Generates Slice Header
814 *
815 * @par   Description
816 *  Generate Slice Header as per Section 7.3.5.1
817 *
818 * @param[inout]   ps_bitstrm
819 *  pointer to bitstream context for generating slice header
820 *
821 * @param[in]   ps_slice_hdr
822 *  pointer to slice header params
823 *
824 * @param[in]   ps_pps
825 *  pointer to pps params referred by slice
826 *
827 * @param[in]   ps_sps
828 *  pointer to sps params referred by slice
829 *
830 * @param[out]   ps_dup_bit_strm_ent_offset
831 *  Bitstream struct to store bitstream state
832 *
833 * @param[out]   pu4_first_slice_start_offset
834 *  first slice offset is returned
835 *
836 * @return      success or failure error code
837 *
838 ******************************************************************************
839 */
ih264e_generate_slice_header(bitstrm_t * ps_bitstrm,slice_header_t * ps_slice_hdr,pps_t * ps_pps,sps_t * ps_sps)840 WORD32 ih264e_generate_slice_header(bitstrm_t *ps_bitstrm,
841                                     slice_header_t *ps_slice_hdr,
842                                     pps_t *ps_pps,
843                                     sps_t *ps_sps)
844 {
845 
846     WORD32 return_status = IH264E_SUCCESS;
847 
848     /* Insert start code */
849     return_status = ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
850     if(return_status != IH264E_SUCCESS)
851     {
852         return return_status;
853     }
854     /* Insert Nal Unit Header */
855     return_status = ih264e_generate_nal_unit_header(ps_bitstrm, ps_slice_hdr->i1_nal_unit_type, ps_slice_hdr->i1_nal_unit_idc);
856     if(return_status != IH264E_SUCCESS)
857     {
858         return return_status;
859     }
860     /* first_mb_in_slice */
861     PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u2_first_mb_in_slice, return_status, "first_mb_in_slice");
862 
863     /* slice_type */
864     PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_slice_type, return_status, "slice_type");
865 
866     /* pic_parameter_set_id */
867     PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_pps_id, return_status, "pic_parameter_set_id");
868 
869     /* frame_num */
870     PUT_BITS(ps_bitstrm, ps_slice_hdr->i4_frame_num, ps_sps->i1_log2_max_frame_num, return_status, "frame_num");
871 
872     if (!ps_sps->i1_frame_mbs_only_flag)
873     {
874         /* field_pic_flag */
875         PUT_BITS(ps_bitstrm, ps_slice_hdr->i1_field_pic_flag, 1, return_status, "field_pic_flag");
876 
877         if(ps_slice_hdr->i1_field_pic_flag)
878         {
879             /* bottom_field_flag */
880             PUT_BITS(ps_bitstrm, ps_slice_hdr->i1_bottom_field_flag, 1, return_status, "bottom_field_flag");
881         }
882     }
883 
884     if (ps_slice_hdr->i1_nal_unit_type == 5)
885     {
886         /* u2_idr_pic_id */
887         PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u2_idr_pic_id, return_status, "u2_idr_pic_id");
888     }
889 
890     if (ps_sps->i1_pic_order_cnt_type == 0)
891     {
892         /* pic_order_cnt_lsb */
893         PUT_BITS(ps_bitstrm, ps_slice_hdr->i4_pic_order_cnt_lsb, ps_sps->i1_log2_max_pic_order_cnt_lsb, return_status, "pic_order_cnt_lsb");
894 
895         if(ps_pps->u1_pic_order_present_flag && !ps_slice_hdr->i1_field_pic_flag)
896         {
897             /* delta_pic_order_cnt_bottom */
898             PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i4_delta_pic_order_cnt_bottom, return_status, "delta_pic_order_cnt_bottom");
899         }
900     }
901 
902     if (ps_sps->i1_pic_order_cnt_type == 1 && !ps_sps->i1_delta_pic_order_always_zero_flag)
903     {
904         /* delta_pic_order_cnt[0] */
905         PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->ai4_delta_pic_order_cnt[0], return_status, "delta_pic_order_cnt[0]");
906 
907         if (ps_pps->u1_pic_order_present_flag && !ps_slice_hdr->i1_field_pic_flag)
908         {
909             /* delta_pic_order_cnt[1] */
910             PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->ai4_delta_pic_order_cnt[1], return_status, "delta_pic_order_cnt[1]");
911         }
912     }
913 
914     if (ps_pps->i1_redundant_pic_cnt_present_flag)
915     {
916         /* redundant_pic_cnt */
917         PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_redundant_pic_cnt, return_status, "redundant_pic_cnt");
918     }
919 
920     if (ps_slice_hdr->u1_slice_type == BSLICE)
921     {
922         /* direct_spatial_mv_pred_flag */
923         PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_direct_spatial_mv_pred_flag, 1, return_status, "direct_spatial_mv_pred_flag");
924     }
925 
926     if (ps_slice_hdr->u1_slice_type == PSLICE || ps_slice_hdr->u1_slice_type == SPSLICE || ps_slice_hdr->u1_slice_type == BSLICE)
927     {
928         /* num_ref_idx_active_override_flag */
929         PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_num_ref_idx_active_override_flag, 1, return_status, "num_ref_idx_active_override_flag");
930 
931         if (ps_slice_hdr->u1_num_ref_idx_active_override_flag)
932         {
933             /* num_ref_idx_l0_active_minus1 */
934             PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_num_ref_idx_l0_active - 1, return_status, "num_ref_idx_l0_active_minus1");
935 
936             if (ps_slice_hdr->u1_slice_type == BSLICE)
937             {
938                 /* num_ref_idx_l1_active_minus1 */
939                 PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_num_ref_idx_l1_active - 1, return_status, "num_ref_idx_l1_active_minus1");
940             }
941         }
942     }
943 
944     /* ref_idx_reordering */
945     /* TODO: ref_idx_reordering */
946     if ((ps_slice_hdr->u1_slice_type != ISLICE) && (ps_slice_hdr->u1_slice_type != SISLICE))
947     {
948         /* ref_pic_list_reordering_flag_l0 */
949         PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_ref_idx_reordering_flag_l0, 1, return_status, "ref_pic_list_reordering_flag_l0");
950 
951         if (ps_slice_hdr->u1_ref_idx_reordering_flag_l0)
952         {
953 
954         }
955     }
956 
957     if (ps_slice_hdr->u1_slice_type == BSLICE)
958     {
959         /* ref_pic_list_reordering_flag_l1 */
960         PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_ref_idx_reordering_flag_l1, 1, return_status, "ref_pic_list_reordering_flag_l1");
961 
962         if (ps_slice_hdr->u1_ref_idx_reordering_flag_l1)
963         {
964 
965         }
966     }
967 
968     if ((ps_pps->i1_weighted_pred_flag &&
969                     (ps_slice_hdr->u1_slice_type == PSLICE || ps_slice_hdr->u1_slice_type == SPSLICE)) ||
970                     (ps_slice_hdr->u1_slice_type == BSLICE && ps_pps->i1_weighted_bipred_idc == 1))
971     {
972         /* TODO_LATER: Currently there is no support for weighted prediction.
973          This needs to be updated when the support is added */
974     }
975 
976     if (ps_slice_hdr->i1_nal_unit_idc != 0)
977     {
978         if (ps_slice_hdr->i1_nal_unit_type == 5)
979         {
980             /* no_output_of_prior_pics_flag  */
981             PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_no_output_of_prior_pics_flag , 1, return_status, "no_output_of_prior_pics_flag ");
982 
983             /* long_term_reference_flag  */
984             PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_long_term_reference_flag , 1, return_status, "long_term_reference_flag ");
985         }
986         else
987         {
988             /* adaptive_ref_pic_marking_mode_flag  */
989             PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag , 1, return_status, "adaptive_ref_pic_marking_mode_flag ");
990 
991             if (ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag)
992             {
993                 /* TODO: if the reference picture marking mode is adaptive
994                  add these fields in the bit-stream */
995             }
996         }
997     }
998 
999     if (ps_slice_hdr->u1_entropy_coding_mode_flag && ps_slice_hdr->u1_slice_type != ISLICE &&
1000                     ps_slice_hdr->u1_slice_type != SISLICE)
1001     {
1002         /* cabac_init_idc */
1003         PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_cabac_init_idc, return_status, "cabac_init_idc");
1004     }
1005 
1006     /* slice_qp_delta */
1007     PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_qp - ps_pps->i1_pic_init_qp, return_status, "slice_qp_delta");
1008 
1009     if (ps_slice_hdr->u1_slice_type == SPSLICE || ps_slice_hdr->u1_slice_type == SISLICE)
1010     {
1011         if (ps_slice_hdr->u1_slice_type == SPSLICE)
1012         {
1013             /* sp_for_switch_flag */
1014             PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_sp_for_switch_flag , 1, return_status, "sp_for_switch_flag");
1015         }
1016         /* slice_qs_delta */
1017         PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->u1_slice_qs - ps_pps->i1_pic_init_qs, return_status, "slice_qs_delta");
1018     }
1019 
1020     if (ps_pps->i1_deblocking_filter_control_present_flag)
1021     {
1022         /* disable_deblocking_filter_idc */
1023         PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_disable_deblocking_filter_idc, return_status, "disable_deblocking_filter_idc");
1024 
1025         if(ps_slice_hdr->u1_disable_deblocking_filter_idc != 1)
1026         {
1027             /* slice_alpha_c0_offset_div2 */
1028             PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_alpha_c0_offset_div2, return_status, "slice_alpha_c0_offset_div2");
1029 
1030             /* slice_beta_offset_div2 */
1031             PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_beta_offset_div2, return_status, "slice_beta_offset_div2");
1032         }
1033     }
1034 
1035     if (ps_slice_hdr->u1_num_slice_groups_minus1 > 0 &&
1036                     ps_pps->u1_slice_group_map_type >= 3 &&
1037                     ps_pps->u1_slice_group_map_type <= 5)
1038     {
1039         /* slice_group_change_cycle */
1040         /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
1041          * If this is not the case, we have to add Slice group map type to the bit stream */
1042     }
1043 
1044     return return_status;
1045 }
1046 
1047 /**
1048 ******************************************************************************
1049 *
1050 * @brief Populates VUI structure
1051 *
1052 * @par   Description
1053 *  Populates VUI structure for its use in header generation
1054 *
1055 * @param[in]   ps_codec
1056 *  pointer to encoder context
1057 *
1058 * @return      success or failure error code
1059 *
1060 ******************************************************************************
1061 */
ih264e_populate_vui(codec_t * ps_codec)1062 IH264E_ERROR_T ih264e_populate_vui(codec_t *ps_codec)
1063 {
1064     /* vui params */
1065     vui_t *ps_vui = &ps_codec->s_cfg.s_vui;
1066 
1067     /* active sps params */
1068     sps_t *ps_sps = ps_codec->ps_sps_base + ps_codec->i4_sps_id;
1069 
1070     ps_vui->u1_nal_hrd_parameters_present_flag = 0;
1071 
1072     ps_vui->u1_vcl_hrd_parameters_present_flag = 0;
1073 
1074     ps_vui->u1_bitstream_restriction_flag = 1;
1075 
1076     ps_vui->u1_motion_vectors_over_pic_boundaries_flag = 1;
1077 
1078     ps_vui->u1_max_bytes_per_pic_denom = 0;
1079 
1080     ps_vui->u1_max_bits_per_mb_denom = 0;
1081 
1082     ps_vui->u1_log2_max_mv_length_horizontal = 16;
1083 
1084     ps_vui->u1_log2_max_mv_length_vertical = 16;
1085 
1086     if (ps_codec->s_cfg.u4_num_bframes == 0)
1087     {
1088         ps_vui->u1_num_reorder_frames = 0;
1089     }
1090     else
1091     {
1092         ps_vui->u1_num_reorder_frames = 1;
1093     }
1094 
1095     ps_vui->u1_max_dec_frame_buffering = ps_sps->u1_max_num_ref_frames;
1096 
1097     return IH264E_SUCCESS;
1098 }
1099 
1100 /**
1101 ******************************************************************************
1102 *
1103 * @brief Populates sps structure
1104 *
1105 * @par   Description
1106 *  Populates sps structure for its use in header generation
1107 *
1108 * @param[in]   ps_codec
1109 *  pointer to encoder context
1110 *
1111 * @param[out]  ps_sps
1112 *  pointer to sps params that needs to be populated
1113 *
1114 * @return      success or failure error code
1115 *
1116 ******************************************************************************
1117 */
ih264e_populate_sps(codec_t * ps_codec,sps_t * ps_sps)1118 IH264E_ERROR_T ih264e_populate_sps(codec_t *ps_codec, sps_t *ps_sps)
1119 {
1120     /* active config parameters */
1121     cfg_params_t    *ps_cfg = &(ps_codec->s_cfg);
1122 
1123 //    /* level */
1124 //    IH264_LEVEL_T   level_idc;
1125 
1126     /* error_status */
1127     IH264E_ERROR_T i4_err_code = IH264E_FAIL;
1128 
1129     /* profile */
1130     /*
1131      * Baseline profile supports, 8 bits per sample, 4:2:0 format, CAVLC.
1132      * B frames are not allowed. Further, Flexible mb ordering, Redundant slices, Arbitrary slice ordering are supported.
1133      * The constrained baseline profile is baseline profile minus ASO, FMO and redundant slices.
1134      * To the constrained baseline profile if we add support for B slices, support for encoding interlaced frames,
1135      * support for weighted prediction and introduce CABAC entropy coding then we have Main Profile.
1136      */
1137     if ((ps_cfg->u4_num_bframes) || (ps_cfg->e_content_type != IV_PROGRESSIVE) ||
1138         (ps_cfg->u4_entropy_coding_mode == CABAC) || (ps_cfg->u4_weighted_prediction))
1139     {
1140         ps_sps->u1_profile_idc = IH264_PROFILE_MAIN;
1141     }
1142     else
1143     {
1144         ps_sps->u1_profile_idc = IH264_PROFILE_BASELINE;
1145     }
1146 
1147     /* level */
1148     ps_sps->u1_level_idc = MAX(ps_cfg->u4_max_level,
1149                                (UWORD32)ih264e_get_min_level(ps_cfg->u4_max_wd, ps_cfg->u4_max_ht));
1150 
1151     /* constrained flags */
1152     /*
1153      * baseline profile automatically implies set 0 flag
1154      */
1155     ps_sps->u1_constraint_set0_flag = (ps_sps->u1_profile_idc == IH264_PROFILE_BASELINE);
1156     /*
1157      * main profile automatically implies set 1 flag
1158      * Although the encoder says it supports Baseline profile it actually supports constrained
1159      * baseline profile as ASO, FMO and redundant slices are not supported
1160      */
1161     ps_sps->u1_constraint_set1_flag = (ps_sps->u1_profile_idc <= IH264_PROFILE_MAIN);
1162     /*
1163      * extended profile is not supported
1164      */
1165     ps_sps->u1_constraint_set2_flag = 0x00;
1166     /*
1167      * level 1b or level 11
1168      */
1169     if (ps_sps->u1_level_idc == IH264_LEVEL_1B)
1170     {
1171         ps_sps->u1_constraint_set3_flag = 0;
1172         ps_sps->u1_level_idc = IH264_LEVEL_11;
1173     }
1174     else
1175     {
1176         ps_sps->u1_constraint_set3_flag = 0;
1177     }
1178 
1179     /* active sps id */
1180     ps_sps->u1_sps_id = ps_codec->i4_sps_id;
1181 
1182     if (ps_sps->u1_profile_idc >= IH264_PROFILE_HIGH)
1183     {
1184         /* chroma format idc */
1185         ps_sps->u1_chroma_format_idc = CHROMA_FMT_IDC_YUV420;
1186 
1187         /* residual_colour_transform_flag */
1188         ps_sps->i1_residual_colour_transform_flag = 0;
1189 
1190         /* luma bit depth 8 */
1191         ps_sps->i1_bit_depth_luma = 8;
1192 
1193         /* chroma bit depth 8 */
1194         ps_sps->i1_bit_depth_chroma = 8;
1195 
1196         /* qpprime_y_zero_transform_bypass_flag */
1197         ps_sps->i1_qpprime_y_zero_transform_bypass_flag = 0;
1198 
1199         /* seq_scaling_matrix_present_flag */
1200         ps_sps->i1_seq_scaling_matrix_present_flag = 0;
1201 
1202         if (ps_sps->i1_seq_scaling_matrix_present_flag)
1203         {
1204             /* TODO_LATER: Will be enabled once scaling list support is added */
1205         }
1206     }
1207 
1208     /* log2_max_frame_num_minus4 */
1209     ps_sps->i1_log2_max_frame_num = 16;
1210 
1211     /* pic_order_cnt_type */
1212     ps_sps->i1_pic_order_cnt_type = 2;
1213 
1214     if (ps_codec->i4_non_ref_frames_in_stream)
1215     {
1216         ps_sps->i1_pic_order_cnt_type = 0;
1217     }
1218 
1219     /* log2_max_pic_order_cnt_lsb_minus4 */
1220     ps_sps->i1_log2_max_pic_order_cnt_lsb = 8;
1221 
1222     /* TODO : add support for other poc types */
1223     if (ps_sps->i1_pic_order_cnt_type == 0)
1224     {
1225 
1226     }
1227     else if (ps_sps->i1_pic_order_cnt_type == 1)
1228     {
1229 
1230     }
1231 
1232     /* num_ref_frames */
1233     /* TODO : Should we have a flexible num ref frames */
1234     if (ps_codec->s_cfg.u4_num_bframes > 0)
1235     {
1236         ps_sps->u1_max_num_ref_frames = 2;
1237     }
1238     else
1239     {
1240         ps_sps->u1_max_num_ref_frames = 1;
1241     }
1242 
1243     /* gaps_in_frame_num_value_allowed_flag */
1244     ps_sps->i1_gaps_in_frame_num_value_allowed_flag = 0;
1245 
1246     /* pic width in mb - 1 */
1247     ps_sps->i2_pic_width_in_mbs_minus1 = ps_cfg->i4_wd_mbs - 1;
1248 
1249     /* pic height in mb - 1 */
1250     ps_sps->i2_pic_height_in_map_units_minus1 = ps_cfg->i4_ht_mbs - 1;;
1251 
1252     /* frame_mbs_only_flag, no support for interlace encoding */
1253     ps_sps->i1_frame_mbs_only_flag = 1;
1254 
1255     /* mb_adaptive_frame_field_flag */
1256     if (ps_sps->i1_frame_mbs_only_flag == 0)
1257     {
1258         ps_sps->i1_mb_adaptive_frame_field_flag = 0;
1259     }
1260 
1261     /* direct_8x8_inference_flag */
1262     if (ps_sps->u1_level_idc < IH264_LEVEL_30)
1263     {
1264         ps_sps->i1_direct_8x8_inference_flag = 0;
1265     }
1266     else
1267     {
1268         ps_sps->i1_direct_8x8_inference_flag = 1;
1269     }
1270 
1271 
1272     /* cropping params */
1273     /*NOTE : Cropping values depend on the chroma format
1274      * For our case ,decoder interprets the cropping values as 2*num pixels
1275      * Hence the difference in the disp width and width must be halved before sending
1276      * to get the expected results
1277      */
1278     ps_sps->i1_frame_cropping_flag      = 0;
1279     ps_sps->i2_frame_crop_left_offset   = 0;
1280     ps_sps->i2_frame_crop_right_offset  = (ps_codec->s_cfg.u4_wd - ps_codec->s_cfg.u4_disp_wd)>>1;
1281     ps_sps->i2_frame_crop_top_offset    = 0;
1282     ps_sps->i2_frame_crop_bottom_offset = (ps_codec->s_cfg.u4_ht - ps_codec->s_cfg.u4_disp_ht)>>1;
1283 
1284     if (ps_sps->i2_frame_crop_left_offset    ||
1285                     ps_sps->i2_frame_crop_right_offset   ||
1286                     ps_sps->i2_frame_crop_top_offset     ||
1287                     ps_sps->i2_frame_crop_bottom_offset)
1288     {
1289         ps_sps->i1_frame_cropping_flag      = 1;
1290     }
1291 
1292     /* vui params */
1293     ps_sps->i1_vui_parameters_present_flag = 1;
1294 
1295     if (ps_sps->i1_vui_parameters_present_flag)
1296     {
1297         /* populate vui params */
1298         ih264e_populate_vui(ps_codec);
1299     }
1300 
1301     return i4_err_code;
1302 }
1303 
1304 /**
1305 ******************************************************************************
1306 *
1307 * @brief Populates pps structure
1308 *
1309 * @par   Description
1310 *  Populates pps structure for its use in header generation
1311 *
1312 * @param[in]   ps_codec
1313 *  pointer to encoder context
1314 *
1315 * @param[out]  ps_pps
1316 *  pointer to pps params that needs to be populated
1317 *
1318 * @return      success or failure error code
1319 *
1320 ******************************************************************************
1321 */
ih264e_populate_pps(codec_t * ps_codec,pps_t * ps_pps)1322 IH264E_ERROR_T ih264e_populate_pps(codec_t *ps_codec, pps_t *ps_pps)
1323 {
1324     /* active config parameters */
1325     cfg_params_t    *ps_cfg = &(ps_codec->s_cfg);
1326 
1327     /* seq_parameter_set_id */
1328     ps_pps->u1_sps_id = ps_codec->i4_sps_id;
1329 
1330     /* pic_parameter_set_id */
1331     ps_pps->u1_pps_id = ps_codec->i4_pps_id;
1332 
1333     /* entropy_coding_mode */
1334     ps_pps->u1_entropy_coding_mode_flag = ps_cfg->u4_entropy_coding_mode;
1335 
1336     /* pic_order_present_flag is unset if we don't have feilds */
1337     ps_pps->u1_pic_order_present_flag = 0;
1338 
1339     /* Currently number of slice groups supported are 1 */
1340     ps_pps->u1_num_slice_groups = 1;
1341 
1342     if (ps_pps->u1_num_slice_groups - 1)
1343     {
1344         /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
1345          * If this is not the case, we have to add Slice group map type to the bit stream*/
1346     }
1347 
1348     /* number of reference frames for list 0 */
1349     /* FIXME : fix this hard coded value */
1350     ps_pps->i1_num_ref_idx_l0_default_active = 1;
1351 
1352     /* number of reference frames for list 1 */
1353     ps_pps->i1_num_ref_idx_l1_default_active = 1;
1354 
1355     /* weighted prediction for now is disabled */
1356     ps_pps->i1_weighted_pred_flag = 0;
1357     ps_pps->i1_weighted_bipred_idc = 0;
1358 
1359     /* The intent is to not signal qp from pps. Rather send the same in slice headers */
1360     ps_pps->i1_pic_init_qp = 0;
1361 
1362     /* The intent is to not signal qp from pps. Rather send the same in slice headers */
1363     ps_pps->i1_pic_init_qs = 0;
1364 
1365     /* The intent is to not signal qp from pps. Rather send the same in slice headers */
1366     ps_pps->i1_chroma_qp_index_offset = 0;
1367 
1368     /* deblocking filter flags present in slice header */
1369     ps_pps->i1_deblocking_filter_control_present_flag = 1;
1370 
1371     /* constrained intra prediction */
1372     ps_pps->i1_constrained_intra_pred_flag = ps_cfg->u4_constrained_intra_pred;
1373 
1374     /* sending redundant slices is not supported for now */
1375     ps_pps->i1_redundant_pic_cnt_present_flag = 0;
1376 
1377     ps_pps->u1_slice_group_map_type = 0;
1378 
1379     return IH264E_SUCCESS;
1380 }
1381 
1382 /**
1383 ******************************************************************************
1384 *
1385 * @brief Populates slice header structure
1386 *
1387 * @par   Description
1388 *  Populates slice header structure for its use in header generation
1389 *
1390 * @param[in]  ps_proc
1391 *  pointer to proc context
1392 *
1393 * @param[out]  ps_slice_hdr
1394 *  pointer to slice header structure that needs to be populated
1395 *
1396 * @param[in]  ps_pps
1397 *  pointer to pps params structure referred by the slice
1398 *
1399 * @param[in]   ps_sps
1400 *  pointer to sps params referred by the pps
1401 *
1402 * @return      success or failure error code
1403 *
1404 ******************************************************************************
1405 */
ih264e_populate_slice_header(process_ctxt_t * ps_proc,slice_header_t * ps_slice_hdr,pps_t * ps_pps,sps_t * ps_sps)1406 WORD32 ih264e_populate_slice_header(process_ctxt_t *ps_proc,
1407                                     slice_header_t *ps_slice_hdr,
1408                                     pps_t *ps_pps,
1409                                     sps_t *ps_sps)
1410 {
1411     /* entropy context */
1412     entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
1413 
1414     codec_t *ps_codec = ps_proc->ps_codec;
1415 
1416     if (ps_proc->ps_codec->u4_is_curr_frm_ref)
1417     {
1418         ps_slice_hdr->i1_nal_unit_idc = 3;
1419     }
1420     else
1421     {
1422         ps_slice_hdr->i1_nal_unit_idc = 0;
1423     }
1424 
1425     /* start mb address */
1426     ps_slice_hdr->u2_first_mb_in_slice = ps_entropy->i4_mb_start_add;
1427 
1428     /* slice type */
1429     ps_slice_hdr->u1_slice_type = ps_proc->i4_slice_type;
1430 
1431     /* pic_parameter_set_id */
1432     ps_slice_hdr->u1_pps_id = ps_pps->u1_pps_id;
1433 
1434     /* Separate color plane flag is 0,
1435      * hence the syntax element color_plane_id not included */
1436 
1437     /* frame num */
1438     ps_slice_hdr->i4_frame_num = ps_proc->i4_frame_num;
1439 
1440     /* frame_mbs_only_flag, no support for interlace encoding */
1441     if (!ps_sps->i1_frame_mbs_only_flag)
1442     {
1443         ps_slice_hdr->i1_field_pic_flag = 0;
1444 
1445         if (ps_slice_hdr->i1_field_pic_flag)
1446         {
1447             ps_slice_hdr->i1_bottom_field_flag = 0;
1448         }
1449     }
1450 
1451     /* idr pic id */
1452     if (ps_proc->u4_is_idr)
1453     {
1454         ps_slice_hdr->u2_idr_pic_id = ps_proc->u4_idr_pic_id;
1455         ps_slice_hdr->i1_nal_unit_type = 5;
1456     }
1457     else
1458     {
1459         ps_slice_hdr->i1_nal_unit_type = 1;
1460     }
1461 
1462     if (ps_sps->i1_pic_order_cnt_type == 0)
1463     {
1464 
1465         WORD32 i4_poc;
1466         i4_poc = ps_codec->i4_poc;
1467         i4_poc %= (1 << ps_sps->i1_log2_max_pic_order_cnt_lsb);
1468         ps_slice_hdr->i4_pic_order_cnt_lsb = i4_poc;
1469     }
1470     /* TODO add support for poc type 1 */
1471     else if (ps_sps->i1_pic_order_cnt_type == 1)
1472     {
1473 
1474     }
1475 
1476 
1477     /*
1478      * redundant slices are not currently supported.
1479      * Hence the syntax element redundant slice cnt is not initialized
1480      */
1481     if (ps_pps->i1_redundant_pic_cnt_present_flag)
1482     {
1483 
1484     }
1485 
1486     /* direct spatial mv pred flag */
1487     if (ps_proc->i4_slice_type == BSLICE)
1488     {
1489         ps_slice_hdr->u1_direct_spatial_mv_pred_flag = 1;
1490     }
1491 
1492     if (ps_proc->i4_slice_type == PSLICE || ps_proc->i4_slice_type == SPSLICE || ps_proc->i4_slice_type == BSLICE)
1493     {
1494         /* num_ref_idx_active_override_flag */
1495         ps_slice_hdr->u1_num_ref_idx_active_override_flag = 0;
1496 
1497         if (ps_slice_hdr->u1_num_ref_idx_active_override_flag)
1498         {
1499             /* num_ref_idx_l0_active_minus1 */
1500 
1501             if (ps_proc->i4_slice_type == BSLICE)
1502             {
1503                 /* num_ref_idx_l1_active_minus1 */
1504 
1505             }
1506         }
1507     }
1508 
1509     /* ref_idx_reordering */
1510     /* TODO: ref_idx_reordering */
1511     if ((ps_proc->i4_slice_type != ISLICE) && (ps_proc->i4_slice_type != SISLICE))
1512     {
1513         /* ref_pic_list_reordering_flag_l0 */
1514         ps_slice_hdr->u1_ref_idx_reordering_flag_l0 = 0;
1515 
1516         if (ps_slice_hdr->u1_ref_idx_reordering_flag_l0)
1517         {
1518 
1519         }
1520 
1521         /* ref_pic_list_reordering_flag_l1 */
1522         ps_slice_hdr->u1_ref_idx_reordering_flag_l1 = 0;
1523 
1524         if (ps_slice_hdr->u1_ref_idx_reordering_flag_l1)
1525         {
1526 
1527         }
1528     }
1529 
1530 
1531     /* Currently we do not support weighted pred */
1532     /* ps_slice_hdr->u1_weighted_bipred_idc = 0; */
1533 
1534     if ((ps_pps->i1_weighted_pred_flag &&
1535                     (ps_proc->i4_slice_type == PSLICE || ps_proc->i4_slice_type == SPSLICE)) ||
1536                     (ps_proc->i4_slice_type == BSLICE && ps_pps->i1_weighted_bipred_idc == 1))
1537     {
1538         /* TODO_LATER: Currently there is no support for weighted prediction.
1539              This needs to be updated when the support is added */
1540     }
1541 
1542     if (ps_slice_hdr->i1_nal_unit_idc != 0)
1543     {
1544         if (ps_slice_hdr->i1_nal_unit_type == 5)
1545         {
1546             /* no_output_of_prior_pics_flag  */
1547             ps_slice_hdr->u1_no_output_of_prior_pics_flag = 0;
1548 
1549             /* long_term_reference_flag  */
1550             ps_slice_hdr->u1_long_term_reference_flag = 0;
1551         }
1552         else
1553         {
1554             /* adaptive_ref_pic_marking_mode_flag  */
1555             ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag = 0;
1556 
1557             if (ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag)
1558             {
1559                 /* TODO: if the reference picture marking mode is adaptive
1560                      add these fields in the bit-stream */
1561             }
1562         }
1563     }
1564 
1565     /* entropy coding mode flag */
1566     ps_slice_hdr->u1_entropy_coding_mode_flag = ps_entropy->u1_entropy_coding_mode_flag;
1567 
1568     if (ps_slice_hdr->u1_entropy_coding_mode_flag && ps_proc->i4_slice_type != ISLICE &&
1569                     ps_proc->i4_slice_type != SISLICE)
1570     {
1571         /* cabac_init_idc */
1572     }
1573 
1574     /* slice qp */
1575     ps_slice_hdr->i1_slice_qp = ps_proc->u4_frame_qp;
1576 
1577     if (ps_proc->i4_slice_type == SPSLICE || ps_proc->i4_slice_type == SISLICE)
1578     {
1579         if (ps_proc->i4_slice_type == SPSLICE)
1580         {
1581             /* sp_for_switch_flag */
1582         }
1583         /* slice_qs_delta */
1584     }
1585 
1586     if (ps_pps->i1_deblocking_filter_control_present_flag)
1587     {
1588         /* disable_deblocking_filter_idc */
1589         ps_slice_hdr->u1_disable_deblocking_filter_idc = ps_proc->u4_disable_deblock_level;
1590 
1591         if (ps_slice_hdr->u1_disable_deblocking_filter_idc != 1)
1592         {
1593             /* slice_alpha_c0_offset_div2 */
1594             ps_slice_hdr->i1_slice_alpha_c0_offset_div2 = 0;
1595 
1596             /* slice_beta_offset_div2 */
1597             ps_slice_hdr->i1_slice_beta_offset_div2 = 0;
1598         }
1599     }
1600     ps_slice_hdr->u1_num_slice_groups_minus1 = 0;
1601     if(ps_slice_hdr->u1_num_slice_groups_minus1 > 0 &&
1602         ps_pps->u1_slice_group_map_type >= 3 &&
1603         ps_pps->u1_slice_group_map_type <= 5)
1604     {
1605         /* slice_group_change_cycle */
1606         /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
1607          * If this is not the case, we have to add Slice group map type to the bit stream */
1608     }
1609 
1610     ps_slice_hdr->i1_cabac_init_idc = CABAC_INIT_IDC;
1611 
1612     return IH264E_SUCCESS;
1613 }
1614 
1615 /**
1616 ******************************************************************************
1617 *
1618 * @brief inserts FILLER Nal Unit.
1619 *
1620 * @par   Description
1621 *  In constant bit rate rc mode, when the bits generated by the codec is
1622 *  underflowing the target bit rate, the encoder library inserts filler nal unit.
1623 *
1624 * @param[in]    ps_bitstrm
1625 *  pointer to bitstream context (handle)
1626 *
1627 * @param[in]    insert_fill_bytes
1628 *  Number of fill bytes to be inserted
1629 *
1630 * @return      success or failure error code
1631 *
1632 ******************************************************************************
1633 */
ih264e_add_filler_nal_unit(bitstrm_t * ps_bitstrm,WORD32 insert_fill_bytes)1634 IH264E_ERROR_T ih264e_add_filler_nal_unit(bitstrm_t *ps_bitstrm,
1635                                           WORD32 insert_fill_bytes)
1636 {
1637     WORD32  i4_num_words_to_fill, i4_words_filled;
1638 
1639     IH264E_ERROR_T return_status = IH264E_SUCCESS;
1640 
1641     /* Insert the NAL start code */
1642     return_status = ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
1643     if(return_status != IH264E_SUCCESS)
1644     {
1645         return return_status;
1646     }
1647 
1648     if (ps_bitstrm->u4_strm_buf_offset + insert_fill_bytes >= ps_bitstrm->u4_max_strm_size)
1649     {
1650         return (IH264E_BITSTREAM_BUFFER_OVERFLOW);
1651     }
1652 
1653     /* Insert Nal Unit Header */
1654     PUT_BITS(ps_bitstrm, NAL_FILLER_FIRST_BYTE, 8, return_status, "filler_header");
1655 
1656     PUT_BITS(ps_bitstrm, 0xFFFFFF, 24, return_status, "fill bytes");
1657 
1658     /* Initializing Variables                           */
1659     i4_words_filled    = 1;
1660 
1661     /****************************************************/
1662     /* Flooring the number of bytes for be stuffed to   */
1663     /* WORD unit                                        */
1664     /****************************************************/
1665     i4_num_words_to_fill = (insert_fill_bytes >> 2);
1666 
1667     /****************************************************/
1668     /* Reducing already 4 bytes filled. In case stuffing*/
1669     /* is <= 4 bytes, we are actually not stuffing      */
1670     /* anything                                         */
1671     /****************************************************/
1672     i4_num_words_to_fill -= i4_words_filled;
1673 
1674     while (i4_num_words_to_fill > 0)
1675     {
1676         /* Insert Nal Unit Header */
1677         PUT_BITS(ps_bitstrm, 0xFFFFFFFF, 32, return_status, "fill bytes");
1678 
1679         i4_num_words_to_fill-- ;
1680     }
1681 
1682     return_status = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
1683 
1684     return return_status;
1685 }
1686 
1687