static u32 ddl_channel_set_callback(struct ddl_context *ddl_context,
	u32 instance_id)
{
	struct ddl_client_context *ddl;
	u32 ret = false;

	DDL_MSG_MED("ddl_channel_open_callback");
	ddl = ddl_get_current_ddl_client_for_command(ddl_context,
			DDL_CMD_CHANNEL_SET);
	if (ddl) {
		ddl->cmd_state = DDL_CMD_INVALID;
		if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHDONE)) {
			DDL_MSG_ERROR("STATE-CRITICAL-CHSET");
			ddl_release_command_channel(ddl_context,
			ddl->command_channel);
		} else {
			DDL_MSG_LOW("CH_SET_DONE");
			DDL_MSG_LOW("ddl_state_transition: %s ~~>"
				"DDL_CLIENT_WAIT_FOR_INITCODEC",
				ddl_get_state_string(ddl->client_state));
			ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODEC;
			ddl->instance_id = instance_id;
			if (ddl->decoding) {
				if (vidc_msg_timing)
					ddl_calc_core_proc_time(__func__,
						DEC_OP_TIME);
				if (ddl->codec_data.decoder.header_in_start)
					ddl_vidc_decode_init_codec(ddl);
				else {
					ddl_context->ddl_callback(
						VCD_EVT_RESP_START,
						VCD_S_SUCCESS, NULL, 0,
						(u32 *)ddl,
						ddl->client_data);
					ddl_release_command_channel(
						ddl_context,
						ddl->command_channel);
					ret = true;
				}
			} else
				ddl_vidc_encode_init_codec(ddl);
		}
	}
	return ret;
}
static u32 ddl_channel_set_callback(struct ddl_context_type *p_ddl_context,
	u32 n_instance_id)
{
	struct ddl_client_context_type *p_ddl;
	u32 b_ret = FALSE;

	DDL_MSG_MED("ddl_channel_open_callback");
	p_ddl = ddl_get_current_ddl_client_for_command(p_ddl_context,
			DDL_CMD_CHANNEL_SET);
	if (p_ddl) {
		p_ddl->e_cmd_state = DDL_CMD_INVALID;
		if (!DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_WAIT_FOR_CHDONE)) {
			DDL_MSG_ERROR("STATE-CRITICAL-CHSET");
			ddl_release_command_channel(p_ddl_context,
			p_ddl->n_command_channel);
		} else {
			DDL_MSG_LOW("CH_SET_DONE");
			DDL_MSG_LOW("ddl_state_transition: %s ~~>\
				DDL_CLIENT_WAIT_FOR_INITCODEC",
				ddl_get_state_string(p_ddl->e_client_state));
			p_ddl->e_client_state = DDL_CLIENT_WAIT_FOR_INITCODEC;
			p_ddl->n_channel_id = n_instance_id;
			if (p_ddl->b_decoding) {
				if (p_ddl->codec_data.decoder.b_header_in_start)
					ddl_vidc_decode_init_codec(p_ddl);
				else {
					p_ddl_context->ddl_callback(
						VCD_EVT_RESP_START,
						VCD_S_SUCCESS, NULL, 0,
						(u32 *)p_ddl,
						p_ddl->p_client_data);
					ddl_release_command_channel(
						p_ddl_context,
						p_ddl->n_command_channel);
					b_ret = TRUE;
				}
			} else
				ddl_vidc_encode_init_codec(p_ddl);
		}
	}
	return b_ret;
}
Exemple #3
0
u32 ddl_decode_frame(u32 *ddl_handle,
	struct ddl_frame_data_tag *input_bits, void *client_data)
{
	u32 vcd_status = VCD_S_SUCCESS;
	struct ddl_client_context *ddl =
		(struct ddl_client_context *) ddl_handle;
	struct ddl_context *ddl_context;
	struct ddl_decoder_data *decoder;
	DDL_MSG_HIGH("ddl_decode_frame");
	ddl_context = ddl_get_context();
	if (!DDL_IS_INITIALIZED(ddl_context)) {
		DDL_MSG_ERROR("ddl_dec_frame:Not_inited");
		return VCD_ERR_ILLEGAL_OP;
	}
	if (DDL_IS_BUSY(ddl_context)) {
		DDL_MSG_ERROR("ddl_dec_frame:Ddl_busy");
		return VCD_ERR_BUSY;
	}
	if (!ddl || !ddl->decoding) {
		DDL_MSG_ERROR("ddl_dec_frame:Bad_handle");
		return VCD_ERR_BAD_HANDLE;
	}
	if (!input_bits || ((!input_bits->vcd_frm.physical ||
		!input_bits->vcd_frm.data_len) &&
		(!(VCD_FRAME_FLAG_EOS &	input_bits->vcd_frm.flags)))) {
		DDL_MSG_ERROR("ddl_dec_frame:Bad_input_param");
		return VCD_ERR_ILLEGAL_PARM;
	}
	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) &&
		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) &&
		!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) {
		DDL_MSG_ERROR("Dec_frame:Wrong_state");
		return VCD_ERR_ILLEGAL_OP;
	}
	decoder = &(ddl->codec_data.decoder);
	if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC)	&&
		!ddl->codec_data.decoder.dp_buf.no_of_dec_pic_buf) {
		DDL_MSG_ERROR("ddl_dec_frame:Dpbs_requied");
		return VCD_ERR_ILLEGAL_OP;
	}
	if (!ddl_take_command_channel(ddl_context, ddl, client_data))
		return VCD_ERR_BUSY;

	ddl->input_frame = *input_bits;
	if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME))
		ddl_vidc_decode_frame_run(ddl);
	else {
		if (!ddl->codec_data.decoder.dp_buf.no_of_dec_pic_buf) {
			DDL_MSG_ERROR("ddl_dec_frame:Dpbs_requied");
			vcd_status = VCD_ERR_ILLEGAL_OP;
		} else if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) {
			vcd_status = ddl_vidc_decode_set_buffers(ddl);
		if (vcd_status)
			ddl_release_command_channel(ddl_context,
				ddl->command_channel);
		} else if (DDLCLIENT_STATE_IS(ddl,
			DDL_CLIENT_WAIT_FOR_INITCODEC)) {
			if (decoder->codec.codec == VCD_CODEC_DIVX_3) {
				if ((!decoder->client_frame_size.width) ||
				(!decoder->client_frame_size.height))
					return VCD_ERR_ILLEGAL_OP;
		}
		ddl->codec_data.decoder.decode_config.sequence_header =
			ddl->input_frame.vcd_frm.physical;
		ddl->codec_data.decoder.decode_config.sequence_header_len =
			ddl->input_frame.vcd_frm.data_len;
		ddl_vidc_decode_init_codec(ddl);
		} else {
			DDL_MSG_ERROR("Dec_frame:Wrong_state");
			vcd_status = VCD_ERR_ILLEGAL_OP;
		}
		if (vcd_status)
			DDL_IDLE(ddl_context);
		}
	return vcd_status;
}
static u32 ddl_eos_frame_done_callback(
	struct ddl_client_context *ddl)
{
	struct ddl_context *ddl_context = ddl->ddl_context;
	struct ddl_decoder_data *decoder = &ddl->codec_data.decoder;
	struct ddl_mask *dpb_mask = &decoder->dpb_mask;
	u32 ret_status = true, rsl_chg, more_field_needed;
	enum vidc_1080p_display_status disp_status;

	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) {
		DDL_MSG_ERROR("STATE-CRITICAL-EOSFRMRUN");
		ddl_client_fatal_cb(ddl);
	} else {
		DDL_MSG_LOW("EOS_FRM_RUN_DONE");
		ddl->cmd_state = DDL_CMD_INVALID;
		get_dec_status(ddl, &ddl->codec_data.decoder.dec_disp_info,
			ddl->codec_data.decoder.output_order,
			&disp_status, &rsl_chg);
		vidc_sm_get_extended_decode_status(
			&ddl->shared_mem[ddl->command_channel],
			&more_field_needed, &rsl_chg);

		decoder->field_needed_for_prev_ip =
			more_field_needed;
		decoder->prev_ip_frm_tag =
			ddl->input_frame.vcd_frm.ip_frm_tag;
		ddl_vidc_decode_dynamic_property(ddl, false);
		if (disp_status ==
			VIDC_1080P_DISPLAY_STATUS_DPB_EMPTY) {
			if (rsl_chg) {
				decoder->header_in_start = false;
				decoder->decode_config.sequence_header =
					ddl->input_frame.vcd_frm.physical;
				decoder->decode_config.sequence_header_len =
					ddl->input_frame.vcd_frm.data_len;
				ddl_vidc_decode_init_codec(ddl);
				ret_status = false;
			} else
				ddl_decoder_eos_done_callback(ddl);
		} else {
			struct vidc_1080p_dec_frame_start_param dec_param;
			ret_status = false;
			if (disp_status ==
				VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY) {
				if (ddl_decoder_output_done_callback(
					ddl, false))
					ret_status = true;
			} else if (disp_status !=
				VIDC_1080P_DISPLAY_STATUS_NOOP)
				DDL_MSG_ERROR("EOS-STATE-CRITICAL-"
					"WRONG-DISP-STATUS");
			if (!ret_status) {
				ddl_decoder_dpb_transact(decoder, NULL,
					DDL_DPB_OP_SET_MASK);
				ddl->cmd_state = DDL_CMD_EOS;

				memset(&dec_param, 0, sizeof(dec_param));

				dec_param.cmd_seq_num =
					++ddl_context->cmd_seq_num;
				dec_param.inst_id = ddl->instance_id;
				dec_param.shared_mem_addr_offset =
					DDL_ADDR_OFFSET(
					ddl_context->dram_base_a,
					ddl->shared_mem[ddl->command_channel]);
				dec_param.release_dpb_bit_mask =
					dpb_mask->hw_mask;
				dec_param.decode =
					VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA;

				ddl_context->vidc_decode_frame_start[ddl->\
					command_channel](&dec_param);
			}
		}
	}
	return ret_status;
}