Esempio n. 1
0
static u32 ddl_handle_core_recoverable_errors(struct ddl_context \
			*ddl_context)
{
	struct ddl_client_context  *ddl = ddl_context->current_ddl;
	u32   vcd_status = VCD_S_SUCCESS;
	u32   vcd_event = VCD_EVT_RESP_INPUT_DONE;
	u32   eos = false, pending_display = 0, release_mask = 0;

	if (ddl->decoding)
		if (ddl_handle_seqhdr_fail_error(ddl_context))
			return true;

	if (ddl_context->cmd_state != DDL_CMD_DECODE_FRAME &&
		ddl_context->cmd_state != DDL_CMD_ENCODE_FRAME) {
		return false;
	}
	switch (ddl_context->cmd_err_status) {
	case NON_PAIRED_FIELD_NOT_SUPPORTED:
		{
			ddl_handle_npf_decoding_error(ddl_context);
			return true;
		}
	case NO_BUFFER_RELEASED_FROM_HOST:
		{
			/* lets check sanity of this error */
			release_mask =
				ddl->codec_data.decoder.dpb_mask.hw_mask;
			while (release_mask > 0) {
				if ((release_mask & 0x1))
					pending_display += 1;
				release_mask >>= 1;
			}

			if (pending_display >=
				ddl->codec_data.decoder.min_dpb_num) {
				DBG("FWISSUE-REQBUF!!");
				/* callback to client for client fatal error */
				ddl_client_fatal_cb(ddl_context);
				return true ;
			}
		vcd_event = VCD_EVT_RESP_OUTPUT_REQ;
		break;
		}
	case BIT_STREAM_BUF_EXHAUST:
	case MB_HEADER_NOT_DONE:
	case MB_COEFF_NOT_DONE:
	case CODEC_SLICE_NOT_DONE:
	case VME_NOT_READY:
	case VC1_BITPLANE_DECODE_ERR:
		{
			u32 reset_core;
			/* need to reset the internal core hw engine */
			reset_core = ddl_hal_engine_reset(ddl_context);
			if (!reset_core)
				return true;
			/* fall through to process bitstream error handling */
		}
	case RESOLUTION_MISMATCH:
	case NV_QUANT_ERR:
	case SYNC_MARKER_ERR:
	case FEATURE_NOT_SUPPORTED:
	case MEM_CORRUPTION:
	case INVALID_REFERENCE_FRAME:
	case PICTURE_CODING_TYPE_ERR:
	case MV_RANGE_ERR:
	case PICTURE_STRUCTURE_ERR:
	case SLICE_ADDR_INVALID:
	case NON_FRAME_DATA_RECEIVED:
	case INCOMPLETE_FRAME:
	case PICTURE_MANAGEMENT_ERROR:
	case INVALID_MMCO:
	case INVALID_PIC_REORDERING:
	case INVALID_POC_TYPE:
	case ACTIVE_SPS_NOT_PRESENT:
	case ACTIVE_PPS_NOT_PRESENT:
		{
			vcd_status = VCD_ERR_BITSTREAM_ERR;
			break;
		}
	case PROFILE_UNKOWN:
		if (ddl->decoding)
			vcd_status = VCD_ERR_BITSTREAM_ERR;
		break;
	}

	if (!vcd_status && vcd_event == VCD_EVT_RESP_INPUT_DONE)
		return false;

	ddl->input_frame.frm_trans_end = true;

	eos = ((vcd_event == VCD_EVT_RESP_INPUT_DONE) &&
		((VCD_FRAME_FLAG_EOS & ddl->input_frame.
				vcd_frm.flags)));

	if ((ddl->decoding && eos) ||
		(!ddl->decoding))
		ddl->input_frame.frm_trans_end = false;

	if (vcd_event == VCD_EVT_RESP_INPUT_DONE &&
		ddl->decoding &&
		!ddl->codec_data.decoder.header_in_start &&
		!ddl->codec_data.decoder.dec_disp_info.img_size_x &&
		!ddl->codec_data.decoder.dec_disp_info.img_size_y
		) {
		/* this is first frame seq. header only case */
		vcd_status = VCD_S_SUCCESS;
		ddl->input_frame.vcd_frm.flags |=
			VCD_FRAME_FLAG_CODECCONFIG;
		ddl->input_frame.frm_trans_end = !eos;
		/* put just some non - zero value */
		ddl->codec_data.decoder.dec_disp_info.img_size_x = 0xff;
	}
	/* inform client about input failed */
	ddl_input_failed_cb(ddl_context, vcd_event, vcd_status);

	/* for Encoder case, we need to send output done also */
	if (!ddl->decoding) {
		/* transaction is complete after this callback */
		ddl->output_frame.frm_trans_end = !eos;
		/* error case: NO data present */
		ddl->output_frame.vcd_frm.data_len = 0;
		/* call back to client for output frame done */
		ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
		VCD_ERR_FAIL, &(ddl->output_frame),
			sizeof(struct ddl_frame_data_tag),
			(void *)ddl, ddl_context->client_data);

		if (eos) {
			DBG("ENC-EOS_DONE");
			/* send client EOS DONE callback */
			ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE,
				VCD_S_SUCCESS, NULL, 0, (void *)ddl,
				ddl_context->client_data);
		}
	}

	/* if it is decoder EOS case */
	if (ddl->decoding && eos)
		ddl_decode_eos_run(ddl);
	else
		DDL_IDLE(ddl_context);

	return true;
}
static u32 ddl_handle_core_recoverable_errors(struct ddl_context \
			*ddl_context)
{
	struct ddl_client_context  *ddl = ddl_context->current_ddl;
	u32   vcd_status = VCD_S_SUCCESS;
	u32   vcd_event = VCD_EVT_RESP_INPUT_DONE;
	u32   eos = false, pending_display = 0, release_mask = 0;

	if (ddl->decoding)
		if (ddl_handle_seqhdr_fail_error(ddl_context))
			return true;

	if (ddl_context->cmd_state != DDL_CMD_DECODE_FRAME &&
		ddl_context->cmd_state != DDL_CMD_ENCODE_FRAME) {
		return false;
	}
	switch (ddl_context->cmd_err_status) {
	case NON_PAIRED_FIELD_NOT_SUPPORTED:
		{
			ddl_handle_npf_decoding_error(ddl_context);
			return true;
		}
	case NO_BUFFER_RELEASED_FROM_HOST:
		{
			
			release_mask =
				ddl->codec_data.decoder.dpb_mask.hw_mask;
			while (release_mask > 0) {
				if ((release_mask & 0x1))
					pending_display += 1;
				release_mask >>= 1;
			}

			if (pending_display >=
				ddl->codec_data.decoder.min_dpb_num) {
				DBG("FWISSUE-REQBUF!!");
				
				ddl_client_fatal_cb(ddl_context);
				return true ;
			}
		vcd_event = VCD_EVT_RESP_OUTPUT_REQ;
		break;
		}
	case BIT_STREAM_BUF_EXHAUST:
	case MB_HEADER_NOT_DONE:
	case MB_COEFF_NOT_DONE:
	case CODEC_SLICE_NOT_DONE:
	case VME_NOT_READY:
	case VC1_BITPLANE_DECODE_ERR:
		{
			u32 reset_core;
			
			reset_core = ddl_hal_engine_reset(ddl_context);
			if (!reset_core)
				return true;
			
		}
	case RESOLUTION_MISMATCH:
	case NV_QUANT_ERR:
	case SYNC_MARKER_ERR:
	case FEATURE_NOT_SUPPORTED:
	case MEM_CORRUPTION:
	case INVALID_REFERENCE_FRAME:
	case PICTURE_CODING_TYPE_ERR:
	case MV_RANGE_ERR:
	case PICTURE_STRUCTURE_ERR:
	case SLICE_ADDR_INVALID:
	case NON_FRAME_DATA_RECEIVED:
	case INCOMPLETE_FRAME:
	case PICTURE_MANAGEMENT_ERROR:
	case INVALID_MMCO:
	case INVALID_PIC_REORDERING:
	case INVALID_POC_TYPE:
		{
			vcd_status = VCD_ERR_BITSTREAM_ERR;
			break;
		}
	case ACTIVE_SPS_NOT_PRESENT:
	case ACTIVE_PPS_NOT_PRESENT:
		{
			if (ddl->codec_data.decoder.idr_only_decoding) {
				DBG("Consider warnings as errors in idr mode");
				ddl_client_fatal_cb(ddl_context);
				return true;
			}
			vcd_status = VCD_ERR_BITSTREAM_ERR;
			break;
		}
	case PROFILE_UNKOWN:
		if (ddl->decoding)
			vcd_status = VCD_ERR_BITSTREAM_ERR;
		break;
	}

	if (!vcd_status && vcd_event == VCD_EVT_RESP_INPUT_DONE)
		return false;

	ddl->input_frame.frm_trans_end = true;

	eos = ((vcd_event == VCD_EVT_RESP_INPUT_DONE) &&
		((VCD_FRAME_FLAG_EOS & ddl->input_frame.
				vcd_frm.flags)));

	if ((ddl->decoding && eos) ||
		(!ddl->decoding))
		ddl->input_frame.frm_trans_end = false;

	if (vcd_event == VCD_EVT_RESP_INPUT_DONE &&
		ddl->decoding &&
		!ddl->codec_data.decoder.header_in_start &&
		!ddl->codec_data.decoder.dec_disp_info.img_size_x &&
		!ddl->codec_data.decoder.dec_disp_info.img_size_y &&
		!eos) {
		DBG("Treat header in start error %u as success",
			vcd_status);
		
		vcd_status = VCD_S_SUCCESS;
		ddl->input_frame.vcd_frm.flags |=
			VCD_FRAME_FLAG_CODECCONFIG;
		ddl->input_frame.frm_trans_end = !eos;
		
		ddl->codec_data.decoder.dec_disp_info.img_size_x = 0xff;
	}
	
	ddl_input_failed_cb(ddl_context, vcd_event, vcd_status);

	
	if (!ddl->decoding) {
		
		ddl->output_frame.frm_trans_end = !eos;
		
		ddl->output_frame.vcd_frm.data_len = 0;
		
		ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
		VCD_ERR_FAIL, &(ddl->output_frame),
			sizeof(struct ddl_frame_data_tag),
			(void *)ddl, ddl_context->client_data);

		if (eos) {
			DBG("ENC-EOS_DONE");
			
			ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE,
				VCD_S_SUCCESS, NULL, 0, (void *)ddl,
				ddl_context->client_data);
		}
	}

	
	if (ddl->decoding && eos) {
		DBG("DEC-EOS_RUN");
		ddl_decode_eos_run(ddl);
	} else
		DDL_IDLE(ddl_context);

	return true;
}
Esempio n. 3
0
static u32 ddl_handle_core_recoverable_errors(
	struct ddl_client_context_type *p_ddl)
{
	struct ddl_context_type *p_ddl_context = p_ddl->p_ddl_context;
	u32 vcd_status = VCD_S_SUCCESS;
	u32 vcd_event = VCD_EVT_RESP_INPUT_DONE;
	u32 b_eos = FALSE, b_status = FALSE;

