summaryrefslogtreecommitdiff
Diffstat
-rw-r--r--drivers/amvdec_ports/Makefile13
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.c22
-rw-r--r--drivers/amvdec_ports/aml_vcodec_adapt.h3
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.c534
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.h39
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec_drv.c57
-rw-r--r--drivers/amvdec_ports/aml_vcodec_drv.h11
-rw-r--r--drivers/amvdec_ports/aml_vcodec_util.c18
-rw-r--r--drivers/amvdec_ports/aml_vcodec_util.h8
-rw-r--r--drivers/amvdec_ports/aml_vcodec_vfm.c9
-rw-r--r--drivers/amvdec_ports/aml_vcodec_vfm.h6
-rw-r--r--drivers/amvdec_ports/decoder/aml_h264_parser.c662
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/aml_h264_parser.h226
-rw-r--r--drivers/amvdec_ports/decoder/aml_hevc_parser.c1274
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/aml_hevc_parser.h137
-rw-r--r--drivers/amvdec_ports/decoder/aml_mjpeg_parser.c397
-rw-r--r--drivers/amvdec_ports/decoder/aml_mjpeg_parser.h163
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg12_parser.c198
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg12_parser.h74
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg4_parser.c1233
-rw-r--r--drivers/amvdec_ports/decoder/aml_mpeg4_parser.h250
-rw-r--r--drivers/amvdec_ports/decoder/aml_vp9_parser.c299
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/aml_vp9_parser.h279
-rw-r--r--drivers/amvdec_ports/decoder/h264_parse.c389
-rw-r--r--drivers/amvdec_ports/decoder/h264_parse.h141
-rw-r--r--drivers/amvdec_ports/decoder/h264_stream.c111
-rw-r--r--drivers/amvdec_ports/decoder/h264_stream.h39
-rw-r--r--drivers/amvdec_ports/decoder/vdec_h264_if.c357
-rw-r--r--drivers/amvdec_ports/decoder/vdec_hevc_if.c477
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mjpeg_if.c498
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mpeg12_if.c490
-rw-r--r--drivers/amvdec_ports/decoder/vdec_mpeg4_if.c499
-rw-r--r--drivers/amvdec_ports/decoder/vdec_vp9_if.c461
-rw-r--r--[-rwxr-xr-x]drivers/amvdec_ports/decoder/vdec_vp9_trigger.h0
-rw-r--r--drivers/amvdec_ports/test/vcodec_m2m_test.c18
-rw-r--r--drivers/amvdec_ports/utils/common.c221
-rw-r--r--drivers/amvdec_ports/utils/common.h72
-rw-r--r--drivers/amvdec_ports/utils/get_bits.h590
-rw-r--r--drivers/amvdec_ports/utils/golomb.c147
-rw-r--r--drivers/amvdec_ports/utils/golomb.h500
-rw-r--r--drivers/amvdec_ports/utils/pixfmt.h470
-rw-r--r--drivers/amvdec_ports/utils/put_bits.h323
-rw-r--r--drivers/amvdec_ports/vdec_drv_base.h11
-rw-r--r--drivers/amvdec_ports/vdec_drv_if.c45
-rw-r--r--drivers/amvdec_ports/vdec_drv_if.h10
-rw-r--r--drivers/frame_provider/decoder/h264_multi/vmh264.c219
-rw-r--r--drivers/frame_provider/decoder/h265/vh265.c308
-rw-r--r--drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c334
-rw-r--r--drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c233
-rw-r--r--drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c317
-rw-r--r--drivers/frame_provider/decoder/utils/Makefile1
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_input.c19
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c131
-rw-r--r--drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h22
-rw-r--r--drivers/frame_provider/decoder/vp9/vvp9.c388
55 files changed, 11471 insertions, 2282 deletions
diff --git a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c
index 94539f9..c8c3eaa 100644
--- a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c
+++ b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c
@@ -43,8 +43,7 @@
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/amlogic/media/codec_mm/configs.h>
#include "../utils/firmware.h"
-
-
+#include "../utils/vdec_v4l2_buffer_ops.h"
#define MEM_NAME "codec_mmjpeg"
@@ -111,6 +110,7 @@ unsigned int mmjpeg_debug_mask = 0xff;
#define PRINT_FLAG_FORCE_DONE 0x0100
#define PRINT_FRAMEBASE_DATA 0x0400
#define PRINT_FLAG_TIMEOUT_STATUS 0x1000
+#define PRINT_FLAG_V4L_DETAIL 0x8000
int mmjpeg_debug_print(int index, int debug_flag, const char *fmt, ...)
{
@@ -143,8 +143,9 @@ static const struct vframe_operations_s vf_provider_ops = {
#define DEC_RESULT_NONE 0
#define DEC_RESULT_DONE 1
#define DEC_RESULT_AGAIN 2
-#define DEC_RESULT_FORCE_EXIT 3
-#define DEC_RESULT_EOS 4
+#define DEC_RESULT_ERROR 3
+#define DEC_RESULT_FORCE_EXIT 4
+#define DEC_RESULT_EOS 5
#define DEC_DECODE_TIMEOUT 0x21
@@ -161,6 +162,7 @@ struct buffer_spec_s {
unsigned long cma_alloc_addr;
int cma_alloc_count;
unsigned int buf_adr;
+ ulong v4l_ref_buf_addr;
};
#define spec2canvas(x) \
@@ -206,9 +208,13 @@ struct vdec_mjpeg_hw_s {
u32 put_num;
u32 run_count;
u32 not_run_ready;
+ u32 buffer_not_ready;
u32 input_empty;
u32 peek_num;
u32 get_num;
+ bool is_used_v4l;
+ void *v4l2_ctx;
+ bool v4l_params_parsed;
};
static void reset_process_time(struct vdec_mjpeg_hw_s *hw);
@@ -280,6 +286,40 @@ static irqreturn_t vmjpeg_isr(struct vdec_s *vdec, int irq)
return IRQ_HANDLED;
}
+ if (hw->is_used_v4l) {
+ struct aml_vcodec_ctx *ctx =
+ (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
+
+ if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
+ struct aml_vdec_pic_infos info;
+
+ 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;
+ hw->v4l_params_parsed = true;
+ vdec_v4l_set_pic_infos(ctx, &info);
+ }
+
+ if (!ctx->v4l_codec_ready)
+ return IRQ_HANDLED;
+ }
+
+ if (hw->is_used_v4l) {
+ vf->v4l_mem_handle
+ = hw->buffer_spec[index].v4l_ref_buf_addr;
+ if (vdec_v4l_binding_fd_and_vf(vf->v4l_mem_handle, vf) < 0) {
+ mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
+ "v4l: binding vf fail.\n");
+ return -1;
+ }
+ mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
+ "[%d] %s(), v4l mem handle: 0x%lx\n",
+ ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id,
+ __func__, vf->v4l_mem_handle);
+ }
+
vf->index = index;
set_frame_info(hw, vf);
@@ -415,14 +455,13 @@ static int vmjpeg_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
}
/****************************************/
-static void vmjpeg_canvas_init(struct vdec_s *vdec)
+static void vmjpeg_canvas_init(struct vdec_mjpeg_hw_s *hw)
{
int i, ret;
u32 canvas_width, canvas_height;
u32 decbuf_size, decbuf_y_size, decbuf_uv_size;
unsigned long buf_start, addr;
- struct vdec_mjpeg_hw_s *hw =
- (struct vdec_mjpeg_hw_s *)vdec->private;
+ struct vdec_s *vdec = hw_to_vdec(hw);
canvas_width = 1920;
canvas_height = 1088;
@@ -433,12 +472,16 @@ static void vmjpeg_canvas_init(struct vdec_s *vdec)
for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
int canvas;
- ret = decoder_bmmu_box_alloc_buf_phy(hw->mm_blk_handle, i,
- decbuf_size, DRIVER_NAME, &buf_start);
- if (ret < 0) {
- pr_err("CMA alloc failed! size 0x%d idx %d\n",
- decbuf_size, i);
- return;
+ if (hw->is_used_v4l) {
+ continue;
+ } else {
+ ret = decoder_bmmu_box_alloc_buf_phy(hw->mm_blk_handle, i,
+ decbuf_size, DRIVER_NAME, &buf_start);
+ if (ret < 0) {
+ pr_err("CMA alloc failed! size 0x%d idx %d\n",
+ decbuf_size, i);
+ return;
+ }
}
hw->buffer_spec[i].buf_adr = buf_start;
@@ -782,27 +825,178 @@ static void check_timer_func(unsigned long arg)
mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
}
-static void vmjpeg_hw_ctx_restore(struct vdec_s *vdec, int index)
+static int vmjpeg_v4l_alloc_buff_config_canvas(struct vdec_mjpeg_hw_s *hw, int i)
+{
+ int ret;
+ u32 canvas;
+ ulong decbuf_start = 0, addr;
+ int decbuf_y_size = 0, decbuf_uv_size = 0;
+ u32 canvas_width = 0, canvas_height = 0;
+ struct vdec_s *vdec = hw_to_vdec(hw);
+ struct vdec_v4l2_buffer *fb = NULL;
+
+ if (hw->buffer_spec[i].v4l_ref_buf_addr)
+ return 0;
+
+ ret = vdec_v4l_get_buffer(hw->v4l2_ctx, &fb);
+ if (ret) {
+ mmjpeg_debug_print(DECODE_ID(hw), 0,
+ "[%d] get fb fail.\n",
+ ((struct aml_vcodec_ctx *)
+ (hw->v4l2_ctx))->id);
+ return ret;
+ }
+
+ hw->buffer_spec[i].v4l_ref_buf_addr = (ulong)fb;
+ if (fb->num_planes == 1) {
+ decbuf_start = fb->m.mem[0].addr;
+ decbuf_y_size = fb->m.mem[0].offset;
+ decbuf_uv_size = fb->m.mem[0].size - fb->m.mem[0].offset;
+ canvas_width = ALIGN(hw->frame_width, 16);
+ canvas_height = ALIGN(hw->frame_height, 16);
+ fb->m.mem[0].bytes_used = fb->m.mem[0].size;
+ } else if (fb->num_planes == 2) {
+ decbuf_start = fb->m.mem[0].addr;
+ decbuf_y_size = fb->m.mem[0].size;
+ decbuf_uv_size = fb->m.mem[1].size << 1;
+ canvas_width = ALIGN(hw->frame_width, 16);
+ canvas_height = ALIGN(hw->frame_height, 16);
+ fb->m.mem[0].bytes_used = decbuf_y_size;
+ fb->m.mem[1].bytes_used = decbuf_uv_size >> 1;
+ }
+
+ hw->buffer_spec[i].buf_adr = decbuf_start;
+ addr = hw->buffer_spec[i].buf_adr;
+ hw->buffer_spec[i].y_addr = addr;
+ addr += decbuf_y_size;
+ hw->buffer_spec[i].u_addr = addr;
+ addr += decbuf_uv_size;
+ hw->buffer_spec[i].v_addr = addr;
+
+ mmjpeg_debug_print(DECODE_ID(hw), 0, "[%d] %s(), v4l ref buf addr: 0x%x\n",
+ ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id, __func__, fb);
+
+ if (vdec->parallel_dec == 1) {
+ if (hw->buffer_spec[i].y_canvas_index == -1)
+ hw->buffer_spec[i].y_canvas_index =
+ vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
+ if (hw->buffer_spec[i].u_canvas_index == -1)
+ hw->buffer_spec[i].u_canvas_index =
+ vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
+ if (hw->buffer_spec[i].v_canvas_index == -1)
+ hw->buffer_spec[i].v_canvas_index =
+ vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
+ } else {
+ canvas = vdec->get_canvas(i, 3);
+ hw->buffer_spec[i].y_canvas_index = canvas_y(canvas);
+ hw->buffer_spec[i].u_canvas_index = canvas_u(canvas);
+ hw->buffer_spec[i].v_canvas_index = canvas_v(canvas);
+ }
+
+ canvas_config(hw->buffer_spec[i].y_canvas_index,
+ hw->buffer_spec[i].y_addr,
+ canvas_width,
+ canvas_height,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_LINEAR);
+ hw->buffer_spec[i].canvas_config[0].phy_addr =
+ hw->buffer_spec[i].y_addr;
+ hw->buffer_spec[i].canvas_config[0].width =
+ canvas_width;
+ hw->buffer_spec[i].canvas_config[0].height =
+ canvas_height;
+ hw->buffer_spec[i].canvas_config[0].block_mode =
+ CANVAS_BLKMODE_LINEAR;
+
+ canvas_config(hw->buffer_spec[i].u_canvas_index,
+ hw->buffer_spec[i].u_addr,
+ canvas_width / 2,
+ canvas_height / 2,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_LINEAR);
+ hw->buffer_spec[i].canvas_config[1].phy_addr =
+ hw->buffer_spec[i].u_addr;
+ hw->buffer_spec[i].canvas_config[1].width =
+ canvas_width / 2;
+ hw->buffer_spec[i].canvas_config[1].height =
+ canvas_height / 2;
+ hw->buffer_spec[i].canvas_config[1].block_mode =
+ CANVAS_BLKMODE_LINEAR;
+
+ canvas_config(hw->buffer_spec[i].v_canvas_index,
+ hw->buffer_spec[i].v_addr,
+ canvas_width / 2,
+ canvas_height / 2,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_LINEAR);
+ hw->buffer_spec[i].canvas_config[2].phy_addr =
+ hw->buffer_spec[i].v_addr;
+ hw->buffer_spec[i].canvas_config[2].width =
+ canvas_width / 2;
+ hw->buffer_spec[i].canvas_config[2].height =
+ canvas_height / 2;
+ hw->buffer_spec[i].canvas_config[2].block_mode =
+ CANVAS_BLKMODE_LINEAR;
+
+ return 0;
+}
+
+static bool is_enough_free_buffer(struct vdec_mjpeg_hw_s *hw)
+{
+ int i;
+
+ for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
+ if (hw->vfbuf_use[i] == 0)
+ break;
+ }
+
+ return i == DECODE_BUFFER_NUM_MAX ? false : true;
+}
+
+static int find_free_buffer(struct vdec_mjpeg_hw_s *hw)
+{
+ int i;
+
+ for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
+ if (hw->vfbuf_use[i] == 0)
+ break;
+ }
+
+ if (i == DECODE_BUFFER_NUM_MAX)
+ return -1;
+
+ if (hw->is_used_v4l)
+ if (vmjpeg_v4l_alloc_buff_config_canvas(hw, i))
+ return -1;
+
+ return i;
+}
+
+static int vmjpeg_hw_ctx_restore(struct vdec_mjpeg_hw_s *hw)
{
- struct vdec_mjpeg_hw_s *hw =
- (struct vdec_mjpeg_hw_s *)vdec->private;
struct buffer_spec_s *buff_spec;
- u32 i;
+ u32 index, i;
+
+ index = find_free_buffer(hw);
+ if (index < 0)
+ return -1;
WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6));
WRITE_VREG(DOS_SW_RESET0, 0);
if (!hw->init_flag) {
- vmjpeg_canvas_init(vdec);
+ vmjpeg_canvas_init(hw);
} else {
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
- buff_spec = &hw->buffer_spec[i];
- canvas_config_config(buff_spec->y_canvas_index,
- &buff_spec->canvas_config[0]);
- canvas_config_config(buff_spec->u_canvas_index,
- &buff_spec->canvas_config[1]);
- canvas_config_config(buff_spec->v_canvas_index,
- &buff_spec->canvas_config[2]);
+ if (!hw->is_used_v4l) {
+ for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
+ buff_spec = &hw->buffer_spec[i];
+ canvas_config_config(buff_spec->y_canvas_index,
+ &buff_spec->canvas_config[0]);
+ canvas_config_config(buff_spec->u_canvas_index,
+ &buff_spec->canvas_config[1]);
+ canvas_config_config(buff_spec->v_canvas_index,
+ &buff_spec->canvas_config[2]);
+ }
}
}
@@ -828,6 +1022,7 @@ static void vmjpeg_hw_ctx_restore(struct vdec_s *vdec, int index)
#if 1/*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6*/
CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
#endif
+ return 0;
}
static s32 vmjpeg_init(struct vdec_s *vdec)
@@ -929,8 +1124,14 @@ static unsigned long run_ready(struct vdec_s *vdec,
if (level < pre_decode_buf_level)
return 0;
}
- hw->not_run_ready = 0;
+ if (!is_enough_free_buffer(hw)) {
+ hw->buffer_not_ready++;
+ return 0;
+ }
+
+ hw->not_run_ready = 0;
+ hw->buffer_not_ready = 0;
if (vdec->parallel_dec == 1)
return CORE_MASK_VDEC_1;
else
@@ -998,7 +1199,13 @@ static void run(struct vdec_s *vdec, unsigned long mask,
return;
}*/
- vmjpeg_hw_ctx_restore(vdec, i);
+ if (vmjpeg_hw_ctx_restore(hw) < 0) {
+ hw->dec_result = DEC_RESULT_ERROR;
+ mmjpeg_debug_print(DECODE_ID(hw), 0,
+ "amvdec_mmjpeg: error HW context restore\n");
+ vdec_schedule_work(&hw->work);
+ return;
+ }
#if 0
vdec_enable_input(vdec);
mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
@@ -1013,19 +1220,19 @@ static void run(struct vdec_s *vdec, unsigned long mask,
hw->init_flag = 1;
mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "%s (0x%x 0x%x 0x%x) vldcrl 0x%x bitcnt 0x%x powerctl 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
- __func__,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VLD_DECODE_CONTROL),
- READ_VREG(VIFF_BIT_CNT),
- READ_VREG(POWER_CTL_VLD),
- READ_VREG(VLD_MEM_VIFIFO_START_PTR),
- READ_VREG(VLD_MEM_VIFIFO_CURR_PTR),
- READ_VREG(VLD_MEM_VIFIFO_CONTROL),
- READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL),
- READ_VREG(VLD_MEM_VIFIFO_END_PTR));
+ "%s (0x%x 0x%x 0x%x) vldcrl 0x%x bitcnt 0x%x powerctl 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ __func__,
+ READ_VREG(VLD_MEM_VIFIFO_LEVEL),
+ READ_VREG(VLD_MEM_VIFIFO_WP),
+ READ_VREG(VLD_MEM_VIFIFO_RP),
+ READ_VREG(VLD_DECODE_CONTROL),
+ READ_VREG(VIFF_BIT_CNT),
+ READ_VREG(POWER_CTL_VLD),
+ READ_VREG(VLD_MEM_VIFIFO_START_PTR),
+ READ_VREG(VLD_MEM_VIFIFO_CURR_PTR),
+ READ_VREG(VLD_MEM_VIFIFO_CONTROL),
+ READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL),
+ READ_VREG(VLD_MEM_VIFIFO_END_PTR));
}
static void wait_vmjpeg_search_done(struct vdec_mjpeg_hw_s *hw)
{
@@ -1047,6 +1254,40 @@ static void wait_vmjpeg_search_done(struct vdec_mjpeg_hw_s *hw)
} while (1);
}
+static int notify_v4l_eos(struct vdec_s *vdec)
+{
+ struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)vdec->private;
+ struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
+ struct vframe_s *vf = NULL;
+ struct vdec_v4l2_buffer *fb = NULL;
+
+ if (hw->is_used_v4l && hw->eos) {
+ if (kfifo_get(&hw->newframe_q, &vf) == 0 || vf == NULL) {
+ mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
+ "%s fatal error, no available buffer slot.\n",
+ __func__);
+ return -1;
+ }
+
+ if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb)) {
+ pr_err("[%d] get fb fail.\n", ctx->id);
+ return -1;
+ }
+
+ vf->timestamp = ULONG_MAX;
+ vf->v4l_mem_handle = (unsigned long)fb;
+ vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
+
+ kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+
+ pr_info("[%d] mpeg12 EOS notify.\n", ctx->id);
+ }
+
+ return 0;
+}
+
static void vmjpeg_work(struct work_struct *work)
{
struct vdec_mjpeg_hw_s *hw = container_of(work,
@@ -1087,6 +1328,9 @@ static void vmjpeg_work(struct work_struct *work)
hw->stat &= ~STAT_VDEC_RUN;
}
hw->eos = 1;
+ if (hw->is_used_v4l)
+ notify_v4l_eos(vdec);
+
vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
hw->chunk = NULL;
vdec_clean_input(hw_to_vdec(hw));
@@ -1165,6 +1409,9 @@ static int ammvdec_mjpeg_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ /* the ctx from v4l2 driver. */
+ hw->v4l2_ctx = pdata->private;
+
pdata->private = hw;
pdata->dec_status = vmjpeg_dec_status;
@@ -1196,8 +1443,11 @@ static int ammvdec_mjpeg_probe(struct platform_device *pdev)
hw->platform_dev = pdev;
- if (pdata->sys_info)
+ if (pdata->sys_info) {
hw->vmjpeg_amstream_dec_info = *pdata->sys_info;
+ hw->is_used_v4l = (((unsigned long)
+ hw->vmjpeg_amstream_dec_info.param & 0x80) >> 7);
+ }
vdec_source_changed(VFORMAT_MJPEG,
1920, 1080, 60);