/* Any workload management goes in this file */

#include "viddec_fw_debug.h"
#include "viddec_parser_ops.h"
#include "h264.h"
#include "h264parse.h"
#include "viddec_fw_item_types.h"
#include "h264parse_dpb.h"


#include "viddec_fw_workload.h"
#include <auto_eas/gen4_mfd.h>
#include "viddec_pm_utils_bstream.h"

// picture parameter 1
#define PUT_BSD_PP1_IMG_DISPOSABLE_FLAG_BIT(w)            (((uint32_t)w)&0x1)
#define PUT_BSD_PP1_SLICE_TYPE_BITS(w)                    ((((uint32_t)w)&0x7)<<1)
#define PUT_BSD_PP1_WEIGHTED_BIPRED_IDC_BITS(w)           ((((uint32_t)w)&0x3)<<4)
#define PUT_BSD_PP1_WEIGHTED_PRED_FLAG_BIT(w)             ((((uint32_t)w)&0x1)<<6)
#define PUT_BSD_PP1_NUM_REF_IDX_L0_BITS(w)                ((((uint32_t)w)&0x3F)<<8)
#define PUT_BSD_PP1_NUM_REF_IDX_L1_BITS(w)                ((((uint32_t)w)&0x3F)<<16)

// picture parameter 2
#define PUT_BSD_PP2_CABAC_INIT_IDC_BITS(w)                (((uint32_t)w)&0x3)
#define PUT_BSD_PP2_QP_BITS(w)                            ((((uint32_t)w)&0x3F)<<2)
#define PUT_BSD_PP2_DISABLE_DBF_IDC_BITS(w)               ((((uint32_t)w)&0x3)<<8)
#define PUT_BSD_PP2_ALPHA_C0_OFFSET_DIV2_BITS(w)          ((((uint32_t)w)&0xF)<<10)
#define PUT_BSD_PP2_BETA_OFFSET_DIV2_BITS(w)              ((((uint32_t)w)&0xF)<<14)
#define PUT_BSD_PP2_IMG_DIRECT_TYPE_BIT(w)                ((((uint32_t)w)&0x1)<<18)
#define PUT_BSD_PP2_CHROMA_QP_OFFSET_BITS(w)              ((((uint32_t)w)&0x1F)<<19)
#define PUT_BSD_PP2_CHROMA_QP_OFFSET_2_BITS(w)            ((((uint32_t)w)&0x1F)<<24)


// slice start parameter
#define PUT_BSD_SS_START_ADDR_BITS(w)                      (((uint32_t)w)&0x7fff)         // 14:0  current slice start address
#define PUT_BSD_SS_SKIP_FS_IDC_BITS(w)                    ((((uint32_t)w)&0x3f)<<16)      // [5:0], [4:0] frame store idc, [5] - 0: top-filed, 1: bottom field
#define PUT_BSD_SS_SKIP_TYPE_BIT(w)                       ((((uint32_t)w)&0x1)<<24)       // 0: P-skip, 1: I-skip
#define PUT_BSD_SS_SKIP_REWIND_BITS(w)                    ((((uint32_t)w)&0xf)<<28)       // number of MB or MBAFF pairs to rewind before skip

//h264_dpb_init
#define PUT_FRAME_WIDTH_MB_BITS(w)                        (((uint32_t)w)&0x7F)
#define PUT_FRAME_HEIGHT_MB_BITS(w)                       ((((uint32_t)w)&0x7F)<<16)

//dpb lut table init
//#define PUT_BSD_IMAGE_FRAME_STORE_IDC_BITS(w)             ((((uint32_t)w)&0x1F)<<8)

//h264 img init
#define PUT_BSD_IMAGE_STRUCTURE_BITS(w)                   (((uint32_t)w)&0x3)
#define PUT_BSD_IMAGE_IDR_BIT(w)                          ((((uint32_t)w)&0x1)<<2)
#define PUT_BSD_IMAGE_MBAFF_FRAME_FLAG_BIT(w)             ((((uint32_t)w)&0x1)<<3)
#define PUT_BSD_IMAGE_ENTROPY_CODING_MODE_FLAG_BIT(w)     ((((uint32_t)w)&0x1)<<4)
#define PUT_BSD_IMAGE_CONSTRAINED_INTRA_PRED_FLAG_BIT(w)  ((((uint32_t)w)&0x1)<<5)
#define PUT_BSD_IMG_FRAME_MBS_ONLY_FLAG_BIT(w)            ((((uint32_t)w)&0x1)<<6)
#define PUT_BSD_IMG_DIRECT_8X8_INFER_FLAG_BIT(w)          ((((uint32_t)w)&0x1)<<7)
#define PUT_BSD_IMAGE_FRAME_STORE_IDC_BITS(w)             ((((uint32_t)w)&0x1F)<<8)

#define PUT_HPD_BSD_IMG_TRANSFORM_8X8_MODE_FLAG_BIT(w)    ((((uint32_t)w)&0x1)<<13)
#define PUT_HPD_BSD_IMG_MONOCHROME_FLAG_BIT(w)            ((((uint32_t)w)&0x1)<<14)
#define PUT_HPD_BSD_IMG_GREY_NONEXISTING_FLAG_BIT(w)      ((((uint32_t)w)&0x1)<<15)
#define PUT_HPD_BSD_IMG_QM_PRESENT_FLAG_BIT(w)            ((((uint32_t)w)&0x1)<<16)
#define PUT_HPD_BSD_IMG_QM_LIST_FLAGS_BITS(w)             ((((uint32_t)w)&0xFF)<<17)
#define PUT_HPD_BSD_IMG_MONOCHROME_PWT_FLAG_BIT(w)        ((((uint32_t)w)&0x1)<<25)


extern void h264_dpb_store_previous_picture_in_dpb(h264_Info * pInfo,
											int32_t NonExisting, 
											int32_t use_old);

extern void h264_dpb_flush_dpb (h264_Info * pInfo,int32_t output_all, int32_t keep_complement, int32_t num_ref_frames);