	if ((p_ddl->e_cmd_state == DDL_CMD_DECODE_FRAME) ||
		(p_ddl->e_cmd_state == DDL_CMD_ENCODE_FRAME) ||
		(p_ddl->e_cmd_state == DDL_CMD_HEADER_PARSE)) {
		if (p_ddl_context->n_cmd_err_status ==
			VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED) {
			ddl_handle_npf_decoding_error(p_ddl);
			b_status = TRUE;
		} else {
			switch (p_ddl_context->n_cmd_err_status) {
			case VIDC_1080P_ERROR_HEADER_NOT_FOUND:
				if (p_ddl->e_client_state !=
					DDL_CLIENT_WAIT_FOR_INITCODECDONE){
					DDL_MSG_ERROR("VIDC_CRITICAL_HEADER");
					DDL_MSG_ERROR("Unrecoverable error");
				} else {
					DDL_MSG_ERROR("VIDC_HDR_PARSE_FAIL");
					vcd_event = VCD_EVT_RESP_START;
					vcd_status = VCD_ERR_NO_SEQ_HDR;
					p_ddl->codec_data.decoder.\
						b_header_in_start = FALSE;
				}
			break;
			case VIDC_1080P_ERROR_SYNC_POINT_NOT_RECEIVED:
				vcd_status = VCD_ERR_IFRAME_EXPECTED;
			break;
			case VIDC_1080P_ERROR_NO_BUFFER_RELEASED_FROM_HOST:
			{
				u32 n_pending_display = 0, n_release_mask;

				n_release_mask =
					p_ddl->codec_data.decoder.\
					dpb_mask.n_hw_mask;
				while (n_release_mask > 0) {
					if (n_release_mask & 0x1)
						n_pending_display++;
					n_release_mask >>= 1;
				}
				if (n_pending_display >= p_ddl->codec_data.\
					decoder.n_min_dpb_num) {
					DDL_MSG_ERROR("VIDC_FW_ISSUE_REQ_BUF");
					ddl_client_fatal_cb(p_ddl);
					b_status = TRUE;
				} else {
					vcd_event = VCD_EVT_RESP_OUTPUT_REQ;
					DDL_MSG_LOW("VIDC_OUTPUT_BUF_REQ!!");
				}
			}
			break;
			case VIDC_1080P_ERROR_BIT_STREAM_BUF_EXHAUST:
			case VIDC_1080P_ERROR_MB_HEADER_NOT_DONE:
			case VIDC_1080P_ERROR_MB_COEFF_NOT_DONE:
			case VIDC_1080P_ERROR_CODEC_SLICE_NOT_DONE:
			case VIDC_1080P_ERROR_VIDC_CORE_TIME_OUT:
			case VIDC_1080P_ERROR_VC1_BITPLANE_DECODE_ERR:
			case VIDC_1080P_ERROR_RESOLUTION_MISMATCH:
			case VIDC_1080P_ERROR_NV_QUANT_ERR:
			case VIDC_1080P_ERROR_SYNC_MARKER_ERR:
			case VIDC_1080P_ERROR_FEATURE_NOT_SUPPORTED:
			case VIDC_1080P_ERROR_MEM_CORRUPTION:
			case VIDC_1080P_ERROR_INVALID_REFERENCE_FRAME:
			case VIDC_1080P_ERROR_PICTURE_CODING_TYPE_ERR:
			case VIDC_1080P_ERROR_MV_RANGE_ERR:
			case VIDC_1080P_ERROR_PICTURE_STRUCTURE_ERR:
			case VIDC_1080P_ERROR_SLICE_ADDR_INVALID:
			case VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED:
			case VIDC_1080P_ERROR_INCOMPLETE_FRAME:
			case VIDC_1080P_ERROR_NALU_HEADER_ERROR:
			case VIDC_1080P_ERROR_SPS_PARSE_ERROR:
			case VIDC_1080P_ERROR_PPS_PARSE_ERROR:
			case VIDC_1080P_ERROR_SLICE_PARSE_ERROR:
				vcd_status = VCD_ERR_BITSTREAM_ERR;
				DDL_MSG_ERROR("VIDC_BIT_STREAM_ERR");
			break;
			default:
			break;
			}
			if (((!vcd_status) || (vcd_event !=
				VCD_EVT_RESP_INPUT_DONE)) && !b_status) {
				p_ddl->input_frame.b_frm_trans_end = TRUE;
				b_eos = ((vcd_event ==
				VCD_EVT_RESP_INPUT_DONE) &&
				(p_ddl->input_frame.vcd_frm.n_flags &
				VCD_FRAME_FLAG_EOS));
				if ((p_ddl->b_decoding && b_eos) ||
					!p_ddl->b_decoding)
					p_ddl->input_frame.b_frm_trans_end =
						FALSE;
				if ((vcd_event == VCD_EVT_RESP_INPUT_DONE ||
					vcd_event == VCD_EVT_RESP_START) &&
					p_ddl->b_decoding &&
					!p_ddl->codec_data.decoder.\
					b_header_in_start &&
					!p_ddl->codec_data.decoder.\
					dec_disp_info.n_img_size_x &&
					!p_ddl->codec_data.decoder.\
					dec_disp_info.n_img_size_y) {
					vcd_status = VCD_S_SUCCESS;
					p_ddl->input_frame.vcd_frm.n_flags |=
					VCD_FRAME_FLAG_CODECCONFIG;
					p_ddl->input_frame.b_frm_trans_end =
						!b_eos;
					p_ddl->codec_data.decoder.\
						dec_disp_info.n_img_size_x =
							0xff;
				}
				ddl_input_failed_cb(p_ddl, vcd_event,
					vcd_status);
				if (!p_ddl->b_decoding) {
					p_ddl->output_frame.b_frm_trans_end =
						!b_eos;
					p_ddl->output_frame.vcd_frm.\
						n_data_len = 0;
					p_ddl_context->ddl_callback(
						VCD_EVT_RESP_OUTPUT_DONE,
						VCD_ERR_FAIL,
						&p_ddl->output_frame,
						sizeof(struct
						ddl_frame_data_type_tag),
						(u32 *)p_ddl,
						p_ddl->p_client_data);
					if (b_eos) {
						DDL_MSG_LOW(
							"VIDC_ENC_EOS_DONE");
						p_ddl_context->ddl_callback(
							VCD_EVT_RESP_EOS_DONE,
							VCD_S_SUCCESS,
							NULL, 0, (u32 *)p_ddl,
							p_ddl->p_client_data);
					}
				}
				if (p_ddl->b_decoding && b_eos)
					ddl_vidc_decode_eos_run(p_ddl);
				else
					ddl_release_command_channel(
						p_ddl_context,
						p_ddl->n_command_channel);
				b_status = TRUE;
			}
		}
	}
	return b_status;
}