[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250930040348.3702923-26-h.dewangan@samsung.com>
Date: Tue, 30 Sep 2025 09:33:44 +0530
From: Himanshu Dewangan <h.dewangan@...sung.com>
To: mchehab@...nel.org, robh@...nel.org, krzk+dt@...nel.org,
conor+dt@...nel.org, sumit.semwal@...aro.org, christian.koenig@....com,
alim.akhtar@...sung.com, manjun@...sung.com, nagaraju.s@...sung.com,
ih0206.lee@...sung.com, jehyung.lee@...sung.com
Cc: linux-arm-kernel@...ts.infradead.org, linux-media@...r.kernel.org,
devicetree@...r.kernel.org, linux-samsung-soc@...r.kernel.org,
linux-kernel@...r.kernel.org, dri-devel@...ts.freedesktop.org,
linaro-mm-sig@...ts.linaro.org, Himanshu Dewangan <h.dewangan@...sung.com>
Subject: [PATCH 25/29] media: mfc: Add encoder v4l2 driver interface
From: Nagaraju Siddineni <nagaraju.s@...sung.com>
- Add encoder V4L2 ioctls, format handling, control operations,
buffer management, and driver initialization.
Signed-off-by: Nagaraju Siddineni <nagaraju.s@...sung.com>
Signed-off-by: Himanshu Dewangan <h.dewangan@...sung.com>
---
.../platform/samsung/exynos-mfc/Makefile | 2 +-
.../samsung/exynos-mfc/mfc_enc_v4l2.c | 4179 +++++++++++++++++
.../samsung/exynos-mfc/mfc_enc_v4l2.h | 20 +
3 files changed, 4200 insertions(+), 1 deletion(-)
create mode 100644 drivers/media/platform/samsung/exynos-mfc/mfc_enc_v4l2.c
create mode 100644 drivers/media/platform/samsung/exynos-mfc/mfc_enc_v4l2.h
diff --git a/drivers/media/platform/samsung/exynos-mfc/Makefile b/drivers/media/platform/samsung/exynos-mfc/Makefile
index dad94a7c468c..96d70f9b790d 100644
--- a/drivers/media/platform/samsung/exynos-mfc/Makefile
+++ b/drivers/media/platform/samsung/exynos-mfc/Makefile
@@ -3,7 +3,7 @@ obj-$(CONFIG_VIDEO_EXYNOS_MFC) := exynos_mfc.o
ccflags-y += -I$(srctree)/$(src)
#Dev interface layer
-exynos_mfc-y += mfc.o mfc_dec_v4l2.o mfc_dec_vb2.o mfc_enc_vb2.o
+exynos_mfc-y += mfc.o mfc_dec_v4l2.o mfc_dec_vb2.o mfc_enc_v4l2.o mfc_enc_vb2.o
#Dev control layer
exynos_mfc-y += mfc_rm.o mfc_ctx_ctrl.o mfc_debugfs.o
#Core interface layer
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_enc_v4l2.c b/drivers/media/platform/samsung/exynos-mfc/mfc_enc_v4l2.c
new file mode 100644
index 000000000000..84edebac82b2
--- /dev/null
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_enc_v4l2.c
@@ -0,0 +1,4179 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * mfc_enc_v4l2.c file
+ *
+ * Nagaraju Siddineni, <nagaraju.s@...sung.com>
+ * Himanshu Dewangan, <h.dewangan@...sung.com>
+ */
+
+#include "mfc_enc_v4l2.h"
+#include "mfc_enc_vb2.h"
+#include "mfc_rm.h"
+
+#include "base/mfc_queue.h"
+#include "base/mfc_utils.h"
+#include "base/mfc_buf.h"
+#include "base/mfc_mem.h"
+static struct v4l2_queryctrl enc_controls[] = {
+ {
+ .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "The period of intra frame",
+ .minimum = 0,
+ .maximum = BIT(30) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "The slice partitioning method",
+ .minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+ .maximum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_FIXED_BYTES,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "The number of MB in a slice",
+ .minimum = 1,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "The maximum bits per slices",
+ .minimum = 350,
+ .maximum = INT_MAX / 8,
+ .step = 1,
+ .default_value = 350,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB_ROW,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "The number of MB row in a slice",
+ .minimum = 1,
+ .maximum = INT_MAX / SZ_256,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "The number of intra refresh MBs",
+ .minimum = 0,
+ .maximum = BIT(18) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Padding control enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Padding Color YUV Value",
+ .minimum = 0,
+ .maximum = BIT(24) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Frame level rate control enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_BITRATE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Target bit rate rate-control",
+ .minimum = 1,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Rate control reaction coeff.",
+ .minimum = 1,
+ .maximum = BIT(16) - 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_STREAM_SIZE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Encoded stream size",
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ .flags = V4L2_CTRL_FLAG_READ_ONLY,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_COUNT,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Encoded frame count",
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ .flags = V4L2_CTRL_FLAG_READ_ONLY,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TYPE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Encoded frame type",
+ .minimum = 0,
+ .maximum = 5,
+ .step = 1,
+ .default_value = 0,
+ .flags = V4L2_CTRL_FLAG_READ_ONLY,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Force frame type",
+ .minimum = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED,
+ .maximum = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED,
+ .step = 1,
+ .default_value = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VBV_SIZE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VBV buffer size (1Kbits)",
+ .minimum = 0,
+ .maximum = BIT(16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEADER_MODE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Sequence header mode",
+ .minimum = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
+ .maximum = V4L2_MPEG_VIDEO_HEADER_MODE_AT_THE_READY,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Frame skip enable",
+ .minimum = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED,
+ .maximum = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT,
+ .step = 1,
+ .default_value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Fixed target bit enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_B_FRAMES,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "The number of B frames",
+ .minimum = 0,
+ .maximum = 2,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 profile",
+ .minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+ .maximum = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 level",
+ .minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+ .maximum = V4L2_MPEG_VIDEO_H264_LEVEL_6_0,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "H264 interlace mode",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 loop filter mode",
+ .minimum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,
+ .maximum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_S_B,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 loop filter alpha offset",
+ .minimum = -12,
+ .maximum = 12,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 loop filter beta offset",
+ .minimum = -12,
+ .maximum = 12,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 entorpy mode",
+ .minimum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
+ .maximum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "The number of ref. picture of P",
+ .minimum = 1,
+ .maximum = 2,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "H264 8x8 transform enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "MB level rate control",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 Frame rate",
+ .minimum = 1,
+ .maximum = FRAME_RATE_RESOLUTION,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 Frame QP value",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "H264 dark region adaptive",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "H264 smooth region adaptive",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "H264 static region adaptive",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "H264 MB activity adaptive",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 P frame QP value",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 B frame QP value",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Aspect ratio VUI enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VUI aspect ratio IDC",
+ .minimum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED,
+ .maximum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Horizontal size of SAR",
+ .minimum = 0,
+ .maximum = BIT(16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Vertical size of SAR",
+ .minimum = 0,
+ .maximum = BIT(16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "GOP closure",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 I period",
+ .minimum = 0,
+ .maximum = BIT(16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Hierarchical Coding",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Type",
+ .minimum = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B,
+ .maximum = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer",
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer QP",
+ .minimum = 0,
+ .maximum = ((6 << 16) | 0xFFFF), /* (index << 16) | value */
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "frame pack sei generation flag",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Current frame is frame 0 flag",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Frame packing arrangement type",
+ .minimum = V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_SIDE_BY_SIDE,
+ .maximum = V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TEMPORAL,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_SIDE_BY_SIDE,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_FMO,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Flexible Macroblock Order",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Map type for FMO",
+ .minimum = V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES,
+ .maximum = V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Number of slice groups for FMO",
+ .minimum = 1,
+ .maximum = 4,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "FMO Run Length",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Direction of the slice group",
+ .minimum = V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT,
+ .maximum = V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_LEFT,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Size of the first slice group",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_ASO,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Arbitrary Slice Order",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "ASO Slice order",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Prepend SPS/PPS to every IDR",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 profile",
+ .minimum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
+ .maximum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 level",
+ .minimum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
+ .maximum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_6,
+ .step = 1,
+ .default_value = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 Frame QP value",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Quarter pixel search enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 P frame QP value",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 B frame QP value",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 vop time resolution",
+ .minimum = 0,
+ .maximum = BIT(16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 frame delta",
+ .minimum = 1,
+ .maximum = BIT(16) - 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H263 Frame rate",
+ .minimum = 1,
+ .maximum = BIT(8) - 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H263 Frame QP value",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H263 P frame QP value",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Frame Tag",
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Frame Status",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_QOS_RATIO,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "QoS ratio value",
+ .minimum = 20,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 100,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_VERSION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 version",
+ .minimum = 0,
+ .maximum = 3,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP8_I_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 Frame QP value",
+ .minimum = 0,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP8_P_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 Frame QP value",
+ .minimum = 0,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_RC_FRAME_RATE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 Frame rate",
+ .minimum = 1,
+ .maximum = BIT(16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_NUM_OF_PARTITIONS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 number of partitions",
+ .minimum = 0,
+ .maximum = 8,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_FILTER_LEVEL,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 loop filter level",
+ .minimum = 0,
+ .maximum = 63,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_FILTER_SHARPNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 loop filter sharpness",
+ .minimum = 0,
+ .maximum = 7,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_GOLDEN_FRAMESEL,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 indication of golden frame",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_GF_REFRESH_PERIOD,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 indication of golden frame",
+ .minimum = 0,
+ .maximum = BIT(16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "VP8 hierarchy QP enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER0,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 layer0 QP value",
+ .minimum = 0,
+ .maximum = ((2 << 16) | 0xFFFF), /* (index << 16) | value */
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER1,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 layer1 QP value",
+ .minimum = 0,
+ .maximum = ((2 << 16) | 0xFFFF), /* (index << 16) | value */
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_HIERARCHY_QP_LAYER2,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 layer2 QP value",
+ .minimum = 0,
+ .maximum = ((2 << 16) | 0xFFFF), /* (index << 16) | value */
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_REF_NUMBER_FOR_PFRAMES,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 Number of reference picture",
+ .minimum = 1,
+ .maximum = 2,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_DISABLE_INTRA_MD4X4,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "VP8 intra 4x4 mode disable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC70_VIDEO_VP8_NUM_TEMPORAL_LAYER,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "VP8 number of hierarchical layer",
+ .minimum = 0,
+ .maximum = 3,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_VERSION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP9 version",
+ .minimum = 0,
+ .maximum = 3,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP9 profile",
+ .minimum = 0,
+ .maximum = 3,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_LEVEL,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP9 level",
+ .minimum = 10,
+ .maximum = 62,
+ .step = 1,
+ .default_value = 10,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_I_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP9 Frame QP value",
+ .minimum = 1,
+ .maximum = U8_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_P_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP9 Frame QP value",
+ .minimum = 1,
+ .maximum = U8_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_RC_FRAME_RATE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP9 Frame rate",
+ .minimum = 1,
+ .maximum = BIT(16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_GOLDEN_FRAMESEL,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP9 indication of golden frame",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_GF_REFRESH_PERIOD,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP9 indication of golden frame",
+ .minimum = 0,
+ .maximum = (BIT(16) - 1),
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHY_QP_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "VP9 hierarchy QP enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP9 layer0 QP value",
+ .minimum = 0,
+ .maximum = ((2 << 16) | 0xFFFF), /* (index << 16) | value */
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_REF_NUMBER_FOR_PFRAMES,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP9 Number of reference picture",
+ .minimum = 1,
+ .maximum = 2,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "VP9 number of hierarchical layer",
+ .minimum = 0,
+ .maximum = 3,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_MAX_PARTITION_DEPTH,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "VP9 Maximum coding unit depth",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_DISABLE_INTRA_PU_SPLIT,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "VP9 disable intra pu split",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT0,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Bit0",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT1,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Bit1",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_BIT2,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Bit2",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Change",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_DISABLE_IVF_HEADER,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "IVF header generation",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC Frame QP value",
+ .minimum = -12,
+ .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 = -12,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC B frame QP value",
+ .minimum = -12,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_DARK,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC dark region adaptive",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_SMOOTH,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC smooth region adaptive",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_STATIC,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC static region adaptive",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_ADAPTIVE_RC_ACTIVITY,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC activity adaptive",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC Profile",
+ .minimum = 0,
+ .maximum = 4,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC level",
+ .minimum = 10,
+ .maximum = 62,
+ .step = 1,
+ .default_value = 10,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_TIER_FLAG,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC tier_flag default is Main",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_RC_FRAME_RATE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC Frame rate",
+ .minimum = 1,
+ .maximum = BIT(16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_MAX_PARTITION_DEPTH,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC Maximum coding unit depth",
+ .minimum = 0,
+ .maximum = 2,
+ .step = 1,
+ .default_value = 2,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REF_NUMBER_FOR_PFRAMES,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC Number of reference picture",
+ .minimum = 1,
+ .maximum = 2,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REFRESH_TYPE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC Number of reference picture",
+ .minimum = 0,
+ .maximum = 2,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_CONST_INTRA_PRED_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC refresh type",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LOSSLESS_CU_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC lossless encoding select",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_WAVEFRONT_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC Wavefront enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_DISABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC Filter disable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_SLICE_BOUNDARY,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "across or not slice boundary",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LTR_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "long term reference enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_QP_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "QP values for temporal layer",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_TYPE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Hierarchical Coding Type",
+ .minimum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B,
+ .maximum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer",
+ .minimum = 0,
+ .maximum = 7,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer QP",
+ .minimum = 0,
+ .maximum = ((6 << 16) | 0xFFFF), /* (index << 16) | value */
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT0,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer BIT0",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT1,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer BIT1",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT2,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer BIT2",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT3,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer BIT3",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT4,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer BIT4",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT5,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer BIT5",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_BIT6,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer BIT6",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Change",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIGN_DATA_HIDING,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC Sign data hiding",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_GENERAL_PB_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC General pb enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_TEMPORAL_ID_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC Temporal id enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_STRONG_SMOTHING_FLAG,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC Strong intra smoothing flag",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_DISABLE_INTRA_PU_SPLIT,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC disable intra pu split",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_DISABLE_TMV_PREDICTION,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "HEVC disable tmv prediction",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "max number of candidate MVs",
+ .minimum = 0,
+ .maximum = 4,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_WITHOUT_STARTCODE_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "ENC without startcode enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_REFRESH_PERIOD,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC Number of reference picture",
+ .minimum = 0,
+ .maximum = BIT(16) - 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_BETA_OFFSET_DIV2,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC loop filter beta offset",
+ .minimum = -6,
+ .maximum = 6,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_LF_TC_OFFSET_DIV2,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC loop filter tc offset",
+ .minimum = -6,
+ .maximum = 6,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC size of length field",
+ .minimum = 0,
+ .maximum = 3,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_USER_REF,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "user long term reference frame",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC90_VIDEO_HEVC_STORE_REF,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "store long term reference frame",
+ .minimum = 0,
+ .maximum = 2,
+ .step = 1,
+ .default_value = 0, /* need to check default value */
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_GET_VERSION_INFO,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Get MFC version information",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_GET_EXTRA_BUFFER_SIZE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Get extra buffer size",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_GET_EXT_INFO,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Get extra information",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT0,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Bit0",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT1,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Bit1",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT2,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Bit2",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT3,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Bit3",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT4,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Bit4",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT5,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Bit5",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT6,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Bit6",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Change",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT0,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Bit0",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT1,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Bit1",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_BIT2,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Bit2",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding Layer Change",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_H264_ENABLE_LTR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Enable LTR",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_H264_NUM_OF_LTR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Number of LTR",
+ .minimum = 0,
+ .maximum = 4,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_H264_MARK_LTR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Set the frame as a LTRP",
+ .minimum = 0,
+ .maximum = 4,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_H264_USE_LTR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Specify a LTRP for encoding",
+ .minimum = 0,
+ .maximum = 0xF,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Base Layer Priority",
+ .minimum = 0,
+ .maximum = 63,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_CONFIG_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "QP control per each frame",
+ .minimum = -12,
+ .maximum = U8_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_H264_VUI_RESTRICTION_ENABLE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 vui generation enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_PREPEND_SPSPPS_TO_IDR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Prepend SPS/PPS to every IDR",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_CONFIG_QP_ENABLE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "set dynamic qp controls",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_ROI_CONTROL,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Region-Of-Interest control",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_ROI_ENABLE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Region-Of-Interest enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 Min QP value for I frame",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 Max QP value for I frame",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC Min QP value for I frame",
+ .minimum = -12,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC Max QP value for I frame",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 Min QP value for I frame",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 Max QP value for I frame",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H263 Min QP value for I frame",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H263 Max QP value for I frame",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 Min QP value for I frame",
+ .minimum = 0,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 Max QP value for I frame",
+ .minimum = 0,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_MIN_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP9 Min QP value for I frame",
+ .minimum = 1,
+ .maximum = U8_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_MAX_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP9 Max QP value for I frame",
+ .minimum = 1,
+ .maximum = U8_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 Min QP value for P frame",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 Max QP value for P frame",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_P,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC Min QP value for P frame",
+ .minimum = -12,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_P,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC Max QP value for P frame",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_P,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 Min QP value for P frame",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_P,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 Max QP value for P frame",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP_P,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H263 Min QP value for P frame",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP_P,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H263 Max QP value for P frame",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP8_MIN_QP_P,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 Min QP value for P frame",
+ .minimum = 0,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP8_MAX_QP_P,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP8 Max QP value for P frame",
+ .minimum = 0,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_MIN_QP_P,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP9 Min QP value for P frame",
+ .minimum = 1,
+ .maximum = U8_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_VP9_MAX_QP_P,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "VP9 Max QP value for P frame",
+ .minimum = 1,
+ .maximum = U8_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 Min QP value for B frame",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "H264 Max QP value for B frame",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP_B,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC Min QP value for B frame",
+ .minimum = -12,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP_B,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "HEVC Max QP value for B frame",
+ .minimum = 0,
+ .maximum = 51,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP_B,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 Min QP value for B frame",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP_B,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MPEG4 Max QP value for B frame",
+ .minimum = 1,
+ .maximum = 31,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_RC_PVC_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Perceptual Video Coding enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_SHORTTERM_MAX_LAYER,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hierarchical Coding max layer",
+ .minimum = 0,
+ .maximum = 3,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_WEIGHTED_ENABLE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Weighted Prediction enable",
+ .minimum = 0,
+ .maximum = 3,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_YSUM,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "YSUM for weighted Prediction",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "ratio of intra encoded size",
+ .minimum = 15,
+ .maximum = 50,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Color range",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Colour primaries",
+ .minimum = 0,
+ .maximum = 22,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Transfer characteristics",
+ .minimum = 0,
+ .maximum = 18,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Matrix coefficients",
+ .minimum = 0,
+ .maximum = 10,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HIERARCHICAL_BITRATE_CTRL,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Hierarchical bitrate control",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_STATIC_INFO_ENABLE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Static info enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_SEI_MAX_PIC_AVERAGE_LIGHT,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Max pic average light",
+ .minimum = 0,
+ .maximum = 0xFFFF,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_SEI_MAX_CONTENT_LIGHT,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Max content light",
+ .minimum = 0,
+ .maximum = 0xFFFF,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_SEI_MAX_DISPLAY_LUMINANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Max display luminance",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_SEI_MIN_DISPLAY_LUMINANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Min display luminance",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_SEI_WHITE_POINT,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "White point",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_0,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Display primaries 0",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_1,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Display primaries 1",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_2,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Display primaries 2",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_HDR_USER_SHARED_HANDLE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Dynamic HDR10+ SEI metadata",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_DROP_CONTROL,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Drop control",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_CHROMA_QP_OFFSET_CB,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Chroma QP index for Cb",
+ .minimum = -12,
+ .maximum = 12,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_CHROMA_QP_OFFSET_CR,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Chroma QP index for Cr",
+ .minimum = -12,
+ .maximum = 12,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_SRC_BUF_FLAG,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Buffer flag",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_DST_BUF_FLAG,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Buffer flag",
+ .minimum = INT_MIN,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_GDC_VOTF,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "GDC vOTF",
+ .minimum = 0,
+ .maximum = 2,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_SKIP_LAZY_UNMAP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "skip lazy unmap",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Frames per second in 1000x scale",
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 60000,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_GOP_CTRL,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Meaning of GOP_SIZE",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_AVERAGE_QP,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Frames average QP",
+ .minimum = 0,
+ .maximum = U8_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MV_SEARCH_MODE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MV search mode",
+ .minimum = 0,
+ .maximum = 2,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MV_HOR_POSITION_L0,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MV HOR position L0",
+ .minimum = -128,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MV_HOR_POSITION_L1,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MV HOR position L1",
+ .minimum = -128,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MV_VER_POSITION_L0,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MV VER position L0",
+ .minimum = -128,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MV_VER_POSITION_L1,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MV VER position L1",
+ .minimum = -128,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_PRIORITY,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "priority",
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MIN_QUALITY,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "MIN quality mode enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MAX_IFRAME_SIZE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "max I frame size",
+ .minimum = 0,
+ .maximum = BIT(16) - 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_WP_TWO_PASS_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "WP two pass encoding enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_TIMING_INFO_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Timing info enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_ADAPTIVE_GOP_ENABLE,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Adaptive GOP enable",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_SUM_SKIP_MB,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "The number of skip MB",
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_SUM_INTRA_MB,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "The number of intra MB",
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_SUM_ZERO_MV_MB,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "The number of zero MV MB",
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MV_HOR_RANGE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MV HOR Range",
+ .minimum = 16,
+ .maximum = 128,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDEO_MV_VER_RANGE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "MV VER Range",
+ .minimum = 16,
+ .maximum = 128,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_MULTI_VIEW_ENABLE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Multi-View Enable",
+ .minimum = 0,
+ .maximum = 2,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_MFC_MULTI_VIEW_MAIN_TYPE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Main-View Type",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+};
+
+#define ENC_NUM_CTRLS ARRAY_SIZE(enc_controls)
+/* Find selected format description */
+static struct mfc_fmt *__mfc_enc_find_format(struct mfc_ctx *ctx,
+ unsigned int pixelformat)
+{
+ struct mfc_dev *dev = ctx->dev;
+ struct mfc_fmt *fmt = NULL;
+ unsigned long i;
+
+ for (i = 0; i < MFC_NUM_FORMATS; i++) {
+ if ((mfc_formats[i].type & MFC_FMT_STREAM) &&
+ !(mfc_formats[i].type & MFC_FMT_ENC)) {
+ continue;
+ }
+ if (mfc_formats[i].fourcc == pixelformat) {
+ fmt = (struct mfc_fmt *)&mfc_formats[i];
+ break;
+ }
+ }
+
+ if (fmt && !dev->pdata->support_10bit && (fmt->type & MFC_FMT_10BIT)) {
+ mfc_ctx_err("[FRAME] 10bit is not supported\n");
+ fmt = NULL;
+ }
+ if (fmt && !dev->pdata->support_422 && (fmt->type & MFC_FMT_422)) {
+ mfc_ctx_err("[FRAME] 422 is not supported\n");
+ fmt = NULL;
+ }
+ if (fmt && !dev->pdata->support_rgb && (fmt->type & MFC_FMT_RGB)) {
+ mfc_ctx_err("[FRAME] RGB is not supported\n");
+ fmt = NULL;
+ }
+
+ if (fmt && (fmt->type & MFC_FMT_STREAM) &&
+ dev->pdata->mfc_resource[fmt->codec_mode].op_core_type == MFC_OP_CORE_NOT_FIXED) {
+ mfc_ctx_err("[STREAM] %s is not supported\n", fmt->name);
+ fmt = NULL;
+ }
+
+ return fmt;
+}
+
+static struct v4l2_queryctrl *__mfc_enc_get_ctrl(int id)
+{
+ unsigned long i;
+
+ for (i = 0; i < ENC_NUM_CTRLS; ++i)
+ if (id == enc_controls[i].id)
+ return &enc_controls[i];
+ return NULL;
+}
+
+static int __mfc_enc_check_ctrl_val(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
+{
+ struct v4l2_queryctrl *c;
+ struct mfc_enc *enc = ctx->enc_priv;
+ struct mfc_enc_params *p = &enc->params;
+
+ c = __mfc_enc_get_ctrl(ctrl->id);
+ if (!c) {
+ mfc_ctx_err("[CTRLS] not supported control id (%#x)\n", ctrl->id);
+ return -EINVAL;
+ }
+
+ if (ctrl->id == V4L2_CID_MPEG_VIDEO_GOP_SIZE && ctrl->value > c->maximum) {
+ mfc_ctx_info("GOP_SIZE is changed to max(%d -> %d)\n",
+ ctrl->value, c->maximum);
+ ctrl->value = c->maximum;
+ }
+
+ if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER ||
+ ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER) {
+ if ((ctrl->value & ~BIT(16)) < c->minimum ||
+ (ctrl->value & ~BIT(16)) > c->maximum ||
+ (c->step != 0 && (ctrl->value & ~BIT(16)) % c->step != 0)) {
+ mfc_ctx_err("[CTRLS][%s] Invalid control id: %#x, value: %d (%#x)\n",
+ c->name, ctrl->id, ctrl->value, ctrl->value);
+ return -ERANGE;
+ } else {
+ return 0;
+ }
+ }
+
+ if (ctrl->id == V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY) {
+ if (ctrl->value < c->minimum ||
+ (ctrl->value + p->num_hier_max_layer - 1) > c->maximum ||
+ (c->step != 0 && (ctrl->value & ~BIT(16)) % c->step != 0)) {
+ mfc_ctx_err("[CTRLS][%s] Invalid control id: %#x, value: %d (%#x)\n",
+ c->name, ctrl->id, ctrl->value, ctrl->value);
+ return -ERANGE;
+ } else {
+ return 0;
+ }
+ }
+
+ if (ctrl->value < c->minimum || ctrl->value > c->maximum ||
+ (c->step != 0 && ctrl->value % c->step != 0)) {
+ mfc_ctx_err("[CTRLS][%s] id: %#x, invalid value (%d)\n",
+ c->name, ctrl->id, ctrl->value);
+ return -ERANGE;
+ }
+
+ mfc_ctx_debug(5, "[CTRLS][%s] id: %#x, value: %d (%#x)\n",
+ c->name, ctrl->id, ctrl->value, ctrl->value);
+
+ return 0;
+}
+
+static inline int __mfc_enc_h264_profile(struct mfc_ctx *ctx, int profile)
+{
+ int ret = 0;
+
+ switch (profile) {
+ case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+ ret = MFC_REG_E_PROFILE_H264_MAIN;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+ ret = MFC_REG_E_PROFILE_H264_HIGH;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+ ret = MFC_REG_E_PROFILE_H264_BASELINE;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
+ ret = MFC_REG_E_PROFILE_H264_CONSTRAINED_BASELINE;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
+ ret = MFC_REG_E_PROFILE_H264_CONSTRAINED_HIGH;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/* Query capabilities of the device */
+static int mfc_enc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ strscpy(cap->driver, "MFC", sizeof(cap->driver));
+ strscpy(cap->card, "encoder", sizeof(cap->card));
+
+ return 0;
+}
+
+static int __mfc_enc_enum_fmt(struct mfc_dev *dev, struct v4l2_fmtdesc *f,
+ unsigned int type)
+{
+ struct mfc_fmt *fmt;
+ unsigned long i, j = 0;
+
+ for (i = 0; i < MFC_NUM_FORMATS; ++i) {
+ if (!(mfc_formats[i].type & type))
+ continue;
+ if (!dev->pdata->support_10bit && (mfc_formats[i].type & MFC_FMT_10BIT))
+ continue;
+ if (!dev->pdata->support_422 && (mfc_formats[i].type & MFC_FMT_422))
+ continue;
+ if (!dev->pdata->support_rgb && (mfc_formats[i].type & MFC_FMT_RGB))
+ continue;
+
+ if (j == f->index) {
+ fmt = &mfc_formats[i];
+ strscpy(f->description, fmt->name,
+ sizeof(f->description));
+ f->pixelformat = fmt->fourcc;
+
+ return 0;
+ }
+
+ ++j;
+ }
+
+ return -EINVAL;
+}
+
+static int mfc_enc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv,
+ struct v4l2_fmtdesc *f)
+{
+ struct mfc_dev *dev = video_drvdata(file);
+
+ return __mfc_enc_enum_fmt(dev, f, MFC_FMT_STREAM);
+}
+
+static int mfc_enc_enum_fmt_vid_out_mplane(struct file *file, void *prov,
+ struct v4l2_fmtdesc *f)
+{
+ struct mfc_dev *dev = video_drvdata(file);
+
+ return __mfc_enc_enum_fmt(dev, f, MFC_FMT_FRAME);
+}
+
+static int mfc_enc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
+{
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+ struct mfc_enc *enc = ctx->enc_priv;
+ struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+ struct mfc_raw_info *raw;
+ int i;
+
+ mfc_ctx_debug_enter();
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ mfc_ctx_debug(4, "enc dst g_fmt\n");
+ /* This is run on output (encoder dest) */
+ pix_fmt_mp->width = 0;
+ pix_fmt_mp->height = 0;
+ pix_fmt_mp->field = V4L2_FIELD_NONE;
+ pix_fmt_mp->pixelformat = ctx->dst_fmt->fourcc;
+ pix_fmt_mp->num_planes = ctx->dst_fmt->mem_planes;
+
+ pix_fmt_mp->plane_fmt[0].bytesperline = enc->dst_buf_size;
+ pix_fmt_mp->plane_fmt[0].sizeimage = enc->dst_buf_size;
+ } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ mfc_ctx_debug(4, "enc src g_fmt\n");
+ /* This is run on capture (encoder src) */
+ raw = &ctx->raw_buf;
+
+ pix_fmt_mp->width = ctx->img_width;
+ pix_fmt_mp->height = ctx->img_height;
+ pix_fmt_mp->field = V4L2_FIELD_NONE;
+ pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
+ pix_fmt_mp->num_planes = ctx->src_fmt->mem_planes;
+ for (i = 0; i < ctx->src_fmt->mem_planes; i++) {
+ pix_fmt_mp->plane_fmt[i].bytesperline = raw->stride[i];
+ pix_fmt_mp->plane_fmt[i].sizeimage = raw->plane_size[i];
+ }
+ } else {
+ mfc_ctx_err("invalid buf type (%d)\n", f->type);
+ return -EINVAL;
+ }
+
+ mfc_ctx_debug_leave();
+
+ return 0;
+}
+
+static int mfc_enc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
+{
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+ struct mfc_fmt *fmt;
+ struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+
+ fmt = __mfc_enc_find_format(ctx, pix_fmt_mp->pixelformat);
+ if (!fmt) {
+ mfc_ctx_err("Unsupported format for %s\n",
+ V4L2_TYPE_IS_OUTPUT(f->type) ? "source" : "destination");
+ return -EINVAL;
+ }
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
+ fmt->codec_mode == MFC_FORMATS_NO_CODEC) {
+ mfc_ctx_err("MFC_FORMATS_NO_CODEC is invalid to dst(fmt is %s)\n",
+ fmt->name);
+ return -EINVAL;
+ }
+
+ /* For resource reservation */
+ if ((!ctx->img_width && !ctx->img_height) &&
+ pix_fmt_mp->width > 0 && pix_fmt_mp->height > 0) {
+ ctx->img_width = pix_fmt_mp->width;
+ ctx->img_height = pix_fmt_mp->height;
+ }
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ ctx->dst_fmt = fmt;
+ ctx->codec_mode = ctx->dst_fmt->codec_mode;
+ ctx->op_core_type = ctx->dev->pdata->mfc_resource[ctx->codec_mode].op_core_type;
+ }
+
+ mfc_ctx_debug(2, "[%s] resolution %dx%d, %s : %s\n",
+ V4L2_TYPE_IS_OUTPUT(f->type) ? "FRAME" : "STREAM",
+ ctx->img_width, ctx->img_height,
+ V4L2_TYPE_IS_OUTPUT(f->type) ? "pixelformat" : "codectype", fmt->name);
+
+ return 0;
+}
+
+static void __mfc_enc_check_format(struct mfc_ctx *ctx)
+{
+ ctx->is_422 = 0;
+ ctx->rgb_bpp = 0;
+
+ switch (ctx->src_fmt->fourcc) {
+ case V4L2_PIX_FMT_NV16M:
+ case V4L2_PIX_FMT_NV61M:
+ mfc_ctx_debug(2, "[FRAME] is 422 format\n");
+ ctx->is_422 = 1;
+ break;
+ case V4L2_PIX_FMT_RGB24:
+ ctx->rgb_bpp = 24;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ ctx->rgb_bpp = 16;
+ break;
+ case V4L2_PIX_FMT_RGB32X:
+ case V4L2_PIX_FMT_BGR32:
+ case V4L2_PIX_FMT_ARGB32:
+ case V4L2_PIX_FMT_RGB32:
+ ctx->rgb_bpp = 32;
+ break;
+ default:
+ break;
+ }
+ mfc_ctx_debug(2, "[FRAME] 422: %d, rgb: %d\n",
+ ctx->is_422, ctx->rgb_bpp);
+}
+
+static int __mfc_enc_check_resolution(struct mfc_ctx *ctx)
+{
+ int max_width = 0, max_height = 0, min_width = 0, min_height = 0, swap_check = 0;
+
+ /* Check max resolution */
+ switch (ctx->codec_mode) {
+ case MFC_REG_CODEC_H264_ENC:
+ max_width = 8192;
+ max_height = 8192;
+ break;
+ default:
+ mfc_ctx_err("Not supported codec(%d)\n", ctx->codec_mode);
+ return -EINVAL;
+ }
+
+ if (swap_check) {
+ if (!((ctx->crop_width < max_width && ctx->crop_height < max_height) ||
+ (ctx->crop_width < max_height && ctx->crop_height < max_width))) {
+ mfc_ctx_err("Resolution is too big(%dx%d > %dxi%d or %dx%d\n",
+ ctx->crop_width, ctx->crop_height, max_width, max_height,
+ max_height, max_width);
+ return -EINVAL;
+ }
+ } else {
+ if (ctx->crop_width > max_width || ctx->crop_height > max_height) {
+ mfc_ctx_err("Resolution is too big(%dx%d > %dx%d)\n",
+ ctx->crop_width, ctx->crop_height, max_width, max_height);
+ return -EINVAL;
+ }
+ }
+
+ /* Check min resolution */
+ switch (ctx->codec_mode) {
+ case MFC_REG_CODEC_H264_ENC:
+ min_width = 32;
+ min_height = 32;
+ break;
+ default:
+ mfc_ctx_err("Not supported codec(%d)\n", ctx->codec_mode);
+ return -EINVAL;
+ }
+
+ if (ctx->crop_width < min_width || ctx->crop_height < min_height) {
+ mfc_ctx_err("Resolution is too small(%dx%d < %dx%d)\n",
+ ctx->crop_width, ctx->crop_height, min_width, min_height);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mfc_enc_s_fmt_vid_cap_mplane(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct mfc_dev *dev = video_drvdata(file);
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+ struct mfc_enc *enc = ctx->enc_priv;
+ struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+ struct mfc_fmt *fmt = NULL;
+ int ret = 0;
+
+ mfc_ctx_debug_enter();
+
+ if (ctx->vq_dst.streaming) {
+ mfc_ctx_err("dst queue busy\n");
+ return -EBUSY;
+ }
+
+ fmt = __mfc_enc_find_format(ctx, pix_fmt_mp->pixelformat);
+ if (!fmt) {
+ mfc_ctx_err("Unsupported format for destination\n");
+ return -EINVAL;
+ }
+ ctx->dst_fmt = fmt;
+
+ if ((!ctx->img_width && !ctx->img_height) &&
+ pix_fmt_mp->width > 0 && pix_fmt_mp->height > 0) {
+ ctx->img_width = pix_fmt_mp->width;
+ ctx->img_height = pix_fmt_mp->height;
+ ctx->crop_width = ctx->img_width;
+ ctx->crop_height = ctx->img_height;
+ }
+
+ ctx->codec_mode = ctx->dst_fmt->codec_mode;
+ mfc_ctx_info("[STREAM] codectype: %s(%d), %d x %d\n",
+ ctx->dst_fmt->name, ctx->codec_mode,
+ ctx->img_width, ctx->img_height);
+
+ if (__mfc_enc_check_resolution(ctx)) {
+ mfc_ctx_err("Unsupported MFC resolution\n");
+ return -EINVAL;
+ }
+
+ if (mfc_check_resolution(ctx)) {
+ mfc_ctx_err("Unsupported product resolution\n");
+ return -EINVAL;
+ }
+
+ enc->dst_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage;
+ pix_fmt_mp->plane_fmt[0].bytesperline = 0;
+
+ ret = mfc_rm_instance_open(dev, ctx);
+ if (ret)
+ mfc_ctx_err("Failed to instance open\n");
+
+ if (dev->pdata->support_enc_mode1 &&
+ (dev->debugfs.feature_option & MFC_OPTION_SET_MULTI_CORE_FORCE)) {
+ if (dev->debugfs.feature_option & MFC_OPTION_MULTI_CORE_DISABLE) {
+ mfc_ctx_info("[2CORE] multi core mode disabled\n");
+ } else {
+ if (dev->num_inst > 1)
+ mfc_ctx_debug(2, "[2CORE] multi core bits: %#lx, num inst: %d\n",
+ dev->multi_core_inst_bits, dev->num_inst);
+ ctx->stream_op_mode = MFC_OP_TWO_MODE1;
+ mfc_ctx_info("[2CORE] This stream need to multi core stream_op_mode(%d)\n",
+ ctx->stream_op_mode);
+ }
+ }
+
+ mfc_ctx_debug_leave();
+ return ret;
+}
+
+static int __mfc_enc_set_num_fd_frame(struct mfc_ctx *ctx,
+ struct v4l2_pix_format_mplane *pix_fmt_mp)
+{
+ int calc_num_planes;
+ int num_fd_depth_map = 0;
+ int num_view = 1;
+ int num_fd_sub_view_meta = 0;
+
+ if (ctx->multi_view_enable) {
+ if (pix_fmt_mp->flags & MFC_FMT_FLAG_MULTI_VIEW) {
+ num_view = MFC_NUM_MULTI_VIEW;
+ num_fd_sub_view_meta = MFC_NUM_FD_SUB_VIEW_META;
+ }
+ if (pix_fmt_mp->flags & MFC_FMT_FLAG_DEPTH_MAP)
+ num_fd_depth_map = MFC_NUM_FD_DEPTH_MAP;
+
+ calc_num_planes =
+ (ctx->src_fmt->mem_planes + num_fd_depth_map) * num_view +
+ num_fd_sub_view_meta;
+ } else {
+ calc_num_planes = ctx->src_fmt->mem_planes;
+ }
+
+ if (calc_num_planes != pix_fmt_mp->num_planes)
+ return -EINVAL;
+
+ mfc_set_view_buf_info(ctx, ctx->src_fmt->mem_planes,
+ num_fd_depth_map, num_fd_sub_view_meta);
+
+ ctx->num_fd_frame = calc_num_planes;
+
+ return 0;
+}
+
+static int mfc_enc_s_fmt_vid_out_mplane(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+ struct mfc_dev *dev = ctx->dev;
+ struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+ struct mfc_core *core;
+ struct mfc_core_ctx *core_ctx;
+ struct mfc_fmt *prev_src_fmt = NULL;
+ struct mfc_fmt *fmt = NULL;
+ int i, shift;
+
+ mfc_ctx_debug_enter();
+
+ if (ctx->vq_src.streaming) {
+ mfc_ctx_err("src queue busy\n");
+ return -EBUSY;
+ }
+
+ /* Backup previous format */
+ prev_src_fmt = ctx->src_fmt;
+ fmt = __mfc_enc_find_format(ctx, pix_fmt_mp->pixelformat);
+ if (!fmt) {
+ mfc_ctx_err("Unsupported format for source\n");
+ return -EINVAL;
+ }
+ ctx->src_fmt = fmt;
+
+ if (__mfc_enc_set_num_fd_frame(ctx, pix_fmt_mp)) {
+ mfc_ctx_err("[FRAME] enc src plane number is different (%d != %d)\n",
+ ctx->num_fd_frame, pix_fmt_mp->num_planes);
+ return -EINVAL;
+ }
+
+ ctx->raw_buf.num_planes = ctx->src_fmt->num_planes;
+ shift = ctx->src_fmt->num_planes - 2;
+ ctx->img_width = pix_fmt_mp->width;
+ ctx->img_height = pix_fmt_mp->height;
+ for (i = 0; i < ctx->src_fmt->mem_planes; i++)
+ ctx->bytesperline[i] = pix_fmt_mp->plane_fmt[i].bytesperline;
+
+ __mfc_enc_check_format(ctx);
+
+ /* Encoder works only single core */
+ core = mfc_get_main_core_lock(dev, ctx);
+ core_ctx = core->core_ctx[ctx->num];
+
+ /* Dynamic Resolution & Format Changes */
+ if (core_ctx->state == MFCINST_FINISHED) {
+ mfc_change_state(core_ctx, MFCINST_GOT_INST);
+ if (ctx->stream_op_mode == MFC_OP_TWO_MODE1) {
+ core = mfc_get_sub_core_lock(dev, ctx);
+ if (core) {
+ core_ctx = core->core_ctx[ctx->num];
+ mfc_change_state(core_ctx, MFCINST_GOT_INST);
+ mfc_clean_core_ctx_int_flags(core_ctx);
+ }
+ }
+ if (ctx->src_fmt->fourcc != prev_src_fmt->fourcc)
+ mfc_info("[DFC] Enc Dynamic Format Changed %s -> %s\n",
+ prev_src_fmt->name, ctx->src_fmt->name);
+ else
+ mfc_info("[DRC] Enc Dynamic Resolution Changed\n");
+ }
+
+ /* When single fd format, use luma stride for chroma stride */
+ if (IS_SINGLE_FD(ctx, ctx->src_fmt))
+ for (i = 1; i < ctx->src_fmt->num_planes; i++)
+ ctx->bytesperline[i] = ctx->bytesperline[0] >> shift;
+
+ mfc_info("[FRAME] enc src pixelformat : %s\n", ctx->src_fmt->name);
+ mfc_info("[FRAME] resolution w: %d, h: %d, Y stride: %d, C stride: %d\n",
+ pix_fmt_mp->width, pix_fmt_mp->height,
+ ctx->bytesperline[0], ctx->bytesperline[1]);
+
+ /*
+ * It should be keep till buffer size and stride was calculated.
+ * And it can be changed to real encoding size, if user call the s_crop.
+ */
+ ctx->crop_width = ctx->img_width;
+ ctx->crop_height = ctx->img_height;
+ mfc_enc_calc_src_size(ctx);
+
+ ctx->output_state = QUEUE_FREE;
+
+ mfc_ctx_debug_leave();
+ return 0;
+}
+
+static int mfc_enc_g_selection(struct file *file, void *fh,
+ struct v4l2_selection *s)
+{
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+
+ mfc_ctx_debug_enter();
+
+ s->r.left = ctx->crop_left;
+ s->r.top = ctx->crop_top;
+ s->r.width = ctx->crop_width;
+ s->r.height = ctx->crop_height;
+
+ mfc_ctx_debug(2, "[FRAME] enc crop w: %d, h: %d, offset l: %d t: %d\n",
+ ctx->crop_width, ctx->crop_height, ctx->crop_left, ctx->crop_top);
+
+ mfc_ctx_debug_leave();
+
+ return 0;
+}
+
+static int mfc_enc_s_selection(struct file *file, void *priv,
+ struct v4l2_selection *s)
+{
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+
+ mfc_ctx_debug_enter();
+
+ if (!V4L2_TYPE_IS_OUTPUT(s->type)) {
+ mfc_ctx_err("not supported type (It can only in the source)\n");
+ return -EINVAL;
+ }
+
+ if (s->r.left < 0 || s->r.top < 0) {
+ mfc_ctx_err("[FRAME] crop position is negative\n");
+ return -EINVAL;
+ }
+
+ if (s->r.height > ctx->img_height || s->r.top > ctx->img_height ||
+ s->r.width > ctx->img_width || s->r.left > ctx->img_width ||
+ (s->r.left > (ctx->img_width - s->r.width)) ||
+ (s->r.top > (ctx->img_height - s->r.height))) {
+ mfc_ctx_err("[FRAME] Out of crop range: (%d,%d,%d,%d) from %dx%d\n",
+ s->r.left, s->r.top, s->r.width, s->r.height,
+ ctx->img_width, ctx->img_height);
+ return -EINVAL;
+ }
+
+ ctx->crop_top = s->r.top;
+ ctx->crop_left = s->r.left;
+ ctx->crop_height = s->r.height;
+ ctx->crop_width = s->r.width;
+
+ mfc_ctx_debug(3, "[FRAME] enc original: %dx%d, crop: %dx%d, offset l: %d t: %d\n",
+ ctx->img_width, ctx->img_height,
+ ctx->crop_width, ctx->crop_height,
+ ctx->crop_left, ctx->crop_top);
+
+ return 0;
+}
+
+static int mfc_enc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *reqbufs)
+{
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+ int ret = 0;
+
+ mfc_ctx_debug_enter();
+
+ if (reqbufs->memory == V4L2_MEMORY_MMAP) {
+ mfc_ctx_err("Not supported memory type (%d)\n", reqbufs->memory);
+ return -EINVAL;
+ }
+
+ if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ mfc_ctx_debug(4, "enc dst reqbuf(%d)\n", reqbufs->count);
+
+ if (reqbufs->count == 0) {
+ ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
+ ctx->capture_state = QUEUE_FREE;
+ return ret;
+ }
+
+ if (ctx->capture_state != QUEUE_FREE) {
+ mfc_ctx_err("invalid capture state: %d\n", ctx->capture_state);
+ return -EINVAL;
+ }
+
+ ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
+ if (ret) {
+ mfc_ctx_err("error in vb2_reqbufs() for E(D)\n");
+ return ret;
+ }
+
+ ctx->capture_state = QUEUE_BUFS_REQUESTED;
+ } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ mfc_ctx_debug(4, "enc src reqbuf(%d)\n", reqbufs->count);
+ if (reqbufs->count == 0) {
+ ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
+ ctx->output_state = QUEUE_FREE;
+ return ret;
+ }
+
+ if (ctx->output_state != QUEUE_FREE) {
+ mfc_ctx_err("invalid output state: %d\n", ctx->output_state);
+ return -EINVAL;
+ }
+
+ ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
+ if (ret) {
+ mfc_ctx_err("error in vb2_reqbufs() for E(S)\n");
+ return ret;
+ }
+
+ ctx->output_state = QUEUE_BUFS_REQUESTED;
+ } else {
+ mfc_ctx_err("invalid buf type (%d)\n", reqbufs->type);
+ return -EINVAL;
+ }
+
+ mfc_ctx_debug_leave();
+
+ return ret;
+}
+
+static int mfc_enc_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *buf)
+{
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+ struct mfc_dev *dev = ctx->dev;
+ struct mfc_core *core;
+ struct mfc_core_ctx *core_ctx;
+ int ret = 0;
+
+ mfc_ctx_debug_enter();
+
+ /* Encoder works only single core */
+ core = mfc_get_main_core_lock(dev, ctx);
+ core_ctx = core->core_ctx[ctx->num];
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ mfc_debug(4, "enc dst querybuf, state: %d\n", core_ctx->state);
+ ret = vb2_querybuf(&ctx->vq_dst, buf);
+ if (ret != 0) {
+ mfc_err("enc dst: error in vb2_querybuf()\n");
+ return ret;
+ }
+ } else if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ mfc_debug(4, "enc src querybuf, state: %d\n", core_ctx->state);
+ ret = vb2_querybuf(&ctx->vq_src, buf);
+ if (ret != 0) {
+ mfc_err("enc src: error in vb2_querybuf()\n");
+ return ret;
+ }
+ } else {
+ mfc_err("invalid buf type (%d)\n", buf->type);
+ return -EINVAL;
+ }
+
+ mfc_ctx_debug_leave();
+
+ return ret;
+}
+
+/* Queue a buffer */
+static int mfc_enc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+ struct mfc_dev *dev = ctx->dev;
+ struct mfc_core *core;
+ struct mfc_core_ctx *core_ctx;
+ int i, ret = -EINVAL;
+
+ mfc_ctx_debug_enter();
+
+ /* Encoder works only single core */
+ core = mfc_get_main_core_lock(dev, ctx);
+ core_ctx = core->core_ctx[ctx->num];
+
+ if (core_ctx->state == MFCINST_ERROR) {
+ mfc_err("Call on QBUF after unrecoverable error\n");
+ return -EIO;
+ }
+
+ if (!V4L2_TYPE_IS_MULTIPLANAR(buf->type)) {
+ mfc_err("Invalid V4L2 Buffer for driver: type(%d)\n", buf->type);
+ return -EINVAL;
+ }
+
+ if (!buf->length) {
+ mfc_err("multiplanar but length is zero\n");
+ return -EIO;
+ }
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ mfc_debug(4, "enc src buf[%d] Q\n", buf->index);
+
+ if (ctx->num_fd_frame != buf->length) {
+ mfc_err("number of memory container miss-match between Src%s planes(%d) and buffer length(%d)\n",
+ ctx->multi_view_enable ? "(Multi-View)" : "",
+ ctx->num_fd_frame, buf->length);
+ return -EINVAL;
+ }
+
+ mfc_idle_update_queued(dev, ctx);
+ mfc_rate_update_bufq_framerate(ctx, MFC_TS_SRC_Q);
+ mfc_rate_update_framerate(ctx);
+
+ for (i = 0; i < ctx->num_fd_frame; i++) {
+ if (!buf->m.planes[i].bytesused) {
+ mfc_debug(2, "[FRAME] enc src[%d] %s %d\n",
+ i,
+ "size zero, changed to buf size",
+ buf->m.planes[i].length);
+ buf->m.planes[i].bytesused = buf->m.planes[i].length;
+ } else {
+ mfc_debug(2, "[FRAME] enc src[%d] size %d\n",
+ i, buf->m.planes[i].bytesused);
+ }
+ }
+
+ ret = vb2_qbuf(&ctx->vq_src, NULL, buf);
+ } else {
+ mfc_idle_update_queued(dev, ctx);
+ mfc_rate_update_bufq_framerate(ctx, MFC_TS_DST_Q);
+ mfc_rate_update_framerate(ctx);
+
+ mfc_debug(4, "enc dst buf[%d] Q\n", buf->index);
+ ret = vb2_qbuf(&ctx->vq_dst, NULL, buf);
+ }
+
+ mfc_ctx_debug_leave();
+ return ret;
+}
+
+/* Dequeue a buffer */
+static int mfc_enc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+ struct mfc_dev *dev = ctx->dev;
+ struct mfc_core *core;
+ struct mfc_core_ctx *core_ctx;
+ int ret;
+
+ mfc_ctx_debug_enter();
+
+ /* Encoder works only single core */
+ core = mfc_get_main_core_lock(dev, ctx);
+ core_ctx = core->core_ctx[ctx->num];
+
+ if (core_ctx->state == MFCINST_ERROR) {
+ mfc_err("Call on DQBUF after unrecoverable error\n");
+ return -EIO;
+ }
+
+ if (!V4L2_TYPE_IS_MULTIPLANAR(buf->type)) {
+ mfc_err("Invalid V4L2 Buffer for driver: type(%d)\n", buf->type);
+ return -EINVAL;
+ }
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ ret = vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
+ mfc_debug(4, "enc src buf[%d] DQ\n", buf->index);
+ } else {
+ ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
+ mfc_debug(4, "enc dst buf[%d] DQ\n", buf->index);
+ }
+ mfc_ctx_debug_leave();
+ return ret;
+}
+
+/* Stream on */
+static int mfc_enc_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+ int ret = -EINVAL;
+
+ mfc_ctx_debug_enter();
+
+ if (!V4L2_TYPE_IS_MULTIPLANAR(type)) {
+ mfc_ctx_err("Invalid V4L2 Buffer for driver: type(%d)\n", type);
+ return -EINVAL;
+ }
+
+ if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ mfc_ctx_debug(4, "enc src streamon\n");
+ ret = vb2_streamon(&ctx->vq_src, type);
+ if (!ret)
+ mfc_rm_qos_control(ctx, MFC_QOS_ON);
+ } else {
+ mfc_ctx_debug(4, "enc dst streamon\n");
+ ret = vb2_streamon(&ctx->vq_dst, type);
+ }
+
+ mfc_ctx_debug(2, "src: %d, dst: %d, dpb_count = %d\n",
+ mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->src_buf_ready_queue),
+ mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->dst_buf_queue),
+ ctx->dpb_count);
+ mfc_ctx_debug_leave();
+ return ret;
+}
+
+/* Stream off, which equals to a pause */
+static int mfc_enc_streamoff(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+ int ret = -EINVAL;
+
+ mfc_ctx_debug_enter();
+
+ if (!V4L2_TYPE_IS_MULTIPLANAR(type)) {
+ mfc_ctx_err("Invalid V4L2 Buffer for driver: type(%d)\n", type);
+ return -EINVAL;
+ }
+
+ if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ mfc_ctx_debug(4, "enc src streamoff\n");
+ mfc_rate_reset_last_framerate(ctx);
+
+ ret = vb2_streamoff(&ctx->vq_src, type);
+ if (!ret)
+ mfc_rm_qos_control(ctx, MFC_QOS_OFF);
+ } else {
+ mfc_ctx_debug(4, "enc dst streamoff\n");
+ ret = vb2_streamoff(&ctx->vq_dst, type);
+ }
+
+ mfc_ctx_debug_leave();
+
+ return ret;
+}
+
+static int __mfc_enc_ext_info(struct mfc_ctx *ctx)
+{
+ struct mfc_dev *dev = ctx->dev;
+ int val = 0;
+
+ val |= ENC_SET_SPARE_SIZE;
+ val |= ENC_SET_TEMP_SVC_CH;
+
+ if (MFC_FEATURE_SUPPORT(dev, dev->pdata->skype))
+ val |= ENC_SET_SKYPE_FLAG;
+
+ val |= ENC_SET_ROI_CONTROL;
+ val |= ENC_SET_QP_BOUND_PB;
+ val |= ENC_SET_FIXED_SLICE;
+ val |= ENC_SET_PVC_MODE;
+ val |= ENC_SET_RATIO_OF_INTRA;
+ val |= ENC_SET_DROP_CONTROL;
+ val |= ENC_SET_CHROMA_QP_CONTROL;
+ val |= ENC_SET_BUF_FLAG_CTRL;
+ val |= ENC_SET_OPERATING_FPS;
+ val |= ENC_SET_GOP_CTRL;
+ val |= ENC_SET_PRIORITY;
+ val |= ENC_SET_TIMING_INFO_ENABLE;
+
+ if (MFC_FEATURE_SUPPORT(dev, dev->pdata->color_aspect_enc))
+ val |= ENC_SET_COLOR_ASPECT;
+
+ val |= ENC_SET_HP_BITRATE_CONTROL;
+
+ if (MFC_FEATURE_SUPPORT(dev, dev->pdata->static_info_enc))
+ val |= ENC_SET_STATIC_INFO;
+
+ if (dev->pdata->support_422)
+ val |= ENC_SET_VP9_PROFILE_LEVEL;
+
+ if (MFC_FEATURE_SUPPORT(dev, dev->pdata->average_qp))
+ val |= ENC_SET_AVERAGE_QP;
+
+ if (MFC_FEATURE_SUPPORT(dev, dev->pdata->mv_search_mode))
+ val |= ENC_SET_MV_SEARCH_MODE;
+
+ if (MFC_FEATURE_SUPPORT(dev, dev->pdata->max_i_frame_size))
+ val |= ENC_SET_IFRAME_SIZE;
+
+ /*
+ * This is the integrated meaning of all the function support below.
+ * V4L2_CID_MPEG_VIDEO_WP_TWO_PASS_ENABLE
+ * V4L2_CID_MPEG_VIDEO_ADAPTIVE_GOP_ENABLE
+ * V4L2_CID_MPEG_VIDEO_SUM_SKIP_MB
+ * V4L2_CID_MPEG_VIDEO_SUM_INTRA_MB
+ * V4L2_CID_MPEG_VIDEO_SUM_ZERO_MV_MB
+ * V4L2_CID_MPEG_VIDEO_MV_HOR_RANGE
+ * V4L2_CID_MPEG_VIDEO_MV_VER_RANGE
+ * V4L2_CID_MPEG_MFC_H264_SUB_GOP_ENABLE
+ * V4L2_CID_MPEG_MFC_H264_SUB_GOP_TYPE
+ * V4L2_CID_MPEG_MFC_HEVC_SUB_GOP_ENABLE
+ */
+ if (MFC_FEATURE_SUPPORT(dev, dev->pdata->enc_capability))
+ val |= ENC_SET_CAPABILITY;
+
+ mfc_ctx_debug(5, "[CTRLS] ext info val: %#x\n", val);
+
+ return val;
+}
+
+static int __mfc_enc_get_ctrl_val(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
+{
+ struct mfc_dev *dev = ctx->dev;
+ struct mfc_enc *enc = ctx->enc_priv;
+ struct mfc_ctx_ctrl *ctx_ctrl;
+ int ret = 0;
+ int found = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_MFC51_VIDEO_STREAM_SIZE:
+ ctrl->value = enc->dst_buf_size;
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TYPE:
+ ctrl->value = enc->frame_type;
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE:
+ ctrl->value = MFCSTATE_PROCESSING;
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
+ case V4L2_CID_MPEG_MFC51_VIDEO_LUMA_ADDR:
+ case V4L2_CID_MPEG_MFC51_VIDEO_CHROMA_ADDR:
+ case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_STATUS:
+ case V4L2_CID_MPEG_VIDEO_SRC_BUF_FLAG:
+ case V4L2_CID_MPEG_VIDEO_DST_BUF_FLAG:
+ case V4L2_CID_MPEG_VIDEO_AVERAGE_QP:
+ case V4L2_CID_MPEG_VIDEO_SUM_SKIP_MB:
+ case V4L2_CID_MPEG_VIDEO_SUM_INTRA_MB:
+ case V4L2_CID_MPEG_VIDEO_SUM_ZERO_MV_MB:
+ list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
+ if (!(ctx_ctrl->type & MFC_CTRL_TYPE_GET))
+ continue;
+
+ if (ctx_ctrl->id == ctrl->id) {
+ if (ctx_ctrl->get.has_new) {
+ ctx_ctrl->get.has_new = 0;
+ ctrl->value = ctx_ctrl->get.val;
+ } else {
+ mfc_ctx_debug(5, "[CTRLS] %s 0x%08x\n",
+ "Control value is not up to date:",
+ ctrl->id);
+ if (ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG)
+ ctrl->value = IGNORE_TAG;
+ else
+ return -EINVAL;
+ }
+
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ mfc_ctx_err("Invalid control: 0x%08x\n", ctrl->id);
+ return -EINVAL;
+ }
+ break;
+ case V4L2_CID_MPEG_MFC_GET_VERSION_INFO:
+ ctrl->value = dev->pdata->ip_ver;
+ break;
+ case V4L2_CID_MPEG_MFC_GET_DRIVER_INFO:
+ ctrl->value = MFC_DRIVER_INFO;
+ break;
+ case V4L2_CID_MPEG_MFC_GET_EXTRA_BUFFER_SIZE:
+ ctrl->value = MFC_LINEAR_BUF_SIZE;
+ break;
+ case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
+ ctrl->value = ctx->qos_ratio;
+ break;
+ case V4L2_CID_MPEG_MFC_GET_EXT_INFO:
+ ctrl->value = __mfc_enc_ext_info(ctx);
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE:
+ ctrl->value = mfc_rate_get_framerate(ctx);
+ break;
+ case V4L2_CID_MPEG_VIDEO_PRIORITY:
+ ctrl->value = ctx->prio;
+ mfc_ctx_debug(2, "[PRIO] user get priority: %d(%d)\n", ctrl->value, ctx->user_prio);
+ break;
+ default:
+ mfc_ctx_err("Invalid control: 0x%08x\n", ctrl->id);
+ ret = -EINVAL;
+ break;
+ }
+
+ mfc_ctx_debug(5, "[CTRLS] get id: %#x, value: %d\n", ctrl->id, ctrl->value);
+
+ return ret;
+}
+
+static inline int __mfc_enc_h264_level(enum v4l2_mpeg_video_h264_level lvl)
+{
+ static unsigned int t[V4L2_MPEG_VIDEO_H264_LEVEL_6_0 + 1] = {
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_1_0 */ 10,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_1B */ 9,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_1_1 */ 11,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_1_2 */ 12,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_1_3 */ 13,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_2_0 */ 20,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_2_1 */ 21,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_2_2 */ 22,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_3_0 */ 30,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_3_1 */ 31,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_3_2 */ 32,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_4_0 */ 40,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_4_1 */ 41,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_4_2 */ 42,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_5_0 */ 50,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_5_1 */ 51,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_5_2 */ 52,
+ /* V4L2_MPEG_VIDEO_H264_LEVEL_6_0 */ 60,
+ };
+ return t[lvl];
+}
+
+static inline int __mfc_enc_mpeg4_level(enum v4l2_mpeg_video_mpeg4_level lvl)
+{
+ static unsigned int t[V4L2_MPEG_VIDEO_MPEG4_LEVEL_6 + 1] = {
+ /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 */ 0,
+ /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B, Simple */ 9,
+ /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 */ 1,
+ /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 */ 2,
+ /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 */ 3,
+ /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B, Advanced */ 7,
+ /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 */ 4,
+ /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 */ 5,
+ /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_6, Simple */ 6,
+ };
+ return t[lvl];
+}
+
+static inline int __mfc_enc_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] = {
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED */ 0,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1 */ 1,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11 */ 2,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11 */ 3,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11 */ 4,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33 */ 5,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11 */ 6,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11 */ 7,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11 */ 8,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33 */ 9,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11 */ 10,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11 */ 11,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33 */ 12,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99 */ 13,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3 */ 14,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2 */ 15,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1 */ 16,
+ /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED */ 255,
+ };
+ return t[sar];
+}
+
+static int __mfc_enc_get_roi(struct mfc_ctx *ctx, int value)
+{
+ struct mfc_enc *enc = ctx->enc_priv;
+ int index = 0;
+
+ if (enc->sh_handle_roi.fd == -1) {
+ enc->sh_handle_roi.fd = value;
+ if (mfc_mem_get_user_shared_handle(ctx, &enc->sh_handle_roi, "ROI"))
+ return -EINVAL;
+ }
+ index = enc->roi_index;
+
+ /* Copy the ROI info from shared buf */
+ memcpy(&enc->roi_info[index], enc->sh_handle_roi.vaddr,
+ sizeof(struct mfc_enc_roi_info));
+ if (enc->roi_info[index].size > enc->roi_buf[index].size) {
+ mfc_ctx_err("[MEMINFO][ROI] roi info size %d is over\n",
+ enc->roi_info[index].size);
+ return -EINVAL;
+ }
+
+ /* Copy the ROI map buffer from user's map buf */
+ if (copy_from_user(enc->roi_buf[index].vaddr,
+ enc->roi_info[index].addr,
+ enc->roi_info[index].size))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int __mfc_enc_set_param(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
+{
+ struct mfc_enc *enc = ctx->enc_priv;
+ struct mfc_enc_params *p = &enc->params;
+ int ret = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
+ ctx->qos_ratio = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_PRIORITY:
+ mfc_ctx_debug(2, "[PRIO] user set priority: %d\n", ctrl->value);
+ ctx->user_prio = ctrl->value;
+ mfc_rm_update_real_time(ctx);
+ break;
+ case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+ p->gop_size = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
+ p->slice_mode =
+ (enum v4l2_mpeg_video_multi_slice_mode)ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
+ p->slice_mb = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
+ p->slice_bit = ctrl->value * 8;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB_ROW:
+ p->slice_mb_row = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
+ p->intra_refresh_mb = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_PADDING:
+ p->pad = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV:
+ p->pad_luma = (ctrl->value >> 16) & 0xff;
+ p->pad_cb = (ctrl->value >> 8) & 0xff;
+ p->pad_cr = (ctrl->value >> 0) & 0xff;
+ break;
+ case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
+ p->rc_frame = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ p->rc_bitrate = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF:
+ p->rc_reaction_coeff = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
+ enc->force_frame_type = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_VBV_SIZE:
+ p->vbv_buf_size = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
+ p->seq_hdr_mode =
+ (enum v4l2_mpeg_video_header_mode)(ctrl->value);
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE:
+ p->frame_skip_mode =
+ (enum v4l2_mpeg_mfc51_video_frame_skip_mode)
+ (ctrl->value);
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT:
+ p->fixed_target_bit = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+ p->num_b_frame = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+ p->codec.h264.profile =
+ __mfc_enc_h264_profile(ctx, (enum v4l2_mpeg_video_h264_profile)(ctrl->value));
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+ p->codec.h264.level =
+ __mfc_enc_h264_level((enum v4l2_mpeg_video_h264_level)(ctrl->value));
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE:
+ p->codec.h264.interlace = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
+ p->codec.h264.loop_filter_mode =
+ (enum v4l2_mpeg_video_h264_loop_filter_mode)(ctrl->value);
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
+ p->codec.h264.loop_filter_alpha = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
+ p->codec.h264.loop_filter_beta = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
+ p->codec.h264.entropy_mode =
+ (enum v4l2_mpeg_video_h264_entropy_mode)(ctrl->value);
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P:
+ p->num_refs_for_p = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
+ p->codec.h264._8x8_transform = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
+ p->rc_mb = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE:
+ p->rc_framerate = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+ p->codec.h264.rc_frame_qp = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
+ p->codec.h264.rc_min_qp = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
+ p->codec.h264.rc_max_qp = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P:
+ p->codec.h264.rc_min_qp_p = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P:
+ p->codec.h264.rc_max_qp_p = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B:
+ p->codec.h264.rc_min_qp_b = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B:
+ p->codec.h264.rc_max_qp_b = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK:
+ p->codec.h264.rc_mb_dark = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH:
+ p->codec.h264.rc_mb_smooth = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC:
+ p->codec.h264.rc_mb_static = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY:
+ p->codec.h264.rc_mb_activity = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+ p->codec.h264.rc_p_frame_qp = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
+ p->codec.h264.rc_b_frame_qp = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
+ p->codec.h264.ar_vui = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
+ p->codec.h264.ar_vui_idc =
+ __mfc_enc_vui_sar_idc((enum v4l2_mpeg_video_h264_vui_sar_idc)(ctrl->value));
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:
+ p->codec.h264.ext_sar_width = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:
+ p->codec.h264.ext_sar_height = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+ p->codec.h264.open_gop = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
+ p->codec.h264.open_gop_size = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING:
+ p->codec.h264.hier_qp_enable = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE:
+ p->codec.h264.hier_qp_type =
+ (enum v4l2_mpeg_video_h264_hierarchical_coding_type)(ctrl->value);
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:
+ p->codec.h264.num_hier_layer = ctrl->value & 0x7;
+ p->codec.h264.hier_ref_type = (ctrl->value >> 16) & 0x1;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP:
+ p->codec.h264.hier_qp_layer[(ctrl->value >> 16) & 0x7] =
+ ctrl->value & 0xFF;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT0:
+ p->codec.h264.hier_bit_layer[0] = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT1:
+ p->codec.h264.hier_bit_layer[1] = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT2:
+ p->codec.h264.hier_bit_layer[2] = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT3:
+ p->codec.h264.hier_bit_layer[3] = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT4:
+ p->codec.h264.hier_bit_layer[4] = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT5:
+ p->codec.h264.hier_bit_layer[5] = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_BIT6:
+ p->codec.h264.hier_bit_layer[6] = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING:
+ p->codec.h264.sei_gen_enable = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0:
+ p->codec.h264.sei_fp_curr_frame_0 = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
+ p->codec.h264.sei_fp_arrangement_type = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_FMO:
+ p->codec.h264.fmo_enable = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
+ switch ((enum v4l2_mpeg_video_h264_fmo_map_type)(ctrl->value)) {
+ case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES:
+ case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES:
+ case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN:
+ case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN:
+ p->codec.h264.fmo_slice_map_type = ctrl->value;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP:
+ p->codec.h264.fmo_slice_num_grp = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH:
+ p->codec.h264.fmo_run_length[(ctrl->value >> 30) & 0x3] = ctrl->value & 0x3FFFFFFF;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION:
+ p->codec.h264.fmo_sg_dir = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE:
+ p->codec.h264.fmo_sg_rate = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_ASO:
+ p->codec.h264.aso_enable = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER:
+ p->codec.h264.aso_slice_order[(ctrl->value >> 18) & 0x7] &=
+ ~(0xFF << (((ctrl->value >> 16) & 0x3) << 3));
+ p->codec.h264.aso_slice_order[(ctrl->value >> 18) & 0x7] |=
+ (ctrl->value & 0xFF) << (((ctrl->value >> 16) & 0x3) << 3);
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_PREPEND_SPSPPS_TO_IDR:
+ p->codec.h264.prepend_sps_pps_to_idr = ctrl->value ? 1 : 0;
+ break;
+ case V4L2_CID_MPEG_MFC_H264_ENABLE_LTR:
+ p->codec.h264.enable_ltr = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC_H264_NUM_OF_LTR:
+ p->codec.h264.num_of_ltr = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY:
+ p->codec.h264.base_priority = ctrl->value;
+ p->codec.h264.set_priority = 1;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ROI_ENABLE:
+ p->roi_enable = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC_H264_VUI_RESTRICTION_ENABLE:
+ p->codec.h264.vui_enable = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC_CONFIG_QP_ENABLE:
+ p->dynamic_qp = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC_CONFIG_QP:
+ p->config_qp = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_RC_PVC_ENABLE:
+ /* It is valid for H.264, HEVC, VP8, VP9 */
+ p->rc_pvc = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_TEMPORAL_SHORTTERM_MAX_LAYER:
+ p->num_hier_max_layer = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC90_VIDEO_HEVC_SIGN_DATA_HIDING:
+ break;
+ case V4L2_CID_MPEG_VIDEO_WEIGHTED_ENABLE:
+ p->weighted_enable = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA:
+ p->ratio_intra = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG:
+ p->check_color_range = 1;
+ p->color_range = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES:
+ p->colour_primaries = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_TRANSFER_CHARACTERISTICS:
+ p->transfer_characteristics = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MATRIX_COEFFICIENTS:
+ p->matrix_coefficients = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_HIERARCHICAL_BITRATE_CTRL:
+ p->hier_bitrate_ctrl = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_STATIC_INFO_ENABLE:
+ p->static_info_enable = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_SEI_MAX_PIC_AVERAGE_LIGHT:
+ p->max_pic_average_light = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_SEI_MAX_CONTENT_LIGHT:
+ p->max_content_light = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_SEI_MAX_DISPLAY_LUMINANCE:
+ p->max_display_luminance = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_SEI_MIN_DISPLAY_LUMINANCE:
+ p->min_display_luminance = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_SEI_WHITE_POINT:
+ p->white_point = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_0:
+ p->display_primaries_0 = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_1:
+ p->display_primaries_1 = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_SEI_DISPLAY_PRIMARIES_2:
+ p->display_primaries_2 = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_DROP_CONTROL:
+ p->drop_control = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_CHROMA_QP_OFFSET_CB:
+ p->chroma_qp_offset_cb = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_CHROMA_QP_OFFSET_CR:
+ p->chroma_qp_offset_cr = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_SKIP_LAZY_UNMAP:
+ ctx->skip_lazy_unmap = ctrl->value;
+ mfc_ctx_debug(2, "[LAZY_UNMAP] lazy unmap %s\n",
+ ctx->skip_lazy_unmap ? "disable" : "enable");
+ break;
+ case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE:
+ mfc_ctx_debug(2, "[QoS] user set the operating frame rate: %d\n", ctrl->value);
+ ctx->operating_framerate = ctrl->value;
+ mfc_rm_update_real_time(ctx);
+ break;
+ case V4L2_CID_MPEG_VIDEO_GOP_CTRL:
+ p->gop_ctrl = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MV_SEARCH_MODE:
+ p->mv_search_mode = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MV_HOR_POSITION_L0:
+ p->mv_hor_pos_l0 = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MV_HOR_POSITION_L1:
+ p->mv_hor_pos_l1 = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MV_VER_POSITION_L0:
+ p->mv_ver_pos_l0 = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MV_VER_POSITION_L1:
+ p->mv_ver_pos_l1 = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MIN_QUALITY:
+ p->min_quality_mode = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MAX_IFRAME_SIZE:
+ p->max_i_frame_size = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_WP_TWO_PASS_ENABLE:
+ p->wp_two_pass_enable = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ADAPTIVE_GOP_ENABLE:
+ p->adaptive_gop_enable = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MV_HOR_RANGE:
+ p->mv_hor_range = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MV_VER_RANGE:
+ p->mv_ver_range = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC_TIMING_INFO_ENABLE:
+ p->timing_info_enable = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC_MULTI_VIEW_ENABLE:
+ ctx->multi_view_enable = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_MFC_MULTI_VIEW_MAIN_TYPE:
+ ctx->left_view_id = ((ctrl->value & 0x1) == 0) ? MFC_VIEW_ID_MAIN : MFC_VIEW_ID_SUB;
+ break;
+ /* These are stored in specific variables */
+ case V4L2_CID_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_LAYER_CH:
+ case V4L2_CID_MPEG_VIDEO_VP9_HIERARCHICAL_CODING_LAYER_CH:
+ case V4L2_CID_MPEG_VIDEO_VP8_HIERARCHICAL_CODING_LAYER_CH:
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH:
+ /* These require control per buffer */
+ case V4L2_CID_MPEG_VIDEO_YSUM:
+ case V4L2_CID_MPEG_VIDEO_ROI_CONTROL:
+ case V4L2_CID_MPEG_MFC_H264_USE_LTR:
+ case V4L2_CID_MPEG_MFC_H264_MARK_LTR:
+ case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
+ case V4L2_CID_MPEG_VIDEO_SRC_BUF_FLAG:
+ case V4L2_CID_MPEG_VIDEO_DST_BUF_FLAG:
+ break;
+ default:
+ mfc_ctx_err("Invalid control: 0x%08x\n", ctrl->id);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int __mfc_enc_set_ctrl_val_list(struct mfc_ctx *ctx,
+ struct v4l2_control *ctrl)
+{
+ struct mfc_enc *enc = ctx->enc_priv;
+ struct mfc_enc_params *p = &enc->params;
+ struct mfc_ctx_ctrl *ctx_ctrl;
+ int ret = 0;
+ int found = 0;
+
+ list_for_each_entry(ctx_ctrl, &ctx->ctrls, list) {
+ if (!(ctx_ctrl->type & MFC_CTRL_TYPE_SET))
+ continue;
+
+ if (ctx_ctrl->id == ctrl->id) {
+ ctx_ctrl->set.has_new = 1;
+ ctx_ctrl->set.val = ctrl->value;
+ if (ctx_ctrl->id ==
+ V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH) {
+ if (enc->sh_handle_svc.fd == -1) {
+ enc->sh_handle_svc.fd = ctrl->value;
+ if (mfc_mem_get_user_shared_handle
+ (ctx, &enc->sh_handle_svc, "SVC"))
+ return -EINVAL;
+ }
+ }
+ if (ctx_ctrl->id == V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH &&
+ p->i_frm_ctrl_mode) {
+ if (!p->gop_ctrl)
+ ctx_ctrl->set.val = ctx_ctrl->set.val *
+ (p->num_b_frame + 1);
+
+ if (ctx_ctrl->set.val >= 0x3FFFFFFF) {
+ mfc_ctx_info("I frame interval is bigger than max: %d\n",
+ ctx_ctrl->set.val);
+ ctx_ctrl->set.val = 0x3FFFFFFF;
+ }
+ }
+ if (ctx_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL)
+ ctx_ctrl->set.val = __mfc_enc_h264_level
+ ((enum v4l2_mpeg_video_h264_level)(ctrl->value));
+ if (ctx_ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE)
+ ctx_ctrl->set.val =
+ __mfc_enc_h264_profile
+ (ctx,
+ (enum v4l2_mpeg_video_h264_profile)(ctrl->value));
+ if (ctx_ctrl->id == V4L2_CID_MPEG_VIDEO_ROI_CONTROL) {
+ ret = __mfc_enc_get_roi(ctx, ctrl->value);
+ if (ret)
+ return ret;
+ }
+
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ mfc_ctx_err("Invalid control: 0x%08x\n", ctrl->id);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int __mfc_enc_set_ctrl_val(struct mfc_ctx *ctx, struct v4l2_control *ctrl)
+{
+ int ret = 0;
+
+ /* update parameter value */
+ ret = __mfc_enc_set_param(ctx, ctrl);
+ if (ret)
+ return ret;
+
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_VIDEO_QOS_RATIO:
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_P:
+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_P:
+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP_B:
+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP_B:
+ case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG:
+ case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
+ case V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH:
+ case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH:
+ case V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH:
+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_CH:
+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+ case V4L2_CID_MPEG_MFC_H264_MARK_LTR:
+ case V4L2_CID_MPEG_MFC_H264_USE_LTR:
+ case V4L2_CID_MPEG_MFC_H264_BASE_PRIORITY:
+ case V4L2_CID_MPEG_MFC_CONFIG_QP:
+ case V4L2_CID_MPEG_VIDEO_ROI_CONTROL:
+ case V4L2_CID_MPEG_VIDEO_YSUM:
+ case V4L2_CID_MPEG_VIDEO_RATIO_OF_INTRA:
+ case V4L2_CID_MPEG_VIDEO_DROP_CONTROL:
+ case V4L2_CID_MPEG_VIDEO_MV_HOR_POSITION_L0:
+ case V4L2_CID_MPEG_VIDEO_MV_HOR_POSITION_L1:
+ case V4L2_CID_MPEG_VIDEO_MV_VER_POSITION_L0:
+ case V4L2_CID_MPEG_VIDEO_MV_VER_POSITION_L1:
+ case V4L2_CID_MPEG_VIDEO_MAX_IFRAME_SIZE:
+ case V4L2_CID_MPEG_VIDEO_SRC_BUF_FLAG:
+ case V4L2_CID_MPEG_VIDEO_DST_BUF_FLAG:
+ ret = __mfc_enc_set_ctrl_val_list(ctx, ctrl);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static int mfc_enc_g_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *f)
+{
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+ struct v4l2_ext_control *ext_ctrl;
+ struct v4l2_control ctrl;
+ int i;
+ int ret = 0;
+
+ if (f->which != V4L2_CTRL_CLASS_CODEC && f->which != V4L2_CTRL_CLASS_USER)
+ return -EINVAL;
+
+ for (i = 0; i < f->count; i++) {
+ ext_ctrl = (f->controls + i);
+
+ ctrl.id = ext_ctrl->id;
+
+ ret = __mfc_enc_get_ctrl_val(ctx, &ctrl);
+ if (ret == 0) {
+ ext_ctrl->value = ctrl.value;
+ } else {
+ f->error_idx = i;
+ break;
+ }
+
+ mfc_ctx_debug(5, "[CTRLS][%d] id: %#x, value: %d\n",
+ i, ext_ctrl->id, ext_ctrl->value);
+ }
+
+ return ret;
+}
+
+static int mfc_enc_s_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *f)
+{
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+ struct v4l2_ext_control *ext_ctrl;
+ struct v4l2_control ctrl;
+ int i;
+ int ret = 0;
+
+ mfc_ctx_debug_enter();
+
+ if (f->which != V4L2_CTRL_CLASS_CODEC && f->which != V4L2_CTRL_CLASS_USER)
+ return -EINVAL;
+
+ for (i = 0; i < f->count; i++) {
+ ext_ctrl = (f->controls + i);
+
+ ctrl.id = ext_ctrl->id;
+ ctrl.value = ext_ctrl->value;
+
+ ret = __mfc_enc_check_ctrl_val(ctx, &ctrl);
+ if (ret != 0) {
+ f->error_idx = i;
+ break;
+ }
+
+ if (f->which == V4L2_CTRL_CLASS_USER)
+ ret = __mfc_enc_set_ctrl_val(ctx, &ctrl);
+ else
+ ret = __mfc_enc_set_param(ctx, &ctrl);
+ if (ret != 0) {
+ f->error_idx = i;
+ break;
+ }
+ }
+
+ mfc_ctx_debug_leave();
+
+ return ret;
+}
+
+static int mfc_enc_try_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *f)
+{
+ struct mfc_ctx *ctx = fh_to_mfc_ctx(file->private_data);
+ struct v4l2_ext_control *ext_ctrl;
+ struct v4l2_control ctrl;
+ int i;
+ int ret = 0;
+
+ mfc_ctx_debug_enter();
+
+ if (f->which != V4L2_CTRL_CLASS_CODEC)
+ return -EINVAL;
+
+ for (i = 0; i < f->count; i++) {
+ ext_ctrl = (f->controls + i);
+
+ ctrl.id = ext_ctrl->id;
+ ctrl.value = ext_ctrl->value;
+
+ ret = __mfc_enc_check_ctrl_val(ctx, &ctrl);
+ if (ret != 0) {
+ f->error_idx = i;
+ break;
+ }
+ }
+
+ mfc_ctx_debug_leave();
+
+ return ret;
+}
+
+/* Initialize for default format */
+void mfc_enc_set_default_format(struct mfc_ctx *ctx)
+{
+ struct mfc_fmt *fmt = NULL;
+
+ /* Set default format for source */
+ fmt = __mfc_enc_find_format(ctx, V4L2_PIX_FMT_NV12M);
+ if (!fmt) {
+ /* NEVER come here */
+ mfc_ctx_err("Wrong memory access. Set fmt by mfc_formats[0]\n");
+ fmt = &mfc_formats[0];
+ }
+ ctx->src_fmt = fmt;
+
+ /* Set default format for destination */
+ fmt = __mfc_enc_find_format(ctx, V4L2_PIX_FMT_H264);
+ if (!fmt) {
+ /* NEVER come here */
+ mfc_ctx_err("Wrong memory access. Set fmt by mfc_formats[0]\n");
+ fmt = &mfc_formats[0];
+ }
+ ctx->dst_fmt = fmt;
+}
+
+static const struct v4l2_ioctl_ops mfc_enc_ioctl_ops = {
+ .vidioc_querycap = mfc_enc_querycap,
+ .vidioc_enum_fmt_vid_cap = mfc_enc_enum_fmt_vid_cap_mplane,
+ .vidioc_enum_fmt_vid_out = mfc_enc_enum_fmt_vid_out_mplane,
+ .vidioc_g_fmt_vid_cap_mplane = mfc_enc_g_fmt,
+ .vidioc_g_fmt_vid_out_mplane = mfc_enc_g_fmt,
+ .vidioc_try_fmt_vid_cap_mplane = mfc_enc_try_fmt,
+ .vidioc_try_fmt_vid_out_mplane = mfc_enc_try_fmt,
+ .vidioc_s_fmt_vid_cap_mplane = mfc_enc_s_fmt_vid_cap_mplane,
+ .vidioc_s_fmt_vid_out_mplane = mfc_enc_s_fmt_vid_out_mplane,
+ .vidioc_g_selection = mfc_enc_g_selection,
+ .vidioc_s_selection = mfc_enc_s_selection,
+ .vidioc_reqbufs = mfc_enc_reqbufs,
+ .vidioc_querybuf = mfc_enc_querybuf,
+ .vidioc_qbuf = mfc_enc_qbuf,
+ .vidioc_dqbuf = mfc_enc_dqbuf,
+ .vidioc_streamon = mfc_enc_streamon,
+ .vidioc_streamoff = mfc_enc_streamoff,
+ .vidioc_g_ext_ctrls = mfc_enc_g_ext_ctrls,
+ .vidioc_s_ext_ctrls = mfc_enc_s_ext_ctrls,
+ .vidioc_try_ext_ctrls = mfc_enc_try_ext_ctrls,
+};
+
+const struct v4l2_ioctl_ops *mfc_get_enc_v4l2_ioctl_ops(void)
+{
+ return &mfc_enc_ioctl_ops;
+}
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_enc_v4l2.h b/drivers/media/platform/samsung/exynos-mfc/mfc_enc_v4l2.h
new file mode 100644
index 000000000000..93cca69ae385
--- /dev/null
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_enc_v4l2.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * mfc_enc_v4l2.h file
+ *
+ * Nagaraju Siddineni, <nagaraju.s@...sung.com>
+ * Himanshu Dewangan, <h.dewangan@...sung.com>
+ */
+
+#ifndef __MFC_ENC_V4L2_H
+#define __MFC_ENC_V4L2_H __FILE__
+
+#include "base/mfc_common.h"
+
+const struct v4l2_ioctl_ops *mfc_get_enc_v4l2_ioctl_ops(void);
+void mfc_enc_set_default_format(struct mfc_ctx *ctx);
+
+#endif /* __MFC_ENC_V4L2_H */
--
2.34.1
Powered by blists - more mailing lists