Improved error resilience in decoder

Fixed buffer management for error cases
Fixed end of picture detection logic for multiple slice error cases
Fixed handling of incomplete frame, missing slices.

Change-Id: Iae447667e4d88869a8bf992180cacd77870b9877
diff --git a/decoder/ih264d_api.c b/decoder/ih264d_api.c
index 9367200..332e4ad 100644
--- a/decoder/ih264d_api.c
+++ b/decoder/ih264d_api.c
@@ -1492,7 +1492,6 @@
     ps_dec->u2_mbx = 0xffff;
     ps_dec->u2_mby = 0;
     ps_dec->u2_total_mbs_coded = 0;
-    ps_cur_slice->u1_end_of_frame_signal = 0;
 
     /* POC initializations */
     ps_prev_poc = &ps_dec->s_prev_pic_poc;
@@ -2850,8 +2849,9 @@
     ps_dec->u2_cur_slice_num = 0;
     ps_dec->cur_dec_mb_num = 0;
     ps_dec->cur_recon_mb_num = 0;
-    ps_dec->u4_first_slice_in_pic = 1;
+    ps_dec->u4_first_slice_in_pic = 2;
     ps_dec->u1_slice_header_done = 0;
+    ps_dec->u1_dangling_field = 0;
 
     ps_dec->u4_dec_thread_created = 0;
     ps_dec->u4_bs_deblk_thread_created = 0;
@@ -2905,7 +2905,6 @@
                 {
                     ps_dec->u2_total_mbs_coded =
                                     ps_dec->ps_cur_sps->u2_max_mb_addr + 1;
-                    ps_dec->ps_cur_slice->u1_end_of_frame_signal = 1;
                 }
 
                 /* close deblock thread if it is not closed yet*/
@@ -3020,16 +3019,39 @@
             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))
             {
                 /*dont consume the SPS*/
                 ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
                 return IV_FAIL;
             }
-            if(ret == ERROR_IN_LAST_SLICE_OF_PIC)
+
+            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;
             }
+
+            if((ret == ERROR_INCOMPLETE_FRAME) || (ret == ERROR_DANGLING_FIELD_IN_PIC))
+            {
+                ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
+                api_ret_value = IV_FAIL;
+                break;
+            }
+
+            if(ret == ERROR_IN_LAST_SLICE_OF_PIC)
+            {
+                api_ret_value = IV_FAIL;
+                break;
+            }
+
         }
 
         if(ps_dec->u4_return_to_app)
@@ -3070,11 +3092,24 @@
     {
         // last slice - missing/corruption
         WORD32 num_mb_skipped;
+        WORD32 prev_slice_err;
         pocstruct_t temp_poc;
 
         num_mb_skipped = (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
                             - ps_dec->u2_total_mbs_coded;
-        ih264d_mark_err_slice_skip(ps_dec, num_mb_skipped, ps_dec->u1_nal_unit_type == IDR_SLICE_NAL,&temp_poc,3);
+
+        if(ps_dec->u4_first_slice_in_pic)
+            prev_slice_err = 1;
+        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,
+                                   &temp_poc, prev_slice_err);
+
+        if((ret == ERROR_UNAVAIL_PICBUF_T) || (ret == ERROR_UNAVAIL_MVBUF_T))
+        {
+            return IV_FAIL;
+        }
     }
 
 
@@ -3172,19 +3207,6 @@
          * For field pictures, set the bottom and top picture decoded u4_flag correctly.
          */
 
-        if(ps_dec->u4_pic_buf_got == 0)
-        {
-            ih264d_fill_output_struct_from_context(ps_dec, ps_dec_op);
-
-            ps_dec_op->u4_frame_decoded_flag = 0;
-            /* close deblock thread if it is not closed yet*/
-            if(ps_dec->u4_num_cores == 3)
-            {
-                ih264d_signal_bs_deblk_thread(ps_dec);
-            }
-            return (IV_FAIL);
-        }
-
         if(ps_dec->ps_cur_slice->u1_field_pic_flag)
         {
             if(1 == ps_dec->ps_cur_slice->u1_bottom_field_flag)
@@ -3197,10 +3219,19 @@
             }
         }
 
