Support for level greater than level at init in Decoder

Added support to check num_ref_frames  in SPS
and num_reorder_frames in VUI before returning error for level

Change-Id: I392bab419385ca239836d200f9f2b064915a8a46
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_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 84909ea..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
         {
@@ -2514,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;
@@ -2532,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_ */