video: rockchip: mpp: rkvdec2: add codec_info

the codec_info is similar to rkvenc && vepu.

Change-Id: I2dfb1ceaaf582e16a8525ed2286768bf1296542a
Signed-off-by: Ding Wei <leo.ding@rock-chips.com>
This commit is contained in:
Ding Wei
2021-02-22 09:57:01 +08:00
parent e26a5d3bf2
commit aedde11d4e
6 changed files with 109 additions and 15 deletions

View File

@@ -1075,7 +1075,7 @@ static int mpp_process_request(struct mpp_session *session,
if (mpp->dev_ops->ioctl)
return mpp->dev_ops->ioctl(session, req);
mpp_err("unknown mpp ioctl cmd %x\n", req->cmd);
mpp_debug(DEBUG_IOCTL, "unknown mpp ioctl cmd %x\n", req->cmd);
return -ENOIOCTLCMD;
} break;
}

View File

@@ -150,12 +150,23 @@ enum ENC_INFO_TYPE {
ENC_INFO_BUTT,
};
enum ENC_INFO_FLAGS {
ENC_INFO_FLAG_NULL = 0,
ENC_INFO_FLAG_NUMBER,
ENC_INFO_FLAG_STRING,
enum DEC_INFO_TYPE {
DEC_INFO_BASE = 0,
DEC_INFO_WIDTH,
DEC_INFO_HEIGHT,
DEC_INFO_FORMAT,
DEC_INFO_BITDEPTH,
DEC_INFO_FPS,
ENC_INFO_FLAG_BUTT,
DEC_INFO_BUTT,
};
enum CODEC_INFO_FLAGS {
CODEC_INFO_FLAG_NULL = 0,
CODEC_INFO_FLAG_NUMBER,
CODEC_INFO_FLAG_STRING,
CODEC_INFO_FLAG_BUTT,
};
/* data common struct for parse out */

View File

@@ -27,6 +27,7 @@
#include <linux/thermal.h>
#include <linux/notifier.h>
#include <linux/proc_fs.h>
#include <linux/nospec.h>
#include <linux/rockchip/rockchip_sip.h>
#include <linux/regulator/consumer.h>
@@ -144,6 +145,16 @@ struct rkvdec_task {
struct mpp_request r_reqs[MPP_MAX_MSG_NUM];
};
struct rkvdec_session_priv {
/* codec info from user */
struct {
/* show mode */
u32 flag;
/* item data */
u64 val;
} codec_info[DEC_INFO_BUTT];
};
struct rkvdec_dev {
struct mpp_dev mpp;
/* sip smc reset lock */
@@ -610,6 +621,75 @@ static int rkvdec_free_task(struct mpp_session *session,
return 0;
}
static int rkvdec_control(struct mpp_session *session, struct mpp_request *req)
{
switch (req->cmd) {
case MPP_CMD_SEND_CODEC_INFO: {
int i;
int cnt;
struct codec_info_elem elem;
struct rkvdec_session_priv *priv;
if (!session || !session->priv) {
mpp_err("session info null\n");
return -EINVAL;
}
priv = session->priv;
cnt = req->size / sizeof(elem);
cnt = (cnt > DEC_INFO_BUTT) ? DEC_INFO_BUTT : cnt;
mpp_debug(DEBUG_IOCTL, "codec info count %d\n", cnt);
for (i = 0; i < cnt; i++) {
if (copy_from_user(&elem, req->data + i * sizeof(elem), sizeof(elem))) {
mpp_err("copy_from_user failed\n");
continue;
}
if (elem.type > DEC_INFO_BASE && elem.type < DEC_INFO_BUTT &&
elem.flag > CODEC_INFO_FLAG_NULL && elem.flag < CODEC_INFO_FLAG_BUTT) {
elem.type = array_index_nospec(elem.type, DEC_INFO_BUTT);
priv->codec_info[elem.type].flag = elem.flag;
priv->codec_info[elem.type].val = elem.data;
} else {
mpp_err("codec info invalid, type %d, flag %d\n",
elem.type, elem.flag);
}
}
} break;
default: {
mpp_err("unknown mpp ioctl cmd %x\n", req->cmd);
} break;
}
return 0;
}
static int rkvdec_free_session(struct mpp_session *session)
{
if (session && session->priv) {
kfree(session->priv);
session->priv = NULL;
}
return 0;
}
static int rkvdec_init_session(struct mpp_session *session)
{
struct rkvdec_session_priv *priv;
if (!session) {
mpp_err("session is null\n");
return -EINVAL;
}
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
session->priv = priv;
return 0;
}
#ifdef CONFIG_PROC_FS
static int rkvdec_procfs_remove(struct mpp_dev *mpp)
{
@@ -821,6 +901,9 @@ static struct mpp_dev_ops rkvdec_v2_dev_ops = {
.finish = rkvdec_finish,
.result = rkvdec_result,
.free_task = rkvdec_free_task,
.ioctl = rkvdec_control,
.init_session = rkvdec_init_session,
.free_session = rkvdec_free_session,
};
static const struct mpp_dev_var rkvdec_v2_data = {

View File

@@ -667,7 +667,7 @@ static int rkvenc_control(struct mpp_session *session, struct mpp_request *req)
continue;
}
if (elem.type > ENC_INFO_BASE && elem.type < ENC_INFO_BUTT &&
elem.flag > ENC_INFO_FLAG_NULL && elem.flag < ENC_INFO_FLAG_BUTT) {
elem.flag > CODEC_INFO_FLAG_NULL && elem.flag < CODEC_INFO_FLAG_BUTT) {
elem.type = array_index_nospec(elem.type, ENC_INFO_BUTT);
priv->codec_info[elem.type].flag = elem.flag;
priv->codec_info[elem.type].val = elem.data;
@@ -753,11 +753,11 @@ static int rkvenc_dump_session(struct mpp_session *session, struct seq_file *seq
if (!flag)
continue;
if (flag == ENC_INFO_FLAG_NUMBER) {
if (flag == CODEC_INFO_FLAG_NUMBER) {
u32 data = priv->codec_info[i].val;
seq_printf(seq, "%8d|", data);
} else if (flag == ENC_INFO_FLAG_STRING) {
} else if (flag == CODEC_INFO_FLAG_STRING) {
const char *name = (const char *)&priv->codec_info[i].val;
seq_printf(seq, "%8s|", name);

View File

@@ -419,7 +419,7 @@ static int vepu_control(struct mpp_session *session, struct mpp_request *req)
continue;
}
if (elem.type > ENC_INFO_BASE && elem.type < ENC_INFO_BUTT &&
elem.flag > ENC_INFO_FLAG_NULL && elem.flag < ENC_INFO_FLAG_BUTT) {
elem.flag > CODEC_INFO_FLAG_NULL && elem.flag < CODEC_INFO_FLAG_BUTT) {
elem.type = array_index_nospec(elem.type, ENC_INFO_BUTT);
priv->codec_info[elem.type].flag = elem.flag;
priv->codec_info[elem.type].val = elem.data;
@@ -506,11 +506,11 @@ static int vepu_dump_session(struct mpp_session *session, struct seq_file *seq)
if (!flag)
continue;
if (flag == ENC_INFO_FLAG_NUMBER) {
if (flag == CODEC_INFO_FLAG_NUMBER) {
u32 data = priv->codec_info[i].val;
seq_printf(seq, "%8d|", data);
} else if (flag == ENC_INFO_FLAG_STRING) {
} else if (flag == CODEC_INFO_FLAG_STRING) {
const char *name = (const char *)&priv->codec_info[i].val;
seq_printf(seq, "%8s|", name);

View File

@@ -442,7 +442,7 @@ static int vepu_control(struct mpp_session *session, struct mpp_request *req)
continue;
}
if (elem.type > ENC_INFO_BASE && elem.type < ENC_INFO_BUTT &&
elem.flag > ENC_INFO_FLAG_NULL && elem.flag < ENC_INFO_FLAG_BUTT) {
elem.flag > CODEC_INFO_FLAG_NULL && elem.flag < CODEC_INFO_FLAG_BUTT) {
elem.type = array_index_nospec(elem.type, ENC_INFO_BUTT);
priv->codec_info[elem.type].flag = elem.flag;
priv->codec_info[elem.type].val = elem.data;
@@ -528,11 +528,11 @@ static int vepu_dump_session(struct mpp_session *session, struct seq_file *seq)
if (!flag)
continue;
if (flag == ENC_INFO_FLAG_NUMBER) {
if (flag == CODEC_INFO_FLAG_NUMBER) {
u32 data = priv->codec_info[i].val;
seq_printf(seq, "%8d|", data);
} else if (flag == ENC_INFO_FLAG_STRING) {
} else if (flag == CODEC_INFO_FLAG_STRING) {
const char *name = (const char *)&priv->codec_info[i].val;
seq_printf(seq, "%8s|", name);