-        /* Calling Function to deblock Picture and Display */
-        ret = ih264d_deblock_display(ps_dec);
-        if(ret != 0)
-            return IV_FAIL;
+        /* if new frame in not found (if we are still getting slices from previous frame)
+         * ih264d_deblock_display is not called. Such frames will not be added to reference /display
+         */
+        if((ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC) == 0)
+        {
+            /* Calling Function to deblock Picture and Display */
+            ret = ih264d_deblock_display(ps_dec);
+            if(ret != 0)
+            {
+                return IV_FAIL;
+            }
+        }
+
 
         /*set to complete ,as we dont support partial frame decode*/
         if(ps_dec->i4_header_decoded == 3)
diff --git a/decoder/ih264d_error_handler.h b/decoder/ih264d_error_handler.h
index 1ff5c7d..5b1bc84 100644
--- a/decoder/ih264d_error_handler.h
+++ b/decoder/ih264d_error_handler.h
@@ -110,14 +110,18 @@
     ERROR_LEVEL_UNSUPPORTED = 0x90,
     ERROR_START_CODE_NOT_FOUND = 0x91,
     ERROR_PIC_NUM_IS_REPEATED = 0x92,
-    ERROR_IN_LAST_SLICE_OF_PIC = 0x93
+    ERROR_IN_LAST_SLICE_OF_PIC = 0x93,
+    ERROR_NEW_FRAME_EXPECTED = 0x94,
+    ERROR_INCOMPLETE_FRAME = 0x95
 
 } h264_decoder_error_code_t;
 
 WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec,
                                   WORD32 num_mb_skip,
                                   UWORD8 u1_is_idr_slice,
+                                  UWORD16 u2_frame_num,
                                   pocstruct_t *ps_cur_poc,
                                   WORD32 prev_slice_err);
 
+void ih264d_err_pic_dispbuf_mgr(dec_struct_t *ps_dec);
 #endif /* _IH264D_ERROR_HANDLER_H_ */
diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c
index 37684db..743b573 100644
--- a/decoder/ih264d_parse_headers.c
+++ b/decoder/ih264d_parse_headers.c
@@ -1096,8 +1096,17 @@
                                                             == IDR_SLICE_NAL),
                                             u1_nal_ref_idc, ps_dec);
 
+                            if((ps_dec->u4_first_slice_in_pic != 0)&&
+                                ((ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC) == 0))
+                            {
+                                /*  if the first slice header was not valid set to 1 */
+                                ps_dec->u4_first_slice_in_pic = 1;
+                            }
+
                             if(i_status != OK)
