Merge "Encoder: Fixed an issue in handling FPS greater than 60" into mnc-dev
diff --git a/common/ih264_common_tables.c b/common/ih264_common_tables.c
index 3a04a38..7d15440 100644
--- a/common/ih264_common_tables.c
+++ b/common/ih264_common_tables.c
@@ -394,7 +394,7 @@
 };
 
 
-const UWORD8 *gpau1_ih264_inv_scan8x8[] =
+const UWORD8 *const gpau1_ih264_inv_scan8x8[] =
 {
      gau1_ih264_inv_scan_prog8x8_cavlc,
      gau1_ih264_inv_scan_int8x8_cavlc,
@@ -402,7 +402,7 @@
      gau1_ih264_inv_scan_int8x8_cabac
 };
 
-const UWORD8 *gpau1_ih264_inv_scan4x4[] =
+const UWORD8 *const gpau1_ih264_inv_scan4x4[] =
 {
      gau1_ih264_inv_scan_prog4x4,
      gau1_ih264_inv_scan_int4x4,
diff --git a/common/ih264_common_tables.h b/common/ih264_common_tables.h
index 3127a2c..d4ec147 100644
--- a/common/ih264_common_tables.h
+++ b/common/ih264_common_tables.h
@@ -108,8 +108,8 @@
 extern const UWORD8 gau1_ih264_inv_scan_prog8x8_cabac[64];
 extern const UWORD8 gau1_ih264_inv_scan_int8x8_cabac[64];
 
-extern const UWORD8 *gpau1_ih264_inv_scan8x8[];
-extern const UWORD8 *gpau1_ih264_inv_scan4x4[];
+extern const UWORD8 *const gpau1_ih264_inv_scan8x8[];
+extern const UWORD8 *const gpau1_ih264_inv_scan4x4[];
 
 extern const UWORD8 gau1_ih264_8x8_subblk_idx[];
 
diff --git a/decoder.x86.mk b/decoder.x86.mk
index e7a4686..100a501 100644
--- a/decoder.x86.mk
+++ b/decoder.x86.mk
@@ -1,4 +1,4 @@
-libavcd_cflags_x86 += -DX86 -msse4.2 -mno-avx -DDEFAULT_ARCH=D_ARCH_X86_SSE42
+libavcd_cflags_x86 += -DX86 -msse4.2 -DDEFAULT_ARCH=D_ARCH_X86_SSE42
 
 libavcd_inc_dir_x86     +=  $(LOCAL_PATH)/decoder/x86
 libavcd_inc_dir_x86     +=  $(LOCAL_PATH)/common/x86
diff --git a/decoder.x86_64.mk b/decoder.x86_64.mk
index b265f4f..4d926ec 100644
--- a/decoder.x86_64.mk
+++ b/decoder.x86_64.mk
@@ -1,4 +1,4 @@
-libavcd_cflags_x86_64 += -DX86 -msse4.2 -mno-avx  -DDEFAULT_ARCH=D_ARCH_X86_SSE42
+libavcd_cflags_x86_64 += -DX86 -msse4.2 -DDEFAULT_ARCH=D_ARCH_X86_SSE42
 
 libavcd_inc_dir_x86_64   +=  $(LOCAL_PATH)/decoder/x86
 libavcd_inc_dir_x86_64   +=  $(LOCAL_PATH)/common/x86
diff --git a/decoder/ih264d.h b/decoder/ih264d.h
index 6dd9893..beda247 100644
--- a/decoder/ih264d.h
+++ b/decoder/ih264d.h
@@ -78,7 +78,8 @@
 typedef enum {
 
     IH264D_VID_HDR_DEC_NUM_FRM_BUF_NOT_SUFFICIENT   = IVD_DUMMY_ELEMENT_FOR_CODEC_EXTENSIONS + 1,
-    IH264D_UNSUPPORTED_LEVEL   = IVD_DUMMY_ELEMENT_FOR_CODEC_EXTENSIONS + 2
+    IH264D_UNSUPPORTED_LEVEL   = IVD_DUMMY_ELEMENT_FOR_CODEC_EXTENSIONS + 2,
+    IH264D_UNSUPPORTED_NUM_REF_FRAMES   = IVD_DUMMY_ELEMENT_FOR_CODEC_EXTENSIONS + 3
 
 }IH264D_ERROR_CODES_T;
 
diff --git a/decoder/ih264d_api.c b/decoder/ih264d_api.c
index 6ea75c6..6fbd834 100644
--- a/decoder/ih264d_api.c
+++ b/decoder/ih264d_api.c
@@ -2589,7 +2589,7 @@
     UWORD32 cur_slice_is_nonref = 0;
     UWORD32 u4_next_is_aud;
     UWORD32 u4_first_start_code_found = 0;
-    WORD32 ret,api_ret_value = IV_SUCCESS;
+    WORD32 ret = 0,api_ret_value = IV_SUCCESS;
     WORD32 header_data_left = 0,frame_data_left = 0;
     UWORD8 *pu1_bitstrm_buf;
     ivd_video_decode_ip_t *ps_dec_ip;
@@ -3019,24 +3019,12 @@
             ps_dec_op->u4_error_code = error | ret;
             api_ret_value = IV_FAIL;
 
-            if((ret == IVD_RES_CHANGED) || (ret == IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED))
+            if((ret == IVD_RES_CHANGED)
+                            || (ret == IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED)
+                            || (ret == ERROR_UNAVAIL_PICBUF_T)
+                            || (ret == ERROR_UNAVAIL_MVBUF_T))
             {
-                /*dont consume the SPS*/
-                ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
-                return IV_FAIL;
-            }
-
-            if((ret == IVD_RES_CHANGED) || (ret == IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED))
-            {
-                /*dont consume the SPS*/
-                ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
-                return IV_FAIL;
-            }
-
-            if((ret == ERROR_UNAVAIL_PICBUF_T) || (ret == ERROR_UNAVAIL_MVBUF_T))
-            {
-                ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
-                return IV_FAIL;
+                break;
             }
 
             if((ret == ERROR_INCOMPLETE_FRAME) || (ret == ERROR_DANGLING_FIELD_IN_PIC))
@@ -3094,6 +3082,7 @@
         WORD32 num_mb_skipped;
         WORD32 prev_slice_err;
         pocstruct_t temp_poc;
+        WORD32 ret1;
 
         num_mb_skipped = (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
                             - ps_dec->u2_total_mbs_coded;
@@ -3103,15 +3092,33 @@
         else
             prev_slice_err = 2;
 
-        ret = ih264d_mark_err_slice_skip(ps_dec, num_mb_skipped, ps_dec->u1_nal_unit_type == IDR_SLICE_NAL, ps_dec->ps_cur_slice->u2_frame_num,
+        ret1 = ih264d_mark_err_slice_skip(ps_dec, num_mb_skipped, ps_dec->u1_nal_unit_type == IDR_SLICE_NAL, ps_dec->ps_cur_slice->u2_frame_num,
                                    &temp_poc, prev_slice_err);
 
-        if((ret == ERROR_UNAVAIL_PICBUF_T) || (ret == ERROR_UNAVAIL_MVBUF_T))
+        if((ret1 == ERROR_UNAVAIL_PICBUF_T) || (ret1 == ERROR_UNAVAIL_MVBUF_T))
         {
             return IV_FAIL;
         }
     }
 
+    if((ret == IVD_RES_CHANGED)
+                    || (ret == IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED)
+                    || (ret == ERROR_UNAVAIL_PICBUF_T)
+                    || (ret == ERROR_UNAVAIL_MVBUF_T))
+    {
+
+        /* signal the decode thread */
+        ih264d_signal_decode_thread(ps_dec);
+        /* close deblock thread if it is not closed yet */
+        if(ps_dec->u4_num_cores == 3)
+        {
+            ih264d_signal_bs_deblk_thread(ps_dec);
+        }
+        /* dont consume bitstream */
+        ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
+        return IV_FAIL;
+    }
+
 
     if(ps_dec->u1_separate_parse)
     {
diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c
index 743b573..35c3a16 100644
--- a/decoder/ih264d_parse_headers.c
+++ b/decoder/ih264d_parse_headers.c
@@ -728,6 +728,12 @@
         return ERROR_NUM_REF;
     }
     ps_seq->u1_num_ref_frames = u4_temp;
+
+    if(ps_seq->u1_num_ref_frames > ps_dec->u4_num_ref_frames_at_init)
+    {
+        return IH264D_UNSUPPORTED_NUM_REF_FRAMES;
+    }
+
     COPYTHECONTEXT("SPS: num_ref_frames",ps_seq->u1_num_ref_frames);
 
     ps_seq->u1_gaps_in_frame_num_value_allowed_flag = ih264d_get_bit_h264(
@@ -930,10 +936,6 @@
         ps_dec->u2_disp_width = i4_cropped_wd;
 
     }
-     if(ps_dec->u4_level_at_init < u1_level_idc)
-     {
-         return IH264D_UNSUPPORTED_LEVEL;
-     }
 
     ps_seq->u1_is_valid = TRUE;
 
@@ -944,6 +946,44 @@
             return ret;
     }
 
+    if(ps_dec->u4_level_at_init < u1_level_idc)
+    {
+        UWORD32 u4_num_pic_bufs_reqd, u4_num_reorder_frames,
+                        u4_num_mv_bufs_reqd;
+        UWORD32 u4_num_pic_bufs_memory, u4_num_mv_bufs_memory;
+        UWORD32 u4_num_ref_frames;
+
+        u4_num_ref_frames = ps_seq->u1_num_ref_frames;
+        if(1 == ps_seq->u1_vui_parameters_present_flag)
+        {
+            u4_num_reorder_frames = ps_seq->s_vui.u4_num_reorder_frames;
+        }
+        else
+        {
+            u4_num_reorder_frames = ps_dec->u4_num_reorder_frames_at_init;
+        }
+
+        u4_num_pic_bufs_reqd = u4_num_ref_frames + u4_num_reorder_frames + 1;
+
+        u4_num_pic_bufs_memory = ih264d_get_numbuf_dpb_bank(ps_dec, u2_frm_wd_y,
+                                                     u2_frm_ht_y);
+
+        u4_num_mv_bufs_reqd = u4_num_ref_frames + 1;
+
+        if(u4_num_mv_bufs_reqd < 2)
+            u4_num_mv_bufs_reqd = 2;
+
+        u4_num_mv_bufs_memory = ih264d_get_numbuf_mv_bank(ps_dec, u2_pic_wd,
+                                                   u2_pic_ht);
+
+        if((u4_num_pic_bufs_reqd > u4_num_pic_bufs_memory)
+                        || (u4_num_mv_bufs_reqd > u4_num_mv_bufs_memory))
+        {
+            return IH264D_UNSUPPORTED_LEVEL;
+        }
+
+    }
+
     ps_dec->u2_pic_wd = u2_pic_wd;
     ps_dec->u2_pic_ht = u2_pic_ht;
 
diff --git a/decoder/ih264d_utils.c b/decoder/ih264d_utils.c
index 1581bd6..a4896c0 100644
--- a/decoder/ih264d_utils.c
+++ b/decoder/ih264d_utils.c
@@ -831,7 +831,7 @@
 
 /*!
  **************************************************************************
- * \if Function name : get_numbuf_dpb_bank \endif
+ * \if Function name : ih264d_get_numbuf_dpb_bank \endif
  *
  * \brief
  *    Initializes the picture.
@@ -844,7 +844,7 @@
  *    NON -IDR picture is encountered.
  **************************************************************************
  */
-static WORD32 get_numbuf_dpb_bank(dec_struct_t *ps_dec)
+WORD32 ih264d_get_numbuf_dpb_bank(dec_struct_t *ps_dec, UWORD32 u4_frame_wd, UWORD32 u4_frame_ht)
 {
     WORD32 i4_DPB_size;
     WORD32 i4_pic_size;
@@ -852,13 +852,11 @@
     UWORD32 Ysize;
     UWORD32 UVsize;
     UWORD32 one_frm_size;
-    UWORD32 luma_height;
 
-    luma_height = ps_dec->u2_pic_ht;
 
     i4_DPB_size = ps_dec->ps_mem_tab[MEM_REC_REF_PIC].u4_mem_size;
 
-    Ysize = (ps_dec->u2_frm_wd_y) * (luma_height + (PAD_LEN_Y_V << 2));
+    Ysize = u4_frame_wd * u4_frame_ht;
 
     UVsize = Ysize >> 2;
 
@@ -889,6 +887,32 @@
 
     return i4_num_buf_alloc;
 }
+
+/*!
+ **************************************************************************
+ * \if Function name : ih264d_get_numbuf_mv_bank \endif
+ *
+ * \brief
+ *    Computes number of MVbank buffers that can be allocated.
+ *
+ * \return
+ *    Number of MV bank buffers that can be allocated.
+ *
+ * \note
+ **************************************************************************
+ */
+UWORD32 ih264d_get_numbuf_mv_bank(dec_struct_t *ps_dec, UWORD32 width,
+                                  UWORD32 height)
+{
+    UWORD32 u4_mv_bank_size,one_frame_size;
+    UWORD32 u4_num_buf_alloc;
+
+    u4_mv_bank_size = ps_dec->ps_mem_tab[MEM_REC_MVBANK].u4_mem_size;
+    one_frame_size = sizeof(mv_pred_t)
+                    * ((width * (height + PAD_MV_BANK_ROW)) >> 4);
+    u4_num_buf_alloc = u4_mv_bank_size / one_frame_size;
+    return u4_num_buf_alloc;
+}
 /*!
  **************************************************************************
  * \if Function name : ih264d_init_pic \endif
@@ -955,7 +979,8 @@
 
         if(ps_dec->u4_share_disp_buf == 0)
         {
-            i4_pic_bufs = get_numbuf_dpb_bank(ps_dec);
+            i4_pic_bufs = ih264d_get_numbuf_dpb_bank(ps_dec, ps_dec->u2_frm_wd_y,
+                                              ps_dec->u2_frm_ht_y);
         }
         else
         {
@@ -2080,6 +2105,8 @@
                     ps_dec->ps_mem_tab[MEM_REC_SLICE_NUM_MAP].pv_base;
 
     ps_dec->ps_dec_slice_buf = ps_dec->ps_mem_tab[MEM_REC_SLICE_HDR].pv_base;
+    memset(ps_dec->ps_mem_tab[MEM_REC_SLICE_HDR].pv_base, 0,
+           ps_dec->ps_mem_tab[MEM_REC_SLICE_HDR].u4_mem_size);
     pu1_buf = (UWORD8 *)ps_dec->ps_dec_slice_buf;
     pu1_buf += sizeof(dec_slice_struct_t) * u4_total_mbs;
     ps_dec->pv_map_ref_idx_to_poc_buf = (void *)pu1_buf;
@@ -2512,6 +2539,7 @@
     UWORD8 *pu1_col_zero_flag_buf;
     dec_struct_t *ps_dec = (dec_struct_t *)pv_dec;
     WORD32 buf_ret;
+    UWORD32 u4_num_bufs;
 
     pu1_mv_buf_mgr_base = ps_dec->ps_mem_tab[MEM_REC_MV_BUF_MGR].pv_base;
     u4_mv_buf_mgr_mem_used = 0;
@@ -2530,7 +2558,11 @@
     u4_mv_buf_mgr_mem_used += sizeof(col_mv_buf_t) * (H264_MAX_REF_PICS * 2);
     u4_mv_buf_mgr_mem_used = ALIGN128(u4_mv_buf_mgr_mem_used);
 
-    for(i = 0 ; i < ps_dec->u1_max_dec_frame_buffering + 1; i++)
+    u4_num_bufs = ih264d_get_numbuf_mv_bank(ps_dec, ui_width, ui_height);
+
+    u4_num_bufs = MIN(u4_num_bufs, ps_dec->u1_pic_bufs);
+
+    for(i = 0 ; i < u4_num_bufs ; i++)
     {
         pu1_col_zero_flag_buf = pu1_mv_buf_mgr_base + u4_mv_buf_mgr_mem_used;
         u4_mv_buf_mgr_mem_used +=  col_flag_buffer_size;
diff --git a/decoder/ih264d_utils.h b/decoder/ih264d_utils.h
index a1a64d5..326acc0 100644
--- a/decoder/ih264d_utils.h
+++ b/decoder/ih264d_utils.h
@@ -97,5 +97,9 @@
                                 UWORD32 u4_cur_pos,
                                 UWORD32 u4_max_ofst,
                                 UWORD32 *pu4_length_of_start_code);
+UWORD32 ih264d_get_numbuf_mv_bank(dec_struct_t *ps_dec, UWORD32 width, UWORD32 height);
+WORD32 ih264d_get_numbuf_dpb_bank(dec_struct_t *ps_dec,
+                           UWORD32 u2_frame_wd,
+                           UWORD32 u2_frame_ht);
 
 #endif /* _IH264D_UTILS_H_ */
diff --git a/encoder.x86.mk b/encoder.x86.mk
index f1e2ffa..91f20d9 100644
--- a/encoder.x86.mk
+++ b/encoder.x86.mk
@@ -1,4 +1,4 @@
-libavce_cflags_x86 += -DX86 -msse4.2 -mno-avx
+libavce_cflags_x86 += -DX86 -msse4.2
 
 libavce_inc_dir_x86     +=  $(LOCAL_PATH)/encoder/x86
 libavce_inc_dir_x86     +=  $(LOCAL_PATH)/common/x86
diff --git a/encoder.x86_64.mk b/encoder.x86_64.mk
index 14205a3..3e7b850 100644
--- a/encoder.x86_64.mk
+++ b/encoder.x86_64.mk
@@ -1,4 +1,4 @@
-libavce_cflags_x86_64   += -DX86 -msse4.2 -mno-avx
+libavce_cflags_x86_64   += -DX86 -msse4.2
 
 libavce_inc_dir_x86_64  +=  $(LOCAL_PATH)/encoder/x86
 libavce_inc_dir_x86_64  +=  $(LOCAL_PATH)/common/x86
diff --git a/encoder/ih264e_api.c b/encoder/ih264e_api.c
index 96122de..c46134d 100644
--- a/encoder/ih264e_api.c
+++ b/encoder/ih264e_api.c
@@ -1758,6 +1758,15 @@
                         return IV_FAIL;
                     }
 
