static void ddl_eos_done_callback(struct ddl_context_type *p_ddl_context) { struct ddl_client_context_type *p_ddl = p_ddl_context->p_current_ddl; u32 n_displaystatus; if (!DDLCOMMAND_STATE_IS(p_ddl_context, DDL_CMD_EOS)) { VIDC_LOGERR_STRING("UNKWN_EOSDONE"); ddl_client_fatal_cb(p_ddl_context); return; } if (!p_ddl || !p_ddl->b_decoding || !DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE) ) { VIDC_LOG_STRING("STATE-CRITICAL-EOSDONE"); ddl_client_fatal_cb(p_ddl_context); return; } ddl_move_command_state(p_ddl_context, DDL_CMD_INVALID); vidc_720p_eos_info(&n_displaystatus); if ((enum vidc_720p_display_status_type)n_displaystatus != VIDC_720P_EMPTY_BUFFER) { VIDC_LOG_STRING("EOSDONE-EMPTYBUF-ISSUE"); } ddl_decode_dynamic_property(p_ddl, FALSE); ddl_move_client_state(p_ddl, DDL_CLIENT_WAIT_FOR_FRAME); VIDC_LOG_STRING("EOS_DONE"); p_ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, VCD_S_SUCCESS, NULL, 0, (u32 *) p_ddl, p_ddl_context->p_client_data); DDL_IDLE(p_ddl_context); }
static void ddl_handle_npf_decoding_error(struct ddl_client_context_type *p_ddl) { struct vidc_1080p_dec_disp_info_type *p_dec_disp_info = &(p_ddl->codec_data.decoder.dec_disp_info); if (!p_ddl->b_decoding) { DDL_MSG_ERROR("VIDC_FW_ISSUE_ENC_NPF"); ddl_client_fatal_cb(p_ddl); } else { vidc_sm_get_frame_tags( &p_ddl->shared_mem[p_ddl->n_command_channel], &p_dec_disp_info->n_tag_top, &p_dec_disp_info->n_tag_bottom); ddl_vidc_decode_dynamic_property(p_ddl, FALSE); p_ddl->output_frame.vcd_frm.n_ip_frm_tag = p_dec_disp_info->n_tag_top; p_ddl->output_frame.vcd_frm.p_physical = NULL; p_ddl->output_frame.vcd_frm.p_virtual = NULL; p_ddl->output_frame.b_frm_trans_end = FALSE; p_ddl->p_ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, VCD_ERR_INTRLCD_FIELD_DROP, &(p_ddl->output_frame), sizeof(struct ddl_frame_data_type_tag), (u32 *) p_ddl, p_ddl->p_client_data); ddl_vidc_decode_frame_run(p_ddl); } }
static u32 ddl_encoder_seq_done_callback(struct ddl_context *ddl_context, struct ddl_client_context *ddl) { struct ddl_encoder_data *encoder; DDL_MSG_MED("ddl_encoder_seq_done_callback"); if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) { DDL_MSG_ERROR("STATE-CRITICAL-INITCODEC"); ddl_client_fatal_cb(ddl); return true; } if (vidc_msg_timing) ddl_calc_core_proc_time(__func__, ENC_OP_TIME); ddl->cmd_state = DDL_CMD_INVALID; 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_MSG_LOW("INIT_CODEC_DONE"); encoder = &ddl->codec_data.encoder; vidc_1080p_get_encoder_sequence_header_size( &encoder->seq_header_length); if ((encoder->codec.codec == VCD_CODEC_H264) && (encoder->profile.profile == VCD_PROFILE_H264_BASELINE)) if ((encoder->seq_header.align_virtual_addr) && (encoder->seq_header_length > 6)) encoder->seq_header.align_virtual_addr[6] = 0xC0; 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); return true; }
static void ddl_encoder_eos_done(struct ddl_context *ddl_context) { struct ddl_client_context *ddl; u32 channel_inst_id; vidc_1080p_get_returned_channel_inst_id(&channel_inst_id); vidc_1080p_clear_returned_channel_inst_id(); ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context, ddl_context->response_cmd_ch_id); if (!ddl || (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE))) { DDL_MSG_ERROR("STATE-CRITICAL-EOSFRMDONE"); ddl_client_fatal_cb(ddl); } else { struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); vidc_1080p_get_encode_frame_info(&encoder->enc_frame_info); ddl_handle_enc_frame_done(ddl); DDL_MSG_LOW("encoder_eos_done"); ddl->cmd_state = DDL_CMD_INVALID; 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_MSG_LOW("eos_done"); ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, VCD_S_SUCCESS, NULL, 0, (u32 *)ddl, ddl->client_data); ddl_release_command_channel(ddl_context, ddl->command_channel); } }
static u32 ddl_handle_client_fatal_errors(struct ddl_context *ddl_context) { u32 status = false; switch (ddl_context->cmd_err_status) { case MB_NUM_INVALID: case FRAME_RATE_NOT_SUPPORTED: case INVALID_QP_VALUE: case INVALID_RC_REACTION_COEFFICIENT: case INVALID_CPB_SIZE_AT_GIVEN_LEVEL: case ALLOC_DPB_SIZE_NOT_SUFFICIENT: case ALLOC_DB_SIZE_NOT_SUFFICIENT: case ALLOC_COMV_SIZE_NOT_SUFFICIENT: case NUM_BUF_OUT_OF_RANGE: case NULL_CONTEXT_POINTER: case NULL_COMAMND_CONTROL_COMM_POINTER: case NULL_METADATA_INPUT_POINTER: case NULL_DPB_POINTER: case NULL_COMV_POINTER: { status = true; break; } } if (!status) ERR("UNKNOWN-OP-FAILED"); ddl_client_fatal_cb(ddl_context); return true; }
static u32 ddl_encoder_seq_done_callback(struct ddl_context_type *p_ddl_context, struct ddl_client_context_type *p_ddl) { struct ddl_encoder_data_type *p_encoder; DDL_MSG_MED("ddl_encoder_seq_done_callback"); if (!DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) { DDL_MSG_ERROR("STATE-CRITICAL-INITCODEC"); ddl_client_fatal_cb(p_ddl); return TRUE; } p_ddl->e_cmd_state = DDL_CMD_INVALID; DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_FRAME", ddl_get_state_string(p_ddl->e_client_state)); p_ddl->e_client_state = DDL_CLIENT_WAIT_FOR_FRAME; DDL_MSG_LOW("INIT_CODEC_DONE"); p_encoder = &p_ddl->codec_data.encoder; vidc_1080p_get_encoder_sequence_header_size( &p_encoder->n_seq_header_length); 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); return TRUE; }
static void ddl_init_codec_done_callback(struct ddl_context *ddl_context) { struct ddl_client_context *ddl = ddl_context->current_ddl; struct ddl_encoder_data *encoder; if (!ddl || ddl->decoding || !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE) ) { VIDC_LOG_STRING("STATE-CRITICAL-INITCODEC"); ddl_client_fatal_cb(ddl_context); return; } ddl_move_command_state(ddl_context, DDL_CMD_INVALID); ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); VIDC_LOG_STRING("INIT_CODEC_DONE"); encoder = &ddl->codec_data.encoder; if (encoder->seq_header.virtual_base_addr) { vidc_720p_encode_get_header(&encoder->seq_header. buffer_size); } ddl_context->ddl_callback(VCD_EVT_RESP_START, VCD_S_SUCCESS, NULL, 0, (u32 *) ddl, ddl_context->client_data); DDL_IDLE(ddl_context); }
u32 ddl_handle_seqhdr_fail_error(struct ddl_context *ddl_context) { struct ddl_client_context *ddl = ddl_context->current_ddl; struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; u32 status = false; if (ddl_context->cmd_state == DDL_CMD_HEADER_PARSE && DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) { switch (ddl_context->cmd_err_status) { case UNSUPPORTED_FEATURE_IN_PROFILE: case HEADER_NOT_FOUND: case INVALID_SPS_ID: case INVALID_PPS_ID: case RESOLUTION_NOT_SUPPORTED: ERR("SEQ-HDR-FAILED!!!"); if ((ddl_context->cmd_err_status == RESOLUTION_NOT_SUPPORTED) && (decoder->codec.codec == VCD_CODEC_H264 || decoder->codec.codec == VCD_CODEC_H263 || decoder->codec.codec == VCD_CODEC_MPEG4 || decoder->codec.codec == VCD_CODEC_VC1_RCV || decoder->codec.codec == VCD_CODEC_VC1)) { ddl_client_fatal_cb(ddl_context); status = true; break; } if (decoder->header_in_start) { decoder->header_in_start = false; ddl_context->ddl_callback(VCD_EVT_RESP_START, VCD_ERR_SEQHDR_PARSE_FAIL, NULL, 0, (void *)ddl, ddl_context->client_data); } else { if (ddl->input_frame.vcd_frm.flags & VCD_FRAME_FLAG_EOS) ddl->input_frame.frm_trans_end = false; else ddl->input_frame.frm_trans_end = true; ddl_decode_dynamic_property(ddl, false); ddl_context->ddl_callback( VCD_EVT_RESP_INPUT_DONE, VCD_ERR_SEQHDR_PARSE_FAIL, &ddl->input_frame, sizeof(struct ddl_frame_data_tag), (void *)ddl, ddl_context->client_data); if (ddl->input_frame.vcd_frm.flags & VCD_FRAME_FLAG_EOS) ddl_context->ddl_callback( VCD_EVT_RESP_EOS_DONE, VCD_S_SUCCESS, NULL, 0, (void *)ddl, ddl_context->client_data); } ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC); DDL_IDLE(ddl_context); status = true; } } return 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; 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->codec_data.decoder.dec_disp_info, ddl->codec_data.decoder.output_order, &disp_status, &rsl_chg); ddl_vidc_decode_dynamic_property(ddl, false); if (disp_status == VIDC_1080P_DISPLAY_STATUS_DPB_EMPTY) { 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; }
static u32 ddl_eos_frame_done_callback(struct ddl_context *ddl_context) { struct ddl_client_context *ddl = ddl_context->current_ddl; struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); struct vidc_720p_dec_disp_info *dec_disp_info = &(decoder->dec_disp_info); if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) { VIDC_LOGERR_STRING("STATE-CRITICAL-EOSFRMRUN"); ddl_client_fatal_cb(ddl_context); return true; } VIDC_LOG_STRING("EOS_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->disp_status == VIDC_720P_DISPLAY_ONLY) { if (ddl_decoder_output_done_callback(ddl, false) != VCD_S_SUCCESS) return true; } else VIDC_LOG_STRING("STATE-CRITICAL-WRONG-DISP-STATUS"); ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK); ddl_move_command_state(ddl_context, DDL_CMD_EOS); vidc_720p_submit_command(ddl->channel_id, VIDC_720P_CMD_FRAMERUN); return false; }
static u32 ddl_dpb_buffers_set_done_callback( struct ddl_context *ddl_context) { struct ddl_client_context *ddl; u32 channel_inst_id, ret_status = true; DDL_MSG_MED("ddl_dpb_buffers_set_done_callback"); vidc_1080p_get_returned_channel_inst_id(&channel_inst_id); vidc_1080p_clear_returned_channel_inst_id(); ddl = ddl_get_current_ddl_client_for_command(ddl_context, DDL_CMD_DECODE_SET_DPB); if (ddl) { ddl->cmd_state = DDL_CMD_INVALID; if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPBDONE)) { DDL_MSG_ERROR("STATE-CRITICAL-DPBDONE"); ddl_client_fatal_cb(ddl); } else { DDL_MSG_LOW("INTR_DPBDONE"); DDL_MSG_LOW("ddl_state_transition: %s ~~>" "DDL_CLIENT_WAIT_FOR_FRAME", ddl_get_state_string(ddl->client_state)); if (vidc_msg_timing) { ddl_calc_core_proc_time(__func__, DEC_OP_TIME); ddl_reset_core_time_variables(DEC_OP_TIME); } ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; ddl_vidc_decode_frame_run(ddl); ret_status = false; } } return ret_status; }
static u32 ddl_handle_client_fatal_errors( struct ddl_client_context_type *p_ddl) { struct ddl_context_type *p_ddl_context = p_ddl->p_ddl_context; u32 b_status = FALSE; switch (p_ddl_context->n_cmd_err_status) { case VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE: case VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED: case VIDC_1080P_ERROR_FRAME_RATE_NOT_SUPPORTED: case VIDC_1080P_ERROR_INVALID_QP_VALUE: case VIDC_1080P_ERROR_INVALID_RC_REACTION_COEFFICIENT: case VIDC_1080P_ERROR_INVALID_CPB_SIZE_AT_GIVEN_LEVEL: case VIDC_1080P_ERROR_ALLOC_DPB_SIZE_NOT_SUFFICIENT: case VIDC_1080P_ERROR_NUM_DPB_OUT_OF_RANGE: case VIDC_1080P_ERROR_NULL_METADATA_INPUT_POINTER: case VIDC_1080P_ERROR_NULL_DPB_POINTER: case VIDC_1080P_ERROR_NULL_OTH_EXT_BUFADDR: case VIDC_1080P_ERROR_NULL_MV_POINTER: b_status = TRUE; DDL_MSG_ERROR("VIDC_CLIENT_FATAL!!"); break; default: break; } if (!b_status) DDL_MSG_ERROR("VIDC_UNKNOWN_OP_FAILED"); ddl_client_fatal_cb(p_ddl); return TRUE; }
static void ddl_encoder_frame_run_callback(struct ddl_context *ddl_context) { struct ddl_client_context *ddl = ddl_context->current_ddl; struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); u32 eos_present = false; if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE) ) { VIDC_LOG_STRING("STATE-CRITICAL-ENCFRMRUN"); ddl_client_fatal_cb(ddl_context); return; } VIDC_LOG_STRING("ENC_FRM_RUN_DONE"); ddl_move_command_state(ddl_context, DDL_CMD_INVALID); vidc_720p_enc_frame_info(&encoder->enc_frame_info); ddl->output_frame.vcd_frm.ip_frm_tag = ddl->input_frame.vcd_frm.ip_frm_tag; ddl->output_frame.vcd_frm.data_len = encoder->enc_frame_info.enc_size; ddl->output_frame.vcd_frm.flags |= VCD_FRAME_FLAG_ENDOFFRAME; ddl_get_frame (&(ddl->output_frame.vcd_frm), encoder->enc_frame_info.frame); ddl_process_encoder_metadata(ddl); ddl_encode_dynamic_property(ddl, false); ddl->input_frame.frm_trans_end = false; ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE, VCD_S_SUCCESS, &(ddl->input_frame), sizeof(struct ddl_frame_data_tag), (u32 *) ddl, ddl_context->client_data); if (vidc_msg_timing) ddl_calc_core_proc_time(__func__, ENC_OP_TIME); /* check the presence of EOS */ eos_present = ((VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags)); ddl->output_frame.frm_trans_end = !eos_present; ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, VCD_S_SUCCESS, &(ddl->output_frame), sizeof(struct ddl_frame_data_tag), (u32 *) ddl, ddl_context->client_data); if (eos_present) { VIDC_LOG_STRING("ENC-EOS_DONE"); ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, VCD_S_SUCCESS, NULL, 0, (u32 *)ddl, ddl_context->client_data); } ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); DDL_IDLE(ddl_context); }
static void ddl_encoder_frame_run_callback(struct ddl_context_type *p_ddl_context) { struct ddl_client_context_type *p_ddl = p_ddl_context->p_current_ddl; struct ddl_encoder_data_type *p_encoder = &(p_ddl->codec_data.encoder); u32 b_eos_present = FALSE; if (!DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE) ) { VIDC_LOG_STRING("STATE-CRITICAL-ENCFRMRUN"); ddl_client_fatal_cb(p_ddl_context); return; } VIDC_LOG_STRING("ENC_FRM_RUN_DONE"); ddl_move_command_state(p_ddl_context, DDL_CMD_INVALID); vidc_720p_enc_frame_info(&p_encoder->enc_frame_info); p_ddl->output_frame.vcd_frm.n_ip_frm_tag = p_ddl->input_frame.vcd_frm.n_ip_frm_tag; p_ddl->output_frame.vcd_frm.n_data_len = p_encoder->enc_frame_info.n_enc_size; p_ddl->output_frame.vcd_frm.n_flags |= VCD_FRAME_FLAG_ENDOFFRAME; ddl_get_frame_type (&(p_ddl->output_frame.vcd_frm), p_encoder->enc_frame_info.n_frame_type); ddl_process_encoder_metadata(p_ddl); ddl_encode_dynamic_property(p_ddl, FALSE); p_ddl->input_frame.b_frm_trans_end = FALSE; p_ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE, VCD_S_SUCCESS, &(p_ddl->input_frame), sizeof(struct ddl_frame_data_type_tag), (u32 *) p_ddl, p_ddl_context->p_client_data); #ifdef CORE_TIMING_INFO ddl_calc_core_time(1); #endif b_eos_present = ((VCD_FRAME_FLAG_EOS & p_ddl->input_frame.vcd_frm.n_flags)); p_ddl->output_frame.b_frm_trans_end = !b_eos_present; p_ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, VCD_S_SUCCESS, &(p_ddl->output_frame), sizeof(struct ddl_frame_data_type_tag), (u32 *) p_ddl, p_ddl_context->p_client_data); if (b_eos_present) { VIDC_LOG_STRING("ENC-EOS_DONE"); p_ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, VCD_S_SUCCESS, NULL, 0, (u32 *)p_ddl, p_ddl_context->p_client_data); } ddl_move_client_state(p_ddl, DDL_CLIENT_WAIT_FOR_FRAME); DDL_IDLE(p_ddl_context); }
static u32 ddl_eos_done_callback(struct ddl_context *ddl_context) { struct ddl_client_context *ddl = ddl_context->current_ddl; u32 displaystatus, resl_change; if (!DDLCOMMAND_STATE_IS(ddl_context, DDL_CMD_EOS)) { VIDC_LOGERR_STRING("UNKWN_EOSDONE"); ddl_client_fatal_cb(ddl_context); return true; } if (!ddl || !ddl->decoding || !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE) ) { VIDC_LOG_STRING("STATE-CRITICAL-EOSDONE"); ddl_client_fatal_cb(ddl_context); return true; } ddl_move_command_state(ddl_context, DDL_CMD_INVALID); vidc_720p_eos_info(&displaystatus, &resl_change); if ((enum vidc_720p_display_status)displaystatus != VIDC_720P_EMPTY_BUFFER) { VIDC_LOG_STRING("EOSDONE-EMPTYBUF-ISSUE"); } ddl_decode_dynamic_property(ddl, false); if (resl_change == 0x1) { ddl->codec_data.decoder.header_in_start = false; 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_decode_init_codec(ddl); return false; } ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); VIDC_LOG_STRING("EOS_DONE"); ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, VCD_S_SUCCESS, NULL, 0, (u32 *) ddl, ddl_context->client_data); DDL_IDLE(ddl_context); return true; }
static void ddl_decoder_eos_done_callback( struct ddl_client_context_type *p_ddl) { struct ddl_context_type *p_ddl_context = p_ddl->p_ddl_context; if (!p_ddl->b_decoding) { DDL_MSG_ERROR("STATE-CRITICAL-EOSDONE"); ddl_client_fatal_cb(p_ddl); } else { p_ddl->e_client_state = DDL_CLIENT_WAIT_FOR_FRAME; DDL_MSG_LOW("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); ddl_release_command_channel(p_ddl_context, p_ddl->n_command_channel); } }
static u32 ddl_dpb_buffers_set_done_callback(struct ddl_context *ddl_context) { struct ddl_client_context *ddl = ddl_context->current_ddl; ddl_move_command_state(ddl_context, DDL_CMD_INVALID); if (!ddl || !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPBDONE) ) { VIDC_LOG_STRING("STATE-CRITICAL-DPBDONE"); ddl_client_fatal_cb(ddl_context); return true; } VIDC_LOG_STRING("INTR_DPBDONE"); ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); ddl->codec_data.decoder.dec_disp_info.img_size_x = 0; ddl->codec_data.decoder.dec_disp_info.img_size_y = 0; ddl_decode_frame_run(ddl); return false; }
void ddl_handle_npf_decoding_error(struct ddl_context *ddl_context) { struct ddl_client_context *ddl = ddl_context->current_ddl; struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; if (!ddl->decoding) { ERR("FWISSUE-ENC-NPF!!!"); ddl_client_fatal_cb(ddl_context); return; } vidc_720p_decode_display_info(&decoder->dec_disp_info); ddl_decode_dynamic_property(ddl, false); ddl->output_frame.vcd_frm.ip_frm_tag = decoder->dec_disp_info.tag_top; ddl->output_frame.vcd_frm.physical = NULL; ddl->output_frame.frm_trans_end = false; ddl->ddl_context->ddl_callback( VCD_EVT_RESP_OUTPUT_DONE, VCD_ERR_INTRLCD_FIELD_DROP, &ddl->output_frame, sizeof(struct ddl_frame_data_tag), (void *)ddl, ddl->ddl_context->client_data); ddl_decode_frame_run(ddl); }
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); } } }
static u32 ddl_decoder_seq_done_callback(struct ddl_context *ddl_context, struct ddl_client_context *ddl) { struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; struct vidc_1080p_seq_hdr_info seq_hdr_info; u32 process_further = true; DDL_MSG_MED("ddl_decoder_seq_done_callback"); if (!ddl->decoding || !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) { DDL_MSG_ERROR("STATE-CRITICAL-HDDONE"); ddl_client_fatal_cb(ddl); } else { ddl->cmd_state = DDL_CMD_INVALID; DDL_MSG_LOW("ddl_state_transition: %s ~~>" "DDL_CLIENT_WAIT_FOR_DPB", ddl_get_state_string(ddl->client_state)); ddl->client_state = DDL_CLIENT_WAIT_FOR_DPB; DDL_MSG_LOW("HEADER_DONE"); vidc_1080p_get_decode_seq_start_result(&seq_hdr_info); parse_hdr_size_data(ddl, &seq_hdr_info); if (!seq_hdr_info.img_size_x || !seq_hdr_info.img_size_y) { DDL_MSG_ERROR("FATAL:ZeroImageSize"); ddl_client_fatal_cb(ddl); return process_further; } vidc_sm_get_profile_info(&ddl->shared_mem [ddl->command_channel], &seq_hdr_info.profile, &seq_hdr_info.level); ddl_get_dec_profile_level(decoder, seq_hdr_info.profile, seq_hdr_info.level); ddl_calculate_stride(&decoder->frame_size, !decoder->progressive_only); decoder->frame_size.scan_lines = DDL_ALIGN(decoder->frame_size.height, DDL_TILE_ALIGN_HEIGHT); decoder->frame_size.stride = DDL_ALIGN(decoder->frame_size.width, DDL_TILE_ALIGN_WIDTH); parse_hdr_crop_data(ddl, &seq_hdr_info); if (decoder->codec.codec == VCD_CODEC_H264 && seq_hdr_info.level > VIDC_1080P_H264_LEVEL4) { DDL_MSG_ERROR("WARNING: H264MaxLevelExceeded : %d", seq_hdr_info.level); } ddl_set_default_decoder_buffer_req(decoder, false); if (decoder->header_in_start) { decoder->client_frame_size = decoder->frame_size; decoder->client_output_buf_req = decoder->actual_output_buf_req; if ((decoder->frame_size.width * decoder->frame_size.height) >= VCD_DDL_WVGA_BUF_SIZE) { if ((decoder->actual_output_buf_req.\ actual_count + 2) < 10) decoder->client_output_buf_req.\ actual_count = 10; else decoder->client_output_buf_req.\ actual_count += 2; } else decoder->client_output_buf_req.\ actual_count = decoder->\ actual_output_buf_req.\ actual_count + 5; decoder->client_input_buf_req = decoder->actual_input_buf_req; 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); } else { u32 seq_hdr_only_frame = false; u32 need_reconfig = true; struct vcd_frame_data *input_vcd_frm = &ddl->input_frame.vcd_frm; if ((input_vcd_frm->flags & VCD_FRAME_FLAG_EOS) || ((decoder->frame_size.width == decoder->client_frame_size.width) && (decoder->frame_size.height == decoder->client_frame_size.height) && (decoder->actual_output_buf_req.sz <= decoder->client_output_buf_req.sz) && (decoder->actual_output_buf_req.actual_count == decoder->client_output_buf_req.actual_count) && (decoder->frame_size.scan_lines == decoder->client_frame_size.scan_lines) && (decoder->frame_size.stride == decoder->client_frame_size.stride))) need_reconfig = false; if (((input_vcd_frm->flags & VCD_FRAME_FLAG_CODECCONFIG) && (!(input_vcd_frm->flags & VCD_FRAME_FLAG_SYNCFRAME))) || input_vcd_frm->data_len <= seq_hdr_info.dec_frm_size) { seq_hdr_only_frame = true; input_vcd_frm->offset += seq_hdr_info.dec_frm_size; input_vcd_frm->data_len = 0; input_vcd_frm->flags |= VCD_FRAME_FLAG_CODECCONFIG; ddl->input_frame.frm_trans_end = !need_reconfig; 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); } else { if (decoder->codec.codec == VCD_CODEC_VC1_RCV) { vidc_sm_set_start_byte_number( &ddl->shared_mem [ddl->command_channel], seq_hdr_info.dec_frm_size); } } if (need_reconfig) { struct ddl_frame_data_tag *payload = &ddl->input_frame; u32 payload_size = sizeof(struct ddl_frame_data_tag); decoder->client_frame_size = decoder->frame_size; decoder->client_output_buf_req = decoder->actual_output_buf_req; decoder->client_input_buf_req = decoder->actual_input_buf_req; if (seq_hdr_only_frame) { payload = NULL; payload_size = 0; } ddl_context->ddl_callback( VCD_EVT_IND_OUTPUT_RECONFIG, VCD_S_SUCCESS, payload, payload_size, (u32 *) ddl, ddl->client_data); } if (!need_reconfig && !seq_hdr_only_frame) { if (!ddl_vidc_decode_set_buffers(ddl)) process_further = false; else { DDL_MSG_ERROR("ddl_vidc_decode_set_" "buffers failed"); ddl_client_fatal_cb(ddl); } } else ddl_release_command_channel(ddl_context, ddl->command_channel); } } return process_further; }
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_decoder_frame_run_callback(struct ddl_client_context *ddl) { struct ddl_context *ddl_context = ddl->ddl_context; u32 callback_end = false, ret_status = false; u32 eos_present = false, rsl_chg; enum vidc_1080p_display_status disp_status; DDL_MSG_MED("ddl_decoder_frame_run_callback"); if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE)) { DDL_MSG_ERROR("STATE-CRITICAL-DECFRMRUN"); ddl_client_fatal_cb(ddl); ret_status = true; } else { DDL_MSG_LOW("DEC_FRM_RUN_DONE"); ddl->cmd_state = DDL_CMD_INVALID; get_dec_status(&ddl->codec_data.decoder.dec_disp_info, ddl->codec_data.decoder.output_order, &disp_status, &rsl_chg); ddl_vidc_decode_dynamic_property(ddl, false); if (rsl_chg) { DDL_MSG_ERROR("DEC_RECONFIG_NOT_SUPPORTED"); ddl_client_fatal_cb(ddl); #if (1) //PANTECH Qualcomm SBA Àû¿ë: Case No.517406 ret_status = true; #endif } else { if ((VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags)) { callback_end = false; eos_present = true; } if (disp_status == VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY || disp_status == VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY) { if (!eos_present) callback_end = (disp_status == VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY); ddl_decoder_input_done_callback(ddl, callback_end); } if (disp_status == VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY || disp_status == VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY) { if (!eos_present) callback_end = (disp_status == VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY); if (ddl_decoder_output_done_callback( ddl, callback_end)) ret_status = true; } if (!ret_status) { if (disp_status == VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY || disp_status == VIDC_1080P_DISPLAY_STATUS_DPB_EMPTY || disp_status == VIDC_1080P_DISPLAY_STATUS_NOOP) { ddl_vidc_decode_frame_run(ddl); } else if (eos_present) ddl_vidc_decode_eos_run(ddl); else { ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; ddl_release_command_channel(ddl_context, ddl->command_channel); ret_status = true; } } } } return ret_status; }
static u32 ddl_header_done_callback(struct ddl_context *ddl_context) { struct ddl_client_context *ddl = ddl_context->current_ddl; struct ddl_decoder_data *decoder; struct vidc_720p_seq_hdr_info seq_hdr_info; u32 process_further = true; u32 seq_hdr_only_frame = false; u32 need_reconfig = true; struct vcd_frame_data *input_vcd_frm; struct ddl_frame_data_tag *reconfig_payload = NULL; u32 reconfig_payload_size = 0; if (!ddl || !ddl->decoding || !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE) ) { VIDC_LOG_STRING("STATE-CRITICAL-HDDONE"); ddl_client_fatal_cb(ddl_context); return true; } if (vidc_msg_timing) ddl_calc_core_proc_time(__func__, DEC_OP_TIME); ddl_move_command_state(ddl_context, DDL_CMD_INVALID); ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_DPB); VIDC_LOG_STRING("HEADER_DONE"); VIDC_DEBUG_REGISTER_LOG; vidc_720p_decode_get_seq_hdr_info(&seq_hdr_info); decoder = &(ddl->codec_data.decoder); decoder->frame_size.width = seq_hdr_info.img_size_x; decoder->frame_size.height = seq_hdr_info.img_size_y; decoder->min_dpb_num = seq_hdr_info.min_num_dpb; decoder->y_cb_cr_size = seq_hdr_info.min_dpb_size; decoder->progressive_only = 1 - seq_hdr_info.progressive; if (!seq_hdr_info.img_size_x || !seq_hdr_info.img_size_y) { VIDC_LOGERR_STRING("FATAL: ZeroImageSize"); ddl_client_fatal_cb(ddl_context); return process_further; } if (seq_hdr_info.data_partitioned == 0x1 && decoder->codec.codec == VCD_CODEC_MPEG4 && seq_hdr_info.img_size_x > DDL_MAX_DP_FRAME_WIDTH && seq_hdr_info.img_size_y > DDL_MAX_DP_FRAME_HEIGHT) { ddl_client_fatal_cb(ddl_context); return process_further; } ddl_getdec_profilelevel(decoder, seq_hdr_info.profile, seq_hdr_info.level); ddl_calculate_stride(&decoder->frame_size, !decoder->progressive_only, decoder->codec.codec); if (seq_hdr_info.crop_exists) { decoder->frame_size.width -= (seq_hdr_info.crop_right_offset + seq_hdr_info.crop_left_offset); decoder->frame_size.height -= (seq_hdr_info.crop_top_offset + seq_hdr_info.crop_bottom_offset); } ddl_set_default_decoder_buffer_req(decoder, false); if (decoder->header_in_start) { decoder->client_frame_size = decoder->frame_size; decoder->client_output_buf_req = decoder->actual_output_buf_req; decoder->client_input_buf_req = decoder->actual_input_buf_req; ddl_context->ddl_callback(VCD_EVT_RESP_START, VCD_S_SUCCESS, NULL, 0, (u32 *) ddl, ddl_context->client_data); DDL_IDLE(ddl_context); } else { DBG("%s(): Client data: WxH(%u x %u) SxSL(%u x %u) Sz(%u)\n", __func__, decoder->client_frame_size.width, decoder->client_frame_size.height, decoder->client_frame_size.stride, decoder->client_frame_size.scan_lines, decoder->client_output_buf_req.sz); DBG("%s(): DDL data: WxH(%u x %u) SxSL(%u x %u) Sz(%u)\n", __func__, decoder->frame_size.width, decoder->frame_size.height, decoder->frame_size.stride, decoder->frame_size.scan_lines, decoder->actual_output_buf_req.sz); DBG("%s(): min_dpb_num = %d actual_count = %d\n", __func__, decoder->min_dpb_num, decoder->client_output_buf_req.actual_count); input_vcd_frm = &(ddl->input_frame.vcd_frm); if (decoder->frame_size.width == decoder->client_frame_size.width && decoder->frame_size.height == decoder->client_frame_size.height && decoder->frame_size.stride == decoder->client_frame_size.stride && decoder->frame_size.scan_lines == decoder->client_frame_size.scan_lines && decoder->actual_output_buf_req.sz <= decoder->client_output_buf_req.sz && decoder->actual_output_buf_req.actual_count <= decoder->client_output_buf_req.actual_count && decoder->progressive_only) need_reconfig = false; if ((input_vcd_frm->data_len == seq_hdr_info.dec_frm_size || (input_vcd_frm->flags & VCD_FRAME_FLAG_CODECCONFIG)) && (!need_reconfig || !(input_vcd_frm->flags & VCD_FRAME_FLAG_EOS))) { input_vcd_frm->flags |= VCD_FRAME_FLAG_CODECCONFIG; seq_hdr_only_frame = true; ddl->input_frame.frm_trans_end = !need_reconfig; ddl_context->ddl_callback( VCD_EVT_RESP_INPUT_DONE, VCD_S_SUCCESS, &ddl->input_frame, sizeof(struct ddl_frame_data_tag), (u32 *) ddl, ddl->ddl_context->client_data); } else if (decoder->codec.codec != VCD_CODEC_H263) { input_vcd_frm->offset += seq_hdr_info.dec_frm_size; input_vcd_frm->data_len -= seq_hdr_info.dec_frm_size; } if (need_reconfig) { decoder->client_frame_size = decoder->frame_size; decoder->client_output_buf_req = decoder->actual_output_buf_req; decoder->client_input_buf_req = decoder->actual_input_buf_req; if (!seq_hdr_only_frame) { reconfig_payload = &ddl->input_frame; reconfig_payload_size = sizeof(struct ddl_frame_data_tag); } ddl_context->ddl_callback(VCD_EVT_IND_OUTPUT_RECONFIG, VCD_S_SUCCESS, reconfig_payload, reconfig_payload_size, (u32 *) ddl, ddl_context->client_data); } if (!need_reconfig && !seq_hdr_only_frame) { if (ddl_decode_set_buffers(ddl) == VCD_S_SUCCESS) process_further = false; else ddl_client_fatal_cb(ddl_context); } else DDL_IDLE(ddl_context); } return process_further; }
static u32 ddl_decoder_frame_run_callback( struct ddl_client_context *ddl) { struct ddl_context *ddl_context = ddl->ddl_context; struct vidc_1080p_dec_disp_info *dec_disp_info = &ddl->codec_data.decoder.dec_disp_info; u32 callback_end = false, ret_status = true, eos_present = false; DDL_MSG_MED("ddl_decoder_frame_run_callback"); if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE)) { DDL_MSG_ERROR("STATE-CRITICAL-DECFRMRUN"); ddl_client_fatal_cb(ddl); } else { DDL_MSG_LOW("DEC_FRM_RUN_DONE"); ddl->cmd_state = DDL_CMD_INVALID; vidc_1080p_get_display_frame_result(dec_disp_info); ddl_vidc_decode_dynamic_property(ddl, false); if (dec_disp_info->resl_change) { DDL_MSG_ERROR("DEC_RECONFIG_NOT_SUPPORTED"); ddl_client_fatal_cb(ddl); } else { if ((VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags)) { callback_end = false; eos_present = true; } if (dec_disp_info->display_status == VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY || dec_disp_info->display_status == VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY) { if (!eos_present) callback_end = (dec_disp_info->display_status == VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY); ddl_decoder_input_done_callback(ddl, callback_end); } if (dec_disp_info->display_status == VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY || dec_disp_info->display_status == VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY) { u32 vcd_status; if (!eos_present) callback_end = (dec_disp_info->\ display_status == VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY); vcd_status = ddl_decoder_ouput_done_callback( ddl, callback_end); if (vcd_status) return true; } if (dec_disp_info->display_status == VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY || dec_disp_info->display_status == VIDC_1080P_DISPLAY_STATUS_DPB_EMPTY) { ddl_vidc_decode_frame_run(ddl); ret_status = false; } else if (eos_present) { ddl_vidc_decode_eos_run(ddl); ret_status = false; } else { ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; ddl_release_command_channel(ddl_context, ddl->command_channel); } } } return ret_status; }
static u32 ddl_decoder_seq_done_callback(struct ddl_context_type *p_ddl_context, struct ddl_client_context_type *p_ddl) { struct ddl_decoder_data_type *p_decoder = &p_ddl->codec_data.decoder; struct vidc_1080p_seq_hdr_info_type seq_hdr_info; u32 b_process_further = TRUE; DDL_MSG_MED("ddl_decoder_seq_done_callback"); if (!p_ddl->b_decoding || !DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) { DDL_MSG_ERROR("STATE-CRITICAL-HDDONE"); ddl_client_fatal_cb(p_ddl); } else { p_ddl->e_cmd_state = DDL_CMD_INVALID; DDL_MSG_LOW("ddl_state_transition: %s ~~>\ DDL_CLIENT_WAIT_FOR_DPB",\ ddl_get_state_string(p_ddl->e_client_state)); p_ddl->e_client_state = DDL_CLIENT_WAIT_FOR_DPB; DDL_MSG_LOW("HEADER_DONE"); vidc_1080p_get_decode_seq_start_result(&seq_hdr_info); p_decoder->frame_size.n_width = seq_hdr_info.n_img_size_x; p_decoder->frame_size.n_height = seq_hdr_info.n_img_size_y; p_decoder->n_min_dpb_num = seq_hdr_info.n_min_num_dpb; vidc_sm_get_min_yc_dpb_sizes( &p_ddl->shared_mem[p_ddl->n_command_channel], &seq_hdr_info.n_min_luma_dpb_size, &seq_hdr_info.n_min_chroma_dpb_size); p_decoder->n_y_cb_cr_size = seq_hdr_info.n_min_luma_dpb_size + seq_hdr_info.n_min_chroma_dpb_size; p_decoder->dpb_buf_size.n_size_yuv = p_decoder->n_y_cb_cr_size; p_decoder->dpb_buf_size.n_size_y = seq_hdr_info.n_min_luma_dpb_size; p_decoder->dpb_buf_size.n_size_c = seq_hdr_info.n_min_chroma_dpb_size; p_decoder->n_progressive_only = 1 - seq_hdr_info.n_progressive; if (!seq_hdr_info.n_img_size_x || !seq_hdr_info.n_img_size_y) { DDL_MSG_ERROR("FATAL:ZeroImageSize"); ddl_client_fatal_cb(p_ddl); return b_process_further; } vidc_sm_get_profile_info(&p_ddl->shared_mem [p_ddl->n_command_channel], &seq_hdr_info.n_profile, &seq_hdr_info.n_level); ddl_get_dec_profile_level(p_decoder, seq_hdr_info.n_profile, seq_hdr_info.n_level); ddl_calculate_stride(&p_decoder->frame_size, !p_decoder->n_progressive_only); vidc_sm_get_crop_info( &p_ddl->shared_mem[p_ddl->n_command_channel], &seq_hdr_info.n_crop_left_offset, &seq_hdr_info.n_crop_right_offset, &seq_hdr_info.n_crop_top_offset, &seq_hdr_info.n_crop_bottom_offset); seq_hdr_info.n_crop_exists = (seq_hdr_info.n_crop_left_offset || seq_hdr_info.n_crop_right_offset || seq_hdr_info.n_crop_top_offset || seq_hdr_info.n_crop_bottom_offset); if (seq_hdr_info.n_crop_exists) { p_decoder->frame_size.n_width -= seq_hdr_info.n_crop_right_offset + seq_hdr_info.n_crop_left_offset; p_decoder->frame_size.n_height -= seq_hdr_info.n_crop_top_offset + seq_hdr_info.n_crop_bottom_offset; } ddl_set_default_decoder_buffer_req(p_decoder, FALSE); if (p_decoder->b_header_in_start) { p_decoder->client_frame_size = p_decoder->frame_size; p_decoder->client_output_buf_req = p_decoder->actual_output_buf_req; if ((p_decoder->frame_size.n_width * p_decoder->frame_size.n_height) >= VCD_DDL_WVGA_BUF_SIZE) { if ((p_decoder->actual_output_buf_req.\ n_actual_count + 2) < 10) p_decoder->client_output_buf_req.\ n_actual_count = 10; else p_decoder->client_output_buf_req.\ n_actual_count += 2; } else p_decoder->client_output_buf_req.\ n_actual_count = p_decoder->\ actual_output_buf_req.\ n_actual_count + 5; p_decoder->client_input_buf_req = p_decoder->actual_input_buf_req; 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); } else { u32 b_seq_hdr_only_frame = FALSE; u32 b_need_reconfig = TRUE; struct vcd_frame_data_type *p_input_vcd_frm = &p_ddl->input_frame.vcd_frm; if ((p_decoder->frame_size.n_width <= p_decoder->client_frame_size.n_stride) && (p_decoder->frame_size.n_height <= p_decoder->client_frame_size.n_scan_lines) && (p_decoder->actual_output_buf_req.n_size <= p_decoder->client_output_buf_req.n_size) && (p_decoder->n_min_dpb_num <= p_decoder->\ client_output_buf_req.n_actual_count)) b_need_reconfig = FALSE; if (((p_input_vcd_frm->n_flags & VCD_FRAME_FLAG_CODECCONFIG) && (!(p_input_vcd_frm->n_flags & VCD_FRAME_FLAG_SYNCFRAME))) || p_input_vcd_frm->n_data_len == seq_hdr_info.n_dec_frm_size) { b_seq_hdr_only_frame = TRUE; p_input_vcd_frm->n_offset += seq_hdr_info.n_dec_frm_size; p_input_vcd_frm->n_data_len -= seq_hdr_info.n_dec_frm_size; p_input_vcd_frm->n_flags |= VCD_FRAME_FLAG_CODECCONFIG; p_ddl->input_frame.b_frm_trans_end = !b_need_reconfig; p_ddl_context->ddl_callback( VCD_EVT_RESP_INPUT_DONE, VCD_S_SUCCESS, &p_ddl->input_frame, sizeof(struct ddl_frame_data_type_tag), (u32 *) p_ddl, p_ddl->p_client_data); } if (b_need_reconfig) { struct ddl_frame_data_type_tag *p_payload = &p_ddl->input_frame; u32 n_payload_size = sizeof(struct ddl_frame_data_type_tag); p_decoder->client_frame_size = p_decoder->frame_size; p_decoder->client_output_buf_req = p_decoder->actual_output_buf_req; p_decoder->client_input_buf_req = p_decoder->actual_input_buf_req; if (b_seq_hdr_only_frame) { p_payload = NULL; n_payload_size = 0; } p_ddl_context->ddl_callback( VCD_EVT_IND_OUTPUT_RECONFIG, VCD_S_SUCCESS, p_payload, n_payload_size, (u32 *) p_ddl, p_ddl->p_client_data); } if (!b_need_reconfig && !b_seq_hdr_only_frame) { if (!ddl_vidc_decode_set_buffers(p_ddl)) b_process_further = FALSE; else { DDL_MSG_ERROR("ddl_vidc_decode_set_\ buffers failed"); ddl_client_fatal_cb(p_ddl); } } else ddl_release_command_channel(p_ddl_context, p_ddl->n_command_channel); } }
static u32 ddl_decoder_seq_done_callback(struct ddl_context *ddl_context, struct ddl_client_context *ddl) { struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; struct vidc_1080p_seq_hdr_info seq_hdr_info; u32 process_further = true; DDL_MSG_MED("ddl_decoder_seq_done_callback"); if (!ddl->decoding || !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) { DDL_MSG_ERROR("STATE-CRITICAL-HDDONE"); ddl_client_fatal_cb(ddl); } else { ddl->cmd_state = DDL_CMD_INVALID; DDL_MSG_LOW("ddl_state_transition: %s ~~>\ DDL_CLIENT_WAIT_FOR_DPB",\ ddl_get_state_string(ddl->client_state)); ddl->client_state = DDL_CLIENT_WAIT_FOR_DPB; DDL_MSG_LOW("HEADER_DONE"); vidc_1080p_get_decode_seq_start_result(&seq_hdr_info); decoder->frame_size.width = seq_hdr_info.img_size_x; decoder->frame_size.height = seq_hdr_info.img_size_y; decoder->min_dpb_num = seq_hdr_info.min_num_dpb; vidc_sm_get_min_yc_dpb_sizes( &ddl->shared_mem[ddl->command_channel], &seq_hdr_info.min_luma_dpb_size, &seq_hdr_info.min_chroma_dpb_size); decoder->y_cb_cr_size = seq_hdr_info.min_luma_dpb_size + seq_hdr_info.min_chroma_dpb_size; decoder->dpb_buf_size.size_yuv = decoder->y_cb_cr_size; decoder->dpb_buf_size.size_y = seq_hdr_info.min_luma_dpb_size; decoder->dpb_buf_size.size_c = seq_hdr_info.min_chroma_dpb_size; decoder->progressive_only = 1 - seq_hdr_info.progressive; if (!seq_hdr_info.img_size_x || !seq_hdr_info.img_size_y) { DDL_MSG_ERROR("FATAL:ZeroImageSize"); ddl_client_fatal_cb(ddl); return process_further; } vidc_sm_get_profile_info(&ddl->shared_mem [ddl->command_channel], &seq_hdr_info.profile, &seq_hdr_info.level); ddl_get_dec_profile_level(decoder, seq_hdr_info.profile, seq_hdr_info.level); ddl_calculate_stride(&decoder->frame_size, !decoder->progressive_only); vidc_sm_get_crop_info( &ddl->shared_mem[ddl->command_channel], &seq_hdr_info.crop_left_offset, &seq_hdr_info.crop_right_offset, &seq_hdr_info.crop_top_offset, &seq_hdr_info.crop_bottom_offset); seq_hdr_info.crop_exists = (seq_hdr_info.crop_left_offset || seq_hdr_info.crop_right_offset || seq_hdr_info.crop_top_offset || seq_hdr_info.crop_bottom_offset); if (seq_hdr_info.crop_exists) { decoder->frame_size.width -= seq_hdr_info.crop_right_offset + seq_hdr_info.crop_left_offset; decoder->frame_size.height -= seq_hdr_info.crop_top_offset + seq_hdr_info.crop_bottom_offset; } ddl_set_default_decoder_buffer_req(decoder, false); if (decoder->header_in_start) { decoder->client_frame_size = decoder->frame_size; decoder->client_output_buf_req = decoder->actual_output_buf_req; if ((decoder->frame_size.width * decoder->frame_size.height) >= VCD_DDL_WVGA_BUF_SIZE) { if ((decoder->actual_output_buf_req.\ actual_count + 2) < 10) decoder->client_output_buf_req.\ actual_count = 10; else decoder->client_output_buf_req.\ actual_count += 2; } else decoder->client_output_buf_req.\ actual_count = decoder->\ actual_output_buf_req.\ actual_count + 5; decoder->client_input_buf_req = decoder->actual_input_buf_req; 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); } else { u32 seq_hdr_only_frame = false; u32 need_reconfig = true; struct vcd_frame_data *input_vcd_frm = &ddl->input_frame.vcd_frm; if ((decoder->frame_size.width == decoder->client_frame_size.width) && (decoder->frame_size.height == decoder->client_frame_size.height) && (decoder->actual_output_buf_req.sz <= decoder->client_output_buf_req.sz) && (decoder->actual_output_buf_req.actual_count <= decoder->client_output_buf_req.actual_count) && (decoder->frame_size.scan_lines == decoder->client_frame_size.scan_lines) && (decoder->frame_size.stride == decoder->client_frame_size.stride)) need_reconfig = false; if (((input_vcd_frm->flags & VCD_FRAME_FLAG_CODECCONFIG) && (!(input_vcd_frm->flags & VCD_FRAME_FLAG_SYNCFRAME))) || input_vcd_frm->data_len == seq_hdr_info.dec_frm_size) { seq_hdr_only_frame = true; input_vcd_frm->offset += seq_hdr_info.dec_frm_size; input_vcd_frm->data_len -= seq_hdr_info.dec_frm_size; input_vcd_frm->flags |= VCD_FRAME_FLAG_CODECCONFIG; ddl->input_frame.frm_trans_end = !need_reconfig; 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); } if (need_reconfig) { struct ddl_frame_data_tag *payload = &ddl->input_frame; u32 payload_size = sizeof(struct ddl_frame_data_tag); decoder->client_frame_size = decoder->frame_size; decoder->client_output_buf_req = decoder->actual_output_buf_req; decoder->client_input_buf_req = decoder->actual_input_buf_req; if (seq_hdr_only_frame) { payload = NULL; payload_size = 0; } ddl_context->ddl_callback( VCD_EVT_IND_OUTPUT_RECONFIG, VCD_S_SUCCESS, payload, payload_size, (u32 *) ddl, ddl->client_data); } if (!need_reconfig && !seq_hdr_only_frame) { if (!ddl_vidc_decode_set_buffers(ddl)) process_further = false; else { DDL_MSG_ERROR("ddl_vidc_decode_set_\ buffers failed"); ddl_client_fatal_cb(ddl); } } else ddl_release_command_channel(ddl_context, ddl->command_channel); } }
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_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_decoder_frame_run_callback(struct ddl_client_context *ddl) { struct ddl_context *ddl_context = ddl->ddl_context; struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; u32 callback_end = false, ret_status = false; u32 eos_present = false, rsl_chg; u32 more_field_needed, extended_rsl_chg; enum vidc_1080p_display_status disp_status; DDL_MSG_MED("ddl_decoder_frame_run_callback"); if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE)) { DDL_MSG_ERROR("STATE-CRITICAL-DECFRMRUN"); ddl_client_fatal_cb(ddl); ret_status = true; } else { DDL_MSG_LOW("DEC_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, &extended_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 (rsl_chg != DDL_RESL_CHANGE_NO_CHANGE) { ddl_handle_reconfig(rsl_chg, ddl); ret_status = false; } else { if ((VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags)) { callback_end = false; eos_present = true; } if (disp_status == VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY || disp_status == VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY) { if (!eos_present) callback_end = (disp_status == VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY); ddl_decoder_input_done_callback(ddl, callback_end); } if (disp_status == VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY || disp_status == VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY) { if (!eos_present) callback_end = (disp_status == VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY); if (ddl_decoder_output_done_callback( ddl, callback_end)) ret_status = true; } if (!ret_status) { if (disp_status == VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY || disp_status == VIDC_1080P_DISPLAY_STATUS_DPB_EMPTY || disp_status == VIDC_1080P_DISPLAY_STATUS_NOOP) { ddl_vidc_decode_frame_run(ddl); } else if (eos_present) ddl_vidc_decode_eos_run(ddl); else { ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; ddl_release_command_channel(ddl_context, ddl->command_channel); ret_status = true; } } } } return ret_status; }
static u32 ddl_decoder_seq_done_callback(struct ddl_context *ddl_context, struct ddl_client_context *ddl) { struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; struct vidc_1080p_seq_hdr_info seq_hdr_info; u32 process_further = true; struct ddl_profile_info_type disp_profile_info; /*HTC_START Fix Klocwork issue*/ seq_hdr_info.profile = 0; seq_hdr_info.level = 0; /*HTC_END*/ DDL_MSG_MED("ddl_decoder_seq_done_callback"); if (!ddl->decoding || !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) { DDL_MSG_ERROR("STATE-CRITICAL-HDDONE"); ddl_client_fatal_cb(ddl); } else { if (vidc_msg_timing) ddl_calc_core_proc_time(__func__, DEC_OP_TIME); ddl->cmd_state = DDL_CMD_INVALID; DDL_MSG_LOW("ddl_state_transition: %s ~~>" "DDL_CLIENT_WAIT_FOR_DPB", ddl_get_state_string(ddl->client_state)); ddl->client_state = DDL_CLIENT_WAIT_FOR_DPB; DDL_MSG_LOW("HEADER_DONE"); vidc_1080p_get_decode_seq_start_result(&seq_hdr_info); parse_hdr_size_data(ddl, &seq_hdr_info); if (!seq_hdr_info.img_size_x || !seq_hdr_info.img_size_y) { DDL_MSG_ERROR("FATAL:ZeroImageSize"); ddl_client_fatal_cb(ddl); return process_further; } vidc_sm_get_profile_info(&ddl->shared_mem [ddl->command_channel], &disp_profile_info); disp_profile_info.pic_profile = seq_hdr_info.profile; disp_profile_info.pic_level = seq_hdr_info.level; ddl_get_dec_profile_level(decoder, seq_hdr_info.profile, seq_hdr_info.level); switch (decoder->codec.codec) { case VCD_CODEC_H264: if (decoder->profile.profile == VCD_PROFILE_H264_HIGH || decoder->profile.profile == VCD_PROFILE_UNKNOWN) { if ((disp_profile_info.chroma_format_idc > VIDC_1080P_IDCFORMAT_420) || (disp_profile_info.bit_depth_luma_minus8 || disp_profile_info. bit_depth_chroma_minus8)) { DDL_MSG_ERROR("Unsupported H.264 " "feature: IDC " "format : %d, Bitdepth: %d", disp_profile_info. chroma_format_idc, (disp_profile_info. bit_depth_luma_minus8 || disp_profile_info. bit_depth_chroma_minus8)); ddl_client_fatal_cb(ddl); return process_further; } } break; case VCD_CODEC_MPEG4: case VCD_CODEC_DIVX_4: case VCD_CODEC_DIVX_5: case VCD_CODEC_DIVX_6: case VCD_CODEC_XVID: if (seq_hdr_info.data_partition) if ((seq_hdr_info.img_size_x * seq_hdr_info.img_size_y) > (720 * 576)) { DDL_MSG_ERROR("Unsupported DP clip"); ddl_client_fatal_cb(ddl); return process_further; } break; default: break; } ddl_calculate_stride(&decoder->frame_size, !decoder->progressive_only); decoder->frame_size.scan_lines = DDL_ALIGN(decoder->frame_size.height, DDL_TILE_ALIGN_HEIGHT); decoder->frame_size.stride = DDL_ALIGN(decoder->frame_size.width, DDL_TILE_ALIGN_WIDTH); parse_hdr_crop_data(ddl, &seq_hdr_info); if (decoder->codec.codec == VCD_CODEC_H264 && seq_hdr_info.level > VIDC_1080P_H264_LEVEL4) { DDL_MSG_ERROR("WARNING: H264MaxLevelExceeded : %d", seq_hdr_info.level); } ddl_set_default_decoder_buffer_req(decoder, false); if (decoder->header_in_start) { if (!(decoder->cont_mode) || (decoder->min_dpb_num > decoder->client_output_buf_req.min_count) || (decoder->actual_output_buf_req.sz > decoder->client_output_buf_req.sz)) { decoder->client_frame_size = decoder->frame_size; decoder->client_output_buf_req = decoder->actual_output_buf_req; decoder->client_input_buf_req = decoder->actual_input_buf_req; } 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); } else { u32 seq_hdr_only_frame = false; u32 need_reconfig = false; struct vcd_frame_data *input_vcd_frm = &ddl->input_frame.vcd_frm; need_reconfig = ddl_check_reconfig(ddl); DDL_MSG_HIGH("%s : need_reconfig = %u\n", __func__, need_reconfig); if (input_vcd_frm->flags & VCD_FRAME_FLAG_EOS) { need_reconfig = false; } if (((input_vcd_frm->flags & VCD_FRAME_FLAG_CODECCONFIG) && (!(input_vcd_frm->flags & VCD_FRAME_FLAG_SYNCFRAME))) || input_vcd_frm->data_len <= seq_hdr_info.dec_frm_size) { seq_hdr_only_frame = true; input_vcd_frm->offset += seq_hdr_info.dec_frm_size; input_vcd_frm->data_len = 0; input_vcd_frm->flags |= VCD_FRAME_FLAG_CODECCONFIG; ddl->input_frame.frm_trans_end = !need_reconfig; 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); } else { if (decoder->codec.codec == VCD_CODEC_VC1_RCV) { vidc_sm_set_start_byte_number( &ddl->shared_mem [ddl->command_channel], seq_hdr_info.dec_frm_size); } } if (need_reconfig) { struct ddl_frame_data_tag *payload = &ddl->input_frame; u32 payload_size = sizeof(struct ddl_frame_data_tag); decoder->client_frame_size = decoder->frame_size; decoder->client_output_buf_req = decoder->actual_output_buf_req; decoder->client_input_buf_req = decoder->actual_input_buf_req; if (seq_hdr_only_frame) { payload = NULL; payload_size = 0; } DDL_MSG_HIGH("%s : sending port reconfig\n", __func__); ddl_context->ddl_callback( VCD_EVT_IND_OUTPUT_RECONFIG, VCD_S_SUCCESS, payload, payload_size, (u32 *) ddl, ddl->client_data); } if (!need_reconfig && !seq_hdr_only_frame) { if (!ddl_vidc_decode_set_buffers(ddl)) process_further = false; else { DDL_MSG_ERROR("ddl_vidc_decode_set_" "buffers failed"); ddl_client_fatal_cb(ddl); } } else ddl_release_command_channel(ddl_context, ddl->command_channel); } } return process_further; }