+                            {
                                 return i_status;
+                            }
                         }
                         else
                         {
diff --git a/decoder/ih264d_parse_pslice.c b/decoder/ih264d_parse_pslice.c
index 02110eb..d56f44e 100644
--- a/decoder/ih264d_parse_pslice.c
+++ b/decoder/ih264d_parse_pslice.c
@@ -1432,6 +1432,7 @@
 WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec,
                                 WORD32 num_mb_skip,
                                 UWORD8 u1_is_idr_slice,
+                                UWORD16 u2_frame_num,
                                 pocstruct_t *ps_cur_poc,
                                 WORD32 prev_slice_err)
 {
@@ -1457,14 +1458,20 @@
     UWORD16 u2_total_mbs_coded;
     UWORD32 u1_mbaff = ps_slice->u1_mbaff_frame_flag;
     parse_part_params_t *ps_part_info;
+    WORD32 ret;
+
+
+    if(ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC)
+    {
+        ih264d_err_pic_dispbuf_mgr(ps_dec);
+        return 0;
+    }
 
     if(prev_slice_err == 1)
     {
-        // first slice - missing/header corruption
-        if(u1_is_idr_slice)
-            ps_dec->ps_cur_slice->u2_frame_num = 0;
-        else
-            ps_dec->ps_cur_slice->u2_frame_num++;
+        /* first slice - missing/header corruption */
+        ps_dec->ps_cur_slice->u2_frame_num = u2_frame_num;
+
 
         if(!ps_dec->u1_first_slice_in_stream)
         {
@@ -1482,7 +1489,6 @@
             ps_dec->pf_mvpred = ih264d_mvpred_nonmbaff;
             ps_dec->p_form_mb_part_info = ih264d_form_mb_part_info_bp;
             ps_dec->p_motion_compensate = ih264d_motion_compensate_bp;
-            ps_dec->ps_pps->ps_sps = ps_dec->ps_cur_sps;
 
             if(ps_dec->ps_cur_pic != NULL)
                 poc = ps_dec->ps_cur_pic->i4_poc + 2;
@@ -1491,10 +1497,16 @@
             for(i = 0; i < MAX_NUM_PIC_PARAMS; i++)
                    if(ps_dec->ps_pps[i].u1_is_valid == TRUE)
                        j = i;
+            {
+                ret = ih264d_start_of_pic(ps_dec, poc, ps_cur_poc,
+                        ps_dec->ps_cur_slice->u2_frame_num,
+                        &ps_dec->ps_pps[j]);
 
-            ih264d_start_of_pic(ps_dec, poc, ps_cur_poc,
-                    ps_dec->ps_cur_slice->u2_frame_num,
-                    &ps_dec->ps_pps[j]);
+                if(ret != OK)
+                {
+                    return ret;
+                }
+            }
 
             ps_dec->ps_ref_pic_buf_lx[0][0]->u1_pic_buf_id = 0;
 
@@ -1617,7 +1629,7 @@
                     >= ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
             {
                 ps_dec->u1_pic_decode_done = 1;
-                return 1;
+                return 0;
             }
 
             // Inserting new slice
@@ -1685,8 +1697,6 @@
     /******************************************************/
     /* Parsing / decoding the slice                       */
     /******************************************************/
-    ps_dec->u4_first_slice_in_pic = 0;
-    ps_dec->u1_first_slice_in_stream = 0;
     ps_dec->u1_slice_header_done = 2;
     ps_dec->u1_qp = ps_slice->u1_slice_qp;
     ih264d_update_qp(ps_dec, 0);
@@ -1823,6 +1833,11 @@
     H264_DEC_DEBUG_PRINT("Mbs in slice: %d\n", ps_dec->ps_cur_slice->u4_mbs_in_slice);
 
     ps_dec->u2_cur_slice_num++;
+
+    /* incremented here only if first slice is inserted */
+    if(ps_dec->u4_first_slice_in_pic != 0)
+        ps_dec->ps_parse_cur_slice++;
+
     ps_dec->i2_prev_slice_mbx = ps_dec->u2_mbx;
     ps_dec->i2_prev_slice_mby = ps_dec->u2_mby;
 
@@ -1830,7 +1845,6 @@
             >= ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
     {
         ps_dec->u1_pic_decode_done = 1;
-        return 1;
     }
 
     return 0;
diff --git a/decoder/ih264d_parse_slice.c b/decoder/ih264d_parse_slice.c
index b3a7632..73073c7 100644
--- a/decoder/ih264d_parse_slice.c
+++ b/decoder/ih264d_parse_slice.c
@@ -849,13 +849,6 @@
                                  ps_cur_slice->u1_field_pic_flag,
                                  ps_dec->u1_second_field);
         }
-        {
-
-            if(!ps_cur_slice->u1_end_of_frame_signal)
-            {
-                ps_cur_slice->u1_end_of_frame_signal = 1;
-            }
-        }
 
         if(!ps_cur_slice->u1_field_pic_flag
                         || ((TOP_FIELD_ONLY | BOT_FIELD_ONLY)
@@ -961,7 +954,6 @@
     dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice;
     WORD32 ret;
 
-    ps_dec->u4_first_slice_in_pic = 1;
     ps_dec->u1_first_pb_nal_in_pic = 1;
     ps_dec->u2_mbx = 0xffff;
     ps_dec->u2_mby = 0;
@@ -969,9 +961,8 @@
         dec_err_status_t * ps_err = ps_dec->ps_dec_err_status;
         if(ps_err->u1_err_flag & REJECT_CUR_PIC)
         {
-            ps_err->u1_err_flag ^= REJECT_CUR_PIC;
             ih264d_err_pic_dispbuf_mgr(ps_dec);
-            return OK;
+            return ERROR_NEW_FRAME_EXPECTED;
         }
     }
 
@@ -1016,10 +1007,8 @@
             ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field;
         }
     }
-    if(!ps_cur_slice->u1_end_of_frame_signal)
-    {
-        return ERROR_END_OF_FRAME_EXPECTED_T;
-    } H264_MUTEX_UNLOCK(&ps_dec->process_disp_mutex);
+
+    H264_MUTEX_UNLOCK(&ps_dec->process_disp_mutex);
 
     return OK;
 }
