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); }
static u32 ddl_channel_set_callback(struct ddl_context *ddl_context) { struct ddl_client_context *ddl = ddl_context->current_ddl; u32 return_status = false; ddl_move_command_state(ddl_context, DDL_CMD_INVALID); VIDC_DEBUG_REGISTER_LOG; if (!ddl || !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHDONE) ) { VIDC_LOG_STRING("STATE-CRITICAL-CHSET"); DDL_IDLE(ddl_context); return return_status; } VIDC_LOG_STRING("Channel-set"); ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC); if (ddl->decoding) { if (ddl->codec_data.decoder.header_in_start) { ddl_decode_init_codec(ddl); } else { ddl_context->ddl_callback(VCD_EVT_RESP_START, VCD_S_SUCCESS, NULL, 0, (u32 *) ddl, ddl_context->client_data); DDL_IDLE(ddl_context); return_status = true; } } else { ddl_encode_init_codec(ddl); } return return_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 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_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 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); }
u32 ddl_reset_hw(u32 mode) { struct ddl_context *ddl_context; struct ddl_client_context *ddl; int i_client_num; VIDC_LOG_STRING("ddl_reset_hw:called"); ddl_context = ddl_get_context(); ddl_move_command_state(ddl_context, DDL_CMD_INVALID); DDL_BUSY(ddl_context); if (ddl_context->core_virtual_base_addr) vidc_720p_do_sw_reset(); ddl_context->device_state = DDL_DEVICE_NOTINIT; for (i_client_num = 0; i_client_num < VCD_MAX_NO_CLIENT; ++i_client_num) { ddl = ddl_context->ddl_clients[i_client_num]; ddl_context->ddl_clients[i_client_num] = NULL; if (ddl) { ddl_release_client_internal_buffers(ddl); ddl_client_transact(DDL_FREE_CLIENT, &ddl); } } ddl_release_context_buffers(ddl_context); DDL_MEMSET(ddl_context, 0, sizeof(struct ddl_context)); return true; }
u32 ddl_device_release(void *client_data) { struct ddl_context *ddl_context; ddl_context = ddl_get_context(); if (DDL_IS_BUSY(ddl_context)) { VIDC_LOGERR_STRING("ddl_dev_rel:Ddl_busy"); return VCD_ERR_BUSY; } if (!DDL_IS_INITIALIZED(ddl_context)) { VIDC_LOGERR_STRING("ddl_dev_rel:Not_inited"); return VCD_ERR_ILLEGAL_OP; } if (!ddl_client_transact(DDL_ACTIVE_CLIENT, NULL)) { VIDC_LOGERR_STRING("ddl_dev_rel:Client_present_err"); return VCD_ERR_CLIENT_PRESENT; } DDL_BUSY(ddl_context); ddl_context->device_state = DDL_DEVICE_NOTINIT; ddl_context->client_data = client_data; ddl_move_command_state(ddl_context, DDL_CMD_INVALID); vidc_720p_stop_fw(); VIDC_LOG_STRING("FW_ENDDONE"); ddl_release_context_buffers(ddl_context); DDL_IDLE(ddl_context); return VCD_S_SUCCESS; }
u32 ddl_reset_hw(u32 n_mode) { struct ddl_context_type *p_ddl_context; struct ddl_client_context_type *p_ddl; int i_client_num; VIDC_LOG_STRING("ddl_reset_hw:called"); p_ddl_context = ddl_get_context(); ddl_move_command_state(p_ddl_context, DDL_CMD_INVALID); DDL_BUSY(p_ddl_context); if (NULL != p_ddl_context->p_core_virtual_base_addr) vidc_720p_do_sw_reset(); p_ddl_context->n_device_state = DDL_DEVICE_NOTINIT; for (i_client_num = 0; i_client_num < VCD_MAX_NO_CLIENT; ++i_client_num) { p_ddl = p_ddl_context->a_ddl_clients[i_client_num]; p_ddl_context->a_ddl_clients[i_client_num] = NULL; if (p_ddl) { ddl_release_client_internal_buffers(p_ddl); ddl_client_transact(DDL_FREE_CLIENT, &p_ddl); } } ddl_release_context_buffers(p_ddl_context); DDL_MEMSET(p_ddl_context, 0, sizeof(struct ddl_context_type)); VIDC_LOG_BUFFER_INIT; return TRUE; }
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_dma_done_callback(struct ddl_context *ddl_context) { if (!DDLCOMMAND_STATE_IS(ddl_context, DDL_CMD_DMA_INIT)) { VIDC_LOGERR_STRING("UNKWN_DMADONE"); return; } ddl_move_command_state(ddl_context, DDL_CMD_INVALID); VIDC_LOG_STRING("DMA_DONE"); ddl_core_start_cpu(ddl_context); }
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; }
static void ddl_channel_end_callback(struct ddl_context *ddl_context) { struct ddl_client_context *ddl; ddl_move_command_state(ddl_context, DDL_CMD_INVALID); VIDC_LOG_STRING("CH_END_DONE"); ddl = ddl_context->current_ddl; if (!ddl || !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHEND) ) { VIDC_LOG_STRING("STATE-CRITIC
static void ddl_channel_end_callback(struct ddl_context *ddl_context) { struct ddl_client_context *ddl; ddl_move_command_state(ddl_context, DDL_CMD_INVALID); VIDC_LOG_STRING("CH_END_DONE"); ddl = ddl_context->current_ddl; if (!ddl || !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHEND) ) { VIDC_LOG_STRING("STATE-CRITICAL-CHEND"); DDL_IDLE(ddl_context); return; } ddl_release_client_internal_buffers(ddl); ddl_context->ddl_callback(VCD_EVT_RESP_STOP, VCD_S_SUCCESS, NULL, 0, (u32 *) ddl, ddl_context->client_data); ddl_move_client_state(ddl, DDL_CLIENT_OPEN); DDL_IDLE(ddl_context); }
static void ddl_cpu_started_callback(struct ddl_context *ddl_context) { ddl_move_command_state(ddl_context, DDL_CMD_INVALID); VIDC_LOG_STRING("CPU-STARTED"); if (!vidc_720p_cpu_start()) { ddl_hw_fatal_cb(ddl_context); return; } vidc_720p_set_deblock_line_buffer( ddl_context->db_line_buffer.align_physical_addr, ddl_context->db_line_buffer.buffer_size); ddl_context->device_state = DDL_DEVICE_INITED; ddl_context->ddl_callback(VCD_EVT_RESP_DEVICE_INIT, VCD_S_SUCCESS, NULL, 0, NULL, ddl_context->client_data); DDL_IDLE(ddl_context); }
static u32 ddl_get_frame (struct vcd_frame_data *frame, u32 frametype) { enum vidc_720p_frame vidc_frame = (enum vidc_720p_frame)frametype; u32 status = true; switch (vidc_frame) { case VIDC_720P_IFRAME: { frame->flags |= VCD_FRAME_FLAG_SYNCFRAME; frame->frame = VCD_FRAME_I; break; } case VIDC_720P_PFRAME: { frame->frame = VCD_FRAME_P; break; } case VIDC_720P_BFRAME: { frame->frame = VCD_FRAME_B; break; } case VIDC_720P_NOTCODED: { frame->frame = VCD_FRAME_NOTCODED; frame->data_len = 0; break; } case VIDC_720P_IDRFRAME: { frame->flags |= VCD_FRAME_FLAG_SYNCFRAME; frame->frame = VCD_FRAME_IDR; break; } default: { VIDC_LOG_STRING("CRITICAL-FRAMETYPE"); status = false; break; } } return status; }
static u32 ddl_get_frame_type (struct vcd_frame_data_type *p_frame, u32 n_frame_type) { enum vidc_720p_frame_type e_frame_type = (enum vidc_720p_frame_type)n_frame_type; u32 b_status = TRUE; switch (e_frame_type) { case VIDC_720P_IFRAME: { p_frame->n_flags |= VCD_FRAME_FLAG_SYNCFRAME; p_frame->e_frame_type = VCD_FRAME_I; break; } case VIDC_720P_PFRAME: { p_frame->e_frame_type = VCD_FRAME_P; break; } case VIDC_720P_BFRAME: { p_frame->e_frame_type = VCD_FRAME_B; break; } case VIDC_720P_NOTCODED: { p_frame->e_frame_type = VCD_FRAME_NOTCODED; p_frame->n_data_len = 0; break; } default: { VIDC_LOG_STRING("CRITICAL-FRAMETYPE"); b_status = FALSE; break; } } return b_status; }
u32 ddl_client_transact(u32 operation, struct ddl_client_context_type **pddl_client) { u32 ret_status = VCD_ERR_FAIL; u32 n_counter; struct ddl_context_type *p_ddl_context; p_ddl_context = ddl_get_context(); switch (operation) { case DDL_FREE_CLIENT: { if (pddl_client && *pddl_client) { u32 n_channel_id; n_channel_id = (*pddl_client)->n_channel_id; if (n_channel_id < VCD_MAX_NO_CLIENT) { p_ddl_context-> a_ddl_clients[n_channel_id] = NULL; } else { VIDC_LOG_STRING("CHID_CORRUPTION"); } DDL_FREE(*pddl_client); ret_status = VCD_S_SUCCESS; } break; } case DDL_GET_CLIENT: { ret_status = VCD_ERR_MAX_CLIENT; for (n_counter = 0; n_counter < VCD_MAX_NO_CLIENT && ret_status == VCD_ERR_MAX_CLIENT; ++n_counter) { if (!p_ddl_context->a_ddl_clients[n_counter]) { *pddl_client = (struct ddl_client_context_type *) DDL_MALLOC(sizeof (struct ddl_client_context_type) ); if (!*pddl_client) { ret_status = VCD_ERR_ALLOC_FAIL; } else { DDL_MEMSET(*pddl_client, 0, sizeof(struct ddl_client_context_type)); p_ddl_context-> a_ddl_clients[n_counter] = *pddl_client; (*pddl_client)->n_channel_id = n_counter; (*pddl_client)->p_ddl_context = p_ddl_context; ret_status = VCD_S_SUCCESS; } } } break; } case DDL_INIT_CLIENTS: { for (n_counter = 0; n_counter < VCD_MAX_NO_CLIENT; ++n_counter) { p_ddl_context->a_ddl_clients[n_counter] = NULL; } ret_status = VCD_S_SUCCESS; break; } case DDL_ACTIVE_CLIENT: { for (n_counter = 0; n_counter < VCD_MAX_NO_CLIENT; ++n_counter) { if (p_ddl_context->a_ddl_clients[n_counter]) { ret_status = VCD_S_SUCCESS; break; } } break; } default: { ret_status = VCD_ERR_ILLEGAL_PARM; break; } } return ret_status; }
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; }
static u32 ddl_operation_done_callback(struct ddl_context *ddl_context) { u32 return_status = true; switch (ddl_context->cmd_state) { case DDL_CMD_DECODE_FRAME: { return_status = ddl_decoder_frame_run_callback( ddl_context); break; } case DDL_CMD_ENCODE_FRAME: { ddl_encoder_frame_run_callback(ddl_context); break; } case DDL_CMD_CHANNEL_SET: { return_status = ddl_channel_set_callback( ddl_context); break; } case DDL_CMD_INIT_CODEC: { ddl_init_codec_done_callback(ddl_context); break; } case DDL_CMD_HEADER_PARSE: { return_status = ddl_header_done_callback( ddl_context); break; } case DDL_CMD_DECODE_SET_DPB: { return_status = ddl_dpb_buffers_set_done_callback( ddl_context); break; } case DDL_CMD_CHANNEL_END: { ddl_channel_end_callback(ddl_context); break; } case DDL_CMD_EOS: { return_status = ddl_eos_frame_done_callback( ddl_context); break; } case DDL_CMD_CPU_RESET: { ddl_cpu_started_callback(ddl_context); break; } default: { VIDC_LOG_STRING("UNKWN_OPDONE"); return_status = false; break; } } return return_status; }
u32 ddl_decoder_dpb_transact(struct ddl_decoder_data_type *p_decoder, struct ddl_frame_data_type_tag *p_in_out_frame, u32 n_operation) { u32 vcd_status = VCD_S_SUCCESS; u32 n_loopc; struct ddl_frame_data_type_tag *p_found_frame = NULL; struct ddl_mask_type *p_dpb_mask = &p_decoder->dpb_mask; switch (n_operation) { case DDL_DPB_OP_MARK_BUSY: case DDL_DPB_OP_MARK_FREE: { for (n_loopc = 0; !p_found_frame && n_loopc < p_decoder->dp_buf.n_no_of_dec_pic_buf; ++n_loopc) { if (p_in_out_frame->vcd_frm.p_physical == p_decoder->dp_buf. a_dec_pic_buffers[n_loopc].vcd_frm. p_physical) { p_found_frame = &(p_decoder->dp_buf. a_dec_pic_buffers[n_loopc]); break; } } if (p_found_frame) { if (n_operation == DDL_DPB_OP_MARK_BUSY) { p_dpb_mask->n_hw_mask &= (~(0x1 << n_loopc)); *p_in_out_frame = *p_found_frame; } else if (n_operation == DDL_DPB_OP_MARK_FREE) { p_dpb_mask->n_client_mask |= (0x1 << n_loopc); *p_found_frame = *p_in_out_frame; } } else { p_in_out_frame->vcd_frm.p_physical = NULL; p_in_out_frame->vcd_frm.p_virtual = NULL; vcd_status = VCD_ERR_BAD_POINTER; VIDC_LOG_STRING("BUF_NOT_FOUND"); } break; } case DDL_DPB_OP_SET_MASK: { p_dpb_mask->n_hw_mask |= p_dpb_mask->n_client_mask; p_dpb_mask->n_client_mask = 0; vidc_720p_decode_set_dpb_release_buffer_mask (p_dpb_mask->n_hw_mask); break; } case DDL_DPB_OP_INIT: { u32 n_dpb_size; n_dpb_size = (!p_decoder->n_meta_data_offset) ? p_decoder->dp_buf.a_dec_pic_buffers[0].vcd_frm. n_alloc_len : p_decoder->n_meta_data_offset; vidc_720p_decode_set_dpb_details(p_decoder->dp_buf. n_no_of_dec_pic_buf, n_dpb_size, p_decoder->ref_buffer. p_align_physical_addr); for (n_loopc = 0; n_loopc < p_decoder->dp_buf.n_no_of_dec_pic_buf; ++n_loopc) { vidc_720p_decode_set_dpb_buffers(n_loopc, (u32 *) p_decoder-> dp_buf. a_dec_pic_buffers [n_loopc]. vcd_frm. p_physical); VIDC_LOG1("DEC_DPB_BUFn_SIZE", p_decoder->dp_buf. a_dec_pic_buffers[n_loopc].vcd_frm. n_alloc_len); } break; } case DDL_DPB_OP_RETRIEVE: { u32 n_position; if (p_dpb_mask->n_client_mask) { n_position = 0x1; for (n_loopc = 0; n_loopc < p_decoder->dp_buf.n_no_of_dec_pic_buf && !p_found_frame; ++n_loopc) { if (p_dpb_mask-> n_client_mask & n_position) { p_found_frame = &p_decoder->dp_buf. a_dec_pic_buffers[n_loopc]; p_dpb_mask->n_client_mask &= ~(n_position); } n_position <<= 1; } } else if (p_dpb_mask->n_hw_mask) { n_position = 0x1; for (n_loopc = 0; n_loopc < p_decoder->dp_buf.n_no_of_dec_pic_buf && !p_found_frame; ++n_loopc) { if (p_dpb_mask->n_hw_mask & n_position) { p_found_frame = &p_decoder->dp_buf. a_dec_pic_buffers[n_loopc]; p_dpb_mask->n_hw_mask &= ~(n_position); } n_position <<= 1; } } if (p_found_frame) *p_in_out_frame = *p_found_frame; else { p_in_out_frame->vcd_frm.p_physical = NULL; p_in_out_frame->vcd_frm.p_virtual = NULL; } break; } } return vcd_status; }
static u32 ddl_header_done_callback(struct ddl_context_type *p_ddl_context) { struct ddl_client_context_type *p_ddl = p_ddl_context->p_current_ddl; struct ddl_decoder_data_type *p_decoder; struct vidc_720p_seq_hdr_info_type seq_hdr_info; u32 b_process_further = TRUE; u32 b_seq_hdr_only_frame = FALSE; u32 b_need_reconfig = TRUE; struct vcd_frame_data_type *p_input_vcd_frm; struct ddl_frame_data_type_tag *p_reconfig_payload; u32 reconfig_payload_size; if (!p_ddl || !p_ddl->b_decoding || !DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE) ) { VIDC_LOG_STRING("STATE-CRITICAL-HDDONE"); ddl_client_fatal_cb(p_ddl_context); return TRUE; } ddl_move_command_state(p_ddl_context, DDL_CMD_INVALID); ddl_move_client_state(p_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); p_decoder = &(p_ddl->codec_data.decoder); 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; p_decoder->n_y_cb_cr_size = seq_hdr_info.n_min_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) { VIDC_LOGERR_STRING("FATAL: ZeroImageSize"); ddl_client_fatal_cb(p_ddl_context); return b_process_further; } if (seq_hdr_info.n_data_partitioned == 0x1 && p_decoder->codec_type.e_codec == VCD_CODEC_MPEG4 && seq_hdr_info.n_img_size_x > DDL_MAX_DP_FRAME_WIDTH && seq_hdr_info.n_img_size_y > DDL_MAX_DP_FRAME_HEIGHT) { ddl_client_fatal_cb(p_ddl_context); return b_process_further; } ddl_getdec_profilelevel(p_decoder, seq_hdr_info.n_profile, seq_hdr_info.n_level); ddl_calculate_stride(&p_decoder->frame_size, !p_decoder->n_progressive_only); 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; 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_context->p_client_data); DDL_IDLE(p_ddl_context); } else { DBG("%s(): n_width = %d client_frame_size.n_width = %d\n", __func__, p_decoder->frame_size.n_width, p_decoder->client_frame_size.n_width); DBG("%s(): n_height = %d client_frame_size.n_height = %d\n", __func__, p_decoder->frame_size.n_height, p_decoder->client_frame_size.n_height); DBG("%s(): n_size = %d client_frame_size n_size = %d\n", __func__, p_decoder->actual_output_buf_req.n_size, p_decoder->client_output_buf_req.n_size); DBG("%s(): n_min_dpb_num = %d n_actual_count = %d\n", __func__, p_decoder->n_min_dpb_num, p_decoder->client_output_buf_req.n_actual_count); p_input_vcd_frm = &(p_ddl->input_frame.vcd_frm); if (p_decoder->frame_size.n_width == p_decoder->client_frame_size.n_width && p_decoder->frame_size.n_height == p_decoder->client_frame_size.n_height && 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_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_ddl_context->p_client_data); } if (b_need_reconfig) { p_reconfig_payload = &p_ddl->input_frame; reconfig_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_reconfig_payload = NULL; reconfig_payload_size = 0; } p_ddl_context->ddl_callback(VCD_EVT_IND_OUTPUT_RECONFIG, VCD_S_SUCCESS, p_reconfig_payload, reconfig_payload_size, (u32 *) p_ddl, p_ddl_context->p_client_data); } if (!b_need_reconfig && !b_seq_hdr_only_frame) { if (ddl_decode_set_buffers(p_ddl) == VCD_S_SUCCESS) b_process_further = FALSE; else ddl_client_fatal_cb(p_ddl_context); } else DDL_IDLE(p_ddl_context); } return b_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_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; }