Ejemplo n.º 1
0
static u32 ddl_decoder_ouput_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;

	output_vcd_frm->physical =
		(u8 *) (dec_disp_info->display_y_addr << 11);
		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_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);
		if (dec_disp_info->crop_exists) {
			vidc_sm_get_crop_info(&ddl->shared_mem
				[ddl_context->response_cmd_ch_id],
				&dec_disp_info->crop_left_offset,
				&dec_disp_info->crop_right_offset,
				&dec_disp_info->crop_top_offset,
				&dec_disp_info->crop_bottom_offset);

			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 =
				decoder->frame_size.width -
				dec_disp_info->crop_right_offset;
			output_vcd_frm->dec_op_prop.disp_frm.bottom =
				decoder->frame_size.height -
				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 =
				decoder->frame_size.width;
			output_vcd_frm->dec_op_prop.disp_frm.bottom =
				decoder->frame_size.height;
		}
		if (dec_disp_info->display_coding ==
			VIDC_1080P_DISPLAY_CODING_PROGRESSIVE_SCAN) {
			output_vcd_frm->interlaced = false;
			output_vcd_frm->intrlcd_ip_frm_tag =
				VCD_FRAMETAG_INVALID;
		} else {
			output_vcd_frm->interlaced = true;
			if (!dec_disp_info->tag_bottom)
				output_vcd_frm->intrlcd_ip_frm_tag =
					VCD_FRAMETAG_INVALID;
			else
				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;
		output_frame->frm_trans_end = frame_transact_end;
#ifdef DDL_PROFILE
		ddl_calc_core_time(0);
#endif
		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);
	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;
}