u32 ddl_close(u32 **ddl_handle) { struct ddl_context *ddl_context; struct ddl_client_context **ddl = (struct ddl_client_context **)ddl_handle; if (!ddl || !*ddl) { VIDC_LOGERR_STRING("ddl_close:Bad_handle"); return VCD_ERR_BAD_HANDLE; } ddl_context = ddl_get_context(); if (!DDL_IS_INITIALIZED(ddl_context)) { VIDC_LOGERR_STRING("ddl_close:Not_inited"); return VCD_ERR_ILLEGAL_OP; } if (!DDLCLIENT_STATE_IS(*ddl, DDL_CLIENT_OPEN)) { VIDC_LOGERR_STRING("ddl_close:Not_in_open_state"); return VCD_ERR_ILLEGAL_OP; } ddl_move_client_state(*ddl, DDL_CLIENT_INVALID); if ((*ddl)->decoding) { vcd_fw_transact(false, true, (*ddl)->codec_data.decoder.codec.codec); } else { vcd_fw_transact(false, false, (*ddl)->codec_data.encoder.codec.codec); } ddl_client_transact(DDL_FREE_CLIENT, ddl); return VCD_S_SUCCESS; }
u32 ddl_close(u32 **p_ddl_handle) { struct ddl_context_type *p_ddl_context; struct ddl_client_context_type **pp_ddl = (struct ddl_client_context_type **)p_ddl_handle; if (NULL == pp_ddl || NULL == *pp_ddl) { VIDC_LOGERR_STRING("ddl_close:Bad_handle"); return VCD_ERR_BAD_HANDLE; } p_ddl_context = ddl_get_context(); if (!DDL_IS_INITIALIZED(p_ddl_context)) { VIDC_LOGERR_STRING("ddl_close:Not_inited"); return VCD_ERR_ILLEGAL_OP; } if (!DDLCLIENT_STATE_IS(*pp_ddl, DDL_CLIENT_OPEN)) { VIDC_LOGERR_STRING("ddl_close:Not_in_open_state"); return VCD_ERR_ILLEGAL_OP; } ddl_move_client_state(*pp_ddl, DDL_CLIENT_INVALID); if ((*pp_ddl)->b_decoding) { vcd_fw_transact(FALSE, TRUE, (*pp_ddl)->codec_data.decoder.codec_type.e_codec); } else { vcd_fw_transact(FALSE, FALSE, (*pp_ddl)->codec_data.encoder.codec_type.e_codec); } ddl_client_transact(DDL_FREE_CLIENT, pp_ddl); return VCD_S_SUCCESS; }
static u32 ddl_process_intr_status(struct ddl_context_type *p_ddl_context, u32 int_status) { u32 b_status = TRUE; switch (int_status) { case VIDC_720P_INTR_FRAME_DONE: { b_status = ddl_operation_done_callback(p_ddl_context); break; } case VIDC_720P_INTR_DMA_DONE: { ddl_dma_done_callback(p_ddl_context); b_status = FALSE; break; } case VIDC_720P_INTR_FW_DONE: { ddl_eos_done_callback(p_ddl_context); break; } case VIDC_720P_INTR_BUFFER_FULL: { VIDC_LOGERR_STRING("BUF_FULL_INTR"); ddl_hw_fatal_cb(p_ddl_context); break; } default: { VIDC_LOGERR_STRING("UNKWN_INTR"); break; } } return b_status; }
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_process_core_response(void) { struct ddl_context_type *p_ddl_context; u32 b_return_status = TRUE; p_ddl_context = ddl_get_context(); if (!p_ddl_context->p_core_virtual_base_addr) { VIDC_LOGERR_STRING("UNKWN_INTR"); return FALSE; } if (p_ddl_context->intr_status == DDL_INVALID_INTR_STATUS) { VIDC_LOGERR_STRING("INTERRUPT_NOT_READ"); return FALSE; } if (!ddl_handle_core_errors(p_ddl_context)) { b_return_status = ddl_process_intr_status(p_ddl_context, p_ddl_context->intr_status); } if (p_ddl_context->pf_interrupt_clr) (*p_ddl_context->pf_interrupt_clr)(); p_ddl_context->intr_status = DDL_INVALID_INTR_STATUS; return b_return_status; }
static u32 ddl_process_intr_status(struct ddl_context *ddl_context, u32 int_status) { u32 status = true; switch (int_status) { case VIDC_720P_INTR_FRAME_DONE: { status = ddl_operation_done_callback(ddl_context); break; } case VIDC_720P_INTR_DMA_DONE: { ddl_dma_done_callback(ddl_context); status = false; break; } case VIDC_720P_INTR_FW_DONE: { status = ddl_eos_done_callback(ddl_context); break; } case VIDC_720P_INTR_BUFFER_FULL: { VIDC_LOGERR_STRING("BUF_FULL_INTR"); ddl_hw_fatal_cb(ddl_context); break; } default: { VIDC_LOGERR_STRING("UNKWN_INTR"); break; } } return status; }
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 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; }
u32 vidc_720p_engine_reset(u32 ch_id, enum vidc_720p_endian dma_endian, enum vidc_720p_interrupt_level_selection interrupt_sel, u32 interrupt_mask ) { u32 op_done = 0; u32 counter = 0; VIDC_LOGERR_STRING("ENG-RESET!!"); /* issue the engine reset command */ vidc_720p_submit_command(ch_id, VIDC_720P_CMD_MFC_ENGINE_RESET); do { VIDC_BUSY_WAIT(20); VIDC_IO_IN(REG_982553, &op_done); counter++; } while (!op_done && counter < 10); if (!op_done) { /* Reset fails */ return false ; } /* write invalid channel id */ VIDC_IO_OUT(REG_97293, 4); /* Set INT_PULSE_SEL */ if (interrupt_sel == VIDC_720P_INTERRUPT_LEVEL_SEL) VIDC_IO_OUT(REG_491082, 0); else VIDC_IO_OUT(REG_491082, 1); if (!interrupt_mask) { /* Disable interrupt */ VIDC_IO_OUT(REG_609676, 1); } else { /* Enable interrupt */ VIDC_IO_OUT(REG_609676, 0); } /* Clear any pending interrupt */ VIDC_IO_OUT(REG_614776, 1); /* Set INT_ENABLE_REG */ VIDC_IO_OUT(REG_418173, interrupt_mask); /*Sets the DMA endianness */ VIDC_IO_OUT(REG_736316, dma_endian); /*Restore ARM endianness */ VIDC_IO_OUT(REG_215724, 0); /* retun engine reset success */ 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); }
u32 ddl_decode_end(u32 *ddl_handle, void *client_data) { struct ddl_client_context *ddl = (struct ddl_client_context *)ddl_handle; struct ddl_context *ddl_context; ddl_context = ddl_get_context(); if (vidc_msg_timing) { ddl_reset_core_time_variables(DEC_OP_TIME); ddl_reset_core_time_variables(DEC_IP_TIME); } if (!DDL_IS_INITIALIZED(ddl_context)) { VIDC_LOGERR_STRING("ddl_dec_end:Not_inited"); return VCD_ERR_ILLEGAL_OP; } if (DDL_IS_BUSY(ddl_context)) { VIDC_LOGERR_STRING("ddl_dec_end:Ddl_busy"); return VCD_ERR_BUSY; } if (!ddl || !ddl->decoding) { VIDC_LOGERR_STRING("ddl_dec_end:Bad_handle"); return VCD_ERR_BAD_HANDLE; } if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) && !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) && !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) && !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_FATAL_ERROR) ) { VIDC_LOGERR_STRING("ddl_dec_end:Wrong_state"); return VCD_ERR_ILLEGAL_OP; } DDL_BUSY(ddl_context); ddl_context->current_ddl = ddl; ddl_context->client_data = client_data; ddl_channel_end(ddl); return VCD_S_SUCCESS; }
u32 ddl_decode_end(u32 *ddl_handle, void *p_client_data) { struct ddl_client_context_type *p_ddl = (struct ddl_client_context_type *)ddl_handle; struct ddl_context_type *p_ddl_context; p_ddl_context = ddl_get_context(); #ifdef CORE_TIMING_INFO ddl_reset_time_variables(0); #endif if (!DDL_IS_INITIALIZED(p_ddl_context)) { VIDC_LOGERR_STRING("ddl_dec_end:Not_inited"); return VCD_ERR_ILLEGAL_OP; } if (DDL_IS_BUSY(p_ddl_context)) { VIDC_LOGERR_STRING("ddl_dec_end:Ddl_busy"); return VCD_ERR_BUSY; } if (NULL == p_ddl || FALSE == p_ddl->b_decoding) { VIDC_LOGERR_STRING("ddl_dec_end:Bad_handle"); return VCD_ERR_BAD_HANDLE; } if (!DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_WAIT_FOR_FRAME) && !DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) && !DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_WAIT_FOR_DPB) && !DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_FATAL_ERROR) ) { VIDC_LOGERR_STRING("ddl_dec_end:Wrong_state"); return VCD_ERR_ILLEGAL_OP; } DDL_BUSY(p_ddl_context); p_ddl_context->p_current_ddl = p_ddl; p_ddl_context->p_client_data = p_client_data; ddl_channel_end(p_ddl); return VCD_S_SUCCESS; }
u32 ddl_open(u32 **ddl_handle, u32 decoding) { struct ddl_context *ddl_context; struct ddl_client_context *ddl; u32 status; if (!ddl_handle) { VIDC_LOGERR_STRING("ddl_open:Bad_handle"); return VCD_ERR_BAD_HANDLE; } ddl_context = ddl_get_context(); if (!DDL_IS_INITIALIZED(ddl_context)) { VIDC_LOGERR_STRING("ddl_open:Not_inited"); return VCD_ERR_ILLEGAL_OP; } status = ddl_client_transact(DDL_GET_CLIENT, &ddl); if (status) { VIDC_LOGERR_STRING("ddl_open:Client_trasac_failed"); return status; } ddl_move_client_state(ddl, DDL_CLIENT_OPEN); ddl->codec_data.hdr.decoding = decoding; ddl->decoding = decoding; ddl_set_default_meta_data_hdr(ddl); ddl_set_initial_default_values(ddl); *ddl_handle = (u32 *) ddl; return VCD_S_SUCCESS; }
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; }
void ddl_read_and_clear_interrupt(void) { struct ddl_context *ddl_context; ddl_context = ddl_get_context(); if (!ddl_context->core_virtual_base_addr) { VIDC_LOGERR_STRING("SPURIOUS_INTERRUPT"); return; } vidc_720p_get_interrupt_status(&ddl_context->intr_status, &ddl_context->cmd_err_status, &ddl_context->disp_pic_err_status, &ddl_context->op_failed ); vidc_720p_interrupt_done_clear(); }
u32 ddl_process_core_response(void) { struct ddl_context *ddl_context; u32 return_status = true; ddl_context = ddl_get_context(); if (!ddl_context->core_virtual_base_addr) { VIDC_LOGERR_STRING("UNKWN_INTR"); return false; } if (!ddl_handle_core_errors(ddl_context)) { return_status = ddl_process_intr_status(ddl_context, ddl_context->intr_status); } if (ddl_context->interrupt_clr) (*ddl_context->interrupt_clr)(); return return_status; }
u32 ddl_device_init(struct ddl_init_config *ddl_init_config, void *client_data) { struct ddl_context *ddl_context; u32 status = VCD_S_SUCCESS; if ((!ddl_init_config) || (!ddl_init_config->ddl_callback) || (!ddl_init_config->core_virtual_base_addr) ) { VIDC_LOGERR_STRING("ddl_dev_init:Bad_argument"); return VCD_ERR_ILLEGAL_PARM; } ddl_context = ddl_get_context(); if (DDL_IS_INITIALIZED(ddl_context)) { VIDC_LOGERR_STRING("ddl_dev_init:Multiple_init"); return VCD_ERR_ILLEGAL_OP; } if (DDL_IS_BUSY(ddl_context)) { VIDC_LOGERR_STRING("ddl_dev_init:Ddl_busy"); return VCD_ERR_BUSY; } DDL_MEMSET(ddl_context, 0, sizeof(struct ddl_context)); DDL_BUSY(ddl_context); ddl_context->ddl_callback = ddl_init_config->ddl_callback; ddl_context->interrupt_clr = ddl_init_config->interrupt_clr; ddl_context->core_virtual_base_addr = ddl_init_config->core_virtual_base_addr; ddl_context->client_data = client_data; vidc_720p_set_device_virtual_base(ddl_context-> core_virtual_base_addr); ddl_context->current_ddl = NULL; ddl_move_command_state(ddl_context, DDL_CMD_INVALID); ddl_client_transact(DDL_INIT_CLIENTS, NULL); ddl_pmem_alloc(&ddl_context->context_buf_addr, DDL_CONTEXT_MEMORY, DDL_LINEAR_BUFFER_ALIGN_BYTES); if (!ddl_context->context_buf_addr.virtual_base_addr) { VIDC_LOGERR_STRING("ddl_dev_init:Context_alloc_fail"); status = VCD_ERR_ALLOC_FAIL; } if (!status) { ddl_pmem_alloc(&ddl_context->db_line_buffer, DDL_DB_LINE_BUF_SIZE, DDL_TILE_BUFFER_ALIGN_BYTES); if (!ddl_context->db_line_buffer.virtual_base_addr) { VIDC_LOGERR_STRING("ddl_dev_init:Line_buf_alloc_fail"); status = VCD_ERR_ALLOC_FAIL; } } if (!status) { ddl_pmem_alloc(&ddl_context->data_partition_tempbuf, DDL_MPEG4_DATA_PARTITION_BUF_SIZE, DDL_TILE_BUFFER_ALIGN_BYTES); if (ddl_context->data_partition_tempbuf.virtual_base_addr \ == NULL) { VIDC_LOGERR_STRING ("ddl_dev_init:Data_partition_buf_alloc_fail"); status = VCD_ERR_ALLOC_FAIL; } } if (!status) { ddl_pmem_alloc(&ddl_context->metadata_shared_input, DDL_METADATA_TOTAL_INPUTBUFSIZE, DDL_LINEAR_BUFFER_ALIGN_BYTES); if (!ddl_context->metadata_shared_input.virtual_base_addr) { VIDC_LOGERR_STRING ("ddl_dev_init:metadata_shared_input_alloc_fail"); status = VCD_ERR_ALLOC_FAIL; } } if (!status) { ddl_pmem_alloc(&ddl_context->dbg_core_dump, \ DDL_DBG_CORE_DUMP_SIZE, \ DDL_LINEAR_BUFFER_ALIGN_BYTES); if (!ddl_context->dbg_core_dump.virtual_base_addr) { VIDC_LOGERR_STRING ("ddl_dev_init:dbg_core_dump_alloc_failed"); status = VCD_ERR_ALLOC_FAIL; } ddl_context->enable_dbg_core_dump = 0; } if (!status && !vcd_fw_init()) { VIDC_LOGERR_STRING("ddl_dev_init:fw_init_failed"); status = VCD_ERR_ALLOC_FAIL; } if (status) { ddl_release_context_buffers(ddl_context); DDL_IDLE(ddl_context); return status; } ddl_move_command_state(ddl_context, DDL_CMD_DMA_INIT); ddl_core_init(ddl_context); return 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; }
u32 ddl_encode_frame(u32 *ddl_handle, struct ddl_frame_data_type_tag *p_input_frame, struct ddl_frame_data_type_tag *p_output_bit, void *p_client_data) { struct ddl_client_context_type *p_ddl = (struct ddl_client_context_type *)ddl_handle; struct ddl_context_type *p_ddl_context = ddl_get_context(); #ifdef CORE_TIMING_INFO ddl_get_core_start_time(1); #endif if (!DDL_IS_INITIALIZED(p_ddl_context)) { VIDC_LOGERR_STRING("ddl_enc_frame:Not_inited"); return VCD_ERR_ILLEGAL_OP; } if (DDL_IS_BUSY(p_ddl_context)) { VIDC_LOGERR_STRING("ddl_enc_frame:Ddl_busy"); return VCD_ERR_BUSY; } if (NULL == p_ddl || TRUE == p_ddl->b_decoding) { VIDC_LOGERR_STRING("ddl_enc_frame:Bad_handle"); return VCD_ERR_BAD_HANDLE; } if (NULL == p_input_frame || NULL == p_input_frame->vcd_frm.p_physical || p_ddl->codec_data.encoder.input_buf_req.n_size != p_input_frame->vcd_frm.n_data_len) { VIDC_LOGERR_STRING("ddl_enc_frame:Bad_input_params"); return VCD_ERR_ILLEGAL_PARM; } if (0 != (((u32) p_input_frame->vcd_frm.p_physical + p_input_frame->vcd_frm.n_offset) & (DDL_STREAMBUF_ALIGN_GUARD_BYTES) ) ) { VIDC_LOGERR_STRING ("ddl_enc_frame:Un_aligned_yuv_start_address"); return VCD_ERR_ILLEGAL_PARM; } if (NULL == p_output_bit || NULL == p_output_bit->vcd_frm.p_physical || 0 == p_output_bit->vcd_frm.n_alloc_len) { VIDC_LOGERR_STRING("ddl_enc_frame:Bad_output_params"); return VCD_ERR_ILLEGAL_PARM; } if ((p_ddl->codec_data.encoder.output_buf_req.n_size + p_output_bit->vcd_frm.n_offset) > p_output_bit->vcd_frm.n_alloc_len) { VIDC_LOGERR_STRING ("ddl_enc_frame:n_offset_large, Exceeds_min_buf_size"); } if (!DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_WAIT_FOR_FRAME)) { VIDC_LOGERR_STRING("ddl_enc_frame:Wrong_state"); return VCD_ERR_ILLEGAL_OP; } DDL_BUSY(p_ddl_context); p_ddl_context->p_current_ddl = p_ddl; p_ddl_context->p_client_data = p_client_data; p_ddl->input_frame = *p_input_frame; p_ddl->output_frame = *p_output_bit; ddl_encode_frame_run(p_ddl); return VCD_S_SUCCESS; }
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_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_output_done_callback( struct ddl_client_context_type *p_ddl, u32 b_frame_transact_end) { struct ddl_decoder_data_type *p_decoder = &(p_ddl->codec_data.decoder); struct vidc_720p_dec_disp_info_type *p_dec_disp_info = &(p_decoder->dec_disp_info); struct ddl_frame_data_type_tag *p_output_frame = &p_ddl->output_frame; struct vcd_frame_data_type *p_output_vcd_frm = &(p_output_frame->vcd_frm); u32 vcd_status; u32 n_free_luma_dpb = 0; p_output_vcd_frm->p_physical = (u8 *)p_dec_disp_info->n_y_addr; if (p_decoder->codec_type.e_codec == VCD_CODEC_MPEG4 || p_decoder->codec_type.e_codec == VCD_CODEC_VC1 || p_decoder->codec_type.e_codec == VCD_CODEC_VC1_RCV || (p_decoder->codec_type.e_codec >= VCD_CODEC_DIVX_3 && p_decoder->codec_type.e_codec <= VCD_CODEC_XVID)){ vidc_720p_decode_skip_frm_details(&n_free_luma_dpb); if (n_free_luma_dpb) p_output_vcd_frm->p_physical = (u8 *) n_free_luma_dpb; } vcd_status = ddl_decoder_dpb_transact( p_decoder, p_output_frame, DDL_DPB_OP_MARK_BUSY); if (vcd_status != VCD_S_SUCCESS) { VIDC_LOGERR_STRING("CorruptedOutputBufferAddress"); ddl_hw_fatal_cb(p_ddl->p_ddl_context); return vcd_status; } p_output_vcd_frm->n_ip_frm_tag = p_dec_disp_info->n_tag_top; if (p_dec_disp_info->n_crop_exists == 0x1) { p_output_vcd_frm->dec_op_prop.disp_frm.n_left = p_dec_disp_info->n_crop_left_offset; p_output_vcd_frm->dec_op_prop.disp_frm.n_top = p_dec_disp_info->n_crop_top_offset; p_output_vcd_frm->dec_op_prop.disp_frm.n_right = p_dec_disp_info->n_img_size_x - p_dec_disp_info->n_crop_right_offset; p_output_vcd_frm->dec_op_prop.disp_frm.n_bottom = p_dec_disp_info->n_img_size_y - p_dec_disp_info->n_crop_bottom_offset; } else { p_output_vcd_frm->dec_op_prop.disp_frm.n_left = 0; p_output_vcd_frm->dec_op_prop.disp_frm.n_top = 0; p_output_vcd_frm->dec_op_prop.disp_frm.n_right = p_dec_disp_info->n_img_size_x; p_output_vcd_frm->dec_op_prop.disp_frm.n_bottom = p_dec_disp_info->n_img_size_y; } if (!p_dec_disp_info->n_disp_is_interlace) { p_output_vcd_frm->b_interlaced = FALSE; p_output_vcd_frm->n_intrlcd_ip_frm_tag = VCD_FRAMETAG_INVALID; } else { p_output_vcd_frm->b_interlaced = TRUE; p_output_vcd_frm->n_intrlcd_ip_frm_tag = p_dec_disp_info->n_tag_bottom; } p_output_vcd_frm->n_offset = 0; p_output_vcd_frm->n_data_len = p_decoder->n_y_cb_cr_size; if (n_free_luma_dpb) { p_output_vcd_frm->n_data_len = 0; p_output_vcd_frm->n_flags |= VCD_FRAME_FLAG_DECODEONLY; } p_output_vcd_frm->n_flags |= VCD_FRAME_FLAG_ENDOFFRAME; ddl_process_decoder_metadata(p_ddl); p_output_frame->b_frm_trans_end = b_frame_transact_end; #ifdef CORE_TIMING_INFO ddl_calc_core_time(0); #endif p_ddl->p_ddl_context->ddl_callback( VCD_EVT_RESP_OUTPUT_DONE, vcd_status, p_output_frame, sizeof(struct ddl_frame_data_type_tag), (void *)p_ddl, p_ddl->p_ddl_context->p_client_data); return vcd_status; }
u32 ddl_encode_frame(u32 *ddl_handle, struct ddl_frame_data_tag *input_frame, struct ddl_frame_data_tag *output_bit, void *client_data) { struct ddl_client_context *ddl = (struct ddl_client_context *)ddl_handle; struct ddl_context *ddl_context = ddl_get_context(); if (vidc_msg_timing) ddl_set_core_start_time(__func__, ENC_OP_TIME); if (!DDL_IS_INITIALIZED(ddl_context)) { VIDC_LOGERR_STRING("ddl_enc_frame:Not_inited"); return VCD_ERR_ILLEGAL_OP; } if (DDL_IS_BUSY(ddl_context)) { VIDC_LOGERR_STRING("ddl_enc_frame:Ddl_busy"); return VCD_ERR_BUSY; } if (!ddl || ddl->decoding) { VIDC_LOGERR_STRING("ddl_enc_frame:Bad_handle"); return VCD_ERR_BAD_HANDLE; } if (!input_frame || !input_frame->vcd_frm.physical || ddl->codec_data.encoder.input_buf_req.sz != input_frame->vcd_frm.data_len) { VIDC_LOGERR_STRING("ddl_enc_frame:Bad_input_params"); return VCD_ERR_ILLEGAL_PARM; } if ((((u32) input_frame->vcd_frm.physical + input_frame->vcd_frm.offset) & (DDL_STREAMBUF_ALIGN_GUARD_BYTES) ) ) { VIDC_LOGERR_STRING ("ddl_enc_frame:Un_aligned_yuv_start_address"); return VCD_ERR_ILLEGAL_PARM; } if (!output_bit || !output_bit->vcd_frm.physical || !output_bit->vcd_frm.alloc_len) { VIDC_LOGERR_STRING("ddl_enc_frame:Bad_output_params"); return VCD_ERR_ILLEGAL_PARM; } if ((ddl->codec_data.encoder.output_buf_req.sz + output_bit->vcd_frm.offset) > output_bit->vcd_frm.alloc_len) { VIDC_LOGERR_STRING ("ddl_enc_frame:offset_large, Exceeds_min_buf_size"); } if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) { VIDC_LOGERR_STRING("ddl_enc_frame:Wrong_state"); return VCD_ERR_ILLEGAL_OP; } DDL_BUSY(ddl_context); ddl_context->current_ddl = ddl; ddl_context->client_data = client_data; ddl->input_frame = *input_frame; ddl->output_frame = *output_bit; ddl_encode_frame_run(ddl); return VCD_S_SUCCESS; }
u32 ddl_decode_frame(u32 *ddl_handle, struct ddl_frame_data_tag *input_bits, void *client_data) { u32 vcd_status = VCD_S_SUCCESS; struct ddl_client_context *ddl = (struct ddl_client_context *)ddl_handle; struct ddl_context *ddl_context = ddl_get_context(); if (!DDL_IS_INITIALIZED(ddl_context)) { VIDC_LOGERR_STRING("ddl_dec_frame:Not_inited"); return VCD_ERR_ILLEGAL_OP; } if (DDL_IS_BUSY(ddl_context)) { VIDC_LOGERR_STRING("ddl_dec_frame:Ddl_busy"); return VCD_ERR_BUSY; } if (!ddl || !ddl->decoding) { VIDC_LOGERR_STRING("ddl_dec_frame:Bad_handle"); return VCD_ERR_BAD_HANDLE; } if (!input_bits || ((!input_bits->vcd_frm.physical || !input_bits->vcd_frm.data_len) && (!(VCD_FRAME_FLAG_EOS & input_bits->vcd_frm.flags)) ) ) { VIDC_LOGERR_STRING("ddl_dec_frame:Bad_input_param"); return VCD_ERR_ILLEGAL_PARM; } DDL_BUSY(ddl_context); ddl_context->current_ddl = ddl; ddl_context->client_data = client_data; ddl->input_frame = *input_bits; if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) { ddl_decode_frame_run(ddl); } else { if (!ddl->codec_data.decoder.dp_buf.no_of_dec_pic_buf) { VIDC_LOGERR_STRING("ddl_dec_frame:Dpbs_requied"); vcd_status = VCD_ERR_ILLEGAL_OP; } else if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) { vcd_status = ddl_decode_set_buffers(ddl); } else if (DDLCLIENT_STATE_IS (ddl, DDL_CLIENT_WAIT_FOR_INITCODEC)) { 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); } else { VIDC_LOGERR_STRING("Dec_frame:Wrong_state"); vcd_status = VCD_ERR_ILLEGAL_OP; } if (vcd_status) DDL_IDLE(ddl_context); } return vcd_status; }
u32 ddl_decode_start(u32 *ddl_handle, struct vcd_sequence_hdr *header, void *client_data) { struct ddl_client_context *ddl = (struct ddl_client_context *)ddl_handle; struct ddl_context *ddl_context; struct ddl_decoder_data *decoder; ddl_context = ddl_get_context(); if (!DDL_IS_INITIALIZED(ddl_context)) { VIDC_LOGERR_STRING("ddl_dec_start:Not_inited"); return VCD_ERR_ILLEGAL_OP; } if (DDL_IS_BUSY(ddl_context)) { VIDC_LOGERR_STRING("ddl_dec_start:Ddl_busy"); return VCD_ERR_BUSY; } if (!ddl || !ddl->decoding) { VIDC_LOGERR_STRING("ddl_dec_start:Bad_handle"); return VCD_ERR_BAD_HANDLE; } if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { VIDC_LOGERR_STRING("ddl_dec_start:Not_in_opened_state"); return VCD_ERR_ILLEGAL_OP; } if ((header) && ((!header->sequence_header_len) || (!header->sequence_header) ) ) { VIDC_LOGERR_STRING("ddl_dec_start:Bad_param_seq_header"); return VCD_ERR_ILLEGAL_PARM; } if (!ddl_decoder_ready_to_start(ddl, header)) { VIDC_LOGERR_STRING("ddl_dec_start:Err_param_settings"); return VCD_ERR_ILLEGAL_OP; } DDL_BUSY(ddl_context); decoder = &ddl->codec_data.decoder; if (header) { decoder->header_in_start = true; decoder->decode_config = *header; } else { decoder->header_in_start = false; decoder->decode_config.sequence_header_len = 0; } if (decoder->codec.codec == VCD_CODEC_H264) { ddl_pmem_alloc(&decoder->h264Vsp_temp_buffer, DDL_DECODE_H264_VSPTEMP_BUFSIZE, DDL_LINEAR_BUFFER_ALIGN_BYTES); if (!decoder->h264Vsp_temp_buffer.virtual_base_addr) { DDL_IDLE(ddl_context); VIDC_LOGERR_STRING ("ddl_dec_start:H264Sps_alloc_failed"); return VCD_ERR_ALLOC_FAIL; } } ddl_context->current_ddl = ddl; ddl_context->client_data = client_data; ddl_channel_set(ddl); return VCD_S_SUCCESS; }
u32 ddl_decode_frame(u32 *ddl_handle, struct ddl_frame_data_type_tag *p_input_bits, void *p_client_data) { u32 vcd_status = VCD_S_SUCCESS; struct ddl_client_context_type *p_ddl = (struct ddl_client_context_type *)ddl_handle; struct ddl_context_type *p_ddl_context = ddl_get_context(); #ifdef CORE_TIMING_INFO ddl_get_core_start_time(0); #endif if (!DDL_IS_INITIALIZED(p_ddl_context)) { VIDC_LOGERR_STRING("ddl_dec_frame:Not_inited"); return VCD_ERR_ILLEGAL_OP; } if (DDL_IS_BUSY(p_ddl_context)) { VIDC_LOGERR_STRING("ddl_dec_frame:Ddl_busy"); return VCD_ERR_BUSY; } if (NULL == p_ddl || FALSE == p_ddl->b_decoding) { VIDC_LOGERR_STRING("ddl_dec_frame:Bad_handle"); return VCD_ERR_BAD_HANDLE; } if (NULL == p_input_bits || ((0 == p_input_bits->vcd_frm.p_physical || 0 == p_input_bits->vcd_frm.n_data_len) && (0 == (VCD_FRAME_FLAG_EOS & p_input_bits->vcd_frm.n_flags)) ) ) { VIDC_LOGERR_STRING("ddl_dec_frame:Bad_input_param"); return VCD_ERR_ILLEGAL_PARM; } DDL_BUSY(p_ddl_context); p_ddl_context->p_current_ddl = p_ddl; p_ddl_context->p_client_data = p_client_data; p_ddl->input_frame = *p_input_bits; if (DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_WAIT_FOR_FRAME)) { ddl_decode_frame_run(p_ddl); } else { if (0 == p_ddl->codec_data.decoder.dp_buf.n_no_of_dec_pic_buf) { VIDC_LOGERR_STRING("ddl_dec_frame:Dpbs_requied"); vcd_status = VCD_ERR_ILLEGAL_OP; } else if (DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_WAIT_FOR_DPB)) { vcd_status = ddl_decode_set_buffers(p_ddl); } else if (DDLCLIENT_STATE_IS (p_ddl, DDL_CLIENT_WAIT_FOR_INITCODEC)) { p_ddl->codec_data.decoder.decode_config. p_sequence_header = p_ddl->input_frame.vcd_frm.p_physical; p_ddl->codec_data.decoder.decode_config. n_sequence_header_len = p_ddl->input_frame.vcd_frm.n_data_len; ddl_decode_init_codec(p_ddl); } else { VIDC_LOGERR_STRING("Dec_frame:Wrong_state"); vcd_status = VCD_ERR_ILLEGAL_OP; } if (VCD_S_SUCCESS != vcd_status) DDL_IDLE(p_ddl_context); } return vcd_status; }
u32 ddl_encode_start(u32 *ddl_handle, void *p_client_data) { struct ddl_client_context_type *p_ddl = (struct ddl_client_context_type *)ddl_handle; struct ddl_context_type *p_ddl_context; struct ddl_encoder_data_type *p_encoder; u32 n_dpb_size; p_ddl_context = ddl_get_context(); if (!DDL_IS_INITIALIZED(p_ddl_context)) { VIDC_LOGERR_STRING("ddl_enc_start:Not_inited"); return VCD_ERR_ILLEGAL_OP; } if (DDL_IS_BUSY(p_ddl_context)) { VIDC_LOGERR_STRING("ddl_enc_start:Ddl_busy"); return VCD_ERR_BUSY; } if (NULL == p_ddl || TRUE == p_ddl->b_decoding) { VIDC_LOGERR_STRING("ddl_enc_start:Bad_handle"); return VCD_ERR_BAD_HANDLE; } if (!DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_OPEN)) { VIDC_LOGERR_STRING("ddl_enc_start:Not_opened"); return VCD_ERR_ILLEGAL_OP; } if (FALSE == ddl_encoder_ready_to_start(p_ddl)) { VIDC_LOGERR_STRING("ddl_enc_start:Err_param_settings"); return VCD_ERR_ILLEGAL_OP; } p_encoder = &p_ddl->codec_data.encoder; n_dpb_size = ddl_get_yuv_buffer_size(&p_encoder->frame_size, &p_encoder->re_con_buf_format, FALSE); n_dpb_size *= DDL_ENC_NUM_DPB_BUFFERS; ddl_pmem_alloc(&p_encoder->enc_dpb_addr, n_dpb_size, DDL_TILE_BUFFER_ALIGN_BYTES); if (NULL == p_encoder->enc_dpb_addr.p_virtual_base_addr) { VIDC_LOGERR_STRING("ddl_enc_start:Dpb_alloc_failed"); return VCD_ERR_ALLOC_FAIL; } if ((VCD_CODEC_MPEG4 == p_encoder->codec_type.e_codec && FALSE == p_encoder->short_header.b_short_header) || VCD_CODEC_H264 == p_encoder->codec_type.e_codec) { ddl_pmem_alloc(&p_encoder->seq_header, DDL_ENC_SEQHEADER_SIZE, DDL_LINEAR_BUFFER_ALIGN_BYTES); if (NULL == p_encoder->seq_header.p_virtual_base_addr) { ddl_pmem_free(p_encoder->enc_dpb_addr); VIDC_LOGERR_STRING ("ddl_enc_start:Seq_hdr_alloc_failed"); return VCD_ERR_ALLOC_FAIL; } } else { p_encoder->seq_header.n_buffer_size = 0; p_encoder->seq_header.p_virtual_base_addr = 0; } DDL_BUSY(p_ddl_context); p_ddl_context->p_current_ddl = p_ddl; p_ddl_context->p_client_data = p_client_data; ddl_channel_set(p_ddl); return VCD_S_SUCCESS; }
u32 ddl_encode_start(u32 *ddl_handle, void *client_data) { struct ddl_client_context *ddl = (struct ddl_client_context *)ddl_handle; struct ddl_context *ddl_context; struct ddl_encoder_data *encoder; u32 dpb_size; ddl_context = ddl_get_context(); if (!DDL_IS_INITIALIZED(ddl_context)) { VIDC_LOGERR_STRING("ddl_enc_start:Not_inited"); return VCD_ERR_ILLEGAL_OP; } if (DDL_IS_BUSY(ddl_context)) { VIDC_LOGERR_STRING("ddl_enc_start:Ddl_busy"); return VCD_ERR_BUSY; } if (!ddl || ddl->decoding) { VIDC_LOGERR_STRING("ddl_enc_start:Bad_handle"); return VCD_ERR_BAD_HANDLE; } if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { VIDC_LOGERR_STRING("ddl_enc_start:Not_opened"); return VCD_ERR_ILLEGAL_OP; } if (!ddl_encoder_ready_to_start(ddl)) { VIDC_LOGERR_STRING("ddl_enc_start:Err_param_settings"); return VCD_ERR_ILLEGAL_OP; } encoder = &ddl->codec_data.encoder; dpb_size = ddl_get_yuv_buffer_size(&encoder->frame_size, &encoder->re_con_buf_format, false, encoder->codec.codec); dpb_size *= DDL_ENC_NUM_DPB_BUFFERS; ddl_pmem_alloc(&encoder->enc_dpb_addr, dpb_size, DDL_TILE_BUFFER_ALIGN_BYTES); if (!encoder->enc_dpb_addr.virtual_base_addr) { VIDC_LOGERR_STRING("ddl_enc_start:Dpb_alloc_failed"); return VCD_ERR_ALLOC_FAIL; } if ((encoder->codec.codec == VCD_CODEC_MPEG4 && !encoder->short_header.short_header) || encoder->codec.codec == VCD_CODEC_H264) { ddl_pmem_alloc(&encoder->seq_header, DDL_ENC_SEQHEADER_SIZE, DDL_LINEAR_BUFFER_ALIGN_BYTES); if (!encoder->seq_header.virtual_base_addr) { ddl_pmem_free(&encoder->enc_dpb_addr); VIDC_LOGERR_STRING ("ddl_enc_start:Seq_hdr_alloc_failed"); return VCD_ERR_ALLOC_FAIL; } } else { encoder->seq_header.buffer_size = 0; encoder->seq_header.virtual_base_addr = 0; } DDL_BUSY(ddl_context); ddl_context->current_ddl = ddl; ddl_context->client_data = client_data; ddl_channel_set(ddl); return VCD_S_SUCCESS; }
static u32 ddl_decoder_output_done_callback( struct ddl_client_context *ddl, u32 frame_transact_end) { struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); struct vidc_720p_dec_disp_info *dec_disp_info = &(decoder->dec_disp_info); struct ddl_frame_data_tag *output_frame = &ddl->output_frame; struct vcd_frame_data *output_vcd_frm = &(output_frame->vcd_frm); u32 vcd_status; u32 free_luma_dpb = 0; output_vcd_frm->physical = (u8 *)dec_disp_info->y_addr; if (decoder->codec.codec == VCD_CODEC_MPEG4 || decoder->codec.codec == VCD_CODEC_VC1 || decoder->codec.codec == VCD_CODEC_VC1_RCV || (decoder->codec.codec >= VCD_CODEC_DIVX_3 && decoder->codec.codec <= VCD_CODEC_XVID)){ vidc_720p_decode_skip_frm_details(&free_luma_dpb); if (free_luma_dpb) output_vcd_frm->physical = (u8 *) free_luma_dpb; } vcd_status = ddl_decoder_dpb_transact( decoder, output_frame, DDL_DPB_OP_MARK_BUSY); if (vcd_status != VCD_S_SUCCESS) { VIDC_LOGERR_STRING("CorruptedOutputBufferAddress"); ddl_hw_fatal_cb(ddl->ddl_context); return vcd_status; } output_vcd_frm->ip_frm_tag = dec_disp_info->tag_top; if (dec_disp_info->crop_exists == 0x1) { output_vcd_frm->dec_op_prop.disp_frm.left = dec_disp_info->crop_left_offset; output_vcd_frm->dec_op_prop.disp_frm.top = dec_disp_info->crop_top_offset; output_vcd_frm->dec_op_prop.disp_frm.right = dec_disp_info->img_size_x - dec_disp_info->crop_right_offset; output_vcd_frm->dec_op_prop.disp_frm.bottom = dec_disp_info->img_size_y - dec_disp_info->crop_bottom_offset; } else { output_vcd_frm->dec_op_prop.disp_frm.left = 0; output_vcd_frm->dec_op_prop.disp_frm.top = 0; output_vcd_frm->dec_op_prop.disp_frm.right = dec_disp_info->img_size_x; output_vcd_frm->dec_op_prop.disp_frm.bottom = dec_disp_info->img_size_y; } if (!dec_disp_info->disp_is_interlace) { output_vcd_frm->interlaced = false; output_vcd_frm->intrlcd_ip_frm_tag = VCD_FRAMETAG_INVALID; } else { output_vcd_frm->interlaced = true; output_vcd_frm->intrlcd_ip_frm_tag = dec_disp_info->tag_bottom; } output_vcd_frm->offset = 0; output_vcd_frm->data_len = decoder->y_cb_cr_size; if (free_luma_dpb) { output_vcd_frm->data_len = 0; output_vcd_frm->flags |= VCD_FRAME_FLAG_DECODEONLY; } output_vcd_frm->flags |= VCD_FRAME_FLAG_ENDOFFRAME; ddl_process_decoder_metadata(ddl); output_frame->frm_trans_end = frame_transact_end; if (vidc_msg_timing) ddl_calc_core_proc_time(__func__, DEC_OP_TIME); ddl->ddl_context->ddl_callback( VCD_EVT_RESP_OUTPUT_DONE, vcd_status, output_frame, sizeof(struct ddl_frame_data_tag), (void *)ddl, ddl->ddl_context->client_data); return vcd_status; }
u32 ddl_decode_start(u32 *ddl_handle, struct vcd_sequence_hdr_type *p_header, void *p_client_data) { struct ddl_client_context_type *p_ddl = (struct ddl_client_context_type *)ddl_handle; struct ddl_context_type *p_ddl_context; struct ddl_decoder_data_type *p_decoder; p_ddl_context = ddl_get_context(); if (!DDL_IS_INITIALIZED(p_ddl_context)) { VIDC_LOGERR_STRING("ddl_dec_start:Not_inited"); return VCD_ERR_ILLEGAL_OP; } if (DDL_IS_BUSY(p_ddl_context)) { VIDC_LOGERR_STRING("ddl_dec_start:Ddl_busy"); return VCD_ERR_BUSY; } if (NULL == p_ddl || FALSE == p_ddl->b_decoding) { VIDC_LOGERR_STRING("ddl_dec_start:Bad_handle"); return VCD_ERR_BAD_HANDLE; } if (!DDLCLIENT_STATE_IS(p_ddl, DDL_CLIENT_OPEN)) { VIDC_LOGERR_STRING("ddl_dec_start:Not_in_opened_state"); return VCD_ERR_ILLEGAL_OP; } if ((NULL != p_header) && ((0 == p_header->n_sequence_header_len) || (NULL == p_header->p_sequence_header) ) ) { VIDC_LOGERR_STRING("ddl_dec_start:Bad_param_seq_header"); return VCD_ERR_ILLEGAL_PARM; } if (FALSE == ddl_decoder_ready_to_start(p_ddl, p_header)) { VIDC_LOGERR_STRING("ddl_dec_start:Err_param_settings"); return VCD_ERR_ILLEGAL_OP; } DDL_BUSY(p_ddl_context); p_decoder = &p_ddl->codec_data.decoder; if (p_header) { p_decoder->b_header_in_start = TRUE; p_decoder->decode_config = *p_header; } else { p_decoder->b_header_in_start = FALSE; p_decoder->decode_config.n_sequence_header_len = 0; } if (p_decoder->codec_type.e_codec == VCD_CODEC_H264) { ddl_pmem_alloc(&p_decoder->h264Vsp_temp_buffer, DDL_DECODE_H264_VSPTEMP_BUFSIZE, DDL_LINEAR_BUFFER_ALIGN_BYTES); if (p_decoder->h264Vsp_temp_buffer.p_virtual_base_addr == NULL) { DDL_IDLE(p_ddl_context); VIDC_LOGERR_STRING ("ddl_dec_start:H264Sps_alloc_failed"); return VCD_ERR_ALLOC_FAIL; } } p_ddl_context->p_current_ddl = p_ddl; p_ddl_context->p_client_data = p_client_data; ddl_channel_set(p_ddl); return VCD_S_SUCCESS; }