void h264_translate_parser_info_to_frame_attributes(viddec_workload_t *wl, h264_Info *pInfo)
{

   viddec_frame_attributes_t *attrs = &wl->attrs;  



	//// Cont_size
   attrs->cont_size.height       = pInfo->img.FrameHeightInMbs*16;
   attrs->cont_size.width        = pInfo->img.PicWidthInMbs*16;

	//// The following attributes will be updated in slice level
	attrs->h264.used_for_reference = 0;
	attrs->h264.top_field_first = 0;
	attrs->h264.top_field_poc = 0;
	attrs->h264.bottom_field_poc = 0;
	attrs->h264.field_pic_flag = 0;

#if 1 
/// Double check the size late!!!!!
	//attrs->h264.cropped_size.width = pInfo->img.PicWidthInMbs*16;
	//attrs->h264.cropped_size.height = pInfo->img.PicWidthInMbs*16;

   if( (pInfo->active_SPS.sps_disp.frame_cropping_flag) &&
      (pInfo->active_SPS.sps_disp.chroma_format_idc < 4))
   {
		int32_t CropUnitX, CropUnitY;
		int32_t SubWidthC, SubHeightC;
   
      if(pInfo->active_SPS.sps_disp.chroma_format_idc == 0)
      {
         CropUnitX = 1;
         CropUnitY = 2 - pInfo->active_SPS.sps_disp.frame_mbs_only_flag;
      }
      else
      {
         SubWidthC = 2 - ((pInfo->active_SPS.sps_disp.chroma_format_idc - 1) >> 1);
         SubHeightC = 2 - ((pInfo->active_SPS.sps_disp.chroma_format_idc - 1) >>1)
                        - ((pInfo->active_SPS.sps_disp.chroma_format_idc - 1) & 0x1);
         CropUnitX = SubWidthC;
         CropUnitY = SubHeightC * (2 - pInfo->active_SPS.sps_disp.frame_mbs_only_flag);
      }

      if ((int32_t)attrs->cont_size.height >(pInfo->active_SPS.sps_disp.frame_crop_rect_bottom_offset*CropUnitY)) 
		{
         attrs->cont_size.height -= (pInfo->active_SPS.sps_disp.frame_crop_rect_bottom_offset*CropUnitY);
			//attrs->h264.cropped_size.height-= (pInfo->active_SPS.sps_disp.frame_crop_rect_bottom_offset*CropUnitY);	
      }		
   }  
/// Pan-Scan Info

#endif

}


static void h264_parse_update_frame_attributes(void *parent, h264_Info *pInfo)
{
   viddec_workload_t        *wl_cur,  *wl_next;
   viddec_frame_attributes_t *attrs;   
   uint8_t    frame_type=0;
	

   if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
   {         
      wl_cur = viddec_pm_get_header( parent );
      attrs = &wl_cur->attrs;            
   }
   else
   {
      wl_next = viddec_pm_get_next_header (parent);
      attrs = &wl_next->attrs;         
   }    

   /////////update frame type
   if((pInfo->dpb.fs[pInfo->dpb.fs_dec_idc].pic_type)&(0x1 << FRAME_TYPE_STRUCTRUE_OFFSET))
   {
		frame_type = ( (pInfo->dpb.fs[pInfo->dpb.fs_dec_idc].pic_type)&((0x7 << FRAME_TYPE_FRAME_OFFSET)) )>> FRAME_TYPE_FRAME_OFFSET;
		switch(frame_type)
		{
			case FRAME_TYPE_IDR:   attrs->frame_type = VIDDEC_FRAME_TYPE_IDR; break;
			case FRAME_TYPE_I:     attrs->frame_type = VIDDEC_FRAME_TYPE_I; break;
			case FRAME_TYPE_P:     attrs->frame_type = VIDDEC_FRAME_TYPE_P; break;
			case FRAME_TYPE_B:     attrs->frame_type = VIDDEC_FRAME_TYPE_B; break;
			default:               attrs->frame_type = VIDDEC_FRAME_TYPE_INVALID; break;
		}

	  	attrs->bottom_field_type = VIDDEC_FRAME_TYPE_INVALID;
   }
   else
   {
	  frame_type = ( (pInfo->dpb.fs[pInfo->dpb.fs_dec_idc].pic_type)&((0x7 << FRAME_TYPE_TOP_OFFSET)) )>> FRAME_TYPE_TOP_OFFSET;
	  switch(frame_type)
	  {
	      case FRAME_TYPE_IDR:   attrs->frame_type = VIDDEC_FRAME_TYPE_IDR; break;
		  case FRAME_TYPE_I:     attrs->frame_type = VIDDEC_FRAME_TYPE_I; break;
		  case FRAME_TYPE_P:     attrs->frame_type = VIDDEC_FRAME_TYPE_P; break;
		  case FRAME_TYPE_B:     attrs->frame_type = VIDDEC_FRAME_TYPE_B; break;
		  default:               attrs->frame_type = VIDDEC_FRAME_TYPE_INVALID; break;

	  }

	  frame_type = ( (pInfo->dpb.fs[pInfo->dpb.fs_dec_idc].pic_type)&((0x7 << FRAME_TYPE_BOTTOM_OFFSET)) )>> FRAME_TYPE_BOTTOM_OFFSET;
	  switch(frame_type)
	  {
	      case FRAME_TYPE_IDR:   attrs->bottom_field_type = VIDDEC_FRAME_TYPE_IDR; break;
		  case FRAME_TYPE_I:     attrs->bottom_field_type = VIDDEC_FRAME_TYPE_I; break;
		  case FRAME_TYPE_P:     attrs->bottom_field_type = VIDDEC_FRAME_TYPE_P; break;
		  case FRAME_TYPE_B:     attrs->bottom_field_type = VIDDEC_FRAME_TYPE_B; break;
		  default:               attrs->bottom_field_type = VIDDEC_FRAME_TYPE_INVALID; break;

	  }
   }

	/////////update is_referece flag
	attrs->h264.used_for_reference |= (pInfo->SliceHeader.nal_ref_idc == 0)? 0: 1;

	/////////update POC
	attrs->h264.top_field_poc = pInfo->img.toppoc;
	attrs->h264.bottom_field_poc = pInfo->img.bottompoc;

	//////// update TFF
	if(attrs->h264.top_field_poc <= attrs->h264.bottom_field_poc) {
		attrs->h264.top_field_first = 1;
	} else {
		attrs->h264.top_field_first = 0;
	}

	/////// update field_pic_flag
	//attrs->h264.field_pic_flag |= (pInfo->SliceHeader.field_pic_flag << pInfo->SliceHeader.bottom_field_flag);
	attrs->h264.field_pic_flag |= pInfo->SliceHeader.field_pic_flag;

	return;
}