+                    if (ps_ip->s_ive_ip.u4_entropy_coding_mode > 1)
+                    {
+                        ps_op->s_ive_op.u4_error_code |= 1
+                                        << IVE_UNSUPPORTEDPARAM;
+                        ps_op->s_ive_op.u4_error_code |=
+                                        IH264E_INVALID_ENTROPY_CODING_MODE;
+                        return IV_FAIL;
+                    }
+
                     break;
                 }
 
@@ -1819,18 +1828,11 @@
         UWORD32 ht_aln = ALIGN16(ps_cfg->u4_ht);
 
         if (ps_curr_cfg->u4_wd != wd_aln || ps_curr_cfg->u4_ht != ht_aln
-                        || ps_curr_cfg->u4_strd != ps_cfg->u4_strd
                         || ps_curr_cfg->u4_disp_wd != ps_cfg->u4_disp_wd
                         || ps_curr_cfg->u4_disp_ht != ps_cfg->u4_disp_ht)
         {
             ps_curr_cfg->u4_wd = wd_aln;
             ps_curr_cfg->u4_ht = ht_aln;
-            ps_curr_cfg->u4_strd = ps_cfg->u4_strd;
-
-            if (ps_curr_cfg->u4_strd == 0)
-            {
-                ps_curr_cfg->u4_strd = ps_curr_cfg->u4_wd;
-            }
 
             ps_curr_cfg->u4_disp_wd = ps_cfg->u4_disp_wd;
             ps_curr_cfg->u4_disp_ht = ps_cfg->u4_disp_ht;
@@ -2320,7 +2322,6 @@
     ps_cfg->u4_disp_ht = MAX_HT;
     ps_cfg->u4_wd = MAX_WD;
     ps_cfg->u4_ht = MAX_HT;
-    ps_cfg->u4_strd = ALIGN16(MAX_WD);
     ps_cfg->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE;
     ps_cfg->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE;
     ps_cfg->u4_target_bitrate = DEFAULT_BITRATE;
@@ -4667,7 +4668,6 @@
 
     ps_cfg->u4_wd = ALIGN16(ps_ip->s_ive_ip.u4_wd);
     ps_cfg->u4_ht = ALIGN16(ps_ip->s_ive_ip.u4_ht);
-    ps_cfg->u4_strd = ps_ip->s_ive_ip.u4_strd;
     ps_cfg->i4_wd_mbs = ps_cfg->u4_wd >> 4;
     ps_cfg->i4_ht_mbs = ps_cfg->u4_ht >> 4;
     ps_cfg->u4_disp_wd = ps_ip->s_ive_ip.u4_wd;
diff --git a/encoder/ih264e_cabac.c b/encoder/ih264e_cabac.c
index 64ff7cd..26ded4d 100644
--- a/encoder/ih264e_cabac.c
+++ b/encoder/ih264e_cabac.c
@@ -111,30 +111,29 @@
  *
  *******************************************************************************
  */
+
 UWORD32 ih264e_cabac_UEGk0_binarization(WORD16 i2_sufs, WORD8 *pi1_bins_len)
 {
-    UWORD32 u4_bins;
-    WORD32 i4_len;
-    WORD16 x, y;
+    WORD32 unary_length;
+    UWORD32 u4_sufs_shiftk_plus1, u4_egk, u4_unary_bins;
 
-    x = i2_sufs + 1;
-    i4_len = CLZ(x);
-    i4_len = 31 - i4_len;
-    y = 1 << i4_len;
-    y = y - 1;
-    i2_sufs = i2_sufs - y;
-    u4_bins = y << 1;
-    u4_bins = u4_bins << i4_len;
-    u4_bins = u4_bins + i2_sufs;
+    u4_sufs_shiftk_plus1 = i2_sufs + 1;
 
-    REV(u4_bins, u4_bins);
-    u4_bins = u4_bins >> (31 - 2 * i4_len);
-    (*pi1_bins_len) = 2 * i4_len + 1;
+    unary_length = (32 - CLZ(u4_sufs_shiftk_plus1) + (0 == u4_sufs_shiftk_plus1));
 
-    return (u4_bins);
+    /* unary code with (unary_length-1) '1's and terminating '0' bin */
+    u4_unary_bins = (1 << unary_length) - 2;
+
+    /* insert the symbol prefix of (unary length - 1)  bins */
+    u4_egk = (u4_unary_bins << (unary_length - 1))
+                    | (u4_sufs_shiftk_plus1 & ((1 << (unary_length - 1)) - 1));
+
+    /* length of the code = 2 *(unary_length - 1) + 1 + k */
+    *pi1_bins_len = (2 * unary_length) - 1;
+
+    return (u4_egk);
 }
 
-
 /**
  *******************************************************************************
  *
@@ -236,14 +235,14 @@
  *  @param[in]   ps_cabac_ctxt
  *  pointer to cabac context (handle)
  *
- * @returns  success or failure error code
+ * @returns  none
  *
  * @remarks
  *  None
  *
  *******************************************************************************
  */
-WORD32 ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt)
+void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt)
 {
 
     /* bit stream ptr */
@@ -267,17 +266,6 @@
         WORD32 bits_left;
         WORD32 rem_bits;
 
-        /*********************************************************************/
-        /* Bitstream overflow check                                          */
-        /* NOTE: corner case of epb bytes (max 2 for 32bit word) not handled */
-        /*********************************************************************/
-        if ((u4_strm_buf_offset + u4_out_standing_bytes + 1)
-                        >= ps_stream->u4_max_strm_size)
-        {
-            /* return without corrupting the buffer beyond its size */
-            return (IH264E_BITSTREAM_BUFFER_OVERFLOW);
-        }
-
         if (carry)
         {
             /* CORNER CASE: if the previous data is 0x000003, then EPB will be inserted
@@ -336,7 +324,6 @@
         ps_stream->u4_cur_word = 0;
         ps_stream->i4_bits_left_in_cw = WORD_SIZE;
 
-        return (IH264E_SUCCESS);
     }
 }
 
@@ -763,7 +750,6 @@
 
     UWORD32 u4_range = ps_cab_enc_env->u4_code_int_range;
     WORD32 next_byte;
-    UWORD32 rev_next_byte;
 
     /* Sanity checks */
     ASSERT((num_bins < 33) && (num_bins > 0));
@@ -777,14 +763,11 @@
     {
         num_bins -= 8;
 
-        /* extract the leading 8 bins */
-        next_byte = (u4_bins) & 0xff;
-        u4_bins >>= 8;
-        REV_NBITS(next_byte, 8, rev_next_byte);
+        next_byte = (u4_bins >> (num_bins)) & 0xff;
 
         /*  L = (L << 8) +  (R * next_byte) */
         ps_cab_enc_env->u4_code_int_low <<= 8;
-        ps_cab_enc_env->u4_code_int_low += (rev_next_byte * u4_range);
+        ps_cab_enc_env->u4_code_int_low += (next_byte * u4_range);
         ps_cab_enc_env->u4_bits_gen += 8;
 
         if (ps_cab_enc_env->u4_bits_gen > CABAC_BITS)
@@ -797,10 +780,8 @@
     /* Update low with remaining bins and return */
     next_byte = (u4_bins & ((1 << num_bins) - 1));
 
-    REV_NBITS(next_byte, num_bins, rev_next_byte);
-
     ps_cab_enc_env->u4_code_int_low <<= num_bins;
-    ps_cab_enc_env->u4_code_int_low += (rev_next_byte * u4_range);
+    ps_cab_enc_env->u4_code_int_low += (next_byte * u4_range);
     ps_cab_enc_env->u4_bits_gen += num_bins;
 
     if (ps_cab_enc_env->u4_bits_gen > CABAC_BITS)
@@ -810,10 +791,3 @@
     }
 
 }
-
-
-
-
-
-
-
diff --git a/encoder/ih264e_cabac.h b/encoder/ih264e_cabac.h
index e781783..e4722fa 100644
--- a/encoder/ih264e_cabac.h
+++ b/encoder/ih264e_cabac.h
@@ -47,24 +47,6 @@
 #define CABAC_BITS  9
 
 
-
-
-/**
-******************************************************************************
- *  @macro Count number of bits set
-******************************************************************************
-*/
-#define REV_NBITS(word, size, rev_word)               \
-{                                                     \
-    WORD32 i;                                         \
-    rev_word = 0;                                     \
-    for (i = 0; i < (size); i++)                      \
-    {                                                 \
-        UWORD32 bit = ((word) >> i) & 1;              \
-        rev_word += (1 << ((size) - i - 1)) * bit;    \
-    }                                                 \
-}                                                     \
-
 /**
 ******************************************************************************
  *  @macro Reverse bits in an unsigned integer
@@ -201,14 +183,14 @@
  *  @param[in]   ps_cabac_ctxt
  *  pointer to cabac context (handle)
  *
- * @returns  success or failure error code
+ * @returns  none
  *
  * @remarks
  *  None
  *
  *******************************************************************************
  */
-WORD32 ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt);
+void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt);
 
 
 /**
diff --git a/encoder/ih264e_cabac_encode.c b/encoder/ih264e_cabac_encode.c
index ebcd418..ecc30f5 100644
--- a/encoder/ih264e_cabac_encode.c
+++ b/encoder/ih264e_cabac_encode.c
@@ -856,7 +856,7 @@
                 }
                 /* encode coeff_sign_flag[i] */
                 u1_sign = ((*pi16_coeffs) < 0) ? 1 : 0;
