1 /* Any workload management goes in this file */ 2 3 #include "viddec_fw_debug.h" 4 #include "viddec_parser_ops.h" 5 #include "h264.h" 6 #include "h264parse.h" 7 #include "viddec_fw_item_types.h" 8 #include "h264parse_dpb.h" 9 10 11 #include "viddec_fw_workload.h" 12 #include <auto_eas/gen4_mfd.h> 13 #include "viddec_pm_utils_bstream.h" 14 15 // picture parameter 1 16 #define PUT_BSD_PP1_IMG_DISPOSABLE_FLAG_BIT(w) (((uint32_t)w)&0x1) 17 #define PUT_BSD_PP1_SLICE_TYPE_BITS(w) ((((uint32_t)w)&0x7)<<1) 18 #define PUT_BSD_PP1_WEIGHTED_BIPRED_IDC_BITS(w) ((((uint32_t)w)&0x3)<<4) 19 #define PUT_BSD_PP1_WEIGHTED_PRED_FLAG_BIT(w) ((((uint32_t)w)&0x1)<<6) 20 #define PUT_BSD_PP1_NUM_REF_IDX_L0_BITS(w) ((((uint32_t)w)&0x3F)<<8) 21 #define PUT_BSD_PP1_NUM_REF_IDX_L1_BITS(w) ((((uint32_t)w)&0x3F)<<16) 22 23 // picture parameter 2 24 #define PUT_BSD_PP2_CABAC_INIT_IDC_BITS(w) (((uint32_t)w)&0x3) 25 #define PUT_BSD_PP2_QP_BITS(w) ((((uint32_t)w)&0x3F)<<2) 26 #define PUT_BSD_PP2_DISABLE_DBF_IDC_BITS(w) ((((uint32_t)w)&0x3)<<8) 27 #define PUT_BSD_PP2_ALPHA_C0_OFFSET_DIV2_BITS(w) ((((uint32_t)w)&0xF)<<10) 28 #define PUT_BSD_PP2_BETA_OFFSET_DIV2_BITS(w) ((((uint32_t)w)&0xF)<<14) 29 #define PUT_BSD_PP2_IMG_DIRECT_TYPE_BIT(w) ((((uint32_t)w)&0x1)<<18) 30 #define PUT_BSD_PP2_CHROMA_QP_OFFSET_BITS(w) ((((uint32_t)w)&0x1F)<<19) 31 #define PUT_BSD_PP2_CHROMA_QP_OFFSET_2_BITS(w) ((((uint32_t)w)&0x1F)<<24) 32 33 34 // slice start parameter 35 #define PUT_BSD_SS_START_ADDR_BITS(w) (((uint32_t)w)&0x7fff) // 14:0 current slice start address 36 #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 37 #define PUT_BSD_SS_SKIP_TYPE_BIT(w) ((((uint32_t)w)&0x1)<<24) // 0: P-skip, 1: I-skip 38 #define PUT_BSD_SS_SKIP_REWIND_BITS(w) ((((uint32_t)w)&0xf)<<28) // number of MB or MBAFF pairs to rewind before skip 39 40 //h264_dpb_init 41 #define PUT_FRAME_WIDTH_MB_BITS(w) (((uint32_t)w)&0x7F) 42 #define PUT_FRAME_HEIGHT_MB_BITS(w) ((((uint32_t)w)&0x7F)<<16) 43 44 //dpb lut table init 45 //#define PUT_BSD_IMAGE_FRAME_STORE_IDC_BITS(w) ((((uint32_t)w)&0x1F)<<8) 46 47 //h264 img init 48 #define PUT_BSD_IMAGE_STRUCTURE_BITS(w) (((uint32_t)w)&0x3) 49 #define PUT_BSD_IMAGE_IDR_BIT(w) ((((uint32_t)w)&0x1)<<2) 50 #define PUT_BSD_IMAGE_MBAFF_FRAME_FLAG_BIT(w) ((((uint32_t)w)&0x1)<<3) 51 #define PUT_BSD_IMAGE_ENTROPY_CODING_MODE_FLAG_BIT(w) ((((uint32_t)w)&0x1)<<4) 52 #define PUT_BSD_IMAGE_CONSTRAINED_INTRA_PRED_FLAG_BIT(w) ((((uint32_t)w)&0x1)<<5) 53 #define PUT_BSD_IMG_FRAME_MBS_ONLY_FLAG_BIT(w) ((((uint32_t)w)&0x1)<<6) 54 #define PUT_BSD_IMG_DIRECT_8X8_INFER_FLAG_BIT(w) ((((uint32_t)w)&0x1)<<7) 55 #define PUT_BSD_IMAGE_FRAME_STORE_IDC_BITS(w) ((((uint32_t)w)&0x1F)<<8) 56 57 #define PUT_HPD_BSD_IMG_TRANSFORM_8X8_MODE_FLAG_BIT(w) ((((uint32_t)w)&0x1)<<13) 58 #define PUT_HPD_BSD_IMG_MONOCHROME_FLAG_BIT(w) ((((uint32_t)w)&0x1)<<14) 59 #define PUT_HPD_BSD_IMG_GREY_NONEXISTING_FLAG_BIT(w) ((((uint32_t)w)&0x1)<<15) 60 #define PUT_HPD_BSD_IMG_QM_PRESENT_FLAG_BIT(w) ((((uint32_t)w)&0x1)<<16) 61 #define PUT_HPD_BSD_IMG_QM_LIST_FLAGS_BITS(w) ((((uint32_t)w)&0xFF)<<17) 62 #define PUT_HPD_BSD_IMG_MONOCHROME_PWT_FLAG_BIT(w) ((((uint32_t)w)&0x1)<<25) 63 64 65 extern void h264_dpb_store_previous_picture_in_dpb(h264_Info * pInfo, 66 int32_t NonExisting, 67 int32_t use_old); 68 69 extern void h264_dpb_flush_dpb (h264_Info * pInfo,int32_t output_all, int32_t keep_complement, int32_t num_ref_frames); 70 71 72 73 void h264_translate_parser_info_to_frame_attributes(viddec_workload_t *wl, h264_Info *pInfo) 74 { 75 76 viddec_frame_attributes_t *attrs = &wl->attrs; 77 78 79 80 //// Cont_size 81 attrs->cont_size.height = pInfo->img.FrameHeightInMbs*16; 82 attrs->cont_size.width = pInfo->img.PicWidthInMbs*16; 83 84 //// The following attributes will be updated in slice level 85 attrs->h264.used_for_reference = 0; 86 attrs->h264.top_field_first = 0; 87 attrs->h264.top_field_poc = 0; 88 attrs->h264.bottom_field_poc = 0; 89 attrs->h264.field_pic_flag = 0; 90 91 #if 1 92 /// Double check the size late!!!!! 93 //attrs->h264.cropped_size.width = pInfo->img.PicWidthInMbs*16; 94 //attrs->h264.cropped_size.height = pInfo->img.PicWidthInMbs*16; 95 96 if( (pInfo->active_SPS.sps_disp.frame_cropping_flag) && 97 (pInfo->active_SPS.sps_disp.chroma_format_idc < 4)) 98 { 99 int32_t CropUnitX, CropUnitY; 100 int32_t SubWidthC, SubHeightC; 101 102 if(pInfo->active_SPS.sps_disp.chroma_format_idc == 0) 103 { 104 CropUnitX = 1; 105 CropUnitY = 2 - pInfo->active_SPS.sps_disp.frame_mbs_only_flag; 106 } 107 else 108 { 109 SubWidthC = 2 - ((pInfo->active_SPS.sps_disp.chroma_format_idc - 1) >> 1); 110 SubHeightC = 2 - ((pInfo->active_SPS.sps_disp.chroma_format_idc - 1) >>1) 111 - ((pInfo->active_SPS.sps_disp.chroma_format_idc - 1) & 0x1); 112 CropUnitX = SubWidthC; 113 CropUnitY = SubHeightC * (2 - pInfo->active_SPS.sps_disp.frame_mbs_only_flag); 114 } 115 116 if ((int32_t)attrs->cont_size.height >(pInfo->active_SPS.sps_disp.frame_crop_rect_bottom_offset*CropUnitY)) 117 { 118 attrs->cont_size.height -= (pInfo->active_SPS.sps_disp.frame_crop_rect_bottom_offset*CropUnitY); 119 //attrs->h264.cropped_size.height-= (pInfo->active_SPS.sps_disp.frame_crop_rect_bottom_offset*CropUnitY); 120 } 121 } 122 /// Pan-Scan Info 123 124 #endif 125 126 } 127 128 129 static void h264_parse_update_frame_attributes(void *parent, h264_Info *pInfo) 130 { 131 viddec_workload_t *wl_cur, *wl_next; 132 viddec_frame_attributes_t *attrs; 133 uint8_t frame_type=0; 134 135 136 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 137 { 138 wl_cur = viddec_pm_get_header( parent ); 139 attrs = &wl_cur->attrs; 140 } 141 else 142 { 143 wl_next = viddec_pm_get_next_header (parent); 144 attrs = &wl_next->attrs; 145 } 146 147 /////////update frame type 148 if((pInfo->dpb.fs[pInfo->dpb.fs_dec_idc].pic_type)&(0x1 << FRAME_TYPE_STRUCTRUE_OFFSET)) 149 { 150 frame_type = ( (pInfo->dpb.fs[pInfo->dpb.fs_dec_idc].pic_type)&((0x7 << FRAME_TYPE_FRAME_OFFSET)) )>> FRAME_TYPE_FRAME_OFFSET; 151 switch(frame_type) 152 { 153 case FRAME_TYPE_IDR: attrs->frame_type = VIDDEC_FRAME_TYPE_IDR; break; 154 case FRAME_TYPE_I: attrs->frame_type = VIDDEC_FRAME_TYPE_I; break; 155 case FRAME_TYPE_P: attrs->frame_type = VIDDEC_FRAME_TYPE_P; break; 156 case FRAME_TYPE_B: attrs->frame_type = VIDDEC_FRAME_TYPE_B; break; 157 default: attrs->frame_type = VIDDEC_FRAME_TYPE_INVALID; break; 158 } 159 160 attrs->bottom_field_type = VIDDEC_FRAME_TYPE_INVALID; 161 } 162 else 163 { 164 frame_type = ( (pInfo->dpb.fs[pInfo->dpb.fs_dec_idc].pic_type)&((0x7 << FRAME_TYPE_TOP_OFFSET)) )>> FRAME_TYPE_TOP_OFFSET; 165 switch(frame_type) 166 { 167 case FRAME_TYPE_IDR: attrs->frame_type = VIDDEC_FRAME_TYPE_IDR; break; 168 case FRAME_TYPE_I: attrs->frame_type = VIDDEC_FRAME_TYPE_I; break; 169 case FRAME_TYPE_P: attrs->frame_type = VIDDEC_FRAME_TYPE_P; break; 170 case FRAME_TYPE_B: attrs->frame_type = VIDDEC_FRAME_TYPE_B; break; 171 default: attrs->frame_type = VIDDEC_FRAME_TYPE_INVALID; break; 172 173 } 174 175 frame_type = ( (pInfo->dpb.fs[pInfo->dpb.fs_dec_idc].pic_type)&((0x7 << FRAME_TYPE_BOTTOM_OFFSET)) )>> FRAME_TYPE_BOTTOM_OFFSET; 176 switch(frame_type) 177 { 178 case FRAME_TYPE_IDR: attrs->bottom_field_type = VIDDEC_FRAME_TYPE_IDR; break; 179 case FRAME_TYPE_I: attrs->bottom_field_type = VIDDEC_FRAME_TYPE_I; break; 180 case FRAME_TYPE_P: attrs->bottom_field_type = VIDDEC_FRAME_TYPE_P; break; 181 case FRAME_TYPE_B: attrs->bottom_field_type = VIDDEC_FRAME_TYPE_B; break; 182 default: attrs->bottom_field_type = VIDDEC_FRAME_TYPE_INVALID; break; 183 184 } 185 } 186 187 /////////update is_referece flag 188 attrs->h264.used_for_reference |= (pInfo->SliceHeader.nal_ref_idc == 0)? 0: 1; 189 190 /////////update POC 191 attrs->h264.top_field_poc = pInfo->img.toppoc; 192 attrs->h264.bottom_field_poc = pInfo->img.bottompoc; 193 194 //////// update TFF 195 if(attrs->h264.top_field_poc <= attrs->h264.bottom_field_poc) { 196 attrs->h264.top_field_first = 1; 197 } else { 198 attrs->h264.top_field_first = 0; 199 } 200 201 /////// update field_pic_flag 202 //attrs->h264.field_pic_flag |= (pInfo->SliceHeader.field_pic_flag << pInfo->SliceHeader.bottom_field_flag); 203 attrs->h264.field_pic_flag |= pInfo->SliceHeader.field_pic_flag; 204 205 return; 206 } 207 208 209 static void h264_fill_slice_data(h264_Info *pInfo, h264_slice_data * p_slice_data) 210 { 211 uint32_t data=0; 212 uint32_t first_mb_in_slice =0; 213 214 215 216 ////////////fill pic parameters 1 217 data = PUT_BSD_PP1_IMG_DISPOSABLE_FLAG_BIT( (pInfo->SliceHeader.nal_ref_idc == 0) ) + 218 PUT_BSD_PP1_SLICE_TYPE_BITS(pInfo->SliceHeader.slice_type) + 219 PUT_BSD_PP1_WEIGHTED_BIPRED_IDC_BITS(pInfo->active_PPS.weighted_bipred_idc) + 220 PUT_BSD_PP1_WEIGHTED_PRED_FLAG_BIT(pInfo->active_PPS.weighted_pred_flag) + 221 PUT_BSD_PP1_NUM_REF_IDX_L0_BITS(pInfo->SliceHeader.num_ref_idx_l0_active) + 222 PUT_BSD_PP1_NUM_REF_IDX_L1_BITS(pInfo->SliceHeader.num_ref_idx_l1_active); 223 p_slice_data->h264_bsd_slice_p1 = data; 224 225 226 ///////////fill pic parameters 2 227 data = PUT_BSD_PP2_CABAC_INIT_IDC_BITS(pInfo->SliceHeader.cabac_init_idc) + 228 PUT_BSD_PP2_QP_BITS( (pInfo->SliceHeader.slice_qp_delta + pInfo->active_PPS.pic_init_qp_minus26+26) ) + 229 PUT_BSD_PP2_DISABLE_DBF_IDC_BITS(pInfo->SliceHeader.disable_deblocking_filter_idc) + 230 PUT_BSD_PP2_ALPHA_C0_OFFSET_DIV2_BITS(pInfo->SliceHeader.slice_alpha_c0_offset_div2) + 231 PUT_BSD_PP2_BETA_OFFSET_DIV2_BITS(pInfo->SliceHeader.slice_beta_offset_div2) + 232 PUT_BSD_PP2_IMG_DIRECT_TYPE_BIT(pInfo->SliceHeader.direct_spatial_mv_pred_flag) + 233 PUT_BSD_PP2_CHROMA_QP_OFFSET_BITS(pInfo->active_PPS.chroma_qp_index_offset) + 234 PUT_BSD_PP2_CHROMA_QP_OFFSET_2_BITS(pInfo->active_PPS.second_chroma_qp_index_offset); 235 236 p_slice_data->h264_bsd_slice_p2 = data; 237 238 /////////fill slice start 239 first_mb_in_slice = pInfo->SliceHeader.first_mb_in_slice; 240 241 data = PUT_BSD_SS_START_ADDR_BITS(first_mb_in_slice); 242 data |= PUT_BSD_SS_SKIP_FS_IDC_BITS( pInfo->h264_list_replacement) | 243 PUT_BSD_SS_SKIP_TYPE_BIT(0) | 244 PUT_BSD_SS_SKIP_REWIND_BITS((pInfo->img.MbaffFrameFlag? 2: 3)); 245 246 p_slice_data->h264_bsd_slice_start = data; 247 248 } 249 250 251 static void h264_parse_emit_4X4_scaling_matrix( void *parent, h264_Info *pInfo ) 252 { 253 254 viddec_workload_item_t wi; 255 256 uint32_t i=0, n_items=0; 257 uint32_t qm_type=0; 258 259 260 for( i = 0; i < 6; i++ ) 261 { 262 qm_type = FB_QM; 263 if (pInfo->active_SPS.seq_scaling_matrix_present_flag) // check sps first 264 { 265 if (pInfo->active_SPS.seq_scaling_list_present_flag[i]) 266 { 267 pInfo->qm_present_list |= ((0x1)<<i); 268 269 if (pInfo->active_SPS.UseDefaultScalingMatrix4x4Flag[i]) { 270 qm_type = DEFAULT_QM; 271 } else { 272 qm_type = SPS_QM; 273 } 274 } 275 } 276 277 if (pInfo->active_PPS.pic_scaling_matrix_present_flag) // then check pps 278 { 279 if (pInfo->active_PPS.pic_scaling_list_present_flag[i]) 280 { 281 pInfo->qm_present_list |= ((0x1)<<i); 282 if (pInfo->active_PPS.UseDefaultScalingMatrix4x4Flag[i]) { 283 qm_type = DEFAULT_QM; 284 } else { 285 qm_type = PPS_QM; 286 } 287 } 288 else 289 { 290 if ((i != 0) && (i != 3) && (i < 6)) { 291 pInfo->qm_present_list &= ~((0x1)<<i); 292 qm_type = FB_QM; 293 } 294 } 295 } 296 297 298 ///////////////////// Emit out Scaling_matrix////////////////////// 299 wi.vwi_type = VIDDEC_WORKLOAD_H264_SCALING_MATRIX; 300 // data_offset 0x aa bb cc dd 301 // bb is the workload item offset 302 // cc is the qm_type 303 // dd is the matrix number 304 // 305 switch (qm_type) 306 { 307 case (SPS_QM):{ 308 309 for(n_items =0; n_items<2; n_items++) 310 { 311 wi.data.data_offset = i + (SPS_QM << 4) + (n_items <<8); 312 wi.data.data_payload[0] = ((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+0]))+ 313 (((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+1]))<<8)+ 314 (((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+2]))<<16)+ 315 (((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+3]))<<24); 316 wi.data.data_payload[1] = ((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+4]))+ 317 (((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+5]))<<8)+ 318 (((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+6]))<<16)+ 319 (((uint32_t)(pInfo->active_SPS.ScalingList4x4[i][n_items*8+7]))<<24); 320 321 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 322 { 323 viddec_pm_append_workitem( parent, &wi ); 324 } 325 else 326 { 327 viddec_pm_append_workitem_next( parent, &wi ); 328 } 329 330 } 331 332 break; 333 } 334 case (PPS_QM):{ 335 336 for(n_items =0; n_items<2; n_items++) 337 { 338 wi.data.data_offset = i + (PPS_QM << 4) + (n_items <<8); 339 wi.data.data_payload[0] = ((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+0]))+ 340 (((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+1]))<<8)+ 341 (((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+2]))<<16)+ 342 (((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+3]))<<24); 343 wi.data.data_payload[1] = ((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+4]))+ 344 (((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+5]))<<8)+ 345 (((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+6]))<<16)+ 346 (((uint32_t)(pInfo->active_PPS.ScalingList4x4[i][n_items*8+7]))<<24); 347 348 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 349 { 350 viddec_pm_append_workitem( parent, &wi ); 351 } 352 else 353 { 354 viddec_pm_append_workitem_next( parent, &wi ); 355 } 356 } 357 358 break; 359 } 360 case (DEFAULT_QM): 361 { 362 363 wi.data.data_offset = i + (DEFAULT_QM << 4); 364 wi.data.data_payload[0] = 0; 365 wi.data.data_payload[1] = 0; 366 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 367 { 368 viddec_pm_append_workitem( parent, &wi ); 369 } 370 else 371 { 372 viddec_pm_append_workitem_next( parent, &wi ); 373 } 374 break; 375 } 376 default: 377 { 378 break; 379 } 380 } 381 } 382 383 } 384 385 static void h264_parse_emit_8X8_scaling_matrix( void *parent, h264_Info *pInfo ) 386 { 387 388 viddec_workload_item_t wi; 389 390 uint32_t i=0, n_items=0; 391 uint32_t qm_type=0; 392 393 for( i = 6; i < 8; i++ ) 394 { 395 qm_type = FB_QM; 396 if (pInfo->active_SPS.seq_scaling_matrix_present_flag) // check sps first 397 { 398 if (pInfo->active_SPS.seq_scaling_list_present_flag[i]) 399 { 400 pInfo->qm_present_list |= ((0x1)<<i); 401 402 if (pInfo->active_SPS.UseDefaultScalingMatrix8x8Flag[i-6]) 403 { 404 qm_type = DEFAULT_QM; 405 } 406 else 407 { 408 qm_type = SPS_QM; 409 } 410 } 411 } 412 413 if (pInfo->active_PPS.pic_scaling_matrix_present_flag) // then check pps 414 { 415 if (pInfo->active_PPS.pic_scaling_list_present_flag[i]) 416 { 417 pInfo->qm_present_list |= ((0x1)<<i); 418 419 if (pInfo->active_PPS.UseDefaultScalingMatrix8x8Flag[i-6]) 420 { 421 qm_type = DEFAULT_QM; 422 } 423 else 424 { 425 qm_type = PPS_QM; 426 } 427 } 428 } 429 wi.vwi_type = VIDDEC_WORKLOAD_H264_SCALING_MATRIX; 430 431 // data_offset 0x aa bb cc dd 432 // bb is the workload item offset 433 // cc is the qm_type 434 // dd is the matrix number 435 // 436 switch (qm_type) 437 { 438 case (SPS_QM): 439 { 440 for(n_items =0; n_items<8; n_items++) 441 { 442 wi.data.data_offset = i + (SPS_QM << 4) + (n_items <<8); 443 wi.data.data_payload[0] = ((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+0]))+ 444 (((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+1]))<<8)+ 445 (((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+2]))<<16)+ 446 (((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+3]))<<24); 447 wi.data.data_payload[1] = ((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+4]))+ 448 (((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+5]))<<8)+ 449 (((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+6]))<<16)+ 450 (((uint32_t)(pInfo->active_SPS.ScalingList8x8[i-6][n_items*8+7]))<<24); 451 452 if(pInfo->push_to_cur) { //cur is empty, fill new frame in cur 453 viddec_pm_append_workitem( parent, &wi ); 454 } else { 455 viddec_pm_append_workitem_next( parent, &wi ); 456 } 457 } 458 break; 459 } 460 case (PPS_QM): 461 { 462 for(n_items =0; n_items<8; n_items++) 463 { 464 wi.data.data_offset = i + (PPS_QM << 4) + (n_items <<8); 465 wi.data.data_payload[0] = ((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+0]))+ 466 (((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+1]))<<8)+ 467 (((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+2]))<<16)+ 468 (((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+3]))<<24); 469 wi.data.data_payload[1] = ((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+4]))+ 470 (((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+5]))<<8)+ 471 (((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+6]))<<16)+ 472 (((uint32_t)(pInfo->active_PPS.ScalingList8x8[i-6][n_items*8+7]))<<24); 473 474 if(pInfo->push_to_cur) { //cur is empty, fill new frame in cur 475 viddec_pm_append_workitem( parent, &wi ); 476 } else { 477 viddec_pm_append_workitem_next( parent, &wi ); 478 } 479 } 480 481 break; 482 } 483 case (DEFAULT_QM): 484 { 485 wi.data.data_offset = i + (DEFAULT_QM << 4); 486 wi.data.data_payload[0] = 0; 487 wi.data.data_payload[1] = 0; 488 if(pInfo->push_to_cur) { //cur is empty, fill new frame in cur 489 viddec_pm_append_workitem( parent, &wi ); 490 } else { 491 viddec_pm_append_workitem_next( parent, &wi ); 492 } 493 494 break; 495 } 496 default:{ 497 break; 498 } 499 } 500 } 501 502 } 503 504 505 506 static void h264_fill_pic_data(h264_Info *pInfo, h264_pic_data * p_pic_data) 507 { 508 uint32_t data=0; 509 uint32_t dec_idc =0; 510 uint32_t frame_structure =0; 511 512 //fill h264_dpb_init 513 data = PUT_FRAME_WIDTH_MB_BITS(pInfo->dpb.PicWidthInMbs) + 514 PUT_FRAME_HEIGHT_MB_BITS(pInfo->dpb.FrameHeightInMbs); 515 516 p_pic_data->h264_dpb_init = data; 517 518 ////////////////////////////////file current pic info 519 data = 0; 520 dec_idc = pInfo->dpb.fs_dec_idc; 521 frame_structure = pInfo->img.structure; 522 if(frame_structure == FRAME) 523 frame_structure=0; 524 //data = PUT_BSD_IMAGE_FRAME_STORE_IDC_BITS(pInfo->dpb.fs[dec_idc].fs_idc); 525 526 //p_pic_data->h264_cur_bsd_img_init= data; 527 528 data = PUT_BSD_IMAGE_STRUCTURE_BITS(frame_structure) + 529 PUT_BSD_IMAGE_IDR_BIT(pInfo->nal_unit_type == h264_NAL_UNIT_TYPE_IDR) + 530 PUT_BSD_IMAGE_MBAFF_FRAME_FLAG_BIT(pInfo->img.MbaffFrameFlag) + 531 PUT_BSD_IMAGE_ENTROPY_CODING_MODE_FLAG_BIT(pInfo->active_PPS.entropy_coding_mode_flag) + 532 PUT_BSD_IMAGE_CONSTRAINED_INTRA_PRED_FLAG_BIT(pInfo->active_PPS.constrained_intra_pred_flag) + 533 PUT_BSD_IMG_FRAME_MBS_ONLY_FLAG_BIT(pInfo->active_SPS.sps_disp.frame_mbs_only_flag) + 534 PUT_BSD_IMG_DIRECT_8X8_INFER_FLAG_BIT(pInfo->active_SPS.sps_disp.direct_8x8_inference_flag) + 535 PUT_HPD_BSD_IMG_TRANSFORM_8X8_MODE_FLAG_BIT(pInfo->active_PPS.transform_8x8_mode_flag) + 536 PUT_HPD_BSD_IMG_MONOCHROME_FLAG_BIT(((pInfo->active_SPS.sps_disp.chroma_format_idc==0)? 0x1: 0x0)) + 537 PUT_HPD_BSD_IMG_GREY_NONEXISTING_FLAG_BIT(0x0) + 538 PUT_HPD_BSD_IMG_QM_PRESENT_FLAG_BIT((pInfo->active_PPS.pic_scaling_matrix_present_flag||pInfo->active_SPS.seq_scaling_matrix_present_flag)) + 539 PUT_HPD_BSD_IMG_QM_LIST_FLAGS_BITS(pInfo->qm_present_list) + 540 PUT_HPD_BSD_IMG_MONOCHROME_PWT_FLAG_BIT(0x1) + 541 PUT_BSD_IMAGE_FRAME_STORE_IDC_BITS(pInfo->dpb.fs[dec_idc].fs_idc); 542 543 p_pic_data->h264_cur_bsd_img_init= data; 544 545 //to do: add qm list 546 //PUT_HPD_BSD_IMG_QM_LIST_FLAGS_BITS(pInfo->img.q .qm_present_list) + 547 //printf("structure = %d, tpoc = %d, bpoc = %d\n", pInfo->img.structure, pInfo->img.toppoc, pInfo->img.bottompoc); 548 549 if(pInfo->img.structure == FRAME) 550 { 551 // Write down POC 552 p_pic_data->h264_cur_mpr_tf_poc = pInfo->img.toppoc; 553 p_pic_data->h264_cur_mpr_bf_poc = pInfo->img.bottompoc; 554 }else if (pInfo->img.structure == TOP_FIELD) 555 { 556 // Write down POC 557 p_pic_data->h264_cur_mpr_tf_poc = pInfo->img.toppoc; 558 p_pic_data->h264_cur_mpr_bf_poc = 0; 559 } 560 else if (pInfo->img.structure == BOTTOM_FIELD) 561 { 562 // Write down POC 563 p_pic_data->h264_cur_mpr_tf_poc = 0; 564 p_pic_data->h264_cur_mpr_bf_poc = pInfo->img.bottompoc; 565 } 566 else 567 { 568 // Write down POC 569 p_pic_data->h264_cur_mpr_tf_poc = 0; 570 p_pic_data->h264_cur_mpr_bf_poc = 0; 571 } 572 573 return; 574 } 575 576 static void h264_parse_emit_sps(void *parent, h264_Info *pInfo) 577 { 578 viddec_workload_item_t wi; 579 580 if(pInfo->Is_SPS_updated) 581 { 582 viddec_fw_reset_workload_item(&wi); 583 wi.vwi_type = VIDDEC_WORKLOAD_SEQUENCE_INFO; 584 585 viddec_fw_h264_sps_set_profile_idc(&(wi.h264_sps), pInfo->active_SPS.profile_idc); 586 viddec_fw_h264_sps_set_level_idc(&(wi.h264_sps), pInfo->active_SPS.level_idc); 587 viddec_fw_h264_sps_set_chroma_format_idc(&(wi.h264_sps), pInfo->active_SPS.sps_disp.chroma_format_idc); 588 viddec_fw_h264_sps_set_num_ref_frames(&(wi.h264_sps), pInfo->active_SPS.num_ref_frames); 589 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); 590 viddec_fw_h264_sps_set_frame_mbs_only_flag(&(wi.h264_sps), pInfo->active_SPS.sps_disp.frame_mbs_only_flag); 591 viddec_fw_h264_sps_set_frame_cropping_flag(&(wi.h264_sps), pInfo->active_SPS.sps_disp.frame_cropping_flag); 592 viddec_fw_h264_sps_set_vui_parameters_present_flag(&(wi.h264_sps), pInfo->active_SPS.sps_disp.vui_parameters_present_flag); 593 wi.h264_sps.pic_width_in_mbs_minus1 = pInfo->active_SPS.sps_disp.pic_width_in_mbs_minus1; 594 wi.h264_sps.pic_height_in_map_units_minus1 = pInfo->active_SPS.sps_disp.pic_height_in_map_units_minus1; 595 596 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 597 { 598 viddec_pm_append_workitem( parent, &wi ); 599 } 600 else 601 { 602 viddec_pm_append_workitem_next( parent, &wi ); 603 } 604 605 viddec_fw_reset_workload_item(&wi); 606 if(pInfo->active_SPS.sps_disp.frame_cropping_flag) 607 { 608 wi.vwi_type = VIDDEC_WORKLOAD_H264_CROPPING; 609 viddec_fw_h264_cropping_set_left(&(wi.h264_cropping), pInfo->active_SPS.sps_disp.frame_crop_rect_left_offset); 610 viddec_fw_h264_cropping_set_right(&(wi.h264_cropping), pInfo->active_SPS.sps_disp.frame_crop_rect_right_offset); 611 viddec_fw_h264_cropping_set_top(&(wi.h264_cropping), pInfo->active_SPS.sps_disp.frame_crop_rect_top_offset); 612 viddec_fw_h264_cropping_set_bottom(&(wi.h264_cropping), pInfo->active_SPS.sps_disp.frame_crop_rect_bottom_offset); 613 614 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 615 { 616 viddec_pm_append_workitem( parent, &wi ); 617 } 618 else 619 { 620 viddec_pm_append_workitem_next( parent, &wi ); 621 } 622 } 623 viddec_fw_reset_workload_item(&wi); 624 if(pInfo->active_SPS.sps_disp.vui_parameters_present_flag == 1) 625 { 626 wi.vwi_type = VIDDEC_WORKLOAD_DISPLAY_INFO; 627 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); 628 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); 629 viddec_fw_h264_vui_set_pic_struct_present_flag(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.pic_struct_present_flag); 630 viddec_fw_h264_vui_set_timing_info_present_flag(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.timing_info_present_flag); 631 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); 632 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); 633 634 if(pInfo->active_SPS.sps_disp.vui_seq_parameters.aspect_ratio_info_present_flag == 1) 635 { 636 viddec_fw_h264_vui_set_aspect_ratio_idc(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.aspect_ratio_idc); 637 if(h264_AR_Extended_SAR == pInfo->active_SPS.sps_disp.vui_seq_parameters.aspect_ratio_idc) 638 { 639 viddec_fw_h264_vui_set_sar_width(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.sar_width); 640 viddec_fw_h264_vui_set_sar_height(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.sar_height); 641 } 642 } 643 644 645 if(pInfo->active_SPS.sps_disp.vui_seq_parameters.video_signal_type_present_flag) 646 { 647 viddec_fw_h264_vui_set_colour_description_present_flag(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.colour_description_present_flag); 648 if(pInfo->active_SPS.sps_disp.vui_seq_parameters.colour_description_present_flag) 649 { 650 viddec_fw_h264_vui_set_colour_primaries(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.colour_primaries); 651 viddec_fw_h264_vui_set_transfer_characteristics(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.transfer_characteristics); 652 } 653 viddec_fw_h264_vui_set_video_format(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.video_format); 654 } 655 656 if(pInfo->active_SPS.sps_disp.vui_seq_parameters.timing_info_present_flag == 1) 657 { 658 viddec_fw_h264_vui_set_fixed_frame_rate_flag(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.fixed_frame_rate_flag); 659 } 660 661 if( (pInfo->active_SPS.sps_disp.vui_seq_parameters.nal_hrd_parameters_present_flag == 1) 662 || (pInfo->active_SPS.sps_disp.vui_seq_parameters.vcl_hrd_parameters_present_flag == 1)) 663 { 664 viddec_fw_h264_vui_set_low_delay_hrd_flag(&(wi.h264_vui), pInfo->active_SPS.sps_disp.vui_seq_parameters.low_delay_hrd_flag); 665 } 666 667 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 668 { 669 viddec_pm_append_workitem( parent, &wi ); 670 } 671 else 672 { 673 viddec_pm_append_workitem_next( parent, &wi ); 674 } 675 } 676 677 viddec_fw_reset_workload_item(&wi); 678 679 if(pInfo->active_SPS.sps_disp.vui_seq_parameters.timing_info_present_flag == 1) 680 { 681 wi.vwi_type = VIDDEC_WORKLOAD_H264_VUI_TIMING_INFO; 682 683 wi.h264_vui_time_info.num_units_in_tick = pInfo->active_SPS.sps_disp.vui_seq_parameters.num_units_in_tick; 684 wi.h264_vui_time_info.time_scale = pInfo->active_SPS.sps_disp.vui_seq_parameters.time_scale; 685 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 686 { 687 viddec_pm_append_workitem( parent, &wi ); 688 } 689 else 690 { 691 viddec_pm_append_workitem_next( parent, &wi ); 692 } 693 } 694 695 696 pInfo->Is_SPS_updated =0; 697 698 } 699 700 return; 701 } 702 703 704 705 706 static void h264_parse_emit_ref_list( void *parent, h264_Info *pInfo, uint32_t list_id) 707 { 708 uint32_t i=0, nitems=0, byte_index=0, data=0, data_writed=0; 709 uint8_t *p_list; 710 viddec_workload_item_t wi; 711 712 if(0 == list_id) 713 { 714 wi.vwi_type = VIDDEC_WORKLOAD_H264_REFR_LIST_0; 715 716 if( (h264_PtypeB==pInfo->SliceHeader.slice_type)||(h264_PtypeP==pInfo->SliceHeader.slice_type) ) 717 { 718 nitems = pInfo->SliceHeader.num_ref_idx_l0_active; 719 if(pInfo->SliceHeader.sh_refpic_l0.ref_pic_list_reordering_flag) 720 { 721 p_list = pInfo->slice_ref_list0; 722 } 723 else 724 { 725 p_list = pInfo->dpb.listX_0; 726 } 727 } 728 else 729 { 730 nitems =0; 731 p_list = pInfo->dpb.listX_0; 732 } 733 } 734 else 735 { 736 wi.vwi_type = VIDDEC_WORKLOAD_H264_REFR_LIST_1; 737 738 if( h264_PtypeB==pInfo->SliceHeader.slice_type) 739 { 740 nitems = pInfo->SliceHeader.num_ref_idx_l1_active; 741 if(pInfo->SliceHeader.sh_refpic_l1.ref_pic_list_reordering_flag) 742 { 743 p_list = pInfo->slice_ref_list1; 744 } 745 else 746 { 747 p_list = pInfo->dpb.listX_1; 748 } 749 } 750 else 751 { 752 nitems = 0; 753 p_list = pInfo->dpb.listX_1; 754 } 755 756 } 757 758 if(0 == nitems) 759 { 760 return; 761 } 762 763 byte_index =0; 764 data_writed=0; 765 766 767 for (i=0; i < 32; i++) 768 { 769 if(byte_index == 0) data = 0; 770 771 if(i<nitems) 772 { 773 if( viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[ (p_list[i]&0x1f) ]))) 774 { 775 data |= (pInfo->h264_list_replacement) << byte_index; 776 } 777 else 778 { 779 data |= (p_list[i] & 0x7f) << byte_index; 780 } 781 } 782 else 783 { 784 data |= (0x80) << byte_index; 785 } 786 787 788 if(byte_index == 24) 789 { 790 byte_index = 0; 791 wi.data.data_offset = data_writed&(~0x1); 792 wi.data.data_payload[data_writed&0x1]=data; 793 794 data =0; 795 796 if(data_writed&0x1) 797 { 798 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 799 { 800 viddec_pm_append_workitem( parent, &wi ); 801 } 802 else 803 { 804 viddec_pm_append_workitem_next( parent, &wi ); 805 } 806 } 807 data_writed ++; 808 } 809 else 810 { 811 byte_index += 8; 812 } 813 } 814 815 } 816 817 818 819 void h264_parse_emit_current_slice( void *parent, h264_Info *pInfo ) 820 { 821 822 viddec_workload_item_t wi; 823 h264_slice_data slice_data; 824 825 uint32_t i=0, nitems=0, data=0; 826 uint32_t bits_offset =0, byte_offset =0; 827 uint8_t is_emul =0; 828 829 ////////////////////// Update frame attributes///////////////// 830 h264_parse_update_frame_attributes(parent,pInfo); 831 832 833 if(pInfo->SliceHeader.sh_error) { 834 // Error type definition, refer to viddec_fw_common_defs.h 835 // if error in top field, VIDDEC_FW_WORKLOAD_ERR_TOPFIELD = (1 << 17) 836 // if error in bottom field, VIDDEC_FW_WORKLOAD_ERR_BOTTOMFIELD = (1 << 18) 837 // if this is frame based, both 2 bits should be set 838 839 if(pInfo->push_to_cur) { 840 pInfo->wl_err_curr |= VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE; 841 pInfo->wl_err_curr |= (pInfo->SliceHeader.structure << FIELD_ERR_OFFSET); 842 } else { 843 pInfo->wl_err_next |= VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE; 844 pInfo->wl_err_next |= (pInfo->SliceHeader.structure << FIELD_ERR_OFFSET); 845 } 846 } 847 848 849 ////////////////////// Update Reference list ////////////////// 850 if( (h264_PtypeB==pInfo->SliceHeader.slice_type)||(h264_PtypeP==pInfo->SliceHeader.slice_type) ) 851 { 852 if(pInfo->SliceHeader.sh_refpic_l0.ref_pic_list_reordering_flag) 853 { 854 nitems = pInfo->SliceHeader.num_ref_idx_l0_active; 855 856 for(i=0; i<nitems;i++) 857 { 858 if(viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[pInfo->slice_ref_list0[i]&0x1f]))==0) 859 { 860 pInfo->h264_list_replacement = (pInfo->slice_ref_list0[i]&0xFF)|0x80; 861 break; 862 } 863 } 864 } 865 else 866 { 867 nitems = pInfo->dpb.listXsize[0]; 868 869 for(i=0; i<nitems;i++) 870 { 871 if(viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[pInfo->dpb.listX_0[i]&0x1f]))==0) 872 { 873 pInfo->h264_list_replacement = (pInfo->dpb.listX_0[i]&0xFF)|0x80; 874 break; 875 } 876 } 877 } 878 879 } 880 else 881 { 882 nitems =0; 883 } 884 /////file ref list 0 885 h264_parse_emit_ref_list(parent, pInfo, 0); 886 887 /////file ref list 1 888 h264_parse_emit_ref_list(parent, pInfo, 1); 889 890 ///////////////////////////////////// Slice Data //////////////////////////////// 891 h264_fill_slice_data(pInfo, &slice_data); 892 893 wi.vwi_type = VIDDEC_WORKLOAD_H264_SLICE_REG; 894 895 wi.data.data_offset = slice_data.h264_bsd_slice_start; 896 wi.data.data_payload[0] = slice_data.h264_bsd_slice_p1; 897 wi.data.data_payload[1] = slice_data.h264_bsd_slice_p2; 898 899 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 900 { 901 viddec_pm_append_workitem( parent , &wi); 902 } 903 else 904 { 905 viddec_pm_append_workitem_next( parent , &wi); 906 } 907 908 909 ///////////////////////////predict weight table item and data if have/////////////////////////// 910 if(pInfo->h264_pwt_enabled) 911 { 912 wi.vwi_type = VIDDEC_WORKLOAD_H264_PWT_BITS_OFFSET; 913 wi.data.data_offset = pInfo->h264_pwt_end_byte_offset- pInfo->h264_pwt_start_byte_offset+1; 914 wi.data.data_payload[0] = pInfo->h264_pwt_start_bit_offset; 915 wi.data.data_payload[1] = pInfo->h264_pwt_end_bit_offset; 916 917 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 918 { 919 viddec_pm_append_workitem( parent , &wi); 920 921 wi.vwi_type = VIDDEC_WORKLOAD_H264_PWT_ES_BYTES; 922 wi.es.es_flags = 0; 923 viddec_pm_append_misc_tags(parent, pInfo->h264_pwt_start_byte_offset, pInfo->h264_pwt_end_byte_offset,&wi,1); 924 } 925 else 926 { 927 viddec_pm_append_workitem_next( parent , &wi); 928 929 wi.vwi_type = VIDDEC_WORKLOAD_H264_PWT_ES_BYTES; 930 wi.es.es_flags = 0; 931 viddec_pm_append_misc_tags(parent, pInfo->h264_pwt_start_byte_offset, pInfo->h264_pwt_end_byte_offset,&wi,0); 932 } 933 } 934 935 936 ////////////////////////////////// Update ES Buffer for Slice /////////////////////// 937 viddec_pm_get_au_pos(parent, &bits_offset, &byte_offset, &is_emul); 938 939 //OS_INFO("DEBUG---entropy_coding_mode_flag:%d, bits_offset: %d\n", pInfo->active_PPS.entropy_coding_mode_flag, bits_offset); 940 941 if(pInfo->active_PPS.entropy_coding_mode_flag) 942 { 943 if(0!=bits_offset) { 944 viddec_pm_get_bits(parent, &data, 8-bits_offset); 945 } 946 } 947 else 948 { 949 if(0!=bits_offset) { 950 wi.vwi_type = VIDDEC_WORKLOAD_H264_SH_BITS_OFFSET; 951 wi.data.data_offset = bits_offset; 952 wi.data.data_payload[0]=0; 953 wi.data.data_payload[1]=0; 954 955 if(pInfo->push_to_cur) { //cur is empty, fill new frame in cur 956 viddec_pm_append_workitem( parent , &wi); 957 } 958 else { 959 viddec_pm_append_workitem_next( parent , &wi); 960 } 961 } 962 } 963 964 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 965 { 966 viddec_pm_append_pixeldata( parent ); 967 } 968 else 969 { 970 viddec_pm_append_pixeldata_next( parent); 971 } 972 973 return; 974 } 975 976 977 void h264_parse_emit_current_pic( void *parent, h264_Info *pInfo ) 978 { 979 980 viddec_workload_item_t wi; 981 982 const uint32_t *pl; 983 uint32_t i=0,nitems=0; 984 985 h264_pic_data pic_data; 986 987 pInfo->qm_present_list=0; 988 989 h264_parse_emit_4X4_scaling_matrix(parent, pInfo); 990 h264_parse_emit_8X8_scaling_matrix(parent, pInfo); 991 992 h264_fill_pic_data(pInfo, &pic_data); 993 994 // How many payloads must be generated 995 nitems = (sizeof(h264_pic_data) + 7) / 8; // In QWORDs rounded up 996 997 pl = (const uint32_t *) &pic_data; 998 999 // Dump slice data to an array of workitems, to do pl access non valid mem 1000 for( i = 0; i < nitems; i++ ) 1001 { 1002 wi.vwi_type = VIDDEC_WORKLOAD_H264_PIC_REG; 1003 wi.data.data_offset = (unsigned int)pl - (unsigned int)&pic_data; // offset within struct 1004 wi.data.data_payload[0] = pl[0]; 1005 wi.data.data_payload[1] = pl[1]; 1006 pl += 2; 1007 1008 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 1009 { 1010 1011 viddec_pm_append_workitem( parent, &wi ); 1012 } 1013 else 1014 { 1015 viddec_pm_append_workitem_next( parent, &wi ); 1016 } 1017 } 1018 1019 return; 1020 } 1021 1022 void h264_parse_emit_start_new_frame( void *parent, h264_Info *pInfo ) 1023 { 1024 1025 viddec_workload_item_t wi; 1026 uint32_t i=0,nitems=0; 1027 1028 ///////////////////////// Frame attributes////////////////////////// 1029 1030 //Push data into current workload if first frame or frame_boundary already detected by non slice nal 1031 if( (pInfo->Is_first_frame_in_stream)||(pInfo->is_frame_boundary_detected_by_non_slice_nal)) 1032 { 1033 viddec_workload_t *wl_cur = viddec_pm_get_header( parent ); 1034 //pInfo->img.g_new_frame = 0; 1035 pInfo->Is_first_frame_in_stream =0; 1036 pInfo->is_frame_boundary_detected_by_non_slice_nal=0; 1037 pInfo->push_to_cur = 1; 1038 h264_translate_parser_info_to_frame_attributes(wl_cur, pInfo); 1039 } 1040 else // move to cur if frame boundary detected by previous non slice nal, or move to next if not 1041 { 1042 viddec_workload_t *wl_next = viddec_pm_get_next_header (parent); 1043 1044 pInfo->push_to_cur = 0; 1045 h264_translate_parser_info_to_frame_attributes(wl_next, pInfo); 1046 1047 pInfo->is_current_workload_done=1; 1048 } 1049 1050 ///////////////////// SPS///////////////////// 1051 h264_parse_emit_sps(parent, pInfo); 1052 1053 /////////////////////display frames///////////////////// 1054 nitems = pInfo->dpb.frame_numbers_need_to_be_displayed; 1055 1056 for(i=0; i<nitems; i++) 1057 { 1058 wi.vwi_type = VIDDEC_WORKLOAD_REF_FRAME_DISPLAY_0 + pInfo->dpb.frame_id_need_to_be_displayed[i]; 1059 wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_displayed[i]; 1060 wi.ref_frame.luma_phys_addr = 0; 1061 wi.ref_frame.chroma_phys_addr = 0; 1062 1063 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 1064 { 1065 viddec_pm_append_workitem( parent, &wi ); 1066 } 1067 else 1068 { 1069 viddec_pm_append_workitem_next( parent, &wi ); 1070 } 1071 } 1072 pInfo->dpb.frame_numbers_need_to_be_displayed =0; 1073 1074 1075 /////////////////////release frames///////////////////// 1076 nitems = pInfo->dpb.frame_numbers_need_to_be_removed; 1077 1078 for(i=0; i<nitems; i++) 1079 { 1080 wi.vwi_type = VIDDEC_WORKLOAD_REF_FRAME_RELEASE_0 + pInfo->dpb.frame_id_need_to_be_removed[i]; 1081 wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_removed[i]; 1082 wi.ref_frame.luma_phys_addr = 0; 1083 wi.ref_frame.chroma_phys_addr = 0; 1084 1085 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 1086 { 1087 viddec_pm_append_workitem( parent, &wi ); 1088 } 1089 else 1090 { 1091 viddec_pm_append_workitem_next( parent, &wi ); 1092 } 1093 1094 } 1095 pInfo->dpb.frame_numbers_need_to_be_removed =0; 1096 1097 /////////////////////flust frames (do not display)///////////////////// 1098 nitems = pInfo->dpb.frame_numbers_need_to_be_dropped; 1099 1100 for(i=0; i<nitems; i++) 1101 { 1102 wi.vwi_type = VIDDEC_WORKLOAD_REF_FRAME_DROPOUT_0 + pInfo->dpb.frame_id_need_to_be_dropped[i]; 1103 wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_dropped[i]; 1104 wi.ref_frame.luma_phys_addr = 0; 1105 wi.ref_frame.chroma_phys_addr = 0; 1106 1107 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 1108 { 1109 viddec_pm_append_workitem( parent, &wi ); 1110 } 1111 else 1112 { 1113 viddec_pm_append_workitem_next( parent, &wi ); 1114 } 1115 1116 } 1117 pInfo->dpb.frame_numbers_need_to_be_dropped =0; 1118 1119 /////////////////////updata DPB frames///////////////////// 1120 nitems = pInfo->dpb.used_size; 1121 for(i=0; i<nitems; i++) 1122 { 1123 uint8_t fs_id = pInfo->dpb.fs_dpb_idc[i]; 1124 1125 if(viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[fs_id])) == 0) 1126 { 1127 wi.vwi_type = VIDDEC_WORKLOAD_DPB_ACTIVE_FRAME_0+fs_id; 1128 wi.ref_frame.reference_id = fs_id; 1129 wi.ref_frame.luma_phys_addr = 0; 1130 wi.ref_frame.chroma_phys_addr = 0; 1131 1132 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 1133 { 1134 viddec_pm_append_workitem( parent, &wi ); 1135 } 1136 else 1137 { 1138 viddec_pm_append_workitem_next( parent, &wi ); 1139 } 1140 } 1141 } 1142 1143 1144 /////////////////////updata dpb frames info (poc)///////////////////// 1145 nitems = pInfo->dpb.used_size; 1146 for(i=0; i<nitems; i++) 1147 { 1148 uint8_t fs_id = pInfo->dpb.fs_dpb_idc[i]; 1149 1150 if(viddec_h264_get_is_non_existent(&(pInfo->dpb.fs[fs_id])) == 0) 1151 { 1152 wi.vwi_type = VIDDEC_WORKLOAD_H264_DPB_FRAME_POC; 1153 wi.data.data_offset = fs_id; 1154 //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); 1155 1156 switch(viddec_h264_get_is_used(&(pInfo->dpb.fs[fs_id]))) 1157 { 1158 case (FRAME):{ 1159 wi.data.data_payload[0] = pInfo->dpb.fs[fs_id].top_field.poc; 1160 wi.data.data_payload[1] = pInfo->dpb.fs[fs_id].bottom_field.poc; 1161 break; 1162 }; 1163 1164 case (TOP_FIELD):{ 1165 wi.data.data_payload[0] = pInfo->dpb.fs[fs_id].top_field.poc; 1166 wi.data.data_payload[1] = 0; 1167 break; 1168 }; 1169 1170 case (BOTTOM_FIELD):{ 1171 wi.data.data_payload[0] = 0; 1172 wi.data.data_payload[1] = pInfo->dpb.fs[fs_id].bottom_field.poc; 1173 break; 1174 }; 1175 1176 default : { 1177 wi.data.data_payload[0] = 0; 1178 wi.data.data_payload[1] = 0; 1179 break; 1180 }; 1181 } 1182 1183 1184 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 1185 { 1186 viddec_pm_append_workitem( parent, &wi ); 1187 } 1188 else 1189 { 1190 viddec_pm_append_workitem_next( parent, &wi ); 1191 } 1192 1193 } 1194 } 1195 1196 /////////////////////Alloc buffer for current Existing frame///////////////////// 1197 if(0!=pInfo->dpb.frame_numbers_need_to_be_allocated) 1198 { 1199 if(pInfo->push_to_cur) 1200 { 1201 viddec_workload_t *wl_cur = viddec_pm_get_header (parent); 1202 wl_cur->is_reference_frame |= WORKLOAD_REFERENCE_FRAME | (pInfo->dpb.frame_id_need_to_be_allocated & 0x1f); 1203 } 1204 else 1205 { 1206 viddec_workload_t *wl_next = viddec_pm_get_next_header (parent); 1207 wl_next->is_reference_frame |= WORKLOAD_REFERENCE_FRAME | (pInfo->dpb.frame_id_need_to_be_allocated & 0x1f); 1208 } 1209 } 1210 pInfo->dpb.frame_numbers_need_to_be_allocated =0; 1211 1212 return; 1213 } 1214 1215 1216 1217 void h264_parse_emit_eos( void *parent, h264_Info *pInfo ) 1218 { 1219 1220 uint32_t nitems=0, i=0; 1221 viddec_workload_item_t wi; 1222 1223 1224 wi.vwi_type = VIDDEC_WORKLOAD_EOS_BEGIN_BOUNDARY; 1225 wi.ref_frame.reference_id = 0; 1226 wi.ref_frame.luma_phys_addr = 0; 1227 wi.ref_frame.chroma_phys_addr = 0; 1228 1229 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 1230 { 1231 viddec_pm_append_workitem( parent, &wi ); 1232 } 1233 else 1234 { 1235 viddec_pm_append_workitem_next( parent, &wi ); 1236 } 1237 1238 //// 1239 //// Now we can flush out all frames in DPB fro display 1240 1241 if(MPD_DPB_FS_NULL_IDC != pInfo->dpb.fs_dec_idc) 1242 { 1243 if(viddec_h264_get_is_used(&(pInfo->dpb.fs[pInfo->dpb.fs_dec_idc])) != 3) 1244 { 1245 h264_dpb_mark_dangling_field(&pInfo->dpb, pInfo->dpb.fs_dec_idc); //, DANGLING_TYPE_GAP_IN_FRAME 1246 } 1247 } 1248 1249 1250 h264_dpb_store_previous_picture_in_dpb(pInfo, 0,0); 1251 h264_dpb_flush_dpb(pInfo, 1, 0, pInfo->active_SPS.num_ref_frames); 1252 1253 1254 /////////////////////display frames///////////////////// 1255 nitems = pInfo->dpb.frame_numbers_need_to_be_displayed; 1256 1257 for(i=0; i<nitems; i++) 1258 { 1259 wi.vwi_type = VIDDEC_WORKLOAD_EOS_DISPLAY_FRAME_0 + pInfo->dpb.frame_id_need_to_be_displayed[i]; 1260 wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_displayed[i]; 1261 wi.ref_frame.luma_phys_addr = 0; 1262 wi.ref_frame.chroma_phys_addr = 0; 1263 1264 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 1265 { 1266 viddec_pm_append_workitem( parent, &wi ); 1267 } 1268 else 1269 { 1270 viddec_pm_append_workitem_next( parent, &wi ); 1271 } 1272 } 1273 pInfo->dpb.frame_numbers_need_to_be_displayed =0; 1274 1275 1276 /////////////////////release frames///////////////////// 1277 nitems = pInfo->dpb.frame_numbers_need_to_be_removed; 1278 1279 for(i=0; i<nitems; i++) 1280 { 1281 wi.vwi_type = VIDDEC_WORKLOAD_EOS_RELEASE_FRAME_0 + pInfo->dpb.frame_id_need_to_be_removed[i]; 1282 wi.ref_frame.reference_id = pInfo->dpb.frame_id_need_to_be_removed[i]; 1283 wi.ref_frame.luma_phys_addr = 0; 1284 wi.ref_frame.chroma_phys_addr = 0; 1285 1286 if(pInfo->push_to_cur) //cur is empty, fill new frame in cur 1287 { 1288 viddec_pm_append_workitem( parent, &wi ); 1289 viddec_pm_set_next_frame_error_on_eos(parent, VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE); 1290 } 1291 else 1292 { 1293 viddec_pm_append_workitem_next( parent, &wi ); 1294 viddec_pm_set_next_frame_error_on_eos(parent, pInfo->wl_err_next); 1295 } 1296 } 1297 pInfo->dpb.frame_numbers_need_to_be_removed =0; 1298 1299 return; 1300 } 1301 1302 1303 1304 1305 1306 1307