static void parse_hdr_crop_data(struct ddl_client_context *ddl, struct vidc_1080p_seq_hdr_info *seq_hdr_info) { struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; u32 crop_exists = (decoder->output_order == VCD_DEC_ORDER_DISPLAY) ? seq_hdr_info->disp_crop_exists : seq_hdr_info->dec_crop_exists; if (crop_exists) { if (decoder->output_order == VCD_DEC_ORDER_DISPLAY) 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); else vidc_sm_get_dec_order_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); 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; } }
static void get_dec_op_done_crop(u32 output_order, struct vidc_1080p_dec_disp_info *dec_disp_info, struct vcd_frame_rect *crop_data, struct vcd_property_frame_size *op_frame_sz, struct vcd_property_frame_size *frame_sz, struct ddl_buf_addr *shared_mem) { u32 crop_exists = (output_order == VCD_DEC_ORDER_DECODE) ? dec_disp_info->dec_crop_exists : dec_disp_info->disp_crop_exists; crop_data->left = 0; crop_data->top = 0; crop_data->right = dec_disp_info->img_size_x; crop_data->bottom = dec_disp_info->img_size_y; op_frame_sz->width = dec_disp_info->img_size_x; op_frame_sz->height = dec_disp_info->img_size_y; ddl_calculate_stride(op_frame_sz, false); op_frame_sz->stride = DDL_ALIGN(op_frame_sz->width, DDL_TILE_ALIGN_WIDTH); op_frame_sz->scan_lines = DDL_ALIGN(op_frame_sz->height, DDL_TILE_ALIGN_HEIGHT); DDL_MSG_LOW("%s img_size_x = %u img_size_y = %u\n", __func__, dec_disp_info->img_size_x, dec_disp_info->img_size_y); if (crop_exists) { if (output_order == VCD_DEC_ORDER_DECODE) vidc_sm_get_dec_order_crop_info(shared_mem, &dec_disp_info->crop_left_offset, &dec_disp_info->crop_right_offset, &dec_disp_info->crop_top_offset, &dec_disp_info->crop_bottom_offset); else vidc_sm_get_crop_info(shared_mem, &dec_disp_info->crop_left_offset, &dec_disp_info->crop_right_offset, &dec_disp_info->crop_top_offset, &dec_disp_info->crop_bottom_offset); crop_data->left = dec_disp_info->crop_left_offset; crop_data->top = dec_disp_info->crop_top_offset; crop_data->right -= dec_disp_info->crop_right_offset; crop_data->bottom -= dec_disp_info->crop_bottom_offset; op_frame_sz->width = crop_data->right - crop_data->left; op_frame_sz->height = crop_data->bottom - crop_data->top; } }
static void get_dec_op_done_crop(u32 output_order, struct vidc_1080p_dec_disp_info *dec_disp_info, struct vcd_frame_rect *crop_data, struct vcd_property_frame_size *frame_sz, struct ddl_buf_addr *shared_mem) { u32 crop_exists = (output_order == VCD_DEC_ORDER_DECODE) ? dec_disp_info->dec_crop_exists : dec_disp_info->disp_crop_exists; if (crop_exists) { if (output_order == VCD_DEC_ORDER_DECODE) vidc_sm_get_dec_order_crop_info(shared_mem, &dec_disp_info->crop_left_offset, &dec_disp_info->crop_right_offset, &dec_disp_info->crop_top_offset, &dec_disp_info->crop_bottom_offset); else vidc_sm_get_crop_info(shared_mem, &dec_disp_info->crop_left_offset, &dec_disp_info->crop_right_offset, &dec_disp_info->crop_top_offset, &dec_disp_info->crop_bottom_offset); crop_data->left = dec_disp_info->crop_left_offset; crop_data->top = dec_disp_info->crop_top_offset; crop_data->right = frame_sz->width - dec_disp_info->crop_right_offset; crop_data->bottom = frame_sz->height - dec_disp_info->crop_bottom_offset; } else { crop_data->left = 0; crop_data->top = 0; crop_data->right = frame_sz->width; crop_data->bottom = frame_sz->height; } }
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_decoder_ouput_done_callback( struct ddl_client_context *ddl, u32 frame_transact_end) { struct ddl_context *ddl_context = ddl->ddl_context; struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); struct vidc_1080p_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, free_luma_dpb = 0, disp_pict = 0; output_vcd_frm->physical = (u8 *) (dec_disp_info->display_y_addr << 11); output_vcd_frm->frame = VCD_FRAME_YUV; 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_sm_get_displayed_picture_frame(&ddl->shared_mem [ddl->command_channel], &disp_pict); if (!disp_pict) output_vcd_frm->frame = VCD_FRAME_NOTCODED; if (output_vcd_frm->frame == VCD_FRAME_NOTCODED) { vidc_sm_get_available_luma_dpb_address( &ddl->shared_mem[ddl->command_channel], &free_luma_dpb); if (free_luma_dpb) output_vcd_frm->physical = (u8 *)(free_luma_dpb << 11); } } vcd_status = ddl_decoder_dpb_transact(decoder, output_frame, DDL_DPB_OP_MARK_BUSY); if (vcd_status) { DDL_MSG_ERROR("CORRUPTED_OUTPUT_BUFFER_ADDRESS"); ddl_hw_fatal_cb(ddl); } else { vidc_sm_get_frame_tags(&ddl->shared_mem [ddl->command_channel], &dec_disp_info->tag_top, &dec_disp_info->tag_bottom); output_vcd_frm->ip_frm_tag = dec_disp_info->tag_top; vidc_sm_get_picture_times(&ddl->shared_mem [ddl->command_channel], &dec_disp_info->pic_time_top, &dec_disp_info->pic_time_bottom); if (dec_disp_info->crop_exists) { vidc_sm_get_crop_info(&ddl->shared_mem [ddl_context->response_cmd_ch_id], &dec_disp_info->crop_left_offset, &dec_disp_info->crop_right_offset, &dec_disp_info->crop_top_offset, &dec_disp_info->crop_bottom_offset); 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 = decoder->frame_size.width - dec_disp_info->crop_right_offset; output_vcd_frm->dec_op_prop.disp_frm.bottom = decoder->frame_size.height - 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 = decoder->frame_size.width; output_vcd_frm->dec_op_prop.disp_frm.bottom = decoder->frame_size.height; } if (dec_disp_info->display_coding == VIDC_1080P_DISPLAY_CODING_PROGRESSIVE_SCAN) { output_vcd_frm->interlaced = false; output_vcd_frm->intrlcd_ip_frm_tag = VCD_FRAMETAG_INVALID; } else { output_vcd_frm->interlaced = true; if (!dec_disp_info->tag_bottom) output_vcd_frm->intrlcd_ip_frm_tag = VCD_FRAMETAG_INVALID; else 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; output_frame->frm_trans_end = frame_transact_end; #ifdef DDL_PROFILE ddl_calc_core_time(0); #endif ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, vcd_status, output_frame, sizeof(struct ddl_frame_data_tag), (u32 *)ddl, ddl->client_data); } return vcd_status; }