-                ih264e_cabac_encode_bypass_bins(ps_cabac_ctxt, u1_sign, 1);
+                ih264e_cabac_encode_bypass_bin(ps_cabac_ctxt, u1_sign);
                 i = CLZ(u4_sig_coeff);
                 i = 31 - i;
                 pi16_coeffs--;
@@ -1206,11 +1206,13 @@
             }
             else
             {
+                UWORD8 u1_csbf;
+
                 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data,
                                            u1_nnz, u2_sig_coeff_map,
                                            pi2_res_block);
 
-                UWORD8 u1_csbf = !!(u1_nnz);
+                u1_csbf = !!(u1_nnz);
                 {
                     UWORD8 u1_a, u1_b;
                     UWORD32 u4_ctx_inc;
@@ -1373,7 +1375,7 @@
             {
                 if (i2_sufs >= (1 << k))
                 {
-                    u4_bins = (u4_bins | (1 << i1_bins_len));
+                    u4_bins = (u4_bins | (1 << (31 - i1_bins_len)));
                     i1_bins_len++;
                     i2_sufs = i2_sufs - (1 << k);
                     k++;
@@ -1384,12 +1386,13 @@
                     while (k--)
                     {
                         u1_bin = ((i2_sufs >> k) & 0x01);
-                        u4_bins = (u4_bins | (u1_bin << i1_bins_len));
+                        u4_bins = (u4_bins | (u1_bin << (31 - i1_bins_len)));
                         i1_bins_len++;
                     }
                     break;
                 }
             }
+            u4_bins >>= (32 - i1_bins_len);
             ih264e_cabac_encode_bypass_bins(ps_cabac_ctxt, u4_bins,
                                             i1_bins_len);
         }
