static u32 ddl_decoder_output_done_callback( struct ddl_client_context *ddl, u32 frame_transact_end) { struct ddl_context *ddl_context = ddl->ddl_context; struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); struct vidc_1080p_dec_disp_info *dec_disp_info = &(decoder->dec_disp_info); struct ddl_frame_data_tag *output_frame = &(ddl->output_frame); struct vcd_frame_data *output_vcd_frm = &(output_frame->vcd_frm); u32 vcd_status, free_luma_dpb = 0, disp_pict = 0, is_interlaced; get_dec_op_done_data(dec_disp_info, decoder->output_order, &output_vcd_frm->physical, &is_interlaced); decoder->progressive_only = !(is_interlaced); output_vcd_frm->frame = VCD_FRAME_YUV; if (decoder->codec.codec == VCD_CODEC_MPEG4 || decoder->codec.codec == VCD_CODEC_VC1 || decoder->codec.codec == VCD_CODEC_VC1_RCV || (decoder->codec.codec >= VCD_CODEC_DIVX_3 && decoder->codec.codec <= VCD_CODEC_XVID)) { vidc_sm_get_displayed_picture_frame(&ddl->shared_mem [ddl->command_channel], &disp_pict); if (decoder->output_order == VCD_DEC_ORDER_DISPLAY) { if (!disp_pict) { output_vcd_frm->frame = VCD_FRAME_NOTCODED; vidc_sm_get_available_luma_dpb_address( &ddl->shared_mem[ddl->command_channel], &free_luma_dpb); } } else { if (dec_disp_info->input_frame == VIDC_1080P_DECODE_FRAMETYPE_NOT_CODED) { output_vcd_frm->frame = VCD_FRAME_NOTCODED; vidc_sm_get_available_luma_dpb_dec_order_address( &ddl->shared_mem[ddl->command_channel], &free_luma_dpb); } } if (free_luma_dpb) output_vcd_frm->physical = (u8 *)(free_luma_dpb << 11); } vcd_status = ddl_decoder_dpb_transact(decoder, output_frame, DDL_DPB_OP_MARK_BUSY); if (vcd_status) { DDL_MSG_ERROR("CORRUPTED_OUTPUT_BUFFER_ADDRESS"); ddl_hw_fatal_cb(ddl); } else { vidc_sm_get_metadata_status(&ddl->shared_mem [ddl->command_channel], &decoder->meta_data_exists); if (decoder->output_order == VCD_DEC_ORDER_DISPLAY) vidc_sm_get_frame_tags(&ddl->shared_mem [ddl->command_channel], &dec_disp_info->tag_top, &dec_disp_info->tag_bottom); output_vcd_frm->ip_frm_tag = dec_disp_info->tag_top; vidc_sm_get_picture_times(&ddl->shared_mem [ddl->command_channel], &dec_disp_info->pic_time_top, &dec_disp_info->pic_time_bottom); get_dec_op_done_crop(decoder->output_order, dec_disp_info, &output_vcd_frm->dec_op_prop.disp_frm, &output_vcd_frm->dec_op_prop.frm_size, &decoder->frame_size, &ddl->shared_mem[ddl_context->response_cmd_ch_id]); if ((decoder->cont_mode) && ((output_vcd_frm->dec_op_prop.frm_size.width != decoder->frame_size.width) || (output_vcd_frm->dec_op_prop.frm_size.height != decoder->frame_size.height) || (decoder->frame_size.width != decoder->client_frame_size.width) || (decoder->frame_size.height != decoder->client_frame_size.height))) { DDL_MSG_LOW("%s o/p width = %u o/p height = %u" "decoder width = %u decoder height = %u ", __func__, output_vcd_frm->dec_op_prop.frm_size.width, output_vcd_frm->dec_op_prop.frm_size.height, decoder->frame_size.width, decoder->frame_size.height); DDL_MSG_HIGH("%s Sending INFO_OP_RECONFIG event\n", __func__); ddl_context->ddl_callback( VCD_EVT_IND_INFO_OUTPUT_RECONFIG, VCD_S_SUCCESS, NULL, 0, (u32 *)ddl, ddl->client_data); decoder->frame_size = output_vcd_frm->dec_op_prop.frm_size; decoder->client_frame_size = decoder->frame_size; decoder->y_cb_cr_size = ddl_get_yuv_buffer_size(&decoder->frame_size, &decoder->buf_format, (!decoder->progressive_only), decoder->codec.codec, NULL); decoder->actual_output_buf_req.sz = decoder->y_cb_cr_size + decoder->suffix; decoder->min_output_buf_req = decoder->actual_output_buf_req; DDL_MSG_LOW("%s y_cb_cr_size = %u " "actual_output_buf_req.sz = %u" "min_output_buf_req.sz = %u\n", decoder->y_cb_cr_size, decoder->actual_output_buf_req.sz, decoder->min_output_buf_req.sz); vidc_sm_set_chroma_addr_change( &ddl->shared_mem[ddl->command_channel], false); } output_vcd_frm->interlaced = is_interlaced; output_vcd_frm->intrlcd_ip_frm_tag = (!is_interlaced || !dec_disp_info->tag_bottom) ? VCD_FRAMETAG_INVALID : dec_disp_info->tag_bottom; output_vcd_frm->offset = 0; output_vcd_frm->data_len = decoder->y_cb_cr_size; if (free_luma_dpb) { output_vcd_frm->data_len = 0; output_vcd_frm->flags |= VCD_FRAME_FLAG_DECODEONLY; } output_vcd_frm->flags |= VCD_FRAME_FLAG_ENDOFFRAME; output_frame->frm_trans_end = frame_transact_end; if (vidc_msg_timing) ddl_calc_core_proc_time(__func__, DEC_OP_TIME); ddl_process_decoder_metadata(ddl); ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, vcd_status, output_frame, sizeof(struct ddl_frame_data_tag), (u32 *)ddl, ddl->client_data); } return vcd_status; }
static u32 ddl_decoder_output_done_callback( struct ddl_client_context *ddl, u32 frame_transact_end) { struct ddl_context *ddl_context = ddl->ddl_context; struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); struct vidc_1080p_dec_disp_info *dec_disp_info = &(decoder->dec_disp_info); struct ddl_frame_data_tag *output_frame = &(ddl->output_frame); struct vcd_frame_data *output_vcd_frm = &(output_frame->vcd_frm); u32 vcd_status, free_luma_dpb = 0, disp_pict = 0, is_interlaced; get_dec_op_done_data(dec_disp_info, decoder->output_order, &output_vcd_frm->physical, &is_interlaced); output_vcd_frm->frame = VCD_FRAME_YUV; if (decoder->codec.codec == VCD_CODEC_MPEG4 || decoder->codec.codec == VCD_CODEC_VC1 || decoder->codec.codec == VCD_CODEC_VC1_RCV || (decoder->codec.codec >= VCD_CODEC_DIVX_3 && decoder->codec.codec <= VCD_CODEC_XVID)) { vidc_sm_get_displayed_picture_frame(&ddl->shared_mem [ddl->command_channel], &disp_pict); if (!disp_pict) output_vcd_frm->frame = VCD_FRAME_NOTCODED; if (output_vcd_frm->frame == VCD_FRAME_NOTCODED) { vidc_sm_get_available_luma_dpb_address( &ddl->shared_mem[ddl->command_channel], &free_luma_dpb); if (free_luma_dpb) output_vcd_frm->physical = (u8 *)(free_luma_dpb << 11); } } vcd_status = ddl_decoder_dpb_transact(decoder, output_frame, DDL_DPB_OP_MARK_BUSY); if (vcd_status) { DDL_MSG_ERROR("CORRUPTED_OUTPUT_BUFFER_ADDRESS"); ddl_hw_fatal_cb(ddl); } else { vidc_sm_get_metadata_status(&ddl->shared_mem [ddl->command_channel], &decoder->meta_data_exists); if (decoder->output_order == VCD_DEC_ORDER_DISPLAY) vidc_sm_get_frame_tags(&ddl->shared_mem [ddl->command_channel], &dec_disp_info->tag_top, &dec_disp_info->tag_bottom); output_vcd_frm->ip_frm_tag = dec_disp_info->tag_top; vidc_sm_get_picture_times(&ddl->shared_mem [ddl->command_channel], &dec_disp_info->pic_time_top, &dec_disp_info->pic_time_bottom); get_dec_op_done_crop(decoder->output_order, dec_disp_info, &output_vcd_frm->dec_op_prop.disp_frm, &decoder->frame_size, &ddl->shared_mem[ddl_context->response_cmd_ch_id]); output_vcd_frm->interlaced = is_interlaced; output_vcd_frm->intrlcd_ip_frm_tag = (!is_interlaced || !dec_disp_info->tag_bottom) ? VCD_FRAMETAG_INVALID : dec_disp_info->tag_bottom; output_vcd_frm->offset = 0; output_vcd_frm->data_len = decoder->y_cb_cr_size; if (free_luma_dpb) { output_vcd_frm->data_len = 0; output_vcd_frm->flags |= VCD_FRAME_FLAG_DECODEONLY; } output_vcd_frm->flags |= VCD_FRAME_FLAG_ENDOFFRAME; output_frame->frm_trans_end = frame_transact_end; #ifdef DDL_PROFILE ddl_calc_core_time(0); #endif ddl_process_decoder_metadata(ddl); ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, vcd_status, output_frame, sizeof(struct ddl_frame_data_tag), (u32 *)ddl, ddl->client_data); } return vcd_status; }