Exemplo n.º 1
0
static u32 ddl_process_intr_status(struct ddl_context_type *p_ddl_context,
			u32 int_status)
{
	u32 b_status = TRUE;
	switch (int_status) {
	case VIDC_720P_INTR_FRAME_DONE:
		 {
			b_status = ddl_operation_done_callback(p_ddl_context);
			break;
		 }
	case VIDC_720P_INTR_DMA_DONE:
		 {
			ddl_dma_done_callback(p_ddl_context);
			b_status = FALSE;
			break;
		 }
	case VIDC_720P_INTR_FW_DONE:
		 {
			ddl_eos_done_callback(p_ddl_context);
			break;
		 }
	case VIDC_720P_INTR_BUFFER_FULL:
		 {
			VIDC_LOGERR_STRING("BUF_FULL_INTR");
			ddl_hw_fatal_cb(p_ddl_context);
			break;
		 }
	default:
		 {
			VIDC_LOGERR_STRING("UNKWN_INTR");
			break;
		 }
	}
	return b_status;
}
static u32 ddl_process_intr_status(struct ddl_context *ddl_context,
			u32 int_status)
{
	u32 status = true;
	switch (int_status) {
	case VIDC_720P_INTR_FRAME_DONE:
		 {
			status = ddl_operation_done_callback(ddl_context);
			break;
		 }
	case VIDC_720P_INTR_DMA_DONE:
		 {
			ddl_dma_done_callback(ddl_context);
			status = false;
			break;
		 }
	case VIDC_720P_INTR_FW_DONE:
		 {
			status = ddl_eos_done_callback(ddl_context);
			break;
		 }
	case VIDC_720P_INTR_BUFFER_FULL:
		 {
			VIDC_LOGERR_STRING("BUF_FULL_INTR");
			ddl_hw_fatal_cb(ddl_context);
			break;
		 }
	default:
		 {
			VIDC_LOGERR_STRING("UNKWN_INTR");
			break;
		 }
	}
	return status;
}
Exemplo n.º 3
0
static u32 ddl_handle_hw_fatal_errors(struct ddl_client_context_type *p_ddl)
{
	struct ddl_context_type *p_ddl_context = p_ddl->p_ddl_context;
	u32 b_status = FALSE, error_code = p_ddl_context->n_cmd_err_status;

	switch (error_code) {
	case VIDC_1080P_ERROR_INVALID_CHANNEL_NUMBER:
	case VIDC_1080P_ERROR_INVALID_COMMAND_ID:
	case VIDC_1080P_ERROR_CHANNEL_ALREADY_IN_USE:
	case VIDC_1080P_ERROR_CHANNEL_NOT_OPEN_BEFORE_CHANNEL_CLOSE:
	case VIDC_1080P_ERROR_OPEN_CH_ERROR_SEQ_START:
	case VIDC_1080P_ERROR_SEQ_START_ALREADY_CALLED:
	case VIDC_1080P_ERROR_OPEN_CH_ERROR_INIT_BUFFERS:
	case VIDC_1080P_ERROR_SEQ_START_ERROR_INIT_BUFFERS:
	case VIDC_1080P_ERROR_INIT_BUFFER_ALREADY_CALLED:
	case VIDC_1080P_ERROR_OPEN_CH_ERROR_FRAME_START:
	case VIDC_1080P_ERROR_SEQ_START_ERROR_FRAME_START:
	case VIDC_1080P_ERROR_INIT_BUFFERS_ERROR_FRAME_START:
	case VIDC_1080P_ERROR_CODEC_LIMIT_EXCEEDED:
	case VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED:
	case VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE:
	case VIDC_1080P_ERROR_DIVIDE_BY_ZERO:
	case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY:
	case VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE:
	case VIDC_1080P_ERROR_VSP_NOT_READY:
	case VIDC_1080P_ERROR_BUFFER_FULL_STATE:
		ddl_hw_fatal_cb(p_ddl);
		b_status = TRUE;
	break;
	default:
	break;
	}
	return b_status;
}
static void ddl_cpu_started_callback(struct ddl_context *ddl_context)
{
	ddl_move_command_state(ddl_context, DDL_CMD_INVALID);
	VIDC_LOG_STRING("CPU-STARTED");

	if (!vidc_720p_cpu_start()) {
		ddl_hw_fatal_cb(ddl_context);
		return;
	}

	vidc_720p_set_deblock_line_buffer(
			ddl_context->db_line_buffer.align_physical_addr,
			ddl_context->db_line_buffer.buffer_size);
	ddl_context->device_state = DDL_DEVICE_INITED;
	ddl_context->ddl_callback(VCD_EVT_RESP_DEVICE_INIT, VCD_S_SUCCESS,
			NULL, 0, NULL, ddl_context->client_data);
	DDL_IDLE(ddl_context);
}
static u32 ddl_handle_hw_fatal_errors(struct ddl_context
			*ddl_context)
{
	u32 status = false;

	switch (ddl_context->cmd_err_status) {

	case INVALID_CHANNEL_NUMBER:
	case INVALID_COMMAND_ID:
	case CHANNEL_ALREADY_IN_USE:
	case CHANNEL_NOT_SET_BEFORE_CHANNEL_CLOSE:
	case CHANNEL_SET_ERROR_INIT_CODEC:
	case INIT_CODEC_ALREADY_CALLED:
	case CHANNEL_SET_ERROR_INIT_BUFFERS:
	case INIT_CODEC_ERROR_INIT_BUFFERS:
	case INIT_BUFFER_ALREADY_CALLED:
	case CHANNEL_SET_ERROR_FRAME_RUN:
	case INIT_CODEC_ERROR_FRAME_RUN:
	case INIT_BUFFERS_ERROR_FRAME_RUN:
	case CODEC_LIMIT_EXCEEDED:
	case FIRMWARE_SIZE_ZERO:
	case FIRMWARE_ADDRESS_EXT_ZERO:

	case CONTEXT_DMA_IN_ERROR:
	case CONTEXT_DMA_OUT_ERROR:
	case PROGRAM_DMA_ERROR:
	case CONTEXT_STORE_EXT_ADD_ZERO:
	case MEM_ALLOCATION_FAILED:

	case DIVIDE_BY_ZERO:
	case DMA_NOT_STOPPED:
	case DMA_TX_NOT_COMPLETE:

	case VSP_NOT_READY:
	case BUFFER_FULL_STATE:
	case NULL_DB_POINTER:
		ERR("HW FATAL ERROR");
		ddl_hw_fatal_cb(ddl_context);
		status = true;
		break;
	}
	return status;
}
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;
}
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;
}
Exemplo n.º 8
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);
	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;
}
Exemplo n.º 10
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;
}