diff options
author | Mauro Carvalho Chehab <mchehab@kernel.org> | 2022-03-13 11:18:18 +0100 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@kernel.org> | 2022-03-18 05:58:34 +0100 |
commit | 43ecec16c4face9a59e81771e7cbff4671c62117 (patch) | |
tree | ca6f40fedfd661743ee9819d2fe861770d656a91 /drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | |
parent | media: platform: rename s5p-jpeg/ to samsung/s5p-jpeg/ (diff) | |
download | linux-dev-43ecec16c4face9a59e81771e7cbff4671c62117.tar.xz linux-dev-43ecec16c4face9a59e81771e7cbff4671c62117.zip |
media: platform: rename s5p-mfc/ to samsung/s5p-mfc/
As the end goal is to have platform drivers split by vendor,
rename s5p-mfc/ to samsung/s5p-mfc/.
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers/media/platform/s5p-mfc/s5p_mfc_enc.c')
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 2697 |
1 files changed, 0 insertions, 2697 deletions
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c deleted file mode 100644 index 1fad99edb091..000000000000 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ /dev/null @@ -1,2697 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * linux/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Jeongtae Park <jtp.park@samsung.com> - * Kamil Debski <k.debski@samsung.com> - */ - -#include <linux/clk.h> -#include <linux/interrupt.h> -#include <linux/io.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/sched.h> -#include <linux/videodev2.h> -#include <media/v4l2-event.h> -#include <linux/workqueue.h> -#include <media/v4l2-ctrls.h> -#include <media/videobuf2-v4l2.h> -#include "s5p_mfc_common.h" -#include "s5p_mfc_ctrl.h" -#include "s5p_mfc_debug.h" -#include "s5p_mfc_enc.h" -#include "s5p_mfc_intr.h" -#include "s5p_mfc_opr.h" - -#define DEF_SRC_FMT_ENC V4L2_PIX_FMT_NV12M -#define DEF_DST_FMT_ENC V4L2_PIX_FMT_H264 - -static struct s5p_mfc_fmt formats[] = { - { - .fourcc = V4L2_PIX_FMT_NV12MT_16X16, - .codec_mode = S5P_MFC_CODEC_NONE, - .type = MFC_FMT_RAW, - .num_planes = 2, - .versions = MFC_V6_BIT | MFC_V7_BIT, - }, - { - .fourcc = V4L2_PIX_FMT_NV12MT, - .codec_mode = S5P_MFC_CODEC_NONE, - .type = MFC_FMT_RAW, - .num_planes = 2, - .versions = MFC_V5_BIT, - }, - { - .fourcc = V4L2_PIX_FMT_NV12M, - .codec_mode = S5P_MFC_CODEC_NONE, - .type = MFC_FMT_RAW, - .num_planes = 2, - .versions = MFC_V5PLUS_BITS, - }, - { - .fourcc = V4L2_PIX_FMT_NV21M, - .codec_mode = S5P_MFC_CODEC_NONE, - .type = MFC_FMT_RAW, - .num_planes = 2, - .versions = MFC_V6PLUS_BITS, - }, - { - .fourcc = V4L2_PIX_FMT_H264, - .codec_mode = S5P_MFC_CODEC_H264_ENC, - .type = MFC_FMT_ENC, - .num_planes = 1, - .versions = MFC_V5PLUS_BITS, - }, - { - .fourcc = V4L2_PIX_FMT_MPEG4, - .codec_mode = S5P_MFC_CODEC_MPEG4_ENC, - .type = MFC_FMT_ENC, - .num_planes = 1, - .versions = MFC_V5PLUS_BITS, - }, - { - .fourcc = V4L2_PIX_FMT_H263, - .codec_mode = S5P_MFC_CODEC_H263_ENC, - .type = MFC_FMT_ENC, - .num_planes = 1, - .versions = MFC_V5PLUS_BITS, - }, - { - .fourcc = V4L2_PIX_FMT_VP8, - .codec_mode = S5P_MFC_CODEC_VP8_ENC, - .type = MFC_FMT_ENC, - .num_planes = 1, - .versions = MFC_V7PLUS_BITS, - }, - { - .fourcc = V4L2_PIX_FMT_HEVC, - .codec_mode = S5P_FIMV_CODEC_HEVC_ENC, - .type = MFC_FMT_ENC, - .num_planes = 1, - .versions = MFC_V10_BIT, - }, -}; - -#define NUM_FORMATS ARRAY_SIZE(formats) -static struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t) -{ - unsigned int i; - - for (i = 0; i < NUM_FORMATS; i++) { - if (formats[i].fourcc == f->fmt.pix_mp.pixelformat && - formats[i].type == t) - return &formats[i]; - } - return NULL; -} - -static struct mfc_control controls[] = { - { - .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = (1 << 16) - 1, - .step = 1, - .default_value = 12, - }, - { - .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE, - .maximum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES, - .default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 1, - .maximum = (1 << 16) - 1, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 1900, - .maximum = (1 << 30) - 1, - .step = 1, - .default_value = 1900, - }, - { - .id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = (1 << 16) - 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 = (1 << 25) - 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_BITRATE, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 1, - .maximum = (1 << 30) - 1, - .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 = (1 << 16) - 1, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Force frame type", - .minimum = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED, - .maximum = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED, - .default_value = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, - .type = V4L2_CTRL_TYPE_BUTTON, - .minimum = 0, - .maximum = 0, - .step = 0, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_VBV_SIZE, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = (1 << 16) - 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Horizontal MV Search Range", - .minimum = 16, - .maximum = 128, - .step = 16, - .default_value = 32, - }, - { - .id = V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Vertical MV Search Range", - .minimum = 16, - .maximum = 128, - .step = 16, - .default_value = 32, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = (1 << 16) - 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEADER_MODE, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE, - .maximum = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME, - .default_value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Frame Skip Enable", - .minimum = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED, - .maximum = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT, - .menu_skip_mask = 0, - .default_value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED, - }, - { - .id = V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE, - .type = V4L2_CTRL_TYPE_MENU, - .maximum = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT, - .default_value = V4L2_MPEG_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, - .default_value = 0, - .step = 1, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_B_FRAMES, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, - .maximum = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH, - .default_value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, - .menu_skip_mask = ~( - (1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | - (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | - (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) - ), - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - .maximum = V4L2_MPEG_VIDEO_H264_LEVEL_4_0, - .default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0, - .maximum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5, - .default_value = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED, - .maximum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY, - .default_value = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = -6, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = -6, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC, - .maximum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC, - .default_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "The Number of Ref. Pic for P", - .minimum = 1, - .maximum = 2, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 51, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "H263 I-Frame QP value", - .minimum = 1, - .maximum = 31, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "H263 Minimum QP value", - .minimum = 1, - .maximum = 31, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "H263 Maximum QP value", - .minimum = 1, - .maximum = 31, - .step = 1, - .default_value = 31, - }, - { - .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_VIDEO_H263_B_FRAME_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "H263 B frame QP value", - .minimum = 1, - .maximum = 31, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "MPEG4 I-Frame QP value", - .minimum = 1, - .maximum = 31, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "MPEG4 Minimum QP value", - .minimum = 1, - .maximum = 31, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "MPEG4 Maximum QP value", - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 51, - }, - { - .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_H264_ADAPTIVE_RC_DARK, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "H264 Dark Reg Adaptive RC", - .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 Reg Adaptive RC", - .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 Reg Adaptive RC", - .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 Activity Reg Adaptive RC", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED, - .maximum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED, - .default_value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = (1 << 16) - 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = (1 << 16) - 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = (1 << 16) - 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE, - .maximum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE, - .default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS, - .type = V4L2_CTRL_TYPE_INTEGER_MENU, - .maximum = V4L2_CID_MPEG_VIDEO_VPX_8_PARTITIONS, - .default_value = V4L2_CID_MPEG_VIDEO_VPX_1_PARTITION, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES, - .type = V4L2_CTRL_TYPE_INTEGER_MENU, - .maximum = V4L2_CID_MPEG_VIDEO_VPX_2_REF_FRAME, - .default_value = V4L2_CID_MPEG_VIDEO_VPX_1_REF_FRAME, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 63, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 7, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = (1 << 16) - 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV, - .maximum = V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_REF_PERIOD, - .default_value = V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_VPX_MAX_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 127, - .step = 1, - .default_value = 127, - }, - { - .id = V4L2_CID_MPEG_VIDEO_VPX_MIN_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 11, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 127, - .step = 1, - .default_value = 10, - }, - { - .id = V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 127, - .step = 1, - .default_value = 10, - }, - { - .id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_VP8_PROFILE_0, - .maximum = V4L2_MPEG_VIDEO_VP8_PROFILE_3, - .default_value = V4L2_MPEG_VIDEO_VP8_PROFILE_0, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "HEVC I Frame QP Value", - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "HEVC P Frame QP Value", - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, - .maximum = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE, - .step = 1, - .default_value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - .maximum = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2, - .step = 1, - .default_value = V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_TIER, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN, - .maximum = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH, - .step = 1, - .default_value = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 1, - .maximum = (1 << 16) - 1, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 1, - .maximum = 2, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE, - .maximum = V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR, - .step = 1, - .default_value = V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED, - .maximum = V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY, - .step = 1, - .default_value = V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B, - .maximum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P, - .step = 1, - .default_value = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = INT_MIN, - .maximum = INT_MAX, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = INT_MIN, - .maximum = INT_MAX, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = INT_MIN, - .maximum = INT_MAX, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = INT_MIN, - .maximum = INT_MAX, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = INT_MIN, - .maximum = INT_MAX, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = INT_MIN, - .maximum = INT_MAX, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = INT_MIN, - .maximum = INT_MAX, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = (1 << 16) - 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = -6, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = -6, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_HEVC_SIZE_0, - .maximum = V4L2_MPEG_VIDEO_HEVC_SIZE_4, - .step = 1, - .default_value = V4L2_MPEG_VIDEO_HEVC_SIZE_0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Minimum number of output bufs", - .minimum = 1, - .maximum = 32, - .step = 1, - .default_value = 1, - .is_volatile = 1, - }, -}; - -#define NUM_CTRLS ARRAY_SIZE(controls) -static const char * const *mfc51_get_menu(u32 id) -{ - static const char * const mfc51_video_frame_skip[] = { - "Disabled", - "Level Limit", - "VBV/CPB Limit", - NULL, - }; - static const char * const mfc51_video_force_frame[] = { - "Disabled", - "I Frame", - "Not Coded", - NULL, - }; - switch (id) { - case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE: - return mfc51_video_frame_skip; - case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE: - return mfc51_video_force_frame; - } - return NULL; -} - -static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx) -{ - mfc_debug(2, "src=%d, dst=%d, state=%d\n", - ctx->src_queue_cnt, ctx->dst_queue_cnt, ctx->state); - /* context is ready to make header */ - if (ctx->state == MFCINST_GOT_INST && ctx->dst_queue_cnt >= 1) - return 1; - /* context is ready to encode a frame */ - if ((ctx->state == MFCINST_RUNNING || - ctx->state == MFCINST_HEAD_PRODUCED) && - ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1) - return 1; - /* context is ready to encode remaining frames */ - if (ctx->state == MFCINST_FINISHING && - ctx->dst_queue_cnt >= 1) - return 1; - mfc_debug(2, "ctx is not ready\n"); - return 0; -} - -static void cleanup_ref_queue(struct s5p_mfc_ctx *ctx) -{ - struct s5p_mfc_buf *mb_entry; - - /* move buffers in ref queue to src queue */ - while (!list_empty(&ctx->ref_queue)) { - mb_entry = list_entry((&ctx->ref_queue)->next, - struct s5p_mfc_buf, list); - list_del(&mb_entry->list); - ctx->ref_queue_cnt--; - list_add_tail(&mb_entry->list, &ctx->src_queue); - ctx->src_queue_cnt++; - } - mfc_debug(2, "enc src count: %d, enc ref count: %d\n", - ctx->src_queue_cnt, ctx->ref_queue_cnt); - INIT_LIST_HEAD(&ctx->ref_queue); - ctx->ref_queue_cnt = 0; -} - -static int enc_pre_seq_start(struct s5p_mfc_ctx *ctx) -{ - struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_buf *dst_mb; - unsigned long dst_addr; - unsigned int dst_size; - - dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); - dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0); - dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0); - s5p_mfc_hw_call(dev->mfc_ops, set_enc_stream_buffer, ctx, dst_addr, - dst_size); - return 0; -} - -static int enc_post_seq_start(struct s5p_mfc_ctx *ctx) -{ - struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_enc_params *p = &ctx->enc_params; - struct s5p_mfc_buf *dst_mb; - unsigned int enc_pb_count; - - if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) { - if (!list_empty(&ctx->dst_queue)) { - dst_mb = list_entry(ctx->dst_queue.next, - struct s5p_mfc_buf, list); - list_del(&dst_mb->list); - ctx->dst_queue_cnt--; - vb2_set_plane_payload(&dst_mb->b->vb2_buf, 0, - s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, - dev)); - vb2_buffer_done(&dst_mb->b->vb2_buf, - VB2_BUF_STATE_DONE); - } - } - - if (!IS_MFCV6_PLUS(dev)) { - ctx->state = MFCINST_RUNNING; - if (s5p_mfc_ctx_ready(ctx)) - set_work_bit_irqsave(ctx); - s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); - } else { - enc_pb_count = s5p_mfc_hw_call(dev->mfc_ops, - get_enc_dpb_count, dev); - if (ctx->pb_count < enc_pb_count) - ctx->pb_count = enc_pb_count; - if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) { - ctx->scratch_buf_size = s5p_mfc_hw_call(dev->mfc_ops, - get_e_min_scratch_buf_size, dev); - ctx->bank1.size += ctx->scratch_buf_size; - } - ctx->state = MFCINST_HEAD_PRODUCED; - } - - return 0; -} - -static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx) -{ - struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_buf *dst_mb; - struct s5p_mfc_buf *src_mb; - unsigned long src_y_addr, src_c_addr, dst_addr; - unsigned int dst_size; - - src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); - src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0); - src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1); - s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx, - src_y_addr, src_c_addr); - - dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); - dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0); - dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0); - s5p_mfc_hw_call(dev->mfc_ops, set_enc_stream_buffer, ctx, dst_addr, - dst_size); - - return 0; -} - -static int enc_post_frame_start(struct s5p_mfc_ctx *ctx) -{ - struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_buf *mb_entry; - unsigned long enc_y_addr = 0, enc_c_addr = 0; - unsigned long mb_y_addr, mb_c_addr; - int slice_type; - unsigned int strm_size; - - slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev); - strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev); - mfc_debug(2, "Encoded slice type: %d\n", slice_type); - mfc_debug(2, "Encoded stream size: %d\n", strm_size); - mfc_debug(2, "Display order: %d\n", - mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT)); - if (slice_type >= 0) { - s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer, ctx, - &enc_y_addr, &enc_c_addr); - list_for_each_entry(mb_entry, &ctx->src_queue, list) { - mb_y_addr = vb2_dma_contig_plane_dma_addr( - &mb_entry->b->vb2_buf, 0); - mb_c_addr = vb2_dma_contig_plane_dma_addr( - &mb_entry->b->vb2_buf, 1); - if ((enc_y_addr == mb_y_addr) && - (enc_c_addr == mb_c_addr)) { - list_del(&mb_entry->list); - ctx->src_queue_cnt--; - vb2_buffer_done(&mb_entry->b->vb2_buf, - VB2_BUF_STATE_DONE); - break; - } - } - list_for_each_entry(mb_entry, &ctx->ref_queue, list) { - mb_y_addr = vb2_dma_contig_plane_dma_addr( - &mb_entry->b->vb2_buf, 0); - mb_c_addr = vb2_dma_contig_plane_dma_addr( - &mb_entry->b->vb2_buf, 1); - if ((enc_y_addr == mb_y_addr) && - (enc_c_addr == mb_c_addr)) { - list_del(&mb_entry->list); - ctx->ref_queue_cnt--; - vb2_buffer_done(&mb_entry->b->vb2_buf, - VB2_BUF_STATE_DONE); - break; - } - } - } - if ((ctx->src_queue_cnt > 0) && (ctx->state == MFCINST_RUNNING)) { - mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, - list); - if (mb_entry->flags & MFC_BUF_FLAG_USED) { - list_del(&mb_entry->list); - ctx->src_queue_cnt--; - list_add_tail(&mb_entry->list, &ctx->ref_queue); - ctx->ref_queue_cnt++; - } - } - mfc_debug(2, "enc src count: %d, enc ref count: %d\n", - ctx->src_queue_cnt, ctx->ref_queue_cnt); - if ((ctx->dst_queue_cnt > 0) && (strm_size > 0)) { - mb_entry = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, - list); - list_del(&mb_entry->list); - ctx->dst_queue_cnt--; - switch (slice_type) { - case S5P_FIMV_ENC_SI_SLICE_TYPE_I: - mb_entry->b->flags |= V4L2_BUF_FLAG_KEYFRAME; - break; - case S5P_FIMV_ENC_SI_SLICE_TYPE_P: - mb_entry->b->flags |= V4L2_BUF_FLAG_PFRAME; - break; - case S5P_FIMV_ENC_SI_SLICE_TYPE_B: - mb_entry->b->flags |= V4L2_BUF_FLAG_BFRAME; - break; - } - vb2_set_plane_payload(&mb_entry->b->vb2_buf, 0, strm_size); - vb2_buffer_done(&mb_entry->b->vb2_buf, VB2_BUF_STATE_DONE); - } - if ((ctx->src_queue_cnt == 0) || (ctx->dst_queue_cnt == 0)) - clear_work_bit(ctx); - - return 0; -} - -static const struct s5p_mfc_codec_ops encoder_codec_ops = { - .pre_seq_start = enc_pre_seq_start, - .post_seq_start = enc_post_seq_start, - .pre_frame_start = enc_pre_frame_start, - .post_frame_start = enc_post_frame_start, -}; - -/* Query capabilities of the device */ -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct s5p_mfc_dev *dev = video_drvdata(file); - - strscpy(cap->driver, S5P_MFC_NAME, sizeof(cap->driver)); - strscpy(cap->card, dev->vfd_enc->name, sizeof(cap->card)); - snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", - dev_name(&dev->plat_dev->dev)); - return 0; -} - -static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f, - bool out) -{ - struct s5p_mfc_dev *dev = video_drvdata(file); - int i, j = 0; - - for (i = 0; i < ARRAY_SIZE(formats); ++i) { - if (out && formats[i].type != MFC_FMT_RAW) - continue; - else if (!out && formats[i].type != MFC_FMT_ENC) - continue; - else if ((dev->variant->version_bit & formats[i].versions) == 0) - continue; - - if (j == f->index) { - f->pixelformat = formats[i].fourcc; - return 0; - } - ++j; - } - return -EINVAL; -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv, - struct v4l2_fmtdesc *f) -{ - return vidioc_enum_fmt(file, f, false); -} - -static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - return vidioc_enum_fmt(file, f, true); -} - -static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) -{ - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); - struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; - - mfc_debug(2, "f->type = %d ctx->state = %d\n", f->type, ctx->state); - if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - /* 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->num_planes; - - pix_fmt_mp->plane_fmt[0].bytesperline = ctx->enc_dst_buf_size; - pix_fmt_mp->plane_fmt[0].sizeimage = ctx->enc_dst_buf_size; - } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - /* This is run on capture (encoder src) */ - 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->num_planes; - - pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width; - pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size; - pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width; - pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size; - } else { - mfc_err("invalid buf type\n"); - return -EINVAL; - } - return 0; -} - -static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) -{ - struct s5p_mfc_dev *dev = video_drvdata(file); - struct s5p_mfc_fmt *fmt; - struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; - - if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - fmt = find_format(f, MFC_FMT_ENC); - if (!fmt) { - mfc_err("failed to try output format\n"); - return -EINVAL; - } - if ((dev->variant->version_bit & fmt->versions) == 0) { - mfc_err("Unsupported format by this MFC version.\n"); - return -EINVAL; - } - - pix_fmt_mp->plane_fmt[0].bytesperline = - pix_fmt_mp->plane_fmt[0].sizeimage; - } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - fmt = find_format(f, MFC_FMT_RAW); - if (!fmt) { - mfc_err("failed to try output format\n"); - return -EINVAL; - } - if ((dev->variant->version_bit & fmt->versions) == 0) { - mfc_err("Unsupported format by this MFC version.\n"); - return -EINVAL; - } - - v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1, - &pix_fmt_mp->height, 4, 1080, 1, 0); - } else { - mfc_err("invalid buf type\n"); - return -EINVAL; - } - return 0; -} - -static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) -{ - struct s5p_mfc_dev *dev = video_drvdata(file); - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); - struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; - int ret = 0; - - ret = vidioc_try_fmt(file, priv, f); - if (ret) - return ret; - if (ctx->vq_src.streaming || ctx->vq_dst.streaming) { - v4l2_err(&dev->v4l2_dev, "%s queue busy\n", __func__); - ret = -EBUSY; - goto out; - } - if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - /* dst_fmt is validated by call to vidioc_try_fmt */ - ctx->dst_fmt = find_format(f, MFC_FMT_ENC); - ctx->state = MFCINST_INIT; - ctx->codec_mode = ctx->dst_fmt->codec_mode; - ctx->enc_dst_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage; - pix_fmt_mp->plane_fmt[0].bytesperline = 0; - ctx->dst_bufs_cnt = 0; - ctx->capture_state = QUEUE_FREE; - ret = s5p_mfc_open_mfc_inst(dev, ctx); - } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - /* src_fmt is validated by call to vidioc_try_fmt */ - ctx->src_fmt = find_format(f, MFC_FMT_RAW); - ctx->img_width = pix_fmt_mp->width; - ctx->img_height = pix_fmt_mp->height; - mfc_debug(2, "codec number: %d\n", ctx->src_fmt->codec_mode); - mfc_debug(2, "fmt - w: %d, h: %d, ctx - w: %d, h: %d\n", - pix_fmt_mp->width, pix_fmt_mp->height, - ctx->img_width, ctx->img_height); - - s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx); - pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size; - pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width; - pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size; - pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width; - - ctx->src_bufs_cnt = 0; - ctx->output_state = QUEUE_FREE; - } else { - mfc_err("invalid buf type\n"); - ret = -EINVAL; - } -out: - mfc_debug_leave(); - return ret; -} - -static int vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *reqbufs) -{ - struct s5p_mfc_dev *dev = video_drvdata(file); - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); - int ret = 0; - - /* if memory is not mmp or userptr return error */ - if ((reqbufs->memory != V4L2_MEMORY_MMAP) && - (reqbufs->memory != V4L2_MEMORY_USERPTR)) - return -EINVAL; - if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - if (reqbufs->count == 0) { - mfc_debug(2, "Freeing buffers\n"); - ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); - s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, - ctx); - ctx->capture_state = QUEUE_FREE; - return ret; - } - if (ctx->capture_state != QUEUE_FREE) { - mfc_err("invalid capture state: %d\n", - ctx->capture_state); - return -EINVAL; - } - ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); - if (ret != 0) { - mfc_err("error in vb2_reqbufs() for E(D)\n"); - return ret; - } - ctx->capture_state = QUEUE_BUFS_REQUESTED; - - ret = s5p_mfc_hw_call(ctx->dev->mfc_ops, - alloc_codec_buffers, ctx); - if (ret) { - mfc_err("Failed to allocate encoding buffers\n"); - reqbufs->count = 0; - ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); - return -ENOMEM; - } - } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - if (reqbufs->count == 0) { - mfc_debug(2, "Freeing buffers\n"); - ret = vb2_reqbufs(&ctx->vq_src, reqbufs); - s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, - ctx); - ctx->output_state = QUEUE_FREE; - return ret; - } - if (ctx->output_state != QUEUE_FREE) { - mfc_err("invalid output state: %d\n", - ctx->output_state); - return -EINVAL; - } - - if (IS_MFCV6_PLUS(dev)) { - /* Check for min encoder buffers */ - if (ctx->pb_count && - (reqbufs->count < ctx->pb_count)) { - reqbufs->count = ctx->pb_count; - mfc_debug(2, "Minimum %d output buffers needed\n", - ctx->pb_count); - } else { - ctx->pb_count = reqbufs->count; - } - } - - ret = vb2_reqbufs(&ctx->vq_src, reqbufs); - if (ret != 0) { - mfc_err("error in vb2_reqbufs() for E(S)\n"); - return ret; - } - ctx->output_state = QUEUE_BUFS_REQUESTED; - } else { - mfc_err("invalid buf type\n"); - return -EINVAL; - } - return ret; -} - -static int vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *buf) -{ - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); - int ret = 0; - - /* if memory is not mmp or userptr return error */ - if ((buf->memory != V4L2_MEMORY_MMAP) && - (buf->memory != V4L2_MEMORY_USERPTR)) - return -EINVAL; - if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - if (ctx->state != MFCINST_GOT_INST) { - mfc_err("invalid context state: %d\n", ctx->state); - return -EINVAL; - } - ret = vb2_querybuf(&ctx->vq_dst, buf); - if (ret != 0) { - mfc_err("error in vb2_querybuf() for E(D)\n"); - return ret; - } - buf->m.planes[0].m.mem_offset += DST_QUEUE_OFF_BASE; - } else if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - ret = vb2_querybuf(&ctx->vq_src, buf); - if (ret != 0) { - mfc_err("error in vb2_querybuf() for E(S)\n"); - return ret; - } - } else { - mfc_err("invalid buf type\n"); - return -EINVAL; - } - return ret; -} - -/* Queue a buffer */ -static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -{ - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); - - if (ctx->state == MFCINST_ERROR) { - mfc_err("Call on QBUF after unrecoverable error\n"); - return -EIO; - } - if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - if (ctx->state == MFCINST_FINISHING) { - mfc_err("Call on QBUF after EOS command\n"); - return -EIO; - } - return vb2_qbuf(&ctx->vq_src, NULL, buf); - } else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - return vb2_qbuf(&ctx->vq_dst, NULL, buf); - } - return -EINVAL; -} - -/* Dequeue a buffer */ -static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -{ - const struct v4l2_event ev = { - .type = V4L2_EVENT_EOS - }; - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); - int ret; - - if (ctx->state == MFCINST_ERROR) { - mfc_err_limited("Call on DQBUF after unrecoverable error\n"); - return -EIO; - } - if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - ret = vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK); - } else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK); - if (ret == 0 && ctx->state == MFCINST_FINISHED - && list_empty(&ctx->vq_dst.done_list)) - v4l2_event_queue_fh(&ctx->fh, &ev); - } else { - ret = -EINVAL; - } - - return ret; -} - -/* Export DMA buffer */ -static int vidioc_expbuf(struct file *file, void *priv, - struct v4l2_exportbuffer *eb) -{ - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); - - if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) - return vb2_expbuf(&ctx->vq_src, eb); - if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - return vb2_expbuf(&ctx->vq_dst, eb); - return -EINVAL; -} - -/* Stream on */ -static int vidioc_streamon(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); - - if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) - return vb2_streamon(&ctx->vq_src, type); - else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - return vb2_streamon(&ctx->vq_dst, type); - return -EINVAL; -} - -/* Stream off, which equals to a pause */ -static int vidioc_streamoff(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); - - if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) - return vb2_streamoff(&ctx->vq_src, type); - else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - return vb2_streamoff(&ctx->vq_dst, type); - return -EINVAL; -} - -static inline int h264_level(enum v4l2_mpeg_video_h264_level lvl) -{ - static unsigned int t[V4L2_MPEG_VIDEO_H264_LEVEL_4_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, - }; - return t[lvl]; -} - -static inline int mpeg4_level(enum v4l2_mpeg_video_mpeg4_level lvl) -{ - static unsigned int t[V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 + 1] = { - /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 */ 0, - /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B */ 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 */ 7, - /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 */ 4, - /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 */ 5, - }; - return t[lvl]; -} - -static inline int hevc_level(enum v4l2_mpeg_video_hevc_level lvl) -{ - static unsigned int t[] = { - /* V4L2_MPEG_VIDEO_HEVC_LEVEL_1 */ 10, - /* V4L2_MPEG_VIDEO_HEVC_LEVEL_2 */ 20, - /* V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1 */ 21, - /* V4L2_MPEG_VIDEO_HEVC_LEVEL_3 */ 30, - /* V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1 */ 31, - /* V4L2_MPEG_VIDEO_HEVC_LEVEL_4 */ 40, - /* V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1 */ 41, - /* V4L2_MPEG_VIDEO_HEVC_LEVEL_5 */ 50, - /* V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1 */ 51, - /* V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2 */ 52, - /* V4L2_MPEG_VIDEO_HEVC_LEVEL_6 */ 60, - /* V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1 */ 61, - /* V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2 */ 62, - }; - return t[lvl]; -} - -static inline int vui_sar_idc(enum v4l2_mpeg_video_h264_vui_sar_idc sar) -{ - static unsigned int t[V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED + 1] = { - /* 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]; -} - -/* - * Update range of all HEVC quantization parameter controls that depend on the - * V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP controls. - */ -static void __enc_update_hevc_qp_ctrls_range(struct s5p_mfc_ctx *ctx, - int min, int max) -{ - static const int __hevc_qp_ctrls[] = { - V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP, - V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP, - V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP, - V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP, - V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP, - V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP, - V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP, - V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP, - V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP, - V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP, - }; - struct v4l2_ctrl *ctrl = NULL; - int i, j; - - for (i = 0; i < ARRAY_SIZE(__hevc_qp_ctrls); i++) { - for (j = 0; j < ARRAY_SIZE(ctx->ctrls); j++) { - if (ctx->ctrls[j]->id == __hevc_qp_ctrls[i]) { - ctrl = ctx->ctrls[j]; - break; - } - } - if (WARN_ON(!ctrl)) - break; - - __v4l2_ctrl_modify_range(ctrl, min, max, ctrl->step, min); - } -} - -static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl); - struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_enc_params *p = &ctx->enc_params; - int ret = 0; - - switch (ctrl->id) { - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - p->gop_size = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: - p->slice_mode = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: - p->slice_mb = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: - p->slice_bit = ctrl->val * 8; - break; - case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: - p->intra_refresh_mb = ctrl->val; - break; - case V4L2_CID_MPEG_MFC51_VIDEO_PADDING: - p->pad = ctrl->val; - break; - case V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV: - p->pad_luma = (ctrl->val >> 16) & 0xff; - p->pad_cb = (ctrl->val >> 8) & 0xff; - p->pad_cr = (ctrl->val >> 0) & 0xff; - break; - case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: - p->rc_frame = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_BITRATE: - p->rc_bitrate = ctrl->val; - break; - case V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF: - p->rc_reaction_coeff = ctrl->val; - break; - case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE: - ctx->force_frame_type = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: - ctx->force_frame_type = - V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME; - break; - case V4L2_CID_MPEG_VIDEO_VBV_SIZE: - p->vbv_size = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE: - p->mv_h_range = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: - p->mv_v_range = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: - p->codec.h264.cpb_size = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEADER_MODE: - p->seq_hdr_mode = ctrl->val; - break; - case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE: - case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: - p->frame_skip_mode = ctrl->val; - break; - case V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT: - p->fixed_target_bit = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - p->num_b_frame = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_PROFILE: - switch (ctrl->val) { - case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: - p->codec.h264.profile = - S5P_FIMV_ENC_PROFILE_H264_MAIN; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: - p->codec.h264.profile = - S5P_FIMV_ENC_PROFILE_H264_HIGH; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: - p->codec.h264.profile = - S5P_FIMV_ENC_PROFILE_H264_BASELINE; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: - if (IS_MFCV6_PLUS(dev)) - p->codec.h264.profile = - S5P_FIMV_ENC_PROFILE_H264_CONSTRAINED_BASELINE; - else - ret = -EINVAL; - break; - default: - ret = -EINVAL; - } - break; - case V4L2_CID_MPEG_VIDEO_H264_LEVEL: - p->codec.h264.level_v4l2 = ctrl->val; - p->codec.h264.level = h264_level(ctrl->val); - if (p->codec.h264.level < 0) { - mfc_err("Level number is wrong\n"); - ret = p->codec.h264.level; - } - break; - case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: - p->codec.mpeg4.level_v4l2 = ctrl->val; - p->codec.mpeg4.level = mpeg4_level(ctrl->val); - if (p->codec.mpeg4.level < 0) { - mfc_err("Level number is wrong\n"); - ret = p->codec.mpeg4.level; - } - break; - case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: - p->codec.h264.loop_filter_mode = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: - p->codec.h264.loop_filter_alpha = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: - p->codec.h264.loop_filter_beta = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: - p->codec.h264.entropy_mode = ctrl->val; - break; - case V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P: - p->codec.h264.num_ref_pic_4p = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: - p->codec.h264._8x8_transform = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: - p->rc_mb = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: - p->codec.h264.rc_frame_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: - p->codec.h264.rc_min_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: - p->codec.h264.rc_max_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: - p->codec.h264.rc_p_frame_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: - p->codec.h264.rc_b_frame_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: - case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: - p->codec.mpeg4.rc_frame_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: - case V4L2_CID_MPEG_VIDEO_H263_MIN_QP: - p->codec.mpeg4.rc_min_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: - case V4L2_CID_MPEG_VIDEO_H263_MAX_QP: - p->codec.mpeg4.rc_max_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: - case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: - p->codec.mpeg4.rc_p_frame_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: - case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: - p->codec.mpeg4.rc_b_frame_qp = ctrl->val; - break; - case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK: - p->codec.h264.rc_mb_dark = ctrl->val; - break; - case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH: - p->codec.h264.rc_mb_smooth = ctrl->val; - break; - case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC: - p->codec.h264.rc_mb_static = ctrl->val; - break; - case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY: - p->codec.h264.rc_mb_activity = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: - p->codec.h264.vui_sar = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: - p->codec.h264.vui_sar_idc = vui_sar_idc(ctrl->val); - break; - case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH: - p->codec.h264.vui_ext_sar_width = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT: - p->codec.h264.vui_ext_sar_height = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: - p->codec.h264.open_gop = !ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: - p->codec.h264.open_gop_size = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: - switch (ctrl->val) { - case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE: - p->codec.mpeg4.profile = - S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE; - break; - case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE: - p->codec.mpeg4.profile = - S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE; - break; - default: - ret = -EINVAL; - } - break; - case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: - p->codec.mpeg4.quarter_pixel = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: - p->codec.vp8.num_partitions = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4: - p->codec.vp8.imd_4x4 = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: - p->codec.vp8.num_ref = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL: - p->codec.vp8.filter_level = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS: - p->codec.vp8.filter_sharpness = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD: - p->codec.vp8.golden_frame_ref_period = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: - p->codec.vp8.golden_frame_sel = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP: - p->codec.vp8.rc_min_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP: - p->codec.vp8.rc_max_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP: - p->codec.vp8.rc_frame_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: - p->codec.vp8.rc_p_frame_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: - p->codec.vp8.profile = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP: - p->codec.hevc.rc_frame_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP: - p->codec.hevc.rc_p_frame_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP: - p->codec.hevc.rc_b_frame_qp = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION: - p->codec.hevc.rc_framerate = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP: - p->codec.hevc.rc_min_qp = ctrl->val; - __enc_update_hevc_qp_ctrls_range(ctx, ctrl->val, - p->codec.hevc.rc_max_qp); - break; - case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP: - p->codec.hevc.rc_max_qp = ctrl->val; - __enc_update_hevc_qp_ctrls_range(ctx, p->codec.hevc.rc_min_qp, - ctrl->val); - break; - case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: - p->codec.hevc.level_v4l2 = ctrl->val; - p->codec.hevc.level = hevc_level(ctrl->val); - break; - case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: - switch (ctrl->val) { - case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN: - p->codec.hevc.profile = - V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN; - break; - case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE: - p->codec.hevc.profile = - V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE; - break; - default: - ret = -EINVAL; - } - break; - case V4L2_CID_MPEG_VIDEO_HEVC_TIER: - p->codec.hevc.tier = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH: - p->codec.hevc.max_partition_depth = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES: - p->codec.hevc.num_refs_for_p = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: - p->codec.hevc.refreshtype = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED: - p->codec.hevc.const_intra_period_enable = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU: - p->codec.hevc.lossless_cu_enable = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT: - p->codec.hevc.wavefront_enable = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: - p->codec.hevc.loopfilter = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP: - p->codec.hevc.hier_qp_enable = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: - p->codec.hevc.hier_qp_type = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER: - p->codec.hevc.num_hier_layer = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP: - p->codec.hevc.hier_qp_layer[0] = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP: - p->codec.hevc.hier_qp_layer[1] = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP: - p->codec.hevc.hier_qp_layer[2] = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP: - p->codec.hevc.hier_qp_layer[3] = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP: - p->codec.hevc.hier_qp_layer[4] = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP: - p->codec.hevc.hier_qp_layer[5] = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP: - p->codec.hevc.hier_qp_layer[6] = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR: - p->codec.hevc.hier_bit_layer[0] = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR: - p->codec.hevc.hier_bit_layer[1] = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR: - p->codec.hevc.hier_bit_layer[2] = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR: - p->codec.hevc.hier_bit_layer[3] = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR: - p->codec.hevc.hier_bit_layer[4] = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR: - p->codec.hevc.hier_bit_layer[5] = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR: - p->codec.hevc.hier_bit_layer[6] = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB: - p->codec.hevc.general_pb_enable = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID: - p->codec.hevc.temporal_id_enable = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING: - p->codec.hevc.strong_intra_smooth = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT: - p->codec.hevc.intra_pu_split_disable = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION: - p->codec.hevc.tmv_prediction_disable = !ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1: - p->codec.hevc.max_num_merge_mv = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE: - p->codec.hevc.encoding_nostartcode_enable = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD: - p->codec.hevc.refreshperiod = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2: - p->codec.hevc.lf_beta_offset_div2 = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2: - p->codec.hevc.lf_tc_offset_div2 = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: - p->codec.hevc.size_of_length_field = ctrl->val; - break; - case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR: - p->codec.hevc.prepend_sps_pps_to_idr = ctrl->val; - break; - default: - v4l2_err(&dev->v4l2_dev, "Invalid control, id=%d, val=%d\n", - ctrl->id, ctrl->val); - ret = -EINVAL; - } - return ret; -} - -static int s5p_mfc_enc_g_v_ctrl(struct v4l2_ctrl *ctrl) -{ - struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl); - struct s5p_mfc_dev *dev = ctx->dev; - - switch (ctrl->id) { - case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: - if (ctx->state >= MFCINST_HEAD_PARSED && - ctx->state < MFCINST_ABORT) { - ctrl->val = ctx->pb_count; - break; - } else if (ctx->state != MFCINST_INIT) { - v4l2_err(&dev->v4l2_dev, "Encoding not initialised\n"); - return -EINVAL; - } - /* Should wait for the header to be produced */ - s5p_mfc_wait_for_done_ctx(ctx, - S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0); - if (ctx->state >= MFCINST_HEAD_PARSED && - ctx->state < MFCINST_ABORT) { - ctrl->val = ctx->pb_count; - } else { - v4l2_err(&dev->v4l2_dev, "Encoding not initialised\n"); - return -EINVAL; - } - break; - } - return 0; -} - -static const struct v4l2_ctrl_ops s5p_mfc_enc_ctrl_ops = { - .s_ctrl = s5p_mfc_enc_s_ctrl, - .g_volatile_ctrl = s5p_mfc_enc_g_v_ctrl, -}; - -static int vidioc_s_parm(struct file *file, void *priv, - struct v4l2_streamparm *a) -{ - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); - - if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - ctx->enc_params.rc_framerate_num = - a->parm.output.timeperframe.denominator; - ctx->enc_params.rc_framerate_denom = - a->parm.output.timeperframe.numerator; - } else { - mfc_err("Setting FPS is only possible for the output queue\n"); - return -EINVAL; - } - return 0; -} - -static int vidioc_g_parm(struct file *file, void *priv, - struct v4l2_streamparm *a) -{ - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); - - if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { - a->parm.output.timeperframe.denominator = - ctx->enc_params.rc_framerate_num; - a->parm.output.timeperframe.numerator = - ctx->enc_params.rc_framerate_denom; - } else { - mfc_err("Setting FPS is only possible for the output queue\n"); - return -EINVAL; - } - return 0; -} - -static int vidioc_encoder_cmd(struct file *file, void *priv, - struct v4l2_encoder_cmd *cmd) -{ - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); - struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_buf *buf; - unsigned long flags; - - switch (cmd->cmd) { - case V4L2_ENC_CMD_STOP: - if (cmd->flags != 0) - return -EINVAL; - - if (!ctx->vq_src.streaming) - return -EINVAL; - - spin_lock_irqsave(&dev->irqlock, flags); - if (list_empty(&ctx->src_queue)) { - mfc_debug(2, "EOS: empty src queue, entering finishing state\n"); - ctx->state = MFCINST_FINISHING; - if (s5p_mfc_ctx_ready(ctx)) - set_work_bit_irqsave(ctx); - spin_unlock_irqrestore(&dev->irqlock, flags); - s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); - } else { - mfc_debug(2, "EOS: marking last buffer of stream\n"); - buf = list_entry(ctx->src_queue.prev, - struct s5p_mfc_buf, list); - if (buf->flags & MFC_BUF_FLAG_USED) - ctx->state = MFCINST_FINISHING; - else - buf->flags |= MFC_BUF_FLAG_EOS; - spin_unlock_irqrestore(&dev->irqlock, flags); - } - break; - default: - return -EINVAL; - - } - return 0; -} - -static int vidioc_subscribe_event(struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub) -{ - switch (sub->type) { - case V4L2_EVENT_EOS: - return v4l2_event_subscribe(fh, sub, 2, NULL); - default: - return -EINVAL; - } -} - -static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out, - .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt, - .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt, - .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt, - .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt, - .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt, - .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_expbuf = vidioc_expbuf, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, - .vidioc_s_parm = vidioc_s_parm, - .vidioc_g_parm = vidioc_g_parm, - .vidioc_encoder_cmd = vidioc_encoder_cmd, - .vidioc_subscribe_event = vidioc_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, -}; - -static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb) -{ - int i; - - if (!fmt) - return -EINVAL; - if (fmt->num_planes != vb->num_planes) { - mfc_err("invalid plane number for the format\n"); - return -EINVAL; - } - for (i = 0; i < fmt->num_planes; i++) { - dma_addr_t dma = vb2_dma_contig_plane_dma_addr(vb, i); - if (!dma) { - mfc_err("failed to get plane cookie\n"); - return -EINVAL; - } - mfc_debug(2, "index: %d, plane[%d] cookie: %pad\n", - vb->index, i, &dma); - } - return 0; -} - -static int s5p_mfc_queue_setup(struct vb2_queue *vq, - unsigned int *buf_count, unsigned int *plane_count, - unsigned int psize[], struct device *alloc_devs[]) -{ - struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); - struct s5p_mfc_dev *dev = ctx->dev; - - if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - if (ctx->state != MFCINST_GOT_INST) { - mfc_err("invalid state: %d\n", ctx->state); - return -EINVAL; - } - - if (ctx->dst_fmt) - *plane_count = ctx->dst_fmt->num_planes; - else - *plane_count = MFC_ENC_CAP_PLANE_COUNT; - if (*buf_count < 1) - *buf_count = 1; - if (*buf_count > MFC_MAX_BUFFERS) - *buf_count = MFC_MAX_BUFFERS; - psize[0] = ctx->enc_dst_buf_size; - alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX]; - } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - if (ctx->src_fmt) - *plane_count = ctx->src_fmt->num_planes; - else - *plane_count = MFC_ENC_OUT_PLANE_COUNT; - - if (*buf_count < 1) - *buf_count = 1; - if (*buf_count > MFC_MAX_BUFFERS) - *buf_count = MFC_MAX_BUFFERS; - - psize[0] = ctx->luma_size; - psize[1] = ctx->chroma_size; - - if (IS_MFCV6_PLUS(dev)) { - alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX]; - alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX]; - } else { - alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX]; - alloc_devs[1] = ctx->dev->mem_dev[BANK_R_CTX]; - } - } else { - mfc_err("invalid queue type: %d\n", vq->type); - return -EINVAL; - } - return 0; -} - -static int s5p_mfc_buf_init(struct vb2_buffer *vb) -{ - struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); - struct vb2_queue *vq = vb->vb2_queue; - struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); - unsigned int i; - int ret; - - if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - ret = check_vb_with_fmt(ctx->dst_fmt, vb); - if (ret < 0) - return ret; - i = vb->index; - ctx->dst_bufs[i].b = vbuf; - ctx->dst_bufs[i].cookie.stream = - vb2_dma_contig_plane_dma_addr(vb, 0); - ctx->dst_bufs_cnt++; - } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - ret = check_vb_with_fmt(ctx->src_fmt, vb); - if (ret < 0) - return ret; - i = vb->index; - ctx->src_bufs[i].b = vbuf; - ctx->src_bufs[i].cookie.raw.luma = - vb2_dma_contig_plane_dma_addr(vb, 0); - ctx->src_bufs[i].cookie.raw.chroma = - vb2_dma_contig_plane_dma_addr(vb, 1); - ctx->src_bufs_cnt++; - } else { - mfc_err("invalid queue type: %d\n", vq->type); - return -EINVAL; - } - return 0; -} - -static int s5p_mfc_buf_prepare(struct vb2_buffer *vb) -{ - struct vb2_queue *vq = vb->vb2_queue; - struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); - int ret; - - if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - ret = check_vb_with_fmt(ctx->dst_fmt, vb); - if (ret < 0) - return ret; - mfc_debug(2, "plane size: %ld, dst size: %zu\n", - vb2_plane_size(vb, 0), ctx->enc_dst_buf_size); - if (vb2_plane_size(vb, 0) < ctx->enc_dst_buf_size) { - mfc_err("plane size is too small for capture\n"); - return -EINVAL; - } - } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - ret = check_vb_with_fmt(ctx->src_fmt, vb); - if (ret < 0) - return ret; - mfc_debug(2, "plane size: %ld, luma size: %d\n", - vb2_plane_size(vb, 0), ctx->luma_size); - mfc_debug(2, "plane size: %ld, chroma size: %d\n", - vb2_plane_size(vb, 1), ctx->chroma_size); - if (vb2_plane_size(vb, 0) < ctx->luma_size || - vb2_plane_size(vb, 1) < ctx->chroma_size) { - mfc_err("plane size is too small for output\n"); - return -EINVAL; - } - } else { - mfc_err("invalid queue type: %d\n", vq->type); - return -EINVAL; - } - return 0; -} - -static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count) -{ - struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv); - struct s5p_mfc_dev *dev = ctx->dev; - - if (IS_MFCV6_PLUS(dev) && - (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) { - - if ((ctx->state == MFCINST_GOT_INST) && - (dev->curr_ctx == ctx->num) && dev->hw_lock) { - s5p_mfc_wait_for_done_ctx(ctx, - S5P_MFC_R2H_CMD_SEQ_DONE_RET, - 0); - } - - if (ctx->src_bufs_cnt < ctx->pb_count) { - mfc_err("Need minimum %d OUTPUT buffers\n", - ctx->pb_count); - return -ENOBUFS; - } - } - - /* If context is ready then dev = work->data;schedule it to run */ - if (s5p_mfc_ctx_ready(ctx)) - set_work_bit_irqsave(ctx); - s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); - - return 0; -} - -static void s5p_mfc_stop_streaming(struct vb2_queue *q) -{ - unsigned long flags; - struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv); - struct s5p_mfc_dev *dev = ctx->dev; - - if ((ctx->state == MFCINST_FINISHING || - ctx->state == MFCINST_RUNNING) && - dev->curr_ctx == ctx->num && dev->hw_lock) { - ctx->state = MFCINST_ABORT; - s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_FRAME_DONE_RET, - 0); - } - ctx->state = MFCINST_FINISHED; - spin_lock_irqsave(&dev->irqlock, flags); - if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst); - INIT_LIST_HEAD(&ctx->dst_queue); - ctx->dst_queue_cnt = 0; - } - if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - cleanup_ref_queue(ctx); - s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src); - INIT_LIST_HEAD(&ctx->src_queue); - ctx->src_queue_cnt = 0; - } - spin_unlock_irqrestore(&dev->irqlock, flags); -} - -static void s5p_mfc_buf_queue(struct vb2_buffer *vb) -{ - struct vb2_queue *vq = vb->vb2_queue; - struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); - struct s5p_mfc_dev *dev = ctx->dev; - unsigned long flags; - struct s5p_mfc_buf *mfc_buf; - - if (ctx->state == MFCINST_ERROR) { - vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); - cleanup_ref_queue(ctx); - return; - } - if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - mfc_buf = &ctx->dst_bufs[vb->index]; - mfc_buf->flags &= ~MFC_BUF_FLAG_USED; - /* Mark destination as available for use by MFC */ - spin_lock_irqsave(&dev->irqlock, flags); - list_add_tail(&mfc_buf->list, &ctx->dst_queue); - ctx->dst_queue_cnt++; - spin_unlock_irqrestore(&dev->irqlock, flags); - } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - mfc_buf = &ctx->src_bufs[vb->index]; - mfc_buf->flags &= ~MFC_BUF_FLAG_USED; - spin_lock_irqsave(&dev->irqlock, flags); - list_add_tail(&mfc_buf->list, &ctx->src_queue); - ctx->src_queue_cnt++; - spin_unlock_irqrestore(&dev->irqlock, flags); - } else { - mfc_err("unsupported buffer type (%d)\n", vq->type); - } - if (s5p_mfc_ctx_ready(ctx)) - set_work_bit_irqsave(ctx); - s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); -} - -static struct vb2_ops s5p_mfc_enc_qops = { - .queue_setup = s5p_mfc_queue_setup, - .wait_prepare = vb2_ops_wait_prepare, - .wait_finish = vb2_ops_wait_finish, - .buf_init = s5p_mfc_buf_init, - .buf_prepare = s5p_mfc_buf_prepare, - .start_streaming = s5p_mfc_start_streaming, - .stop_streaming = s5p_mfc_stop_streaming, - .buf_queue = s5p_mfc_buf_queue, -}; - -const struct s5p_mfc_codec_ops *get_enc_codec_ops(void) -{ - return &encoder_codec_ops; -} - -struct vb2_ops *get_enc_queue_ops(void) -{ - return &s5p_mfc_enc_qops; -} - -const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void) -{ - return &s5p_mfc_enc_ioctl_ops; -} - -#define IS_MFC51_PRIV(x) ((V4L2_CTRL_ID2WHICH(x) == V4L2_CTRL_CLASS_CODEC) \ - && V4L2_CTRL_DRIVER_PRIV(x)) - -int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx) -{ - struct v4l2_ctrl_config cfg; - int i; - - v4l2_ctrl_handler_init(&ctx->ctrl_handler, NUM_CTRLS); - if (ctx->ctrl_handler.error) { - mfc_err("v4l2_ctrl_handler_init failed\n"); - return ctx->ctrl_handler.error; - } - for (i = 0; i < NUM_CTRLS; i++) { - if (IS_MFC51_PRIV(controls[i].id)) { - memset(&cfg, 0, sizeof(struct v4l2_ctrl_config)); - cfg.ops = &s5p_mfc_enc_ctrl_ops; - cfg.id = controls[i].id; - cfg.min = controls[i].minimum; - cfg.max = controls[i].maximum; - cfg.def = controls[i].default_value; - cfg.name = controls[i].name; - cfg.type = controls[i].type; - cfg.flags = 0; - - if (cfg.type == V4L2_CTRL_TYPE_MENU) { - cfg.step = 0; - cfg.menu_skip_mask = controls[i].menu_skip_mask; - cfg.qmenu = mfc51_get_menu(cfg.id); - } else { - cfg.step = controls[i].step; - cfg.menu_skip_mask = 0; - } - ctx->ctrls[i] = v4l2_ctrl_new_custom(&ctx->ctrl_handler, - &cfg, NULL); - } else { - if ((controls[i].type == V4L2_CTRL_TYPE_MENU) || - (controls[i].type == - V4L2_CTRL_TYPE_INTEGER_MENU)) { - ctx->ctrls[i] = v4l2_ctrl_new_std_menu( - &ctx->ctrl_handler, - &s5p_mfc_enc_ctrl_ops, controls[i].id, - controls[i].maximum, 0, - controls[i].default_value); - } else { - ctx->ctrls[i] = v4l2_ctrl_new_std( - &ctx->ctrl_handler, - &s5p_mfc_enc_ctrl_ops, controls[i].id, - controls[i].minimum, - controls[i].maximum, controls[i].step, - controls[i].default_value); - } - } - if (ctx->ctrl_handler.error) { - mfc_err("Adding control (%d) failed\n", i); - return ctx->ctrl_handler.error; - } - if (controls[i].is_volatile && ctx->ctrls[i]) - ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE; - } - v4l2_ctrl_handler_setup(&ctx->ctrl_handler); - return 0; -} - -void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx) -{ - int i; - - v4l2_ctrl_handler_free(&ctx->ctrl_handler); - for (i = 0; i < NUM_CTRLS; i++) - ctx->ctrls[i] = NULL; -} - -void s5p_mfc_enc_init(struct s5p_mfc_ctx *ctx) -{ - struct v4l2_format f; - f.fmt.pix_mp.pixelformat = DEF_SRC_FMT_ENC; - ctx->src_fmt = find_format(&f, MFC_FMT_RAW); - f.fmt.pix_mp.pixelformat = DEF_DST_FMT_ENC; - ctx->dst_fmt = find_format(&f, MFC_FMT_ENC); -} |