static u32 ddl_decoder_frame_run_callback(struct ddl_context *ddl_context) { struct ddl_client_context *ddl = ddl_context->current_ddl; struct vidc_720p_dec_disp_info *dec_disp_info = &(ddl->codec_data.decoder.dec_disp_info); u32 callback_end = false; u32 status = true, eos_present = false;; if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE)) { VIDC_LOG_STRING("STATE-CRITICAL-DECFRMRUN"); ddl_client_fatal_cb(ddl_context); return true; } VIDC_LOG_STRING("DEC_FRM_RUN_DONE"); ddl_move_command_state(ddl_context, DDL_CMD_INVALID); vidc_720p_decode_display_info(dec_disp_info); ddl_decode_dynamic_property(ddl, false); if (dec_disp_info->resl_change) { VIDC_LOG_STRING ("DEC_FRM_RUN_DONE: RECONFIG"); ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE); ddl_move_command_state(ddl_context, DDL_CMD_EOS); vidc_720p_submit_command(ddl->channel_id, VIDC_720P_CMD_FRAMERUN_REALLOCATE); return false; } if ((VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags)) { callback_end = false; eos_present = true; } if (dec_disp_info->disp_status == VIDC_720P_DECODE_ONLY || dec_disp_info->disp_status == VIDC_720P_DECODE_AND_DISPLAY) { if (!eos_present) callback_end = (dec_disp_info->disp_status == VIDC_720P_DECODE_ONLY); ddl_decoder_input_done_callback(ddl, callback_end); } if (dec_disp_info->disp_status == VIDC_720P_DECODE_AND_DISPLAY || dec_disp_info->disp_status == VIDC_720P_DISPLAY_ONLY) { if (!eos_present) callback_end = (dec_disp_info->disp_status == VIDC_720P_DECODE_AND_DISPLAY); if (ddl_decoder_output_done_callback(ddl, callback_end) != VCD_S_SUCCESS) return true; } if (dec_disp_info->disp_status == VIDC_720P_DISPLAY_ONLY || dec_disp_info->disp_status == VIDC_720P_EMPTY_BUFFER) { /* send the same input once again for decoding */ ddl_decode_frame_run(ddl); /* client need to ignore the interrupt */ status = false; } else if (eos_present) { /* send EOS command to HW */ ddl_decode_eos_run(ddl); /* client need to ignore the interrupt */ status = false; } else { ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); /* move to Idle */ DDL_IDLE(ddl_context); } return status; }
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; }
static u32 ddl_decoder_frame_run_callback(struct ddl_context_type *p_ddl_context) { struct ddl_client_context_type *p_ddl = p_ddl_context->p_current_ddl; struct vidc_720p_dec_disp_info_type *p_dec_disp_info = &(p_ddl->codec_data.decoder.dec_disp_info); u32 b_callback_end = FALSE; u32 status = TRUE, eos_present = FALSE;; if (!DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE)) { VIDC_LOG_STRING("STATE-CRITICAL-DECFRMRUN"); ddl_client_fatal_cb(p_ddl_context); return TRUE; } VIDC_LOG_STRING("DEC_FRM_RUN_DONE"); ddl_move_command_state(p_ddl_context, DDL_CMD_INVALID); vidc_720p_decode_display_info(p_dec_disp_info); ddl_decode_dynamic_property(p_ddl, FALSE); if (p_dec_disp_info->n_resl_change) { VIDC_LOGERR_STRING ("ddl_dec_frm_done:Dec_reconfig_not_supported"); ddl_client_fatal_cb(p_ddl_context); return TRUE; } if ((VCD_FRAME_FLAG_EOS & p_ddl->input_frame.vcd_frm.n_flags)) { b_callback_end = FALSE; eos_present = TRUE; } if (p_dec_disp_info->e_disp_status == VIDC_720P_DECODE_ONLY || p_dec_disp_info->e_disp_status == VIDC_720P_DECODE_AND_DISPLAY) { if (!eos_present) b_callback_end = (p_dec_disp_info->e_disp_status == VIDC_720P_DECODE_ONLY); ddl_decoder_input_done_callback(p_ddl, b_callback_end); } if (p_dec_disp_info->e_disp_status == VIDC_720P_DECODE_AND_DISPLAY || p_dec_disp_info->e_disp_status == VIDC_720P_DISPLAY_ONLY) { if (!eos_present) b_callback_end = (p_dec_disp_info->e_disp_status == VIDC_720P_DECODE_AND_DISPLAY); if (ddl_decoder_output_done_callback(p_ddl, b_callback_end) != VCD_S_SUCCESS) return TRUE; } if (p_dec_disp_info->e_disp_status == VIDC_720P_DISPLAY_ONLY) { ddl_decode_frame_run(p_ddl); status = FALSE; } else if (eos_present) { ddl_decode_eos_run(p_ddl); status = FALSE; } else { ddl_move_client_state(p_ddl, DDL_CLIENT_WAIT_FOR_FRAME); DDL_IDLE(p_ddl_context); } return status; }