@@ -1294,6 +1283,22 @@
                                             u1_field_pic_flag,
                                             u1_bottom_field_flag);
 
+        /* since we support only Full frame decode, every new process should
+         * process a new pic
+         */
+        if((ps_dec->u4_first_slice_in_pic == 2) && (i1_is_end_of_poc == 0))
+        {
+            /* if it is the first slice is process call ,it should be a new frame. If it is not
+             * reject current pic and dont add it to dpb
+             */
+            ps_dec->ps_dec_err_status->u1_err_flag |= REJECT_CUR_PIC;
+            i1_is_end_of_poc = 1;
+        }
+        else
+        {
+            /* reset REJECT_CUR_PIC */
+            ps_dec->ps_dec_err_status->u1_err_flag &= MASK_REJECT_CUR_PIC;
+        }
     }
 
     /*--------------------------------------------------------------------*/
@@ -1310,6 +1315,7 @@
                    && ps_dec->u1_top_bottom_decoded
                        != (TOP_FIELD_ONLY | BOT_FIELD_ONLY))
         {
+            ps_dec->u1_dangling_field = 1;
             if(ps_dec->u4_first_slice_in_pic)
             {
                 // first slice - dangling field
@@ -1332,7 +1338,7 @@
 
             u1_is_idr_slice = ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL;
         }
-        else if(ps_dec->u4_first_slice_in_pic)
+        else if(ps_dec->u4_first_slice_in_pic == 2)
         {
             if(u2_first_mb_in_slice > 0)
             {
@@ -1355,10 +1361,25 @@
         }
         else
         {
-            // last slice - missing/corruption
-            prev_slice_err = 2;
-            num_mb_skipped = (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
-                    - ps_dec->u2_total_mbs_coded;
+
+            if(ps_dec->u4_first_slice_in_pic)
+            {
+                /* if valid slice header is not decoded do start of pic processing
+                 * since in the current process call, frame num is not updated in the slice structure yet
+                 * ih264d_is_end_of_pic is checked with valid frame num of previous process call,
+                 * although i1_is_end_of_poc is set there could be  more slices in the frame,
+                 * so conceal only till cur slice */
+                prev_slice_err = 1;
+                num_mb_skipped = u2_first_mb_in_slice << u1_mbaff;
+            }
+            else
+            {
+                /* since i1_is_end_of_poc is set ,means new frame num is encountered. so conceal the current frame
+                 * completely */
+                prev_slice_err = 2;
+                num_mb_skipped = (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
+                        - ps_dec->u2_total_mbs_coded;
+            }
             ps_cur_poc = &s_tmp_poc;
         }
     }
@@ -1380,13 +1401,40 @@
 
     if(prev_slice_err)
     {
-        end_of_frame = ih264d_mark_err_slice_skip(ps_dec,num_mb_skipped,u1_is_idr_slice,ps_cur_poc,prev_slice_err);
+        ret = ih264d_mark_err_slice_skip(ps_dec, num_mb_skipped, u1_is_idr_slice, u2_frame_num, ps_cur_poc, prev_slice_err);
 
-        if(end_of_frame)
+        if(ps_dec->u1_dangling_field == 1)
         {
-            // return if all MBs in frame are parsed
+            ps_dec->u1_second_field = 1 - ps_dec->u1_second_field;
+            ps_cur_slice->u1_bottom_field_flag = u1_bottom_field_flag;
+            ps_dec->u2_prv_frame_num = u2_frame_num;
+            ps_dec->u1_first_slice_in_stream = 0;
+            return ERROR_DANGLING_FIELD_IN_PIC;
+        }
+
+        if(prev_slice_err == 2)
+        {
+            ps_dec->u1_first_slice_in_stream = 0;
+            return ERROR_INCOMPLETE_FRAME;
+        }
+
+        if(ps_dec->u2_total_mbs_coded
+                >= ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
+        {
+            /* return if all MBs in frame are parsed*/
+            ps_dec->u1_first_slice_in_stream = 0;
             return ERROR_IN_LAST_SLICE_OF_PIC;
         }
+
+        if(ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC)
+        {
+            ih264d_err_pic_dispbuf_mgr(ps_dec);
+            return ERROR_NEW_FRAME_EXPECTED;
+        }
+
+        if(ret != OK)
+            return ret;
+
         i1_is_end_of_poc = 0;
     }
 
@@ -1401,13 +1449,6 @@
     if(!ps_dec->u1_first_slice_in_stream)
     {
         UWORD8 uc_mbs_exceed = 0;
-        /*since we support only Full frame decode, every new process should
-         * process a new pic
-         */
-        if(ps_dec->u4_first_slice_in_pic == 1)
-        {
-            i1_is_end_of_poc = 1;
-        }
 
         if(ps_dec->u2_total_mbs_coded
                         == (ps_dec->ps_cur_sps->u2_max_mb_addr + 1))
@@ -1446,45 +1487,8 @@
         }
     }
 
-    ps_cur_slice->u1_end_of_frame_signal = 0;
     if(u1_field_pic_flag)
     {
-        /*
-         * Check if the frame number has changed.
-         */
-        H264_DEC_DEBUG_PRINT(
-                        "u2_frame_num: %d ps_dec->u2_prv_frame_num: %d ps_dec->u1_top_bottom_decoded: %d\n",
-                        u2_frame_num, ps_dec->u2_prv_frame_num,
-                        ps_dec->u1_top_bottom_decoded);
-        if((u2_frame_num != ps_dec->u2_prv_frame_num)
-                        && (0 != ps_dec->u1_top_bottom_decoded))
-        {
-            if((TOP_FIELD_ONLY | BOT_FIELD_ONLY)
-                            != ps_dec->u1_top_bottom_decoded)
-            {
-                H264_DEC_DEBUG_PRINT("Dangling Field, toggling second field\n");
-                ps_dec->u1_second_field = 1 - ps_dec->u1_second_field;
-                ps_dec->u1_dangling_field = 1;
-                /*
-                 * Updating the u1_bottom_field_flag since its used in the concealment function.
-                 */
-                ps_cur_slice->u1_bottom_field_flag = u1_bottom_field_flag;
-                ps_dec->u2_prv_frame_num = u2_frame_num;
-
-                ret = ih264d_deblock_display(ps_dec);
-                if(ret != OK)
-                    return ret;
-
-                /*
-                 * The bytes consumed will be handled by the
-                 * video_decode function after the error is handled.
-                 */
-                return ERROR_DANGLING_FIELD_IN_PIC;
-
-            }
-
-        }
-
         ps_dec->u2_prv_frame_num = u2_frame_num;
     }
 
@@ -1513,7 +1517,7 @@
         ps_dec->ps_cur_pic->i4_poc = i4_temp_poc;
         ps_dec->ps_cur_pic->i4_avg_poc = i4_temp_poc;
     }
-    if(ps_dec->u4_first_slice_in_pic)
+    if(ps_dec->u4_first_slice_in_pic == 2)
     {
         ret = ih264d_decode_pic_order_cnt(u1_is_idr_slice, u2_frame_num,
                                           &ps_dec->s_prev_pic_poc,
@@ -1581,11 +1585,14 @@
             ps_dec->pf_mvpred = ih264d_mvpred_nonmbaff;
     }
 
-    if(ps_dec->u4_first_slice_in_pic)
+    if(ps_dec->u4_first_slice_in_pic == 2)
     {
-        ret = ih264d_start_of_pic(ps_dec, i4_poc, &s_tmp_poc, u2_frame_num, ps_pps);
-        if(ret != OK)
-            return ret;
+        if(u2_first_mb_in_slice == 0)
+        {
+            ret = ih264d_start_of_pic(ps_dec, i4_poc, &s_tmp_poc, u2_frame_num, ps_pps);
+            if(ret != OK)
+                return ret;
+        }
 
         ps_dec->u4_output_present = 0;
 
@@ -1898,7 +1905,8 @@
 
     if(ps_dec->u1_slice_header_done)
     {
-        /*set to zero to indicate a valid slice has been decoded*/
+        /* set to zero to indicate a valid slice has been decoded */
+        /* first slice header successfully decoded */
         ps_dec->u4_first_slice_in_pic = 0;
         ps_dec->u1_first_slice_in_stream = 0;
     }
diff --git a/decoder/ih264d_process_intra_mb.c b/decoder/ih264d_process_intra_mb.c
index d2da005..72ad9c8 100644
--- a/decoder/ih264d_process_intra_mb.c
+++ b/decoder/ih264d_process_intra_mb.c
@@ -924,7 +924,10 @@
                                             (u1_intrapred_mode ^ 2);
 
             if((u1_err_code & u1_packed_modes) ^ u1_err_code)
+            {
+                u1_intrapred_mode = 0;
                 ps_dec->i4_error_code = ERROR_INTRAPRED;
+            }
         }
         {
             UWORD8 au1_ngbr_pels[33];
@@ -1242,9 +1245,11 @@
                 {
                     UWORD8 u1_err_code = pu1_intra_err_codes[i1_intra_pred];
 
-                    /*if((u1_err_code & u1_packed_modes) ^ u1_err_code)
+                    if((u1_err_code & u1_packed_modes) ^ u1_err_code)
                      {
-                     }*/
+                        i1_intra_pred = 0;
+                        ps_dec->i4_error_code = ERROR_INTRAPRED;
+                     }
 
                 }
             }
@@ -1649,7 +1654,10 @@
                     UWORD8 u1_err_code = pu1_intra_err_codes[i1_intra_pred];
 
                     if((u1_err_code & u1_packed_modes) ^ u1_err_code)
+                    {
+                        i1_intra_pred = 0;
                         ps_dec->i4_error_code = ERROR_INTRAPRED;
+                    }
                 }
             }
 
