Merge cherrypicks of [2310999, 2310925, 2310891, 2311000, 2310892, 2310858, 2310986, 2310963, 2311043, 2310928, 2311044, 2310990, 2311022, 2311023, 2310917, 2310994, 2311024, 2311045, 2310967, 2310995, 2311003, 2311059, 2311025, 2311060, 2310953, 2311061, 2311004, 2311046, 2311005, 2311047, 2311006, 2311079, 2310954, 2311026, 2310896, 2310898, 2310997, 2311062, 2310955, 2311029, 2310998, 2311080, 2311119, 2311030, 2310933, 2311140, 2311063, 2310934, 2311049, 2311050, 2311084, 2311031, 2311145, 2311164] into nyc-mr2-security-c-release

Change-Id: I2667298c3a8e61dc00165b1f8e39fc2662652667
diff --git a/decoder/impeg2d_dec_hdr.c b/decoder/impeg2d_dec_hdr.c
index 1d5bcee..cd6c48f 100644
--- a/decoder/impeg2d_dec_hdr.c
+++ b/decoder/impeg2d_dec_hdr.c
@@ -1732,6 +1732,15 @@
             if(u4_start_code_found == 0)
             {
                 impeg2d_next_start_code(ps_dec);
+                /* In case a dec_pic_data call has not been made, the number of
+                 * bytes consumed in the previous header decode has to be
+                 * consumed. Not consuming it will result in zero bytes consumed
+                 * loops in case there are multiple headers and the second
+                 * or a future header has a resolution change/other error where
+                 * the bytes of the last header are not consumed.
+                 */
+                ps_dec->i4_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
+                ps_dec->i4_bytes_consumed -= ((size_t)ps_dec->s_bit_stream.pv_bs_buf & 3);
             }
         }
         if((u4_start_code_found == 0) && (ps_dec->s_bit_stream.u4_offset > ps_dec->s_bit_stream.u4_max_offset))
@@ -1798,7 +1807,18 @@
                 FLUSH_BITS(ps_dec->s_bit_stream.u4_offset, ps_dec->s_bit_stream.u4_buf, ps_dec->s_bit_stream.u4_buf_nxt, 8, ps_dec->s_bit_stream.pu4_buf_aligned);
             }
             impeg2d_next_start_code(ps_dec);
