/* dump to file */
dump_write(buf, count);
#endif
- aml_v4l2_debug(4, "[%d] write frames, vbuf: %p, size: %u, ret: %d, crc: %x",
+ aml_v4l2_debug(3, "[%d] write frames, vbuf: %p, size: %u, ret: %d, crc: %x",
ada_ctx->ctx->id, buf, count, ret, crc32_le(0, buf, count));
return ret;
return &ctx->q_data[AML_Q_DATA_DST];
}
-static void aml_vdec_queue_res_chg_event(struct aml_vcodec_ctx *ctx)
+void aml_vdec_dispatch_event(struct aml_vcodec_ctx *ctx, u32 changes)
{
- static const struct v4l2_event ev_src_ch = {
- .type = V4L2_EVENT_SOURCE_CHANGE,
- .u.src_change.changes =
- V4L2_EVENT_SRC_CH_RESOLUTION,
- };
+ struct v4l2_event event = {0};
- aml_v4l2_debug(4, "[%d] %s()", ctx->id, __func__);
- v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
+ switch (changes) {
+ case V4L2_EVENT_SRC_CH_RESOLUTION:
+ case V4L2_EVENT_SRC_CH_HDRINFO:
+ case V4L2_EVENT_REQUEST_RESET:
+ case V4L2_EVENT_REQUEST_EXIT:
+ event.type = V4L2_EVENT_SOURCE_CHANGE;
+ event.u.src_change.changes = changes;
+ break;
+ default:
+ pr_err("unsupport dispatch event %x\n", changes);
+ return;
+ }
+
+ v4l2_event_queue_fh(&ctx->fh, &event);
+ aml_v4l2_debug(3, "[%d] %s() changes: %x",
+ ctx->id, __func__, changes);
}
static void aml_vdec_flush_decoder(struct aml_vcodec_ctx *ctx)
if (dstbuf->lastframe &&
ctx->q_data[AML_Q_DATA_SRC].resolution_changed) {
+
+ /* make the run to stanby until new buffs to enque. */
+ ctx->v4l_codec_dpb_ready = false;
+
/*
* After all buffers containing decoded frames from
* before the resolution change point ready to be
* type V4L2_EVENT_SRC_CH_RESOLUTION, also the upper
* layer will get new information from cts->picinfo.
*/
- aml_vdec_queue_res_chg_event(ctx);
+ aml_vdec_dispatch_event(ctx, V4L2_EVENT_SRC_CH_RESOLUTION);
}
ctx->decoded_frame_cnt++;
return ret;
}
+static void aml_check_dpb_ready(struct aml_vcodec_ctx *ctx)
+{
+ if (!ctx->v4l_codec_dpb_ready) {
+ int buf_ready_num;
+
+ /* is there enough dst bufs for decoding? */
+ buf_ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
+ if ((ctx->dpb_size) &&
+ ((buf_ready_num + ctx->buf_used_count) >= ctx->dpb_size))
+ ctx->v4l_codec_dpb_ready = true;
+ aml_v4l2_debug(2, "[%d] %s() dpb: %d, ready: %d, used: %d, dpb is ready: %s",
+ ctx->id, __func__, ctx->dpb_size,
+ buf_ready_num, ctx->buf_used_count,
+ ctx->v4l_codec_dpb_ready ? "yes" : "no");
+ }
+}
+
static int is_vdec_ready(struct aml_vcodec_ctx *ctx)
{
struct aml_vcodec_dev *dev = ctx->dev;
}
mutex_unlock(&ctx->state_lock);
- if (!ctx->v4l_codec_dpb_ready) {
- int buf_ready_num;
-
- /* is there enough dst bufs for decoding? */
- buf_ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
- if ((buf_ready_num + ctx->buf_used_count) >= ctx->dpb_size)
- ctx->v4l_codec_dpb_ready = true;
- aml_v4l2_debug(2, "[%d] %s() dpb: %d, ready: %d, used: %d",
- ctx->id, __func__, ctx->dpb_size,
- buf_ready_num, ctx->buf_used_count);
- }
+ /* check dpb ready */
+ //aml_check_dpb_ready(ctx);
return 1;
}
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_ACTIVE) {
ctx->state = AML_STATE_FLUSHING;// prepare flushing
- aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_FLUSHING-END)",
+ aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_FLUSHING-LASTFRM)",
ctx->id, __func__);
}
mutex_unlock(&ctx->state_lock);
V4L2_BUF_TYPE_VIDEO_CAPTURE);
switch (cmd->cmd) {
case V4L2_DEC_CMD_STOP:
-
- if (ctx->state != AML_STATE_ACTIVE)
- return 0;
+ if (ctx->state != AML_STATE_ACTIVE) {
+ if (ctx->state >= AML_STATE_IDLE &&
+ ctx->state <= AML_STATE_PROBE) {
+ ctx->state = AML_STATE_ABORT;
+ aml_vdec_dispatch_event(ctx, V4L2_EVENT_REQUEST_EXIT);
+ aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)",
+ ctx->id, __func__);
+ return -1;
+ }
+ }
src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
buf->queued_in_vb2 = true;
buf->queued_in_v4l2 = true;
buf->ready_to_display = false;
+
+ /* check dpb ready */
+ aml_check_dpb_ready(ctx);
} else if (buf->frame_buffer.status == FB_ST_DISPLAY) {
buf->queued_in_vb2 = false;
buf->queued_in_v4l2 = true;
ctx->dpb_size = dpb;
ctx->last_decoded_picinfo = ctx->picinfo;
- aml_vdec_queue_res_chg_event(ctx);
+ aml_vdec_dispatch_event(ctx, V4L2_EVENT_SRC_CH_RESOLUTION);
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_INIT) {
struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+ struct aml_dec_params *in =
+ (struct aml_dec_params *) a->parm.raw_data;
+ struct aml_dec_params *dec = &ctx->config.parm.dec;
+
ctx->config.type = V4L2_CONFIG_PARM_DECODE;
- ctx->config.length = sizeof(a->parm.raw_data);
- memcpy(ctx->config.parm.data, a->parm.raw_data,
- sizeof(a->parm.raw_data));
+
+ if (in->parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
+ dec->cfg = in->cfg;
+ if (in->parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
+ dec->ps = in->ps;
+ if (in->parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
+ dec->hdr = in->hdr;
+ if (in->parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
+ dec->cnt = in->cnt;
+
+ dec->parms_status |= in->parms_status;
}
return 0;
#define AML_V4L2_SET_DECMODE (V4L2_CID_USER_AMLOGIC_BASE + 0)
-/* codec types of get/set parms. */
-#define V4L2_CONFIG_PARM_ENCODE (0)
-#define V4L2_CONFIG_PARM_DECODE (1)
-
-/* types of decode parms. */
-#define V4L2_CONFIG_PARM_DECODE_COMMON (1 << 0)
-#define V4L2_CONFIG_PARM_DECODE_PICINFO (1 << 1)
-#define V4L2_CONFIG_PARM_DECODE_HDRINFO (1 << 2)
-
/* for video composer metafd private_data struct */
struct file_privdata {
struct vframe_s vf;
void aml_thread_stop(struct aml_vcodec_ctx *ctx);
void wait_vcodec_ending(struct aml_vcodec_ctx *ctx);
void vdec_frame_buffer_release(void *data);
+void aml_vdec_dispatch_event(struct aml_vcodec_ctx *ctx, u32 changes);
#endif /* _AML_VCODEC_DEC_H_ */
#define AML_V4L2_BENCHMARK 0
#define WAIT_INTR_TIMEOUT_MS 1000
+/* codec types of get/set parms. */
+#define V4L2_CONFIG_PARM_ENCODE (0)
+#define V4L2_CONFIG_PARM_DECODE (1)
+
+/* types of decode parms. */
+#define V4L2_CONFIG_PARM_DECODE_CFGINFO (1 << 0)
+#define V4L2_CONFIG_PARM_DECODE_PSINFO (1 << 1)
+#define V4L2_CONFIG_PARM_DECODE_HDRINFO (1 << 2)
+#define V4L2_CONFIG_PARM_DECODE_CNTINFO (1 << 3)
+
+/* amlogic event define. */
+/* #define V4L2_EVENT_SRC_CH_RESOLUTION (1 << 0) */
+#define V4L2_EVENT_SRC_CH_HDRINFO (1 << 1)
+#define V4L2_EVENT_SRC_CH_PSINFO (1 << 2)
+#define V4L2_EVENT_SRC_CH_CNTINFO (1 << 3)
+
+/* exception handing */
+#define V4L2_EVENT_REQUEST_RESET (1 << 8)
+#define V4L2_EVENT_REQUEST_EXIT (1 << 9)
+
/**
* enum aml_hw_reg_idx - AML hw register base index
*/
unsigned int c_bs_sz;
unsigned int y_len_sz;
unsigned int c_len_sz;
+ int profile_idc;
};
-struct aml_vdec_pic_infos {
- u32 visible_width;
- u32 visible_height;
- u32 coded_width;
- u32 coded_height;
- u32 dpb_size;
+struct aml_vdec_cfg_infos {
+ u32 double_write_mode;
+ u32 init_width;
+ u32 init_height;
+ u32 ref_buf_margin;
+ u32 block_mode;
};
struct aml_vdec_hdr_infos {
struct vframe_master_display_colour_s color_parms;
};
+struct aml_vdec_ps_infos {
+ u32 visible_width;
+ u32 visible_height;
+ u32 coded_width;
+ u32 coded_height;
+ u32 profile;
+ u32 mb_width;
+ u32 mb_height;
+ u32 dpb_size;
+ u32 ref_frames;
+ u32 reorder_frames;
+};
+
+struct aml_vdec_cnt_infos {
+ u32 bit_rate;
+ u32 frame_count;
+ u32 error_frame_count;
+ u32 drop_frame_count;
+ u32 total_data;
+};
+
struct aml_dec_params {
- u32 dec_parms_status;
- u32 es_need_header;
- u32 double_write_mode;
- u32 buffer_mode;
- u32 buffer_width;
- u32 buffer_height;
- u32 buffer_margin;
- struct aml_vdec_pic_infos pic;
- struct aml_vdec_hdr_infos hdr;
+ u32 parms_status;
+ struct aml_vdec_cfg_infos cfg;
+ struct aml_vdec_ps_infos ps;
+ struct aml_vdec_hdr_infos hdr;
+ struct aml_vdec_cnt_infos cnt;
};
struct v4l2_config_parm {
int vcodec_vfm_init(struct vcodec_vfm_s *vfm)
{
+ int ret;
+
snprintf(vfm->recv_name, VF_NAME_SIZE, "%s-%d",
RECEIVER_NAME, vfm->ctx->id);
snprintf(vfm->prov_name, VF_NAME_SIZE, "%s-%d",
vfm->ada_ctx->recv_name = vfm->recv_name;
vf_receiver_init(&vfm->vf_recv, vfm->recv_name, &vf_receiver, vfm);
- vf_reg_receiver(&vfm->vf_recv);
+ ret = vf_reg_receiver(&vfm->vf_recv);
- return 0;
+ vfm->vfm_initialized = ret ? false : true;
+
+ return ret;
}
void vcodec_vfm_release(struct vcodec_vfm_s *vfm)
{
- vf_unreg_receiver(&vfm->vf_recv);
+ if (vfm->vfm_initialized)
+ vf_unreg_receiver(&vfm->vf_recv);
}
char prov_name[VF_NAME_SIZE];
struct vframe_provider_s vf_prov;
struct vframe_receiver_s vf_recv;
+ bool vfm_initialized;
};
int vcodec_vfm_init(struct vcodec_vfm_s *vfm);
goto out;
}
+#if 0
/* if the maximum delay is not stored in the SPS, derive it based on the level */
if (!sps->bitstream_restriction_flag && sps->ref_frame_count) {
sps->num_reorder_frames = MAX_DELAYED_PIC_COUNT - 1;
}
}
}
+#endif
+
+ sps->num_reorder_frames = MAX_DELAYED_PIC_COUNT - 1;
+ for (i = 0; i < ARRAY_SIZE(level_max_dpb_mbs); i++) {
+ if (level_max_dpb_mbs[i][0] == sps->level_idc) {
+ sps->num_reorder_frames =
+ MIN(level_max_dpb_mbs[i][1] / (sps->mb_width * sps->mb_height),
+ sps->num_reorder_frames);
+ sps->num_reorder_frames += 1;
+ if (sps->max_dec_frame_buffering > sps->num_reorder_frames)
+ sps->num_reorder_frames = sps->max_dec_frame_buffering;
+ break;
+ }
+ }
+
+ if ((sps->bitstream_restriction_flag) &&
+ (sps->max_dec_frame_buffering <
+ sps->num_reorder_frames)) {
+ sps->num_reorder_frames = sps->max_dec_frame_buffering;
+ pr_info("set reorder_pic_num to %d\n",
+ sps->num_reorder_frames);
+ }
if (!sps->sar.den)
sps->sar.den = 1;
{
struct aml_vcodec_ctx *ctx = inst->ctx;
- if (!ctx->config.length) {
- ctx->config.type = V4L2_CONFIG_PARM_DECODE;
- ctx->config.parm.dec.double_write_mode = 16;
- inst->parms = ctx->config.parm.dec;
-
- ctx->config.length =
- vdec_config_default_parms(ctx->config.buf);
- } else {
+ if (ctx->config.parm.dec.parms_status &
+ V4L2_CONFIG_PARM_DECODE_CFGINFO) {
u8 *pbuf = ctx->config.buf;
- inst->parms = ctx->config.parm.dec;
pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
pbuf += sprintf(pbuf, "mh264_double_write_mode:%d;",
- inst->parms.double_write_mode);
+ ctx->config.parm.dec.cfg.double_write_mode);
pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
- inst->parms.buffer_margin);
+ ctx->config.parm.dec.cfg.ref_buf_margin);
ctx->config.length = pbuf - ctx->config.buf;
+ } else {
+ ctx->config.parm.dec.cfg.double_write_mode = 16;
+ ctx->config.length = vdec_config_default_parms(ctx->config.buf);
}
- inst->vdec.config = ctx->config;
-
- inst->parms.dec_parms_status |=
- V4L2_CONFIG_PARM_DECODE_COMMON;
+ inst->vdec.config = ctx->config;
+ inst->parms.cfg = ctx->config.parm.dec.cfg;
+ inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
}
static int vdec_h264_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
/* init vfm */
inst->vfm.ctx = ctx;
inst->vfm.ada_ctx = &inst->vdec;
- vcodec_vfm_init(&inst->vfm);
+ ret = vcodec_vfm_init(&inst->vfm);
+ if (ret) {
+ pr_err("%s, init vfm failed.\n", __func__);
+ goto err;
+ }
ret = video_decoder_init(&inst->vdec);
if (ret) {
aml_vcodec_err(inst, "vdec_h264 init err=%d", ret);
- goto error_free_inst;
+ goto err;
}
/* probe info from the stream */
inst->vsi = kzalloc(sizeof(struct vdec_h264_vsi), GFP_KERNEL);
if (!inst->vsi) {
ret = -ENOMEM;
- goto error_free_inst;
+ goto err;
}
/* alloc the header buffer to be used cache sps or spp etc.*/
inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
if (!inst->vsi) {
ret = -ENOMEM;
- goto error_free_vsi;
+ goto err;
}
init_completion(&inst->comp);
//dump_init();
return 0;
-
-error_free_vsi:
- kfree(inst->vsi);
-error_free_inst:
- kfree(inst);
+err:
+ if (inst)
+ vcodec_vfm_release(&inst->vfm);
+ if (inst && inst->vsi && inst->vsi->header_buf)
+ kfree(inst->vsi->header_buf);
+ if (inst && inst->vsi)
+ kfree(inst->vsi);
+ if (inst)
+ kfree(inst);
*h_vdec = 0;
return ret;
struct vdec_pic_info *pic = &inst->vsi->pic;
struct vdec_h264_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
- int dw = inst->parms.double_write_mode;
- int margin = inst->parms.buffer_margin;
+ int dw = inst->parms.cfg.double_write_mode;
+ int margin = inst->parms.cfg.ref_buf_margin;
u32 mb_w, mb_h, width, height;
mb_w = sps->mb_width;
pic->coded_height = ALIGN(mb_h, 4) << 4;
pic->y_len_sz = pic->coded_width * pic->coded_height;
pic->c_len_sz = pic->y_len_sz >> 1;
+ pic->profile_idc = sps->profile_idc;
/* calc DPB size */
- dec->dpb_sz = sps->num_reorder_frames + 1 + margin;
+ dec->dpb_sz = sps->num_reorder_frames + margin;
+
+ inst->parms.ps.visible_width = pic->visible_width;
+ inst->parms.ps.visible_height = pic->visible_height;
+ inst->parms.ps.coded_width = pic->coded_width;
+ inst->parms.ps.coded_height = pic->coded_height;
+ inst->parms.ps.profile = sps->profile_idc;
+ inst->parms.ps.mb_width = sps->mb_width;
+ inst->parms.ps.mb_height = sps->mb_height;
+ inst->parms.ps.ref_frames = sps->ref_frame_count;
+ inst->parms.ps.reorder_frames = sps->num_reorder_frames;
+ inst->parms.ps.dpb_size = dec->dpb_sz;
+ inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_PSINFO;
vdec_config_dw_mode(pic, dw);
- inst->parms.dec_parms_status |=
- V4L2_CONFIG_PARM_DECODE_PICINFO;
-
aml_vcodec_debug(inst, "[%d] The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n",
- inst->ctx->id,inst->parms.double_write_mode,
- pic->coded_width, pic->coded_height,
+ inst->ctx->id, dw, pic->coded_width, pic->coded_height,
pic->visible_width, pic->visible_height,
- dec->dpb_sz - margin + 1, margin);
+ dec->dpb_sz - margin, margin);
}
static bool check_frame_combine(u8 *buf, u32 size, int *pos)
if (type == NAL_H264_SPS) {
ret = stream_parse(inst, p, len);
- if (!ret && (inst->vsi->cur_pic.coded_width !=
+ if (!ret && ((inst->vsi->cur_pic.coded_width !=
inst->vsi->pic.coded_width ||
inst->vsi->cur_pic.coded_height !=
- inst->vsi->pic.coded_height)) {
+ inst->vsi->pic.coded_height) ||
+ (inst->vsi->pic.profile_idc !=
+ inst->vsi->cur_pic.profile_idc))) {
+ pr_info("res change\n");
inst->vsi->cur_pic = inst->vsi->pic;
return true;
}
static void get_param_config_info(struct vdec_h264_inst *inst,
struct aml_dec_params *parms)
{
- *parms = inst->parms;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
+ parms->cfg = inst->parms.cfg;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
+ parms->ps = inst->parms.ps;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
+ parms->hdr = inst->parms.hdr;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
+ parms->cnt = inst->parms.cnt;
+
+ parms->parms_status |= inst->parms.parms_status;
- aml_vcodec_debug(inst, "parms status: %u", parms->dec_parms_status);
+ aml_vcodec_debug(inst, "parms status: %u", parms->parms_status);
}
static int vdec_h264_get_param(unsigned long h_vdec,
complete(&inst->comp);
}
-static void set_param_pic_info(struct vdec_h264_inst *inst,
- struct aml_vdec_pic_infos *info)
+static void set_param_ps_info(struct vdec_h264_inst *inst,
+ struct aml_vdec_ps_infos *ps)
{
struct vdec_pic_info *pic = &inst->vsi->pic;
struct vdec_h264_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
/* fill visible area size that be used for EGL. */
- pic->visible_width = info->visible_width;
- pic->visible_height = info->visible_height;
+ pic->visible_width = ps->visible_width;
+ pic->visible_height = ps->visible_height;
/* calc visible ares. */
rect->left = 0;
rect->height = pic->visible_height;
/* config canvas size that be used for decoder. */
- pic->coded_width = info->coded_width;
- pic->coded_height = info->coded_height;
+ pic->coded_width = ps->coded_width;
+ pic->coded_height = ps->coded_height;
pic->y_len_sz = pic->coded_width * pic->coded_height;
pic->c_len_sz = pic->y_len_sz >> 1;
- dec->dpb_sz = info->dpb_size;
+ dec->dpb_sz = ps->dpb_size;
- inst->parms.dec_parms_status |=
- V4L2_CONFIG_PARM_DECODE_PICINFO;
+ inst->parms.ps = *ps;
+ inst->parms.parms_status |=
+ V4L2_CONFIG_PARM_DECODE_PSINFO;
/*wake up*/
complete(&inst->comp);
pr_info("Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
- info->visible_width, info->visible_height,
- info->coded_width, info->coded_height,
- info->dpb_size);
+ ps->visible_width, ps->visible_height,
+ ps->coded_width, ps->coded_height,
+ dec->dpb_sz);
}
static void set_param_hdr_info(struct vdec_h264_inst *inst,
struct aml_vdec_hdr_infos *hdr)
{
inst->parms.hdr = *hdr;
- inst->parms.dec_parms_status |=
- V4L2_CONFIG_PARM_DECODE_HDRINFO;
+ if (!(inst->parms.parms_status &
+ V4L2_CONFIG_PARM_DECODE_HDRINFO)) {
+ inst->parms.hdr = *hdr;
+ inst->parms.parms_status |=
+ V4L2_CONFIG_PARM_DECODE_HDRINFO;
+ aml_vdec_dispatch_event(inst->ctx,
+ V4L2_EVENT_SRC_CH_HDRINFO);
+ pr_info("H264 set HDR infos\n");
+ }
+}
- //pr_info("H264 set HDR infos\n");
+static void set_param_post_event(struct vdec_h264_inst *inst, u32 *event)
+{
+ aml_vdec_dispatch_event(inst->ctx, *event);
+ pr_info("H264 post event: %d\n", *event);
}
static int vdec_h264_set_param(unsigned long h_vdec,
set_param_write_sync(inst);
break;
- case SET_PARAM_PIC_INFO:
- set_param_pic_info(inst, in);
+ case SET_PARAM_PS_INFO:
+ set_param_ps_info(inst, in);
break;
case SET_PARAM_HDR_INFO:
set_param_hdr_info(inst, in);
break;
+
+ case SET_PARAM_POST_EVENT:
+ set_param_post_event(inst, in);
+ break;
default:
aml_vcodec_err(inst, "invalid set parameter type=%d", type);
ret = -EINVAL;
{
struct aml_vcodec_ctx *ctx = inst->ctx;
- if (!ctx->config.length) {
- ctx->config.type = V4L2_CONFIG_PARM_DECODE;
- ctx->config.parm.dec.double_write_mode = 16;
- inst->parms = ctx->config.parm.dec;
-
- ctx->config.length =
- vdec_config_default_parms(ctx->config.buf);
- } else {
+ if (ctx->config.parm.dec.parms_status &
+ V4L2_CONFIG_PARM_DECODE_CFGINFO) {
u8 *pbuf = ctx->config.buf;
- inst->parms = ctx->config.parm.dec;
pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
- inst->parms.buffer_margin);
+ ctx->config.parm.dec.cfg.ref_buf_margin);
pbuf += sprintf(pbuf, "hevc_double_write_mode:%d;",
- inst->parms.double_write_mode);
- pbuf += sprintf(pbuf, "hevc_buf_width:%d;",
- inst->parms.buffer_width);
- pbuf += sprintf(pbuf, "hevc_buf_height:%d;",
- inst->parms.buffer_height);
- pbuf += sprintf(pbuf, "save_buffer_mode:%d;",
- inst->parms.buffer_mode);
+ ctx->config.parm.dec.cfg.double_write_mode);
+ pbuf += sprintf(pbuf, "hevc_buf_width:4096;");
+ pbuf += sprintf(pbuf, "hevc_buf_height:2304;");
+ pbuf += sprintf(pbuf, "save_buffer_mode:0;");
ctx->config.length = pbuf - ctx->config.buf;
+ } else {
+ ctx->config.parm.dec.cfg.double_write_mode = 16;
+ ctx->config.length = vdec_config_default_parms(ctx->config.buf);
}
- inst->vdec.config = ctx->config;
-
- inst->parms.dec_parms_status |=
- V4L2_CONFIG_PARM_DECODE_COMMON;
+ inst->vdec.config = ctx->config;
+ inst->parms.cfg = ctx->config.parm.dec.cfg;
+ inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
}
static int vdec_hevc_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
/* init vfm */
inst->vfm.ctx = ctx;
inst->vfm.ada_ctx = &inst->vdec;
- vcodec_vfm_init(&inst->vfm);
+ ret = vcodec_vfm_init(&inst->vfm);
+ if (ret) {
+ pr_err("%s, init vfm failed.\n", __func__);
+ goto err;
+ }
ret = video_decoder_init(&inst->vdec);
if (ret) {
aml_vcodec_err(inst, "vdec_hevc init err=%d", ret);
- goto error_free_inst;
+ goto err;
}
/* probe info from the stream */
inst->vsi = kzalloc(sizeof(struct vdec_hevc_vsi), GFP_KERNEL);
if (!inst->vsi) {
ret = -ENOMEM;
- goto error_free_inst;
+ goto err;
}
/* alloc the header buffer to be used cache sps or spp etc.*/
inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
if (!inst->vsi) {
ret = -ENOMEM;
- goto error_free_vsi;
+ goto err;
}
init_completion(&inst->comp);
//dump_init();
return 0;
-
-error_free_vsi:
- kfree(inst->vsi);
-error_free_inst:
- kfree(inst);
+err:
+ if (inst)
+ vcodec_vfm_release(&inst->vfm);
+ if (inst && inst->vsi && inst->vsi->header_buf)
+ kfree(inst->vsi->header_buf);
+ if (inst && inst->vsi)
+ kfree(inst->vsi);
+ if (inst)
+ kfree(inst);
*h_vdec = 0;
return ret;
static int vdec_get_dw_mode(struct vdec_hevc_inst *inst, int dw_mode)
{
- u32 valid_dw_mode = inst->parms.double_write_mode;
- int w = inst->parms.buffer_width;
- int h = inst->parms.buffer_height;
+ u32 valid_dw_mode = inst->parms.cfg.double_write_mode;
+ int w = inst->parms.cfg.init_width;
+ int h = inst->parms.cfg.init_height;
u32 dw = 0x1; /*1:1*/
switch (valid_dw_mode) {
struct vdec_pic_info *pic = &inst->vsi->pic;
struct vdec_hevc_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
- int dw = inst->parms.double_write_mode;
- int margin = inst->parms.buffer_margin;
+ int dw = inst->parms.cfg.double_write_mode;
+ int margin = inst->parms.cfg.ref_buf_margin;
/* fill visible area size that be used for EGL. */
pic->visible_width = sps->width - (sps->output_window.left_offset +
pic->c_len_sz = pic->y_len_sz >> 1;
/* calc DPB size */
- dec->dpb_sz = refer_buffer_num(sps) + margin;
+ dec->dpb_sz = refer_buffer_num(sps) + margin;
- inst->parms.dec_parms_status |=
- V4L2_CONFIG_PARM_DECODE_PICINFO;
+ inst->parms.ps.visible_width = pic->visible_width;
+ inst->parms.ps.visible_height = pic->visible_height;
+ inst->parms.ps.coded_width = pic->coded_width;
+ inst->parms.ps.coded_height = pic->coded_height;
+ inst->parms.ps.dpb_size = dec->dpb_sz;
+ inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_PSINFO;
pr_info("[%d] The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n",
- inst->ctx->id, inst->parms.double_write_mode,
- pic->coded_width, pic->coded_height,
+ inst->ctx->id, dw, pic->coded_width, pic->coded_height,
pic->visible_width, pic->visible_height,
dec->dpb_sz - margin, margin);
}
static void get_param_config_info(struct vdec_hevc_inst *inst,
struct aml_dec_params *parms)
{
- *parms = inst->parms;
-
- aml_vcodec_debug(inst, "parms status: %u", parms->dec_parms_status);
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
+ parms->cfg = inst->parms.cfg;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
+ parms->ps = inst->parms.ps;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
+ parms->hdr = inst->parms.hdr;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
+ parms->cnt = inst->parms.cnt;
+
+ parms->parms_status |= inst->parms.parms_status;
+
+ aml_vcodec_debug(inst, "parms status: %u", parms->parms_status);
}
static int vdec_hevc_get_param(unsigned long h_vdec,
complete(&inst->comp);
}
-static void set_param_pic_info(struct vdec_hevc_inst *inst,
- struct aml_vdec_pic_infos *info)
+static void set_param_ps_info(struct vdec_hevc_inst *inst,
+ struct aml_vdec_ps_infos *ps)
{
struct vdec_pic_info *pic = &inst->vsi->pic;
struct vdec_hevc_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
/* fill visible area size that be used for EGL. */
- pic->visible_width = info->visible_width;
- pic->visible_height = info->visible_height;
+ pic->visible_width = ps->visible_width;
+ pic->visible_height = ps->visible_height;
/* calc visible ares. */
rect->left = 0;
rect->height = pic->visible_height;
/* config canvas size that be used for decoder. */
- pic->coded_width = ALIGN(info->coded_width, 64);
- pic->coded_height = ALIGN(info->coded_height, 64);
+ pic->coded_width = ALIGN(ps->coded_width, 64);
+ pic->coded_height = ALIGN(ps->coded_height, 64);
pic->y_len_sz = pic->coded_width * pic->coded_height;
pic->c_len_sz = pic->y_len_sz >> 1;
- dec->dpb_sz = info->dpb_size;
+ dec->dpb_sz = ps->dpb_size;
- inst->parms.dec_parms_status |=
- V4L2_CONFIG_PARM_DECODE_PICINFO;
+ inst->parms.ps = *ps;
+ inst->parms.parms_status |=
+ V4L2_CONFIG_PARM_DECODE_PSINFO;
/*wake up*/
complete(&inst->comp);
static void set_param_hdr_info(struct vdec_hevc_inst *inst,
struct aml_vdec_hdr_infos *hdr)
{
- inst->parms.hdr = *hdr;
- inst->parms.dec_parms_status |=
- V4L2_CONFIG_PARM_DECODE_HDRINFO;
+ if (!(inst->parms.parms_status &
+ V4L2_CONFIG_PARM_DECODE_HDRINFO)) {
+ inst->parms.hdr = *hdr;
+ inst->parms.parms_status |=
+ V4L2_CONFIG_PARM_DECODE_HDRINFO;
+ aml_vdec_dispatch_event(inst->ctx,
+ V4L2_EVENT_SRC_CH_HDRINFO);
+ pr_info("H265 set HDR infos\n");
+ }
+}
- //pr_info("H265 set HDR infos\n");
+static void set_param_post_event(struct vdec_hevc_inst *inst, u32 *event)
+{
+ aml_vdec_dispatch_event(inst->ctx, *event);
+ pr_info("H265 post event: %d\n", *event);
}
static int vdec_hevc_set_param(unsigned long h_vdec,
set_param_write_sync(inst);
break;
- case SET_PARAM_PIC_INFO:
- set_param_pic_info(inst, in);
+ case SET_PARAM_PS_INFO:
+ set_param_ps_info(inst, in);
break;
case SET_PARAM_HDR_INFO:
set_param_hdr_info(inst, in);
break;
+
+ case SET_PARAM_POST_EVENT:
+ set_param_post_event(inst, in);
+ break;
default:
aml_vcodec_err(inst, "invalid set parameter type=%d", type);
ret = -EINVAL;
return ret;
}
-static void set_param_pic_info(struct vdec_mjpeg_inst *inst,
- struct aml_vdec_pic_infos *info)
+static void set_param_ps_info(struct vdec_mjpeg_inst *inst,
+ struct aml_vdec_ps_infos *ps)
{
pr_info("---%s, %d\n", __func__, __LINE__);
}
}
switch (type) {
- case SET_PARAM_PIC_INFO:
- set_param_pic_info(inst, in);
+ case SET_PARAM_PS_INFO:
+ set_param_ps_info(inst, in);
break;
default:
return ret;
}
-static void set_param_pic_info(struct vdec_mpeg12_inst *inst,
- struct aml_vdec_pic_infos *info)
+static void set_param_ps_info(struct vdec_mpeg12_inst *inst,
+ struct aml_vdec_ps_infos *ps)
{
pr_info("---%s, %d\n", __func__, __LINE__);
}
}
switch (type) {
- case SET_PARAM_PIC_INFO:
- set_param_pic_info(inst, in);
+ case SET_PARAM_PS_INFO:
+ set_param_ps_info(inst, in);
break;
default:
return ret;
}
-static void set_param_pic_info(struct vdec_mpeg4_inst *inst,
- struct aml_vdec_pic_infos *info)
+static void set_param_ps_info(struct vdec_mpeg4_inst *inst,
+ struct aml_vdec_ps_infos *ps)
{
pr_info("---%s, %d\n", __func__, __LINE__);
}
}
switch (type) {
- case SET_PARAM_PIC_INFO:
- set_param_pic_info(inst, in);
+ case SET_PARAM_PS_INFO:
+ set_param_ps_info(inst, in);
break;
default:
{
struct aml_vcodec_ctx *ctx = inst->ctx;
- if (!ctx->config.length) {
- ctx->config.type = V4L2_CONFIG_PARM_DECODE;
- ctx->config.parm.dec.double_write_mode = 16;
- inst->parms = ctx->config.parm.dec;
-
- ctx->config.length =
- vdec_config_default_parms(ctx->config.buf);
- } else {
+ if (ctx->config.parm.dec.parms_status &
+ V4L2_CONFIG_PARM_DECODE_CFGINFO) {
u8 *pbuf = ctx->config.buf;
- inst->parms = ctx->config.parm.dec;
pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
- inst->parms.buffer_margin);
+ ctx->config.parm.dec.cfg.ref_buf_margin);
pbuf += sprintf(pbuf, "vp9_double_write_mode:%d;",
- inst->parms.double_write_mode);
+ ctx->config.parm.dec.cfg.double_write_mode);
pbuf += sprintf(pbuf, "vp9_buf_width:%d;",
- inst->parms.buffer_width);
+ ctx->config.parm.dec.cfg.init_width);
pbuf += sprintf(pbuf, "vp9_buf_height:%d;",
- inst->parms.buffer_height);
- pbuf += sprintf(pbuf, "save_buffer_mode:%d;",
- inst->parms.buffer_mode);
+ ctx->config.parm.dec.cfg.init_height);
+ pbuf += sprintf(pbuf, "save_buffer_mode:0;");
pbuf += sprintf(pbuf, "no_head:0;");
-
- if ((ctx->config.parm.dec.dec_parms_status &
- V4L2_CONFIG_PARM_DECODE_HDRINFO) &&
- inst->parms.hdr.color_parms.present_flag) {
- pbuf += sprintf(pbuf, "mG.x:%d;",
- inst->parms.hdr.color_parms.primaries[0][0]);
- pbuf += sprintf(pbuf, "mG.y:%d;",
- inst->parms.hdr.color_parms.primaries[0][1]);
- pbuf += sprintf(pbuf, "mB.x:%d;",
- inst->parms.hdr.color_parms.primaries[1][0]);
- pbuf += sprintf(pbuf, "mB.y:%d;",
- inst->parms.hdr.color_parms.primaries[1][1]);
- pbuf += sprintf(pbuf, "mR.x:%d;",
- inst->parms.hdr.color_parms.primaries[2][0]);
- pbuf += sprintf(pbuf, "mR.y:%d;",
- inst->parms.hdr.color_parms.primaries[2][1]);
- pbuf += sprintf(pbuf, "mW.x:%d;",
- inst->parms.hdr.color_parms.white_point[0]);
- pbuf += sprintf(pbuf, "mW.y:%d;",
- inst->parms.hdr.color_parms.white_point[1]);
- pbuf += sprintf(pbuf, "mMaxDL:%d;",
- inst->parms.hdr.color_parms.luminance[0] / 1000);
- pbuf += sprintf(pbuf, "mMinDL:%d;",
- inst->parms.hdr.color_parms.luminance[1]);
- pbuf += sprintf(pbuf, "mMaxCLL:%d;",
- inst->parms.hdr.color_parms.content_light_level.max_content);
- pbuf += sprintf(pbuf, "mMaxFALL:%d;",
- inst->parms.hdr.color_parms.content_light_level.max_pic_average);
- }
-
ctx->config.length = pbuf - ctx->config.buf;
+ } else {
+ ctx->config.parm.dec.cfg.double_write_mode = 16;
+ ctx->config.length = vdec_config_default_parms(ctx->config.buf);
}
- inst->vdec.config = ctx->config;
+ if ((ctx->config.parm.dec.parms_status &
+ V4L2_CONFIG_PARM_DECODE_HDRINFO) &&
+ inst->parms.hdr.color_parms.present_flag) {
+ u8 *pbuf = ctx->config.buf + ctx->config.length;
+
+ pbuf += sprintf(pbuf, "mG.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[0][0]);
+ pbuf += sprintf(pbuf, "mG.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[0][1]);
+ pbuf += sprintf(pbuf, "mB.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[1][0]);
+ pbuf += sprintf(pbuf, "mB.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[1][1]);
+ pbuf += sprintf(pbuf, "mR.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[2][0]);
+ pbuf += sprintf(pbuf, "mR.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.primaries[2][1]);
+ pbuf += sprintf(pbuf, "mW.x:%d;",
+ ctx->config.parm.dec.hdr.color_parms.white_point[0]);
+ pbuf += sprintf(pbuf, "mW.y:%d;",
+ ctx->config.parm.dec.hdr.color_parms.white_point[1]);
+ pbuf += sprintf(pbuf, "mMaxDL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.luminance[0] / 1000);
+ pbuf += sprintf(pbuf, "mMinDL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.luminance[1]);
+ pbuf += sprintf(pbuf, "mMaxCLL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.content_light_level.max_content);
+ pbuf += sprintf(pbuf, "mMaxFALL:%d;",
+ ctx->config.parm.dec.hdr.color_parms.content_light_level.max_pic_average);
+ ctx->config.length = pbuf - ctx->config.buf;
+ inst->parms.hdr = ctx->config.parm.dec.hdr;
+ inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_HDRINFO;
+ }
- inst->parms.dec_parms_status |=
- V4L2_CONFIG_PARM_DECODE_COMMON;
+ inst->vdec.config = ctx->config;
+ inst->parms.cfg = ctx->config.parm.dec.cfg;
+ inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
}
static int vdec_vp9_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
/* init vfm */
inst->vfm.ctx = ctx;
inst->vfm.ada_ctx = &inst->vdec;
- vcodec_vfm_init(&inst->vfm);
+ ret = vcodec_vfm_init(&inst->vfm);
+ if (ret) {
+ pr_err("%s, init vfm failed.\n", __func__);
+ goto err;
+ }
/* probe info from the stream */
inst->vsi = kzalloc(sizeof(struct vdec_vp9_vsi), GFP_KERNEL);
if (!inst->vsi) {
ret = -ENOMEM;
- goto error_free_inst;
+ goto err;
}
/* alloc the header buffer to be used cache sps or spp etc.*/
inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
if (!inst->vsi) {
ret = -ENOMEM;
- goto error_free_vsi;
+ goto err;
}
init_completion(&inst->comp);
ret = video_decoder_init(&inst->vdec);
if (ret) {
aml_vcodec_err(inst, "vdec_vp9 init err=%d", ret);
- goto error_free_inst;
+ goto err;
}
//dump_init();
return 0;
-
-error_free_vsi:
- kfree(inst->vsi);
-error_free_inst:
- kfree(inst);
+err:
+ if (inst)
+ vcodec_vfm_release(&inst->vfm);
+ if (inst && inst->vsi && inst->vsi->header_buf)
+ kfree(inst->vsi->header_buf);
+ if (inst && inst->vsi)
+ kfree(inst->vsi);
+ if (inst)
+ kfree(inst);
*h_vdec = 0;
return ret;
static int vdec_get_dw_mode(struct vdec_vp9_inst *inst, int dw_mode)
{
- u32 valid_dw_mode = inst->parms.double_write_mode;
- int w = inst->parms.buffer_width;
- int h = inst->parms.buffer_height;
+ u32 valid_dw_mode = inst->parms.cfg.double_write_mode;
+ int w = inst->parms.cfg.init_width;
+ int h = inst->parms.cfg.init_height;
u32 dw = 0x1; /*1:1*/
switch (valid_dw_mode) {
struct vdec_pic_info *pic = &inst->vsi->pic;
struct vdec_vp9_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
- int dw = inst->parms.double_write_mode;
- int margin = inst->parms.buffer_margin;
+ int dw = inst->parms.cfg.double_write_mode;
+ int margin = inst->parms.cfg.ref_buf_margin;
/* fill visible area size that be used for EGL. */
pic->visible_width = vdec_pic_scale(inst, vp9_ctx->render_width, dw);
/* calc DPB size */
dec->dpb_sz = 5 + margin;//refer_buffer_num(sps->level_idc, poc_cnt, mb_w, mb_h);
- inst->parms.dec_parms_status |=
- V4L2_CONFIG_PARM_DECODE_PICINFO;
+ inst->parms.ps.visible_width = pic->visible_width;
+ inst->parms.ps.visible_height = pic->visible_height;
+ inst->parms.ps.coded_width = pic->coded_width;
+ inst->parms.ps.coded_height = pic->coded_height;
+ inst->parms.ps.dpb_size = dec->dpb_sz;
+ inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_PSINFO;
aml_vcodec_debug(inst, "[%d] The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n",
- inst->ctx->id, inst->parms.double_write_mode,
- pic->coded_width, pic->coded_height,
+ inst->ctx->id, dw, pic->coded_width, pic->coded_height,
pic->visible_width, pic->visible_height,
dec->dpb_sz - margin, margin);
}
static void get_param_config_info(struct vdec_vp9_inst *inst,
struct aml_dec_params *parms)
{
- *parms = inst->parms;
-
- aml_vcodec_debug(inst, "parms status: %u", parms->dec_parms_status);
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
+ parms->cfg = inst->parms.cfg;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
+ parms->ps = inst->parms.ps;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
+ parms->hdr = inst->parms.hdr;
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
+ parms->cnt = inst->parms.cnt;
+
+ parms->parms_status |= inst->parms.parms_status;
+
+ aml_vcodec_debug(inst, "parms status: %u", parms->parms_status);
}
static int vdec_vp9_get_param(unsigned long h_vdec,
complete(&inst->comp);
}
-static void set_param_pic_info(struct vdec_vp9_inst *inst,
- struct aml_vdec_pic_infos *info)
+static void set_param_ps_info(struct vdec_vp9_inst *inst,
+ struct aml_vdec_ps_infos *ps)
{
struct vdec_pic_info *pic = &inst->vsi->pic;
struct vdec_vp9_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
/* fill visible area size that be used for EGL. */
- pic->visible_width = info->visible_width;
- pic->visible_height = info->visible_height;
+ pic->visible_width = ps->visible_width;
+ pic->visible_height = ps->visible_height;
/* calc visible ares. */
rect->left = 0;
rect->height = pic->visible_height;
/* config canvas size that be used for decoder. */
- pic->coded_width = info->coded_width;
- pic->coded_height = info->coded_height;
+ pic->coded_width = ps->coded_width;
+ pic->coded_height = ps->coded_height;
pic->y_len_sz = pic->coded_width * pic->coded_height;
pic->c_len_sz = pic->y_len_sz >> 1;
/* calc DPB size */
- dec->dpb_sz = 5;
+ dec->dpb_sz = 5;
- inst->parms.dec_parms_status |=
- V4L2_CONFIG_PARM_DECODE_PICINFO;
+ inst->parms.ps = *ps;
+ inst->parms.parms_status |=
+ V4L2_CONFIG_PARM_DECODE_PSINFO;
/*wake up*/
complete(&inst->comp);
pr_info("Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
- info->visible_width, info->visible_height,
- info->coded_width, info->coded_height,
- info->dpb_size);
+ ps->visible_width, ps->visible_height,
+ ps->coded_width, ps->coded_height,
+ ps->dpb_size);
}
static void set_param_hdr_info(struct vdec_vp9_inst *inst,
struct aml_vdec_hdr_infos *hdr)
{
- inst->parms.hdr = *hdr;
- inst->parms.dec_parms_status |=
- V4L2_CONFIG_PARM_DECODE_HDRINFO;
+ if ((inst->parms.parms_status &
+ V4L2_CONFIG_PARM_DECODE_HDRINFO)) {
+ inst->parms.hdr = *hdr;
+ inst->parms.parms_status |=
+ V4L2_CONFIG_PARM_DECODE_HDRINFO;
+ aml_vdec_dispatch_event(inst->ctx,
+ V4L2_EVENT_SRC_CH_HDRINFO);
+ pr_info("VP9 set HDR infos\n");
+ }
+}
- //pr_info("VP9 set HDR infos\n");
+static void set_param_post_event(struct vdec_vp9_inst *inst, u32 *event)
+{
+ aml_vdec_dispatch_event(inst->ctx, *event);
+ pr_info("VP9 post event: %d\n", *event);
}
static int vdec_vp9_set_param(unsigned long h_vdec,
set_param_write_sync(inst);
break;
- case SET_PARAM_PIC_INFO:
- set_param_pic_info(inst, in);
+ case SET_PARAM_PS_INFO:
+ set_param_ps_info(inst, in);
break;
case SET_PARAM_HDR_INFO:
set_param_hdr_info(inst, in);
break;
+
+ case SET_PARAM_POST_EVENT:
+ set_param_post_event(inst, in);
+ break;
default:
aml_vcodec_err(inst, "invalid set parameter type=%d", type);
ret = -EINVAL;
};
/*
- * SET_PARAM_PIC_INFO : set picture info, data parsed from ucode.
+ * SET_PARAM_PS_INFO : set picture parms, data parsed from ucode.
*/
enum vdec_set_param_type {
SET_PARAM_WRITE_FRAME_SYNC,
- SET_PARAM_PIC_INFO,
- SET_PARAM_HDR_INFO
+ SET_PARAM_PS_INFO,
+ SET_PARAM_HDR_INFO,
+ SET_PARAM_POST_EVENT
};
/**
{
struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- struct vframe_s *vf = NULL;
+ struct vframe_s *vf = &hw->vframe_dummy;
+ struct vdec_v4l2_buffer *fb = NULL;
int index = INVALID_IDX;
ulong expires;
if (hw->is_used_v4l && hw->eos) {
- if (kfifo_get(&hw->newframe_q, &vf) == 0 || vf == NULL) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "%s fatal error, no available buffer slot.\n",
- __func__);
- return -1;
- }
-
expires = jiffies + msecs_to_jiffies(2000);
while (INVALID_IDX == (index = get_free_buf_idx(vdec))) {
if (time_after(jiffies, expires))
}
if (index == INVALID_IDX) {
- pr_err("[%d] EOS get free buff fail.\n", ctx->id);
- return -1;
+ if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb) < 0) {
+ pr_err("[%d] EOS get free buff fail.\n", ctx->id);
+ return -1;
+ }
}
vf->type |= VIDTYPE_V4L_EOS;
vf->timestamp = ULONG_MAX;
- vf->v4l_mem_handle = hw->buffer_spec[index].cma_alloc_addr;
vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
+ vf->v4l_mem_handle = (index == INVALID_IDX) ? (ulong)fb :
+ hw->buffer_spec[index].cma_alloc_addr;
kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
- struct aml_vdec_pic_infos info;
+ struct aml_vdec_ps_infos ps;
- info.visible_width = hw->frame_width;
- info.visible_height = hw->frame_height;
- info.coded_width = ALIGN(hw->frame_width, 64);
- info.coded_height = ALIGN(hw->frame_height, 64);
- info.dpb_size = hw->dpb.mDPB.size;
+ ps.visible_width = hw->frame_width;
+ ps.visible_height = hw->frame_height;
+ ps.coded_width = ALIGN(hw->frame_width, 64);
+ ps.coded_height = ALIGN(hw->frame_height, 64);
+ ps.dpb_size = hw->dpb.mDPB.size;
hw->v4l_params_parsed = true;
- vdec_v4l_set_pic_infos(ctx, &info);
+ vdec_v4l_set_ps_infos(ctx, &ps);
}
}
get_used_buf_count(hw) >=
run_ready_max_buf_num)
ret = 0;
-
- if (hw->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- if (ctx->param_sets_from_ucode &&
- !ctx->v4l_codec_ready &&
- hw->v4l_params_parsed) {
- ret = 0; /*the params has parsed.*/
- } else if (!ctx->v4l_codec_dpb_ready)
- ret = 0;
- }
}
#endif
+ if (hw->is_used_v4l) {
+ struct aml_vcodec_ctx *ctx =
+ (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
+
+ if (ctx->param_sets_from_ucode &&
+ !ctx->v4l_codec_ready &&
+ hw->v4l_params_parsed) {
+ ret = 0; /*the params has parsed.*/
+ } else if (!ctx->v4l_codec_dpb_ready)
+ ret = 0;
+ }
+
if (ret)
not_run_ready[DECODE_ID(hw)] = 0;
else
{
struct hevc_state_s *hw = (struct hevc_state_s *)vdec->private;
struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- struct vframe_s *vf = NULL;
+ struct vframe_s *vf = &hw->vframe_dummy;
+ struct vdec_v4l2_buffer *fb = NULL;
int index = INVALID_IDX;
ulong expires;
if (hw->is_used_v4l && hw->eos) {
- if (kfifo_get(&hw->newframe_q, &vf) == 0 || vf == NULL) {
- hevc_print(hw, 0,
- "%s fatal error, no available buffer slot.\n",
- __func__);
- return -1;
- }
-
expires = jiffies + msecs_to_jiffies(2000);
while (INVALID_IDX == (index = get_free_buf_idx(hw))) {
if (time_after(jiffies, expires))
}
if (index == INVALID_IDX) {
- pr_err("[%d] EOS get free buff fail.\n", ctx->id);
- return -1;
+ if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb) < 0) {
+ pr_err("[%d] EOS get free buff fail.\n", ctx->id);
+ return -1;
+ }
}
vf->type |= VIDTYPE_V4L_EOS;
vf->timestamp = ULONG_MAX;
- vf->v4l_mem_handle = hw->m_BUF[index].v4l_ref_buf_addr;
vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
-
+ vf->v4l_mem_handle = (index == INVALID_IDX) ? (ulong)fb :
+ hw->m_BUF[index].v4l_ref_buf_addr;
kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
vf_notify_receiver(vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
(struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
if (ctx->param_sets_from_ucode && !hevc->v4l_params_parsed) {
- struct aml_vdec_pic_infos info;
+ struct aml_vdec_ps_infos ps;
hevc->frame_width = hevc->param.p.pic_width_in_luma_samples;
hevc->frame_height = hevc->param.p.pic_height_in_luma_samples;
- info.visible_width = hevc->frame_width;
- info.visible_height = hevc->frame_height;
- info.coded_width = ALIGN(hevc->frame_width, 32);
- info.coded_height = ALIGN(hevc->frame_height, 32);
- info.dpb_size = get_work_pic_num(hevc);
+ ps.visible_width = hevc->frame_width;
+ ps.visible_height = hevc->frame_height;
+ ps.coded_width = ALIGN(hevc->frame_width, 32);
+ ps.coded_height = ALIGN(hevc->frame_height, 32);
+ ps.dpb_size = get_work_pic_num(hevc);
hevc->v4l_params_parsed = true;
/*notice the v4l2 codec.*/
- vdec_v4l_set_pic_infos(ctx, &info);
+ vdec_v4l_set_ps_infos(ctx, &ps);
}
}
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
- struct aml_vdec_pic_infos info;
+ struct aml_vdec_ps_infos ps;
- info.visible_width = hw->frame_width;
- info.visible_height = hw->frame_height;
- info.coded_width = ALIGN(hw->frame_width, 64);
- info.coded_height = ALIGN(hw->frame_height, 64);
- info.dpb_size = MAX_BMMU_BUFFER_NUM - 1;
+ ps.visible_width = hw->frame_width;
+ ps.visible_height = hw->frame_height;
+ ps.coded_width = ALIGN(hw->frame_width, 64);
+ ps.coded_height = ALIGN(hw->frame_height, 64);
+ ps.dpb_size = MAX_BMMU_BUFFER_NUM - 1;
hw->v4l_params_parsed = true;
- vdec_v4l_set_pic_infos(ctx, &info);
+ vdec_v4l_set_ps_infos(ctx, &ps);
}
if (!ctx->v4l_codec_ready)
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
- struct aml_vdec_pic_infos info;
+ struct aml_vdec_ps_infos ps;
- info.visible_width = hw->frame_width;
- info.visible_height = hw->frame_height;
- info.coded_width = ALIGN(hw->frame_width, 64);
- info.coded_height = ALIGN(hw->frame_height, 64);
- info.dpb_size = MAX_BMMU_BUFFER_NUM - 1;
+ ps.visible_width = hw->frame_width;
+ ps.visible_height = hw->frame_height;
+ ps.coded_width = ALIGN(hw->frame_width, 64);
+ ps.coded_height = ALIGN(hw->frame_height, 64);
+ ps.dpb_size = MAX_BMMU_BUFFER_NUM - 1;
hw->v4l_params_parsed = true;
- vdec_v4l_set_pic_infos(ctx, &info);
+ vdec_v4l_set_ps_infos(ctx, &ps);
}
if (!ctx->v4l_codec_ready)
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
- struct aml_vdec_pic_infos info;
+ struct aml_vdec_ps_infos ps;
- info.visible_width = hw->frame_width;
- info.visible_height = hw->frame_height;
- info.coded_width = ALIGN(hw->frame_width, 64);
- info.coded_height = ALIGN(hw->frame_height, 64);
- info.dpb_size = MAX_BMMU_BUFFER_NUM - 1;
+ ps.visible_width = hw->frame_width;
+ ps.visible_height = hw->frame_height;
+ ps.coded_width = ALIGN(hw->frame_width, 64);
+ ps.coded_height = ALIGN(hw->frame_height, 64);
+ ps.dpb_size = MAX_BMMU_BUFFER_NUM - 1;
hw->v4l_params_parsed = true;
- vdec_v4l_set_pic_infos(ctx, &info);
+ vdec_v4l_set_ps_infos(ctx, &ps);
}
if (!ctx->v4l_codec_ready)
}
EXPORT_SYMBOL(vdec_v4l_get_buffer);
-int vdec_v4l_set_pic_infos(struct aml_vcodec_ctx *ctx,
- struct aml_vdec_pic_infos *info)
+int vdec_v4l_set_ps_infos(struct aml_vcodec_ctx *ctx,
+ struct aml_vdec_ps_infos *ps)
{
int ret = 0;
return -EIO;
ret = ctx->dec_if->set_param(ctx->drv_handle,
- SET_PARAM_PIC_INFO, info);
+ SET_PARAM_PS_INFO, ps);
return ret;
}
-EXPORT_SYMBOL(vdec_v4l_set_pic_infos);
+EXPORT_SYMBOL(vdec_v4l_set_ps_infos);
int vdec_v4l_set_hdr_infos(struct aml_vcodec_ctx *ctx,
struct aml_vdec_hdr_infos *hdr)
}
EXPORT_SYMBOL(vdec_v4l_set_hdr_infos);
+int vdec_v4l_post_evet(struct aml_vcodec_ctx *ctx, u32 event)
+{
+ int ret = 0;
+
+ if (ctx->drv_handle == 0)
+ return -EIO;
+
+ ret = ctx->dec_if->set_param(ctx->drv_handle,
+ SET_PARAM_POST_EVENT, &event);
+
+ return ret;
+}
+EXPORT_SYMBOL(vdec_v4l_post_evet);
+
int vdec_v4l_write_frame_sync(struct aml_vcodec_ctx *ctx)
{
int ret = 0;
struct aml_vcodec_ctx *ctx,
struct vdec_v4l2_buffer **out);
-int vdec_v4l_set_pic_infos(
+int vdec_v4l_set_ps_infos(
struct aml_vcodec_ctx *ctx,
- struct aml_vdec_pic_infos *info);
+ struct aml_vdec_ps_infos *ps);
int vdec_v4l_set_hdr_infos(
struct aml_vcodec_ctx *ctx,
int vdec_v4l_write_frame_sync(
struct aml_vcodec_ctx *ctx);
+int vdec_v4l_post_evet(
+ struct aml_vcodec_ctx *ctx,
+ u32 event);
+
#endif
struct vframe_qos_s vframe_qos;
u32 mem_map_mode;
u32 dynamic_buf_num_margin;
+ struct vframe_s vframe_dummy;
};
static int vp9_print(struct VP9Decoder_s *pbi,
struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)op_arg;
uint8_t index = vf->index & 0xff;
+ if (vf == (&pbi->vframe_dummy))
+ return;
+
kfifo_put(&pbi->newframe_q, (const struct vframe_s *)vf);
pbi->vf_put_count++;
if (index < pbi->used_buf_num) {
{
struct VP9Decoder_s *hw = (struct VP9Decoder_s *)vdec->private;
struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- struct vframe_s *vf = NULL;
+ struct vframe_s *vf = &hw->vframe_dummy;
+ struct vdec_v4l2_buffer *fb = NULL;
int index = INVALID_IDX;
ulong expires;
if (hw->is_used_v4l && hw->eos) {
- if (kfifo_get(&hw->newframe_q, &vf) == 0 || vf == NULL) {
- vp9_print(hw, 0,
- "%s fatal error, no available buffer slot.\n",
- __func__);
- return -1;
- }
-
expires = jiffies + msecs_to_jiffies(2000);
while (INVALID_IDX == (index = get_free_fb(hw))) {
if (time_after(jiffies, expires))
}
if (index == INVALID_IDX) {
- pr_err("[%d] EOS get free buff fail.\n", ctx->id);
- return -1;
+ if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb) < 0) {
+ pr_err("[%d] EOS get free buff fail.\n", ctx->id);
+ return -1;
+ }
}
vf->type |= VIDTYPE_V4L_EOS;
vf->timestamp = ULONG_MAX;
- vf->v4l_mem_handle = hw->m_BUF[index].v4l_ref_buf_addr;
vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
+ vf->v4l_mem_handle = (index == INVALID_IDX) ? (ulong)fb :
+ hw->m_BUF[index].v4l_ref_buf_addr;
kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
vf_notify_receiver(vdec->vf_provider_name,
pbi->frame_width = vp9_param.p.width;
pbi->frame_height = vp9_param.p.height;
if (ctx->param_sets_from_ucode && !pbi->v4l_params_parsed) {
- struct aml_vdec_pic_infos info;
+ struct aml_vdec_ps_infos ps;
- info.visible_width = pbi->frame_width;
- info.visible_height = pbi->frame_height;
- info.coded_width = ALIGN(pbi->frame_width, 32);
- info.coded_height = ALIGN(pbi->frame_height, 32);
- info.dpb_size = pbi->used_buf_num;
+ ps.visible_width = pbi->frame_width;
+ ps.visible_height = pbi->frame_height;
+ ps.coded_width = ALIGN(pbi->frame_width, 32);
+ ps.coded_height = ALIGN(pbi->frame_height, 32);
+ ps.dpb_size = pbi->used_buf_num;
pbi->v4l_params_parsed = true;
- vdec_v4l_set_pic_infos(ctx, &info);
+ vdec_v4l_set_ps_infos(ctx, &ps);
}
}