summaryrefslogtreecommitdiff
path: root/drivers/media/platform/amphion/vpu_v4l2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/amphion/vpu_v4l2.c')
-rw-r--r--drivers/media/platform/amphion/vpu_v4l2.c69
1 files changed, 46 insertions, 23 deletions
diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
index c88738e8fff7..47dff9a35bb4 100644
--- a/drivers/media/platform/amphion/vpu_v4l2.c
+++ b/drivers/media/platform/amphion/vpu_v4l2.c
@@ -24,6 +24,11 @@
#include "vpu_msgs.h"
#include "vpu_helpers.h"
+static char *vpu_type_name(u32 type)
+{
+ return V4L2_TYPE_IS_OUTPUT(type) ? "output" : "capture";
+}
+
void vpu_inst_lock(struct vpu_inst *inst)
{
mutex_lock(&inst->lock);
@@ -42,7 +47,7 @@ dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no)
vb->planes[plane_no].data_offset;
}
-unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no)
+static unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no)
{
if (plane_no >= vb->num_planes)
return 0;
@@ -63,6 +68,13 @@ unsigned int vpu_get_buffer_state(struct vb2_v4l2_buffer *vbuf)
return vpu_buf->state;
}
+void vpu_set_buffer_average_qp(struct vb2_v4l2_buffer *vbuf, u32 qp)
+{
+ struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+ vpu_buf->average_qp = qp;
+}
+
void vpu_v4l2_set_error(struct vpu_inst *inst)
{
vpu_inst_lock(inst);
@@ -74,7 +86,7 @@ void vpu_v4l2_set_error(struct vpu_inst *inst)
vpu_inst_unlock(inst);
}
-int vpu_notify_eos(struct vpu_inst *inst)
+static int vpu_notify_eos(struct vpu_inst *inst)
{
static const struct v4l2_event ev = {
.id = 0,
@@ -337,16 +349,6 @@ struct vb2_v4l2_buffer *vpu_next_src_buf(struct vpu_inst *inst)
if (!src_buf || vpu_get_buffer_state(src_buf) == VPU_BUF_STATE_IDLE)
return NULL;
- while (vpu_vb_is_codecconfig(src_buf)) {
- v4l2_m2m_src_buf_remove(inst->fh.m2m_ctx);
- vpu_set_buffer_state(src_buf, VPU_BUF_STATE_IDLE);
- v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
-
- src_buf = v4l2_m2m_next_src_buf(inst->fh.m2m_ctx);
- if (!src_buf || vpu_get_buffer_state(src_buf) == VPU_BUF_STATE_IDLE)
- return NULL;
- }
-
return src_buf;
}
@@ -494,14 +496,25 @@ static int vpu_vb2_queue_setup(struct vb2_queue *vq,
call_void_vop(inst, release);
}
+ if (V4L2_TYPE_IS_CAPTURE(vq->type))
+ call_void_vop(inst, reset_frame_store);
+
return 0;
}
static int vpu_vb2_buf_init(struct vb2_buffer *vb)
{
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+ struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+ vpu_buf->fs_id = -1;
vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+
+ if (!inst->ops->attach_frame_store || V4L2_TYPE_IS_OUTPUT(vb->type))
+ return 0;
+
+ call_void_vop(inst, attach_frame_store, vb);
return 0;
}
@@ -539,6 +552,15 @@ static void vpu_vb2_buf_finish(struct vb2_buffer *vb)
struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
struct vb2_queue *q = vb->vb2_queue;
+ if (V4L2_TYPE_IS_CAPTURE(vb->type)) {
+ struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+ struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&inst->ctrl_handler,
+ V4L2_CID_MPEG_VIDEO_AVERAGE_QP);
+
+ if (ctrl)
+ v4l2_ctrl_s_ctrl(ctrl, vpu_buf->average_qp);
+ }
+
if (vbuf->flags & V4L2_BUF_FLAG_LAST)
vpu_notify_eos(inst);
@@ -546,7 +568,8 @@ static void vpu_vb2_buf_finish(struct vb2_buffer *vb)
call_void_vop(inst, on_queue_empty, q->type);
}
-void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type, enum vb2_buffer_state state)
+static void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type,
+ enum vb2_buffer_state state)
{
struct vb2_v4l2_buffer *buf;
@@ -630,8 +653,6 @@ static const struct vb2_ops vpu_vb2_ops = {
.start_streaming = vpu_vb2_start_streaming,
.stop_streaming = vpu_vb2_stop_streaming,
.buf_queue = vpu_vb2_buf_queue,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
};
static int vpu_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
@@ -682,19 +703,17 @@ static int vpu_v4l2_release(struct vpu_inst *inst)
{
vpu_trace(inst->vpu->dev, "%p\n", inst);
- vpu_release_core(inst->core);
- put_device(inst->dev);
-
if (inst->workqueue) {
cancel_work_sync(&inst->msg_work);
destroy_workqueue(inst->workqueue);
inst->workqueue = NULL;
}
+ vpu_release_core(inst->core);
+ put_device(inst->dev);
+
v4l2_ctrl_handler_free(&inst->ctrl_handler);
mutex_destroy(&inst->lock);
- v4l2_fh_del(&inst->fh);
- v4l2_fh_exit(&inst->fh);
call_void_vop(inst, cleanup);
@@ -731,7 +750,7 @@ int vpu_v4l2_open(struct file *file, struct vpu_inst *inst)
inst->min_buffer_cap = 2;
inst->min_buffer_out = 2;
v4l2_fh_init(&inst->fh, func->vfd);
- v4l2_fh_add(&inst->fh);
+ v4l2_fh_add(&inst->fh, file);
ret = call_vop(inst, ctrl_init);
if (ret)
@@ -745,7 +764,6 @@ int vpu_v4l2_open(struct file *file, struct vpu_inst *inst)
}
inst->fh.ctrl_handler = &inst->ctrl_handler;
- file->private_data = &inst->fh;
inst->state = VPU_CODEC_STATE_DEINIT;
inst->workqueue = alloc_ordered_workqueue("vpu_inst", WQ_MEM_RECLAIM);
if (inst->workqueue) {
@@ -763,6 +781,8 @@ int vpu_v4l2_open(struct file *file, struct vpu_inst *inst)
return 0;
error:
+ v4l2_fh_del(&inst->fh, file);
+ v4l2_fh_exit(&inst->fh);
vpu_inst_put(inst);
return ret;
}
@@ -782,6 +802,9 @@ int vpu_v4l2_close(struct file *file)
call_void_vop(inst, release);
vpu_inst_unlock(inst);
+ v4l2_fh_del(&inst->fh, file);
+ v4l2_fh_exit(&inst->fh);
+
vpu_inst_unregister(inst);
vpu_inst_put(inst);
@@ -825,6 +848,7 @@ int vpu_add_func(struct vpu_dev *vpu, struct vpu_func *func)
vfd->fops = vdec_get_fops();
vfd->ioctl_ops = vdec_get_ioctl_ops();
}
+ video_set_drvdata(vfd, vpu);
ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
if (ret) {
@@ -832,7 +856,6 @@ int vpu_add_func(struct vpu_dev *vpu, struct vpu_func *func)
v4l2_m2m_release(func->m2m_dev);
return ret;
}
- video_set_drvdata(vfd, vpu);
func->vfd = vfd;
ret = v4l2_m2m_register_media_controller(func->m2m_dev, func->vfd, func->function);