@@ -1426,9 +1429,9 @@
         }
         /* sign bit, uses EncodeBypass */
         if (u1_mvd > 0)
-            ih264e_cabac_encode_bypass_bins(ps_cabac_ctxt, 0, 1);
+            ih264e_cabac_encode_bypass_bin(ps_cabac_ctxt, 0);
         else
-            ih264e_cabac_encode_bypass_bins(ps_cabac_ctxt, 1, 1);
+            ih264e_cabac_encode_bypass_bin(ps_cabac_ctxt, 1);
     }
 }
 
diff --git a/encoder/ih264e_cavlc.c b/encoder/ih264e_cavlc.c
index 5d819d9..7491480 100644
--- a/encoder/ih264e_cavlc.c
+++ b/encoder/ih264e_cavlc.c
@@ -1718,13 +1718,17 @@
         {
             if (i4_mb_part_pred_mode != PRED_L1)/* || PRED_BI */
             {
-                PUT_BITS_SEV(ps_bitstream, *pi2_mvd_ptr++, error_status, "mv l0 x");
-                PUT_BITS_SEV(ps_bitstream, *pi2_mvd_ptr++, error_status, "mv l0 y");
+                PUT_BITS_SEV(ps_bitstream, *pi2_mvd_ptr, error_status, "mv l0 x");
+                pi2_mvd_ptr++;
+                PUT_BITS_SEV(ps_bitstream, *pi2_mvd_ptr, error_status, "mv l0 y");
+                pi2_mvd_ptr++;
             }
             if (i4_mb_part_pred_mode != PRED_L0)/* || PRED_BI */
             {
-                PUT_BITS_SEV(ps_bitstream, *pi2_mvd_ptr++, error_status, "mv l1 x");
-                PUT_BITS_SEV(ps_bitstream, *pi2_mvd_ptr++, error_status, "mv l1 y");
+                PUT_BITS_SEV(ps_bitstream, *pi2_mvd_ptr, error_status, "mv l1 x");
+                pi2_mvd_ptr++;
+                PUT_BITS_SEV(ps_bitstream, *pi2_mvd_ptr, error_status, "mv l1 y");
+                pi2_mvd_ptr++;
             }
         }
 
