blob: 6e4037b2196774de3352204f36cf7120328a048a [file] [log] [blame]
/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*
*/
#include "video_core_type.h"
#include "vcd_ddl_utils.h"
#include "vcd_ddl_metadata.h"
static u32 ddl_set_dec_property(struct ddl_client_context *pddl,
struct vcd_property_hdr *hdr, void *value);
static u32 ddl_set_enc_property(struct ddl_client_context *pddl,
struct vcd_property_hdr *hdr, void *value);
static u32 ddl_get_dec_property(struct ddl_client_context *pddl,
struct vcd_property_hdr *hdr, void *value);
static u32 ddl_get_enc_property(struct ddl_client_context *pddl,
struct vcd_property_hdr *hdr, void *value);
static u32 ddl_set_enc_dynamic_property(struct ddl_encoder_data *enc,
struct vcd_property_hdr *hdr, void *value);
static void ddl_set_default_enc_property(struct ddl_client_context *ddl);
static void ddl_set_default_enc_profile(struct ddl_encoder_data *enc);
static void ddl_set_default_enc_level(struct ddl_encoder_data *enc);
static void ddl_set_default_enc_vop_timing(struct ddl_encoder_data *enc);
static void ddl_set_default_enc_intra_period(struct ddl_encoder_data *enc);
static void ddl_set_default_enc_rc_params(struct ddl_encoder_data *enc);
static u32 ddl_valid_buffer_requirement(struct vcd_buffer_requirement
*orig, struct vcd_buffer_requirement *req);
static u32 ddl_decoder_min_num_dpb(struct ddl_decoder_data *dec);
static u32 ddl_set_dec_buffers(struct ddl_decoder_data *dec,
struct ddl_property_dec_pic_buffers *dpb);
u32 ddl_set_property(u32 *ddl_handle, struct vcd_property_hdr *hdr,
void *value)
{
u32 vcd_status;
struct ddl_context *ddl_context;
struct ddl_client_context *ddl = (struct ddl_client_context *)
ddl_handle;
if (!hdr || !value) {
pr_err("ddl_set_prop:Bad_argument\n");
return VCD_ERR_ILLEGAL_PARM;
}
ddl_context = ddl_get_context();
if (!DDL_IS_INITIALIZED(ddl_context)) {
pr_err("ddl_set_prop:Not_inited\n");
return VCD_ERR_ILLEGAL_OP;
}
if (!ddl) {
pr_err("ddl_set_prop:Bad_handle\n");
return VCD_ERR_BAD_HANDLE;
}
if (ddl->decoding)
vcd_status = ddl_set_dec_property(ddl, hdr, value);
else
vcd_status = ddl_set_enc_property(ddl, hdr, value);
if (vcd_status)
pr_err("ddl_set_prop:FAILED\n");
return vcd_status;
}
u32 ddl_get_property(u32 *ddl_handle, struct vcd_property_hdr *hdr, void *value)
{
u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
struct ddl_context *ddl_context;
struct ddl_client_context *ddl = (struct ddl_client_context *)
ddl_handle;
if (!hdr || !value)
return VCD_ERR_ILLEGAL_PARM;
if (hdr->id == DDL_I_CAPABILITY) {
struct ddl_property_capability *cap;
if (sizeof(*cap) == hdr->sz) {
cap = value;
cap->max_num_client = VCD_MAX_NO_CLIENT;
cap->exclusive = VCD_COMMAND_EXCLUSIVE;
cap->frame_command_depth = VCD_FRAME_COMMAND_DEPTH;
cap->general_command_depth = VCD_GENERAL_COMMAND_DEPTH;
cap->ddl_time_out_in_ms = DDL_HW_TIMEOUT_IN_MS;
vcd_status = VCD_S_SUCCESS;
}
return vcd_status;
}
ddl_context = ddl_get_context();
if (!DDL_IS_INITIALIZED(ddl_context))
return VCD_ERR_ILLEGAL_OP;
if (!ddl)
return VCD_ERR_BAD_HANDLE;
if (ddl->decoding)
vcd_status = ddl_get_dec_property(ddl, hdr, value);
else
vcd_status = ddl_get_enc_property(ddl, hdr, value);
if (vcd_status)
pr_err("ddl_get_prop:FAILED\n");
return vcd_status;
}
u32 ddl_decoder_ready_to_start(struct ddl_client_context *ddl,
struct vcd_phys_sequence_hdr *seq_hdr)
{
struct ddl_decoder_data *dec = &ddl->codec_data.decoder;
if (!dec->codec_type.codec) {
pr_err("ddl_dec_start_check:Codec_not_set\n");
return false;
}
if (!seq_hdr && (!dec->client_frame_size.height ||
!dec->client_frame_size.width)) {
pr_err("ddl_dec_start_check:"
"Client_height_width_default\n");
return false;
}
return true;
}
u32 ddl_encoder_ready_to_start(struct ddl_client_context *ddl)
{
struct ddl_encoder_data *enc = &ddl->codec_data.encoder;
if (!enc->codec_type.codec || !enc->frame_size.height ||
!enc->frame_size.width ||
!enc->frame_rate.fps_denominator ||
!enc->frame_rate.fps_numerator ||
!enc->target_bit_rate.target_bitrate) {
return false;
}
return true;
}
static u32 ddl_set_dec_property(struct ddl_client_context *ddl,
struct vcd_property_hdr *hdr, void *value) {
u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
struct ddl_decoder_data *dec = &ddl->codec_data.decoder;
switch (hdr->id) {
case DDL_I_DPB_RELEASE:
if (sizeof(struct ddl_frame_data_tag) == hdr->sz &&
dec->dp_buf.no_of_dec_pic_buf) {
vcd_status = ddl_decoder_dpb_transact(dec, value,
DDL_DPB_OP_MARK_FREE);
}
break;
case DDL_I_DPB:
{
struct ddl_property_dec_pic_buffers *dpb = value;
if (sizeof(*dpb) == hdr->sz &&
(DDLCLIENT_STATE_IS(ddl,
DDL_CLIENT_WAIT_FOR_INITCODEC) ||
DDLCLIENT_STATE_IS(ddl,
DDL_CLIENT_WAIT_FOR_DPB)) &&
dpb->no_of_dec_pic_buf >=
dec->client_output_buf_req.actual_count) {
vcd_status = ddl_set_dec_buffers(dec, dpb);
}
break;
}
case DDL_I_REQ_OUTPUT_FLUSH:
if (sizeof(u32) == hdr->sz) {
dec->dynamic_prop_change |= DDL_DEC_REQ_OUTPUT_FLUSH;
dec->dpb_mask.client_mask = 0;
vcd_status = VCD_S_SUCCESS;
}
break;
case DDL_I_INPUT_BUF_REQ:
{
struct vcd_buffer_requirement *buf_req = value;
if (sizeof(*buf_req) == hdr->sz &&
ddl_valid_buffer_requirement(
&dec->min_input_buf_req, buf_req)) {
dec->client_input_buf_req = *buf_req;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case DDL_I_OUTPUT_BUF_REQ:
{
struct vcd_buffer_requirement *buf_req = value;
if (sizeof(*buf_req) == hdr->sz &&
ddl_valid_buffer_requirement(
&dec->min_output_buf_req, buf_req)) {
dec->client_output_buf_req = *buf_req;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_CODEC:
{
struct vcd_property_codec *codec = value;
if (sizeof(*codec) == hdr->sz &&
DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
if (!vcd_fw_is_codec_supported(true, codec->codec)) {
vcd_status = VCD_ERR_NOT_SUPPORTED;
break;
}
dec->codec_type = *codec;
ddl_set_default_dec_property(ddl);
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_POST_FILTER:
if (sizeof(struct vcd_property_post_filter) == hdr->sz &&
DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) &&
(dec->codec_type.codec == VCD_CODEC_MPEG4 ||
dec->codec_type.codec == VCD_CODEC_MPEG2)) {
dec->post_filter = *(struct vcd_property_post_filter *)
value;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_FRAME_SIZE:
{
struct vcd_property_frame_size *frame_size = value;
if ((sizeof(*frame_size) == hdr->sz) &&
DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
if (dec->client_frame_size.height != frame_size->height
|| dec->client_frame_size.width !=
frame_size->width) {
dec->client_frame_size = *frame_size;
ddl_calculate_stride(&dec->client_frame_size,
!dec->progressive_only);
ddl_set_default_decoder_buffer_req(dec, true);
}
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_BUFFER_FORMAT:
{
struct vcd_property_buffer_format *tile = value;
if (sizeof(*tile) == hdr->sz &&
DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) &&
(tile->buffer_format == VCD_BUFFER_FORMAT_NV12
|| tile->buffer_format ==
VCD_BUFFER_FORMAT_TILE_4x2)) {
if (tile->buffer_format !=
dec->buf_format.buffer_format) {
dec->buf_format = *tile;
ddl_set_default_decoder_buffer_req(dec, true);
}
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_METADATA_ENABLE:
case VCD_I_METADATA_HEADER:
vcd_status = ddl_set_metadata_params(ddl, hdr, value);
break;
default:
vcd_status = VCD_ERR_ILLEGAL_OP;
break;
}
return vcd_status;
}
static u32 ddl_set_enc_property(struct ddl_client_context *ddl,
struct vcd_property_hdr *hdr, void *value)
{
u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
struct ddl_encoder_data *enc = &ddl->codec_data.encoder;
if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) {
vcd_status = ddl_set_enc_dynamic_property(enc, hdr, value);
return vcd_status;
}
if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) {
pr_err("ddl_set_enc_property:"
"Fails_as_not_in_open_state\n");
return VCD_ERR_ILLEGAL_OP;
}
switch (hdr->id) {
case VCD_I_TARGET_BITRATE:
{
struct vcd_property_target_bitrate *bitrate = value;
if (sizeof(*bitrate) == hdr->sz &&
bitrate->target_bitrate) {
enc->target_bit_rate = *bitrate;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_FRAME_RATE:
{
struct vcd_property_frame_rate *framerate = value;
if (sizeof(*framerate) == hdr->sz &&
framerate->fps_denominator &&
framerate->fps_numerator) {
enc->frame_rate = *framerate;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_FRAME_SIZE:
{
struct vcd_property_frame_size *framesize = value;
if (sizeof(*framesize) == hdr->sz &&
DDL_ALLOW_ENC_FRAMESIZE(framesize->width,
framesize->height)) {
enc->frame_size = *framesize;
ddl_calculate_stride(&enc->frame_size, false);
ddl_set_default_encoder_buffer_req(enc);
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_CODEC:
{
struct vcd_property_codec *codec = value;
if (sizeof(*codec) == hdr->sz) {
if (!vcd_fw_is_codec_supported(false, codec->codec)) {
vcd_status = VCD_ERR_NOT_SUPPORTED;
break;
}
enc->codec_type = *codec;
ddl_set_default_enc_property(ddl);
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_REQ_IFRAME:
vcd_status = VCD_S_SUCCESS;
break;
case VCD_I_INTRA_PERIOD:
{
struct vcd_property_i_period *iperiod = value;
if (sizeof(*iperiod) == hdr->sz && !iperiod->bframes) {
enc->period = *iperiod;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_PROFILE:
{
struct vcd_property_profile *profile = value;
if (sizeof(*profile) == hdr->sz &&
((enc->codec_type.codec == VCD_CODEC_MPEG4 &&
(profile->profile == VCD_PROFILE_MPEG4_SP ||
profile->profile == VCD_PROFILE_MPEG4_ASP)) ||
((enc->codec_type.codec == VCD_CODEC_H264 &&
profile->profile >= VCD_PROFILE_H264_BASELINE &&
profile->profile <= VCD_PROFILE_H264_HIGH)) ||
(enc->codec_type.codec == VCD_CODEC_H263 &&
profile->profile == VCD_PROFILE_H263_BASELINE))
) {
enc->profile = *profile;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_LEVEL:
{
struct vcd_property_level *level = value;
if (sizeof(*level) == hdr->sz &&
((enc->codec_type.codec == VCD_CODEC_MPEG4 &&
level->level >= VCD_LEVEL_MPEG4_0 &&
level->level <= VCD_LEVEL_MPEG4_6) ||
(enc->codec_type.codec == VCD_CODEC_H264 &&
level->level >= VCD_LEVEL_H264_1 &&
level->level <= VCD_LEVEL_H264_3p1) ||
(enc->codec_type.codec == VCD_CODEC_H263 &&
level->level >= VCD_LEVEL_H263_10 &&
level->level <= VCD_LEVEL_H263_70))) {
enc->level = *level;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_MULTI_SLICE:
{
struct vcd_property_multi_slice *multislice = value;
switch (multislice->m_slice_sel) {
case VCD_MSLICE_OFF:
vcd_status = VCD_S_SUCCESS;
break;
case VCD_MSLICE_BY_GOB:
if (enc->codec_type.codec == VCD_CODEC_H263)
vcd_status = VCD_S_SUCCESS;
break;
case VCD_MSLICE_BY_MB_COUNT:
if (multislice->m_slice_size >= 1 &&
(multislice->m_slice_size <=
(enc->frame_size.height
* enc->frame_size.width / 16 / 16))) {
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_MSLICE_BY_BYTE_COUNT:
if (multislice->m_slice_size <
DDL_MINIMUM_BYTE_PER_SLICE) {
vcd_status = VCD_S_SUCCESS;
break;
}
default:
break;
}
if (sizeof(struct vcd_property_multi_slice) == hdr->sz &&
!vcd_status) {
enc->multi_slice = *multislice;
}
break;
}
case VCD_I_RATE_CONTROL:
{
struct vcd_property_rate_control *ratecontrol_type = value;
if (sizeof(*ratecontrol_type) == hdr->sz &&
ratecontrol_type->rate_control >=
VCD_RATE_CONTROL_OFF &&
ratecontrol_type->rate_control <=
VCD_RATE_CONTROL_CBR_CFR) {
enc->rc_type = *ratecontrol_type;
ddl_set_default_enc_rc_params(enc);
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_SHORT_HEADER:
if (sizeof(struct vcd_property_short_header) == hdr->sz &&
enc->codec_type.codec == VCD_CODEC_MPEG4) {
enc->short_header =
*(struct vcd_property_short_header *)value;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_VOP_TIMING:
{
struct vcd_property_vop_timing *voptime = value;
if (sizeof(*voptime) == hdr->sz && enc->frame_rate.fps_numerator
<= voptime->vop_time_resolution) {
enc->vop_timing = *voptime;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_HEADER_EXTENSION:
if (sizeof(u32) == hdr->sz && enc->codec_type.codec ==
VCD_CODEC_MPEG4) {
enc->hdr_ext_control = *(u32 *)value;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_ENTROPY_CTRL:
{
struct vcd_property_entropy_control *entropy = value;
if (sizeof(*entropy) == hdr->sz &&
enc->codec_type.codec == VCD_CODEC_H264 &&
entropy->entropy_sel >= VCD_ENTROPY_SEL_CAVLC &&
entropy->entropy_sel <= VCD_ENTROPY_SEL_CABAC) {
enc->entropy_control = *entropy;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_DEBLOCKING:
{
struct vcd_property_db_config *db = value;
if (sizeof(*db) == hdr->sz &&
enc->codec_type.codec == VCD_CODEC_H264 &&
db->db_config >= VCD_DB_ALL_BLOCKING_BOUNDARY &&
db->db_config <= VCD_DB_SKIP_SLICE_BOUNDARY) {
enc->db_control = *db;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_QP_RANGE:
{
struct vcd_property_qp_range *qp = value;
if (sizeof(*qp) == hdr->sz && qp->min_qp <= qp->max_qp &&
((enc->codec_type.codec == VCD_CODEC_H264 &&
qp->max_qp <= DDL_MAX_H264_QP) ||
qp->max_qp <= DDL_MAX_MPEG4_QP)) {
enc->qp_range = *qp;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_SESSION_QP:
{
struct vcd_property_session_qp *qp = value;
if ((sizeof(*qp) == hdr->sz) &&
qp->iframe_qp >= enc->qp_range.min_qp &&
qp->iframe_qp <= enc->qp_range.max_qp &&
qp->frame_qp >= enc->qp_range.min_qp &&
qp->frame_qp <= enc->qp_range.max_qp) {
enc->session_qp = *qp;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_RC_LEVEL_CONFIG:
{
struct vcd_property_rc_level *rc_level = value;
if (sizeof(*rc_level) == hdr->sz &&
(enc->rc_type.rate_control >=
VCD_RATE_CONTROL_VBR_VFR ||
enc->rc_type.rate_control <=
VCD_RATE_CONTROL_CBR_VFR) &&
(!rc_level->mb_level_rc ||
enc->codec_type.codec == VCD_CODEC_H264)) {
enc->rc_level = *rc_level;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_FRAME_LEVEL_RC:
{
struct vcd_property_frame_level_rc_params *rc = value;
if (sizeof(*rc) == hdr->sz && rc->reaction_coeff &&
enc->rc_level.frame_level_rc) {
enc->frame_level_rc = *rc;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_ADAPTIVE_RC:
{
struct vcd_property_adaptive_rc_params *rc = value;
if (sizeof(*rc) == hdr->sz && enc->codec_type.codec ==
VCD_CODEC_H264 && enc->rc_level.mb_level_rc) {
enc->adaptive_rc = *rc;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_INTRA_REFRESH:
{
struct vcd_property_intra_refresh_mb_number *mbnum = value;
u32 frame_mbnum = (enc->frame_size.width / 16) *
(enc->frame_size.height / 16);
if (sizeof(*mbnum) == hdr->sz && mbnum->cir_mb_number <=
frame_mbnum) {
enc->intra_refresh = *mbnum;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_BUFFER_FORMAT:
{
struct vcd_property_buffer_format *tile = value;
if (sizeof(*tile) == hdr->sz && tile->buffer_format ==
VCD_BUFFER_FORMAT_NV12) {
enc->buf_format = *tile;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case DDL_I_INPUT_BUF_REQ:
{
struct vcd_buffer_requirement *buf_req = value;
if (sizeof(*buf_req) == hdr->sz && ddl_valid_buffer_requirement(
&enc->input_buf_req, buf_req)) {
enc->client_input_buf_req = *buf_req;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case DDL_I_OUTPUT_BUF_REQ:
{
struct vcd_buffer_requirement *buf_req = value;
if (sizeof(*buf_req) == hdr->sz && ddl_valid_buffer_requirement(
&enc->output_buf_req, buf_req)) {
enc->client_output_buf_req = *buf_req;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_METADATA_ENABLE:
case VCD_I_METADATA_HEADER:
vcd_status = ddl_set_metadata_params(ddl, hdr, value);
break;
default:
vcd_status = VCD_ERR_ILLEGAL_OP;
break;
}
return vcd_status;
}
static u32 ddl_get_dec_property(struct ddl_client_context *ddl,
struct vcd_property_hdr *hdr, void *value)
{
u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
struct ddl_decoder_data *dec = &ddl->codec_data.decoder;
switch (hdr->id) {
case VCD_I_FRAME_SIZE:
if (sizeof(struct vcd_property_frame_size) == hdr->sz) {
if (dec->client_frame_size.width) {
struct vcd_property_frame_size *size = value;
*size = dec->client_frame_size;
vcd_status = VCD_S_SUCCESS;
} else {
vcd_status = VCD_ERR_ILLEGAL_OP;
}
}
break;
case VCD_I_PROFILE:
if (sizeof(struct vcd_property_profile) == hdr->sz) {
*(struct vcd_property_profile *)value = dec->profile;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_LEVEL:
if (sizeof(struct vcd_property_level) == hdr->sz) {
*(struct vcd_property_level *)value = dec->level;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_PROGRESSIVE_ONLY:
if (sizeof(u32) == hdr->sz) {
*(u32 *)value = dec->progressive_only;
vcd_status = VCD_S_SUCCESS;
}
break;
case DDL_I_INPUT_BUF_REQ:
if (sizeof(struct vcd_buffer_requirement) == hdr->sz) {
if (dec->client_input_buf_req.size) {
*(struct vcd_buffer_requirement *)value =
dec->client_input_buf_req;
vcd_status = VCD_S_SUCCESS;
} else {
vcd_status = VCD_ERR_ILLEGAL_OP;
}
}
break;
case DDL_I_OUTPUT_BUF_REQ:
if (sizeof(struct vcd_buffer_requirement) == hdr->sz) {
if (dec->client_output_buf_req.size) {
*(struct vcd_buffer_requirement *)value =
dec->client_output_buf_req;
vcd_status = VCD_S_SUCCESS;
} else {
vcd_status = VCD_ERR_ILLEGAL_OP;
}
}
break;
case VCD_I_CODEC:
if (sizeof(struct vcd_property_codec) == hdr->sz) {
if (dec->codec_type.codec) {
*(struct vcd_property_codec *)value =
dec->codec_type;
vcd_status = VCD_S_SUCCESS;
} else {
vcd_status = VCD_ERR_ILLEGAL_OP;
}
}
break;
case VCD_I_BUFFER_FORMAT:
if (sizeof(struct vcd_property_buffer_format) == hdr->sz) {
*(struct vcd_property_buffer_format *)value =
dec->buf_format;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_POST_FILTER:
if (sizeof(struct vcd_property_post_filter) == hdr->sz) {
*(struct vcd_property_post_filter *)value =
dec->post_filter;
vcd_status = VCD_S_SUCCESS;
}
break;
case DDL_I_SEQHDR_ALIGN_BYTES:
if (sizeof(u32) == hdr->sz) {
*(u32 *)value = DDL_LINEAR_BUFFER_ALIGN_BYTES;
vcd_status = VCD_S_SUCCESS;
}
break;
case DDL_I_FRAME_PROC_UNITS:
if (sizeof(u32) == hdr->sz && dec->client_frame_size.width &&
dec->client_frame_size.height) {
*(u32 *)value = ((dec->client_frame_size.width >> 4) *
(dec->client_frame_size.height >> 4));
vcd_status = VCD_S_SUCCESS;
}
break;
case DDL_I_DPB_RETRIEVE:
if (sizeof(struct ddl_frame_data_tag) == hdr->sz) {
vcd_status = ddl_decoder_dpb_transact(dec,
(struct ddl_frame_data_tag *)value,
DDL_DPB_OP_RETRIEVE);
}
break;
case VCD_I_METADATA_ENABLE:
case VCD_I_METADATA_HEADER:
vcd_status = ddl_get_metadata_params(ddl, hdr, value);
break;
default:
vcd_status = VCD_ERR_ILLEGAL_OP;
break;
}
return vcd_status;
}
static u32 ddl_get_enc_property(struct ddl_client_context *ddl,
struct vcd_property_hdr *hdr, void *value)
{
u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
struct ddl_encoder_data *enc = &ddl->codec_data.encoder;
struct vcd_property_entropy_control *entropy_control;
struct vcd_property_intra_refresh_mb_number *intra_refresh;
switch (hdr->id) {
case VCD_I_CODEC:
if (sizeof(struct vcd_property_codec) == hdr->sz) {
*(struct vcd_property_codec *)value = enc->codec_type;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_FRAME_SIZE:
if (sizeof(struct vcd_property_frame_size) == hdr->sz) {
*(struct vcd_property_frame_size *)value =
enc->frame_size;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_FRAME_RATE:
if (sizeof(struct vcd_property_frame_rate) == hdr->sz) {
*(struct vcd_property_frame_rate *)value =
enc->frame_rate;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_TARGET_BITRATE:
if (sizeof(struct vcd_property_target_bitrate) == hdr->sz) {
*(struct vcd_property_target_bitrate *)value =
enc->target_bit_rate;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_RATE_CONTROL:
if (sizeof(struct vcd_property_rate_control) == hdr->sz) {
*(struct vcd_property_rate_control *)value =
enc->rc_type;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_PROFILE:
if (sizeof(struct vcd_property_profile) == hdr->sz) {
*(struct vcd_property_profile *)value = enc->profile;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_LEVEL:
if (sizeof(struct vcd_property_level) == hdr->sz) {
*(struct vcd_property_level *)value = enc->level;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_MULTI_SLICE:
if (sizeof(struct vcd_property_multi_slice) == hdr->sz) {
*(struct vcd_property_multi_slice *)value =
enc->multi_slice;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_SEQ_HEADER:
{
struct vcd_sequence_hdr *seq_hdr = value;
if (enc->seq_header.size && sizeof(struct vcd_sequence_hdr) ==
hdr->sz && enc->seq_header.size <=
seq_hdr->sz) {
memcpy(seq_hdr->addr, enc->seq_header.virt_addr,
enc->seq_header.size);
seq_hdr->sz = enc->seq_header.size;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case DDL_I_SEQHDR_PRESENT:
if (sizeof(u32) == hdr->sz) {
if ((enc->codec_type.codec == VCD_CODEC_MPEG4 &&
!enc->short_header.short_header) ||
enc->codec_type.codec ==
VCD_CODEC_H264)
*(u32 *)value = 0x1;
else
*(u32 *)value = 0x0;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_VOP_TIMING:
if (sizeof(struct vcd_property_vop_timing) == hdr->sz) {
*(struct vcd_property_vop_timing *)value =
enc->vop_timing;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_SHORT_HEADER:
if (sizeof(struct vcd_property_short_header) == hdr->sz) {
if (enc->codec_type.codec == VCD_CODEC_MPEG4) {
*(struct vcd_property_short_header *)value =
enc->short_header;
vcd_status = VCD_S_SUCCESS;
} else {
vcd_status = VCD_ERR_ILLEGAL_OP;
}
}
break;
case VCD_I_ENTROPY_CTRL:
entropy_control = value;
if (sizeof(struct vcd_property_entropy_control) == hdr->sz) {
if (enc->codec_type.codec == VCD_CODEC_H264) {
*entropy_control = enc->entropy_control;
vcd_status = VCD_S_SUCCESS;
} else {
vcd_status = VCD_ERR_ILLEGAL_OP;
}
}
break;
case VCD_I_DEBLOCKING:
if (sizeof(struct vcd_property_db_config) == hdr->sz) {
if (enc->codec_type.codec == VCD_CODEC_H264) {
*(struct vcd_property_db_config *)value =
enc->db_control;
vcd_status = VCD_S_SUCCESS;
} else {
vcd_status = VCD_ERR_ILLEGAL_OP;
}
}
break;
case VCD_I_INTRA_PERIOD:
if (sizeof(struct vcd_property_i_period) == hdr->sz) {
*(struct vcd_property_i_period *)value = enc->period;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_QP_RANGE:
if (sizeof(struct vcd_property_qp_range) == hdr->sz) {
*(struct vcd_property_qp_range *)value = enc->qp_range;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_SESSION_QP:
if (sizeof(struct vcd_property_session_qp) == hdr->sz) {
*(struct vcd_property_session_qp *)value =
enc->session_qp;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_RC_LEVEL_CONFIG:
if (sizeof(struct vcd_property_rc_level) == hdr->sz) {
*(struct vcd_property_rc_level *)value = enc->rc_level;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_FRAME_LEVEL_RC:
if (sizeof(struct vcd_property_frame_level_rc_params) ==
hdr->sz) {
*(struct vcd_property_frame_level_rc_params *)value =
enc->frame_level_rc;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_ADAPTIVE_RC:
if (sizeof(struct vcd_property_adaptive_rc_params) ==
hdr->sz) {
*(struct vcd_property_adaptive_rc_params *)value =
enc->adaptive_rc;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_INTRA_REFRESH:
intra_refresh = value;
if (sizeof(struct vcd_property_intra_refresh_mb_number) ==
hdr->sz) {
*intra_refresh = enc->intra_refresh;
vcd_status = VCD_S_SUCCESS;
}
break;
case DDL_I_INPUT_BUF_REQ:
if (sizeof(struct vcd_buffer_requirement) == hdr->sz) {
if (enc->output_buf_req.size) {
*(struct vcd_buffer_requirement *)value =
enc->client_input_buf_req;
vcd_status = VCD_S_SUCCESS;
} else {
vcd_status = VCD_ERR_ILLEGAL_OP;
}
}
break;
case DDL_I_OUTPUT_BUF_REQ:
if (sizeof(struct vcd_buffer_requirement) == hdr->sz) {
if (enc->output_buf_req.size) {
*(struct vcd_buffer_requirement *)value =
enc->client_output_buf_req;
vcd_status = VCD_S_SUCCESS;
} else {
vcd_status = VCD_ERR_ILLEGAL_OP;
}
}
break;
case VCD_I_BUFFER_FORMAT:
if (sizeof(struct vcd_property_buffer_format) == hdr->sz) {
*(struct vcd_property_buffer_format *)value =
enc->buf_format;
vcd_status = VCD_S_SUCCESS;
}
break;
case DDL_I_FRAME_PROC_UNITS:
if (sizeof(u32) == hdr->sz && enc->frame_size.width &&
enc->frame_size.height) {
*(u32 *)value = ((enc->frame_size.width >> 4) *
(enc->frame_size.height >> 4));
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_HEADER_EXTENSION:
if (sizeof(u32) == hdr->sz && enc->codec_type.codec ==
VCD_CODEC_MPEG4) {
*(u32 *)value = enc->hdr_ext_control;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_METADATA_ENABLE:
case VCD_I_METADATA_HEADER:
vcd_status = ddl_get_metadata_params(ddl, hdr, value);
break;
default:
vcd_status = VCD_ERR_ILLEGAL_OP;
break;
}
return vcd_status;
}
static u32 ddl_set_enc_dynamic_property(struct ddl_encoder_data *enc,
struct vcd_property_hdr *hdr, void *value)
{
u32 vcd_status = VCD_ERR_ILLEGAL_PARM;
switch (hdr->id) {
case VCD_I_REQ_IFRAME:
if (sizeof(struct vcd_property_req_i_frame) == hdr->sz) {
enc->dynamic_prop_change |= DDL_ENC_REQ_IFRAME;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_TARGET_BITRATE:
if (sizeof(struct vcd_property_target_bitrate) == hdr->sz) {
enc->target_bit_rate =
*(struct vcd_property_target_bitrate *)value;
enc->dynamic_prop_change |= DDL_ENC_CHANGE_BITRATE;
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_INTRA_PERIOD:
{
struct vcd_property_i_period *iperiod = value;
if (sizeof(struct vcd_property_i_period) == hdr->sz &&
!iperiod->bframes) {
enc->period = *iperiod;
enc->dynamic_prop_change |= DDL_ENC_CHANGE_IPERIOD;
vcd_status = VCD_S_SUCCESS;
}
break;
}
case VCD_I_FRAME_RATE:
{
struct vcd_property_frame_rate *frame_rate = value;
if (sizeof(struct vcd_property_frame_rate) == hdr->sz &&
frame_rate->fps_denominator &&
frame_rate->fps_numerator &&
frame_rate->fps_denominator <=
frame_rate->fps_numerator) {
enc->frame_rate = *frame_rate;
enc->dynamic_prop_change |= DDL_ENC_CHANGE_FRAMERATE;
vcd_status = VCD_S_SUCCESS;
}
break;
}
default:
vcd_status = VCD_ERR_ILLEGAL_OP;
break;
}
return vcd_status;
}
void ddl_set_default_dec_property(struct ddl_client_context *ddl)
{
struct ddl_decoder_data *dec = &(ddl->codec_data.decoder);
if (dec->codec_type.codec == VCD_CODEC_MPEG4 ||
dec->codec_type.codec == VCD_CODEC_MPEG2) {
dec->post_filter.post_filter = true;
} else {
dec->post_filter.post_filter = false;
}
dec->buf_format.buffer_format = VCD_BUFFER_FORMAT_NV12;
dec->client_frame_size.height = 144;
dec->client_frame_size.width = 176;
dec->client_frame_size.stride = 176;
dec->client_frame_size.scan_lines = 144;
dec->progressive_only = 1;
ddl_set_default_metadata_flag(ddl);
ddl_set_default_decoder_buffer_req(dec, true);
}
static void ddl_set_default_enc_property(struct ddl_client_context *ddl)
{
struct ddl_encoder_data *enc = &(ddl->codec_data.encoder);
ddl_set_default_enc_profile(enc);
ddl_set_default_enc_level(enc);
enc->rc_type.rate_control = VCD_RATE_CONTROL_VBR_VFR;
ddl_set_default_enc_rc_params(enc);
ddl_set_default_enc_intra_period(enc);
enc->intra_refresh.cir_mb_number = 0;
ddl_set_default_enc_vop_timing(enc);
enc->multi_slice.m_slice_size = VCD_MSLICE_OFF;
enc->short_header.short_header = false;
enc->entropy_control.entropy_sel = VCD_ENTROPY_SEL_CAVLC;
enc->entropy_control.cabac_model = VCD_CABAC_MODEL_NUMBER_0;
enc->db_control.db_config = VCD_DB_ALL_BLOCKING_BOUNDARY;
enc->db_control.slice_alpha_offset = 0;
enc->db_control.slice_beta_offset = 0;
enc->re_con_buf_format.buffer_format = VCD_BUFFER_FORMAT_TILE_4x2;
enc->buf_format.buffer_format = VCD_BUFFER_FORMAT_NV12;
enc->hdr_ext_control = 0;
ddl_set_default_metadata_flag(ddl);
ddl_set_default_encoder_buffer_req(enc);
}
static void ddl_set_default_enc_profile(struct ddl_encoder_data *enc)
{
enum vcd_codec codec = enc->codec_type.codec;
if (codec == VCD_CODEC_MPEG4)
enc->profile.profile = VCD_PROFILE_MPEG4_SP;
else if (codec == VCD_CODEC_H264)
enc->profile.profile = VCD_PROFILE_H264_BASELINE;
else
enc->profile.profile = VCD_PROFILE_H263_BASELINE;
}
static void ddl_set_default_enc_level(struct ddl_encoder_data *enc)
{
enum vcd_codec codec = enc->codec_type.codec;
if (codec == VCD_CODEC_MPEG4)
enc->level.level = VCD_LEVEL_MPEG4_1;
else if (codec == VCD_CODEC_H264)
enc->level.level = VCD_LEVEL_H264_1;
else
enc->level.level = VCD_LEVEL_H263_10;
}
static void ddl_set_default_enc_vop_timing(struct ddl_encoder_data *enc)
{
enc->vop_timing.vop_time_resolution = (2 *
enc->frame_rate.fps_numerator) /
enc->frame_rate.fps_denominator;
}
static void ddl_set_default_enc_intra_period(struct ddl_encoder_data *enc)
{
switch (enc->rc_type.rate_control) {
default:
case VCD_RATE_CONTROL_VBR_VFR:
case VCD_RATE_CONTROL_VBR_CFR:
case VCD_RATE_CONTROL_CBR_VFR:
case VCD_RATE_CONTROL_OFF:
enc->period.frames = ((enc->frame_rate.fps_numerator << 1) /
enc->frame_rate.fps_denominator) - 1;
break;
case VCD_RATE_CONTROL_CBR_CFR:
enc->period.frames = ((enc->frame_rate.fps_numerator >> 1) /
enc->frame_rate.fps_denominator) - 1;
break;
}
enc->period.bframes = 0;
}
static void ddl_set_default_enc_rc_params(struct ddl_encoder_data *enc)
{
enum vcd_codec codec = enc->codec_type.codec;
enc->rc_level.frame_level_rc = true;
enc->qp_range.min_qp = 0x1;
if (codec == VCD_CODEC_H264) {
enc->qp_range.max_qp = 0x33;
enc->session_qp.iframe_qp = 0x19;
enc->session_qp.frame_qp = 0x19;
enc->rc_level.mb_level_rc = true;
enc->adaptive_rc.activity_region_flag = true;
enc->adaptive_rc.dark_region_as_flag = true;
enc->adaptive_rc.smooth_region_as_flag = true;
enc->adaptive_rc.static_region_as_flag = true;
} else {
enc->qp_range.max_qp = 0x1f;
enc->session_qp.iframe_qp = 0x14;
enc->session_qp.frame_qp = 0x14;
enc->rc_level.mb_level_rc = false;
}
switch (enc->rc_type.rate_control) {
default:
case VCD_RATE_CONTROL_VBR_VFR:
enc->r_cframe_skip = 1;
enc->frame_level_rc.reaction_coeff = 0x1f4;
break;
case VCD_RATE_CONTROL_VBR_CFR:
enc->r_cframe_skip = 0;
enc->frame_level_rc.reaction_coeff = 0x1f4;
break;
case VCD_RATE_CONTROL_CBR_VFR:
enc->r_cframe_skip = 1;
if (codec != VCD_CODEC_H264) {
enc->session_qp.iframe_qp = 0xf;
enc->session_qp.frame_qp = 0xf;
}
enc->frame_level_rc.reaction_coeff = 0x6;
break;
case VCD_RATE_CONTROL_CBR_CFR:
enc->r_cframe_skip = 0;
enc->frame_level_rc.reaction_coeff = 0x6;
break;
case VCD_RATE_CONTROL_OFF:
enc->r_cframe_skip = 0;
enc->rc_level.frame_level_rc = false;
enc->rc_level.mb_level_rc = false;
break;
}
}
void ddl_set_default_encoder_buffer_req(struct ddl_encoder_data *enc)
{
u32 y_cb_cr_size;
y_cb_cr_size = ddl_get_yuv_buffer_size(&enc->frame_size,
&enc->buf_format, false);
memset(&enc->input_buf_req, 0, sizeof(struct vcd_buffer_requirement));
enc->input_buf_req.min_count = 1;
enc->input_buf_req.actual_count = enc->input_buf_req.min_count;
enc->input_buf_req.max_count = DDL_MAX_BUFFER_COUNT;
enc->input_buf_req.size = y_cb_cr_size;
enc->input_buf_req.align = DDL_LINEAR_BUFFER_ALIGN_BYTES;
enc->client_input_buf_req = enc->input_buf_req;
memset(&enc->output_buf_req, 0, sizeof(struct vcd_buffer_requirement));
enc->output_buf_req.min_count = 2;
enc->output_buf_req.actual_count = enc->output_buf_req.min_count;
enc->output_buf_req.max_count = DDL_MAX_BUFFER_COUNT;
enc->output_buf_req.align = DDL_LINEAR_BUFFER_ALIGN_BYTES;
enc->output_buf_req.size = y_cb_cr_size;
ddl_set_default_encoder_metadata_buffer_size(enc);
enc->client_output_buf_req = enc->output_buf_req;
}
void ddl_set_default_decoder_buffer_req(struct ddl_decoder_data *dec,
u32 estimate)
{
size_t y_cb_cr_size;
u32 min_dpb;
struct vcd_property_frame_size *frame_size;
struct vcd_buffer_requirement *output_buf_req, *input_buf_req;
if (!dec->codec_type.codec)
return;
if (estimate) {
frame_size = &dec->client_frame_size;
output_buf_req = &dec->client_output_buf_req;
input_buf_req = &dec->client_input_buf_req;
min_dpb = ddl_decoder_min_num_dpb(dec);
y_cb_cr_size = ddl_get_yuv_buffer_size(frame_size,
&dec->buf_format, !dec->progressive_only);
} else {
frame_size = &dec->frame_size;
output_buf_req = &dec->actual_output_buf_req;
input_buf_req = &dec->actual_input_buf_req;
y_cb_cr_size = dec->y_cb_cr_size;
min_dpb = dec->min_dpb_num;
}
memset(output_buf_req, 0, sizeof(struct vcd_buffer_requirement));
output_buf_req->min_count = min_dpb;
output_buf_req->actual_count = output_buf_req->min_count;
output_buf_req->max_count = DDL_MAX_BUFFER_COUNT;
output_buf_req->size = y_cb_cr_size;
if (dec->buf_format.buffer_format != VCD_BUFFER_FORMAT_NV12)
output_buf_req->align = DDL_TILE_BUFFER_ALIGN_BYTES;
else
output_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES;
ddl_set_default_decoder_metadata_buffer_size(dec, frame_size,
output_buf_req);
dec->min_output_buf_req = *output_buf_req;
memset(input_buf_req, 0, sizeof(struct vcd_buffer_requirement));
input_buf_req->min_count = 1;
input_buf_req->actual_count = input_buf_req->min_count;
input_buf_req->max_count = DDL_MAX_BUFFER_COUNT;
input_buf_req->size = y_cb_cr_size;
if (input_buf_req->size >= (1280 * 720 * 3) >> 1)
input_buf_req->size >>= 1;
input_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES;
dec->min_input_buf_req = *input_buf_req;
}
size_t ddl_get_yuv_buffer_size(struct vcd_property_frame_size *frame_size,
struct vcd_property_buffer_format *buf_format, u32 interlace)
{
u32 width = frame_size->stride;
u32 height = frame_size->scan_lines;
size_t sz;
if (buf_format->buffer_format != VCD_BUFFER_FORMAT_NV12) {
size_t component_sz;
u32 width_round_up;
u32 height_round_up;
u32 height_chroma = (height >> 1);
width_round_up = DDL_TILE_ALIGN(width, DDL_TILE_ALIGN_WIDTH);
height_round_up = DDL_TILE_ALIGN(height, DDL_TILE_ALIGN_HEIGHT);
component_sz = width_round_up * height_round_up;
component_sz = DDL_TILE_ALIGN(component_sz,
DDL_TILE_MULTIPLY_FACTOR);
sz = (component_sz + DDL_TILE_BUF_ALIGN_GUARD_BYTES) &
DDL_TILE_BUF_ALIGN_MASK;
height_round_up = DDL_TILE_ALIGN(height_chroma,
DDL_TILE_ALIGN_HEIGHT);
component_sz = width_round_up * height_round_up;
component_sz = DDL_TILE_ALIGN(component_sz,
DDL_TILE_MULTIPLY_FACTOR);
sz += component_sz;
} else {
sz = height * width;
sz += sz >> 1;
}
return sz;
}
void ddl_calculate_stride(struct vcd_property_frame_size *frame_size,
u32 interlace)
{
frame_size->stride = ((frame_size->width + 15) >> 4) << 4;
if (interlace)
frame_size->scan_lines = ((frame_size->height + 31) >> 5) << 5;
else
frame_size->scan_lines = ((frame_size->height + 15) >> 4) << 4;
}
static u32 ddl_valid_buffer_requirement(struct vcd_buffer_requirement
*orig, struct vcd_buffer_requirement *req)
{
u32 status = false;
if (orig->max_count >= req->actual_count &&
orig->actual_count <= req->actual_count &&
orig->align <= req->align && orig->size <= req->size) {
status = true;
} else {
pr_err("ddl_valid_buf_req:Failed\n");
}
return status;
}
static u32 ddl_decoder_min_num_dpb(struct ddl_decoder_data *dec)
{
u32 min_dpb = 0;
switch (dec->codec_type.codec) {
default:
case VCD_CODEC_MPEG4:
case VCD_CODEC_MPEG2:
case VCD_CODEC_DIVX_4:
case VCD_CODEC_DIVX_5:
case VCD_CODEC_DIVX_6:
case VCD_CODEC_XVID:
min_dpb = 3;
break;
case VCD_CODEC_H263:
min_dpb = 2;
break;
case VCD_CODEC_VC1:
case VCD_CODEC_VC1_RCV:
min_dpb = 4;
break;
case VCD_CODEC_H264:
{
u32 yuv_size = (dec->client_frame_size.height *
dec->client_frame_size.width * 3) >> 1;
min_dpb = 6912000 / yuv_size;
if (min_dpb > 16)
min_dpb = 16;
min_dpb += 2;
break;
}
}
return min_dpb;
}
static u32 ddl_set_dec_buffers(struct ddl_decoder_data *dec,
struct ddl_property_dec_pic_buffers *dpb)
{
u32 vcd_status = VCD_S_SUCCESS;
u32 i;
for (i = 0; !vcd_status && i < dpb->no_of_dec_pic_buf; ++i) {
if (!IS_ALIGNED(dpb->dec_pic_buffers[i].vcd_frm.phys_addr,
dec->client_output_buf_req.align) ||
dpb->dec_pic_buffers[i].vcd_frm.alloc_len <
dec->client_output_buf_req.size) {
vcd_status = VCD_ERR_ILLEGAL_PARM;
pr_err("ddl_set_prop:"
"Dpb_align_fail_or_alloc_size_small\n");
return vcd_status;
}
}
if (dec->dp_buf.no_of_dec_pic_buf) {
kfree(dec->dp_buf.dec_pic_buffers);
dec->dp_buf.dec_pic_buffers = NULL;
dec->dp_buf.no_of_dec_pic_buf = 0;
}
dec->dp_buf.dec_pic_buffers = kmalloc(dpb->no_of_dec_pic_buf *
sizeof(struct ddl_frame_data_tag), GFP_KERNEL);
if (!dec->dp_buf.dec_pic_buffers) {
pr_err("ddl_dec_set_prop:"
"Dpb_container_alloc_failed\n");
return VCD_ERR_ALLOC_FAIL;
}
dec->dp_buf.no_of_dec_pic_buf = dpb->no_of_dec_pic_buf;
for (i = 0; i < dpb->no_of_dec_pic_buf; ++i)
dec->dp_buf.dec_pic_buffers[i] = dpb->dec_pic_buffers[i];
dec->dpb_mask.client_mask = 0;
dec->dpb_mask.hw_mask = 0;
dec->dynamic_prop_change = 0;
return VCD_S_SUCCESS;
}
void ddl_set_initial_default_values(struct ddl_client_context *ddl)
{
if (ddl->decoding) {
ddl->codec_data.decoder.codec_type.codec = VCD_CODEC_MPEG4;
ddl_set_default_dec_property(ddl);
} else {
struct ddl_encoder_data *enc = &(ddl->codec_data.encoder);
enc->codec_type.codec = VCD_CODEC_MPEG4;
enc->target_bit_rate.target_bitrate = 64000;
enc->frame_size.width = 176;
enc->frame_size.height = 144;
enc->frame_size.stride = 176;
enc->frame_size.scan_lines = 144;
enc->frame_rate.fps_numerator = 30;
enc->frame_rate.fps_denominator = 1;
ddl_set_default_enc_property(ddl);
}
}