• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
cp_using_dma(uint32_t ddr_addr,uint32_t local_addr,uint32_t size,char to_ddr,char swap)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 
h264_parse_emit_current_slice(void * parent,h264_Info * pInfo)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 
h264_parse_emit_current_pic(void * parent,h264_Info * pInfo)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 
h264_parse_emit_start_new_frame(void * parent,h264_Info * pInfo)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 
h264_parse_emit_eos(void * parent,h264_Info * pInfo)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