diff --git a/encoder/ih264e_core_coding.c b/encoder/ih264e_core_coding.c
index 76266d7..5b36aef 100644
--- a/encoder/ih264e_core_coding.c
+++ b/encoder/ih264e_core_coding.c
@@ -1823,27 +1823,19 @@
             /*  itransform                                          */
             /*  iquantization                                       */
             /********************************************************/
-            /* If the frame is not to be used for P frame reference or dumping recon
-             * we only will use the recon for only predicting intra Mbs
-             * This will need only right and bottom edge 4x4 blocks recon
-             * Hence we selectively enable them
-             */
-            if (ps_proc->u4_compute_recon || (0xF888 & (1 << ((b8 << 2) + b4))))
-            {
-                if (u1_nnz)
-                    ps_codec->pf_iquant_itrans_recon_4x4(
-                                    pi2_res_mb, pu1_pred_mb, pu1_ref_mb,
-                                    /*No input stride,*/i4_pred_strd,
-                                    i4_rec_strd, ps_qp_params->pu2_iscale_mat,
-                                    ps_qp_params->pu2_weigh_mat,
-                                    ps_qp_params->u1_qp_div,
-                                    ps_proc->pv_scratch_buff, 0, 0);
-                else
-                    ps_codec->pf_inter_pred_luma_copy(pu1_pred_mb, pu1_ref_mb,
-                                                      i4_pred_strd, i4_rec_strd,
-                                                      BLK_SIZE, BLK_SIZE, NULL,
-                                                      0);
-            }
+            if (u1_nnz)
+                ps_codec->pf_iquant_itrans_recon_4x4(
+                                pi2_res_mb, pu1_pred_mb, pu1_ref_mb,
+                                /*No input stride,*/i4_pred_strd,
+                                i4_rec_strd, ps_qp_params->pu2_iscale_mat,
+                                ps_qp_params->pu2_weigh_mat,
+                                ps_qp_params->u1_qp_div,
+                                ps_proc->pv_scratch_buff, 0, 0);
+            else
+                ps_codec->pf_inter_pred_luma_copy(pu1_pred_mb, pu1_ref_mb,
+                                                  i4_pred_strd, i4_rec_strd,
+                                                  BLK_SIZE, BLK_SIZE, NULL,
+                                                  0);
 
         }
 
diff --git a/encoder/ih264e_encode.c b/encoder/ih264e_encode.c
index c027321..e7057dc 100644
--- a/encoder/ih264e_encode.c
+++ b/encoder/ih264e_encode.c
@@ -361,7 +361,11 @@
         ps_codec->i4_gen_header = 0;
 
         /* send the input to app */