@@ -1761,7 +1769,10 @@
                                             u1_intra_chrom_pred_mode :
                                             (u1_intra_chrom_pred_mode ^ 2);
             if((u1_err_code & u1_packed_modes) ^ u1_err_code)
+            {
+                u1_intra_chrom_pred_mode = 0;
                 ps_dec->i4_error_code = ERROR_INTRAPRED;
+            }
         }
 
         /* CHANGED CODE */
diff --git a/decoder/ih264d_structs.h b/decoder/ih264d_structs.h
index 4e3f0bb..062747b 100644
--- a/decoder/ih264d_structs.h
+++ b/decoder/ih264d_structs.h
@@ -524,7 +524,6 @@
      unsigned. LSB byte : weight and MSB byte: u4_ofst */
     UWORD32 u4_wt_ofst_lx[2][MAX_REF_BUFS][3];
     void * pv_codec_handle; /* For Error Handling */
-    UWORD8 u1_end_of_frame_signal;
 
     /*  This is used when reordering is done in Forward or    */
     /*  backward lists. This is because reordering can point  */
@@ -607,6 +606,9 @@
 #define REJECT_CUR_PIC    (0x01)
 #define REJECT_PB_PICS    (0x02)
 
+#define MASK_REJECT_CUR_PIC (0xFE)
+#define MASK_REJECT_PB_PICS (0xFD)
+
 #define PIC_TYPE_UNKNOWN  (0xFF)
 #define PIC_TYPE_I        (0x00)
 #define SYNC_FRM_DEFAULT  (0xFFFFFFFF)