static void h264_fill_slice_data(h264_Info *pInfo, h264_slice_data * p_slice_data)
{
   uint32_t data=0;
   uint32_t first_mb_in_slice =0;
   


   ////////////fill pic parameters 1   
   data =   PUT_BSD_PP1_IMG_DISPOSABLE_FLAG_BIT( (pInfo->SliceHeader.nal_ref_idc == 0) ) +
            PUT_BSD_PP1_SLICE_TYPE_BITS(pInfo->SliceHeader.slice_type) +
            PUT_BSD_PP1_WEIGHTED_BIPRED_IDC_BITS(pInfo->active_PPS.weighted_bipred_idc) +
            PUT_BSD_PP1_WEIGHTED_PRED_FLAG_BIT(pInfo->active_PPS.weighted_pred_flag)  +
            PUT_BSD_PP1_NUM_REF_IDX_L0_BITS(pInfo->SliceHeader.num_ref_idx_l0_active)  +
            PUT_BSD_PP1_NUM_REF_IDX_L1_BITS(pInfo->SliceHeader.num_ref_idx_l1_active);
   p_slice_data->h264_bsd_slice_p1 = data;


   ///////////fill pic parameters 2
   data =   PUT_BSD_PP2_CABAC_INIT_IDC_BITS(pInfo->SliceHeader.cabac_init_idc) + 
            PUT_BSD_PP2_QP_BITS( (pInfo->SliceHeader.slice_qp_delta + pInfo->active_PPS.pic_init_qp_minus26+26) ) +
            PUT_BSD_PP2_DISABLE_DBF_IDC_BITS(pInfo->SliceHeader.disable_deblocking_filter_idc) +
            PUT_BSD_PP2_ALPHA_C0_OFFSET_DIV2_BITS(pInfo->SliceHeader.slice_alpha_c0_offset_div2) +
            PUT_BSD_PP2_BETA_OFFSET_DIV2_BITS(pInfo->SliceHeader.slice_beta_offset_div2) +
            PUT_BSD_PP2_IMG_DIRECT_TYPE_BIT(pInfo->SliceHeader.direct_spatial_mv_pred_flag) + 
            PUT_BSD_PP2_CHROMA_QP_OFFSET_BITS(pInfo->active_PPS.chroma_qp_index_offset) +
            PUT_BSD_PP2_CHROMA_QP_OFFSET_2_BITS(pInfo->active_PPS.second_chroma_qp_index_offset);

   p_slice_data->h264_bsd_slice_p2 = data;
  
   /////////fill slice start
   first_mb_in_slice = pInfo->SliceHeader.first_mb_in_slice;

   data =   PUT_BSD_SS_START_ADDR_BITS(first_mb_in_slice);   
   data |=  PUT_BSD_SS_SKIP_FS_IDC_BITS( pInfo->h264_list_replacement) |
            PUT_BSD_SS_SKIP_TYPE_BIT(0) | 
            PUT_BSD_SS_SKIP_REWIND_BITS((pInfo->img.MbaffFrameFlag? 2: 3));

   p_slice_data->h264_bsd_slice_start = data;   
   
}


static void h264_parse_emit_4X4_scaling_matrix( void *parent, h264_Info *pInfo )
{

   viddec_workload_item_t     wi;
   
   uint32_t                   i=0, n_items=0;
   uint32_t                   qm_type=0;

   
   for( i = 0; i < 6; i++ )
   {
      qm_type = FB_QM;
      if (pInfo->active_SPS.seq_scaling_matrix_present_flag) // check sps first
      {
         if (pInfo->active_SPS.seq_scaling_list_present_flag[i])
         {
            pInfo->qm_present_list |= ((0x1)<<i);
                
            if (pInfo->active_SPS.UseDefaultScalingMatrix4x4Flag[i]) {
               qm_type = DEFAULT_QM;
            } else {
               qm_type = SPS_QM;               
            }
         }
      }

      if (pInfo->active_PPS.pic_scaling_matrix_present_flag) // then check pps
      {
         if (pInfo->active_PPS.pic_scaling_list_present_flag[i]) 
         {
            pInfo->qm_present_list |= ((0x1)<<i);
            if (pInfo->active_PPS.UseDefaultScalingMatrix4x4Flag[i]) {
               qm_type = DEFAULT_QM;
            } else {
               qm_type = PPS_QM;               
            }
         }
         else
         {
            if ((i != 0) && (i != 3) && (i < 6)) {
               pInfo->qm_present_list  &= ~((0x1)<<i);
               qm_type = FB_QM;               
            }
         }
      }
   

		///////////////////// Emit out Scaling_matrix//////////////////////
      wi.vwi_type = VIDDEC_WORKLOAD_H264_SCALING_MATRIX;   
      //    data_offset    0x aa  bb  cc  dd
      //    bb    is the workload item offset
      //    cc    is the qm_type
      //    dd    is the matrix number
      //
      switch (qm_type)
      {
         case (SPS_QM):{

            for(n_items =0; n_items<2; n_items++)
            {
               wi.data.data_offset = i + (SPS_QM << 4) + (n_items <<8);
               wi.data.data_payload[0] = ((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+0]))+
                                         (((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+1]))<<8)+
                                         (((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+2]))<<16)+
                                         (((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+3]))<<24);
               wi.data.data_payload[1] = ((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+4]))+
                                         (((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+5]))<<8)+
                                         (((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+6]))<<16)+
                                         (((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+7]))<<24);
               //cur is empty, fill new frame in cur
               viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
            }

            break;
         }
         case (PPS_QM):{

            for(n_items =0; n_items<2; n_items++)
            {
               wi.data.data_offset = i + (PPS_QM << 4) + (n_items <<8);
               wi.data.data_payload[0] = ((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+0]))+
                                         (((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+1]))<<8)+
                                         (((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+2]))<<16)+
                                         (((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+3]))<<24);
               wi.data.data_payload[1] = ((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+4]))+
                                         (((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+5]))<<8)+
                                         (((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+6]))<<16)+
                                         (((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+7]))<<24);
               //cur is empty, fill new frame in cur
               viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
            }

         	break;
         }
         case (DEFAULT_QM):
			{

            wi.data.data_offset = i + (DEFAULT_QM << 4);
            wi.data.data_payload[0] = 0;
            wi.data.data_payload[1] = 0;    
            //cur is empty, fill new frame in cur
            viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
         	break;
         }
         default:
			{
	        	 break;   
         }
      }
   }
 
}