-        ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf;
+        ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf;
+        ps_video_encode_op->s_ive_op.u4_timestamp_low = ps_video_encode_ip->s_ive_ip.u4_timestamp_low;
+        ps_video_encode_op->s_ive_op.u4_timestamp_high = ps_video_encode_ip->s_ive_ip.u4_timestamp_high;
+
+        ps_video_encode_op->s_ive_op.u4_is_last = ps_video_encode_ip->s_ive_ip.u4_is_last;
 
         /* send the output to app */
         ps_video_encode_op->s_ive_op.output_present  = 1;
@@ -393,16 +397,6 @@
     /* Only encode if the current frame is not pre-encode skip */
     if (!i4_rc_pre_enc_skip && s_inp_buf.s_raw_buf.apv_bufs[0])
     {
-        /* array giving pic cnt that is being processed in curr context set */
-        ps_codec->ai4_pic_cnt[ctxt_sel] = ps_codec->i4_pic_cnt;
-
-        /* initialize all relevant process ctxts */
-        error_status |= ih264e_pic_init(ps_codec, &s_inp_buf);
-        SET_ERROR_ON_RETURN(error_status,
-                            IVE_FATALERROR,
-                            ps_video_encode_op->s_ive_op.u4_error_code,
-                            IV_FAIL);
-
         /* proc ctxt base idx */
         WORD32 proc_ctxt_select = ctxt_sel * MAX_PROCESS_THREADS;
 
@@ -414,6 +408,16 @@
         /* number of addl. threads to be created */
         WORD32 num_thread_cnt = ps_codec->s_cfg.u4_num_cores - 1;
 
+        /* array giving pic cnt that is being processed in curr context set */
+        ps_codec->ai4_pic_cnt[ctxt_sel] = ps_codec->i4_pic_cnt;
+
+        /* initialize all relevant process ctxts */
+        error_status |= ih264e_pic_init(ps_codec, &s_inp_buf);
+        SET_ERROR_ON_RETURN(error_status,
+                            IVE_FATALERROR,
+                            ps_video_encode_op->s_ive_op.u4_error_code,
+                            IV_FAIL);
+
         for (i = 0; i < num_thread_cnt; i++)
         {
             ret = ithread_create(ps_codec->apv_proc_thread_handle[i],
@@ -469,7 +473,7 @@
 
     ps_video_encode_op->s_ive_op.dump_recon = 0;
 
-    if (ps_codec->s_cfg.u4_enable_recon && (ps_codec->i4_frame_num > 1)
+    if (ps_codec->s_cfg.u4_enable_recon && (ps_codec->i4_frame_num > 1 || s_inp_buf.u4_is_last)
                     && (s_inp_buf.s_raw_buf.apv_bufs[0] || s_inp_buf.u4_is_last))
     {
         /* error status */
diff --git a/encoder/ih264e_error.h b/encoder/ih264e_error.h
index 1eba46c..5a7a560 100644
--- a/encoder/ih264e_error.h
+++ b/encoder/ih264e_error.h
@@ -223,6 +223,9 @@
     /**Not enough memory allocated as output buffer */
     IH264E_INSUFFICIENT_OUTPUT_BUFFER                               = IH264E_CODEC_ERROR_START + 0x30,
 
+    /**Invalid entropy coding mode */
+    IH264E_INVALID_ENTROPY_CODING_MODE                              = IH264E_CODEC_ERROR_START + 0x31,
+
     /**max failure error code to ensure enum is 32 bits wide */
     IH264E_FAIL                                                     = -1,
 
diff --git a/encoder/ih264e_me.c b/encoder/ih264e_me.c
index 68bdea6..36182e4 100644
--- a/encoder/ih264e_me.c
+++ b/encoder/ih264e_me.c
@@ -241,6 +241,9 @@
     WORD32 i4_srch_range_e = ps_me_ctxt->i4_srch_range_e;
     WORD32 i4_srch_range_w = ps_me_ctxt->i4_srch_range_w;
 
+    /* num of candidate search candidates */
+    UWORD32 u4_num_candidates = 0;
+
     ps_left_mv = &ps_proc->s_left_mb_pu_ME.s_me_info[i4_reflist].s_mv;
     ps_top_mv = &(ps_proc->ps_top_row_pu_ME + i4_mb_x)->s_me_info[i4_reflist].s_mv;
     ps_top_left_mv = &ps_proc->s_top_left_mb_pu_ME.s_me_info[i4_reflist].s_mv;
@@ -251,9 +254,6 @@
     i4_top_left_mode = ps_proc->s_top_left_mb_pu_ME.b2_pred_mode != i4_cmpl_predmode;
     i4_top_right_mode = (ps_proc->ps_top_row_pu_ME + i4_mb_x + 1)->b2_pred_mode != i4_cmpl_predmode;
 
-    /* num of candidate search candidates */
-    UWORD32 u4_num_candidates =0 ;
-
     /* Taking the Zero motion vector as one of the candidates   */
     ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvx = 0;
     ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvy = 0;
@@ -893,12 +893,12 @@
     /* quantization parameters */
     quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
 
-    /* Sad therholds */
-    ps_me_ctxt->pu2_sad_thrsh = ps_qp_params->pu2_sad_thrsh;
-
     /* Mb part ctxts for SKIP */
     mb_part_ctxt s_skip_mbpart;
 
+    /* Sad therholds */
+    ps_me_ctxt->pu2_sad_thrsh = ps_qp_params->pu2_sad_thrsh;
+
     {
         WORD32 rows_above, rows_below, columns_left, columns_right;
 
@@ -1281,7 +1281,7 @@
     enc_pu_t *ps_a_pu, *ps_c_pu, *ps_b_pu;
 
     /* Variables to check if a particular mB is available */
-    WORD32 i4_a, i4_b, i4_c, i4_c_avail;;
+    WORD32 i4_a, i4_b, i4_c, i4_c_avail;
 
     /* Mode availability, init to no modes available     */
     WORD32 i4_mode_avail;
@@ -1733,13 +1733,13 @@
         ps_me_ctxt->pf_ime_compute_sad_16x16[u4_fast_sad](
                         ps_me_ctxt->pu1_src_buf_luma, pu1_dst_buf,
                         ps_me_ctxt->i4_src_strd, ps_me_ctxt->u4_subpel_buf_strd,
-                        ps_mb_ctxt_bi->i4_mb_distortion, &i4_mb_distortion);
+                        INT_MAX, &i4_mb_distortion);
 
         /* compute cost */
-        i4_mb_cost =  ps_me_ctxt->pu1_mv_bits[( s_l0_mv.i2_mvy << 2 ) - ps_l0_pred_mv->i2_mvx];
-        i4_mb_cost += ps_me_ctxt->pu1_mv_bits[( s_l0_mv.i2_mvy << 2 ) - ps_l0_pred_mv->i2_mvy];
-        i4_mb_cost += ps_me_ctxt->pu1_mv_bits[( s_l1_mv.i2_mvx << 2 ) - ps_l1_pred_mv->i2_mvx];
-        i4_mb_cost += ps_me_ctxt->pu1_mv_bits[( s_l1_mv.i2_mvy << 2 ) - ps_l1_pred_mv->i2_mvy];
+        i4_mb_cost =  ps_me_ctxt->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[PRED_BI][i].i2_mvx - ps_l0_pred_mv->i2_mvx];
+        i4_mb_cost += ps_me_ctxt->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[PRED_BI][i].i2_mvy - ps_l0_pred_mv->i2_mvy];
+        i4_mb_cost += ps_me_ctxt->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[PRED_BI][i + 1].i2_mvx - ps_l1_pred_mv->i2_mvx];
+        i4_mb_cost += ps_me_ctxt->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[PRED_BI][i + 1].i2_mvy - ps_l1_pred_mv->i2_mvy];
 
         i4_mb_cost -= (ps_me_ctxt->i4_skip_bias[BSLICE]) * (ps_me_ctxt->i4_skip_type == PRED_BI) * (i == 0);
 
@@ -1800,12 +1800,12 @@
     /* quantization parameters */
     quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
 
-    /* Sad therholds */
-    ps_me_ctxt->pu2_sad_thrsh = ps_qp_params->pu2_sad_thrsh;
-
     /* Mb part ctxts for SKIP */
     mb_part_ctxt as_skip_mbpart[2];
 
+    /* Sad therholds */
+    ps_me_ctxt->pu2_sad_thrsh = ps_qp_params->pu2_sad_thrsh;
+
     {
         WORD32 rows_above, rows_below, columns_left, columns_right;
 
diff --git a/encoder/ih264e_rate_control.c b/encoder/ih264e_rate_control.c
index 1da2f03..b81d916 100644
--- a/encoder/ih264e_rate_control.c
+++ b/encoder/ih264e_rate_control.c
@@ -198,7 +198,7 @@
 //    UWORD8  u1_is_mb_level_rc_on = 0;
     UWORD32 au4_peak_bit_rate[2] = {0,0};
     UWORD32 u4_min_bit_rate      = 0;
-    WORD32  i4_is_gop_closed     = 0;
+    WORD32  i4_is_gop_closed     = 1;
 //    WORD32  i4_use_est_intra_sad = 1;
     UWORD32 u4_src_ticks         = 0;
     UWORD32 u4_tgt_ticks         = 0;
diff --git a/encoder/ih264e_structs.h b/encoder/ih264e_structs.h
index fc61277..fdf0e0a 100644
--- a/encoder/ih264e_structs.h
+++ b/encoder/ih264e_structs.h
@@ -2623,9 +2623,9 @@
     inp_buf_t as_inp_list[MAX_NUM_BFRAMES];
 
     /**
-     * IDR flags for each input
+     * Flag to indicate if any IDR requests are pending
      */
-    WORD32 i4_idr_inp_list[MAX_NUM_BFRAMES];
+    WORD32 i4_pending_idr_flag;
 
     /*
     *Flag to indicate if we have recived the last input frame
diff --git a/encoder/ih264e_utils.c b/encoder/ih264e_utils.c
index b339143..455aa9e 100644
--- a/encoder/ih264e_utils.c
+++ b/encoder/ih264e_utils.c
@@ -206,6 +206,7 @@
                     && !ps_codec->i4_last_inp_buff_received)
     {
         ps_enc_buff->s_raw_buf.apv_bufs[0] = NULL;
+        ps_enc_buff->u4_is_last = ps_ive_ip->u4_is_last;
         return 0;
     }
 
@@ -223,7 +224,11 @@
                         ps_codec->s_rate_control.pps_time_stamp,
                         ps_codec->s_rate_control.pps_frame_time);
 
-        if (skip_src) return 1;
+        if (skip_src)
+        {
+            ps_enc_buff->u4_is_last = ps_ive_ip->u4_is_last;
+            return 1;
+        }
     }
 
     /***************************************************************************
@@ -260,9 +265,9 @@
 
         i4_force_i = (ps_codec->force_curr_frame_type == IV_I_FRAME);
 
-        ps_codec->i4_idr_inp_list[ps_codec->i4_pic_cnt % MAX_NUM_BFRAMES] = i4_force_idr;
+        ps_codec->i4_pending_idr_flag |= i4_force_idr;
 
-        if ((ps_codec->i4_frame_num > 0) && (i4_force_idr || i4_force_i))
+        if ((ps_codec->i4_pic_cnt > 0) && (i4_force_idr || i4_force_i))
         {
             irc_force_I_frame(ps_codec->s_rate_control.pps_rate_control_api);
         }
@@ -278,6 +283,7 @@
                     < (WORD32)(ps_codec->s_cfg.u4_num_bframes))
     {
         ps_enc_buff->s_raw_buf.apv_bufs[0] = NULL;
+        ps_enc_buff->u4_is_last = 0;
         return 0;
     }
 
@@ -306,12 +312,13 @@
             return 0;
     }
 
-    /* Set IDR if it has been requested or its the IDR interval */
-    ps_codec->pic_type = ps_codec->i4_idr_inp_list[u4_pic_id % MAX_NUM_BFRAMES] ?
+    /* Set IDR if it has been requested */
+    if (ps_codec->pic_type == PIC_I)
+    {
+        ps_codec->pic_type = ps_codec->i4_pending_idr_flag ?
                                     PIC_IDR : ps_codec->pic_type;
-    ps_codec->i4_idr_inp_list[u4_pic_id % MAX_NUM_BFRAMES] = 0;
-
-
+        ps_codec->i4_pending_idr_flag = 0;
+    }
 
     /* Get current frame Qp */
     u1_frame_qp = (UWORD8)irc_get_frame_level_qp(
@@ -347,6 +354,86 @@
     ps_enc_buff->pv_pic_info = ps_inp_buf->pv_pic_info;
     ps_enc_buff->u4_pic_info_type = ps_inp_buf->u4_pic_info_type;
 
+    /* Special case for encoding trailing B frames
+     *
+     * In encoding streams with B frames it may happen that we have a B frame
+     * at the end without a P/I frame after it. Hence when we are dequeing from
+     * the RC, it will return the P frame [next in display order but before in
+     * encoding order] first. Since the dequeue happens for an invalid frame we
+     * will get a frame with null buff and set u4_is_last. Hence lib with return
+     * last frame flag at this point and will stop encoding.
+     *
+     * Since for the last B frame, we does not have the forward ref frame
+     * it makes sense to force it into P.
+     *
+     * To solve this, in case the current frame is P and if the last frame flag
+     * is set, we need to see if there is and pending B frames. If there are any,
+     * we should just encode that picture as the current P frame and set
+     * that B frame as the last frame. Hence the encoder will terminate naturally
+     * once that B-frame is encoded after all the in between frames.
+     *
+     * Since we cannot touch RC stack directly, the option of actually swapping
+     * frames in RC is ruled out. We have to modify the as_inp_list to simulate
+     * such a behavior by RC. We can do that by
+     *  1) Search through as_inp_list to locate the largest u4_timestamp_low less
+     *     than current u4_timestamp_low. This will give us the last B frame before
+     *     the current P frame. Note that this will handle pre encode skip too since
+     *     queue happens after pre enc skip.
+     *  2) Swap the position in as_inp_list. Hence now the last B frame is
+     *     encoded as P frame. And the new last B frame will have u4_is_last
+     *     set so that encoder will end naturally once we reached that B frame
+     *     or any subsequent frame. Also the current GOP will have 1 less B frame
+     *     Since we are swapping, the poc will also be in-order.
+     *  3) In case we have an IPP stream, the result of our search will be an
+     *     I/P frame which is already encoded. Thus swap and encode will result
+     *     in encoding of duplicate frames. Hence to avoid this we will only
+     *     have this work around in case of u4_num_bframes > 0.
+     *
+     *     In case we have forced an I/IDR frame In between this P frame and
+     *     the last B frame -> This cannot happen as the current P frame is
+     *     supposed to have u4_is_last set. Thus forcing an I/ IDR after this
+     *     is illogical.
+     *
+     *     In cae if we have forced an I such that the frame just before last frame
+     *     in is I/P -> This case will never arise. Since we have a closed GOP now,
+     *     once we force an I, the gop gets reset, hence there will be a B between
+     *     I/P and I/P.
+     */
+    if (ps_enc_buff->u4_is_last && (ps_codec->pic_type == PIC_P)
+                    && ps_codec->s_cfg.u4_num_bframes && (ps_codec->i4_poc > 1))
+    {
+        UWORD32 u4_cntr, u4_lst_bframe;
+        inp_buf_t *ps_swap_buff, *ps_inp_list, *ps_cur_pic;
+
+        u4_cntr = (u4_pic_id + 1) % MAX_NUM_BFRAMES;
+        u4_lst_bframe = u4_pic_id ? ((u4_pic_id - 1) % MAX_NUM_BFRAMES) : (MAX_NUM_BFRAMES - 1);
+
+        ps_inp_list = &ps_codec->as_inp_list[0];
+        ps_cur_pic = &ps_inp_list[u4_pic_id % MAX_NUM_BFRAMES];
+
+        /* Now search the pic in most recent past to current frame */
+        for(; u4_cntr != (u4_pic_id % MAX_NUM_BFRAMES);
+                        u4_cntr = ((u4_cntr + 1) % MAX_NUM_BFRAMES))
+        {
+            if ( (ps_inp_list[u4_cntr].u4_timestamp_low  <= ps_cur_pic->u4_timestamp_low) &&
+                 (ps_inp_list[u4_cntr].u4_timestamp_high <= ps_cur_pic->u4_timestamp_high) &&
+                 (ps_inp_list[u4_cntr].u4_timestamp_low  >= ps_inp_list[u4_lst_bframe].u4_timestamp_low) &&
+                 (ps_inp_list[u4_cntr].u4_timestamp_high >= ps_inp_list[u4_lst_bframe].u4_timestamp_high))
+            {
+                u4_lst_bframe = u4_cntr;
+            }
+        }
+
+        ps_swap_buff = &(ps_codec->as_inp_list[u4_lst_bframe]);
+
+        /* copy the last B buffer to output */
+        *ps_enc_buff = *ps_swap_buff;
+
+        /* Store the current buf into the queue in place of last B buf */
+        *ps_swap_buff = *ps_inp_buf;
+
+    }
+
     if (ps_enc_buff->u4_is_last)
     {
         ps_codec->pic_type = PIC_NA;
@@ -1250,7 +1337,8 @@
                        ps_codec->s_cfg.u4_i_frm_interval,
                        ps_codec->s_cfg.u4_num_bframes + 1, au1_init_qp,
                        ps_codec->s_cfg.u4_num_bframes + 2 , au1_min_max_qp,
-                       ps_codec->s_cfg.u4_max_level);
+                       MAX(ps_codec->s_cfg.u4_max_level,
+                               (UWORD32)ih264e_get_min_level(ps_codec->s_cfg.u4_max_wd, ps_codec->s_cfg.u4_max_ht)));
     }
 
     /* recon stride */
@@ -1267,6 +1355,8 @@
     /* Init dependecy vars */
     ps_codec->i4_last_inp_buff_received = 0;
 
+    /* At codec start no IDR is pending */
+    ps_codec->i4_pending_idr_flag = 0;
 
     return IH264E_SUCCESS;
 }
