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