static void h264_parse_emit_8X8_scaling_matrix( void *parent, h264_Info *pInfo )
{

   viddec_workload_item_t     wi;
   
   uint32_t                   i=0, n_items=0;
   uint32_t                   qm_type=0;
  
   for( i = 6; i < 8; i++ )
   {
      qm_type = FB_QM;
      if (pInfo->active_SPS.seq_scaling_matrix_present_flag) // check sps first
      {
         if (pInfo->active_SPS.seq_scaling_list_present_flag[i])
         {
            pInfo->qm_present_list |= ((0x1)<<i);
                
            if (pInfo->active_SPS.UseDefaultScalingMatrix8x8Flag[i-6])
            {
               qm_type = DEFAULT_QM;
            }
            else
            {
               qm_type = SPS_QM;               
            }
         }
      }

      if (pInfo->active_PPS.pic_scaling_matrix_present_flag) // then check pps
      {
         if (pInfo->active_PPS.pic_scaling_list_present_flag[i]) 
         {
            pInfo->qm_present_list |= ((0x1)<<i);
            
            if (pInfo->active_PPS.UseDefaultScalingMatrix8x8Flag[i-6])
            {
               qm_type = DEFAULT_QM;
            }
            else
            {
               qm_type = PPS_QM;               
            }
         }
      }   
      wi.vwi_type = VIDDEC_WORKLOAD_H264_SCALING_MATRIX;

      //    data_offset    0x aa  bb  cc  dd
      //    bb    is the workload item offset
      //    cc    is the qm_type
      //    dd    is the matrix number
      //
      switch (qm_type)
      {
         case (SPS_QM):
			{
            for(n_items =0; n_items<8; n_items++)
            {
               wi.data.data_offset = i + (SPS_QM << 4) + (n_items <<8);
               wi.data.data_payload[0] = ((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+0]))+
                                         (((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+1]))<<8)+
                                         (((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+2]))<<16)+
                                         (((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+3]))<<24);
               wi.data.data_payload[1] = ((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+4]))+
                                         (((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+5]))<<8)+
                                         (((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+6]))<<16)+
                                         (((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+7]))<<24);
               //cur is empty, fill new frame in cur
               viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
            }
            break;
         }
         case (PPS_QM):
			{
            for(n_items =0; n_items<8; n_items++)
            {
               wi.data.data_offset = i + (PPS_QM << 4) + (n_items <<8);
               wi.data.data_payload[0] = ((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+0]))+
                                         (((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+1]))<<8)+
                                         (((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+2]))<<16)+
                                         (((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+3]))<<24);
               wi.data.data_payload[1] = ((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+4]))+
                                         (((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+5]))<<8)+
                                         (((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+6]))<<16)+
                                         (((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+7]))<<24);
               //cur is empty, fill new frame in cur
               viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
            }
         	break;
         }
         case (DEFAULT_QM):
			{
            wi.data.data_offset = i + (DEFAULT_QM << 4);
            wi.data.data_payload[0] = 0;
            wi.data.data_payload[1] = 0;    
            //cur is empty, fill new frame in cur
            viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
         	break;
         }
         default:{
         	break;   
         }
      }
   }
   
}



static void h264_fill_pic_data(h264_Info *pInfo, h264_pic_data * p_pic_data)
{
   uint32_t data=0;
   uint32_t dec_idc =0;
   uint32_t frame_structure =0;

   //fill h264_dpb_init
   data =   PUT_FRAME_WIDTH_MB_BITS(pInfo->dpb.PicWidthInMbs) + 
            PUT_FRAME_HEIGHT_MB_BITS(pInfo->dpb.FrameHeightInMbs);
  
   p_pic_data->h264_dpb_init = data;

   ////////////////////////////////file current pic info
   data = 0;
   dec_idc = pInfo->dpb.fs_dec_idc;   
   frame_structure = pInfo->img.structure;
   if(frame_structure == FRAME)
      frame_structure=0;
   //data =  PUT_BSD_IMAGE_FRAME_STORE_IDC_BITS(pInfo->dpb.fs[dec_idc].fs_idc);

   //p_pic_data->h264_cur_bsd_img_init= data;   

   data  =  PUT_BSD_IMAGE_STRUCTURE_BITS(frame_structure)  +
            PUT_BSD_IMAGE_IDR_BIT(pInfo->nal_unit_type == h264_NAL_UNIT_TYPE_IDR) +
            PUT_BSD_IMAGE_MBAFF_FRAME_FLAG_BIT(pInfo->img.MbaffFrameFlag) +
            PUT_BSD_IMAGE_ENTROPY_CODING_MODE_FLAG_BIT(pInfo->active_PPS.entropy_coding_mode_flag) +
            PUT_BSD_IMAGE_CONSTRAINED_INTRA_PRED_FLAG_BIT(pInfo->active_PPS.constrained_intra_pred_flag) +
            PUT_BSD_IMG_FRAME_MBS_ONLY_FLAG_BIT(pInfo->active_SPS.sps_disp.frame_mbs_only_flag) +
            PUT_BSD_IMG_DIRECT_8X8_INFER_FLAG_BIT(pInfo->active_SPS.sps_disp.direct_8x8_inference_flag) +
            PUT_HPD_BSD_IMG_TRANSFORM_8X8_MODE_FLAG_BIT(pInfo->active_PPS.transform_8x8_mode_flag) +
            PUT_HPD_BSD_IMG_MONOCHROME_FLAG_BIT(((pInfo->active_SPS.sps_disp.chroma_format_idc==0)? 0x1: 0x0)) +
            PUT_HPD_BSD_IMG_GREY_NONEXISTING_FLAG_BIT(0x0) +
            PUT_HPD_BSD_IMG_QM_PRESENT_FLAG_BIT((pInfo->active_PPS.pic_scaling_matrix_present_flag||pInfo->active_SPS.seq_scaling_matrix_present_flag)) +
            PUT_HPD_BSD_IMG_QM_LIST_FLAGS_BITS(pInfo->qm_present_list) +
            PUT_HPD_BSD_IMG_MONOCHROME_PWT_FLAG_BIT(0x1) +
            PUT_BSD_IMAGE_FRAME_STORE_IDC_BITS(pInfo->dpb.fs[dec_idc].fs_idc);

   p_pic_data->h264_cur_bsd_img_init= data;

   //to do: add qm list
   //PUT_HPD_BSD_IMG_QM_LIST_FLAGS_BITS(pInfo->img.q .qm_present_list) +
   //printf("structure = %d, tpoc = %d, bpoc = %d\n", pInfo->img.structure, pInfo->img.toppoc, pInfo->img.bottompoc);

   if(pInfo->img.structure == FRAME)
   {
      // Write down POC
      p_pic_data->h264_cur_mpr_tf_poc = pInfo->img.toppoc;
      p_pic_data->h264_cur_mpr_bf_poc = pInfo->img.bottompoc;      
   }else if (pInfo->img.structure == TOP_FIELD)
   {
      // Write down POC
      p_pic_data->h264_cur_mpr_tf_poc = pInfo->img.toppoc;
      p_pic_data->h264_cur_mpr_bf_poc = 0;       
   }  
   else if (pInfo->img.structure ==  BOTTOM_FIELD)
   {
      // Write down POC
      p_pic_data->h264_cur_mpr_tf_poc = 0;
      p_pic_data->h264_cur_mpr_bf_poc = pInfo->img.bottompoc; 
   }
   else
   {
      // Write down POC
      p_pic_data->h264_cur_mpr_tf_poc = 0;
      p_pic_data->h264_cur_mpr_bf_poc = 0;      
   }
    
   return;
}

