mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 10:33:41 +02: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:
parent
63357cf8a9
commit
a6882431a1
|
|
@ -21,7 +21,8 @@ struct iris_inst;
|
||||||
#define DEFAULT_MAX_HOST_BUF_COUNT 64
|
#define DEFAULT_MAX_HOST_BUF_COUNT 64
|
||||||
#define DEFAULT_MAX_HOST_BURST_BUF_COUNT 256
|
#define DEFAULT_MAX_HOST_BURST_BUF_COUNT 256
|
||||||
#define DEFAULT_FPS 30
|
#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 {
|
enum stage_type {
|
||||||
STAGE_1 = 1,
|
STAGE_1 = 1,
|
||||||
|
|
@ -183,6 +184,8 @@ struct iris_platform_data {
|
||||||
u32 max_session_count;
|
u32 max_session_count;
|
||||||
/* max number of macroblocks per frame supported */
|
/* max number of macroblocks per frame supported */
|
||||||
u32 max_core_mbpf;
|
u32 max_core_mbpf;
|
||||||
|
/* max number of macroblocks per second supported */
|
||||||
|
u32 max_core_mbps;
|
||||||
const u32 *input_config_params_default;
|
const u32 *input_config_params_default;
|
||||||
unsigned int input_config_params_default_size;
|
unsigned int input_config_params_default_size;
|
||||||
const u32 *input_config_params_hevc;
|
const u32 *input_config_params_hevc;
|
||||||
|
|
|
||||||
|
|
@ -356,6 +356,7 @@ struct iris_platform_data sm8550_data = {
|
||||||
.num_vpp_pipe = 4,
|
.num_vpp_pipe = 4,
|
||||||
.max_session_count = 16,
|
.max_session_count = 16,
|
||||||
.max_core_mbpf = NUM_MBS_8K * 2,
|
.max_core_mbpf = NUM_MBS_8K * 2,
|
||||||
|
.max_core_mbps = ((7680 * 4320) / 256) * 60,
|
||||||
.input_config_params_default =
|
.input_config_params_default =
|
||||||
sm8550_vdec_input_config_params_default,
|
sm8550_vdec_input_config_params_default,
|
||||||
.input_config_params_default_size =
|
.input_config_params_default_size =
|
||||||
|
|
@ -431,6 +432,7 @@ struct iris_platform_data sm8650_data = {
|
||||||
.num_vpp_pipe = 4,
|
.num_vpp_pipe = 4,
|
||||||
.max_session_count = 16,
|
.max_session_count = 16,
|
||||||
.max_core_mbpf = NUM_MBS_8K * 2,
|
.max_core_mbpf = NUM_MBS_8K * 2,
|
||||||
|
.max_core_mbps = ((7680 * 4320) / 256) * 60,
|
||||||
.input_config_params_default =
|
.input_config_params_default =
|
||||||
sm8550_vdec_input_config_params_default,
|
sm8550_vdec_input_config_params_default,
|
||||||
.input_config_params_default_size =
|
.input_config_params_default_size =
|
||||||
|
|
@ -568,6 +570,7 @@ struct iris_platform_data qcs8300_data = {
|
||||||
.num_vpp_pipe = 2,
|
.num_vpp_pipe = 2,
|
||||||
.max_session_count = 16,
|
.max_session_count = 16,
|
||||||
.max_core_mbpf = ((4096 * 2176) / 256) * 4,
|
.max_core_mbpf = ((4096 * 2176) / 256) * 4,
|
||||||
|
.max_core_mbps = (((3840 * 2176) / 256) * 120),
|
||||||
.input_config_params_default =
|
.input_config_params_default =
|
||||||
sm8550_vdec_input_config_params_default,
|
sm8550_vdec_input_config_params_default,
|
||||||
.input_config_params_default_size =
|
.input_config_params_default_size =
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ struct iris_platform_data sm8250_data = {
|
||||||
.num_vpp_pipe = 4,
|
.num_vpp_pipe = 4,
|
||||||
.max_session_count = 16,
|
.max_session_count = 16,
|
||||||
.max_core_mbpf = NUM_MBS_8K,
|
.max_core_mbpf = NUM_MBS_8K,
|
||||||
|
.max_core_mbps = ((7680 * 4320) / 256) * 60,
|
||||||
.input_config_params_default =
|
.input_config_params_default =
|
||||||
sm8250_vdec_input_config_param_default,
|
sm8250_vdec_input_config_param_default,
|
||||||
.input_config_params_default_size =
|
.input_config_params_default_size =
|
||||||
|
|
|
||||||
|
|
@ -263,6 +263,19 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
|
||||||
return 0;
|
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 iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
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_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_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_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);
|
int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub);
|
||||||
void iris_vdec_src_change(struct iris_inst *inst);
|
void iris_vdec_src_change(struct iris_inst *inst);
|
||||||
int iris_vdec_streamon_input(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;
|
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_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_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_s_fmt(struct iris_inst *inst, struct v4l2_format *f);
|
||||||
|
int iris_venc_validate_format(struct iris_inst *inst, u32 pixelformat);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -371,13 +371,18 @@ static int iris_enum_framesizes(struct file *filp, void *fh,
|
||||||
{
|
{
|
||||||
struct iris_inst *inst = iris_get_inst(filp);
|
struct iris_inst *inst = iris_get_inst(filp);
|
||||||
struct platform_inst_caps *caps;
|
struct platform_inst_caps *caps;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (fsize->index)
|
if (fsize->index)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (fsize->pixel_format != V4L2_PIX_FMT_H264 &&
|
if (inst->domain == DECODER)
|
||||||
fsize->pixel_format != V4L2_PIX_FMT_NV12)
|
ret = iris_vdec_validate_format(inst, fsize->pixel_format);
|
||||||
return -EINVAL;
|
else
|
||||||
|
ret = iris_venc_validate_format(inst, fsize->pixel_format);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
caps = inst->core->iris_platform_data->inst_caps;
|
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.max_height = caps->max_frame_height;
|
||||||
fsize->stepwise.step_height = STEP_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;
|
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_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_cap_mplane = iris_g_fmt_vid_mplane,
|
||||||
.vidioc_g_fmt_vid_out_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)
|
void iris_init_ops(struct iris_core *core)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user