@@ -1351,6 +1353,7 @@
     UWORD32 u4_cur_slice_decode_done;
     UWORD32 u4_extra_mem_used;
 
+    /* 2 first slice not parsed , 1 :first slice parsed , 0 :first valid slice header parsed*/
     UWORD32 u4_first_slice_in_pic;
     UWORD32 u4_num_cores;
     IVD_ARCH_T e_processor_arch;
diff --git a/test/decoder/main.c b/test/decoder/main.c
index 921c240..937515e 100644
--- a/test/decoder/main.c
+++ b/test/decoder/main.c
@@ -1827,6 +1827,7 @@
     UWORD32 frm_cnt = 0;
     WORD32 total_bytes_comsumed;
     UWORD32 max_op_frm_ts;
+    UWORD32 u4_num_disp_bufs_with_dec;;
 
 #ifdef PROFILE_ENABLE
     UWORD32 u4_tot_cycles = 0;
@@ -2313,6 +2314,7 @@
 
                 ivd_ctl_getbufinfo_ip_t s_ctl_ip;
                 ivd_ctl_getbufinfo_op_t s_ctl_op;
+                WORD32 outlen = 0;
 
                 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
                 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO;
@@ -2342,7 +2344,6 @@
                 /* Or if shared and output is 420P */
                 if((0 == s_app_ctx.u4_share_disp_buf) || (IV_YUV_420P == s_app_ctx.e_output_chroma_format))
                 {
-                    UWORD32 outlen;
                     ps_out_buf->u4_min_out_buf_size[0] =
                                     s_ctl_op.u4_min_out_buf_size[0];
                     ps_out_buf->u4_min_out_buf_size[1] =
@@ -2377,6 +2378,56 @@
                     ps_out_buf->u4_num_bufs = s_ctl_op.u4_min_num_out_bufs;
                 }
 
