static u32 ddl_decoder_output_done_callback(
	struct ddl_client_context *ddl,
	u32 frame_transact_end)
{
	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
	struct vidc_720p_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;
	u32 free_luma_dpb = 0;

	output_vcd_frm->physical = (u8 *)dec_disp_info->y_addr;

	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_720p_decode_skip_frm_details(&free_luma_dpb);
		if (free_luma_dpb)
			output_vcd_frm->physical = (u8 *) free_luma_dpb;
	}


	vcd_status = ddl_decoder_dpb_transact(
			decoder,
			output_frame,
			DDL_DPB_OP_MARK_BUSY);

	if (vcd_status != VCD_S_SUCCESS) {
		VIDC_LOGERR_STRING("CorruptedOutputBufferAddress");
		ddl_hw_fatal_cb(ddl->ddl_context);
		return vcd_status;
	}

	output_vcd_frm->ip_frm_tag =  dec_disp_info->tag_top;
	if (dec_disp_info->crop_exists == 0x1) {
		output_vcd_frm->dec_op_prop.disp_frm.left =
			dec_disp_info->crop_left_offset;
		output_vcd_frm->dec_op_prop.disp_frm.top =
			dec_disp_info->crop_top_offset;
		output_vcd_frm->dec_op_prop.disp_frm.right =
			dec_disp_info->img_size_x -
			dec_disp_info->crop_right_offset;
		output_vcd_frm->dec_op_prop.disp_frm.bottom =
			dec_disp_info->img_size_y -
			dec_disp_info->crop_bottom_offset;
	} else {
		output_vcd_frm->dec_op_prop.disp_frm.left = 0;
		output_vcd_frm->dec_op_prop.disp_frm.top = 0;
		output_vcd_frm->dec_op_prop.disp_frm.right =
			dec_disp_info->img_size_x;
		output_vcd_frm->dec_op_prop.disp_frm.bottom =
			dec_disp_info->img_size_y;
	}
	if (!dec_disp_info->disp_is_interlace) {
		output_vcd_frm->interlaced = false;
		output_vcd_frm->intrlcd_ip_frm_tag = VCD_FRAMETAG_INVALID;
	} else {
		output_vcd_frm->interlaced = true;
		output_vcd_frm->intrlcd_ip_frm_tag =
			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;
	ddl_process_decoder_metadata(ddl);
	output_frame->frm_trans_end = frame_transact_end;

	if (vidc_msg_timing)
		ddl_calc_core_proc_time(__func__, DEC_OP_TIME);

	ddl->ddl_context->ddl_callback(
		VCD_EVT_RESP_OUTPUT_DONE,
		vcd_status,
		output_frame,
		sizeof(struct ddl_frame_data_tag),
		(void *)ddl,
		ddl->ddl_context->client_data);
	return vcd_status;
}
Exemple #2
0
static u32 ddl_decoder_output_done_callback(
	struct ddl_client_context_type *p_ddl,
	u32 b_frame_transact_end)
{
	struct ddl_decoder_data_type *p_decoder = &(p_ddl->codec_data.decoder);
	struct vidc_720p_dec_disp_info_type *p_dec_disp_info =
		&(p_decoder->dec_disp_info);
	struct ddl_frame_data_type_tag *p_output_frame =
		&p_ddl->output_frame;
	struct vcd_frame_data_type *p_output_vcd_frm =
		&(p_output_frame->vcd_frm);
	u32 vcd_status;
	u32 n_free_luma_dpb = 0;

	p_output_vcd_frm->p_physical = (u8 *)p_dec_disp_info->n_y_addr;

	if (p_decoder->codec_type.e_codec == VCD_CODEC_MPEG4 ||
		p_decoder->codec_type.e_codec == VCD_CODEC_VC1 ||
		p_decoder->codec_type.e_codec == VCD_CODEC_VC1_RCV ||
		(p_decoder->codec_type.e_codec >= VCD_CODEC_DIVX_3 &&
		 p_decoder->codec_type.e_codec <= VCD_CODEC_XVID)){
		vidc_720p_decode_skip_frm_details(&n_free_luma_dpb);
		if (n_free_luma_dpb)
			p_output_vcd_frm->p_physical = (u8 *) n_free_luma_dpb;
	}


	vcd_status = ddl_decoder_dpb_transact(
			p_decoder,
			p_output_frame,
			DDL_DPB_OP_MARK_BUSY);

	if (vcd_status != VCD_S_SUCCESS) {
		VIDC_LOGERR_STRING("CorruptedOutputBufferAddress");
		ddl_hw_fatal_cb(p_ddl->p_ddl_context);
		return vcd_status;
	}

	p_output_vcd_frm->n_ip_frm_tag =  p_dec_disp_info->n_tag_top;
	if (p_dec_disp_info->n_crop_exists == 0x1) {
		p_output_vcd_frm->dec_op_prop.disp_frm.n_left =
			p_dec_disp_info->n_crop_left_offset;
		p_output_vcd_frm->dec_op_prop.disp_frm.n_top =
			p_dec_disp_info->n_crop_top_offset;
		p_output_vcd_frm->dec_op_prop.disp_frm.n_right =
			p_dec_disp_info->n_img_size_x -
			p_dec_disp_info->n_crop_right_offset;
		p_output_vcd_frm->dec_op_prop.disp_frm.n_bottom =
			p_dec_disp_info->n_img_size_y -
			p_dec_disp_info->n_crop_bottom_offset;
	} else {
		p_output_vcd_frm->dec_op_prop.disp_frm.n_left = 0;
		p_output_vcd_frm->dec_op_prop.disp_frm.n_top = 0;
		p_output_vcd_frm->dec_op_prop.disp_frm.n_right =
			p_dec_disp_info->n_img_size_x;
		p_output_vcd_frm->dec_op_prop.disp_frm.n_bottom =
			p_dec_disp_info->n_img_size_y;
	}
	if (!p_dec_disp_info->n_disp_is_interlace) {
		p_output_vcd_frm->b_interlaced = FALSE;
		p_output_vcd_frm->n_intrlcd_ip_frm_tag = VCD_FRAMETAG_INVALID;
	} else {
		p_output_vcd_frm->b_interlaced = TRUE;
		p_output_vcd_frm->n_intrlcd_ip_frm_tag =
			p_dec_disp_info->n_tag_bottom;
	}

	p_output_vcd_frm->n_offset = 0;
	p_output_vcd_frm->n_data_len = p_decoder->n_y_cb_cr_size;
	if (n_free_luma_dpb) {
		p_output_vcd_frm->n_data_len = 0;
		p_output_vcd_frm->n_flags |= VCD_FRAME_FLAG_DECODEONLY;
	}
	p_output_vcd_frm->n_flags |= VCD_FRAME_FLAG_ENDOFFRAME;
	ddl_process_decoder_metadata(p_ddl);
	p_output_frame->b_frm_trans_end = b_frame_transact_end;

#ifdef CORE_TIMING_INFO
	ddl_calc_core_time(0);
#endif

	p_ddl->p_ddl_context->ddl_callback(
		VCD_EVT_RESP_OUTPUT_DONE,
		vcd_status,
		p_output_frame,
		sizeof(struct ddl_frame_data_type_tag),
		(void *)p_ddl,
		p_ddl->p_ddl_context->p_client_data);
	return vcd_status;
}