summaryrefslogtreecommitdiffstats
path: root/encoder/ih264e_encode_header.c
diff options
context:
space:
mode:
authorHamsalekha S <hamsalekha.s@ittiam.com>2015-03-13 21:24:58 +0530
committerHamsalekha S <hamsalekha.s@ittiam.com>2015-04-02 15:59:02 +0530
commit8d3d303c7942ced6a987a52db8977d768dc3605f (patch)
treecc806c96794356996b13ba9970941d0aed74a97e /encoder/ih264e_encode_header.c
parent3956d913d37327dcb340f836e604b04bd478b158 (diff)
downloadandroid_external_libavc-8d3d303c7942ced6a987a52db8977d768dc3605f.tar.gz
android_external_libavc-8d3d303c7942ced6a987a52db8977d768dc3605f.tar.bz2
android_external_libavc-8d3d303c7942ced6a987a52db8977d768dc3605f.zip
Initial version
Change-Id: I7efe9a589cd24edf86e8d086b40c27cbbf8b4017
Diffstat (limited to 'encoder/ih264e_encode_header.c')
-rwxr-xr-xencoder/ih264e_encode_header.c1187
1 files changed, 1187 insertions, 0 deletions
diff --git a/encoder/ih264e_encode_header.c b/encoder/ih264e_encode_header.c
new file mode 100755
index 0000000..67e5409
--- /dev/null
+++ b/encoder/ih264e_encode_header.c
@@ -0,0 +1,1187 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+*/
+
+/**
+*******************************************************************************
+* @file
+* ih264e_encode_header.c
+*
+* @brief
+* This file contains function definitions related to header encoding.
+*
+* @author
+* ittiam
+*
+* @par List of Functions:
+* - ih264e_generate_nal_unit_header()
+* - ih264e_generate_sps()
+* - ih264e_generate_pps()
+* - ih264e_generate_slice_header()
+* - ih264e_get_level()
+* - ih264e_populate_sps()
+* - ih264e_populate_pps()
+* - ih264e_populate_slice_header()
+* - ih264e_add_filler_nal_unit()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+/* User Include Files */
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "ih264e.h"
+#include "ithread.h"
+#include "ih264e_config.h"
+#include "ih264e_trace.h"
+#include "ih264_typedefs.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ih264_debug.h"
+#include "ih264_defs.h"
+#include "ime_distortion_metrics.h"
+#include "ime_structs.h"
+#include "ih264_defs.h"
+#include "ih264_error.h"
+#include "ih264_structs.h"
+#include "ih264_trans_quant_itrans_iquant.h"
+#include "ih264_inter_pred_filters.h"
+#include "ih264_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "ih264e_defs.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "ih264e_rate_control.h"
+#include "ih264e_structs.h"
+#include "ih264e_encode_header.h"
+#include "ih264_common_tables.h"
+#include "ih264_macros.h"
+
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+******************************************************************************
+*
+* @brief Generate nal unit header in the stream as per section 7.4.1
+*
+* @par Description
+* Inserts Nal unit header syntax as per section 7.4.1
+*
+* @param[inout] ps_bitstrm
+* pointer to bitstream context (handle)
+*
+* @param[in] nal_unit_type
+* nal type to be inserted
+*
+* @param[in] nal_ref_idc
+* nal ref idc to be inserted
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+static WORD32 ih264e_generate_nal_unit_header(bitstrm_t *ps_bitstrm,
+ WORD32 nal_unit_type,
+ WORD32 nal_ref_idc)
+{
+ WORD32 return_status = IH264E_SUCCESS;
+
+ /* sanity checks */
+ ASSERT((nal_unit_type > 0) && (nal_unit_type < 32));
+
+ /* forbidden_zero_bit + nal_ref_idc + nal_unit_type */
+ PUT_BITS(ps_bitstrm,
+ ((nal_ref_idc << 5) + nal_unit_type),
+ (1+2+5), /*1 forbidden zero bit + 2 nal_ref_idc + 5 nal_unit_type */
+ return_status,
+ "nal_unit_header");
+
+ return(return_status);
+}
+
+/**
+******************************************************************************
+*
+* @brief Generates SPS (Sequence Parameter Set)
+*
+* @par Description
+* This function generates Sequence Parameter Set header as per the spec
+*
+* @param[in] ps_bitstrm
+* pointer to bitstream context (handle)
+*
+* @param[in] ps_sps
+* pointer to structure containing SPS data
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 ih264e_generate_sps(bitstrm_t *ps_bitstrm, sps_t *ps_sps)
+{
+ WORD32 return_status = IH264E_SUCCESS;
+ WORD32 i;
+ WORD8 i1_nal_unit_type = 7;
+ WORD8 i1_nal_ref_idc = 3;
+
+ /* Insert Start Code */
+ return_status |= ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
+
+ /* Insert Nal Unit Header */
+ return_status |= ih264e_generate_nal_unit_header(ps_bitstrm, i1_nal_unit_type, i1_nal_ref_idc);
+
+ /* profile_idc */
+ PUT_BITS(ps_bitstrm, ps_sps->u1_profile_idc, 8, return_status, "profile_idc");
+
+ /* constrained_set_flags */
+ PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set0_flag, 1, return_status, "constrained_set0_flag");
+ PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set1_flag, 1, return_status, "constrained_set1_flag");
+ PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set2_flag, 1, return_status, "constrained_set2_flag");
+ PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set3_flag, 1, return_status, "constrained_set3_flag");
+
+ /* reserved_zero_four_bits */
+ PUT_BITS(ps_bitstrm, 0, 4, return_status, "reserved_zero_four_bits");
+
+ /* level_idc */
+ PUT_BITS(ps_bitstrm, ps_sps->u1_level_idc, 8, return_status, "level_idc");
+
+ /* seq_parameter_set_id */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_sps_id, return_status, "seq_parameter_set_id");
+
+ if (ps_sps->u1_profile_idc >= IH264_PROFILE_HIGH)
+ {
+ /* chroma_format_idc */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_chroma_format_idc, return_status, "chroma_format_idc");
+
+ if (ps_sps->u1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
+ {
+ /* i1_residual_colour_transform_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_residual_colour_transform_flag, 1, return_status, "i1_residual_colour_transform_flag");
+ }
+
+ /* bit_depth_luma_minus8 */
+ PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_bit_depth_luma - 8), return_status, "bit_depth_luma_minus8");
+
+ /* bit_depth_chroma_minus8 */
+ PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_bit_depth_chroma - 8), return_status, "bit_depth_chroma_minus8");
+
+ /* qpprime_y_zero_transform_bypass_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_qpprime_y_zero_transform_bypass_flag, 1, return_status, "qpprime_y_zero_transform_bypass_flag");
+
+ /* seq_scaling_matrix_present_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_seq_scaling_matrix_present_flag, 1, return_status, "seq_scaling_matrix_present_flag");
+
+ /* seq_scaling_list */
+ if (ps_sps->i1_seq_scaling_matrix_present_flag)
+ {
+ /* TODO_LATER: Will be enabled once scaling list support is added */
+ }
+ }
+
+ /* log2_max_frame_num_minus4 */
+ PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_log2_max_frame_num - 4), return_status, "log2_max_frame_num_minus4");
+
+ /* pic_order_cnt_type */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->i1_pic_order_cnt_type, return_status, "pic_order_cnt_type");
+
+ if (ps_sps->i1_pic_order_cnt_type == 0)
+ {
+ /* log2_max_pic_order_cnt_lsb_minus4 */
+ PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_log2_max_pic_order_cnt_lsb - 4), return_status, "log2_max_pic_order_cnt_lsb_minus4");
+ }
+ else if (ps_sps->i1_pic_order_cnt_type == 1)
+ {
+ /* delta_pic_order_always_zero_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_delta_pic_order_always_zero_flag, 1, return_status, "delta_pic_order_always_zero_flag");
+
+ /* offset_for_non_ref_pic */
+ PUT_BITS_SEV(ps_bitstrm, ps_sps->i4_offset_for_non_ref_pic, return_status, "offset_for_non_ref_pic");
+
+ /* offset_for_top_to_bottom_field */
+ PUT_BITS_SEV(ps_bitstrm, ps_sps->i4_offset_for_top_to_bottom_field, return_status, "offset_for_top_to_bottom_field");
+
+ /* num_ref_frames_in_pic_order_cnt_cycle */
+ 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");
+
+ /* Offset for ref frame */
+ for (i=0; i<ps_sps->u1_num_ref_frames_in_pic_order_cnt_cycle; i++)
+ {
+ /* offset_for_ref_frame */
+ PUT_BITS_SEV(ps_bitstrm, ps_sps->ai4_offset_for_ref_frame[i], return_status, "offset_for_ref_frame");
+ }
+ }
+
+ /* num_ref_frames */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_max_num_ref_frames, return_status, "num_ref_frames");
+
+ /* gaps_in_frame_num_value_allowed_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_gaps_in_frame_num_value_allowed_flag, 1, return_status, "gaps_in_frame_num_value_allowed_flag");
+
+ /* pic_width_in_mbs_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_pic_width_in_mbs_minus1, return_status, "pic_width_in_mbs_minus1");
+
+ /* pic_height_in_map_units_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_pic_height_in_map_units_minus1, return_status, "pic_height_in_map_units_minus1");
+
+ /* frame_mbs_only_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_frame_mbs_only_flag, 1, return_status, "frame_mbs_only_flag");
+
+ if (!ps_sps->i1_frame_mbs_only_flag)
+ {
+ /* mb_adaptive_frame_field_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_mb_adaptive_frame_field_flag, 1, return_status, "mb_adaptive_frame_field_flag");
+ }
+
+ /* direct_8x8_inference_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_direct_8x8_inference_flag, 1, return_status, "direct_8x8_inference_flag");
+
+ /* frame_cropping_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_frame_cropping_flag, 1, return_status, "frame_cropping_flag");
+
+ if (ps_sps->i1_frame_cropping_flag)
+ {
+ /* frame_crop_left_offset */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_left_offset, return_status, "frame_crop_left_offset");
+
+ /* frame_crop_right_offset */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_right_offset, return_status, "frame_crop_right_offset");
+
+ /* frame_crop_top_offset */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_top_offset, return_status, "frame_crop_top_offset");
+
+ /* frame_crop_bottom_offset */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_bottom_offset, return_status, "frame_crop_bottom_offset");
+ }
+
+ /* vui_parameters_present_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_vui_parameters_present_flag, 1, return_status, "vui_parameters_present_flag");
+
+ if (ps_sps->i1_vui_parameters_present_flag)
+ {
+ /* Add vui parameters to the bitstream */;
+ }
+
+ /* rbsp trailing bits */
+ return_status |= ih264e_put_rbsp_trailing_bits(ps_bitstrm);
+
+ return return_status;
+}
+
+/**
+******************************************************************************
+*
+* @brief Generates PPS (Picture Parameter Set)
+*
+* @par Description
+* Generate Picture Parameter Set as per Section 7.3.2.2
+*
+* @param[in] ps_bitstrm
+* pointer to bitstream context (handle)
+*
+* @param[in] ps_pps
+* pointer to structure containing PPS data
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 ih264e_generate_pps(bitstrm_t *ps_bitstrm, pps_t *ps_pps, sps_t *ps_sps)
+{
+ WORD32 return_status = IH264E_SUCCESS;
+
+ /* Insert the NAL start code */
+ return_status |= ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
+
+ /* Insert Nal Unit Header */
+ PUT_BITS(ps_bitstrm, NAL_PPS_FIRST_BYTE, 8, return_status, "pps_header");
+
+ /* pic_parameter_set_id */
+ PUT_BITS_UEV(ps_bitstrm, ps_pps->u1_pps_id, return_status, "pic_parameter_set_id");
+
+ /* seq_parameter_set_id */
+ PUT_BITS_UEV(ps_bitstrm, ps_pps->u1_sps_id, return_status, "seq_parameter_set_id");
+
+ /* Entropy coding : 0-VLC; 1 - CABAC */
+ PUT_BITS(ps_bitstrm, ps_pps->u1_entropy_coding_mode_flag, 1, return_status, "Entropy coding : 0-VLC; 1 - CABAC");
+
+ /* Pic order present flag */
+ PUT_BITS(ps_bitstrm, ps_pps->u1_pic_order_present_flag, 1, return_status, "Pic order present flag");
+
+ /* Number of slice groups */
+ PUT_BITS_UEV(ps_bitstrm, ps_pps->u1_num_slice_groups - 1, return_status, "Number of slice groups");
+
+ if (ps_pps->u1_num_slice_groups > 1)
+ {
+ /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
+ * If this is not the case, we have to add Slice group map type to the bit stream*/
+ }
+
+ /* num_ref_idx_l0_default_active_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, ps_pps->i1_num_ref_idx_l0_default_active - 1, return_status, "num_ref_idx_l0_default_active_minus1");
+
+ /* num_ref_idx_l1_default_active_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, ps_pps->i1_num_ref_idx_l1_default_active - 1, return_status, "num_ref_idx_l1_default_active_minus1");
+
+ /* weighted_pred_flag */
+ PUT_BITS(ps_bitstrm, ps_pps->i1_weighted_pred_flag, 1, return_status, "weighted_pred_flag");
+
+ /* weighted_bipred_flag */
+ PUT_BITS(ps_bitstrm, ps_pps->i1_weighted_bipred_idc, 2, return_status, "weighted_bipred_idc");
+
+ /* pic_init_qp_minus26 */
+ PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_pic_init_qp - 26, return_status, "pic_init_qp_minus26");
+
+ /* pic_init_qs_minus26 */
+ PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_pic_init_qs - 26, return_status, "pic_init_qs_minus26");
+
+ /* chroma_qp_index_offset */
+ PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_chroma_qp_index_offset, return_status, "chroma_qp_index_offset");
+
+ /* deblocking_filter_control_present_flag */
+ PUT_BITS(ps_bitstrm, ps_pps->i1_deblocking_filter_control_present_flag, 1, return_status, "deblocking_filter_control_present_flag");
+
+ /* constrained_intra_pred_flag */
+ PUT_BITS(ps_bitstrm, ps_pps->i1_constrained_intra_pred_flag, 1, return_status, "constrained_intra_pred_flag");
+
+ /*redundant_pic_cnt_present_flag */
+ PUT_BITS(ps_bitstrm, ps_pps->i1_redundant_pic_cnt_present_flag, 1, return_status, "redundant_pic_cnt_present_flag");
+
+ if (ps_sps->u1_profile_idc >= IH264_PROFILE_HIGH)
+ {
+ /* transform_8x8_mode_flag */
+ PUT_BITS(ps_bitstrm, ps_pps->i1_transform_8x8_mode_flag, 1, return_status, "transform_8x8_mode_flag");
+
+ /* pic_scaling_matrix_present_flag */
+ PUT_BITS(ps_bitstrm, ps_pps->i1_pic_scaling_matrix_present_flag, 1, return_status, "pic_scaling_matrix_present_flag");
+
+ if(ps_pps->i1_pic_scaling_matrix_present_flag)
+ {
+ /* TODO_LATER: Will be enabled once scaling list support is added */
+ }
+
+ /* Second chroma QP offset */
+ PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_second_chroma_qp_index_offset, return_status, "Second chroma QP offset");
+ }
+
+ return_status |= ih264e_put_rbsp_trailing_bits(ps_bitstrm);
+
+ return return_status;
+}
+
+/**
+******************************************************************************
+*
+* @brief Generates Slice Header
+*
+* @par Description
+* Generate Slice Header as per Section 7.3.5.1
+*
+* @param[inout] ps_bitstrm
+* pointer to bitstream context for generating slice header
+*
+* @param[in] ps_slice_hdr
+* pointer to slice header params
+*
+* @param[in] ps_pps
+* pointer to pps params referred by slice
+*
+* @param[in] ps_sps
+* pointer to sps params referred by slice
+*
+* @param[out] ps_dup_bit_strm_ent_offset
+* Bitstream struct to store bitstream state
+*
+* @param[out] pu4_first_slice_start_offset
+* first slice offset is returned
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 ih264e_generate_slice_header(bitstrm_t *ps_bitstrm,
+ slice_header_t *ps_slice_hdr,
+ pps_t *ps_pps,
+ sps_t *ps_sps)
+{
+
+ WORD32 return_status = IH264E_SUCCESS;
+
+ /* Insert start code */
+ return_status |= ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
+
+ /* Insert Nal Unit Header */
+ return_status |= ih264e_generate_nal_unit_header(ps_bitstrm, ps_slice_hdr->i1_nal_unit_type, ps_slice_hdr->i1_nal_unit_idc);
+
+ /* first_mb_in_slice */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u2_first_mb_in_slice, return_status, "first_mb_in_slice");
+
+ /* slice_type */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_slice_type, return_status, "slice_type");
+
+ /* pic_parameter_set_id */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_pps_id, return_status, "pic_parameter_set_id");
+
+ /* frame_num */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->i4_frame_num, ps_sps->i1_log2_max_frame_num, return_status, "frame_num");
+
+ if (!ps_sps->i1_frame_mbs_only_flag)
+ {
+ /* field_pic_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->i1_field_pic_flag, 1, return_status, "field_pic_flag");
+
+ if(ps_slice_hdr->i1_field_pic_flag)
+ {
+ /* bottom_field_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->i1_bottom_field_flag, 1, return_status, "bottom_field_flag");
+ }
+ }
+
+ if (ps_slice_hdr->i1_nal_unit_type == 5)
+ {
+ /* u2_idr_pic_id */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u2_idr_pic_id, return_status, "u2_idr_pic_id");
+ }
+
+ if (ps_sps->i1_pic_order_cnt_type == 0)
+ {
+ /* pic_order_cnt_lsb */
+ 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");
+
+ if(ps_pps->u1_pic_order_present_flag && !ps_slice_hdr->i1_field_pic_flag)
+ {
+ /* delta_pic_order_cnt_bottom */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i4_delta_pic_order_cnt_bottom, return_status, "delta_pic_order_cnt_bottom");
+ }
+ }
+
+ if (ps_sps->i1_pic_order_cnt_type == 1 && !ps_sps->i1_delta_pic_order_always_zero_flag)
+ {
+ /* delta_pic_order_cnt[0] */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->ai4_delta_pic_order_cnt[0], return_status, "delta_pic_order_cnt[0]");
+
+ if (ps_pps->u1_pic_order_present_flag && !ps_slice_hdr->i1_field_pic_flag)
+ {
+ /* delta_pic_order_cnt[1] */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->ai4_delta_pic_order_cnt[1], return_status, "delta_pic_order_cnt[1]");
+ }
+ }
+
+ if (ps_pps->i1_redundant_pic_cnt_present_flag)
+ {
+ /* redundant_pic_cnt */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_redundant_pic_cnt, return_status, "redundant_pic_cnt");
+ }
+
+ if (ps_slice_hdr->u1_slice_type == BSLICE)
+ {
+ /* direct_spatial_mv_pred_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_direct_spatial_mv_pred_flag, 1, return_status, "direct_spatial_mv_pred_flag");
+ }
+
+ if (ps_slice_hdr->u1_slice_type == PSLICE || ps_slice_hdr->u1_slice_type == SPSLICE || ps_slice_hdr->u1_slice_type == BSLICE)
+ {
+ /* num_ref_idx_active_override_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_num_ref_idx_active_override_flag, 1, return_status, "num_ref_idx_active_override_flag");
+
+ if (ps_slice_hdr->u1_num_ref_idx_active_override_flag)
+ {
+ /* num_ref_idx_l0_active_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_num_ref_idx_l0_active - 1, return_status, "num_ref_idx_l0_active_minus1");
+ }
+ if (ps_slice_hdr->u1_slice_type == BSLICE)
+ {
+ /* num_ref_idx_l1_active_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_num_ref_idx_l1_active - 1, return_status, "num_ref_idx_l1_active_minus1");
+ }
+ }
+
+ /* ref_idx_reordering */
+ /* TODO: ref_idx_reordering */
+ if ((ps_slice_hdr->u1_slice_type != ISLICE) && (ps_slice_hdr->u1_slice_type != SISLICE))
+ {
+ /* ref_pic_list_reordering_flag_l0 */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_ref_idx_reordering_flag_l0, 1, return_status, "ref_pic_list_reordering_flag_l0");
+
+ if (ps_slice_hdr->u1_ref_idx_reordering_flag_l0)
+ {
+
+ }
+ }
+
+ if ((ps_pps->i1_weighted_pred_flag &&
+ (ps_slice_hdr->u1_slice_type == PSLICE || ps_slice_hdr->u1_slice_type == SPSLICE)) ||
+ (ps_slice_hdr->u1_weighted_bipred_idc == 1 && ps_slice_hdr->u1_slice_type == BSLICE))
+ {
+ /* TODO_LATER: Currently there is no support for weighted prediction.
+ This needs to be updated when the support is added */
+ }
+
+ if (ps_slice_hdr->i1_nal_unit_idc != 0)
+ {
+ if (ps_slice_hdr->i1_nal_unit_type == 5)
+ {
+ /* no_output_of_prior_pics_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_no_output_of_prior_pics_flag , 1, return_status, "no_output_of_prior_pics_flag ");
+
+ /* long_term_reference_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_long_term_reference_flag , 1, return_status, "long_term_reference_flag ");
+ }
+ else
+ {
+ /* adaptive_ref_pic_marking_mode_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag , 1, return_status, "adaptive_ref_pic_marking_mode_flag ");
+
+ if (ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag)
+ {
+ /* TODO: if the reference picture marking mode is adaptive
+ add these fields in the bit-stream */
+ }
+ }
+ }
+
+ if (ps_slice_hdr->u1_entropy_coding_mode_flag && ps_slice_hdr->u1_slice_type != ISLICE &&
+ ps_slice_hdr->u1_slice_type != SISLICE)
+ {
+ /* cabac_init_idc */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_cabac_init_idc, return_status, "cabac_init_idc");
+ }
+
+ /* slice_qp_delta */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_qp - ps_pps->i1_pic_init_qp, return_status, "slice_qp_delta");
+
+ if (ps_slice_hdr->u1_slice_type == SPSLICE || ps_slice_hdr->u1_slice_type == SISLICE)
+ {
+ if (ps_slice_hdr->u1_slice_type == SPSLICE)
+ {
+ /* sp_for_switch_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_sp_for_switch_flag , 1, return_status, "sp_for_switch_flag");
+ }
+ /* slice_qs_delta */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->u1_slice_qs - ps_pps->i1_pic_init_qs, return_status, "slice_qs_delta");
+ }
+
+ if (ps_pps->i1_deblocking_filter_control_present_flag)
+ {
+ /* disable_deblocking_filter_idc */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_disable_deblocking_filter_idc, return_status, "disable_deblocking_filter_idc");
+
+ if(ps_slice_hdr->u1_disable_deblocking_filter_idc != 1)
+ {
+ /* slice_alpha_c0_offset_div2 */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_alpha_c0_offset_div2, return_status, "slice_alpha_c0_offset_div2");
+
+ /* slice_beta_offset_div2 */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_beta_offset_div2, return_status, "slice_beta_offset_div2");
+ }
+ }
+
+ if (ps_slice_hdr->u1_num_slice_groups_minus1 > 0 &&
+ ps_pps->u1_slice_group_map_type >= 3 &&
+ ps_pps->u1_slice_group_map_type <= 5)
+ {
+ /* slice_group_change_cycle */
+ /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
+ * If this is not the case, we have to add Slice group map type to the bit stream */
+ }
+
+ return return_status;
+}
+
+
+
+/**
+******************************************************************************
+*
+* @brief Populates sps structure
+*
+* @par Description
+* Populates sps structure for its use in header generation
+*
+* @param[in] ps_codec
+* pointer to encoder context
+*
+* @param[out] ps_sps
+* pointer to sps params that needs to be populated
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+IH264E_ERROR_T ih264e_populate_sps(codec_t *ps_codec, sps_t *ps_sps)
+{
+ /* active config parameters */
+ cfg_params_t *ps_cfg = &(ps_codec->s_cfg);
+
+// /* level */
+// IH264_LEVEL_T level_idc;
+
+ /* error_status */
+ IH264E_ERROR_T i4_err_code = IH264E_FAIL;
+
+ /* profile */
+ /*
+ * Baseline profile supports, 8 bits per sample, 4:2:0 format, CAVLC.
+ * B frames are not allowed. Further, Flexible mb ordering, Redundant slices, Arbitrary slice ordering are supported.
+ * The constrained baseline profile is baseline profile minus ASO, FMO and redundant slices.
+ * To the constrained baseline profile if we add support for B slices, support for encoding interlaced frames,
+ * support for weighted prediction and introduce CABAC entropy coding then we have Main Profile.
+ */
+ if ((ps_cfg->u4_num_b_frames) || (ps_cfg->e_content_type != IV_PROGRESSIVE) ||
+ (ps_cfg->u4_entropy_coding_mode == CABAC) || (ps_cfg->u4_weighted_prediction))
+ {
+ ps_sps->u1_profile_idc = IH264_PROFILE_MAIN;
+ }
+ else
+ {
+ ps_sps->u1_profile_idc = IH264_PROFILE_BASELINE;
+ }
+
+ /* level */
+ ps_sps->u1_level_idc = ps_cfg->u4_max_level;
+// i4_err_code = ih264e_get_level(ps_cfg, &level_idc);
+// if (i4_err_code == IH264E_SUCCESS)
+// {
+// ps_sps->u1_level_idc = level_idc;
+//
+// }
+// else
+// {
+// return i4_err_code;
+// }
+
+ /* constrained flags */
+ /*
+ * baseline profile automatically implies set 0 flag
+ */
+ ps_sps->u1_constraint_set0_flag = (ps_sps->u1_profile_idc == IH264_PROFILE_BASELINE);
+ /*
+ * main profile automatically implies set 1 flag
+ * Although the encoder says it supports Baseline profile it actually supports constrained
+ * baseline profile as ASO, FMO and redundant slices are not supported
+ */
+ ps_sps->u1_constraint_set1_flag = (ps_sps->u1_profile_idc <= IH264_PROFILE_MAIN);
+ /*
+ * extended profile is not supported
+ */
+ ps_sps->u1_constraint_set2_flag = 0x00;
+ /*
+ * level 1b or level 11
+ */
+ if (ps_sps->u1_level_idc == IH264_LEVEL_1B)
+ {
+ ps_sps->u1_constraint_set3_flag = 0;
+ ps_sps->u1_level_idc = IH264_LEVEL_11;
+ }
+ else
+ {
+ ps_sps->u1_constraint_set3_flag = 0;
+ }
+
+ /* active sps id */
+ ps_sps->u1_sps_id = ps_codec->i4_sps_id;
+
+ if (ps_sps->u1_profile_idc >= IH264_PROFILE_HIGH)
+ {
+ /* chroma format idc */
+ ps_sps->u1_chroma_format_idc = CHROMA_FMT_IDC_YUV420;
+
+ /* residual_colour_transform_flag */
+ ps_sps->i1_residual_colour_transform_flag = 0;
+
+ /* luma bit depth 8 */
+ ps_sps->i1_bit_depth_luma = 8;
+
+ /* chroma bit depth 8 */
+ ps_sps->i1_bit_depth_chroma = 8;
+
+ /* qpprime_y_zero_transform_bypass_flag */
+ ps_sps->i1_qpprime_y_zero_transform_bypass_flag = 0;
+
+ /* seq_scaling_matrix_present_flag */
+ ps_sps->i1_seq_scaling_matrix_present_flag = 0;
+
+ if (ps_sps->i1_seq_scaling_matrix_present_flag)
+ {
+ /* TODO_LATER: Will be enabled once scaling list support is added */
+ }
+ }
+
+ /* log2_max_frame_num_minus4 */
+ ps_sps->i1_log2_max_frame_num = 16;
+
+ /* pic_order_cnt_type */
+ ps_sps->i1_pic_order_cnt_type = 2;
+
+ if(ps_cfg->u4_enable_alt_ref)
+ ps_sps->i1_pic_order_cnt_type = 0;
+
+ /* log2_max_pic_order_cnt_lsb_minus4 */
+ ps_sps->i1_log2_max_pic_order_cnt_lsb = 8;
+
+ /* TODO : add support for other poc types */
+ if (ps_sps->i1_pic_order_cnt_type == 0)
+ {
+
+ }
+ else if (ps_sps->i1_pic_order_cnt_type == 1)
+ {
+
+ }
+
+ /* num_ref_frames */
+ /* FIXME : Fix this hard coding */
+ ps_sps->u1_max_num_ref_frames = 1;
+
+ /* gaps_in_frame_num_value_allowed_flag */
+ ps_sps->i1_gaps_in_frame_num_value_allowed_flag = 0;
+
+ /* pic width in mb - 1 */
+ ps_sps->i2_pic_width_in_mbs_minus1 = ps_cfg->i4_wd_mbs - 1;
+
+ /* pic height in mb - 1 */
+ ps_sps->i2_pic_height_in_map_units_minus1 = ps_cfg->i4_ht_mbs - 1;;
+
+ /* frame_mbs_only_flag, no support for interlace encoding */
+ ps_sps->i1_frame_mbs_only_flag = 1;
+
+ /* mb_adaptive_frame_field_flag */
+ if (ps_sps->i1_frame_mbs_only_flag == 0)
+ {
+ ps_sps->i1_mb_adaptive_frame_field_flag = 0;
+ }
+
+ /* direct_8x8_inference_flag */
+ ps_sps->i1_direct_8x8_inference_flag = 0;
+
+ /* cropping params */
+ /*NOTE : Cropping values depend on the chroma format
+ * For our case ,decoder interprets the cropping values as 2*num pixels
+ * Hence the difference in the disp width and width must be halved before sending
+ * to get the expected results
+ */
+ ps_sps->i1_frame_cropping_flag = 0;
+ ps_sps->i2_frame_crop_left_offset = 0;
+ ps_sps->i2_frame_crop_right_offset = (ps_codec->s_cfg.u4_wd - ps_codec->s_cfg.u4_disp_wd)>>1;
+ ps_sps->i2_frame_crop_top_offset = 0;
+ ps_sps->i2_frame_crop_bottom_offset = (ps_codec->s_cfg.u4_ht - ps_codec->s_cfg.u4_disp_ht)>>1;
+
+ if (ps_sps->i2_frame_crop_left_offset ||
+ ps_sps->i2_frame_crop_right_offset ||
+ ps_sps->i2_frame_crop_top_offset ||
+ ps_sps->i2_frame_crop_bottom_offset)
+ {
+ ps_sps->i1_frame_cropping_flag = 1;
+ }
+
+ /* vui params */
+ ps_sps->i1_vui_parameters_present_flag = 0;
+
+ if (ps_sps->i1_vui_parameters_present_flag)
+ {
+ /* populate vui params */
+ }
+
+ return i4_err_code;
+}
+
+/**
+******************************************************************************
+*
+* @brief Populates pps structure
+*
+* @par Description
+* Populates pps structure for its use in header generation
+*
+* @param[in] ps_codec
+* pointer to encoder context
+*
+* @param[out] ps_pps
+* pointer to pps params that needs to be populated
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+IH264E_ERROR_T ih264e_populate_pps(codec_t *ps_codec, pps_t *ps_pps)
+{
+ /* active config parameters */
+ cfg_params_t *ps_cfg = &(ps_codec->s_cfg);
+
+ /* seq_parameter_set_id */
+ ps_pps->u1_sps_id = ps_codec->i4_sps_id;
+
+ /* pic_parameter_set_id */
+ ps_pps->u1_pps_id = ps_codec->i4_pps_id;
+
+ /* entropy_coding_mode */
+ ps_pps->u1_entropy_coding_mode_flag = ps_cfg->u4_entropy_coding_mode;
+
+ /* pic_order_present_flag is unset for POC type 2 */
+ ps_pps->u1_pic_order_present_flag = 0;
+
+ /* Currently number of slice groups supported are 1 */
+ ps_pps->u1_num_slice_groups = 1;
+
+ if (ps_pps->u1_num_slice_groups - 1)
+ {
+ /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
+ * If this is not the case, we have to add Slice group map type to the bit stream*/
+ }
+
+ /* number of reference frames for list 0 */
+ /* FIXME : fix this hard coded value */
+ ps_pps->i1_num_ref_idx_l0_default_active = 1;
+
+ /* number of reference frames for list 1 */
+ ps_pps->i1_num_ref_idx_l1_default_active = 1;
+
+ /* weighted prediction for now is disabled */
+ ps_pps->i1_weighted_pred_flag = 0;
+ ps_pps->i1_weighted_bipred_idc = 0;
+
+ /* The intent is to not signal qp from pps. Rather send the same in slice headers */
+ ps_pps->i1_pic_init_qp = 0;
+
+ /* The intent is to not signal qp from pps. Rather send the same in slice headers */
+ ps_pps->i1_pic_init_qs = 0;
+
+ /* The intent is to not signal qp from pps. Rather send the same in slice headers */
+ ps_pps->i1_chroma_qp_index_offset = 0;
+
+ /* deblocking filter flags present in slice header */
+ ps_pps->i1_deblocking_filter_control_present_flag = 1;
+
+ /* constrained intra prediction */
+ ps_pps->i1_constrained_intra_pred_flag = ps_cfg->u4_constrained_intra_pred;
+
+ /* sending redundant slices is not supported for now */
+ ps_pps->i1_redundant_pic_cnt_present_flag = 0;
+
+ ps_pps->u1_slice_group_map_type = 0;
+ return IH264E_SUCCESS;
+}
+
+/**
+******************************************************************************
+*
+* @brief Populates slice header structure
+*
+* @par Description
+* Populates slice header structure for its use in header generation
+*
+* @param[in] ps_proc
+* pointer to proc context
+*
+* @param[out] ps_slice_hdr
+* pointer to slice header structure that needs to be populated
+*
+* @param[in] ps_pps
+* pointer to pps params structure referred by the slice
+*
+* @param[in] ps_sps
+* pointer to sps params referred by the pps
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 ih264e_populate_slice_header(process_ctxt_t *ps_proc,
+ slice_header_t *ps_slice_hdr,
+ pps_t *ps_pps,
+ sps_t *ps_sps)
+{
+ /* entropy context */
+ entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
+
+ codec_t *ps_codec = ps_proc->ps_codec;
+
+ if (ps_proc->ps_codec->u4_is_curr_frm_ref)
+ {
+ ps_slice_hdr->i1_nal_unit_idc = 3;
+ }
+ else
+ {
+ ps_slice_hdr->i1_nal_unit_idc = 0;
+ }
+
+ /* start mb address */
+ ps_slice_hdr->u2_first_mb_in_slice = ps_entropy->i4_mb_start_add;
+
+ /* slice type */
+ ps_slice_hdr->u1_slice_type = ps_proc->i4_slice_type;
+
+ /* pic_parameter_set_id */
+ ps_slice_hdr->u1_pps_id = ps_pps->u1_pps_id;
+
+ /* Separate color plane flag is 0,
+ * hence the syntax element color_plane_id not included */
+
+ /* frame num */
+ ps_slice_hdr->i4_frame_num = ps_proc->i4_frame_num;
+
+ /* frame_mbs_only_flag, no support for interlace encoding */
+ if (!ps_sps->i1_frame_mbs_only_flag)
+ {
+ ps_slice_hdr->i1_field_pic_flag = 0;
+
+ if (ps_slice_hdr->i1_field_pic_flag)
+ {
+ ps_slice_hdr->i1_bottom_field_flag = 0;
+ }
+ }
+
+ /* idr pic id */
+ if (ps_proc->u4_is_idr)
+ {
+ ps_slice_hdr->u2_idr_pic_id = ps_proc->u4_idr_pic_id;
+ ps_slice_hdr->i1_nal_unit_type = 5;
+ }
+ else
+ {
+ ps_slice_hdr->i1_nal_unit_type = 1;
+ }
+
+ if (ps_sps->i1_pic_order_cnt_type == 0)
+ {
+
+ WORD32 val;
+ val = ps_codec->i4_coded_pic_cnt;
+ val %= (1 << ps_sps->i1_log2_max_pic_order_cnt_lsb);
+ ps_slice_hdr->i4_pic_order_cnt_lsb = val;
+ }
+ else if (ps_sps->i1_pic_order_cnt_type == 1)
+ {
+
+ }
+
+ if(0 == ps_slice_hdr->u2_first_mb_in_slice)
+ ps_codec->i4_coded_pic_cnt++;
+
+ /*
+ * redundant slices are not currently supported.
+ * Hence the syntax element redundant slice cnt is not initialized
+ */
+ if (ps_pps->i1_redundant_pic_cnt_present_flag)
+ {
+
+ }
+
+ /* direct spatial mv pred flag */
+ if (ps_proc->i4_slice_type == BSLICE)
+ {
+
+ }
+
+ if (ps_proc->i4_slice_type == PSLICE || ps_proc->i4_slice_type == SPSLICE || ps_proc->i4_slice_type == BSLICE)
+ {
+ /* num_ref_idx_active_override_flag */
+ ps_slice_hdr->u1_num_ref_idx_active_override_flag = 0;
+
+ if (ps_slice_hdr->u1_num_ref_idx_active_override_flag)
+ {
+ /* num_ref_idx_l0_active_minus1 */
+
+ if (ps_proc->i4_slice_type == BSLICE)
+ {
+ /* num_ref_idx_l1_active_minus1 */
+
+ }
+ }
+ }
+
+ /* ref_idx_reordering */
+ /* TODO: ref_idx_reordering */
+ if ((ps_proc->i4_slice_type != ISLICE) && (ps_proc->i4_slice_type != SISLICE))
+ {
+ /* ref_pic_list_reordering_flag_l0 */
+ ps_slice_hdr->u1_ref_idx_reordering_flag_l0 = 0;
+
+ if (ps_slice_hdr->u1_ref_idx_reordering_flag_l0)
+ {
+
+ }
+ }
+
+ if ((ps_pps->i1_weighted_pred_flag &&
+ (ps_proc->i4_slice_type == PSLICE || ps_proc->i4_slice_type == SPSLICE)) ||
+ (ps_slice_hdr->u1_weighted_bipred_idc == 1 && ps_proc->i4_slice_type == BSLICE))
+ {
+ /* TODO_LATER: Currently there is no support for weighted prediction.
+ This needs to be updated when the support is added */
+ }
+
+ if (ps_slice_hdr->i1_nal_unit_idc != 0)
+ {
+ if (ps_slice_hdr->i1_nal_unit_type == 5)
+ {
+ /* no_output_of_prior_pics_flag */
+ ps_slice_hdr->u1_no_output_of_prior_pics_flag = 0;
+
+ /* long_term_reference_flag */
+ ps_slice_hdr->u1_long_term_reference_flag = 0;
+ }
+ else
+ {
+ /* adaptive_ref_pic_marking_mode_flag */
+ ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag = 0;
+
+ if (ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag)
+ {
+ /* TODO: if the reference picture marking mode is adaptive
+ add these fields in the bit-stream */
+ }
+ }
+ }
+
+ /* entropy coding mode flag */
+ ps_slice_hdr->u1_entropy_coding_mode_flag = ps_entropy->u1_entropy_coding_mode_flag;
+
+ if (ps_slice_hdr->u1_entropy_coding_mode_flag && ps_proc->i4_slice_type != ISLICE &&
+ ps_proc->i4_slice_type != SISLICE)
+ {
+ /* cabac_init_idc */
+ }
+
+ /* slice qp */
+ ps_slice_hdr->i1_slice_qp = ps_proc->u4_frame_qp;
+
+ if (ps_proc->i4_slice_type == SPSLICE || ps_proc->i4_slice_type == SISLICE)
+ {
+ if (ps_proc->i4_slice_type == SPSLICE)
+ {
+ /* sp_for_switch_flag */
+ }
+ /* slice_qs_delta */
+ }
+
+ if (ps_pps->i1_deblocking_filter_control_present_flag)
+ {
+ /* disable_deblocking_filter_idc */
+ ps_slice_hdr->u1_disable_deblocking_filter_idc = ps_proc->u4_disable_deblock_level;
+
+ if (ps_slice_hdr->u1_disable_deblocking_filter_idc != 1)
+ {
+ /* slice_alpha_c0_offset_div2 */
+ ps_slice_hdr->i1_slice_alpha_c0_offset_div2 = 0;
+
+ /* slice_beta_offset_div2 */
+ ps_slice_hdr->i1_slice_beta_offset_div2 = 0;
+ }
+ }
+ ps_slice_hdr->u1_num_slice_groups_minus1 = 0;
+ if(ps_slice_hdr->u1_num_slice_groups_minus1 > 0 &&
+ ps_pps->u1_slice_group_map_type >= 3 &&
+ ps_pps->u1_slice_group_map_type <= 5)
+ {
+ /* slice_group_change_cycle */
+ /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
+ * If this is not the case, we have to add Slice group map type to the bit stream */
+ }
+
+ return IH264E_SUCCESS;
+}
+
+/**
+******************************************************************************
+*
+* @brief inserts FILLER Nal Unit.
+*
+* @par Description
+* In constant bit rate rc mode, when the bits generated by the codec is
+* underflowing the target bit rate, the encoder library inserts filler nal unit.
+*
+* @param[in] ps_bitstrm
+* pointer to bitstream context (handle)
+*
+* @param[in] insert_fill_bytes
+* Number of fill bytes to be inserted
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+IH264E_ERROR_T ih264e_add_filler_nal_unit(bitstrm_t *ps_bitstrm,
+ WORD32 insert_fill_bytes)
+{
+ WORD32 i4_num_words_to_fill, i4_words_filled;
+
+ IH264E_ERROR_T return_status = IH264E_SUCCESS;
+
+ /* Insert the NAL start code */
+ return_status |= ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
+
+ if (ps_bitstrm->u4_strm_buf_offset + insert_fill_bytes >= ps_bitstrm->u4_max_strm_size)
+ {
+ return (IH264E_BITSTREAM_BUFFER_OVERFLOW);
+ }
+
+ /* Insert Nal Unit Header */
+ PUT_BITS(ps_bitstrm, NAL_FILLER_FIRST_BYTE, 8, return_status, "filler_header");
+
+ PUT_BITS(ps_bitstrm, 0xFFFFFF, 24, return_status, "fill bytes");
+
+ /* Initializing Variables */
+ i4_words_filled = 1;
+
+ /****************************************************/
+ /* Flooring the number of bytes for be stuffed to */
+ /* WORD unit */
+ /****************************************************/
+ i4_num_words_to_fill = (insert_fill_bytes >> 2);
+
+ /****************************************************/
+ /* Reducing already 4 bytes filled. In case stuffing*/
+ /* is <= 4 bytes, we are actually not stuffing */
+ /* anything */
+ /****************************************************/
+ i4_num_words_to_fill -= i4_words_filled;
+
+ while (i4_num_words_to_fill > 0)
+ {
+ /* Insert Nal Unit Header */
+ PUT_BITS(ps_bitstrm, 0xFFFFFFFF, 32, return_status, "fill bytes");
+
+ i4_num_words_to_fill-- ;
+ }
+
+ return_status |= ih264e_put_rbsp_trailing_bits(ps_bitstrm);
+
+ return return_status;
+}
+