static void h264_parse_emit_sps(void *parent, h264_Info *pInfo)
{
   viddec_workload_item_t     wi;   

   if(pInfo->Is_SPS_updated)
   {    
      viddec_fw_reset_workload_item(&wi);
      wi.vwi_type = VIDDEC_WORKLOAD_SEQUENCE_INFO;

      viddec_fw_h264_sps_set_profile_idc(&(wi.h264_sps), pInfo->active_SPS.profile_idc);
      viddec_fw_h264_sps_set_level_idc(&(wi.h264_sps), pInfo->active_SPS.level_idc);
      viddec_fw_h264_sps_set_chroma_format_idc(&(wi.h264_sps), pInfo->active_SPS.sps_disp.chroma_format_idc);
      viddec_fw_h264_sps_set_num_ref_frames(&(wi.h264_sps), pInfo->active_SPS.num_ref_frames);
      viddec_fw_h264_sps_set_gaps_in_frame_num_value_allowed_flag(&(wi.h264_sps), pInfo->active_SPS.gaps_in_frame_num_value_allowed_flag);
      viddec_fw_h264_sps_set_frame_mbs_only_flag(&(wi.h264_sps), pInfo->active_SPS.sps_disp.frame_mbs_only_flag);
      viddec_fw_h264_sps_set_frame_cropping_flag(&(wi.h264_sps), pInfo->active_SPS.sps_disp.frame_cropping_flag);
      viddec_fw_h264_sps_set_vui_parameters_present_flag(&(wi.h264_sps), pInfo->active_SPS.sps_disp.vui_parameters_present_flag);
		wi.h264_sps.pic_width_in_mbs_minus1 = pInfo->active_SPS.sps_disp.pic_width_in_mbs_minus1;
		wi.h264_sps.pic_height_in_map_units_minus1 = pInfo->active_SPS.sps_disp.pic_height_in_map_units_minus1;

      //cur is empty, fill new frame in cur
      viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);

      viddec_fw_reset_workload_item(&wi);
		if(pInfo->active_SPS.sps_disp.frame_cropping_flag)
		{
         wi.vwi_type = VIDDEC_WORKLOAD_H264_CROPPING;
         viddec_fw_h264_cropping_set_left(&(wi.h264_cropping), pInfo->active_SPS.sps_disp.frame_crop_rect_left_offset);
         viddec_fw_h264_cropping_set_right(&(wi.h264_cropping), pInfo->active_SPS.sps_disp.frame_crop_rect_right_offset);
         viddec_fw_h264_cropping_set_top(&(wi.h264_cropping), pInfo->active_SPS.sps_disp.frame_crop_rect_top_offset);
         viddec_fw_h264_cropping_set_bottom(&(wi.h264_cropping), pInfo->active_SPS.sps_disp.frame_crop_rect_bottom_offset);
         //cur is empty, fill new frame in cur
         viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
		}
      viddec_fw_reset_workload_item(&wi);
		if(pInfo->active_SPS.sps_disp.vui_parameters_present_flag == 1)
		{
         wi.vwi_type = VIDDEC_WORKLOAD_DISPLAY_INFO;
         viddec_fw_h264_vui_set_aspect_ratio_info_present_flag(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.aspect_ratio_info_present_flag);
         viddec_fw_h264_vui_set_video_signal_type_present_flag(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.video_signal_type_present_flag);
         viddec_fw_h264_vui_set_pic_struct_present_flag(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.pic_struct_present_flag);
         viddec_fw_h264_vui_set_timing_info_present_flag(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.timing_info_present_flag);
         viddec_fw_h264_vui_set_nal_hrd_parameters_present_flag(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.nal_hrd_parameters_present_flag);
         viddec_fw_h264_vui_set_vcl_hrd_parameters_present_flag(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.vcl_hrd_parameters_present_flag);

         if(pInfo->active_SPS.sps_disp.vui_seq_parameters.aspect_ratio_info_present_flag == 1)
         {
             viddec_fw_h264_vui_set_aspect_ratio_idc(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.aspect_ratio_idc);
             if(h264_AR_Extended_SAR == pInfo->active_SPS.sps_disp.vui_seq_parameters.aspect_ratio_idc)
             {
                 viddec_fw_h264_vui_set_sar_width(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.sar_width);
                 viddec_fw_h264_vui_set_sar_height(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.sar_height);
             }
			}


			if(pInfo->active_SPS.sps_disp.vui_seq_parameters.video_signal_type_present_flag)
			{
             viddec_fw_h264_vui_set_colour_description_present_flag(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.colour_description_present_flag);
				if(pInfo->active_SPS.sps_disp.vui_seq_parameters.colour_description_present_flag)
				{
                viddec_fw_h264_vui_set_colour_primaries(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.colour_primaries);
                viddec_fw_h264_vui_set_transfer_characteristics(&(wi.h264_vui),  pInfo->active_SPS.sps_disp.vui_seq_parameters.transfer_characteristics);
				}
            viddec_fw_h264_vui_set_video_format(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.video_format);
			}

			if(pInfo->active_SPS.sps_disp.vui_seq_parameters.timing_info_present_flag == 1)
			{
				viddec_fw_h264_vui_set_fixed_frame_rate_flag(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.fixed_frame_rate_flag);
			}

			if( (pInfo->active_SPS.sps_disp.vui_seq_parameters.nal_hrd_parameters_present_flag == 1)
				|| (pInfo->active_SPS.sps_disp.vui_seq_parameters.vcl_hrd_parameters_present_flag == 1))
			{
            viddec_fw_h264_vui_set_low_delay_hrd_flag(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.low_delay_hrd_flag);
			}

         //cur is empty, fill new frame in cur
         viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
		}

      viddec_fw_reset_workload_item(&wi);

		if(pInfo->active_SPS.sps_disp.vui_seq_parameters.timing_info_present_flag == 1)
		{
		   wi.vwi_type = VIDDEC_WORKLOAD_H264_VUI_TIMING_INFO;
         
         wi.h264_vui_time_info.num_units_in_tick = pInfo->active_SPS.sps_disp.vui_seq_parameters.num_units_in_tick;
         wi.h264_vui_time_info.time_scale = pInfo->active_SPS.sps_disp.vui_seq_parameters.time_scale;         		
         //cur is empty, fill new frame in cur
         viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
		}
		pInfo->Is_SPS_updated =0;
      
   }
   
   return;
}