diff --git a/encoder/ive2.h b/encoder/ive2.h
index 7a543bb..cbf7087 100644
--- a/encoder/ive2.h
+++ b/encoder/ive2.h
@@ -848,9 +848,6 @@
     /** Input height                                                    */
     UWORD32                                     u4_ht;
 
-    /** Input stride                                                    */
-    UWORD32                                     u4_strd;
-
     /** Lower 32bits of time stamp corresponding to input buffer,
      * from which this command takes effect                             */
     UWORD32                                 u4_timestamp_low;
diff --git a/test/decoder/main.c b/test/decoder/main.c
index 8c9e885..35454a4 100644
--- a/test/decoder/main.c
+++ b/test/decoder/main.c
@@ -1824,7 +1824,7 @@
     UWORD32 frm_cnt = 0;
     WORD32 total_bytes_comsumed;
     UWORD32 max_op_frm_ts;
-    UWORD32 u4_num_disp_bufs_with_dec;;
+    UWORD32 u4_num_disp_bufs_with_dec;
 
 #ifdef PROFILE_ENABLE
     UWORD32 u4_tot_cycles = 0;
diff --git a/test/encoder/main.c b/test/encoder/main.c
index 4ff71af..3510e2b 100644
--- a/test/encoder/main.c
+++ b/test/encoder/main.c
@@ -918,6 +918,7 @@
     ps_app_ctxt->u4_pic_info_size        = 0;
     ps_app_ctxt->u4_start_frm            = DEFAULT_START_FRM;
     ps_app_ctxt->u4_max_num_frms         = DEFAULT_NUM_FRMS;
+    ps_app_ctxt->avg_time                = 0;
     ps_app_ctxt->u4_total_bytes          = 0;
     ps_app_ctxt->u4_pics_cnt             = 0;
     ps_app_ctxt->e_inp_color_fmt         = DEFAULT_INP_COLOR_FMT;
@@ -1011,7 +1012,6 @@
 
     s_frame_dimensions_ip.s_ive_ip.u4_ht = ps_app_ctxt->u4_ht;
     s_frame_dimensions_ip.s_ive_ip.u4_wd = ps_app_ctxt->u4_wd;
-    s_frame_dimensions_ip.s_ive_ip.u4_strd = ps_app_ctxt->u4_strd;
 
     s_frame_dimensions_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high;
     s_frame_dimensions_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low;