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