-
+            if (0 == u4_start_code_found)
+            {
+                /* In case a dec_pic_data call has not been made, the number of
+                 * bytes consumed in the previous header decode has to be
+                 * consumed. Not consuming it will result in zero bytes consumed
+                 * loops in case there are multiple headers and the second
+                 * or a future header has a resolution change/other error where
+                 * the bytes of the last header are not consumed.
+                 */
+                ps_dec->i4_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
+                ps_dec->i4_bytes_consumed -= ((size_t)ps_dec->s_bit_stream.pv_bs_buf & 3);
+            }
         }
         if((u4_start_code_found == 0) && (ps_dec->s_bit_stream.u4_offset > ps_dec->s_bit_stream.u4_max_offset))
         {
diff --git a/decoder/impeg2d_decoder.c b/decoder/impeg2d_decoder.c
index e9b31a0..fa88bb5 100644
--- a/decoder/impeg2d_decoder.c
+++ b/decoder/impeg2d_decoder.c
@@ -185,6 +185,8 @@
 
     ps_dec = (dec_state_t *)pv_dec;
     ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
+    ps_dec->i4_bytes_consumed = 0;
+    ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
 
     IMPEG2D_FRM_NUM_SET();
 
@@ -209,7 +211,7 @@
 
             if ((IMPEG2D_ERROR_CODES_T) IVD_RES_CHANGED == e_error)
             {
-                ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
+                ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
                 ps_dec->u2_header_done = 0;
             }
             else if (IMPEG2D_UNSUPPORTED_DIMENSIONS == e_error)
@@ -222,8 +224,18 @@
             }
             else
             {
-                if(ps_dec->i4_num_cores > 1)
+                if(ps_dec->i4_num_cores > 1 && 0 != ps_dec->i4_bytes_consumed)
+                {
+                    /* If the number of bytes consumed has been updated by
+                     * get_slice_pos function, then use that. Else, the bytes consumed is
+                     * calculated from the offset. The bytes consumed for multi-thread runs
+                     * is updated only into ps_dec->i4_bytes_consumed if the get_slice_pos
+                     * function has been called. If that function has not run, then we have
+                     * encountered an error but still have to consume the bytes in header
+                     * decode, etc.
+                     */
                     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
+                }
                 else
                 {
                     ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
@@ -253,8 +265,18 @@
     /**************************************************************************/
     ps_op->s_ivd_video_decode_op_t.u4_error_code  = IV_SUCCESS;
 
-    if(ps_dec->i4_num_cores > 1)
+    if(ps_dec->i4_num_cores > 1 && 0 != ps_dec->i4_bytes_consumed)
+    {
+        /* If the number of bytes consumed has been updated by
+         * get_slice_pos function, then use that. Else, the bytes consumed is
+         * calculated from the offset. The bytes consumed for multi-thread runs
+         * is updated only into ps_dec->i4_bytes_consumed if the get_slice_pos
+         * function has been called. If that function has not run, then we have
+         * encountered an error but still have to consume the bytes in header
+         * decode, etc.
+         */
         ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
+    }
     else
     {
         ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
diff --git a/decoder/impeg2d_pic_proc.c b/decoder/impeg2d_pic_proc.c
index 029f1bf..fbbbf79 100644
--- a/decoder/impeg2d_pic_proc.c
+++ b/decoder/impeg2d_pic_proc.c
@@ -555,6 +555,32 @@
             ps_dec->as_recent_fld[1][1] = ps_dec->as_recent_fld[0][1];
         }
 
+        /* Error resilience: If forward and backward pictures are going to be NULL*/
+        /* then assign both to the current                                        */
+        /* if one of them NULL then we will assign the non null to the NULL one   */
+
+        if((NULL == ps_dec->as_recent_fld[0][1].pu1_y) && (NULL == ps_dec->as_recent_fld[1][1].pu1_y))
+        {
+            // assign the current picture to both
+            ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf;
+            impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1],
+                                         ps_dec->u2_frame_width);
+            ps_dec->as_recent_fld[0][0] = ps_dec->s_cur_frm_buf;
+            ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
+        }
+        //Assign the non-null picture to the null picture
+
+        else if((NULL == ps_dec->as_recent_fld[0][1].pu1_y) && (NULL != ps_dec->as_recent_fld[1][1].pu1_y))
+        {
+            ps_dec->as_recent_fld[0][0] = ps_dec->as_recent_fld[1][0];
+            ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
+        }
+
+        else if((NULL == ps_dec->as_recent_fld[1][1].pu1_y) && (NULL != ps_dec->as_recent_fld[0][1].pu1_y))
+        {
+            ps_dec->as_recent_fld[1][0] = ps_dec->as_recent_fld[0][0];
+            ps_dec->as_recent_fld[1][1] = ps_dec->as_recent_fld[0][1];
+        }
         ps_dec->as_ref_buf[FORW][TOP]    = ps_dec->as_recent_fld[0][0];
         ps_dec->as_ref_buf[FORW][BOTTOM] = ps_dec->as_recent_fld[0][1];
         ps_dec->as_ref_buf[BACK][TOP]    = ps_dec->as_recent_fld[1][0];
diff --git a/decoder/impeg2d_pnb_pic.c b/decoder/impeg2d_pnb_pic.c
index a6c2351..5540044 100644
--- a/decoder/impeg2d_pnb_pic.c
+++ b/decoder/impeg2d_pnb_pic.c
@@ -106,6 +106,14 @@
                 u2_mb_addr_incr    = ps_dec->u2_num_horiz_mb - ps_dec->u2_mb_x;
             }
 
+            if ((u2_mb_addr_incr - 1) > ps_dec->u2_num_mbs_left)
+            {
+                /* If the number of skip MBs are more than the number of MBs
+                 * left, indicate error.
+                 */
+                return IV_FAIL;
+            }
+
             impeg2d_dec_skip_mbs(ps_dec, (UWORD16)(u2_mb_addr_incr - 1));
         }
 
@@ -297,6 +305,13 @@
                 u2_mb_addr_incr    = ps_dec->u2_num_horiz_mb - ps_dec->u2_mb_x;
             }
 
+            if ((u2_mb_addr_incr - 1) > ps_dec->u2_num_mbs_left)
+            {
+                /* If the number of skip MBs are more than the number of MBs
+                 * left, indicate error.
+                 */
+                return IV_FAIL;
+            }
 
             impeg2d_dec_skip_mbs(ps_dec, (UWORD16)(u2_mb_addr_incr - 1));
         }
@@ -488,7 +503,6 @@
 
         IMPEG2D_TRACE_MB_START(ps_dec->u2_mb_x, ps_dec->u2_mb_y);
 
-
         if(ps_dec->e_pic_type == B_PIC)
             ret = impeg2d_dec_pnb_mb_params(ps_dec);
         else
@@ -687,7 +701,6 @@
             }
         }
 
-
         ps_dec->u2_num_mbs_left--;
         ps_dec->u2_first_mb = 0;
         ps_dec->u2_mb_x++;