mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-21 00:54:52 -04:00
media: iris: Add support for ENUM_FRAMESIZES/FRAMEINTERVALS for encoder
Add support for frame size and frame interval enumeration by implementing ENUM_FRAMESIZES/FRAMEINTERVALS V4L2 ioctls for encoder video device with necessary hooks. This allows userspace application to query encoder capabilities and adapt encoding configurations accordingly. Tested-by: Vikash Garodia <quic_vgarodia@quicinc.com> # X1E80100 Reviewed-by: Vikash Garodia <quic_vgarodia@quicinc.com> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-HDK Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com> Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # x1e80100-crd Signed-off-by: Bryan O'Donoghue <bod@kernel.org> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
committed by
Hans Verkuil
parent
63357cf8a9
commit
a6882431a1
@@ -21,7 +21,8 @@ struct iris_inst;
|
||||
#define DEFAULT_MAX_HOST_BUF_COUNT 64
|
||||
#define DEFAULT_MAX_HOST_BURST_BUF_COUNT 256
|
||||
#define DEFAULT_FPS 30
|
||||
#define NUM_MBS_8K ((8192 * 4352) / 256)
|
||||
#define MAXIMUM_FPS 480
|
||||
#define NUM_MBS_8K ((8192 * 4352) / 256)
|
||||
|
||||
enum stage_type {
|
||||
STAGE_1 = 1,
|
||||
@@ -183,6 +184,8 @@ struct iris_platform_data {
|
||||
u32 max_session_count;
|
||||
/* max number of macroblocks per frame supported */
|
||||
u32 max_core_mbpf;
|
||||
/* max number of macroblocks per second supported */
|
||||
u32 max_core_mbps;
|
||||
const u32 *input_config_params_default;
|
||||
unsigned int input_config_params_default_size;
|
||||
const u32 *input_config_params_hevc;
|
||||
|
||||
@@ -356,6 +356,7 @@ struct iris_platform_data sm8550_data = {
|
||||
.num_vpp_pipe = 4,
|
||||
.max_session_count = 16,
|
||||
.max_core_mbpf = NUM_MBS_8K * 2,
|
||||
.max_core_mbps = ((7680 * 4320) / 256) * 60,
|
||||
.input_config_params_default =
|
||||
sm8550_vdec_input_config_params_default,
|
||||
.input_config_params_default_size =
|
||||
@@ -431,6 +432,7 @@ struct iris_platform_data sm8650_data = {
|
||||
.num_vpp_pipe = 4,
|
||||
.max_session_count = 16,
|
||||
.max_core_mbpf = NUM_MBS_8K * 2,
|
||||
.max_core_mbps = ((7680 * 4320) / 256) * 60,
|
||||
.input_config_params_default =
|
||||
sm8550_vdec_input_config_params_default,
|
||||
.input_config_params_default_size =
|
||||
@@ -568,6 +570,7 @@ struct iris_platform_data qcs8300_data = {
|
||||
.num_vpp_pipe = 2,
|
||||
.max_session_count = 16,
|
||||
.max_core_mbpf = ((4096 * 2176) / 256) * 4,
|
||||
.max_core_mbps = (((3840 * 2176) / 256) * 120),
|
||||
.input_config_params_default =
|
||||
sm8550_vdec_input_config_params_default,
|
||||
.input_config_params_default_size =
|
||||
|
||||
@@ -128,6 +128,7 @@ struct iris_platform_data sm8250_data = {
|
||||
.num_vpp_pipe = 4,
|
||||
.max_session_count = 16,
|
||||
.max_core_mbpf = NUM_MBS_8K,
|
||||
.max_core_mbps = ((7680 * 4320) / 256) * 60,
|
||||
.input_config_params_default =
|
||||
sm8250_vdec_input_config_param_default,
|
||||
.input_config_params_default_size =
|
||||
|
||||
@@ -263,6 +263,19 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iris_vdec_validate_format(struct iris_inst *inst, u32 pixelformat)
|
||||
{
|
||||
const struct iris_fmt *fmt = NULL;
|
||||
|
||||
if (pixelformat != V4L2_PIX_FMT_NV12) {
|
||||
fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
|
||||
if (!fmt)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@@ -13,6 +13,7 @@ void iris_vdec_inst_deinit(struct iris_inst *inst);
|
||||
int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);
|
||||
int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
|
||||
int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f);
|
||||
int iris_vdec_validate_format(struct iris_inst *inst, u32 pixelformat);
|
||||
int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub);
|
||||
void iris_vdec_src_change(struct iris_inst *inst);
|
||||
int iris_vdec_streamon_input(struct iris_inst *inst);
|
||||
|
||||
@@ -273,3 +273,16 @@ int iris_venc_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int iris_venc_validate_format(struct iris_inst *inst, u32 pixelformat)
|
||||
{
|
||||
const struct iris_fmt *fmt = NULL;
|
||||
|
||||
if (pixelformat != V4L2_PIX_FMT_NV12) {
|
||||
fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
|
||||
if (!fmt)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -13,5 +13,6 @@ void iris_venc_inst_deinit(struct iris_inst *inst);
|
||||
int iris_venc_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);
|
||||
int iris_venc_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
|
||||
int iris_venc_s_fmt(struct iris_inst *inst, struct v4l2_format *f);
|
||||
int iris_venc_validate_format(struct iris_inst *inst, u32 pixelformat);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -371,13 +371,18 @@ static int iris_enum_framesizes(struct file *filp, void *fh,
|
||||
{
|
||||
struct iris_inst *inst = iris_get_inst(filp);
|
||||
struct platform_inst_caps *caps;
|
||||
int ret = 0;
|
||||
|
||||
if (fsize->index)
|
||||
return -EINVAL;
|
||||
|
||||
if (fsize->pixel_format != V4L2_PIX_FMT_H264 &&
|
||||
fsize->pixel_format != V4L2_PIX_FMT_NV12)
|
||||
return -EINVAL;
|
||||
if (inst->domain == DECODER)
|
||||
ret = iris_vdec_validate_format(inst, fsize->pixel_format);
|
||||
else
|
||||
ret = iris_venc_validate_format(inst, fsize->pixel_format);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
caps = inst->core->iris_platform_data->inst_caps;
|
||||
|
||||
@@ -389,6 +394,51 @@ static int iris_enum_framesizes(struct file *filp, void *fh,
|
||||
fsize->stepwise.max_height = caps->max_frame_height;
|
||||
fsize->stepwise.step_height = STEP_HEIGHT;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iris_enum_frameintervals(struct file *filp, void *fh,
|
||||
struct v4l2_frmivalenum *fival)
|
||||
|
||||
{
|
||||
struct iris_inst *inst = iris_get_inst(filp);
|
||||
struct iris_core *core = inst->core;
|
||||
struct platform_inst_caps *caps;
|
||||
u32 fps, mbpf;
|
||||
int ret = 0;
|
||||
|
||||
if (inst->domain == DECODER)
|
||||
return -ENOTTY;
|
||||
|
||||
if (fival->index)
|
||||
return -EINVAL;
|
||||
|
||||
ret = iris_venc_validate_format(inst, fival->pixel_format);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!fival->width || !fival->height)
|
||||
return -EINVAL;
|
||||
|
||||
caps = inst->core->iris_platform_data->inst_caps;
|
||||
if (fival->width > caps->max_frame_width ||
|
||||
fival->width < caps->min_frame_width ||
|
||||
fival->height > caps->max_frame_height ||
|
||||
fival->height < caps->min_frame_height)
|
||||
return -EINVAL;
|
||||
|
||||
mbpf = NUM_MBS_PER_FRAME(fival->height, fival->width);
|
||||
fps = DIV_ROUND_UP(core->iris_platform_data->max_core_mbps, mbpf);
|
||||
|
||||
fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
|
||||
fival->stepwise.min.numerator = 1;
|
||||
fival->stepwise.min.denominator =
|
||||
min_t(u32, fps, MAXIMUM_FPS);
|
||||
fival->stepwise.max.numerator = 1;
|
||||
fival->stepwise.max.denominator = 1;
|
||||
fival->stepwise.step.numerator = 1;
|
||||
fival->stepwise.step.denominator = MAXIMUM_FPS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -523,6 +573,8 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops_enc = {
|
||||
.vidioc_s_fmt_vid_out_mplane = iris_s_fmt_vid_mplane,
|
||||
.vidioc_g_fmt_vid_cap_mplane = iris_g_fmt_vid_mplane,
|
||||
.vidioc_g_fmt_vid_out_mplane = iris_g_fmt_vid_mplane,
|
||||
.vidioc_enum_framesizes = iris_enum_framesizes,
|
||||
.vidioc_enum_frameintervals = iris_enum_frameintervals,
|
||||
};
|
||||
|
||||
void iris_init_ops(struct iris_core *core)
|
||||
|
||||
Reference in New Issue
Block a user