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/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c
index a2a1b98..9c34b49 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec.c
@@ -31,11 +31,12 @@
#include <linux/atomic.h>
#include <linux/crc32.h>
#include "aml_vcodec_adapt.h"
+#include <linux/spinlock.h>
#include "aml_vcodec_vfm.h"
#define OUT_FMT_IDX 0 //default h264
-#define CAP_FMT_IDX 3 //capture nv21
+#define CAP_FMT_IDX 8 //capture nv21
#define AML_VDEC_MIN_W 64U
#define AML_VDEC_MIN_H 64U
@@ -72,8 +73,43 @@ static struct aml_video_fmt aml_video_formats[] = {
.num_planes = 1,
},
{
+ .fourcc = V4L2_PIX_FMT_MPEG1,
+ .type = AML_FMT_DEC,
+ .num_planes = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_MPEG2,
+ .type = AML_FMT_DEC,
+ .num_planes = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_MPEG4,
+ .type = AML_FMT_DEC,
+ .num_planes = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_MJPEG,
+ .type = AML_FMT_DEC,
+ .num_planes = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_NV21,
+ .type = AML_FMT_FRAME,
+ .num_planes = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_NV21M,
+ .type = AML_FMT_FRAME,
+ .num_planes = 2,
+ },
+ {
.fourcc = V4L2_PIX_FMT_NV12,
.type = AML_FMT_FRAME,
+ .num_planes = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_NV12M,
+ .type = AML_FMT_FRAME,
.num_planes = 2,
},
};
@@ -94,16 +130,56 @@ static const struct aml_codec_framesizes aml_vdec_framesizes[] = {
.stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
},
+ {
+ .fourcc = V4L2_PIX_FMT_MPEG1,
+ .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
+ AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_MPEG2,
+ .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
+ AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_MPEG4,
+ .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
+ AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_MJPEG,
+ .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 8,
+ AML_VDEC_MIN_H, AML_VDEC_MAX_H, 8 },
+ },
};
#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(aml_vdec_framesizes)
#define NUM_FORMATS ARRAY_SIZE(aml_video_formats)
+extern bool multiplanar;
+
+static ulong aml_vcodec_ctx_lock(struct aml_vcodec_ctx *ctx)
+{
+ ulong flags;
+
+ spin_lock_irqsave(&ctx->slock, flags);
+
+ return flags;
+}
+
+static void aml_vcodec_ctx_unlock(struct aml_vcodec_ctx *ctx, ulong flags)
+{
+ spin_unlock_irqrestore(&ctx->slock, flags);
+}
+
static struct aml_video_fmt *aml_vdec_find_format(struct v4l2_format *f)
{
struct aml_video_fmt *fmt;
unsigned int k;
+ aml_v4l2_debug(4, "%s, type: %u, planes: %u, fmt: %u\n",
+ __func__, f->type, f->fmt.pix_mp.num_planes,
+ f->fmt.pix_mp.pixelformat);
+
for (k = 0; k < NUM_FORMATS; k++) {
fmt = &aml_video_formats[k];
if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
@@ -179,59 +255,105 @@ static void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx)
ctx->picinfo = ctx->last_decoded_picinfo;
}
-int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_fb **out_fb)
+int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_fb)
{
+ ulong flags;
struct vb2_buffer *dst_buf = NULL;
- struct vdec_fb *pfb;
+ struct vdec_v4l2_buffer *pfb;
struct aml_video_dec_buf *dst_buf_info, *info;
struct vb2_v4l2_buffer *dst_vb2_v4l2;
- int try_cnt = 100;
-
- aml_v4l2_debug(4, "[%d] %s() [%d]", ctx->id, __func__, __LINE__);
- do {
- dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
- if (dst_buf)
- break;
- aml_v4l2_debug(3, "[%d] waitting enough dst buffers.", ctx->id);
- msleep(30);
- } while (try_cnt--);
+ flags = aml_vcodec_ctx_lock(ctx);
- if (!dst_buf)
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+ if (!dst_buf) {
+ aml_vcodec_ctx_unlock(ctx, flags);
return -1;
+ }
+
+ aml_v4l2_debug(2, "[%d] %s() vbuf idx: %d, state: %d, ready: %d",
+ ctx->id, __func__, dst_buf->index, dst_buf->state,
+ v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx));
dst_vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf);
dst_buf_info = container_of(dst_vb2_v4l2, struct aml_video_dec_buf, vb);
- pfb = &dst_buf_info->frame_buffer;
- //pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0);
- pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
- pfb->base_y.va = phys_to_virt(dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->base_y.dma_addr));
- pfb->base_y.size = ctx->picinfo.y_len_sz;
-
- //pfb->base_c.va = vb2_plane_vaddr(dst_buf, 1);
- pfb->base_c.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1);
- pfb->base_c.va = phys_to_virt(dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->base_c.dma_addr));
- pfb->base_c.size = ctx->picinfo.c_len_sz;
- pfb->status = FB_ST_NORMAL;
-
- aml_v4l2_debug(4, "[%d] id=%d Framebuf pfb=%p VA=%p Y_DMA=%pad C_DMA=%pad y_size=%zx, c_size: %zx",
- ctx->id, dst_buf->index, pfb, pfb->base_y.va, &pfb->base_y.dma_addr,
- &pfb->base_c.dma_addr, pfb->base_y.size, pfb->base_c.size);
+ if (ctx->scatter_mem_enable) {
+ pfb = &dst_buf_info->frame_buffer;
+ 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->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;
+ pfb->m.mem[0].offset = ctx->picinfo.y_len_sz;
+ pfb->num_planes = dst_buf->num_planes;
+ pfb->status = FB_ST_NORMAL;
+
+ aml_v4l2_debug(4, "[%d] idx: %u, 1 plane, y:(0x%lx, %d)",
+ ctx->id, dst_buf->index,
+ pfb->m.mem[0].addr, pfb->m.mem[0].size);
+ } else if (dst_buf->num_planes == 2) {
+ 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;
+ pfb->m.mem[0].offset = 0;
+
+ pfb->m.mem[1].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1);
+ pfb->m.mem[1].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[1].dma_addr);
+ pfb->m.mem[1].size = ctx->picinfo.c_len_sz;
+ pfb->m.mem[1].offset = ctx->picinfo.c_len_sz >> 1;
+ pfb->num_planes = dst_buf->num_planes;
+ pfb->status = FB_ST_NORMAL;
+
+ aml_v4l2_debug(4, "[%d] idx: %u, 2 planes, y:(0x%lx, %d), c:(0x%lx, %d)",
+ ctx->id, dst_buf->index,
+ pfb->m.mem[0].addr, pfb->m.mem[0].size,
+ pfb->m.mem[1].addr, pfb->m.mem[1].size);
+ } else {
+ 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;
+ pfb->m.mem[0].offset = 0;
+
+ pfb->m.mem[1].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1);
+ pfb->m.mem[1].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[2].dma_addr);
+ pfb->m.mem[1].size = ctx->picinfo.c_len_sz >> 1;
+ pfb->m.mem[1].offset = 0;
+
+ pfb->m.mem[2].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 2);
+ pfb->m.mem[2].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[3].dma_addr);
+ pfb->m.mem[2].size = ctx->picinfo.c_len_sz >> 1;
+ pfb->m.mem[2].offset = 0;
+ pfb->num_planes = dst_buf->num_planes;
+ pfb->status = FB_ST_NORMAL;
+
+ aml_v4l2_debug(4, "[%d] idx: %u, 3 planes, y:(0x%lx, %d), u:(0x%lx, %d), v:(0x%lx, %d)",
+ ctx->id, dst_buf->index,
+ pfb->m.mem[0].addr, pfb->m.mem[0].size,
+ pfb->m.mem[1].addr, pfb->m.mem[1].size,
+ pfb->m.mem[2].addr, pfb->m.mem[2].size);
+ }
dst_buf_info->used = true;
-
- v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+ ctx->buf_used_count++;
*out_fb = pfb;
info = container_of(pfb, struct aml_video_dec_buf, frame_buffer);
+ v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+
+ aml_vcodec_ctx_unlock(ctx, flags);
+
return 0;
}
EXPORT_SYMBOL(get_fb_from_queue);
-int put_fb_to_queue(struct aml_vcodec_ctx *ctx, struct vdec_fb *in_fb)
+int put_fb_to_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *in_fb)
{
struct aml_video_dec_buf *dstbuf;
@@ -267,32 +389,57 @@ out:
}
EXPORT_SYMBOL(put_fb_to_queue);
-void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_fb *fb)
+void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *fb)
{
struct aml_video_dec_buf *dstbuf = NULL;
struct vframe_s *vf = (struct vframe_s *)fb->vf_handle;
- aml_v4l2_debug(2, "[%d] FROM (%s %s) vf: %p, ts: %llx, idx: %d",
+ aml_v4l2_debug(3, "[%d] FROM (%s %s) vf: %p, ts: %llx, idx: %d",
ctx->id, vf_get_provider(ctx->ada_ctx->recv_name)->name,
ctx->ada_ctx->vfm_path != FRAME_BASE_PATH_V4L_VIDEO ? "OSD" : "VIDEO",
vf, vf->timestamp, vf->index);
+ aml_v4l2_debug(4, "[%d] FROM Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)",
+ ctx->id, fb->m.mem[0].addr, fb->m.mem[0].size,
+ fb->m.mem[1].addr, fb->m.mem[1].size,
+ fb->m.mem[2].addr, fb->m.mem[2].size);
+
dstbuf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
- vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, fb->base_y.bytes_used);
- vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, fb->base_c.bytes_used);
+ if (dstbuf->frame_buffer.num_planes == 1) {
+ vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, fb->m.mem[0].bytes_used);
+ } else if (dstbuf->frame_buffer.num_planes == 2) {
+ vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, fb->m.mem[0].bytes_used);
+ vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, fb->m.mem[1].bytes_used);
+ }
dstbuf->vb.vb2_buf.timestamp = vf->timestamp;
dstbuf->ready_to_display = true;
if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) {
dstbuf->lastframe = true;
dstbuf->vb.flags = V4L2_BUF_FLAG_LAST;
- vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, 0);
- vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, 0);
+ if (dstbuf->frame_buffer.num_planes == 1) {
+ vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, 0);
+ } else if (dstbuf->frame_buffer.num_planes == 2) {
+ vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, 0);
+ vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, 0);
+ }
ctx->has_receive_eos = true;
- pr_info("[%d] recevie a empty frame.\n", ctx->id);
+ pr_info("[%d] recevie a empty frame. idx: %d, state: %d\n",
+ ctx->id, dstbuf->vb.vb2_buf.index,
+ dstbuf->vb.vb2_buf.state);
}
- v4l2_m2m_buf_done(&dstbuf->vb, VB2_BUF_STATE_DONE);
+ aml_v4l2_debug(4, "[%d] receive vbuf idx: %d, state: %d",
+ ctx->id, dstbuf->vb.vb2_buf.index,
+ dstbuf->vb.vb2_buf.state);
+
+ if (dstbuf->vb.vb2_buf.state == VB2_BUF_STATE_ACTIVE) {
+ /* binding vframe handle. */
+ if (fb->mem_type == VDEC_SCATTER_MEMORY_TYPE)
+ dstbuf->vb.private = fb->m.vf_fd;
+
+ v4l2_m2m_buf_done(&dstbuf->vb, VB2_BUF_STATE_DONE);
+ }
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_FLUSHING &&
@@ -319,7 +466,7 @@ void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_fb *fb)
ctx->decoded_frame_cnt++;
}
-static int get_display_buffer(struct aml_vcodec_ctx *ctx, struct vdec_fb **out)
+static int get_display_buffer(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out)
{
int ret = -1;
@@ -355,8 +502,8 @@ static int is_vdec_ready(struct aml_vcodec_ctx *ctx)
/* is there enough dst bufs for decoding? */
buf_ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
- if (buf_ready_num < ctx->dpb_size) {
- aml_v4l2_debug(4, "[%d] Not enough dst bufs, num: %d.\n",
+ if ((buf_ready_num + ctx->buf_used_count) < ctx->dpb_size) {
+ aml_v4l2_debug(4, "[%d] Not enough dst bufs, num: %d.",
ctx->id, buf_ready_num);
v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
v4l2_m2m_try_schedule(ctx->m2m_ctx);
@@ -367,6 +514,8 @@ static int is_vdec_ready(struct aml_vcodec_ctx *ctx)
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_PROBE) {
ctx->state = AML_STATE_READY;
+ ctx->v4l_codec_ready = true;
+ wake_up_interruptible(&ctx->wq);
aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_READY)",
ctx->id, __func__);
}
@@ -375,9 +524,12 @@ static int is_vdec_ready(struct aml_vcodec_ctx *ctx)
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_READY) {
- ctx->state = AML_STATE_ACTIVE;
- aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ACTIVE)",
- ctx->id, __func__);
+ if (ctx->m2m_ctx->out_q_ctx.q.streaming &&
+ ctx->m2m_ctx->cap_q_ctx.q.streaming) {
+ ctx->state = AML_STATE_ACTIVE;
+ aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ACTIVE)",
+ ctx->id, __func__);
+ }
}
mutex_unlock(&ctx->state_lock);
@@ -410,8 +562,6 @@ static void aml_vdec_worker(struct work_struct *work)
aml_v4l2_debug(4, "[%d] entry [%d] [%s]", ctx->id, __LINE__, __func__);
- aml_vdec_lock(ctx);
-
if (ctx->state < AML_STATE_INIT ||
ctx->state > AML_STATE_FLUSHED) {
v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
@@ -458,19 +608,16 @@ static void aml_vdec_worker(struct work_struct *work)
goto out;
}
- buf.va = vb2_plane_vaddr(src_buf, 0);
+ buf.vaddr = vb2_plane_vaddr(src_buf, 0);
buf.dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
- //buf.va = phys_to_virt(dma_to_phys(v4l_get_dev_from_codec_mm(), buf.dma_addr));
- buf.size = (size_t)src_buf->planes[0].bytesused;
- if (!buf.va) {
+ buf.size = src_buf->planes[0].bytesused;
+ if (!buf.vaddr) {
v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
aml_v4l2_err("[%d] id=%d src_addr is NULL!!",
ctx->id, src_buf->index);
goto out;
}
- aml_v4l2_debug(4, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
- ctx->id, buf.va, &buf.dma_addr, buf.size, src_buf);
src_buf_info->used = true;
@@ -521,56 +668,34 @@ static void aml_vdec_worker(struct work_struct *work)
v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
out:
- aml_vdec_unlock(ctx);
+ return;
}
-static void aml_reset_worker(struct work_struct *work)
+void wait_vcodec_ending(struct aml_vcodec_ctx *ctx)
{
- struct aml_vcodec_ctx *ctx =
- container_of(work, struct aml_vcodec_ctx, reset_work);
- //struct aml_video_dec_buf *buf = NULL;
- int try_cnt = 10;
+ struct aml_vcodec_dev *dev = ctx->dev;
- aml_vdec_lock(ctx);
+ /* pause inject output data to vdec. */
+ v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx);
- if (ctx->state == AML_STATE_ABORT) {
- pr_err("[%d] %s() the decoder will be exited.\n",
- ctx->id, __func__);
- goto out;
- }
-
- while (!v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx)) {
- pr_err("[%d] %s() src data is not ready.\n",
- ctx->id, __func__);
+ /* flush worker. */
+ flush_workqueue(dev->decode_workqueue);
- if (try_cnt--) {
- msleep(30);
- continue;
- }
+ /* wait reset worker ending. */
+ if (ctx->state == AML_STATE_RESET) {
+ wait_for_completion_timeout(&ctx->comp,
+ msecs_to_jiffies(200));
+ }
+}
- ctx->state = AML_STATE_ABORT;
- aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)",
+static void aml_vdec_reset(struct aml_vcodec_ctx *ctx)
+{
+ if (ctx->state == AML_STATE_ABORT) {
+ pr_err("[%d] %s() the decoder will be exited.\n",
ctx->id, __func__);
goto out;
}
-#if 0
- /*
- *fast enque capture buffers, but need to realloc
- *bufs if the resolution change event was hanped.
- */
- if (!ctx->q_data[AML_Q_DATA_SRC].resolution_changed) {
- list_for_each_entry(buf, &ctx->capture_list, node) {
- buf->que_in_m2m = true;
- buf->queued_in_vb2 = true;
- buf->queued_in_v4l2 = true;
- buf->ready_to_display = false;
- buf->frame_buffer.status = FB_ST_NORMAL;
- v4l2_m2m_buf_queue(ctx->m2m_ctx, &buf->vb);
- pr_err("que buf idx: %d\n", buf->vb.vb2_buf.index);
- }
- }
-#endif
if (aml_codec_reset(ctx->ada_ctx)) {
ctx->state = AML_STATE_ABORT;
aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)",
@@ -578,25 +703,24 @@ static void aml_reset_worker(struct work_struct *work)
goto out;
}
- mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_RESET) {
- ctx->state = AML_STATE_READY;
- aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_READY)",
+ ctx->state = AML_STATE_PROBE;
+ aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_PROBE)",
ctx->id, __func__);
/* vdec has ready to decode subsequence data of new resolution. */
ctx->q_data[AML_Q_DATA_SRC].resolution_changed = false;
v4l2_m2m_job_resume(ctx->dev->m2m_dev_dec, ctx->m2m_ctx);
}
- mutex_unlock(&ctx->state_lock);
out:
- aml_vdec_unlock(ctx);
+ complete(&ctx->comp);
+ return;
}
void try_to_capture(struct aml_vcodec_ctx *ctx)
{
int ret = 0;
- struct vdec_fb *fb = NULL;
+ struct vdec_v4l2_buffer *fb = NULL;
ret = get_display_buffer(ctx, &fb);
if (ret) {
@@ -611,11 +735,15 @@ EXPORT_SYMBOL_GPL(try_to_capture);
static int vdec_thread(void *data)
{
+ struct sched_param param =
+ {.sched_priority = MAX_RT_PRIO / 2};
struct aml_vdec_thread *thread =
(struct aml_vdec_thread *) data;
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *) thread->priv;
+ sched_setscheduler(current, SCHED_FIFO, &param);
+
for (;;) {
aml_v4l2_debug(3, "[%d] %s() state: %d", ctx->id,
__func__, ctx->state);
@@ -717,6 +845,7 @@ static int vidioc_try_decoder_cmd(struct file *file, void *priv,
default:
return -EINVAL;
}
+
return 0;
}
@@ -734,7 +863,8 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
aml_v4l2_debug(3, "[%d] %s() [%d], cmd: %u",
ctx->id, __func__, __LINE__, cmd->cmd);
dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
- V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
+ V4L2_BUF_TYPE_VIDEO_CAPTURE);
switch (cmd->cmd) {
case V4L2_DEC_CMD_STOP:
@@ -757,6 +887,9 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf->vb);
v4l2_m2m_try_schedule(ctx->m2m_ctx);//pay attention
+ /* remark cmd use to distinguish stop or seek. */
+ ctx->receive_cmd_stop = true;
+
break;
case V4L2_DEC_CMD_START:
@@ -776,7 +909,6 @@ static int vidioc_decoder_streamon(struct file *file, void *priv,
{
struct v4l2_fh *fh = file->private_data;
struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
- struct aml_vcodec_dev *dev = ctx->dev;
struct vb2_queue *q;
int ret = 0;
@@ -784,18 +916,35 @@ static int vidioc_decoder_streamon(struct file *file, void *priv,
q = v4l2_m2m_get_vq(fh->m2m_ctx, i);
- mutex_lock(&ctx->state_lock);
+ if (!V4L2_TYPE_IS_OUTPUT(q->type)) {
+ mutex_lock(&ctx->state_lock);
- if (ctx->state == AML_STATE_FLUSHED) {
- if (!V4L2_TYPE_IS_OUTPUT(q->type)) {
- ctx->state = AML_STATE_RESET;
- aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_RESET)",
- ctx->id, __func__);
- queue_work(dev->reset_workqueue, &ctx->reset_work);
+ /*
+ * if receive the cmd is not V4L2_DEC_CMD_STOP
+ * that request should be seek not stop, thus igorn status
+ * AML_STATE_FLUSHING and AML_STATE_FLUSHED.
+ */
+
+ if (ctx->state == AML_STATE_FLUSHED ||
+ ctx->state == AML_STATE_FLUSHING || //????
+ (ctx->state == AML_STATE_ACTIVE &&
+ !ctx->receive_cmd_stop)) {
+ if (!V4L2_TYPE_IS_OUTPUT(q->type)) {
+ /*the short source will be fasted into flushing state.
+ then switch to abort state that caused seek failed.*/
+ if (ctx->state == AML_STATE_FLUSHING)
+ ctx->receive_cmd_stop = false;
+
+ ctx->state = AML_STATE_RESET;
+ ctx->v4l_codec_ready = false;
+
+ aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_RESET)",
+ ctx->id, __func__);
+ aml_vdec_reset(ctx);
+ }
}
+ mutex_unlock(&ctx->state_lock);
}
- mutex_unlock(&ctx->state_lock);
-
return ret;
}
@@ -813,27 +962,14 @@ static int vidioc_decoder_reqbufs(struct file *file, void *priv,
return v4l2_m2m_ioctl_reqbufs(file, priv, rb);
}
-void aml_vdec_unlock(struct aml_vcodec_ctx *ctx)
-{
- mutex_unlock(&ctx->dev->dec_mutex);
-}
-
-void aml_vdec_lock(struct aml_vcodec_ctx *ctx)
-{
- mutex_lock(&ctx->dev->dec_mutex);
-}
-
void aml_vcodec_dec_release(struct aml_vcodec_ctx *ctx)
{
- aml_vdec_lock(ctx);
-
ctx->state = AML_STATE_ABORT;
+ ctx->v4l_codec_ready = false;
aml_v4l2_debug(1, "[%d] %s() vcodec state (AML_STATE_ABORT)",
ctx->id, __func__);
vdec_if_deinit(ctx);
-
- aml_vdec_unlock(ctx);
}
void aml_vcodec_dec_set_default_params(struct aml_vcodec_ctx *ctx)
@@ -844,12 +980,11 @@ void aml_vcodec_dec_set_default_params(struct aml_vcodec_ctx *ctx)
ctx->fh.m2m_ctx = ctx->m2m_ctx;
ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
INIT_WORK(&ctx->decode_work, aml_vdec_worker);
- INIT_WORK(&ctx->reset_work, aml_reset_worker);
ctx->colorspace = V4L2_COLORSPACE_REC709;
ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT;
- ctx->dev->dec_capability = VCODEC_CAPABILITY_4K_DISABLED;//disable 4k
+ ctx->dev->dec_capability = 0;//VCODEC_CAPABILITY_4K_DISABLED;//disable 4k
q_data = &ctx->q_data[AML_Q_DATA_SRC];
memset(q_data, 0, sizeof(struct aml_q_data));
@@ -951,7 +1086,7 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct aml_video_fmt *fmt)
if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
pix_fmt_mp->num_planes = 1;
pix_fmt_mp->plane_fmt[0].bytesperline = 0;
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ } else if (!V4L2_TYPE_IS_OUTPUT(f->type)) {
int tmp_w, tmp_h;
pix_fmt_mp->height = clamp(pix_fmt_mp->height,
@@ -1133,7 +1268,7 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
aml_v4l2_err("[%d] out_q_ctx buffers already requested", ctx->id);
}
- if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
+ if ((!V4L2_TYPE_IS_OUTPUT(f->type)) &&
vb2_is_busy(&ctx->m2m_ctx->cap_q_ctx.q)) {
aml_v4l2_err("[%d] cap_q_ctx buffers already requested", ctx->id);
}
@@ -1144,7 +1279,7 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
f->fmt.pix.pixelformat =
aml_video_formats[OUT_FMT_IDX].fourcc;
fmt = aml_vdec_find_format(f);
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ } else if (!V4L2_TYPE_IS_OUTPUT(f->type)) {
f->fmt.pix.pixelformat =
aml_video_formats[CAP_FMT_IDX].fourcc;
fmt = aml_vdec_find_format(f);
@@ -1283,7 +1418,7 @@ static int vidioc_vdec_g_fmt(struct file *file, void *priv,
pix_mp->quantization = ctx->quantization;
pix_mp->xfer_func = ctx->xfer_func;
- if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
+ if ((!V4L2_TYPE_IS_OUTPUT(f->type)) &&
(ctx->state >= AML_STATE_PROBE)) {
/* Until STREAMOFF is called on the CAPTURE queue
* (acknowledging the event), the driver operates as if
@@ -1346,6 +1481,7 @@ static int vidioc_vdec_g_fmt(struct file *file, void *priv,
aml_v4l2_debug(4, "[%d] type=%d state=%d Format information could not be read, not ready yet!",
ctx->id, f->type, ctx->state);
+ return -EINVAL;
}
return 0;
@@ -1444,21 +1580,18 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
* check if this buffer is ready to be used after decode
*/
if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
- aml_v4l2_debug(3, "[%d] %s() [%d], y_va: %p, vf_h: %lx, state: %d", ctx->id,
- __func__, __LINE__, buf->frame_buffer.base_y.va,
+ aml_v4l2_debug(3, "[%d] %s() [%d], y_addr: %lx, vf_h: %lx, state: %d", ctx->id,
+ __func__, __LINE__, buf->frame_buffer.m.mem[0].addr,
buf->frame_buffer.vf_handle, buf->frame_buffer.status);
if (!buf->que_in_m2m && buf->frame_buffer.status == FB_ST_NORMAL) {
- aml_v4l2_debug(3, "[%d] enque capture buf idx %d, %p\n",
+ aml_v4l2_debug(2, "[%d] enque capture buf idx %d, %p",
ctx->id, vb->index, vb);
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;
-
- /*save capture bufs to be used for resetting config.*/
- list_add(&buf->node, &ctx->capture_list);
} else if (buf->frame_buffer.status == FB_ST_DISPLAY) {
buf->queued_in_vb2 = false;
buf->queued_in_v4l2 = true;
@@ -1488,11 +1621,14 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
return;
}
- src_mem.va = vb2_plane_vaddr(vb, 0);
+ src_mem.vaddr = vb2_plane_vaddr(vb, 0);
src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
- src_mem.size = (size_t)vb->planes[0].bytesused;
- if (vdec_if_probe(ctx, &src_mem, NULL))
+ src_mem.size = vb->planes[0].bytesused;
+ if (vdec_if_probe(ctx, &src_mem, NULL)) {
+ v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_DONE);
return;
+ }
if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo)) {
pr_err("[%d] GET_PARAM_PICTURE_INFO err\n", ctx->id);
@@ -1504,6 +1640,9 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
return;
}
+ if (!dpb)
+ return;
+
ctx->dpb_size = dpb;
ctx->last_decoded_picinfo = ctx->picinfo;
aml_vdec_queue_res_chg_event(ctx);
@@ -1527,13 +1666,11 @@ static void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
- //mutex_lock(&ctx->lock);
- if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
buf->queued_in_v4l2 = false;
buf->queued_in_vb2 = false;
}
buf_error = buf->error;
- //mutex_unlock(&ctx->lock);
if (buf_error) {
aml_v4l2_err("[%d] Unrecoverable error on buffer.", ctx->id);
@@ -1556,7 +1693,7 @@ static int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
aml_v4l2_debug(4, "[%d] (%d) id=%d",
ctx->id, vb->vb2_queue->type, vb->index);
- if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
buf->used = false;
buf->ready_to_display = false;
buf->queued_in_v4l2 = false;
@@ -1578,23 +1715,32 @@ static int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
aml_v4l2_debug(3, "[%d] IN alloc, addr: %x, size: %u, idx: %u",
ctx->id, phy_addr, size, vb->index);
} else {
- size = vb->planes[0].length;
- phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
snprintf(owner, PATH_MAX, "%s-%d", "v4l-output", ctx->id);
strncpy(buf->mem_onwer, owner, sizeof(buf->mem_onwer));
buf->mem_onwer[sizeof(buf->mem_onwer) - 1] = '\0';
- buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
- phy_addr, size, vb->index);
- aml_v4l2_debug(3, "[%d] OUT Y alloc, addr: %x, size: %u, idx: %u",
- ctx->id, phy_addr, size, vb->index);
-
- size = vb->planes[1].length;
- phy_addr = vb2_dma_contig_plane_dma_addr(vb, 1);
- buf->mem[1] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
+ if ((vb->memory == VB2_MEMORY_MMAP) && (vb->num_planes == 1)) {
+ size = vb->planes[0].length;
+ phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
phy_addr, size, vb->index);
- aml_v4l2_debug(3, "[%d] OUT C alloc, addr: %x, size: %u, idx: %u",
- ctx->id, phy_addr, size, vb->index);
+ aml_v4l2_debug(3, "[%d] OUT Y alloc, addr: %x, size: %u, idx: %u",
+ ctx->id, phy_addr, size, vb->index);
+ } else if ((vb->memory == VB2_MEMORY_MMAP) && (vb->num_planes == 2)) {
+ size = vb->planes[0].length;
+ phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
+ phy_addr, size, vb->index);
+ aml_v4l2_debug(3, "[%d] OUT Y alloc, addr: %x, size: %u, idx: %u",
+ ctx->id, phy_addr, size, vb->index);
+
+ size = vb->planes[1].length;
+ phy_addr = vb2_dma_contig_plane_dma_addr(vb, 1);
+ buf->mem[1] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
+ phy_addr, size, vb->index);
+ aml_v4l2_debug(3, "[%d] OUT C alloc, addr: %x, size: %u, idx: %u",
+ ctx->id, phy_addr, size, vb->index);
+ }
}
__putname(owner);
@@ -1624,15 +1770,17 @@ static void codec_mm_bufs_cnt_clean(struct vb2_queue *q)
continue;
}
- v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[0]);
- v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[1]);
+ if (q->memory == VB2_MEMORY_MMAP) {
+ v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[0]);
+ v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[1]);
- aml_v4l2_debug(3, "[%d] OUT Y clean, addr: %lx, size: %u, idx: %u",
- ctx->id, buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i);
- aml_v4l2_debug(3, "[%d] OUT C clean, addr: %lx, size: %u, idx: %u",
- ctx->id, buf->mem[1]->phy_addr, buf->mem[1]->buffer_size, i);
- buf->mem[0] = NULL;
- buf->mem[1] = NULL;
+ aml_v4l2_debug(3, "[%d] OUT Y clean, addr: %lx, size: %u, idx: %u",
+ ctx->id, buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i);
+ aml_v4l2_debug(3, "[%d] OUT C clean, addr: %lx, size: %u, idx: %u",
+ ctx->id, buf->mem[1]->phy_addr, buf->mem[1]->buffer_size, i);
+ buf->mem[0] = NULL;
+ buf->mem[1] = NULL;
+ }
}
}
@@ -1659,26 +1807,23 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
codec_mm_bufs_cnt_clean(q);
if (V4L2_TYPE_IS_OUTPUT(q->type)) {
- while (v4l2_m2m_src_buf_remove(ctx->m2m_ctx));
- return;
- }
+ while ((vb2_v4l2 = v4l2_m2m_src_buf_remove(ctx->m2m_ctx)))
+ v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
+ } else {
+ while ((vb2_v4l2 = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx)))
+ v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
- while (v4l2_m2m_dst_buf_remove(ctx->m2m_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;
- for (i = 0; i < q->num_buffers; ++i) {
- if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE) {
- q->bufs[i]->state = VB2_BUF_STATE_DEQUEUED;
- atomic_dec(&q->owned_by_drv_count);
+ /*pr_info("idx: %d, state: %d\n",
+ q->bufs[i]->index, q->bufs[i]->state);*/
}
- 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;
- }
- while (!list_empty(&ctx->capture_list)) {
- buf = list_entry(ctx->capture_list.next,
- struct aml_video_dec_buf, node);
- list_del(&buf->node);
+ ctx->buf_used_count = 0;
}
}
@@ -1738,6 +1883,7 @@ static int aml_vdec_g_v_ctrl(struct v4l2_ctrl *ctrl)
} else {
pr_err("Seqinfo not ready.\n");
ctrl->val = 0;
+ ret = -EINVAL;
}
break;
default:
@@ -1846,28 +1992,36 @@ static const struct vb2_ops aml_vdec_vb2_ops = {
};
const struct v4l2_ioctl_ops aml_vdec_ioctl_ops = {
- .vidioc_streamon = vidioc_decoder_streamon,
- .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
- .vidioc_reqbufs = vidioc_decoder_reqbufs,
- .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
- .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,//??
- //.vidioc_g_ctrl = vidioc_vdec_g_ctrl,
+ .vidioc_streamon = vidioc_decoder_streamon,
+ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
+ .vidioc_reqbufs = vidioc_decoder_reqbufs,
+ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
+ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,//??
+ //.vidioc_g_ctrl = vidioc_vdec_g_ctrl,
- .vidioc_qbuf = vidioc_vdec_qbuf,
- .vidioc_dqbuf = vidioc_vdec_dqbuf,
+ .vidioc_qbuf = vidioc_vdec_qbuf,
+ .vidioc_dqbuf = vidioc_vdec_dqbuf,
.vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap_mplane,
.vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_out_mplane,
+ .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out_mplane,
.vidioc_s_fmt_vid_cap_mplane = vidioc_vdec_s_fmt,
+ .vidioc_s_fmt_vid_cap = vidioc_vdec_s_fmt,
.vidioc_s_fmt_vid_out_mplane = vidioc_vdec_s_fmt,
+ .vidioc_s_fmt_vid_out = vidioc_vdec_s_fmt,
.vidioc_g_fmt_vid_cap_mplane = vidioc_vdec_g_fmt,
+ .vidioc_g_fmt_vid_cap = vidioc_vdec_g_fmt,
.vidioc_g_fmt_vid_out_mplane = vidioc_vdec_g_fmt,
+ .vidioc_g_fmt_vid_out = vidioc_vdec_g_fmt,
.vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
.vidioc_enum_fmt_vid_cap_mplane = vidioc_vdec_enum_fmt_vid_cap_mplane,
+ .vidioc_enum_fmt_vid_cap = vidioc_vdec_enum_fmt_vid_cap_mplane,
.vidioc_enum_fmt_vid_out_mplane = vidioc_vdec_enum_fmt_vid_out_mplane,
+ .vidioc_enum_fmt_vid_out = vidioc_vdec_enum_fmt_vid_out_mplane,
.vidioc_enum_framesizes = vidioc_enum_framesizes,
.vidioc_querycap = vidioc_vdec_querycap,
@@ -1896,13 +2050,14 @@ int aml_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
src_vq->mem_ops = &vb2_dma_contig_memops;
src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
src_vq->lock = &ctx->dev->dev_mutex;
-
ret = vb2_queue_init(src_vq);
if (ret) {
aml_v4l2_err("[%d] Failed to initialize videobuf2 queue(output)", ctx->id);
return ret;
}
- dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+ dst_vq->type = multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
+ V4L2_BUF_TYPE_VIDEO_CAPTURE;
dst_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
dst_vq->drv_priv = ctx;
dst_vq->buf_struct_size = sizeof(struct aml_video_dec_buf);
@@ -1910,7 +2065,6 @@ int aml_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
dst_vq->mem_ops = &vb2_dma_contig_memops;
dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
dst_vq->lock = &ctx->dev->dev_mutex;
-
ret = vb2_queue_init(dst_vq);
if (ret) {
vb2_queue_release(src_vq);