static void h264_parse_emit_ref_list( void *parent, h264_Info *pInfo, uint32_t list_id)
{
   uint32_t  i=0, nitems=0, byte_index=0, data=0, data_writed=0;
   uint8_t    *p_list;
   viddec_workload_item_t     wi;   

   if(0 == list_id)
   {
      wi.vwi_type = VIDDEC_WORKLOAD_H264_REFR_LIST_0;
      
      if( (h264_PtypeB==pInfo->SliceHeader.slice_type)||(h264_PtypeP==pInfo->SliceHeader.slice_type) )
      {
         nitems = pInfo->SliceHeader.num_ref_idx_l0_active;
         if(pInfo->SliceHeader.sh_refpic_l0.ref_pic_list_reordering_flag)
         {
            p_list = pInfo->slice_ref_list0;      
         }
         else
         {
            p_list = pInfo->dpb.listX_0;
         }
      }
      else
      {
         nitems =0;
         p_list = pInfo->dpb.listX_0;
      }
   }
   else
   {
      wi.vwi_type = VIDDEC_WORKLOAD_H264_REFR_LIST_1;
      
      if( h264_PtypeB==pInfo->SliceHeader.slice_type)
      {
         nitems = pInfo->SliceHeader.num_ref_idx_l1_active;    
         if(pInfo->SliceHeader.sh_refpic_l1.ref_pic_list_reordering_flag)
         {
            p_list = pInfo->slice_ref_list1;      
         }
         else
         {
            p_list = pInfo->dpb.listX_1;
         }    
      }
      else
      {
         nitems = 0;
         p_list = pInfo->dpb.listX_1;      
      }     
      
   }

   if(0 == nitems)
   {
      return;
   }   
   
   byte_index =0;  
   data_writed=0;
      
   
	for (i=0; i < 32; i++)
   {                  
      if(byte_index == 0) data = 0;

      if(i<nitems)
      {
         if( viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[ (p_list[i]&0x1f) ])))
         {
            data |= (pInfo->h264_list_replacement) << byte_index;            
         }
         else
         {
            data |= (p_list[i] & 0x7f) << byte_index;            
         }       
      }
      else
      {
         data |= (0x80) << byte_index;         
      }    
         
         
      if(byte_index == 24)
      {  
         byte_index = 0;         
         wi.data.data_offset = data_writed&(~0x1);
         wi.data.data_payload[data_writed&0x1]=data;

         data =0;
         
         if(data_writed&0x1)
         {
             //cur is empty, fill new frame in cur
             viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
         }
         data_writed ++;
      }
      else 
      {
         byte_index += 8;      
      }
   }      
    
}



void h264_parse_emit_current_slice( void *parent, h264_Info *pInfo )
{

   viddec_workload_item_t     wi;
   h264_slice_data 				slice_data;

   uint32_t		i=0, nitems=0, data=0;
   uint32_t 	bits_offset =0, byte_offset =0;   
   uint8_t    	is_emul =0;

	////////////////////// Update frame attributes/////////////////
	h264_parse_update_frame_attributes(parent,pInfo);


	if(pInfo->SliceHeader.sh_error) {
		// Error type definition, refer to viddec_fw_common_defs.h
		//		if error in top field, VIDDEC_FW_WORKLOAD_ERR_TOPFIELD			= (1 << 17)
		//		if error in bottom field, VIDDEC_FW_WORKLOAD_ERR_BOTTOMFIELD	   = (1 << 18)
		//		if this is frame based, both 2 bits should be set 

		if(pInfo->push_to_cur) {
			pInfo->wl_err_curr |= VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE;
			pInfo->wl_err_curr |= (pInfo->SliceHeader.structure << FIELD_ERR_OFFSET);
		} else {
			pInfo->wl_err_next |= VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE;
			pInfo->wl_err_next |= (pInfo->SliceHeader.structure << FIELD_ERR_OFFSET);
		}
	}


	////////////////////// Update Reference list //////////////////
   if( (h264_PtypeB==pInfo->SliceHeader.slice_type)||(h264_PtypeP==pInfo->SliceHeader.slice_type) )
   {
      if(pInfo->SliceHeader.sh_refpic_l0.ref_pic_list_reordering_flag)
      {
         nitems = pInfo->SliceHeader.num_ref_idx_l0_active;
         
         for(i=0; i<nitems;i++)
         {
            if(viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[pInfo->slice_ref_list0[i]&0x1f]))==0)
            {
              pInfo->h264_list_replacement = (pInfo->slice_ref_list0[i]&0xFF)|0x80;
              break;
            }
         }
      }
      else
      {
         nitems = pInfo->dpb.listXsize[0];
         
         for(i=0; i<nitems;i++)
         {
            if(viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[pInfo->dpb.listX_0[i]&0x1f]))==0)
            {
              pInfo->h264_list_replacement = (pInfo->dpb.listX_0[i]&0xFF)|0x80;
              break;
            }
         }
      }
            
   }
   else
   {
      nitems =0;      
   }
	/////file ref list 0   
   h264_parse_emit_ref_list(parent, pInfo, 0);   
      
   /////file ref list 1
   h264_parse_emit_ref_list(parent, pInfo, 1);     

	///////////////////////////////////// Slice Data ////////////////////////////////
   h264_fill_slice_data(pInfo, &slice_data);

   wi.vwi_type = VIDDEC_WORKLOAD_H264_SLICE_REG;

   wi.data.data_offset = slice_data.h264_bsd_slice_start;
   wi.data.data_payload[0] = slice_data.h264_bsd_slice_p1;
   wi.data.data_payload[1] = slice_data.h264_bsd_slice_p2;

   //cur is empty, fill new frame in cur
   viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);

   ///////////////////////////predict weight table item and data if have///////////////////////////
   if(pInfo->h264_pwt_enabled)
   {
      wi.vwi_type = VIDDEC_WORKLOAD_H264_PWT_BITS_OFFSET;      
      wi.data.data_offset = pInfo->h264_pwt_end_byte_offset- pInfo->h264_pwt_start_byte_offset+1;
      wi.data.data_payload[0] = pInfo->h264_pwt_start_bit_offset;
      wi.data.data_payload[1] = pInfo->h264_pwt_end_bit_offset;     

      if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
      {            
          viddec_pm_append_workitem( parent , &wi, false);

         wi.vwi_type = VIDDEC_WORKLOAD_H264_PWT_ES_BYTES;
         wi.es.es_flags = 0;
         viddec_pm_append_misc_tags(parent, pInfo->h264_pwt_start_byte_offset, pInfo->h264_pwt_end_byte_offset,&wi,1);
      }
      else
      {
          viddec_pm_append_workitem( parent , &wi, true);

         wi.vwi_type = VIDDEC_WORKLOAD_H264_PWT_ES_BYTES;
         wi.es.es_flags = 0;
         viddec_pm_append_misc_tags(parent, pInfo->h264_pwt_start_byte_offset, pInfo->h264_pwt_end_byte_offset,&wi,0);          
      }    
   }


 	////////////////////////////////// Update ES Buffer for Slice ///////////////////////
   viddec_pm_get_au_pos(parent, &bits_offset, &byte_offset, &is_emul);

	//OS_INFO("DEBUG---entropy_coding_mode_flag:%d, bits_offset: %d\n", pInfo->active_PPS.entropy_coding_mode_flag, bits_offset);

   if(pInfo->active_PPS.entropy_coding_mode_flag)
   {
   	if(0!=bits_offset)  {
         viddec_pm_get_bits(parent, &data, 8-bits_offset);
      } 
   }
	else
   {
      if(0!=bits_offset)  {
         wi.vwi_type = VIDDEC_WORKLOAD_H264_SH_BITS_OFFSET;
         wi.data.data_offset = bits_offset;
         wi.data.data_payload[0]=0;
         wi.data.data_payload[1]=0;
         //cur is empty, fill new frame in cur
         viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
      }
   }

   if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
   {         
      viddec_pm_append_pixeldata( parent );
   }
   else
   {
      viddec_pm_append_pixeldata_next( parent);       
   }
   
	return;
}


