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;
}
Ejemplo n.º 2
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;
}