mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
media: mediatek: vcodec: separate struct 'mtk_vcodec_ctx'
Adding different context struct for encoder and decoder and removing struct 'mtk_vcodec_ctx'. Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
This commit is contained in:
committed by
Mauro Carvalho Chehab
parent
41f03c673c
commit
01abf5fbb0
76
drivers/media/platform/mediatek/vcodec/mtk_vcodec_cmn_drv.h
Normal file
76
drivers/media/platform/mediatek/vcodec/mtk_vcodec_cmn_drv.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2023 MediaTek Inc.
|
||||
* Author: Yunfei Dong <yunfei.dong@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _MTK_VCODEC_COM_DRV_H_
|
||||
#define _MTK_VCODEC_COM_DRV_H_
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
#include <media/v4l2-mem2mem.h>
|
||||
#include <media/videobuf2-core.h>
|
||||
|
||||
#define MTK_VCODEC_MAX_PLANES 3
|
||||
|
||||
/**
|
||||
* enum mtk_instance_state - The state of an MTK Vcodec instance.
|
||||
* @MTK_STATE_FREE: default state when instance is created
|
||||
* @MTK_STATE_INIT: vcodec instance is initialized
|
||||
* @MTK_STATE_HEADER: vdec had sps/pps header parsed or venc
|
||||
* had sps/pps header encoded
|
||||
* @MTK_STATE_FLUSH: vdec is flushing. Only used by decoder
|
||||
* @MTK_STATE_ABORT: vcodec should be aborted
|
||||
*/
|
||||
enum mtk_instance_state {
|
||||
MTK_STATE_FREE = 0,
|
||||
MTK_STATE_INIT = 1,
|
||||
MTK_STATE_HEADER = 2,
|
||||
MTK_STATE_FLUSH = 3,
|
||||
MTK_STATE_ABORT = 4,
|
||||
};
|
||||
|
||||
enum mtk_fmt_type {
|
||||
MTK_FMT_DEC = 0,
|
||||
MTK_FMT_ENC = 1,
|
||||
MTK_FMT_FRAME = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct mtk_video_fmt - Structure used to store information about pixelformats
|
||||
*/
|
||||
struct mtk_video_fmt {
|
||||
u32 fourcc;
|
||||
enum mtk_fmt_type type;
|
||||
u32 num_planes;
|
||||
u32 flags;
|
||||
struct v4l2_frmsize_stepwise frmsize;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct mtk_q_data - Structure used to store information about queue
|
||||
*/
|
||||
struct mtk_q_data {
|
||||
unsigned int visible_width;
|
||||
unsigned int visible_height;
|
||||
unsigned int coded_width;
|
||||
unsigned int coded_height;
|
||||
enum v4l2_field field;
|
||||
unsigned int bytesperline[MTK_VCODEC_MAX_PLANES];
|
||||
unsigned int sizeimage[MTK_VCODEC_MAX_PLANES];
|
||||
const struct mtk_video_fmt *fmt;
|
||||
};
|
||||
|
||||
/*
|
||||
* enum mtk_instance_type - The type of an MTK Vcodec instance.
|
||||
*/
|
||||
enum mtk_instance_type {
|
||||
MTK_INST_DECODER = 0,
|
||||
MTK_INST_ENCODER = 1,
|
||||
};
|
||||
|
||||
#endif /* _MTK_VCODEC_COM_DRV_H_ */
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "mtk_vcodec_drv.h"
|
||||
#include "mtk_vcodec_util.h"
|
||||
|
||||
static void mtk_vdec_dbgfs_get_format_type(struct mtk_vcodec_ctx *ctx, char *buf,
|
||||
static void mtk_vdec_dbgfs_get_format_type(struct mtk_vcodec_dec_ctx *ctx, char *buf,
|
||||
int *used, int total)
|
||||
{
|
||||
int curr_len;
|
||||
@@ -91,7 +91,7 @@ static ssize_t mtk_vdec_dbgfs_read(struct file *filp, char __user *ubuf,
|
||||
struct mtk_vcodec_dev *vcodec_dev = filp->private_data;
|
||||
struct mtk_vcodec_dbgfs *dbgfs = &vcodec_dev->dbgfs;
|
||||
struct mtk_vcodec_dbgfs_inst *dbgfs_inst;
|
||||
struct mtk_vcodec_ctx *ctx;
|
||||
struct mtk_vcodec_dec_ctx *ctx;
|
||||
int total_len = 200 * (dbgfs->inst_count == 0 ? 1 : dbgfs->inst_count);
|
||||
int used_len = 0, curr_len, ret;
|
||||
bool dbgfs_index[MTK_VDEC_DBGFS_MAX] = {0};
|
||||
@@ -143,7 +143,7 @@ static const struct file_operations vdec_fops = {
|
||||
.read = mtk_vdec_dbgfs_read,
|
||||
};
|
||||
|
||||
void mtk_vcodec_dbgfs_create(struct mtk_vcodec_ctx *ctx)
|
||||
void mtk_vcodec_dbgfs_create(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
struct mtk_vcodec_dbgfs_inst *dbgfs_inst;
|
||||
struct mtk_vcodec_dev *vcodec_dev = ctx->dev;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define __MTK_VCODEC_DBGFS_H__
|
||||
|
||||
struct mtk_vcodec_dev;
|
||||
struct mtk_vcodec_ctx;
|
||||
struct mtk_vcodec_dec_ctx;
|
||||
|
||||
/*
|
||||
* enum mtk_vdec_dbgfs_log_index - used to get different debug information
|
||||
@@ -22,12 +22,12 @@ enum mtk_vdec_dbgfs_log_index {
|
||||
/**
|
||||
* struct mtk_vcodec_dbgfs_inst - debugfs information for each inst
|
||||
* @node: list node for each inst
|
||||
* @vcodec_ctx: struct mtk_vcodec_ctx
|
||||
* @vcodec_ctx: struct mtk_vcodec_dec_ctx
|
||||
* @inst_id: index of the context that the same with ctx->id
|
||||
*/
|
||||
struct mtk_vcodec_dbgfs_inst {
|
||||
struct list_head node;
|
||||
struct mtk_vcodec_ctx *vcodec_ctx;
|
||||
struct mtk_vcodec_dec_ctx *vcodec_ctx;
|
||||
int inst_id;
|
||||
};
|
||||
|
||||
@@ -50,12 +50,12 @@ struct mtk_vcodec_dbgfs {
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
void mtk_vcodec_dbgfs_create(struct mtk_vcodec_ctx *ctx);
|
||||
void mtk_vcodec_dbgfs_create(struct mtk_vcodec_dec_ctx *ctx);
|
||||
void mtk_vcodec_dbgfs_remove(struct mtk_vcodec_dev *vcodec_dev, int ctx_id);
|
||||
void mtk_vcodec_dbgfs_init(struct mtk_vcodec_dev *vcodec_dev, bool is_encode);
|
||||
void mtk_vcodec_dbgfs_deinit(struct mtk_vcodec_dev *vcodec_dev);
|
||||
#else
|
||||
static inline void mtk_vcodec_dbgfs_create(struct mtk_vcodec_ctx *ctx)
|
||||
static inline void mtk_vcodec_dbgfs_create(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ mtk_vdec_find_format(struct v4l2_format *f,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx *ctx, int format_index)
|
||||
static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_dec_ctx *ctx, int format_index)
|
||||
{
|
||||
const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
|
||||
const struct mtk_video_fmt *fmt;
|
||||
@@ -55,7 +55,7 @@ static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx *ctx, int format_index)
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx,
|
||||
static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_dec_ctx *ctx,
|
||||
enum v4l2_buf_type type)
|
||||
{
|
||||
if (V4L2_TYPE_IS_OUTPUT(type))
|
||||
@@ -74,7 +74,7 @@ static int vidioc_try_decoder_cmd(struct file *file, void *priv,
|
||||
static int vidioc_decoder_cmd(struct file *file, void *priv,
|
||||
struct v4l2_decoder_cmd *cmd)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
|
||||
struct vb2_queue *src_vq, *dst_vq;
|
||||
int ret;
|
||||
|
||||
@@ -112,23 +112,23 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx)
|
||||
void mtk_vdec_unlock(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]);
|
||||
}
|
||||
|
||||
void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx)
|
||||
void mtk_vdec_lock(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
mutex_lock(&ctx->dev->dec_mutex[ctx->hw_id]);
|
||||
}
|
||||
|
||||
void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx)
|
||||
void mtk_vcodec_dec_release(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
vdec_if_deinit(ctx);
|
||||
ctx->state = MTK_STATE_FREE;
|
||||
}
|
||||
|
||||
void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
|
||||
void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
struct mtk_q_data *q_data;
|
||||
|
||||
@@ -169,7 +169,7 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
|
||||
static int vidioc_vdec_qbuf(struct file *file, void *priv,
|
||||
struct v4l2_buffer *buf)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
|
||||
|
||||
if (ctx->state == MTK_STATE_ABORT) {
|
||||
mtk_v4l2_vdec_err(ctx, "[%d] Call on QBUF after unrecoverable error", ctx->id);
|
||||
@@ -182,7 +182,7 @@ static int vidioc_vdec_qbuf(struct file *file, void *priv,
|
||||
static int vidioc_vdec_dqbuf(struct file *file, void *priv,
|
||||
struct v4l2_buffer *buf)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
|
||||
|
||||
if (ctx->state == MTK_STATE_ABORT) {
|
||||
mtk_v4l2_vdec_err(ctx, "[%d] Call on DQBUF after unrecoverable error", ctx->id);
|
||||
@@ -194,7 +194,7 @@ static int vidioc_vdec_dqbuf(struct file *file, void *priv,
|
||||
|
||||
static int mtk_vcodec_dec_get_chip_name(void *priv)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
|
||||
struct device *dev = &ctx->dev->plat_dev->dev;
|
||||
|
||||
if (of_device_is_compatible(dev->of_node, "mediatek,mt8173-vcodec-dec"))
|
||||
@@ -216,7 +216,7 @@ static int mtk_vcodec_dec_get_chip_name(void *priv)
|
||||
static int vidioc_vdec_querycap(struct file *file, void *priv,
|
||||
struct v4l2_capability *cap)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
|
||||
struct device *dev = &ctx->dev->plat_dev->dev;
|
||||
int platform_name = mtk_vcodec_dec_get_chip_name(priv);
|
||||
|
||||
@@ -229,7 +229,7 @@ static int vidioc_vdec_querycap(struct file *file, void *priv,
|
||||
static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
|
||||
const struct v4l2_event_subscription *sub)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(fh);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(fh);
|
||||
|
||||
if (ctx->dev->vdec_pdata->uses_stateless_api)
|
||||
return v4l2_ctrl_subscribe_event(fh, sub);
|
||||
@@ -244,7 +244,7 @@ static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
|
||||
}
|
||||
}
|
||||
|
||||
static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f,
|
||||
static int vidioc_try_fmt(struct mtk_vcodec_dec_ctx *ctx, struct v4l2_format *f,
|
||||
const struct mtk_video_fmt *fmt)
|
||||
{
|
||||
struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
|
||||
@@ -312,7 +312,7 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
const struct mtk_video_fmt *fmt;
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
|
||||
const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
|
||||
|
||||
fmt = mtk_vdec_find_format(f, dec_pdata);
|
||||
@@ -330,7 +330,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
|
||||
{
|
||||
struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
|
||||
const struct mtk_video_fmt *fmt;
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
|
||||
const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
|
||||
|
||||
fmt = mtk_vdec_find_format(f, dec_pdata);
|
||||
@@ -351,7 +351,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
|
||||
static int vidioc_vdec_g_selection(struct file *file, void *priv,
|
||||
struct v4l2_selection *s)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
|
||||
struct mtk_q_data *q_data;
|
||||
|
||||
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
@@ -400,7 +400,7 @@ static int vidioc_vdec_g_selection(struct file *file, void *priv,
|
||||
static int vidioc_vdec_s_selection(struct file *file, void *priv,
|
||||
struct v4l2_selection *s)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
|
||||
|
||||
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
return -EINVAL;
|
||||
@@ -422,7 +422,7 @@ static int vidioc_vdec_s_selection(struct file *file, void *priv,
|
||||
static int vidioc_vdec_s_fmt(struct file *file, void *priv,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
|
||||
struct v4l2_pix_format_mplane *pix_mp;
|
||||
struct mtk_q_data *q_data;
|
||||
int ret = 0;
|
||||
@@ -552,7 +552,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
|
||||
struct v4l2_frmsizeenum *fsize)
|
||||
{
|
||||
int i = 0;
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
|
||||
const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
|
||||
|
||||
if (fsize->index != 0)
|
||||
@@ -584,7 +584,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
|
||||
static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
|
||||
bool output_queue)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
|
||||
const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
|
||||
const struct mtk_video_fmt *fmt;
|
||||
int i, j = 0;
|
||||
@@ -630,7 +630,7 @@ static int vidioc_vdec_enum_fmt_vid_out(struct file *file, void *priv,
|
||||
static int vidioc_vdec_g_fmt(struct file *file, void *priv,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
|
||||
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
|
||||
struct vb2_queue *vq;
|
||||
struct mtk_q_data *q_data;
|
||||
@@ -719,7 +719,7 @@ int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
|
||||
unsigned int *nplanes, unsigned int sizes[],
|
||||
struct device *alloc_devs[])
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq);
|
||||
struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vq);
|
||||
struct mtk_q_data *q_data;
|
||||
unsigned int i;
|
||||
|
||||
@@ -761,7 +761,7 @@ int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
|
||||
|
||||
int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct mtk_q_data *q_data;
|
||||
int i;
|
||||
|
||||
@@ -785,7 +785,7 @@ int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb)
|
||||
|
||||
void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct vb2_v4l2_buffer *vb2_v4l2;
|
||||
struct mtk_video_dec_buf *buf;
|
||||
bool buf_error;
|
||||
@@ -823,7 +823,7 @@ int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
|
||||
|
||||
int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
|
||||
struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(q);
|
||||
|
||||
if (ctx->state == MTK_STATE_FLUSH)
|
||||
ctx->state = MTK_STATE_HEADER;
|
||||
@@ -834,7 +834,7 @@ int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
|
||||
void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
|
||||
{
|
||||
struct vb2_v4l2_buffer *src_buf = NULL, *dst_buf = NULL;
|
||||
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
|
||||
struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(q);
|
||||
int ret;
|
||||
|
||||
mtk_v4l2_vdec_dbg(3, ctx, "[%d] (%d) state=(%x) ctx->decoded_frame_cnt=%d",
|
||||
@@ -889,7 +889,7 @@ void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
|
||||
|
||||
static void m2mops_vdec_device_run(void *priv)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = priv;
|
||||
struct mtk_vcodec_dec_ctx *ctx = priv;
|
||||
struct mtk_vcodec_dev *dev = ctx->dev;
|
||||
|
||||
queue_work(dev->decode_workqueue, &ctx->decode_work);
|
||||
@@ -897,7 +897,7 @@ static void m2mops_vdec_device_run(void *priv)
|
||||
|
||||
static int m2mops_vdec_job_ready(void *m2m_priv)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = m2m_priv;
|
||||
struct mtk_vcodec_dec_ctx *ctx = m2m_priv;
|
||||
|
||||
mtk_v4l2_vdec_dbg(3, ctx, "[%d]", ctx->id);
|
||||
|
||||
@@ -916,7 +916,7 @@ static int m2mops_vdec_job_ready(void *m2m_priv)
|
||||
|
||||
static void m2mops_vdec_job_abort(void *priv)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = priv;
|
||||
struct mtk_vcodec_dec_ctx *ctx = priv;
|
||||
|
||||
ctx->state = MTK_STATE_ABORT;
|
||||
}
|
||||
@@ -964,7 +964,7 @@ const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops = {
|
||||
int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
|
||||
struct vb2_queue *dst_vq)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = priv;
|
||||
struct mtk_vcodec_dec_ctx *ctx = priv;
|
||||
int ret = 0;
|
||||
|
||||
mtk_v4l2_vdec_dbg(3, ctx, "[%d]", ctx->id);
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <media/videobuf2-core.h>
|
||||
#include <media/v4l2-mem2mem.h>
|
||||
|
||||
#include "mtk_vcodec_dec_drv.h"
|
||||
|
||||
#define VCODEC_DEC_ALIGNED_64 64
|
||||
#define VCODEC_CAPABILITY_4K_DISABLED 0x10
|
||||
#define VCODEC_DEC_4K_CODED_WIDTH 4096U
|
||||
@@ -78,12 +80,12 @@ extern const struct mtk_vcodec_dec_pdata mtk_vdec_single_core_pdata;
|
||||
* mtk_vdec_lock get decoder hw lock and set curr_ctx
|
||||
* to ctx instance that get lock
|
||||
*/
|
||||
void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx);
|
||||
void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx);
|
||||
void mtk_vdec_unlock(struct mtk_vcodec_dec_ctx *ctx);
|
||||
void mtk_vdec_lock(struct mtk_vcodec_dec_ctx *ctx);
|
||||
int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
|
||||
struct vb2_queue *dst_vq);
|
||||
void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx);
|
||||
void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx);
|
||||
void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_dec_ctx *ctx);
|
||||
void mtk_vcodec_dec_release(struct mtk_vcodec_dec_ctx *ctx);
|
||||
|
||||
/*
|
||||
* VB2 ops
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "mtk_vcodec_util.h"
|
||||
#include "mtk_vcodec_fw.h"
|
||||
|
||||
static int mtk_vcodec_get_hw_count(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_dev *dev)
|
||||
static int mtk_vcodec_get_hw_count(struct mtk_vcodec_dec_ctx *ctx, struct mtk_vcodec_dev *dev)
|
||||
{
|
||||
switch (dev->vdec_pdata->hw_arch) {
|
||||
case MTK_VDEC_PURE_SINGLE_CORE:
|
||||
@@ -57,7 +57,7 @@ static bool mtk_vcodec_is_hw_active(struct mtk_vcodec_dev *dev)
|
||||
static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
|
||||
{
|
||||
struct mtk_vcodec_dev *dev = priv;
|
||||
struct mtk_vcodec_ctx *ctx;
|
||||
struct mtk_vcodec_dec_ctx *ctx;
|
||||
unsigned int dec_done_status = 0;
|
||||
void __iomem *vdec_misc_addr = dev->reg_base[VDEC_MISC] +
|
||||
VDEC_IRQ_CFG_REG;
|
||||
@@ -81,7 +81,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
|
||||
writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR),
|
||||
dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
|
||||
|
||||
wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
|
||||
wake_up_dec_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
|
||||
|
||||
mtk_v4l2_vdec_dbg(3, ctx, "wake up ctx %d, dec_done_status=%x", ctx->id, dec_done_status);
|
||||
|
||||
@@ -198,7 +198,7 @@ static int mtk_vcodec_init_dec_resources(struct mtk_vcodec_dev *dev)
|
||||
static int fops_vcodec_open(struct file *file)
|
||||
{
|
||||
struct mtk_vcodec_dev *dev = video_drvdata(file);
|
||||
struct mtk_vcodec_ctx *ctx = NULL;
|
||||
struct mtk_vcodec_dec_ctx *ctx = NULL;
|
||||
int ret = 0, i, hw_count;
|
||||
struct vb2_queue *src_vq;
|
||||
|
||||
@@ -295,7 +295,7 @@ err_ctrls_setup:
|
||||
static int fops_vcodec_release(struct file *file)
|
||||
{
|
||||
struct mtk_vcodec_dev *dev = video_drvdata(file);
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(file->private_data);
|
||||
struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(file->private_data);
|
||||
|
||||
mtk_v4l2_vdec_dbg(0, ctx, "[%d] decoder", ctx->id);
|
||||
mutex_lock(&dev->dev_mutex);
|
||||
|
||||
156
drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.h
Normal file
156
drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.h
Normal file
@@ -0,0 +1,156 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2023 MediaTek Inc.
|
||||
* Author: Yunfei Dong <yunfei.dong@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _MTK_VCODEC_DEC_DRV_H_
|
||||
#define _MTK_VCODEC_DEC_DRV_H_
|
||||
|
||||
#include "mtk_vcodec_cmn_drv.h"
|
||||
#include "mtk_vcodec_fw_priv.h"
|
||||
#include "vdec_msg_queue.h"
|
||||
|
||||
/**
|
||||
* struct vdec_pic_info - picture size information
|
||||
* @pic_w: picture width
|
||||
* @pic_h: picture height
|
||||
* @buf_w: picture buffer width (64 aligned up from pic_w)
|
||||
* @buf_h: picture buffer heiht (64 aligned up from pic_h)
|
||||
* @fb_sz: bitstream size of each plane
|
||||
* E.g. suppose picture size is 176x144,
|
||||
* buffer size will be aligned to 176x160.
|
||||
* @cap_fourcc: fourcc number(may changed when resolution change)
|
||||
* @reserved: align struct to 64-bit in order to adjust 32-bit and 64-bit os.
|
||||
*/
|
||||
struct vdec_pic_info {
|
||||
unsigned int pic_w;
|
||||
unsigned int pic_h;
|
||||
unsigned int buf_w;
|
||||
unsigned int buf_h;
|
||||
unsigned int fb_sz[VIDEO_MAX_PLANES];
|
||||
unsigned int cap_fourcc;
|
||||
unsigned int reserved;
|
||||
};
|
||||
|
||||
/*
|
||||
* enum mtk_vdec_hw_id - Hardware index used to separate
|
||||
* different hardware
|
||||
*/
|
||||
enum mtk_vdec_hw_id {
|
||||
MTK_VDEC_CORE,
|
||||
MTK_VDEC_LAT0,
|
||||
MTK_VDEC_LAT1,
|
||||
MTK_VDEC_LAT_SOC,
|
||||
MTK_VDEC_HW_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_vcodec_dec_ctx - Context (instance) private data.
|
||||
*
|
||||
* @type: type of decoder instance
|
||||
* @dev: pointer to the mtk_vcodec_dev of the device
|
||||
* @list: link to ctx_list of mtk_vcodec_dev
|
||||
*
|
||||
* @fh: struct v4l2_fh
|
||||
* @m2m_ctx: pointer to the v4l2_m2m_ctx of the context
|
||||
* @q_data: store information of input and output queue of the context
|
||||
* @id: index of the context that this structure describes
|
||||
* @state: state of the context
|
||||
*
|
||||
* @dec_if: hooked decoder driver interface
|
||||
* @drv_handle: driver handle for specific decode/encode instance
|
||||
*
|
||||
* @picinfo: store picture info after header parsing
|
||||
* @dpb_size: store dpb count after header parsing
|
||||
*
|
||||
* @int_cond: variable used by the waitqueue
|
||||
* @int_type: type of the last interrupt
|
||||
* @queue: waitqueue that can be used to wait for this context to finish
|
||||
* @irq_status: irq status
|
||||
*
|
||||
* @ctrl_hdl: handler for v4l2 framework
|
||||
* @decode_work: worker for the decoding
|
||||
* @last_decoded_picinfo: pic information get from latest decode
|
||||
* @empty_flush_buf: a fake size-0 capture buffer that indicates flush. Used
|
||||
* for stateful decoder.
|
||||
* @is_flushing: set to true if flushing is in progress.
|
||||
*
|
||||
* @current_codec: current set input codec, in V4L2 pixel format
|
||||
* @capture_fourcc: capture queue type in V4L2 pixel format
|
||||
*
|
||||
* @colorspace: enum v4l2_colorspace; supplemental to pixelformat
|
||||
* @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
|
||||
* @quantization: enum v4l2_quantization, colorspace quantization
|
||||
* @xfer_func: enum v4l2_xfer_func, colorspace transfer function
|
||||
*
|
||||
* @decoded_frame_cnt: number of decoded frames
|
||||
* @lock: protect variables accessed by V4L2 threads and worker thread such as
|
||||
* mtk_video_dec_buf.
|
||||
* @hw_id: hardware index used to identify different hardware.
|
||||
*
|
||||
* @msg_queue: msg queue used to store lat buffer information.
|
||||
*/
|
||||
struct mtk_vcodec_dec_ctx {
|
||||
enum mtk_instance_type type;
|
||||
struct mtk_vcodec_dev *dev;
|
||||
struct list_head list;
|
||||
|
||||
struct v4l2_fh fh;
|
||||
struct v4l2_m2m_ctx *m2m_ctx;
|
||||
struct mtk_q_data q_data[2];
|
||||
int id;
|
||||
enum mtk_instance_state state;
|
||||
|
||||
const struct vdec_common_if *dec_if;
|
||||
void *drv_handle;
|
||||
|
||||
struct vdec_pic_info picinfo;
|
||||
int dpb_size;
|
||||
|
||||
int int_cond[MTK_VDEC_HW_MAX];
|
||||
int int_type[MTK_VDEC_HW_MAX];
|
||||
wait_queue_head_t queue[MTK_VDEC_HW_MAX];
|
||||
unsigned int irq_status;
|
||||
|
||||
struct v4l2_ctrl_handler ctrl_hdl;
|
||||
struct work_struct decode_work;
|
||||
struct vdec_pic_info last_decoded_picinfo;
|
||||
struct v4l2_m2m_buffer empty_flush_buf;
|
||||
bool is_flushing;
|
||||
|
||||
u32 current_codec;
|
||||
u32 capture_fourcc;
|
||||
|
||||
enum v4l2_colorspace colorspace;
|
||||
enum v4l2_ycbcr_encoding ycbcr_enc;
|
||||
enum v4l2_quantization quantization;
|
||||
enum v4l2_xfer_func xfer_func;
|
||||
|
||||
int decoded_frame_cnt;
|
||||
struct mutex lock;
|
||||
int hw_id;
|
||||
|
||||
struct vdec_msg_queue msg_queue;
|
||||
};
|
||||
|
||||
static inline struct mtk_vcodec_dec_ctx *fh_to_dec_ctx(struct v4l2_fh *fh)
|
||||
{
|
||||
return container_of(fh, struct mtk_vcodec_dec_ctx, fh);
|
||||
}
|
||||
|
||||
static inline struct mtk_vcodec_dec_ctx *ctrl_to_dec_ctx(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
return container_of(ctrl->handler, struct mtk_vcodec_dec_ctx, ctrl_hdl);
|
||||
}
|
||||
|
||||
/* Wake up context wait_queue */
|
||||
static inline void
|
||||
wake_up_dec_ctx(struct mtk_vcodec_dec_ctx *ctx, unsigned int reason, unsigned int hw_id)
|
||||
{
|
||||
ctx->int_cond[hw_id] = 1;
|
||||
ctx->int_type[hw_id] = reason;
|
||||
wake_up_interruptible(&ctx->queue[hw_id]);
|
||||
}
|
||||
|
||||
#endif /* _MTK_VCODEC_DEC_DRV_H_ */
|
||||
@@ -66,7 +66,7 @@ static int mtk_vdec_hw_prob_done(struct mtk_vcodec_dev *vdec_dev)
|
||||
static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv)
|
||||
{
|
||||
struct mtk_vdec_hw_dev *dev = priv;
|
||||
struct mtk_vcodec_ctx *ctx;
|
||||
struct mtk_vcodec_dec_ctx *ctx;
|
||||
u32 cg_status;
|
||||
unsigned int dec_done_status;
|
||||
void __iomem *vdec_misc_addr = dev->reg_base[VDEC_HW_MISC] +
|
||||
@@ -90,7 +90,7 @@ static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv)
|
||||
writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr);
|
||||
writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr);
|
||||
|
||||
wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->hw_idx);
|
||||
wake_up_dec_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->hw_idx);
|
||||
|
||||
mtk_v4l2_vdec_dbg(3, ctx, "wake up ctx %d, dec_done_status=%x",
|
||||
ctx->id, dec_done_status);
|
||||
|
||||
@@ -49,7 +49,7 @@ struct mtk_vdec_hw_dev {
|
||||
struct mtk_vcodec_dev *main_dev;
|
||||
void __iomem *reg_base[VDEC_HW_MAX];
|
||||
|
||||
struct mtk_vcodec_ctx *curr_ctx;
|
||||
struct mtk_vcodec_dec_ctx *curr_ctx;
|
||||
|
||||
int dec_irq;
|
||||
struct mtk_vcodec_pm pm;
|
||||
|
||||
@@ -142,7 +142,7 @@ static void mtk_vcodec_dec_disable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_i
|
||||
}
|
||||
}
|
||||
|
||||
static void mtk_vcodec_load_racing_info(struct mtk_vcodec_ctx *ctx)
|
||||
static void mtk_vcodec_load_racing_info(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
void __iomem *vdec_racing_addr;
|
||||
int j;
|
||||
@@ -156,7 +156,7 @@ static void mtk_vcodec_load_racing_info(struct mtk_vcodec_ctx *ctx)
|
||||
mutex_unlock(&ctx->dev->dec_racing_info_mutex);
|
||||
}
|
||||
|
||||
static void mtk_vcodec_record_racing_info(struct mtk_vcodec_ctx *ctx)
|
||||
static void mtk_vcodec_record_racing_info(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
void __iomem *vdec_racing_addr;
|
||||
int j;
|
||||
@@ -230,7 +230,7 @@ static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dev *vdec_dev,
|
||||
}
|
||||
}
|
||||
|
||||
void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
|
||||
void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_dec_ctx *ctx, int hw_idx)
|
||||
{
|
||||
mutex_lock(&ctx->dev->dec_mutex[hw_idx]);
|
||||
|
||||
@@ -246,7 +246,7 @@ void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mtk_vcodec_dec_enable_hardware);
|
||||
|
||||
void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
|
||||
void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_dec_ctx *ctx, int hw_idx)
|
||||
{
|
||||
if (IS_VDEC_INNER_RACING(ctx->dev->dec_capability))
|
||||
mtk_vcodec_record_racing_info(ctx);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *pm);
|
||||
|
||||
void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx);
|
||||
void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx);
|
||||
void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_dec_ctx *ctx, int hw_idx);
|
||||
void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_dec_ctx *ctx, int hw_idx);
|
||||
|
||||
#endif /* _MTK_VCODEC_DEC_PM_H_ */
|
||||
|
||||
@@ -55,7 +55,7 @@ static const unsigned int num_supported_formats =
|
||||
* Note the buffers returned from codec driver may still be in driver's
|
||||
* reference list.
|
||||
*/
|
||||
static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
struct vdec_fb *disp_frame_buffer = NULL;
|
||||
struct mtk_video_dec_buf *dstbuf;
|
||||
@@ -98,7 +98,7 @@ static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
* previous sps/pps/resolution change decode, or do nothing if user
|
||||
* space still owns this buffer
|
||||
*/
|
||||
static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
struct mtk_video_dec_buf *dstbuf;
|
||||
struct vdec_fb *free_frame_buffer = NULL;
|
||||
@@ -173,19 +173,19 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
return &vb->vb2_buf;
|
||||
}
|
||||
|
||||
static void clean_display_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
static void clean_display_buffer(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
while (get_display_buffer(ctx))
|
||||
;
|
||||
}
|
||||
|
||||
static void clean_free_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
static void clean_free_buffer(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
while (get_free_buffer(ctx))
|
||||
;
|
||||
}
|
||||
|
||||
static void mtk_vdec_queue_res_chg_event(struct mtk_vcodec_ctx *ctx)
|
||||
static void mtk_vdec_queue_res_chg_event(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
static const struct v4l2_event ev_src_ch = {
|
||||
.type = V4L2_EVENT_SOURCE_CHANGE,
|
||||
@@ -196,7 +196,7 @@ static void mtk_vdec_queue_res_chg_event(struct mtk_vcodec_ctx *ctx)
|
||||
v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
|
||||
}
|
||||
|
||||
static int mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx)
|
||||
static int mtk_vdec_flush_decoder(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
bool res_chg;
|
||||
int ret;
|
||||
@@ -211,7 +211,7 @@ static int mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx,
|
||||
static void mtk_vdec_update_fmt(struct mtk_vcodec_dec_ctx *ctx,
|
||||
unsigned int pixelformat)
|
||||
{
|
||||
const struct mtk_video_fmt *fmt;
|
||||
@@ -232,7 +232,7 @@ static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx,
|
||||
mtk_v4l2_vdec_err(ctx, "Cannot get fourcc(%d), using init value", pixelformat);
|
||||
}
|
||||
|
||||
static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx)
|
||||
static int mtk_vdec_pic_info_update(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
unsigned int dpbsize = 0;
|
||||
int ret;
|
||||
@@ -277,8 +277,8 @@ static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx)
|
||||
|
||||
static void mtk_vdec_worker(struct work_struct *work)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx =
|
||||
container_of(work, struct mtk_vcodec_ctx, decode_work);
|
||||
struct mtk_vcodec_dec_ctx *ctx =
|
||||
container_of(work, struct mtk_vcodec_dec_ctx, decode_work);
|
||||
struct mtk_vcodec_dev *dev = ctx->dev;
|
||||
struct vb2_v4l2_buffer *src_buf, *dst_buf;
|
||||
struct mtk_vcodec_mem buf;
|
||||
@@ -420,7 +420,7 @@ static void vb2ops_vdec_stateful_buf_queue(struct vb2_buffer *vb)
|
||||
bool res_chg = false;
|
||||
int ret;
|
||||
unsigned int dpbsize = 1, i;
|
||||
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct vb2_v4l2_buffer *vb2_v4l2;
|
||||
struct mtk_q_data *dst_q_data;
|
||||
|
||||
@@ -528,7 +528,7 @@ static void vb2ops_vdec_stateful_buf_queue(struct vb2_buffer *vb)
|
||||
|
||||
static int mtk_vdec_g_v_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = ctrl_to_ctx(ctrl);
|
||||
struct mtk_vcodec_dec_ctx *ctx = ctrl_to_dec_ctx(ctrl);
|
||||
int ret = 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
@@ -550,7 +550,7 @@ static const struct v4l2_ctrl_ops mtk_vcodec_dec_ctrl_ops = {
|
||||
.g_volatile_ctrl = mtk_vdec_g_v_ctrl,
|
||||
};
|
||||
|
||||
static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx)
|
||||
static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
@@ -581,7 +581,7 @@ static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
|
||||
static void mtk_init_vdec_params(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@ static const struct v4l2_frmsize_stepwise stepwise_fhd = {
|
||||
.step_height = 16
|
||||
};
|
||||
|
||||
static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_ctx *ctx, int error,
|
||||
static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_dec_ctx *ctx, int error,
|
||||
struct media_request *src_buf_req)
|
||||
{
|
||||
struct vb2_v4l2_buffer *vb2_dst;
|
||||
@@ -242,7 +242,7 @@ static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_ctx *ctx, int error
|
||||
v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
|
||||
}
|
||||
|
||||
static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
struct mtk_video_dec_buf *framebuf;
|
||||
struct vb2_v4l2_buffer *vb2_v4l2;
|
||||
@@ -279,15 +279,15 @@ static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
|
||||
static void vb2ops_vdec_buf_request_complete(struct vb2_buffer *vb)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
|
||||
|
||||
v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->ctrl_hdl);
|
||||
}
|
||||
|
||||
static void mtk_vdec_worker(struct work_struct *work)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx =
|
||||
container_of(work, struct mtk_vcodec_ctx, decode_work);
|
||||
struct mtk_vcodec_dec_ctx *ctx =
|
||||
container_of(work, struct mtk_vcodec_dec_ctx, decode_work);
|
||||
struct mtk_vcodec_dev *dev = ctx->dev;
|
||||
struct vb2_v4l2_buffer *vb2_v4l2_src;
|
||||
struct vb2_buffer *vb2_src;
|
||||
@@ -362,7 +362,7 @@ static void mtk_vdec_worker(struct work_struct *work)
|
||||
|
||||
static void vb2ops_vdec_stateless_buf_queue(struct vb2_buffer *vb)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct mtk_vcodec_dec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct vb2_v4l2_buffer *vb2_v4l2 = to_vb2_v4l2_buffer(vb);
|
||||
|
||||
mtk_v4l2_vdec_dbg(3, ctx, "[%d] (%d) id=%d, vb=%p", ctx->id, vb->vb2_queue->type,
|
||||
@@ -383,14 +383,14 @@ static void vb2ops_vdec_stateless_buf_queue(struct vb2_buffer *vb)
|
||||
}
|
||||
}
|
||||
|
||||
static int mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx)
|
||||
static int mtk_vdec_flush_decoder(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
bool res_chg;
|
||||
|
||||
return vdec_if_decode(ctx, NULL, NULL, &res_chg);
|
||||
}
|
||||
|
||||
static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx)
|
||||
static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@@ -442,7 +442,7 @@ const struct media_device_ops mtk_vcodec_media_ops = {
|
||||
};
|
||||
|
||||
static void mtk_vcodec_add_formats(unsigned int fourcc,
|
||||
struct mtk_vcodec_ctx *ctx)
|
||||
struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
struct mtk_vcodec_dev *dev = ctx->dev;
|
||||
const struct mtk_vcodec_dec_pdata *pdata = dev->vdec_pdata;
|
||||
@@ -483,7 +483,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
|
||||
count_formats, ctx->dev->dec_capability);
|
||||
}
|
||||
|
||||
static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
|
||||
static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
int cap_format_count = 0, out_format_count = 0;
|
||||
|
||||
@@ -526,7 +526,7 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
|
||||
mtk_video_formats[cap_format_count + out_format_count - 1];
|
||||
}
|
||||
|
||||
static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
|
||||
static void mtk_init_vdec_params(struct mtk_vcodec_dec_ctx *ctx)
|
||||
{
|
||||
struct vb2_queue *src_vq;
|
||||
|
||||
|
||||
@@ -17,13 +17,14 @@
|
||||
#include <media/videobuf2-core.h>
|
||||
|
||||
#include "mtk_vcodec_dbgfs.h"
|
||||
#include "mtk_vcodec_dec_drv.h"
|
||||
#include "mtk_vcodec_enc_drv.h"
|
||||
#include "mtk_vcodec_util.h"
|
||||
#include "vdec_msg_queue.h"
|
||||
|
||||
#define MTK_VCODEC_DEC_NAME "mtk-vcodec-dec"
|
||||
#define MTK_VCODEC_ENC_NAME "mtk-vcodec-enc"
|
||||
|
||||
#define MTK_VCODEC_MAX_PLANES 3
|
||||
#define MTK_V4L2_BENCHMARK 0
|
||||
#define WAIT_INTR_TIMEOUT_MS 1000
|
||||
#define IS_VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE)
|
||||
@@ -53,60 +54,7 @@ enum mtk_hw_reg_idx {
|
||||
NUM_MAX_VCODEC_REG_BASE
|
||||
};
|
||||
|
||||
/*
|
||||
* enum mtk_instance_type - The type of an MTK Vcodec instance.
|
||||
*/
|
||||
enum mtk_instance_type {
|
||||
MTK_INST_DECODER = 0,
|
||||
MTK_INST_ENCODER = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum mtk_instance_state - The state of an MTK Vcodec instance.
|
||||
* @MTK_STATE_FREE: default state when instance is created
|
||||
* @MTK_STATE_INIT: vcodec instance is initialized
|
||||
* @MTK_STATE_HEADER: vdec had sps/pps header parsed or venc
|
||||
* had sps/pps header encoded
|
||||
* @MTK_STATE_FLUSH: vdec is flushing. Only used by decoder
|
||||
* @MTK_STATE_ABORT: vcodec should be aborted
|
||||
*/
|
||||
enum mtk_instance_state {
|
||||
MTK_STATE_FREE = 0,
|
||||
MTK_STATE_INIT = 1,
|
||||
MTK_STATE_HEADER = 2,
|
||||
MTK_STATE_FLUSH = 3,
|
||||
MTK_STATE_ABORT = 4,
|
||||
};
|
||||
|
||||
/*
|
||||
* enum mtk_encode_param - General encoding parameters type
|
||||
*/
|
||||
enum mtk_encode_param {
|
||||
MTK_ENCODE_PARAM_NONE = 0,
|
||||
MTK_ENCODE_PARAM_BITRATE = (1 << 0),
|
||||
MTK_ENCODE_PARAM_FRAMERATE = (1 << 1),
|
||||
MTK_ENCODE_PARAM_INTRA_PERIOD = (1 << 2),
|
||||
MTK_ENCODE_PARAM_FORCE_INTRA = (1 << 3),
|
||||
MTK_ENCODE_PARAM_GOP_SIZE = (1 << 4),
|
||||
};
|
||||
|
||||
enum mtk_fmt_type {
|
||||
MTK_FMT_DEC = 0,
|
||||
MTK_FMT_ENC = 1,
|
||||
MTK_FMT_FRAME = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* enum mtk_vdec_hw_id - Hardware index used to separate
|
||||
* different hardware
|
||||
*/
|
||||
enum mtk_vdec_hw_id {
|
||||
MTK_VDEC_CORE,
|
||||
MTK_VDEC_LAT0,
|
||||
MTK_VDEC_LAT1,
|
||||
MTK_VDEC_LAT_SOC,
|
||||
MTK_VDEC_HW_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
* enum mtk_vdec_hw_count - Supported hardware count
|
||||
@@ -118,17 +66,6 @@ enum mtk_vdec_hw_count {
|
||||
MTK_VDEC_MAX_HW_COUNT,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct mtk_video_fmt - Structure used to store information about pixelformats
|
||||
*/
|
||||
struct mtk_video_fmt {
|
||||
u32 fourcc;
|
||||
enum mtk_fmt_type type;
|
||||
u32 num_planes;
|
||||
u32 flags;
|
||||
struct v4l2_frmsize_stepwise frmsize;
|
||||
};
|
||||
|
||||
/*
|
||||
* enum mtk_q_type - Type of queue
|
||||
*/
|
||||
@@ -137,54 +74,6 @@ enum mtk_q_type {
|
||||
MTK_Q_DATA_DST = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct mtk_q_data - Structure used to store information about queue
|
||||
*/
|
||||
struct mtk_q_data {
|
||||
unsigned int visible_width;
|
||||
unsigned int visible_height;
|
||||
unsigned int coded_width;
|
||||
unsigned int coded_height;
|
||||
enum v4l2_field field;
|
||||
unsigned int bytesperline[MTK_VCODEC_MAX_PLANES];
|
||||
unsigned int sizeimage[MTK_VCODEC_MAX_PLANES];
|
||||
const struct mtk_video_fmt *fmt;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_enc_params - General encoding parameters
|
||||
* @bitrate: target bitrate in bits per second
|
||||
* @num_b_frame: number of b frames between p-frame
|
||||
* @rc_frame: frame based rate control
|
||||
* @rc_mb: macroblock based rate control
|
||||
* @seq_hdr_mode: H.264 sequence header is encoded separately or joined
|
||||
* with the first frame
|
||||
* @intra_period: I frame period
|
||||
* @gop_size: group of picture size, it's used as the intra frame period
|
||||
* @framerate_num: frame rate numerator. ex: framerate_num=30 and
|
||||
* framerate_denom=1 means FPS is 30
|
||||
* @framerate_denom: frame rate denominator. ex: framerate_num=30 and
|
||||
* framerate_denom=1 means FPS is 30
|
||||
* @h264_max_qp: Max value for H.264 quantization parameter
|
||||
* @h264_profile: V4L2 defined H.264 profile
|
||||
* @h264_level: V4L2 defined H.264 level
|
||||
* @force_intra: force/insert intra frame
|
||||
*/
|
||||
struct mtk_enc_params {
|
||||
unsigned int bitrate;
|
||||
unsigned int num_b_frame;
|
||||
unsigned int rc_frame;
|
||||
unsigned int rc_mb;
|
||||
unsigned int seq_hdr_mode;
|
||||
unsigned int intra_period;
|
||||
unsigned int gop_size;
|
||||
unsigned int framerate_num;
|
||||
unsigned int framerate_denom;
|
||||
unsigned int h264_max_qp;
|
||||
unsigned int h264_profile;
|
||||
unsigned int h264_level;
|
||||
unsigned int force_intra;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct mtk_vcodec_clk_info - Structure used to store clock name
|
||||
@@ -211,125 +100,6 @@ struct mtk_vcodec_pm {
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct vdec_pic_info - picture size information
|
||||
* @pic_w: picture width
|
||||
* @pic_h: picture height
|
||||
* @buf_w: picture buffer width (64 aligned up from pic_w)
|
||||
* @buf_h: picture buffer heiht (64 aligned up from pic_h)
|
||||
* @fb_sz: bitstream size of each plane
|
||||
* E.g. suppose picture size is 176x144,
|
||||
* buffer size will be aligned to 176x160.
|
||||
* @cap_fourcc: fourcc number(may changed when resolution change)
|
||||
* @reserved: align struct to 64-bit in order to adjust 32-bit and 64-bit os.
|
||||
*/
|
||||
struct vdec_pic_info {
|
||||
unsigned int pic_w;
|
||||
unsigned int pic_h;
|
||||
unsigned int buf_w;
|
||||
unsigned int buf_h;
|
||||
unsigned int fb_sz[VIDEO_MAX_PLANES];
|
||||
unsigned int cap_fourcc;
|
||||
unsigned int reserved;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_vcodec_ctx - Context (instance) private data.
|
||||
*
|
||||
* @type: type of the instance - decoder or encoder
|
||||
* @dev: pointer to the mtk_vcodec_dev of the device
|
||||
* @list: link to ctx_list of mtk_vcodec_dev
|
||||
* @fh: struct v4l2_fh
|
||||
* @m2m_ctx: pointer to the v4l2_m2m_ctx of the context
|
||||
* @q_data: store information of input and output queue
|
||||
* of the context
|
||||
* @id: index of the context that this structure describes
|
||||
* @state: state of the context
|
||||
* @param_change: indicate encode parameter type
|
||||
* @enc_params: encoding parameters
|
||||
* @dec_if: hooked decoder driver interface
|
||||
* @enc_if: hooked encoder driver interface
|
||||
* @drv_handle: driver handle for specific decode/encode instance
|
||||
*
|
||||
* @picinfo: store picture info after header parsing
|
||||
* @dpb_size: store dpb count after header parsing
|
||||
* @int_cond: variable used by the waitqueue
|
||||
* @int_type: type of the last interrupt
|
||||
* @queue: waitqueue that can be used to wait for this context to
|
||||
* finish
|
||||
* @irq_status: irq status
|
||||
*
|
||||
* @ctrl_hdl: handler for v4l2 framework
|
||||
* @decode_work: worker for the decoding
|
||||
* @encode_work: worker for the encoding
|
||||
* @last_decoded_picinfo: pic information get from latest decode
|
||||
* @empty_flush_buf: a fake size-0 capture buffer that indicates flush. Only
|
||||
* to be used with encoder and stateful decoder.
|
||||
* @is_flushing: set to true if flushing is in progress.
|
||||
* @current_codec: current set input codec, in V4L2 pixel format
|
||||
* @capture_fourcc: capture queue type in V4L2 pixel format
|
||||
*
|
||||
* @colorspace: enum v4l2_colorspace; supplemental to pixelformat
|
||||
* @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
|
||||
* @quantization: enum v4l2_quantization, colorspace quantization
|
||||
* @xfer_func: enum v4l2_xfer_func, colorspace transfer function
|
||||
* @decoded_frame_cnt: number of decoded frames
|
||||
* @lock: protect variables accessed by V4L2 threads and worker thread such as
|
||||
* mtk_video_dec_buf.
|
||||
* @hw_id: hardware index used to identify different hardware.
|
||||
*
|
||||
* @msg_queue: msg queue used to store lat buffer information.
|
||||
* @q_mutex: vb2_queue mutex.
|
||||
*/
|
||||
struct mtk_vcodec_ctx {
|
||||
enum mtk_instance_type type;
|
||||
struct mtk_vcodec_dev *dev;
|
||||
struct list_head list;
|
||||
|
||||
struct v4l2_fh fh;
|
||||
struct v4l2_m2m_ctx *m2m_ctx;
|
||||
struct mtk_q_data q_data[2];
|
||||
int id;
|
||||
enum mtk_instance_state state;
|
||||
enum mtk_encode_param param_change;
|
||||
struct mtk_enc_params enc_params;
|
||||
|
||||
const struct vdec_common_if *dec_if;
|
||||
const struct venc_common_if *enc_if;
|
||||
void *drv_handle;
|
||||
|
||||
struct vdec_pic_info picinfo;
|
||||
int dpb_size;
|
||||
|
||||
int int_cond[MTK_VDEC_HW_MAX];
|
||||
int int_type[MTK_VDEC_HW_MAX];
|
||||
wait_queue_head_t queue[MTK_VDEC_HW_MAX];
|
||||
unsigned int irq_status;
|
||||
|
||||
struct v4l2_ctrl_handler ctrl_hdl;
|
||||
struct work_struct decode_work;
|
||||
struct work_struct encode_work;
|
||||
struct vdec_pic_info last_decoded_picinfo;
|
||||
struct v4l2_m2m_buffer empty_flush_buf;
|
||||
bool is_flushing;
|
||||
|
||||
u32 current_codec;
|
||||
u32 capture_fourcc;
|
||||
|
||||
enum v4l2_colorspace colorspace;
|
||||
enum v4l2_ycbcr_encoding ycbcr_enc;
|
||||
enum v4l2_quantization quantization;
|
||||
enum v4l2_xfer_func xfer_func;
|
||||
|
||||
int decoded_frame_cnt;
|
||||
struct mutex lock;
|
||||
int hw_id;
|
||||
|
||||
struct vdec_msg_queue msg_queue;
|
||||
|
||||
struct mutex q_mutex;
|
||||
};
|
||||
|
||||
/*
|
||||
* enum mtk_vdec_hw_arch - Used to separate different hardware architecture
|
||||
*/
|
||||
@@ -375,12 +145,12 @@ enum mtk_vdec_format_types {
|
||||
*/
|
||||
|
||||
struct mtk_vcodec_dec_pdata {
|
||||
void (*init_vdec_params)(struct mtk_vcodec_ctx *ctx);
|
||||
int (*ctrls_setup)(struct mtk_vcodec_ctx *ctx);
|
||||
void (*init_vdec_params)(struct mtk_vcodec_dec_ctx *ctx);
|
||||
int (*ctrls_setup)(struct mtk_vcodec_dec_ctx *ctx);
|
||||
void (*worker)(struct work_struct *work);
|
||||
int (*flush_decoder)(struct mtk_vcodec_ctx *ctx);
|
||||
struct vdec_fb *(*get_cap_buffer)(struct mtk_vcodec_ctx *ctx);
|
||||
void (*cap_to_disp)(struct mtk_vcodec_ctx *ctx, int error,
|
||||
int (*flush_decoder)(struct mtk_vcodec_dec_ctx *ctx);
|
||||
struct vdec_fb *(*get_cap_buffer)(struct mtk_vcodec_dec_ctx *ctx);
|
||||
void (*cap_to_disp)(struct mtk_vcodec_dec_ctx *ctx, int error,
|
||||
struct media_request *src_buf_req);
|
||||
|
||||
struct vb2_ops *vdec_vb2_ops;
|
||||
@@ -434,9 +204,10 @@ struct mtk_vcodec_enc_pdata {
|
||||
* @m2m_dev_dec: m2m device for decoder
|
||||
* @m2m_dev_enc: m2m device for encoder.
|
||||
* @plat_dev: platform device
|
||||
* @ctx_list: list of struct mtk_vcodec_ctx
|
||||
* @ctx_list: list of struct mtk_vcodec_dec_ctx
|
||||
* @irqlock: protect data access by irq handler and work thread
|
||||
* @curr_ctx: The context that is waiting for codec hardware
|
||||
* @curr_enc_ctx: The encoder context that is waiting for codec hardware
|
||||
*
|
||||
* @reg_base: Mapped address of MTK Vcodec registers.
|
||||
* @vdec_pdata: decoder IC-specific data
|
||||
@@ -483,7 +254,8 @@ struct mtk_vcodec_dev {
|
||||
struct platform_device *plat_dev;
|
||||
struct list_head ctx_list;
|
||||
spinlock_t irqlock;
|
||||
struct mtk_vcodec_ctx *curr_ctx;
|
||||
struct mtk_vcodec_dec_ctx *curr_ctx;
|
||||
struct mtk_vcodec_enc_ctx *curr_enc_ctx;
|
||||
void __iomem *reg_base[NUM_MAX_VCODEC_REG_BASE];
|
||||
const struct mtk_vcodec_dec_pdata *vdec_pdata;
|
||||
const struct mtk_vcodec_enc_pdata *venc_pdata;
|
||||
@@ -522,23 +294,4 @@ struct mtk_vcodec_dev {
|
||||
struct mtk_vcodec_dbgfs dbgfs;
|
||||
};
|
||||
|
||||
static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
|
||||
{
|
||||
return container_of(fh, struct mtk_vcodec_ctx, fh);
|
||||
}
|
||||
|
||||
static inline struct mtk_vcodec_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
return container_of(ctrl->handler, struct mtk_vcodec_ctx, ctrl_hdl);
|
||||
}
|
||||
|
||||
/* Wake up context wait_queue */
|
||||
static inline void
|
||||
wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason, unsigned int hw_id)
|
||||
{
|
||||
ctx->int_cond[hw_id] = 1;
|
||||
ctx->int_type[hw_id] = reason;
|
||||
wake_up_interruptible(&ctx->queue[hw_id]);
|
||||
}
|
||||
|
||||
#endif /* _MTK_VCODEC_DRV_H_ */
|
||||
|
||||
@@ -45,7 +45,7 @@ static const struct v4l2_frmsize_stepwise mtk_venc_4k_framesizes = {
|
||||
|
||||
static int vidioc_venc_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = ctrl_to_ctx(ctrl);
|
||||
struct mtk_vcodec_enc_ctx *ctx = ctrl_to_enc_ctx(ctrl);
|
||||
struct mtk_enc_params *p = &ctx->enc_params;
|
||||
int ret = 0;
|
||||
|
||||
@@ -162,7 +162,7 @@ static int vidioc_enum_framesizes(struct file *file, void *fh,
|
||||
struct v4l2_frmsizeenum *fsize)
|
||||
{
|
||||
const struct mtk_video_fmt *fmt;
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(fh);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(fh);
|
||||
|
||||
if (fsize->index != 0)
|
||||
return -EINVAL;
|
||||
@@ -186,7 +186,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
|
||||
struct v4l2_fmtdesc *f)
|
||||
{
|
||||
const struct mtk_vcodec_enc_pdata *pdata =
|
||||
fh_to_ctx(priv)->dev->venc_pdata;
|
||||
fh_to_enc_ctx(priv)->dev->venc_pdata;
|
||||
|
||||
return vidioc_enum_fmt(f, pdata->capture_formats,
|
||||
pdata->num_capture_formats);
|
||||
@@ -196,7 +196,7 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
|
||||
struct v4l2_fmtdesc *f)
|
||||
{
|
||||
const struct mtk_vcodec_enc_pdata *pdata =
|
||||
fh_to_ctx(priv)->dev->venc_pdata;
|
||||
fh_to_enc_ctx(priv)->dev->venc_pdata;
|
||||
|
||||
return vidioc_enum_fmt(f, pdata->output_formats,
|
||||
pdata->num_output_formats);
|
||||
@@ -204,7 +204,7 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
|
||||
|
||||
static int mtk_vcodec_enc_get_chip_name(void *priv)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
|
||||
struct device *dev = &ctx->dev->plat_dev->dev;
|
||||
|
||||
if (of_device_is_compatible(dev->of_node, "mediatek,mt8173-vcodec-enc"))
|
||||
@@ -224,7 +224,7 @@ static int mtk_vcodec_enc_get_chip_name(void *priv)
|
||||
static int vidioc_venc_querycap(struct file *file, void *priv,
|
||||
struct v4l2_capability *cap)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
|
||||
struct device *dev = &ctx->dev->plat_dev->dev;
|
||||
int platform_name = mtk_vcodec_enc_get_chip_name(priv);
|
||||
|
||||
@@ -237,7 +237,7 @@ static int vidioc_venc_querycap(struct file *file, void *priv,
|
||||
static int vidioc_venc_s_parm(struct file *file, void *priv,
|
||||
struct v4l2_streamparm *a)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
|
||||
struct v4l2_fract *timeperframe = &a->parm.output.timeperframe;
|
||||
|
||||
if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
|
||||
@@ -260,7 +260,7 @@ static int vidioc_venc_s_parm(struct file *file, void *priv,
|
||||
static int vidioc_venc_g_parm(struct file *file, void *priv,
|
||||
struct v4l2_streamparm *a)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
|
||||
|
||||
if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
|
||||
return -EINVAL;
|
||||
@@ -274,7 +274,7 @@ static int vidioc_venc_g_parm(struct file *file, void *priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mtk_q_data *mtk_venc_get_q_data(struct mtk_vcodec_ctx *ctx,
|
||||
static struct mtk_q_data *mtk_venc_get_q_data(struct mtk_vcodec_enc_ctx *ctx,
|
||||
enum v4l2_buf_type type)
|
||||
{
|
||||
if (V4L2_TYPE_IS_OUTPUT(type))
|
||||
@@ -294,7 +294,7 @@ static void vidioc_try_fmt_cap(struct v4l2_format *f)
|
||||
/* V4L2 specification suggests the driver corrects the format struct if any of
|
||||
* the dimensions is unsupported
|
||||
*/
|
||||
static int vidioc_try_fmt_out(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f,
|
||||
static int vidioc_try_fmt_out(struct mtk_vcodec_enc_ctx *ctx, struct v4l2_format *f,
|
||||
const struct mtk_video_fmt *fmt)
|
||||
{
|
||||
struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
|
||||
@@ -367,8 +367,8 @@ static int vidioc_try_fmt_out(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_venc_set_param(struct mtk_vcodec_ctx *ctx,
|
||||
struct venc_enc_param *param)
|
||||
static void mtk_venc_set_param(struct mtk_vcodec_enc_ctx *ctx,
|
||||
struct venc_enc_param *param)
|
||||
{
|
||||
struct mtk_q_data *q_data_src = &ctx->q_data[MTK_Q_DATA_SRC];
|
||||
struct mtk_enc_params *enc_params = &ctx->enc_params;
|
||||
@@ -417,7 +417,7 @@ static void mtk_venc_set_param(struct mtk_vcodec_ctx *ctx,
|
||||
static int vidioc_venc_s_fmt_cap(struct file *file, void *priv,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
|
||||
const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
|
||||
struct vb2_queue *vq;
|
||||
struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
|
||||
@@ -472,7 +472,7 @@ static int vidioc_venc_s_fmt_cap(struct file *file, void *priv,
|
||||
static int vidioc_venc_s_fmt_out(struct file *file, void *priv,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
|
||||
const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
|
||||
struct vb2_queue *vq;
|
||||
struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
|
||||
@@ -527,7 +527,7 @@ static int vidioc_venc_g_fmt(struct file *file, void *priv,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
|
||||
struct vb2_queue *vq;
|
||||
struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
|
||||
int i;
|
||||
@@ -560,7 +560,7 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
const struct mtk_video_fmt *fmt;
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
|
||||
const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
|
||||
|
||||
fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata);
|
||||
@@ -582,7 +582,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
const struct mtk_video_fmt *fmt;
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
|
||||
const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
|
||||
|
||||
fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata);
|
||||
@@ -603,7 +603,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
|
||||
static int vidioc_venc_g_selection(struct file *file, void *priv,
|
||||
struct v4l2_selection *s)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
|
||||
struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, s->type);
|
||||
|
||||
if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
|
||||
@@ -633,7 +633,7 @@ static int vidioc_venc_g_selection(struct file *file, void *priv,
|
||||
static int vidioc_venc_s_selection(struct file *file, void *priv,
|
||||
struct v4l2_selection *s)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
|
||||
struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, s->type);
|
||||
|
||||
if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
|
||||
@@ -658,7 +658,7 @@ static int vidioc_venc_s_selection(struct file *file, void *priv,
|
||||
static int vidioc_venc_qbuf(struct file *file, void *priv,
|
||||
struct v4l2_buffer *buf)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
|
||||
|
||||
if (ctx->state == MTK_STATE_ABORT) {
|
||||
mtk_v4l2_venc_err(ctx, "[%d] Call on QBUF after unrecoverable error",
|
||||
@@ -672,7 +672,7 @@ static int vidioc_venc_qbuf(struct file *file, void *priv,
|
||||
static int vidioc_venc_dqbuf(struct file *file, void *priv,
|
||||
struct v4l2_buffer *buf)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
|
||||
int ret;
|
||||
|
||||
if (ctx->state == MTK_STATE_ABORT) {
|
||||
@@ -710,7 +710,7 @@ static int vidioc_venc_dqbuf(struct file *file, void *priv,
|
||||
static int vidioc_encoder_cmd(struct file *file, void *priv,
|
||||
struct v4l2_encoder_cmd *cmd)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
|
||||
struct vb2_queue *src_vq, *dst_vq;
|
||||
int ret;
|
||||
|
||||
@@ -804,7 +804,7 @@ static int vb2ops_venc_queue_setup(struct vb2_queue *vq,
|
||||
unsigned int sizes[],
|
||||
struct device *alloc_devs[])
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq);
|
||||
struct mtk_vcodec_enc_ctx *ctx = vb2_get_drv_priv(vq);
|
||||
struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, vq->type);
|
||||
unsigned int i;
|
||||
|
||||
@@ -826,7 +826,7 @@ static int vb2ops_venc_queue_setup(struct vb2_queue *vq,
|
||||
|
||||
static int vb2ops_venc_buf_prepare(struct vb2_buffer *vb)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct mtk_vcodec_enc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, vb->vb2_queue->type);
|
||||
int i;
|
||||
|
||||
@@ -843,7 +843,7 @@ static int vb2ops_venc_buf_prepare(struct vb2_buffer *vb)
|
||||
|
||||
static void vb2ops_venc_buf_queue(struct vb2_buffer *vb)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct mtk_vcodec_enc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct vb2_v4l2_buffer *vb2_v4l2 =
|
||||
container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
|
||||
|
||||
@@ -865,7 +865,7 @@ static void vb2ops_venc_buf_queue(struct vb2_buffer *vb)
|
||||
|
||||
static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
|
||||
struct mtk_vcodec_enc_ctx *ctx = vb2_get_drv_priv(q);
|
||||
struct venc_enc_param param;
|
||||
int ret, pm_ret;
|
||||
int i;
|
||||
@@ -944,7 +944,7 @@ err_start_stream:
|
||||
|
||||
static void vb2ops_venc_stop_streaming(struct vb2_queue *q)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
|
||||
struct mtk_vcodec_enc_ctx *ctx = vb2_get_drv_priv(q);
|
||||
struct vb2_v4l2_buffer *src_buf, *dst_buf;
|
||||
int ret;
|
||||
|
||||
@@ -1033,7 +1033,7 @@ static const struct vb2_ops mtk_venc_vb2_ops = {
|
||||
|
||||
static int mtk_venc_encode_header(void *priv)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = priv;
|
||||
struct mtk_vcodec_enc_ctx *ctx = priv;
|
||||
int ret;
|
||||
struct vb2_v4l2_buffer *src_buf, *dst_buf;
|
||||
struct mtk_vcodec_mem bs_buf;
|
||||
@@ -1080,7 +1080,7 @@ static int mtk_venc_encode_header(void *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
|
||||
static int mtk_venc_param_change(struct mtk_vcodec_enc_ctx *ctx)
|
||||
{
|
||||
struct venc_enc_param enc_prm;
|
||||
struct vb2_v4l2_buffer *vb2_v4l2 = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
|
||||
@@ -1153,7 +1153,7 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
|
||||
*/
|
||||
static void mtk_venc_worker(struct work_struct *work)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = container_of(work, struct mtk_vcodec_ctx,
|
||||
struct mtk_vcodec_enc_ctx *ctx = container_of(work, struct mtk_vcodec_enc_ctx,
|
||||
encode_work);
|
||||
struct vb2_v4l2_buffer *src_buf, *dst_buf;
|
||||
struct venc_frm_buf frm_buf;
|
||||
@@ -1233,7 +1233,7 @@ static void mtk_venc_worker(struct work_struct *work)
|
||||
|
||||
static void m2mops_venc_device_run(void *priv)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = priv;
|
||||
struct mtk_vcodec_enc_ctx *ctx = priv;
|
||||
|
||||
if ((ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_H264) &&
|
||||
(ctx->state != MTK_STATE_HEADER)) {
|
||||
@@ -1249,7 +1249,7 @@ static void m2mops_venc_device_run(void *priv)
|
||||
|
||||
static int m2mops_venc_job_ready(void *m2m_priv)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = m2m_priv;
|
||||
struct mtk_vcodec_enc_ctx *ctx = m2m_priv;
|
||||
|
||||
if (ctx->state == MTK_STATE_ABORT || ctx->state == MTK_STATE_FREE) {
|
||||
mtk_v4l2_venc_dbg(3, ctx, "[%d]Not ready: state=0x%x.", ctx->id, ctx->state);
|
||||
@@ -1261,7 +1261,7 @@ static int m2mops_venc_job_ready(void *m2m_priv)
|
||||
|
||||
static void m2mops_venc_job_abort(void *priv)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = priv;
|
||||
struct mtk_vcodec_enc_ctx *ctx = priv;
|
||||
|
||||
ctx->state = MTK_STATE_ABORT;
|
||||
}
|
||||
@@ -1272,7 +1272,7 @@ const struct v4l2_m2m_ops mtk_venc_m2m_ops = {
|
||||
.job_abort = m2mops_venc_job_abort,
|
||||
};
|
||||
|
||||
void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx)
|
||||
void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_enc_ctx *ctx)
|
||||
{
|
||||
struct mtk_q_data *q_data;
|
||||
|
||||
@@ -1333,7 +1333,7 @@ void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx)
|
||||
ctx->enc_params.framerate_denom = MTK_DEFAULT_FRAMERATE_DENOM;
|
||||
}
|
||||
|
||||
int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx)
|
||||
int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_enc_ctx *ctx)
|
||||
{
|
||||
const struct v4l2_ctrl_ops *ops = &mtk_vcodec_enc_ctrl_ops;
|
||||
struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl;
|
||||
@@ -1399,7 +1399,7 @@ int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx)
|
||||
int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
|
||||
struct vb2_queue *dst_vq)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = priv;
|
||||
struct mtk_vcodec_enc_ctx *ctx = priv;
|
||||
int ret;
|
||||
|
||||
/* Note: VB2_USERPTR works with dma-contig because mt8173
|
||||
@@ -1434,7 +1434,7 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
|
||||
return vb2_queue_init(dst_vq);
|
||||
}
|
||||
|
||||
int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx)
|
||||
int mtk_venc_unlock(struct mtk_vcodec_enc_ctx *ctx)
|
||||
{
|
||||
struct mtk_vcodec_dev *dev = ctx->dev;
|
||||
|
||||
@@ -1442,7 +1442,7 @@ int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtk_venc_lock(struct mtk_vcodec_ctx *ctx)
|
||||
int mtk_venc_lock(struct mtk_vcodec_enc_ctx *ctx)
|
||||
{
|
||||
struct mtk_vcodec_dev *dev = ctx->dev;
|
||||
|
||||
@@ -1450,7 +1450,7 @@ int mtk_venc_lock(struct mtk_vcodec_ctx *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx)
|
||||
void mtk_vcodec_enc_release(struct mtk_vcodec_enc_ctx *ctx)
|
||||
{
|
||||
int ret = venc_if_deinit(ctx);
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <media/videobuf2-core.h>
|
||||
#include <media/v4l2-mem2mem.h>
|
||||
|
||||
#include "mtk_vcodec_enc_drv.h"
|
||||
|
||||
#define MTK_VENC_IRQ_STATUS_SPS 0x1
|
||||
#define MTK_VENC_IRQ_STATUS_PPS 0x2
|
||||
#define MTK_VENC_IRQ_STATUS_FRM 0x4
|
||||
@@ -39,12 +41,12 @@ struct mtk_video_enc_buf {
|
||||
extern const struct v4l2_ioctl_ops mtk_venc_ioctl_ops;
|
||||
extern const struct v4l2_m2m_ops mtk_venc_m2m_ops;
|
||||
|
||||
int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx);
|
||||
int mtk_venc_lock(struct mtk_vcodec_ctx *ctx);
|
||||
int mtk_venc_unlock(struct mtk_vcodec_enc_ctx *ctx);
|
||||
int mtk_venc_lock(struct mtk_vcodec_enc_ctx *ctx);
|
||||
int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
|
||||
struct vb2_queue *dst_vq);
|
||||
void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx);
|
||||
int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx);
|
||||
void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx);
|
||||
void mtk_vcodec_enc_release(struct mtk_vcodec_enc_ctx *ctx);
|
||||
int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_enc_ctx *ctx);
|
||||
void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_enc_ctx *ctx);
|
||||
|
||||
#endif /* _MTK_VCODEC_ENC_H_ */
|
||||
|
||||
@@ -86,13 +86,13 @@ static void clean_irq_status(unsigned int irq_status, void __iomem *addr)
|
||||
static irqreturn_t mtk_vcodec_enc_irq_handler(int irq, void *priv)
|
||||
{
|
||||
struct mtk_vcodec_dev *dev = priv;
|
||||
struct mtk_vcodec_ctx *ctx;
|
||||
struct mtk_vcodec_enc_ctx *ctx;
|
||||
unsigned long flags;
|
||||
void __iomem *addr;
|
||||
int core_id;
|
||||
|
||||
spin_lock_irqsave(&dev->irqlock, flags);
|
||||
ctx = dev->curr_ctx;
|
||||
ctx = dev->curr_enc_ctx;
|
||||
spin_unlock_irqrestore(&dev->irqlock, flags);
|
||||
|
||||
core_id = dev->venc_pdata->core_id;
|
||||
@@ -110,14 +110,14 @@ static irqreturn_t mtk_vcodec_enc_irq_handler(int irq, void *priv)
|
||||
|
||||
clean_irq_status(ctx->irq_status, addr);
|
||||
|
||||
wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
|
||||
wake_up_enc_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int fops_vcodec_open(struct file *file)
|
||||
{
|
||||
struct mtk_vcodec_dev *dev = video_drvdata(file);
|
||||
struct mtk_vcodec_ctx *ctx = NULL;
|
||||
struct mtk_vcodec_enc_ctx *ctx = NULL;
|
||||
int ret = 0;
|
||||
struct vb2_queue *src_vq;
|
||||
|
||||
@@ -204,7 +204,7 @@ err_ctrls_setup:
|
||||
static int fops_vcodec_release(struct file *file)
|
||||
{
|
||||
struct mtk_vcodec_dev *dev = video_drvdata(file);
|
||||
struct mtk_vcodec_ctx *ctx = fh_to_ctx(file->private_data);
|
||||
struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(file->private_data);
|
||||
|
||||
mtk_v4l2_venc_dbg(1, ctx, "[%d] encoder", ctx->id);
|
||||
mutex_lock(&dev->dev_mutex);
|
||||
|
||||
148
drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_drv.h
Normal file
148
drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_drv.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2023 MediaTek Inc.
|
||||
* Author: Yunfei Dong <yunfei.dong@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _MTK_VCODEC_ENC_DRV_H_
|
||||
#define _MTK_VCODEC_ENC_DRV_H_
|
||||
|
||||
#include "mtk_vcodec_cmn_drv.h"
|
||||
#include "mtk_vcodec_fw_priv.h"
|
||||
|
||||
/*
|
||||
* enum mtk_encode_param - General encoding parameters type
|
||||
*/
|
||||
enum mtk_encode_param {
|
||||
MTK_ENCODE_PARAM_NONE = 0,
|
||||
MTK_ENCODE_PARAM_BITRATE = (1 << 0),
|
||||
MTK_ENCODE_PARAM_FRAMERATE = (1 << 1),
|
||||
MTK_ENCODE_PARAM_INTRA_PERIOD = (1 << 2),
|
||||
MTK_ENCODE_PARAM_FORCE_INTRA = (1 << 3),
|
||||
MTK_ENCODE_PARAM_GOP_SIZE = (1 << 4),
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_enc_params - General encoding parameters
|
||||
* @bitrate: target bitrate in bits per second
|
||||
* @num_b_frame: number of b frames between p-frame
|
||||
* @rc_frame: frame based rate control
|
||||
* @rc_mb: macroblock based rate control
|
||||
* @seq_hdr_mode: H.264 sequence header is encoded separately or joined
|
||||
* with the first frame
|
||||
* @intra_period: I frame period
|
||||
* @gop_size: group of picture size, it's used as the intra frame period
|
||||
* @framerate_num: frame rate numerator. ex: framerate_num=30 and
|
||||
* framerate_denom=1 means FPS is 30
|
||||
* @framerate_denom: frame rate denominator. ex: framerate_num=30 and
|
||||
* framerate_denom=1 means FPS is 30
|
||||
* @h264_max_qp: Max value for H.264 quantization parameter
|
||||
* @h264_profile: V4L2 defined H.264 profile
|
||||
* @h264_level: V4L2 defined H.264 level
|
||||
* @force_intra: force/insert intra frame
|
||||
*/
|
||||
struct mtk_enc_params {
|
||||
unsigned int bitrate;
|
||||
unsigned int num_b_frame;
|
||||
unsigned int rc_frame;
|
||||
unsigned int rc_mb;
|
||||
unsigned int seq_hdr_mode;
|
||||
unsigned int intra_period;
|
||||
unsigned int gop_size;
|
||||
unsigned int framerate_num;
|
||||
unsigned int framerate_denom;
|
||||
unsigned int h264_max_qp;
|
||||
unsigned int h264_profile;
|
||||
unsigned int h264_level;
|
||||
unsigned int force_intra;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_vcodec_enc_ctx - Context (instance) private data.
|
||||
*
|
||||
* @type: type of encoder instance
|
||||
* @dev: pointer to the mtk_vcodec_dev of the device
|
||||
* @list: link to ctx_list of mtk_vcodec_dev
|
||||
*
|
||||
* @fh: struct v4l2_fh
|
||||
* @m2m_ctx: pointer to the v4l2_m2m_ctx of the context
|
||||
* @q_data: store information of input and output queue of the context
|
||||
* @id: index of the context that this structure describes
|
||||
* @state: state of the context
|
||||
* @param_change: indicate encode parameter type
|
||||
* @enc_params: encoding parameters
|
||||
*
|
||||
* @enc_if: hooked encoder driver interface
|
||||
* @drv_handle: driver handle for specific decode/encode instance
|
||||
*
|
||||
* @int_cond: variable used by the waitqueue
|
||||
* @int_type: type of the last interrupt
|
||||
* @queue: waitqueue that can be used to wait for this context to finish
|
||||
* @irq_status: irq status
|
||||
*
|
||||
* @ctrl_hdl: handler for v4l2 framework
|
||||
* @encode_work: worker for the encoding
|
||||
* @empty_flush_buf: a fake size-0 capture buffer that indicates flush. Used for encoder.
|
||||
* @is_flushing: set to true if flushing is in progress.
|
||||
*
|
||||
* @colorspace: enum v4l2_colorspace; supplemental to pixelformat
|
||||
* @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
|
||||
* @quantization: enum v4l2_quantization, colorspace quantization
|
||||
* @xfer_func: enum v4l2_xfer_func, colorspace transfer function
|
||||
*
|
||||
* @q_mutex: vb2_queue mutex.
|
||||
*/
|
||||
struct mtk_vcodec_enc_ctx {
|
||||
enum mtk_instance_type type;
|
||||
struct mtk_vcodec_dev *dev;
|
||||
struct list_head list;
|
||||
|
||||
struct v4l2_fh fh;
|
||||
struct v4l2_m2m_ctx *m2m_ctx;
|
||||
struct mtk_q_data q_data[2];
|
||||
int id;
|
||||
enum mtk_instance_state state;
|
||||
enum mtk_encode_param param_change;
|
||||
struct mtk_enc_params enc_params;
|
||||
|
||||
const struct venc_common_if *enc_if;
|
||||
void *drv_handle;
|
||||
|
||||
int int_cond[MTK_VDEC_HW_MAX];
|
||||
int int_type[MTK_VDEC_HW_MAX];
|
||||
wait_queue_head_t queue[MTK_VDEC_HW_MAX];
|
||||
unsigned int irq_status;
|
||||
|
||||
struct v4l2_ctrl_handler ctrl_hdl;
|
||||
struct work_struct encode_work;
|
||||
struct v4l2_m2m_buffer empty_flush_buf;
|
||||
bool is_flushing;
|
||||
|
||||
enum v4l2_colorspace colorspace;
|
||||
enum v4l2_ycbcr_encoding ycbcr_enc;
|
||||
enum v4l2_quantization quantization;
|
||||
enum v4l2_xfer_func xfer_func;
|
||||
|
||||
struct mutex q_mutex;
|
||||
};
|
||||
|
||||
static inline struct mtk_vcodec_enc_ctx *fh_to_enc_ctx(struct v4l2_fh *fh)
|
||||
{
|
||||
return container_of(fh, struct mtk_vcodec_enc_ctx, fh);
|
||||
}
|
||||
|
||||
static inline struct mtk_vcodec_enc_ctx *ctrl_to_enc_ctx(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
return container_of(ctrl->handler, struct mtk_vcodec_enc_ctx, ctrl_hdl);
|
||||
}
|
||||
|
||||
/* Wake up context wait_queue */
|
||||
static inline void
|
||||
wake_up_enc_ctx(struct mtk_vcodec_enc_ctx *ctx, unsigned int reason, unsigned int hw_id)
|
||||
{
|
||||
ctx->int_cond[hw_id] = 1;
|
||||
ctx->int_type[hw_id] = reason;
|
||||
wake_up_interruptible(&ctx->queue[hw_id]);
|
||||
}
|
||||
|
||||
#endif /* _MTK_VCODEC_ENC_DRV_H_ */
|
||||
@@ -51,10 +51,25 @@ static void mtk_vcodec_vpu_release(struct mtk_vcodec_fw *fw)
|
||||
put_device(&fw->pdev->dev);
|
||||
}
|
||||
|
||||
static void mtk_vcodec_vpu_reset_handler(void *priv)
|
||||
static void mtk_vcodec_vpu_reset_dec_handler(void *priv)
|
||||
{
|
||||
struct mtk_vcodec_dev *dev = priv;
|
||||
struct mtk_vcodec_ctx *ctx;
|
||||
struct mtk_vcodec_dec_ctx *ctx;
|
||||
|
||||
dev_err(&dev->plat_dev->dev, "Watchdog timeout!!");
|
||||
|
||||
mutex_lock(&dev->dev_mutex);
|
||||
list_for_each_entry(ctx, &dev->ctx_list, list) {
|
||||
ctx->state = MTK_STATE_ABORT;
|
||||
mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id);
|
||||
}
|
||||
mutex_unlock(&dev->dev_mutex);
|
||||
}
|
||||
|
||||
static void mtk_vcodec_vpu_reset_enc_handler(void *priv)
|
||||
{
|
||||
struct mtk_vcodec_dev *dev = priv;
|
||||
struct mtk_vcodec_enc_ctx *ctx;
|
||||
|
||||
dev_err(&dev->plat_dev->dev, "Watchdog timeout!!");
|
||||
|
||||
@@ -84,14 +99,13 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(void *priv, enum mtk_vcodec_fw_use
|
||||
struct mtk_vcodec_fw *fw;
|
||||
enum rst_id rst_id;
|
||||
|
||||
switch (fw_use) {
|
||||
case ENCODER:
|
||||
if (fw_use == ENCODER) {
|
||||
rst_id = VPU_RST_ENC;
|
||||
break;
|
||||
case DECODER:
|
||||
default:
|
||||
} else if (fw_use == DECODER) {
|
||||
rst_id = VPU_RST_DEC;
|
||||
break;
|
||||
} else {
|
||||
pr_err("Invalid fw_use %d (use a resonable fw id here)\n", fw_use);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
plat_dev = dev->plat_dev;
|
||||
@@ -101,7 +115,10 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(void *priv, enum mtk_vcodec_fw_use
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
vpu_wdt_reg_handler(fw_pdev, mtk_vcodec_vpu_reset_handler, dev, rst_id);
|
||||
if (fw_use == DECODER)
|
||||
vpu_wdt_reg_handler(fw_pdev, mtk_vcodec_vpu_reset_dec_handler, priv, rst_id);
|
||||
else
|
||||
vpu_wdt_reg_handler(fw_pdev, mtk_vcodec_vpu_reset_enc_handler, priv, rst_id);
|
||||
|
||||
fw = devm_kzalloc(&plat_dev->dev, sizeof(*fw), GFP_KERNEL);
|
||||
if (!fw)
|
||||
|
||||
@@ -14,17 +14,34 @@
|
||||
int mtk_vcodec_wait_for_done_ctx(void *priv, int command, unsigned int timeout_ms,
|
||||
unsigned int hw_id)
|
||||
{
|
||||
struct mtk_vcodec_ctx *ctx = priv;
|
||||
int instance_type = *((int *)priv);
|
||||
long timeout_jiff, ret;
|
||||
int ctx_id, ctx_type, status = 0;
|
||||
int *ctx_int_cond, *ctx_int_type;
|
||||
wait_queue_head_t *ctx_queue;
|
||||
struct platform_device *pdev;
|
||||
|
||||
ctx_id = ctx->id;
|
||||
ctx_type = ctx->type;
|
||||
ctx_int_cond = ctx->int_cond;
|
||||
ctx_int_type = ctx->int_type;
|
||||
ctx_queue = ctx->queue;
|
||||
if (instance_type == DECODER) {
|
||||
struct mtk_vcodec_dec_ctx *ctx;
|
||||
|
||||
ctx = priv;
|
||||
ctx_id = ctx->id;
|
||||
ctx_type = ctx->type;
|
||||
ctx_int_cond = ctx->int_cond;
|
||||
ctx_int_type = ctx->int_type;
|
||||
ctx_queue = ctx->queue;
|
||||
pdev = ctx->dev->plat_dev;
|
||||
} else {
|
||||
struct mtk_vcodec_enc_ctx *ctx;
|
||||
|
||||
ctx = priv;
|
||||
ctx_id = ctx->id;
|
||||
ctx_type = ctx->type;
|
||||
ctx_int_cond = ctx->int_cond;
|
||||
ctx_int_type = ctx->int_type;
|
||||
ctx_queue = ctx->queue;
|
||||
pdev = ctx->dev->plat_dev;
|
||||
}
|
||||
|
||||
timeout_jiff = msecs_to_jiffies(timeout_ms);
|
||||
ret = wait_event_interruptible_timeout(ctx_queue[hw_id],
|
||||
@@ -33,12 +50,12 @@ int mtk_vcodec_wait_for_done_ctx(void *priv, int command, unsigned int timeout_m
|
||||
|
||||
if (!ret) {
|
||||
status = -1; /* timeout */
|
||||
dev_err(&ctx->dev->plat_dev->dev, "[%d] cmd=%d, type=%d, dec timeout=%ums (%d %d)",
|
||||
dev_err(&pdev->dev, "[%d] cmd=%d, type=%d, dec timeout=%ums (%d %d)",
|
||||
ctx_id, command, ctx_type, timeout_ms,
|
||||
ctx_int_cond[hw_id], ctx_int_type[hw_id]);
|
||||
} else if (-ERESTARTSYS == ret) {
|
||||
status = -1;
|
||||
dev_err(&ctx->dev->plat_dev->dev, "[%d] cmd=%d, type=%d, dec inter fail (%d %d)",
|
||||
dev_err(&pdev->dev, "[%d] cmd=%d, type=%d, dec inter fail (%d %d)",
|
||||
ctx_id, command, ctx_type,
|
||||
ctx_int_cond[hw_id], ctx_int_type[hw_id]);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user