void h264_parse_emit_current_pic( void *parent, h264_Info *pInfo )
{

   viddec_workload_item_t     wi;

   const uint32_t             *pl;
   uint32_t                   i=0,nitems=0;

   h264_pic_data pic_data;

   pInfo->qm_present_list=0;
 
   h264_parse_emit_4X4_scaling_matrix(parent, pInfo);
   h264_parse_emit_8X8_scaling_matrix(parent, pInfo);   

   h264_fill_pic_data(pInfo, &pic_data);

   // How many payloads must be generated
   nitems = (sizeof(h264_pic_data) + 7) / 8; // In QWORDs rounded up 

   pl = (const uint32_t *) &pic_data;     

   // Dump slice data to an array of workitems,  to do pl access non valid mem
   for( i = 0; i < nitems; i++ )
   {
      wi.vwi_type           = VIDDEC_WORKLOAD_H264_PIC_REG;
      wi.data.data_offset   = (unsigned int)pl - (unsigned int)&pic_data; // offset within struct
      wi.data.data_payload[0] = pl[0];
      wi.data.data_payload[1] = pl[1];
      pl += 2;
      //cur is empty, fill new frame in cur
      viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
   }     

	return;
}

void h264_parse_emit_start_new_frame( void *parent, h264_Info *pInfo )
{

   viddec_workload_item_t     wi;
   uint32_t                   i=0,nitems=0;
   
	///////////////////////// Frame attributes//////////////////////////
	
   //Push data into current workload if first frame or frame_boundary already detected by non slice nal
   if( (pInfo->Is_first_frame_in_stream)||(pInfo->is_frame_boundary_detected_by_non_slice_nal)) 
   {
		viddec_workload_t			*wl_cur = viddec_pm_get_header( parent );
		//pInfo->img.g_new_frame = 0;
		pInfo->Is_first_frame_in_stream =0;
		pInfo->is_frame_boundary_detected_by_non_slice_nal=0;
		pInfo->push_to_cur = 1;
		h264_translate_parser_info_to_frame_attributes(wl_cur, pInfo);        
   }
   else  // move to cur if frame boundary detected by previous non slice nal, or move to next if not
   {        
		viddec_workload_t        *wl_next = viddec_pm_get_next_header (parent);   

		pInfo->push_to_cur = 0;
		h264_translate_parser_info_to_frame_attributes(wl_next, pInfo);      
			  
		pInfo->is_current_workload_done=1;
   } 

	///////////////////// SPS/////////////////////
   h264_parse_emit_sps(parent, pInfo);

	/////////////////////display frames/////////////////////
	nitems = pInfo->dpb.frame_numbers_need_to_be_displayed;

	for(i=0; i<nitems; i++)
	{      
		wi.vwi_type = VIDDEC_WORKLOAD_REF_FRAME_DISPLAY_0 + pInfo->dpb.frame_id_need_to_be_displayed[i];
		wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_displayed[i];
		wi.ref_frame.luma_phys_addr = 0;
		wi.ref_frame.chroma_phys_addr = 0;
      //cur is empty, fill new frame in cur
      viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
	}  
	pInfo->dpb.frame_numbers_need_to_be_displayed =0;
   
   
	/////////////////////release frames/////////////////////
	nitems = pInfo->dpb.frame_numbers_need_to_be_removed;

	for(i=0; i<nitems; i++)
	{      
	   wi.vwi_type = VIDDEC_WORKLOAD_REF_FRAME_RELEASE_0 + pInfo->dpb.frame_id_need_to_be_removed[i];
	   wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_removed[i];
	   wi.ref_frame.luma_phys_addr = 0;
	   wi.ref_frame.chroma_phys_addr = 0;
      //cur is empty, fill new frame in cur
      viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
	}  
	pInfo->dpb.frame_numbers_need_to_be_removed =0;

	/////////////////////flust frames (do not display)/////////////////////
	nitems = pInfo->dpb.frame_numbers_need_to_be_dropped;

	for(i=0; i<nitems; i++)
	{      
	   wi.vwi_type = VIDDEC_WORKLOAD_REF_FRAME_DROPOUT_0 + pInfo->dpb.frame_id_need_to_be_dropped[i];
	   wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_dropped[i];
	   wi.ref_frame.luma_phys_addr = 0;
	   wi.ref_frame.chroma_phys_addr = 0;
      //cur is empty, fill new frame in cur
      viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
	}  
	pInfo->dpb.frame_numbers_need_to_be_dropped =0;	
	
	/////////////////////updata DPB frames/////////////////////
	nitems = pInfo->dpb.used_size;
	for(i=0; i<nitems; i++)
	{
	   uint8_t fs_id = pInfo->dpb.fs_dpb_idc[i];

	   if(viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[fs_id])) == 0)
	   {   
	      wi.vwi_type = VIDDEC_WORKLOAD_DPB_ACTIVE_FRAME_0+fs_id;
	      wi.ref_frame.reference_id = fs_id;
	      wi.ref_frame.luma_phys_addr = 0;
	      wi.ref_frame.chroma_phys_addr = 0;
         //cur is empty, fill new frame in cur
         viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
	   }
	}
   
	/////////////////////updata dpb frames info (poc)/////////////////////
	nitems = pInfo->dpb.used_size;
	for(i=0; i<nitems; i++)
	{
	   uint8_t fs_id = pInfo->dpb.fs_dpb_idc[i];

	   if(viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[fs_id])) == 0)
	   {
	      wi.vwi_type = VIDDEC_WORKLOAD_H264_DPB_FRAME_POC;
	      wi.data.data_offset = fs_id;	      
	      //printf("is_used = %d, tpoc = %d, bpoc = %d\n", pInfo->dpb.fs[fs_id].is_used, pInfo->dpb.fs[fs_id].top_field.poc, pInfo->dpb.fs[fs_id].bottom_field.poc);

	      switch(viddec_h264_get_is_used(&(pInfo->dpb.fs[fs_id])))
	      {
	         case (FRAME):{               
	            wi.data.data_payload[0] = pInfo->dpb.fs[fs_id].top_field.poc;
	            wi.data.data_payload[1] = pInfo->dpb.fs[fs_id].bottom_field.poc;
	            break;
	         };

	         case (TOP_FIELD):{
	            wi.data.data_payload[0] = pInfo->dpb.fs[fs_id].top_field.poc;
	            wi.data.data_payload[1] = 0;
	            break;
	         };

	         case (BOTTOM_FIELD):{
	            wi.data.data_payload[0] = 0;
	            wi.data.data_payload[1] = pInfo->dpb.fs[fs_id].bottom_field.poc;
	            break;
	         };     

	         default : {
	            wi.data.data_payload[0] = 0;
	            wi.data.data_payload[1] = 0;
	            break;
	         };
	      }
         //cur is empty, fill new frame in cur
         viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
	   }
	}
    
	/////////////////////Alloc buffer for current Existing frame/////////////////////
	if(0!=pInfo->dpb.frame_numbers_need_to_be_allocated)
	{
	   if(pInfo->push_to_cur)
	   {
	      viddec_workload_t        *wl_cur = viddec_pm_get_header (parent);
	      wl_cur->is_reference_frame |= WORKLOAD_REFERENCE_FRAME | (pInfo->dpb.frame_id_need_to_be_allocated & 0x1f);
	   }
	   else
	   {
	      viddec_workload_t        *wl_next = viddec_pm_get_next_header (parent);
	      wl_next->is_reference_frame |= WORKLOAD_REFERENCE_FRAME | (pInfo->dpb.frame_id_need_to_be_allocated & 0x1f);	      
	   }
	}
	pInfo->dpb.frame_numbers_need_to_be_allocated =0;

	return;
}



