Home | History | Annotate | Download | only in parser
      1 #include "viddec_fw_debug.h"
      2 #include "viddec_parser_ops.h"
      3 #include "h264.h"
      4 #include "h264parse.h"
      5 #include "viddec_fw_item_types.h"
      6 #include "h264parse_dpb.h"
      7 #include <glib.h>
      8 
      9 extern void* h264_memcpy( void* dest, void* src, uint32_t num );
     10 
     11 uint32_t cp_using_dma(uint32_t ddr_addr, uint32_t local_addr, uint32_t size, char to_ddr, char swap)
     12 {
     13 	if (swap != 0)
     14 	{
     15 		g_warning("swap copying is not implemented.");
     16 	}
     17 
     18 	if (to_ddr)
     19 	{
     20 		memcpy((void*)ddr_addr, (void*)local_addr, size);
     21 	}
     22 	else
     23 	{
     24 		memcpy((void*)local_addr, (void*)ddr_addr, size);
     25 	}
     26 
     27     return (0);
     28 }
     29 
     30 #if 0
     31 void h264_parse_emit_start_new_frame( void *parent, h264_Info *pInfo )
     32 {
     33 
     34    if(pInfo->Is_first_frame_in_stream) //new stream, fill new frame in cur
     35    {
     36 
     37       pInfo->img.g_new_frame = 0;
     38       pInfo->Is_first_frame_in_stream =0;
     39       pInfo->push_to_cur = 1;
     40 
     41    }
     42    else  // move to next for new frame
     43    {
     44       pInfo->push_to_cur = 0;
     45    }
     46 
     47 
     48 
     49    //fill dpb managemnt info
     50 
     51 
     52 
     53 
     54       pInfo->dpb.frame_numbers_need_to_be_displayed =0;
     55       pInfo->dpb.frame_numbers_need_to_be_removed =0;
     56       pInfo->dpb.frame_numbers_need_to_be_allocated =0;
     57 
     58 
     59 }
     60 
     61 void h264_parse_emit_eos( void *parent, h264_Info *pInfo )
     62 {
     63   	////
     64 	//// Now we can flush out all frames in DPB fro display
     65 	if(pInfo->dpb.fs[pInfo->dpb.fs_dec_idc].is_used != 3)
     66 	{
     67 		h264_dpb_mark_dangling_field(&pInfo->dpb, pInfo->dpb.fs_dec_idc);  //, DANGLING_TYPE_GAP_IN_FRAME
     68 	}
     69 
     70    h264_dpb_store_previous_picture_in_dpb(pInfo, 0,0);
     71    h264_dpb_flush_dpb(pInfo, 1, 0, pInfo->active_SPS.num_ref_frames);
     72 
     73 
     74 	pInfo->dpb.frame_numbers_need_to_be_displayed =0;
     75    	pInfo->dpb.frame_numbers_need_to_be_removed =0;
     76 
     77 }
     78 
     79 void h264_parse_emit_current_pic( void *parent, h264_Info *pInfo )
     80 {
     81    pInfo->qm_present_list=0;
     82 }
     83 
     84 void h264_parse_emit_current_slice( void *parent, h264_Info *pInfo )
     85 {
     86 #if 1
     87    uint32_t  i, nitems=0;
     88 
     89 
     90    if( (h264_PtypeB==pInfo->SliceHeader.slice_type)||(h264_PtypeP==pInfo->SliceHeader.slice_type) )
     91    {
     92       if(pInfo->SliceHeader.sh_refpic_l0.ref_pic_list_reordering_flag)
     93       {
     94          nitems = pInfo->SliceHeader.num_ref_idx_l0_active;
     95 
     96          for(i=0; i<nitems;i++)
     97          {
     98             if(viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[pInfo->slice_ref_list0[i]&0x1f]))==0)
     99             {
    100               pInfo->h264_list_replacement = (pInfo->slice_ref_list0[i]&0xFF)|0x80;
    101               break;
    102             }
    103          }
    104       }
    105       else
    106       {
    107          nitems = pInfo->dpb.listXsize[0];
    108 
    109          for(i=0; i<nitems;i++)
    110          {
    111             if(viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[pInfo->dpb.listX_0[i]&0x1f]))==0)
    112             {
    113               pInfo->h264_list_replacement = (pInfo->dpb.listX_0[i]&0xFF)|0x80;
    114               break;
    115             }
    116          }
    117       }
    118 
    119    }
    120    else
    121    {
    122       nitems =0;
    123    }
    124 #endif
    125 }
    126 #else
    127 
    128 
    129 void h264_parse_emit_current_slice( void *parent, h264_Info *pInfo )
    130 {
    131 
    132    viddec_workload_item_t     wi;
    133    h264_slice_data 				slice_data;
    134 
    135    uint32_t		i=0, nitems=0, data=0;
    136    uint32_t 	bits_offset =0, byte_offset =0;
    137    uint8_t    	is_emul =0;
    138 
    139 
    140 	////////////////////// Update Reference list //////////////////
    141    if( (h264_PtypeB==pInfo->SliceHeader.slice_type)||(h264_PtypeP==pInfo->SliceHeader.slice_type) )
    142    {
    143       if(pInfo->SliceHeader.sh_refpic_l0.ref_pic_list_reordering_flag)
    144       {
    145          nitems = pInfo->SliceHeader.num_ref_idx_l0_active;
    146 
    147          for(i=0; i<nitems;i++)
    148          {
    149             if(viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[pInfo->slice_ref_list0[i]&0x1f]))==0)
    150             {
    151               pInfo->h264_list_replacement = (pInfo->slice_ref_list0[i]&0xFF)|0x80;
    152               break;
    153             }
    154          }
    155       }
    156       else
    157       {
    158          nitems = pInfo->dpb.listXsize[0];
    159 
    160          for(i=0; i<nitems;i++)
    161          {
    162             if(viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[pInfo->dpb.listX_0[i]&0x1f]))==0)
    163             {
    164               pInfo->h264_list_replacement = (pInfo->dpb.listX_0[i]&0xFF)|0x80;
    165               break;
    166             }
    167          }
    168       }
    169 
    170    }
    171    else
    172    {
    173       nitems =0;
    174    }
    175 	/////file ref list 0
    176   // h264_parse_emit_ref_list(parent, pInfo, 0);
    177 
    178    /////file ref list 1
    179    //h264_parse_emit_ref_list(parent, pInfo, 1);
    180 
    181 	///////////////////////////////////// Slice Data ////////////////////////////////
    182   // h264_fill_slice_data(pInfo, &slice_data);
    183 
    184    wi.vwi_type = VIDDEC_WORKLOAD_H264_SLICE_REG;
    185 
    186    wi.data.data_offset = slice_data.h264_bsd_slice_start;
    187    wi.data.data_payload[0] = slice_data.h264_bsd_slice_p1;
    188    wi.data.data_payload[1] = slice_data.h264_bsd_slice_p2;
    189 
    190    if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
    191    {
    192      // viddec_pm_append_workitem( parent , &wi);
    193    }
    194    else
    195    {
    196      // viddec_pm_append_workitem_next( parent , &wi);
    197    }
    198 
    199 
    200    ///////////////////////////predict weight table item and data if have///////////////////////////
    201    if(pInfo->h264_pwt_enabled)
    202    {
    203       wi.vwi_type = VIDDEC_WORKLOAD_H264_PWT_BITS_OFFSET;
    204       wi.data.data_offset = pInfo->h264_pwt_end_byte_offset- pInfo->h264_pwt_start_byte_offset+1;
    205       wi.data.data_payload[0] = pInfo->h264_pwt_start_bit_offset;
    206       wi.data.data_payload[1] = pInfo->h264_pwt_end_bit_offset;
    207 
    208       if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
    209       {
    210         // viddec_pm_append_workitem( parent , &wi);
    211 
    212          wi.vwi_type = VIDDEC_WORKLOAD_H264_PWT_ES_BYTES;
    213          wi.es.es_flags = 0;
    214         // viddec_pm_append_misc_tags(parent, pInfo->h264_pwt_start_byte_offset, pInfo->h264_pwt_end_byte_offset,&wi,1);
    215       }
    216       else
    217       {
    218        //  viddec_pm_append_workitem_next( parent , &wi);
    219 
    220          wi.vwi_type = VIDDEC_WORKLOAD_H264_PWT_ES_BYTES;
    221          wi.es.es_flags = 0;
    222        //  viddec_pm_append_misc_tags(parent, pInfo->h264_pwt_start_byte_offset, pInfo->h264_pwt_end_byte_offset,&wi,0);
    223       }
    224    }
    225 
    226 
    227  	////////////////////////////////// Update ES Buffer for Slice ///////////////////////
    228    viddec_pm_get_au_pos(parent, &bits_offset, &byte_offset, &is_emul);
    229 
    230 	//OS_INFO("DEBUG---entropy_coding_mode_flag:%d, bits_offset: %d\n", pInfo->active_PPS.entropy_coding_mode_flag, bits_offset);
    231 
    232    if(pInfo->active_PPS.entropy_coding_mode_flag)
    233    {
    234    	if(0!=bits_offset)  {
    235    		 data = data; // fix compilation warning
    236    		 // don't skip byte-aligned bits as those bits are actually
    237    		 // part of slice_data
    238          //viddec_pm_get_bits(parent, &data, 8-bits_offset);
    239       }
    240    }
    241 	else
    242    {
    243       if(0!=bits_offset)  {
    244          wi.vwi_type = VIDDEC_WORKLOAD_H264_SH_BITS_OFFSET;
    245          wi.data.data_offset = bits_offset;
    246          wi.data.data_payload[0]=0;
    247          wi.data.data_payload[1]=0;
    248 
    249          if(pInfo->push_to_cur) {			//cur is empty, fill new frame in cur
    250            // viddec_pm_append_workitem( parent , &wi);
    251          }
    252          else {
    253             //viddec_pm_append_workitem_next( parent , &wi);
    254          }
    255       }
    256    }
    257 
    258    if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
    259    {
    260       //viddec_pm_append_pixeldata( parent );
    261    }
    262    else
    263    {
    264       //viddec_pm_append_pixeldata_next( parent);
    265    }
    266 
    267 	return;
    268 }
    269 
    270 
    271 void h264_parse_emit_current_pic( void *parent, h264_Info *pInfo )
    272 {
    273 
    274    viddec_workload_item_t     wi;
    275 
    276    const uint32_t             *pl;
    277    uint32_t                   i=0,nitems=0;
    278 
    279    h264_pic_data pic_data;
    280 
    281    pInfo->qm_present_list=0;
    282 
    283    //h264_parse_emit_4X4_scaling_matrix(parent, pInfo);
    284   // h264_parse_emit_8X8_scaling_matrix(parent, pInfo);
    285 
    286   // h264_fill_pic_data(pInfo, &pic_data);
    287 
    288    // How many payloads must be generated
    289    nitems = (sizeof(h264_pic_data) + 7) / 8; // In QWORDs rounded up
    290 
    291    pl = (const uint32_t *) &pic_data;
    292 
    293    // Dump slice data to an array of workitems,  to do pl access non valid mem
    294    for( i = 0; i < nitems; i++ )
    295    {
    296       wi.vwi_type           = VIDDEC_WORKLOAD_H264_PIC_REG;
    297       wi.data.data_offset   = (unsigned int)pl - (unsigned int)&pic_data; // offset within struct
    298       wi.data.data_payload[0] = pl[0];
    299       wi.data.data_payload[1] = pl[1];
    300       pl += 2;
    301 
    302       if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
    303       {
    304 
    305        //  viddec_pm_append_workitem( parent, &wi );
    306       }
    307       else
    308       {
    309          //viddec_pm_append_workitem_next( parent, &wi );
    310       }
    311    }
    312 
    313 	return;
    314 }
    315 
    316 void h264_parse_emit_start_new_frame( void *parent, h264_Info *pInfo )
    317 {
    318 
    319    viddec_workload_item_t     wi;
    320    uint32_t                   i=0,nitems=0;
    321 
    322 	///////////////////////// Frame attributes//////////////////////////
    323 
    324    //Push data into current workload if first frame or frame_boundary already detected by non slice nal
    325    if( (pInfo->Is_first_frame_in_stream)||(pInfo->is_frame_boundary_detected_by_non_slice_nal))
    326    {
    327 		//viddec_workload_t			*wl_cur = viddec_pm_get_header( parent );
    328 		//pInfo->img.g_new_frame = 0;
    329 		pInfo->Is_first_frame_in_stream =0;
    330 		pInfo->is_frame_boundary_detected_by_non_slice_nal=0;
    331 		pInfo->push_to_cur = 1;
    332 		//h264_translate_parser_info_to_frame_attributes(wl_cur, pInfo);
    333    }
    334    else  // move to cur if frame boundary detected by previous non slice nal, or move to next if not
    335    {
    336 		//viddec_workload_t        *wl_next = viddec_pm_get_next_header (parent);
    337 
    338 		pInfo->push_to_cur = 0;
    339 		//h264_translate_parser_info_to_frame_attributes(wl_next, pInfo);
    340 
    341 		pInfo->is_current_workload_done=1;
    342    }
    343 
    344 	///////////////////// SPS/////////////////////
    345   // h264_parse_emit_sps(parent, pInfo);
    346 
    347 	/////////////////////display frames/////////////////////
    348 	nitems = pInfo->dpb.frame_numbers_need_to_be_displayed;
    349 
    350 	for(i=0; i<nitems; i++)
    351 	{
    352 		wi.vwi_type = VIDDEC_WORKLOAD_REF_FRAME_DISPLAY_0 + pInfo->dpb.frame_id_need_to_be_displayed[i];
    353 		wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_displayed[i];
    354 		wi.ref_frame.luma_phys_addr = 0;
    355 		wi.ref_frame.chroma_phys_addr = 0;
    356 
    357 		if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
    358 		{
    359 		  // viddec_pm_append_workitem( parent, &wi );
    360 		}
    361 		else
    362 		{
    363 		  // viddec_pm_append_workitem_next( parent, &wi );
    364 		}
    365 	}
    366 	pInfo->dpb.frame_numbers_need_to_be_displayed =0;
    367 
    368 
    369 	/////////////////////release frames/////////////////////
    370 	nitems = pInfo->dpb.frame_numbers_need_to_be_removed;
    371 
    372 	for(i=0; i<nitems; i++)
    373 	{
    374 	   wi.vwi_type = VIDDEC_WORKLOAD_REF_FRAME_RELEASE_0 + pInfo->dpb.frame_id_need_to_be_removed[i];
    375 	   wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_removed[i];
    376 	   wi.ref_frame.luma_phys_addr = 0;
    377 	   wi.ref_frame.chroma_phys_addr = 0;
    378 
    379 	   if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
    380 	   {
    381 	      //viddec_pm_append_workitem( parent, &wi );
    382 	   }
    383 	   else
    384 	   {
    385 	     // viddec_pm_append_workitem_next( parent, &wi );
    386 	   }
    387 
    388 	}
    389 	pInfo->dpb.frame_numbers_need_to_be_removed =0;
    390 
    391 	/////////////////////flust frames (do not display)/////////////////////
    392 	nitems = pInfo->dpb.frame_numbers_need_to_be_dropped;
    393 
    394 	for(i=0; i<nitems; i++)
    395 	{
    396 	   wi.vwi_type = VIDDEC_WORKLOAD_REF_FRAME_DROPOUT_0 + pInfo->dpb.frame_id_need_to_be_dropped[i];
    397 	   wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_dropped[i];
    398 	   wi.ref_frame.luma_phys_addr = 0;
    399 	   wi.ref_frame.chroma_phys_addr = 0;
    400 
    401 	   if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
    402 	   {
    403 	      //viddec_pm_append_workitem( parent, &wi );
    404 	   }
    405 	   else
    406 	   {
    407 	     // viddec_pm_append_workitem_next( parent, &wi );
    408 	   }
    409 
    410 	}
    411 	pInfo->dpb.frame_numbers_need_to_be_dropped =0;
    412 
    413 	/////////////////////updata DPB frames/////////////////////
    414 	nitems = pInfo->dpb.used_size;
    415 	for(i=0; i<nitems; i++)
    416 	{
    417 	   uint8_t fs_id = pInfo->dpb.fs_dpb_idc[i];
    418 
    419 	   if(viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[fs_id])) == 0)
    420 	   {
    421 	      wi.vwi_type = VIDDEC_WORKLOAD_DPB_ACTIVE_FRAME_0+fs_id;
    422 	      wi.ref_frame.reference_id = fs_id;
    423 	      wi.ref_frame.luma_phys_addr = 0;
    424 	      wi.ref_frame.chroma_phys_addr = 0;
    425 
    426 	      if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
    427 	      {
    428 	        // viddec_pm_append_workitem( parent, &wi );
    429 	      }
    430 	      else
    431 	      {
    432 	         //viddec_pm_append_workitem_next( parent, &wi );
    433 	      }
    434 	   }
    435 	}
    436 
    437 
    438 	/////////////////////updata dpb frames info (poc)/////////////////////
    439 	nitems = pInfo->dpb.used_size;
    440 	for(i=0; i<nitems; i++)
    441 	{
    442 	   uint8_t fs_id = pInfo->dpb.fs_dpb_idc[i];
    443 
    444 	   if(viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[fs_id])) == 0)
    445 	   {
    446 	      wi.vwi_type = VIDDEC_WORKLOAD_H264_DPB_FRAME_POC;
    447 	      wi.data.data_offset = fs_id;
    448 	      //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);
    449 
    450 	      switch(viddec_h264_get_is_used(&(pInfo->dpb.fs[fs_id])))
    451 	      {
    452 	         case (FRAME):{
    453 	            wi.data.data_payload[0] = pInfo->dpb.fs[fs_id].top_field.poc;
    454 	            wi.data.data_payload[1] = pInfo->dpb.fs[fs_id].bottom_field.poc;
    455 	            break;
    456 	         };
    457 
    458 	         case (TOP_FIELD):{
    459 	            wi.data.data_payload[0] = pInfo->dpb.fs[fs_id].top_field.poc;
    460 	            wi.data.data_payload[1] = 0;
    461 	            break;
    462 	         };
    463 
    464 	         case (BOTTOM_FIELD):{
    465 	            wi.data.data_payload[0] = 0;
    466 	            wi.data.data_payload[1] = pInfo->dpb.fs[fs_id].bottom_field.poc;
    467 	            break;
    468 	         };
    469 
    470 	         default : {
    471 	            wi.data.data_payload[0] = 0;
    472 	            wi.data.data_payload[1] = 0;
    473 	            break;
    474 	         };
    475 	      }
    476 
    477 
    478 	      if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
    479 	      {
    480 	       //  viddec_pm_append_workitem( parent, &wi );
    481 	      }
    482 	      else
    483 	      {
    484 	         //viddec_pm_append_workitem_next( parent, &wi );
    485 	      }
    486 
    487 	   }
    488 	}
    489 
    490 	/////////////////////Alloc buffer for current Existing frame/////////////////////
    491 	if(0!=pInfo->dpb.frame_numbers_need_to_be_allocated)
    492 	{
    493 	   if(pInfo->push_to_cur)
    494 	   {
    495 	     // viddec_workload_t        *wl_cur = viddec_pm_get_header (parent);
    496 	    //  wl_cur->is_reference_frame |= WORKLOAD_REFERENCE_FRAME | (pInfo->dpb.frame_id_need_to_be_allocated & 0x1f);
    497 	   }
    498 	   else
    499 	   {
    500 	     // viddec_workload_t        *wl_next = viddec_pm_get_next_header (parent);
    501 	      //wl_next->is_reference_frame |= WORKLOAD_REFERENCE_FRAME | (pInfo->dpb.frame_id_need_to_be_allocated & 0x1f);
    502 	   }
    503 	}
    504 	pInfo->dpb.frame_numbers_need_to_be_allocated =0;
    505 
    506 	return;
    507 }
    508 
    509 
    510 
    511 void h264_parse_emit_eos( void *parent, h264_Info *pInfo )
    512 {
    513 
    514    uint32_t nitems=0, i=0;
    515    viddec_workload_item_t	wi;
    516 
    517   	////
    518 	//// Now we can flush out all frames in DPB fro display
    519    	if(viddec_h264_get_is_used(&(pInfo->dpb.fs[pInfo->dpb.fs_dec_idc])) != 3)
    520 	{
    521 		h264_dpb_mark_dangling_field(&pInfo->dpb, pInfo->dpb.fs_dec_idc);  //, DANGLING_TYPE_GAP_IN_FRAME
    522 	}
    523 
    524    h264_dpb_store_previous_picture_in_dpb(pInfo, 0,0);
    525    h264_dpb_flush_dpb(pInfo, 1, 0, pInfo->active_SPS.num_ref_frames);
    526 
    527 
    528 	/////////////////////display frames/////////////////////
    529 	nitems = pInfo->dpb.frame_numbers_need_to_be_displayed;
    530 
    531 	for(i=0; i<nitems; i++)
    532 	{
    533 		wi.vwi_type = VIDDEC_WORKLOAD_EOS_DISPLAY_FRAME_0 + pInfo->dpb.frame_id_need_to_be_displayed[i];
    534 		wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_displayed[i];
    535 		wi.ref_frame.luma_phys_addr = 0;
    536 		wi.ref_frame.chroma_phys_addr = 0;
    537 
    538 		if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
    539 		{
    540 		   //viddec_pm_append_workitem( parent, &wi );
    541 		}
    542 		else
    543 		{
    544 		   //viddec_pm_append_workitem_next( parent, &wi );
    545 		}
    546 	}
    547 	pInfo->dpb.frame_numbers_need_to_be_displayed =0;
    548 
    549 
    550 	/////////////////////release frames/////////////////////
    551 	nitems = pInfo->dpb.frame_numbers_need_to_be_removed;
    552 
    553 	for(i=0; i<nitems; i++)
    554 	{
    555 	   wi.vwi_type = VIDDEC_WORKLOAD_EOS_RELEASE_FRAME_0 + pInfo->dpb.frame_id_need_to_be_removed[i];
    556 	   wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_removed[i];
    557 	   wi.ref_frame.luma_phys_addr = 0;
    558 	   wi.ref_frame.chroma_phys_addr = 0;
    559 
    560 	   if(pInfo->push_to_cur) //cur is empty, fill new frame in cur
    561 	   {
    562 	    //  viddec_pm_append_workitem( parent, &wi );
    563 			viddec_pm_set_next_frame_error_on_eos(parent, VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE);
    564 	   }
    565 	   else
    566 	   {
    567 	     // viddec_pm_append_workitem_next( parent, &wi );
    568        viddec_pm_set_next_frame_error_on_eos(parent, pInfo->wl_err_next);
    569 	   }
    570 	}
    571 	pInfo->dpb.frame_numbers_need_to_be_removed =0;
    572 
    573 	return;
    574 }
    575 #endif
    576