Ejemplo n.º 1
0
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_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, is_interlaced;
	get_dec_op_done_data(dec_disp_info, decoder->output_order,
		&output_vcd_frm->physical, &is_interlaced);
	decoder->progressive_only = !(is_interlaced);
	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 (decoder->output_order == VCD_DEC_ORDER_DISPLAY) {
			if (!disp_pict) {
			output_vcd_frm->frame = VCD_FRAME_NOTCODED;
			vidc_sm_get_available_luma_dpb_address(
				&ddl->shared_mem[ddl->command_channel],
				&free_luma_dpb);
			}
		} else {
			if (dec_disp_info->input_frame ==
				VIDC_1080P_DECODE_FRAMETYPE_NOT_CODED) {
				output_vcd_frm->frame = VCD_FRAME_NOTCODED;
			vidc_sm_get_available_luma_dpb_dec_order_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_metadata_status(&ddl->shared_mem
			[ddl->command_channel],
			&decoder->meta_data_exists);
		if (decoder->output_order == VCD_DEC_ORDER_DISPLAY)
			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);
		get_dec_op_done_crop(decoder->output_order, dec_disp_info,
			&output_vcd_frm->dec_op_prop.disp_frm,
			&output_vcd_frm->dec_op_prop.frm_size,
			&decoder->frame_size,
			&ddl->shared_mem[ddl_context->response_cmd_ch_id]);
		if ((decoder->cont_mode) &&
			((output_vcd_frm->dec_op_prop.frm_size.width !=
			decoder->frame_size.width) ||
			(output_vcd_frm->dec_op_prop.frm_size.height !=
			decoder->frame_size.height) ||
			(decoder->frame_size.width !=
			decoder->client_frame_size.width) ||
			(decoder->frame_size.height !=
			decoder->client_frame_size.height))) {
			DDL_MSG_LOW("%s o/p width = %u o/p height = %u"
				"decoder width = %u decoder height = %u ",
				__func__,
				output_vcd_frm->dec_op_prop.frm_size.width,
				output_vcd_frm->dec_op_prop.frm_size.height,
				decoder->frame_size.width,
				decoder->frame_size.height);
			DDL_MSG_HIGH("%s Sending INFO_OP_RECONFIG event\n",
				 __func__);
			ddl_context->ddl_callback(
				VCD_EVT_IND_INFO_OUTPUT_RECONFIG,
				VCD_S_SUCCESS, NULL, 0,
				(u32 *)ddl,
				ddl->client_data);
			decoder->frame_size =
				 output_vcd_frm->dec_op_prop.frm_size;
			decoder->client_frame_size = decoder->frame_size;
			decoder->y_cb_cr_size =
				ddl_get_yuv_buffer_size(&decoder->frame_size,
					&decoder->buf_format,
					(!decoder->progressive_only),
					decoder->codec.codec, NULL);
			decoder->actual_output_buf_req.sz =
				decoder->y_cb_cr_size + decoder->suffix;
			decoder->min_output_buf_req =
				decoder->actual_output_buf_req;
			DDL_MSG_LOW("%s y_cb_cr_size = %u "
				"actual_output_buf_req.sz = %u"
				"min_output_buf_req.sz = %u\n",
				decoder->y_cb_cr_size,
				decoder->actual_output_buf_req.sz,
				decoder->min_output_buf_req.sz);
			vidc_sm_set_chroma_addr_change(
			&ddl->shared_mem[ddl->command_channel],
			false);
		}
		output_vcd_frm->interlaced = is_interlaced;
		output_vcd_frm->intrlcd_ip_frm_tag =
			(!is_interlaced || !dec_disp_info->tag_bottom) ?
			VCD_FRAMETAG_INVALID : 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;
		if (vidc_msg_timing)
			ddl_calc_core_proc_time(__func__, DEC_OP_TIME);
		ddl_process_decoder_metadata(ddl);
		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;
}
Ejemplo n.º 3
0
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;
}