void h264_parse_emit_eos( void *parent, h264_Info *pInfo )
{

   uint32_t nitems=0, i=0;
   viddec_workload_item_t	wi;


   wi.vwi_type = VIDDEC_WORKLOAD_EOS_BEGIN_BOUNDARY;
   wi.ref_frame.reference_id = 0;
   wi.ref_frame.luma_phys_addr = 0;
   wi.ref_frame.chroma_phys_addr = 0;

   //cur is empty, fill new frame in cur
   viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);

	//// Now we can flush out all frames in DPB fro display	

   if(MPD_DPB_FS_NULL_IDC != pInfo->dpb.fs_dec_idc)
   {
   	if(viddec_h264_get_is_used(&(pInfo->dpb.fs[pInfo->dpb.fs_dec_idc])) != 3) 
	   {                                                                                          
		   h264_dpb_mark_dangling_field(&pInfo->dpb, pInfo->dpb.fs_dec_idc);  //, DANGLING_TYPE_GAP_IN_FRAME
	   }	   
   }


   h264_dpb_store_previous_picture_in_dpb(pInfo, 0,0);   
   h264_dpb_flush_dpb(pInfo, 1, 0, pInfo->active_SPS.num_ref_frames);


	/////////////////////display frames/////////////////////
	nitems = pInfo->dpb.frame_numbers_need_to_be_displayed;

	for(i=0; i<nitems; i++)
	{      
		wi.vwi_type = VIDDEC_WORKLOAD_EOS_DISPLAY_FRAME_0 + pInfo->dpb.frame_id_need_to_be_displayed[i];
		wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_displayed[i];
		wi.ref_frame.luma_phys_addr = 0;
		wi.ref_frame.chroma_phys_addr = 0;
      //cur is empty, fill new frame in cur
      viddec_pm_append_workitem( parent, &wi , !pInfo->push_to_cur);
	}  
	pInfo->dpb.frame_numbers_need_to_be_displayed =0;
   
   
	/////////////////////release frames/////////////////////
	nitems = pInfo->dpb.frame_numbers_need_to_be_removed;

	for(i=0; i<nitems; i++)
	{      
	   wi.vwi_type = VIDDEC_WORKLOAD_EOS_RELEASE_FRAME_0 + pInfo->dpb.frame_id_need_to_be_removed[i];
	   wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_removed[i];
	   wi.ref_frame.luma_phys_addr = 0;
	   wi.ref_frame.chroma_phys_addr = 0;

	   if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
	   {	      
          viddec_pm_append_workitem( parent, &wi , false);
			viddec_pm_set_next_frame_error_on_eos(parent, VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE);
	   }
	   else
	   {
          viddec_pm_append_workitem( parent, &wi , true);
			viddec_pm_set_next_frame_error_on_eos(parent, pInfo->wl_err_next);
	   }
	}  
	pInfo->dpb.frame_numbers_need_to_be_removed =0;

	return;
}






