aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-03 17:16:59 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-03 17:16:59 -0700
commitef1c4a6fa91bbbe9b09f770d28eba31a9edf770c (patch)
tree52f5d175031c553160d14890e876ffc5432d2467 /drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
parentMerge tag 'kconfig-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild (diff)
parentmedia: v4l2-ioctl: rename a temp var that stores _IOC_SIZE(cmd) (diff)
downloadlinux-dev-ef1c4a6fa91bbbe9b09f770d28eba31a9edf770c.tar.xz
linux-dev-ef1c4a6fa91bbbe9b09f770d28eba31a9edf770c.zip
Merge tag 'media/v4.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - new CEC pin injection code for testing purposes - DVB frontend cxd2099 promoted from staging - new platform driver for Sony cxd2880 DVB devices - new sensor drivers: mt9t112, ov2685, ov5695, ov772x, tda1997x, tw9910.c - removal of unused cx18 and ivtv alsa mixers - the reneseas-ceu driver doesn't depend on soc_camera anymore and moved from staging - removed the mantis_vp3028 driver, unused since 2009 - s5p-mfc: add support for version 10 of the MSP - added a decoder for imon protocol - atomisp: lots of cleanups - imx074 and mt9t031: don't depend on soc_camera anymore, being promoted from staging - added helper functions to better support DVB I2C binding - lots of driver improvements and cleanups * tag 'media/v4.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (438 commits) media: v4l2-ioctl: rename a temp var that stores _IOC_SIZE(cmd) media: fimc-capture: get rid of two warnings media: dvb-usb-v2: fix a missing dependency of I2C_MUX media: uvc: to the right check at uvc_ioctl_enum_framesizes() media: cec-core: fix a bug at cec_error_inj_write() media: tda9840: cleanup a warning media: tm6000: avoid casting just to print pointer address media: em28xx-input: improve error handling code media: zr364xx: avoid casting just to print pointer address media: vivid-radio-rx: add a cast to avoid a warning media: saa7134-alsa: don't use casts to print a buffer address media: solo6x10: get rid of an address space warning media: zoran: don't cast pointers to print them media: ir-kbd-i2c: change the if logic to avoid a warning media: ir-kbd-i2c: improve error handling code media: saa7134-input: improve error handling media: s2255drv: fix a casting warning media: ivtvfb: Cleanup some warnings media: videobuf-dma-sg: Fix a weird cast soc_camera: fix a weird cast on printk ...
Diffstat (limited to 'drivers/media/platform/s5p-mfc/s5p_mfc_enc.c')
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_enc.c599
1 files changed, 588 insertions, 11 deletions
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
index 0d5d465561be..5c0462ca9993 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
@@ -57,8 +57,7 @@ static struct s5p_mfc_fmt formats[] = {
.codec_mode = S5P_MFC_CODEC_NONE,
.type = MFC_FMT_RAW,
.num_planes = 2,
- .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT |
- MFC_V8_BIT,
+ .versions = MFC_V5PLUS_BITS,
},
{
.name = "4:2:0 2 Planes Y/CrCb",
@@ -66,7 +65,7 @@ static struct s5p_mfc_fmt formats[] = {
.codec_mode = S5P_MFC_CODEC_NONE,
.type = MFC_FMT_RAW,
.num_planes = 2,
- .versions = MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT,
+ .versions = MFC_V6PLUS_BITS,
},
{
.name = "H264 Encoded Stream",
@@ -74,8 +73,7 @@ static struct s5p_mfc_fmt formats[] = {
.codec_mode = S5P_MFC_CODEC_H264_ENC,
.type = MFC_FMT_ENC,
.num_planes = 1,
- .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT |
- MFC_V8_BIT,
+ .versions = MFC_V5PLUS_BITS,
},
{
.name = "MPEG4 Encoded Stream",
@@ -83,8 +81,7 @@ static struct s5p_mfc_fmt formats[] = {
.codec_mode = S5P_MFC_CODEC_MPEG4_ENC,
.type = MFC_FMT_ENC,
.num_planes = 1,
- .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT |
- MFC_V8_BIT,
+ .versions = MFC_V5PLUS_BITS,
},
{
.name = "H263 Encoded Stream",
@@ -92,8 +89,7 @@ static struct s5p_mfc_fmt formats[] = {
.codec_mode = S5P_MFC_CODEC_H263_ENC,
.type = MFC_FMT_ENC,
.num_planes = 1,
- .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT |
- MFC_V8_BIT,
+ .versions = MFC_V5PLUS_BITS,
},
{
.name = "VP8 Encoded Stream",
@@ -101,7 +97,14 @@ static struct s5p_mfc_fmt formats[] = {
.codec_mode = S5P_MFC_CODEC_VP8_ENC,
.type = MFC_FMT_ENC,
.num_planes = 1,
- .versions = MFC_V7_BIT | MFC_V8_BIT,
+ .versions = MFC_V7PLUS_BITS,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_HEVC,
+ .codec_mode = S5P_FIMV_CODEC_HEVC_ENC,
+ .type = MFC_FMT_ENC,
+ .num_planes = 1,
+ .versions = MFC_V10_BIT,
},
};
@@ -697,6 +700,368 @@ static struct mfc_control controls[] = {
.default_value = 0,
},
{
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC I Frame QP Value",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC P Frame QP Value",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+ .maximum = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
+ .maximum = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_TIER,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN,
+ .maximum = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 1,
+ .maximum = (1 << 16) - 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 1,
+ .maximum = 2,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE,
+ .maximum = V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED,
+ .maximum = V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B,
+ .maximum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 6,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 4,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = (1 << 16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = -6,
+ .maximum = 6,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = -6,
+ .maximum = 6,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .minimum = V4L2_MPEG_VIDEO_HEVC_SIZE_0,
+ .maximum = V4L2_MPEG_VIDEO_HEVC_SIZE_4,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_HEVC_SIZE_0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
.id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Minimum number of output bufs",
@@ -817,6 +1182,11 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
get_enc_dpb_count, dev);
if (ctx->pb_count < enc_pb_count)
ctx->pb_count = enc_pb_count;
+ if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) {
+ ctx->scratch_buf_size = s5p_mfc_hw_call(dev->mfc_ops,
+ get_e_min_scratch_buf_size, dev);
+ ctx->bank1.size += ctx->scratch_buf_size;
+ }
ctx->state = MFCINST_HEAD_PRODUCED;
}
@@ -850,7 +1220,7 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
struct s5p_mfc_buf *mb_entry;
- unsigned long enc_y_addr, enc_c_addr;
+ unsigned long enc_y_addr = 0, enc_c_addr = 0;
unsigned long mb_y_addr, mb_c_addr;
int slice_type;
unsigned int strm_size;
@@ -1358,6 +1728,26 @@ static inline int mpeg4_level(enum v4l2_mpeg_video_mpeg4_level lvl)
return t[lvl];
}
+static inline int hevc_level(enum v4l2_mpeg_video_hevc_level lvl)
+{
+ static unsigned int t[] = {
+ /* V4L2_MPEG_VIDEO_HEVC_LEVEL_1 */ 10,
+ /* V4L2_MPEG_VIDEO_HEVC_LEVEL_2 */ 20,
+ /* V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1 */ 21,
+ /* V4L2_MPEG_VIDEO_HEVC_LEVEL_3 */ 30,
+ /* V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1 */ 31,
+ /* V4L2_MPEG_VIDEO_HEVC_LEVEL_4 */ 40,
+ /* V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1 */ 41,
+ /* V4L2_MPEG_VIDEO_HEVC_LEVEL_5 */ 50,
+ /* V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1 */ 51,
+ /* V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2 */ 52,
+ /* V4L2_MPEG_VIDEO_HEVC_LEVEL_6 */ 60,
+ /* V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1 */ 61,
+ /* V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2 */ 62,
+ };
+ return t[lvl];
+}
+
static inline int vui_sar_idc(enum v4l2_mpeg_video_h264_vui_sar_idc sar)
{
static unsigned int t[V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED + 1] = {
@@ -1383,6 +1773,42 @@ static inline int vui_sar_idc(enum v4l2_mpeg_video_h264_vui_sar_idc sar)
return t[sar];
}
+/*
+ * Update range of all HEVC quantization parameter controls that depend on the
+ * V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP controls.
+ */
+static void __enc_update_hevc_qp_ctrls_range(struct s5p_mfc_ctx *ctx,
+ int min, int max)
+{
+ static const int __hevc_qp_ctrls[] = {
+ V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP,
+ V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP,
+ V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP,
+ V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP,
+ V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP,
+ V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP,
+ V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP,
+ V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP,
+ V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP,
+ V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP,
+ };
+ struct v4l2_ctrl *ctrl = NULL;
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(__hevc_qp_ctrls); i++) {
+ for (j = 0; j < ARRAY_SIZE(ctx->ctrls); j++) {
+ if (ctx->ctrls[j]->id == __hevc_qp_ctrls[i]) {
+ ctrl = ctx->ctrls[j];
+ break;
+ }
+ }
+ if (WARN_ON(!ctrl))
+ break;
+
+ __v4l2_ctrl_modify_range(ctrl, min, max, ctrl->step, min);
+ }
+}
+
static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl);
@@ -1634,6 +2060,157 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_MPEG_VIDEO_VPX_PROFILE:
p->codec.vp8.profile = ctrl->val;
break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:
+ p->codec.hevc.rc_frame_qp = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP:
+ p->codec.hevc.rc_p_frame_qp = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP:
+ p->codec.hevc.rc_b_frame_qp = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION:
+ p->codec.hevc.rc_framerate = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:
+ p->codec.hevc.rc_min_qp = ctrl->val;
+ __enc_update_hevc_qp_ctrls_range(ctx, ctrl->val,
+ p->codec.hevc.rc_max_qp);
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:
+ p->codec.hevc.rc_max_qp = ctrl->val;
+ __enc_update_hevc_qp_ctrls_range(ctx, p->codec.hevc.rc_min_qp,
+ ctrl->val);
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
+ p->codec.hevc.level_v4l2 = ctrl->val;
+ p->codec.hevc.level = hevc_level(ctrl->val);
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
+ switch (ctrl->val) {
+ case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN:
+ p->codec.hevc.profile =
+ V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN;
+ break;
+ case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE:
+ p->codec.hevc.profile =
+ V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_TIER:
+ p->codec.hevc.tier = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH:
+ p->codec.hevc.max_partition_depth = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES:
+ p->codec.hevc.num_refs_for_p = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE:
+ p->codec.hevc.refreshtype = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED:
+ p->codec.hevc.const_intra_period_enable = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU:
+ p->codec.hevc.lossless_cu_enable = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT:
+ p->codec.hevc.wavefront_enable = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE:
+ p->codec.hevc.loopfilter = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP:
+ p->codec.hevc.hier_qp_enable = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE:
+ p->codec.hevc.hier_qp_type = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER:
+ p->codec.hevc.num_hier_layer = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP:
+ p->codec.hevc.hier_qp_layer[0] = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP:
+ p->codec.hevc.hier_qp_layer[1] = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP:
+ p->codec.hevc.hier_qp_layer[2] = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP:
+ p->codec.hevc.hier_qp_layer[3] = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP:
+ p->codec.hevc.hier_qp_layer[4] = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP:
+ p->codec.hevc.hier_qp_layer[5] = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP:
+ p->codec.hevc.hier_qp_layer[6] = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR:
+ p->codec.hevc.hier_bit_layer[0] = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR:
+ p->codec.hevc.hier_bit_layer[1] = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR:
+ p->codec.hevc.hier_bit_layer[2] = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR:
+ p->codec.hevc.hier_bit_layer[3] = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR:
+ p->codec.hevc.hier_bit_layer[4] = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR:
+ p->codec.hevc.hier_bit_layer[5] = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR:
+ p->codec.hevc.hier_bit_layer[6] = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB:
+ p->codec.hevc.general_pb_enable = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID:
+ p->codec.hevc.temporal_id_enable = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING:
+ p->codec.hevc.strong_intra_smooth = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT:
+ p->codec.hevc.intra_pu_split_disable = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION:
+ p->codec.hevc.tmv_prediction_disable = !ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1:
+ p->codec.hevc.max_num_merge_mv = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE:
+ p->codec.hevc.encoding_nostartcode_enable = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD:
+ p->codec.hevc.refreshperiod = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2:
+ p->codec.hevc.lf_beta_offset_div2 = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2:
+ p->codec.hevc.lf_tc_offset_div2 = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD:
+ p->codec.hevc.size_of_length_field = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR:
+ p->codec.hevc.prepend_sps_pps_to_idr = ctrl->val;
+ break;
default:
v4l2_err(&dev->v4l2_dev, "Invalid control, id=%d, val=%d\n",
ctrl->id, ctrl->val);