コード例 #1
0
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;
}
コード例 #2
0
static void ddl_encoder_frame_run_callback(
	struct ddl_client_context *ddl)
{
	struct ddl_context *ddl_context = ddl->ddl_context;
	struct ddl_encoder_data *encoder =
		&(ddl->codec_data.encoder);
	struct vcd_frame_data *output_frame =
		&(ddl->output_frame.vcd_frm);
	u32 bottom_frame_tag;

	DDL_MSG_MED("ddl_encoder_frame_run_callback");
	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE) &&
		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) {
		DDL_MSG_ERROR("STATE-CRITICAL-ENCFRMRUN");
		ddl_client_fatal_cb(ddl);
	} else {
		if (vidc_msg_timing)
			ddl_calc_core_proc_time(__func__, ENC_OP_TIME);
		DDL_MSG_LOW("ENC_FRM_RUN_DONE");
		ddl->cmd_state = DDL_CMD_INVALID;
		vidc_1080p_get_encode_frame_info(&encoder->enc_frame_info);
		vidc_sm_get_frame_tags(&ddl->shared_mem
			[ddl->command_channel],
			&output_frame->ip_frm_tag, &bottom_frame_tag);

		if (encoder->meta_data_enable_flag)
			vidc_sm_get_metadata_status(&ddl->shared_mem
				[ddl->command_channel],
				&encoder->enc_frame_info.meta_data_exists);

		if (encoder->enc_frame_info.enc_frame_size ||
			(encoder->enc_frame_info.enc_frame ==
			VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED) ||
			DDLCLIENT_STATE_IS(ddl,
			DDL_CLIENT_WAIT_FOR_EOS_DONE)) {
			u8 *input_buffer_address = NULL;
			output_frame->data_len =
				encoder->enc_frame_info.enc_frame_size;
			output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME;
			ddl_get_encoded_frame(output_frame,
				encoder->codec.codec,
				encoder->enc_frame_info.enc_frame);
			ddl_process_encoder_metadata(ddl);
			ddl_vidc_encode_dynamic_property(ddl, false);
			ddl->input_frame.frm_trans_end = false;
			input_buffer_address = ddl_context->dram_base_a.\
				align_physical_addr +
				encoder->enc_frame_info.enc_luma_address;
			ddl_get_input_frame_from_pool(ddl,
				input_buffer_address);
			ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE,
				VCD_S_SUCCESS, &(ddl->input_frame),
				sizeof(struct ddl_frame_data_tag),
				(u32 *)ddl, ddl->client_data);
			ddl->output_frame.frm_trans_end =
				DDLCLIENT_STATE_IS(ddl,
				DDL_CLIENT_WAIT_FOR_EOS_DONE) ? false : true;
			ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
				VCD_S_SUCCESS, &(ddl->output_frame),
				sizeof(struct ddl_frame_data_tag),
				(u32 *)ddl, ddl->client_data);

			if (DDLCLIENT_STATE_IS(ddl,
				DDL_CLIENT_WAIT_FOR_EOS_DONE) &&
				encoder->i_period.b_frames) {
				if ((ddl->extra_output_buf_count < 0) ||
					(ddl->extra_output_buf_count >
					encoder->i_period.b_frames)) {
					DDL_MSG_ERROR("Invalid B frame output"
								"buffer index");
				} else {
					struct vidc_1080p_enc_frame_start_param
						enc_param;
					ddl->output_frame = ddl->\
					extra_output_frame[ddl->\
					extra_output_buf_count];
					ddl->\
					extra_output_buf_count--;
					output_frame =
					&ddl->output_frame.\
					vcd_frm;
					memset(&enc_param, 0,
						sizeof(enc_param));
					enc_param.cmd_seq_num =
						++ddl_context->cmd_seq_num;
					enc_param.inst_id = ddl->instance_id;
					enc_param.shared_mem_addr_offset =
					   DDL_ADDR_OFFSET(ddl_context->\
						dram_base_a, ddl->shared_mem
						[ddl->command_channel]);
					enc_param.stream_buffer_addr_offset =
						DDL_OFFSET(ddl_context->\
						dram_base_a.\
						align_physical_addr,
						output_frame->physical);
					enc_param.stream_buffer_size =
					encoder->client_output_buf_req.sz;
					enc_param.encode =
					VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA;
					ddl->cmd_state = DDL_CMD_ENCODE_FRAME;
					ddl_context->vidc_encode_frame_start
						[ddl->command_channel]
						(&enc_param);
				} } else {
				DDL_MSG_LOW("ddl_state_transition: %s ~~>"
					"DDL_CLIENT_WAIT_FOR_FRAME",
					ddl_get_state_string(
					ddl->client_state));
				ddl->client_state =
					DDL_CLIENT_WAIT_FOR_FRAME;
				ddl_release_command_channel(ddl_context,
				ddl->command_channel);
			}
		} else {
			ddl_context->ddl_callback(
				VCD_EVT_RESP_TRANSACTION_PENDING,
				VCD_S_SUCCESS, NULL, 0, (u32 *)ddl,
				ddl->client_data);
			DDL_MSG_LOW("ddl_state_transition: %s ~~>"
				"DDL_CLIENT_WAIT_FOR_FRAME",
			ddl_get_state_string(ddl->client_state));
			ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME;
			ddl_release_command_channel(ddl_context,
			ddl->command_channel);
		}
	}
}
コード例 #3
0
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;
}