+#ifdef APP_EXTRA_BUFS
+                s_app_ctx.disp_delay = EXTRA_DISP_BUFFERS;
+                s_ctl_op.u4_num_disp_bufs += EXTRA_DISP_BUFFERS;
+#endif
+
+                /*****************************************************************************/
+                /*   API Call: Allocate display buffers for display buffer shared case       */
+                /*****************************************************************************/
+
+                for(i = 0; i < s_ctl_op.u4_num_disp_bufs; i++)
+                {
+
+                    s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[0] =
+                                    s_ctl_op.u4_min_out_buf_size[0];
+                    s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[1] =
+                                    s_ctl_op.u4_min_out_buf_size[1];
+                    s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[2] =
+                                    s_ctl_op.u4_min_out_buf_size[2];
+
+                    outlen = s_ctl_op.u4_min_out_buf_size[0];
+                    if(s_ctl_op.u4_min_num_out_bufs > 1)
+                        outlen += s_ctl_op.u4_min_out_buf_size[1];
+
+                    if(s_ctl_op.u4_min_num_out_bufs > 2)
+                        outlen += s_ctl_op.u4_min_out_buf_size[2];
+
+                    s_app_ctx.s_disp_buffers[i].pu1_bufs[0] = (UWORD8 *)malloc(outlen);
+
+                    if(s_app_ctx.s_disp_buffers[i].pu1_bufs[0] == NULL)
+                    {
+                        sprintf(ac_error_str,
+                                "\nAllocation failure for output buffer of i4_size %d",
+                                outlen);
+                        codec_exit(ac_error_str);
+                    }
+
+                    if(s_ctl_op.u4_min_num_out_bufs > 1)
+                        s_app_ctx.s_disp_buffers[i].pu1_bufs[1] =
+                                        s_app_ctx.s_disp_buffers[i].pu1_bufs[0]
+                                                        + (s_ctl_op.u4_min_out_buf_size[0]);
+
+                    if(s_ctl_op.u4_min_num_out_bufs > 2)
+                        s_app_ctx.s_disp_buffers[i].pu1_bufs[2] =
+                                        s_app_ctx.s_disp_buffers[i].pu1_bufs[1]
+                                                        + (s_ctl_op.u4_min_out_buf_size[1]);
+
+                    s_app_ctx.s_disp_buffers[i].u4_num_bufs =
+                                    s_ctl_op.u4_min_num_out_bufs;
+                }
+                s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs;
             }
         }
 
