summaryrefslogtreecommitdiff
authorNanxin Qin <nanxin.qin@amlogic.com>2019-12-07 13:46:08 (GMT)
committer Zhi Zhou <zhi.zhou@amlogic.com>2019-12-13 05:16:44 (GMT)
commitb9ff72330f14078663592bcb8566458402d171e2 (patch)
treef0b5bfbbde49bd2a65c10fbb8c3de23758a8eae3
parent6f50ab2c41d54ce523986400245488368b5d6201 (diff)
downloadmedia_modules-b9ff72330f14078663592bcb8566458402d171e2.zip
media_modules-b9ff72330f14078663592bcb8566458402d171e2.tar.gz
media_modules-b9ff72330f14078663592bcb8566458402d171e2.tar.bz2
v4l: fixed the issue of mosaic shows when seeking. [1/1]
PD#SWPL-18134 Problem: playback youtube 4k videos, the automatically switched resolution or seek operation,Display abnormal. Solution: fixed the issue of mosaic shows when seeking or resolution change. Verify: u212 Change-Id: I9654fdbba7711c76dfcee4b999f63ee8ed12899d Signed-off-by: Nanxin Qin <nanxin.qin@amlogic.com>
Diffstat
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.c2
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.c27
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.h2
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec_drv.c30
-rw-r--r--drivers/amvdec_ports/aml_vcodec_drv.h19
-rw-r--r--drivers/amvdec_ports/decoder/vdec_h264_if.c1
-rw-r--r--drivers/amvdec_ports/decoder/vdec_hevc_if.c1
-rw-r--r--drivers/amvdec_ports/decoder/vdec_vp9_if.c1
-rw-r--r--drivers/frame_provider/decoder/h264_multi/vmh264.c12
-rw-r--r--drivers/frame_provider/decoder/h265/vh265.c183
-rw-r--r--drivers/frame_provider/decoder/utils/vdec.c2
-rw-r--r--drivers/frame_provider/decoder/vp9/vvp9.c94
12 files changed, 288 insertions, 86 deletions
diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.c b/drivers/amvdec_ports/aml_vcodec_adapt.c
index f7293f6..9e4658b 100644
--- a/drivers/amvdec_ports/aml_vcodec_adapt.c
+++ b/drivers/amvdec_ports/aml_vcodec_adapt.c
@@ -669,7 +669,7 @@ bool vdec_input_full(struct aml_vdec_adapt *ada_ctx)
{
struct vdec_s *vdec = ada_ctx->vdec;
- return (vdec->input.have_frame_num > 60) ? true : false;
+ return (vdec->input.have_frame_num > 600) ? true : false;
}
int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx,
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c
index 6989153..f773031 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec.c
@@ -337,7 +337,7 @@ int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_
pfb->mem_type = VDEC_SCATTER_MEMORY_TYPE;
pfb->status = FB_ST_NORMAL;
} else if (dst_buf->num_planes == 1) {
- pfb = &dst_buf_info->frame_buffer;
+ pfb = &dst_buf_info->frame_buffer;
pfb->m.mem[0].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
pfb->m.mem[0].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr);
pfb->m.mem[0].size = ctx->picinfo.y_len_sz + ctx->picinfo.c_len_sz;
@@ -399,6 +399,8 @@ int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_
info = container_of(pfb, struct aml_video_dec_buf, frame_buffer);
+ ctx->cap_pool.seq[ctx->cap_pool.out++] =
+ (V4L_CAP_BUFF_IN_DEC << 16 | dst_buf->index);
v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
aml_vcodec_ctx_unlock(ctx, flags);
@@ -511,6 +513,7 @@ void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *f
/* make the run to stanby until new buffs to enque. */
ctx->v4l_codec_dpb_ready = false;
+ ctx->reset_flag = V4L_RESET_MODE_LIGHT;
/*
* After all buffers containing decoded frames from
@@ -1179,8 +1182,7 @@ static int vidioc_vdec_dqbuf(struct file *file, void *priv,
aml_buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
file = fget(vb2_v4l2->private);
- if (is_v4l2_buf_file(file) &&
- !aml_buf->is_install_privdata) {
+ if (is_v4l2_buf_file(file)) {
dmabuf_fd_install_data(vb2_v4l2->private,
(void*)&aml_buf->privdata,
sizeof(struct file_private_data));
@@ -1720,15 +1722,23 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
__func__, __LINE__, buf->frame_buffer.m.mem[0].addr,
buf->frame_buffer.vf_handle, buf->frame_buffer.status);
+ if (vb->index >= ctx->dpb_size) {
+ aml_v4l2_debug(2, "[%d] enque capture buf idx %d is invalid.",
+ ctx->id, vb->index);
+ return;
+ }
+
if (!buf->que_in_m2m) {
- aml_v4l2_debug(2, "[%d] enque capture buf idx %d, %p",
- ctx->id, vb->index, vb);
+ aml_v4l2_debug(2, "[%d] enque capture buf idx %d, vf: %p",
+ ctx->id, vb->index, v4l_get_vf_handle(vb2_v4l2->private));
v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
buf->que_in_m2m = true;
buf->queued_in_vb2 = true;
buf->queued_in_v4l2 = true;
buf->ready_to_display = false;
+ ctx->cap_pool.seq[ctx->cap_pool.in++] =
+ (V4L_CAP_BUFF_IN_M2M << 16 | vb->index);
/* check dpb ready */
aml_check_dpb_ready(ctx);
@@ -1950,12 +1960,15 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
while ((vb2_v4l2 = v4l2_m2m_src_buf_remove(ctx->m2m_ctx)))
v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
} else {
+ /* stop decoder. */
+ wait_vcodec_ending(ctx);
+
for (i = 0; i < q->num_buffers; ++i) {
vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]);
buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
buf->frame_buffer.status = FB_ST_NORMAL;
buf->que_in_m2m = false;
- buf->is_install_privdata = false;
+ ctx->cap_pool.seq[i] = 0;
if (vb2_v4l2->vb2_buf.state == VB2_BUF_STATE_ACTIVE)
v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
@@ -1965,6 +1978,8 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
}
}
ctx->buf_used_count = 0;
+ ctx->cap_pool.in = 0;
+ ctx->cap_pool.out = 0;
}
static void m2mops_vdec_device_run(void *priv)
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.h b/drivers/amvdec_ports/aml_vcodec_dec.h
index 765b788..68f878a 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.h
+++ b/drivers/amvdec_ports/aml_vcodec_dec.h
@@ -94,7 +94,6 @@ struct aml_video_dec_buf {
bool queued_in_v4l2;
bool lastframe;
bool error;
- bool is_install_privdata;
};
extern const struct v4l2_ioctl_ops aml_vdec_ioctl_ops;
@@ -123,5 +122,6 @@ 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);
+void* v4l_get_vf_handle(int fd);
#endif /* _AML_VCODEC_DEC_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_dec_drv.c b/drivers/amvdec_ports/aml_vcodec_dec_drv.c
index d35d738..43ff0c5 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec_drv.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec_drv.c
@@ -269,6 +269,36 @@ int dmabuf_fd_install_data(int fd, void* data, u32 size)
return 0;
}
+void* v4l_get_vf_handle(int fd)
+{
+ struct file *file;
+ struct file_private_data *data = NULL;
+ void *vf_handle = 0;
+
+ file = fget(fd);
+
+ if (!file) {
+ pr_err("%s: fget fd %d fail!, comm %s, pid %d\n",
+ __func__, fd, current->comm, current->pid);
+ return NULL;
+ }
+
+ if (!is_v4l2_buf_file(file)) {
+ fput(file);
+ pr_err("%s the buf file checked fail!\n", __func__);
+ return NULL;
+ }
+
+ data = (struct file_private_data*) file->private_data;
+ if (data)
+ vf_handle = &data->vf;
+
+ fput(file);
+
+ return vf_handle;
+}
+
+
static long v4l2_vcodec_ioctl(struct file *file,
unsigned int cmd,
ulong arg)
diff --git a/drivers/amvdec_ports/aml_vcodec_drv.h b/drivers/amvdec_ports/aml_vcodec_drv.h
index eff017f..1baec44 100644
--- a/drivers/amvdec_ports/aml_vcodec_drv.h
+++ b/drivers/amvdec_ports/aml_vcodec_drv.h
@@ -58,7 +58,15 @@
#define V4L2_EVENT_REQUEST_RESET (1 << 8)
#define V4L2_EVENT_REQUEST_EXIT (1 << 9)
+/* v4l buffer pool */
+#define V4L_CAP_BUFF_MAX (32)
+#define V4L_CAP_BUFF_INVALID (0)
+#define V4L_CAP_BUFF_IN_M2M (1)
+#define V4L_CAP_BUFF_IN_DEC (2)
+/* v4l reset mode */
+#define V4L_RESET_MODE_NORMAL (1 << 0) /* reset vdec_input and decoder. */
+#define V4L_RESET_MODE_LIGHT (1 << 1) /* just only reset decoder. */
/**
* enum aml_hw_reg_idx - AML hw register base index
@@ -330,6 +338,15 @@ struct v4l2_config_parm {
u8 buf[4096];
};
+struct v4l_buff_pool {
+ /*
+ * bit 31-16: buffer state
+ * bit 15- 0: buffer index
+ */
+ u32 seq[V4L_CAP_BUFF_MAX];
+ u32 in, out;
+};
+
enum aml_thread_type {
AML_THREAD_OUTPUT,
AML_THREAD_CAPTURE,
@@ -445,6 +462,8 @@ struct aml_vcodec_ctx {
bool is_stream_off;
int reset_flag;
int stop_cmd;
+ u32 display_count;
+ struct v4l_buff_pool cap_pool;
};
/**
diff --git a/drivers/amvdec_ports/decoder/vdec_h264_if.c b/drivers/amvdec_ports/decoder/vdec_h264_if.c
index 8a740c5..eada4ea 100644
--- a/drivers/amvdec_ports/decoder/vdec_h264_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_h264_if.c
@@ -279,6 +279,7 @@ static void vdec_parser_parms(struct vdec_h264_inst *inst)
ctx->config.length = pbuf - ctx->config.buf;
} else {
ctx->config.parm.dec.cfg.double_write_mode = 16;
+ ctx->config.parm.dec.cfg.ref_buf_margin = 7;
ctx->config.length = vdec_config_default_parms(ctx->config.buf);
}
diff --git a/drivers/amvdec_ports/decoder/vdec_hevc_if.c b/drivers/amvdec_ports/decoder/vdec_hevc_if.c
index 3d7e76e..cd4d361 100644
--- a/drivers/amvdec_ports/decoder/vdec_hevc_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_hevc_if.c
@@ -185,6 +185,7 @@ static void vdec_parser_parms(struct vdec_hevc_inst *inst)
ctx->config.length = pbuf - ctx->config.buf;
} else {
ctx->config.parm.dec.cfg.double_write_mode = 16;
+ ctx->config.parm.dec.cfg.ref_buf_margin = 7;
ctx->config.length = vdec_config_default_parms(ctx->config.buf);
}
diff --git a/drivers/amvdec_ports/decoder/vdec_vp9_if.c b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
index 106dc5e..950894f 100644
--- a/drivers/amvdec_ports/decoder/vdec_vp9_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
@@ -202,6 +202,7 @@ static void vdec_parser_parms(struct vdec_vp9_inst *inst)
ctx->config.length = pbuf - ctx->config.buf;
} else {
ctx->config.parm.dec.cfg.double_write_mode = 16;
+ ctx->config.parm.dec.cfg.ref_buf_margin = 7;
ctx->config.length = vdec_config_default_parms(ctx->config.buf);
}
diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c
index 144cd9f..1038076 100644
--- a/drivers/frame_provider/decoder/h264_multi/vmh264.c
+++ b/drivers/frame_provider/decoder/h264_multi/vmh264.c
@@ -61,6 +61,7 @@
#include "../../../common/chips/decoder_cpu_ver_info.h"
#include "../utils/vdec_v4l2_buffer_ops.h"
#include <linux/crc32.h>
+#include <media/v4l2-mem2mem.h>
#undef pr_info
#define pr_info printk
@@ -159,6 +160,8 @@ static u32 run_ready_display_q_num;
static u32 run_ready_max_buf_num = 0xff;
#endif
+static u32 run_ready_min_buf_num = 2;
+
#define VDEC_ASSIST_CANVAS_BLK32 0x5
@@ -8210,10 +8213,11 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
!ctx->v4l_codec_ready &&
hw->v4l_params_parsed) {
ret = 0; /*the params has parsed.*/
- } else if (!ctx->v4l_codec_dpb_ready)
- ret = 0;
- else if (hw->wait_reset_done_flag)
- ret = 0;
+ } else if (!ctx->v4l_codec_dpb_ready) {
+ if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) <
+ run_ready_min_buf_num)
+ ret = 0;
+ }
}
if (ret)
diff --git a/drivers/frame_provider/decoder/h265/vh265.c b/drivers/frame_provider/decoder/h265/vh265.c
index 714ae42..320457d 100644
--- a/drivers/frame_provider/decoder/h265/vh265.c
+++ b/drivers/frame_provider/decoder/h265/vh265.c
@@ -47,6 +47,7 @@
#include "../utils/firmware.h"
#include "../../../common/chips/decoder_cpu_ver_info.h"
#include "../utils/vdec_v4l2_buffer_ops.h"
+#include <media/v4l2-mem2mem.h>
#define CONSTRAIN_MAX_BUF_NUM
@@ -183,6 +184,8 @@ static int start_decode_buf_level = 0x8000;
static unsigned int decode_timeout_val = 200;
+static u32 run_ready_min_buf_num = 2;
+
/*data_resend_policy:
bit 0, stream base resend data when decoding buf empty
*/
@@ -2150,7 +2153,7 @@ static void hevc_init_stru(struct hevc_state_s *hevc,
for (i = 0; i < MAX_REF_PIC_NUM; i++) {
if (hevc->m_PIC[i] != NULL) {
memset(hevc->m_PIC[i], 0 ,sizeof(struct PIC_s));
- hevc->m_PIC[i]->index = -1;
+ hevc->m_PIC[i]->index = i;
}
}
}
@@ -3051,10 +3054,10 @@ static int cal_current_buf_size(struct hevc_state_s *hevc,
return buf_size;
}
-static int v4l_alloc_buf(struct hevc_state_s *hevc)
+static int v4l_alloc_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
{
- int i;
int ret = -1;
+ int i = pic->index;
struct vdec_v4l2_buffer *fb = NULL;
if (hevc->fatal_error & DECODER_FATAL_ERROR_NO_MEM)
@@ -3067,10 +3070,6 @@ static int v4l_alloc_buf(struct hevc_state_s *hevc)
return ret;
}
- for (i = 0; i < BUF_POOL_SIZE; i++)
- if (hevc->m_BUF[i].start_adr == 0)
- break;
-
if (hevc->mmu_enable) {
if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
(IS_8K_SIZE(hevc->pic_w, hevc->pic_h)))
@@ -3091,8 +3090,9 @@ static int v4l_alloc_buf(struct hevc_state_s *hevc)
}
}
- hevc->m_BUF[i].used_flag = 0;
- hevc->m_BUF[i].v4l_ref_buf_addr = (ulong)fb;
+ hevc->m_BUF[i].used_flag = 0;
+ hevc->m_BUF[i].v4l_ref_buf_addr = (ulong)fb;
+ pic->cma_alloc_addr = hevc->m_BUF[i].v4l_ref_buf_addr;
if (fb->num_planes == 1) {
hevc->m_BUF[i].start_adr = fb->m.mem[0].addr;
hevc->m_BUF[i].size = fb->m.mem[0].size;
@@ -3316,20 +3316,9 @@ static int get_alloc_pic_count(struct hevc_state_s *hevc)
static int v4l_config_pic(struct hevc_state_s *hevc, struct PIC_s *pic)
{
- int i;
+ int i = pic->index;
int dw_mode = get_double_write_mode(hevc);
- for (i = 0; i < BUF_POOL_SIZE; i++) {
- if (hevc->m_BUF[i].start_adr != 0 &&
- hevc->m_BUF[i].used_flag == 0) {
- hevc->m_BUF[i].used_flag = 1;
- break;
- }
- }
-
- if (i >= BUF_POOL_SIZE)
- return -1;
-
if (hevc->mmu_enable)
pic->header_adr = hevc->m_BUF[i].header_addr;
@@ -5580,20 +5569,14 @@ static struct PIC_s *get_new_pic(struct hevc_state_s *hevc,
return NULL;
if (new_pic->BUF_index < 0) {
- ret = hevc->is_used_v4l ?
- v4l_alloc_buf(hevc) :
- alloc_buf(hevc);
- if (ret < 0)
- return NULL;
-
- ret = hevc->is_used_v4l ?
- v4l_config_pic(hevc, new_pic) :
- config_pic(hevc, new_pic);
- if (ret < 0) {
- dealloc_pic_buf(hevc, new_pic);
+ if (alloc_buf(hevc) < 0)
return NULL;
+ else {
+ if (config_pic(hevc, new_pic) < 0) {
+ dealloc_pic_buf(hevc, new_pic);
+ return NULL;
+ }
}
-
new_pic->width = hevc->pic_w;
new_pic->height = hevc->pic_h;
set_canvas(hevc, new_pic);
@@ -5682,6 +5665,124 @@ static struct PIC_s *get_new_pic(struct hevc_state_s *hevc,
return new_pic;
}
+static struct PIC_s *v4l_get_new_pic(struct hevc_state_s *hevc,
+ union param_u *rpm_param)
+{
+ int ret;
+ int used_buf_num = get_work_pic_num(hevc);
+ struct aml_vcodec_ctx * v4l = hevc->v4l2_ctx;
+ struct PIC_s *new_pic = NULL;
+ struct PIC_s *pic = NULL;
+ int i;
+
+ for (i = 0; i < used_buf_num; ++i) {
+ struct v4l_buff_pool *pool = &v4l->cap_pool;
+ u32 state = (pool->seq[i] >> 16);
+ u32 index = (pool->seq[i] & 0xffff);
+
+ switch (state) {
+ case V4L_CAP_BUFF_IN_DEC:
+ pic = hevc->m_PIC[i];
+ if (pic && (pic->index != -1) &&
+ (pic->output_mark == 0) &&
+ (pic->referenced == 0) &&
+ (pic->output_ready == 0) &&
+ (pic->width == hevc->pic_w) &&
+ (pic->height == hevc->pic_h) &&
+ pic->cma_alloc_addr) {
+ new_pic = pic;
+ }
+ break;
+ case V4L_CAP_BUFF_IN_M2M:
+ pic = hevc->m_PIC[index];
+ pic->width = hevc->pic_w;
+ pic->height = hevc->pic_h;
+ if ((pic->index != -1) &&
+ !v4l_alloc_buf(hevc, pic)) {
+ v4l_config_pic(hevc, pic);
+ init_pic_list_hw(hevc);
+ new_pic = pic;
+ }
+ break;
+ default:
+ pr_err("v4l buffer state err %d.\n", state);
+ break;
+ }
+
+ if (new_pic)
+ break;
+ }
+
+ if (new_pic == NULL)
+ return NULL;
+
+ new_pic->double_write_mode = get_double_write_mode(hevc);
+ if (new_pic->double_write_mode)
+ set_canvas(hevc, new_pic);
+
+ if (get_mv_buf(hevc, new_pic) < 0)
+ return NULL;
+
+ if (hevc->mmu_enable) {
+ ret = H265_alloc_mmu(hevc, new_pic,
+ rpm_param->p.bit_depth,
+ hevc->frame_mmu_map_addr);
+ if (ret != 0) {
+ put_mv_buf(hevc, new_pic);
+ hevc_print(hevc, 0,
+ "can't alloc need mmu1,idx %d ret =%d\n",
+ new_pic->decode_idx, ret);
+ return NULL;
+ }
+ }
+
+ new_pic->referenced = 1;
+ new_pic->decode_idx = hevc->decode_idx;
+ new_pic->slice_idx = 0;
+ new_pic->referenced = 1;
+ new_pic->output_mark = 0;
+ new_pic->recon_mark = 0;
+ new_pic->error_mark = 0;
+ new_pic->dis_mark = 0;
+ /* new_pic->output_ready = 0; */
+ new_pic->num_reorder_pic = rpm_param->p.sps_num_reorder_pics_0;
+ new_pic->losless_comp_body_size = hevc->losless_comp_body_size;
+ new_pic->POC = hevc->curr_POC;
+ new_pic->pic_struct = hevc->curr_pic_struct;
+
+ if (new_pic->aux_data_buf)
+ release_aux_data(hevc, new_pic);
+ new_pic->mem_saving_mode =
+ hevc->mem_saving_mode;
+ new_pic->bit_depth_luma =
+ hevc->bit_depth_luma;
+ new_pic->bit_depth_chroma =
+ hevc->bit_depth_chroma;
+ new_pic->video_signal_type =
+ hevc->video_signal_type;
+
+ new_pic->conformance_window_flag =
+ hevc->param.p.conformance_window_flag;
+ new_pic->conf_win_left_offset =
+ hevc->param.p.conf_win_left_offset;
+ new_pic->conf_win_right_offset =
+ hevc->param.p.conf_win_right_offset;
+ new_pic->conf_win_top_offset =
+ hevc->param.p.conf_win_top_offset;
+ new_pic->conf_win_bottom_offset =
+ hevc->param.p.conf_win_bottom_offset;
+ new_pic->chroma_format_idc =
+ hevc->param.p.chroma_format_idc;
+
+ hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
+ "%s: index %d, buf_idx %d, decode_idx %d, POC %d\n",
+ __func__, new_pic->index,
+ new_pic->BUF_index, new_pic->decode_idx,
+ new_pic->POC);
+
+ return new_pic;
+}
+
static int get_display_pic_num(struct hevc_state_s *hevc)
{
int i;
@@ -6918,7 +7019,9 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
set_aux_data(hevc, hevc->cur_pic, 1, 0);
#endif
/* new pic */
- hevc->cur_pic = get_new_pic(hevc, rpm_param);
+ hevc->cur_pic = hevc->is_used_v4l ?
+ v4l_get_new_pic(hevc, rpm_param) :
+ get_new_pic(hevc, rpm_param);
if (hevc->cur_pic == NULL) {
if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
dump_pic_list(hevc);
@@ -6979,7 +7082,9 @@ static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
} else {
if (hevc->wait_buf == 1) {
pic_list_process(hevc);
- hevc->cur_pic = get_new_pic(hevc, rpm_param);
+ hevc->cur_pic = hevc->is_used_v4l ?
+ v4l_get_new_pic(hevc, rpm_param) :
+ get_new_pic(hevc, rpm_param);
if (hevc->cur_pic == NULL)
return -1;
@@ -12147,8 +12252,11 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
!ctx->v4l_codec_ready &&
hevc->v4l_params_parsed) {
ret = 0; /*the params has parsed.*/
- } else if (!ctx->v4l_codec_dpb_ready)
- ret = 0;
+ } else if (!ctx->v4l_codec_dpb_ready) {
+ if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) <
+ run_ready_min_buf_num)
+ ret = 0;
+ }
}
if (ret)
@@ -12357,7 +12465,6 @@ static void aml_free_canvas(struct vdec_s *vdec)
static void reset(struct vdec_s *vdec)
{
-
struct hevc_state_s *hevc =
(struct hevc_state_s *)vdec->private;
int i;
diff --git a/drivers/frame_provider/decoder/utils/vdec.c b/drivers/frame_provider/decoder/utils/vdec.c
index d987eb3..f5acd6a 100644
--- a/drivers/frame_provider/decoder/utils/vdec.c
+++ b/drivers/frame_provider/decoder/utils/vdec.c
@@ -2512,6 +2512,8 @@ int vdec_v4l2_reset(struct vdec_s *vdec, int flag)
vdec_connect(vdec);
+ vdec_frame_check_init(vdec);
+
return 0;
}
EXPORT_SYMBOL(vdec_v4l2_reset);
diff --git a/drivers/frame_provider/decoder/vp9/vvp9.c b/drivers/frame_provider/decoder/vp9/vvp9.c
index 171706f..8c302c7 100644
--- a/drivers/frame_provider/decoder/vp9/vvp9.c
+++ b/drivers/frame_provider/decoder/vp9/vvp9.c
@@ -1243,26 +1243,6 @@ static void resize_context_buffers(struct VP9Decoder_s *pbi,
}
pr_info("%s (%d,%d)=>(%d,%d)\r\n", __func__, cm->width,
cm->height, width, height);
-
- if (pbi->is_used_v4l) {
- struct PIC_BUFFER_CONFIG_s *pic = &cm->cur_frame->buf;
-
- /* resolution change happend need to reconfig buffs if true. */
- if (pic->y_crop_width != width || pic->y_crop_height != height) {
- int i;
- for (i = 0; i < pbi->used_buf_num; i++) {
- pic = &cm->buffer_pool->frame_bufs[i].buf;
- pic->y_crop_width = width;
- pic->y_crop_height = height;
- if (!v4l_alloc_and_config_pic(pbi, pic))
- set_canvas(pbi, pic);
- else
- vp9_print(pbi, 0,
- "v4l: reconfig buff fail.\n");
- }
- }
- }
-
cm->width = width;
cm->height = height;
}
@@ -2156,7 +2136,6 @@ static int get_free_fb(struct VP9Decoder_s *pbi)
{
struct VP9_Common_s *const cm = &pbi->common;
struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- struct PIC_BUFFER_CONFIG_s *pic = NULL;
int i;
unsigned long flags;
@@ -2170,21 +2149,11 @@ static int get_free_fb(struct VP9Decoder_s *pbi)
}
}
for (i = 0; i < pbi->used_buf_num; ++i) {
- pic = &frame_bufs[i].buf;
if ((frame_bufs[i].ref_count == 0) &&
- (pic->vf_ref == 0) && (pic->index != -1)) {
- if (pbi->is_used_v4l && !pic->cma_alloc_addr) {
- pic->y_crop_width = pbi->frame_width;
- pic->y_crop_height = pbi->frame_height;
- if (!v4l_alloc_and_config_pic(pbi, pic)) {
- set_canvas(pbi, pic);
- init_pic_list_hw(pbi);
- } else
- i = pbi->used_buf_num;
- }
-
+ (frame_bufs[i].buf.vf_ref == 0) &&
+ (frame_bufs[i].buf.index != -1)
+ )
break;
- }
}
if (i != pbi->used_buf_num) {
frame_bufs[i].ref_count = 1;
@@ -2200,6 +2169,58 @@ static int get_free_fb(struct VP9Decoder_s *pbi)
return i;
}
+static int v4l_get_free_fb(struct VP9Decoder_s *pbi)
+{
+ struct VP9_Common_s *const cm = &pbi->common;
+ struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
+ struct aml_vcodec_ctx * v4l = pbi->v4l2_ctx;
+ struct PIC_BUFFER_CONFIG_s *pic = NULL;
+ int i, idx = INVALID_IDX;
+ ulong flags;
+
+ lock_buffer_pool(cm->buffer_pool, flags);
+
+ for (i = 0; i < pbi->used_buf_num; ++i) {
+ struct v4l_buff_pool *pool = &v4l->cap_pool;
+ u32 state = (pool->seq[i] >> 16);
+ u32 index = (pool->seq[i] & 0xffff);
+
+ switch (state) {
+ case V4L_CAP_BUFF_IN_DEC:
+ pic = &frame_bufs[i].buf;
+ if ((frame_bufs[i].ref_count == 0) &&
+ (pic->vf_ref == 0) &&
+ (pic->index != -1) &&
+ pic->cma_alloc_addr) {
+ idx = i;
+ }
+ break;
+ case V4L_CAP_BUFF_IN_M2M:
+ pic = &frame_bufs[index].buf;
+ pic->y_crop_width = pbi->frame_width;
+ pic->y_crop_height = pbi->frame_height;
+ if (!v4l_alloc_and_config_pic(pbi, pic)) {
+ set_canvas(pbi, pic);
+ init_pic_list_hw(pbi);
+ idx = index;
+ }
+ break;
+ default:
+ pr_err("v4l buffer state err %d.\n", state);
+ break;
+ }
+
+ if (idx != INVALID_IDX) {
+ frame_bufs[idx].ref_count = 1;
+ break;
+ }
+ }
+
+ unlock_buffer_pool(cm->buffer_pool, flags);
+
+ return idx;
+}
+
static int get_free_buf_count(struct VP9Decoder_s *pbi)
{
struct VP9_Common_s *const cm = &pbi->common;
@@ -2361,7 +2382,9 @@ int vp9_bufmgr_process(struct VP9Decoder_s *pbi, union param_u *params)
if (debug & VP9_DEBUG_BUFMGR_DETAIL)
dump_pic_list(pbi);
#endif
- cm->new_fb_idx = get_free_fb(pbi);
+ cm->new_fb_idx = pbi->is_used_v4l ?
+ v4l_get_free_fb(pbi) :
+ get_free_fb(pbi);
if (cm->new_fb_idx == INVALID_IDX) {
pr_info("get_free_fb error\r\n");
return -1;
@@ -10126,7 +10149,6 @@ static void init_frame_bufs(struct VP9Decoder_s *pbi)
static void reset(struct vdec_s *vdec)
{
-
struct VP9Decoder_s *pbi =
(struct VP9Decoder_s *)vdec->private;