@@ -2556,73 +2607,6 @@
     /*************************************************************************/
     //if(1 == s_app_ctx.u4_share_disp_buf)
     {
-        ivd_ctl_getbufinfo_ip_t s_ctl_ip;
-        ivd_ctl_getbufinfo_op_t s_ctl_op;
-        WORD32 outlen = 0;
-
-        s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
-        s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO;
-        s_ctl_ip.u4_size = sizeof(ivd_ctl_getbufinfo_ip_t);
-        s_ctl_op.u4_size = sizeof(ivd_ctl_getbufinfo_op_t);
-        ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip,
-                                   (void *)&s_ctl_op);
-        if(ret != IV_SUCCESS)
-        {
-            sprintf(ac_error_str, "Error in Get Buf Info %x", s_ctl_op.u4_error_code);
-            codec_exit(ac_error_str);
-        }
-
-#ifdef APP_EXTRA_BUFS
-        s_app_ctx.disp_delay = EXTRA_DISP_BUFFERS;
-        s_ctl_op.u4_num_disp_bufs += EXTRA_DISP_BUFFERS;
-#endif
-
-        /*****************************************************************************/
-        /*   API Call: Allocate display buffers for display buffer shared case       */
-        /*****************************************************************************/
-
-        for(i = 0; i < s_ctl_op.u4_num_disp_bufs; i++)
-        {
-
-            s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[0] =
-                            s_ctl_op.u4_min_out_buf_size[0];
-            s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[1] =
-                            s_ctl_op.u4_min_out_buf_size[1];
-            s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[2] =
-                            s_ctl_op.u4_min_out_buf_size[2];
-
-            outlen = s_ctl_op.u4_min_out_buf_size[0];
-            if(s_ctl_op.u4_min_num_out_bufs > 1)
-                outlen += s_ctl_op.u4_min_out_buf_size[1];
-
-            if(s_ctl_op.u4_min_num_out_bufs > 2)
-                outlen += s_ctl_op.u4_min_out_buf_size[2];
-
-            s_app_ctx.s_disp_buffers[i].pu1_bufs[0] = (UWORD8 *)malloc(outlen);
-
-            if(s_app_ctx.s_disp_buffers[i].pu1_bufs[0] == NULL)
-            {
-                sprintf(ac_error_str,
-                        "\nAllocation failure for output buffer of i4_size %d",
-                        outlen);
-                codec_exit(ac_error_str);
-            }
-
-            if(s_ctl_op.u4_min_num_out_bufs > 1)
-                s_app_ctx.s_disp_buffers[i].pu1_bufs[1] =
-                                s_app_ctx.s_disp_buffers[i].pu1_bufs[0]
-                                                + (s_ctl_op.u4_min_out_buf_size[0]);
-
-            if(s_ctl_op.u4_min_num_out_bufs > 2)
-                s_app_ctx.s_disp_buffers[i].pu1_bufs[2] =
-                                s_app_ctx.s_disp_buffers[i].pu1_bufs[1]
-                                                + (s_ctl_op.u4_min_out_buf_size[1]);
-
-            s_app_ctx.s_disp_buffers[i].u4_num_bufs =
-                            s_ctl_op.u4_min_num_out_bufs;
-        }
-        s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs;
-
         /*****************************************************************************/
         /*   API Call: Send the allocated display buffers to codec                   */
         /*****************************************************************************/
@@ -2638,7 +2622,7 @@
 
             memcpy(&(s_set_display_frame_ip.s_disp_buffer),
                    &(s_app_ctx.s_disp_buffers),
-                   s_ctl_op.u4_num_disp_bufs * sizeof(ivd_out_bufdesc_t));
+                   s_app_ctx.num_disp_buf * sizeof(ivd_out_bufdesc_t));
 
             ret = ivd_api_function((iv_obj_t *)codec_obj,
                                        (void *)&s_set_display_frame_ip,
@@ -2732,7 +2716,17 @@
 #ifndef PRINT_PICSIZE
     get_version(codec_obj);
 #endif
-    max_op_frm_ts = (s_app_ctx.u4_max_frm_ts > 0)? (s_app_ctx.u4_max_frm_ts + s_app_ctx.disp_delay): 0xffffffff;
+
+
+    max_op_frm_ts = s_app_ctx.u4_max_frm_ts + s_app_ctx.disp_delay;
+
+    if(max_op_frm_ts <  s_app_ctx.disp_delay)
+        max_op_frm_ts = 0xffffffff;/* clip as overflow has occured*/
+
+    max_op_frm_ts = (s_app_ctx.u4_max_frm_ts > 0)? (max_op_frm_ts): 0xffffffff;
+
+    u4_num_disp_bufs_with_dec = 0;
+
     while(u4_op_frm_ts < max_op_frm_ts)
     {
 
@@ -2759,9 +2753,10 @@
 
         }
 #endif
-        if(u4_ip_frm_ts < s_app_ctx.num_disp_buf)
+        if(u4_num_disp_bufs_with_dec < s_app_ctx.num_disp_buf)
         {
-            release_disp_frame(codec_obj, u4_ip_frm_ts);
+            release_disp_frame(codec_obj, u4_num_disp_bufs_with_dec);
+            u4_num_disp_bufs_with_dec ++;
         }
 
 
@@ -2991,6 +2986,9 @@
                     sprintf(ac_error_str, "Error in Reset");
                     codec_exit(ac_error_str);
                 }
+
+                /*when reset all buffers are released by lib*/
+                u4_num_disp_bufs_with_dec = 0;
                 /*************************************************************************/
                 /* set num of cores                                                      */
                 /*************************************************************************/