linux/drivers/media/platform/qcom/venus/venc_ctrls.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
   4 * Copyright (C) 2017 Linaro Ltd.
   5 */
   6#include <linux/types.h>
   7#include <media/v4l2-ctrls.h>
   8
   9#include "core.h"
  10#include "venc.h"
  11
  12#define BITRATE_MIN             32000
  13#define BITRATE_MAX             160000000
  14#define BITRATE_DEFAULT         1000000
  15#define BITRATE_DEFAULT_PEAK    (BITRATE_DEFAULT * 2)
  16#define BITRATE_STEP            100
  17#define SLICE_BYTE_SIZE_MAX     1024
  18#define SLICE_BYTE_SIZE_MIN     1024
  19#define SLICE_MB_SIZE_MAX       300
  20#define INTRA_REFRESH_MBS_MAX   300
  21#define AT_SLICE_BOUNDARY       \
  22        V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
  23
  24static int venc_calc_bpframes(u32 gop_size, u32 conseq_b, u32 *bf, u32 *pf)
  25{
  26        u32 half = (gop_size - 1) >> 1;
  27        u32 b, p, ratio;
  28        bool found = false;
  29
  30        if (!gop_size)
  31                return -EINVAL;
  32
  33        *bf = *pf = 0;
  34
  35        if (!conseq_b) {
  36                *pf = gop_size -  1;
  37                return 0;
  38        }
  39
  40        b = p = half;
  41
  42        for (; b <= gop_size - 1; b++, p--) {
  43                if (b % p)
  44                        continue;
  45
  46                ratio = b / p;
  47
  48                if (ratio == conseq_b) {
  49                        found = true;
  50                        break;
  51                }
  52
  53                if (ratio > conseq_b)
  54                        break;
  55        }
  56
  57        if (!found)
  58                return -EINVAL;
  59
  60        if (b + p + 1 != gop_size)
  61                return -EINVAL;
  62
  63        *bf = b;
  64        *pf = p;
  65
  66        return 0;
  67}
  68
  69static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
  70{
  71        struct venus_inst *inst = ctrl_to_inst(ctrl);
  72        struct venc_controls *ctr = &inst->controls.enc;
  73        struct hfi_enable en = { .enable = 1 };
  74        struct hfi_bitrate brate;
  75        u32 bframes;
  76        u32 ptype;
  77        int ret;
  78
  79        switch (ctrl->id) {
  80        case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
  81                ctr->bitrate_mode = ctrl->val;
  82                break;
  83        case V4L2_CID_MPEG_VIDEO_BITRATE:
  84                ctr->bitrate = ctrl->val;
  85                mutex_lock(&inst->lock);
  86                if (inst->streamon_out && inst->streamon_cap) {
  87                        ptype = HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE;
  88                        brate.bitrate = ctr->bitrate;
  89                        brate.layer_id = 0;
  90
  91                        ret = hfi_session_set_property(inst, ptype, &brate);
  92                        if (ret) {
  93                                mutex_unlock(&inst->lock);
  94                                return ret;
  95                        }
  96                }
  97                mutex_unlock(&inst->lock);
  98                break;
  99        case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
 100                ctr->bitrate_peak = ctrl->val;
 101                break;
 102        case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
 103                ctr->h264_entropy_mode = ctrl->val;
 104                break;
 105        case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
 106                ctr->profile.mpeg4 = ctrl->val;
 107                break;
 108        case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
 109                ctr->profile.h264 = ctrl->val;
 110                break;
 111        case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
 112                ctr->profile.hevc = ctrl->val;
 113                break;
 114        case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:
 115                ctr->profile.vpx = ctrl->val;
 116                break;
 117        case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
 118                ctr->level.mpeg4 = ctrl->val;
 119                break;
 120        case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
 121                ctr->level.h264 = ctrl->val;
 122                break;
 123        case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
 124                ctr->level.hevc = ctrl->val;
 125                break;
 126        case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
 127                ctr->h264_i_qp = ctrl->val;
 128                break;
 129        case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
 130                ctr->h264_p_qp = ctrl->val;
 131                break;
 132        case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
 133                ctr->h264_b_qp = ctrl->val;
 134                break;
 135        case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
 136                ctr->h264_min_qp = ctrl->val;
 137                break;
 138        case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
 139                ctr->h264_max_qp = ctrl->val;
 140                break;
 141        case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
 142                ctr->multi_slice_mode = ctrl->val;
 143                break;
 144        case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
 145                ctr->multi_slice_max_bytes = ctrl->val;
 146                break;
 147        case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
 148                ctr->multi_slice_max_mb = ctrl->val;
 149                break;
 150        case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
 151                ctr->h264_loop_filter_alpha = ctrl->val;
 152                break;
 153        case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
 154                ctr->h264_loop_filter_beta = ctrl->val;
 155                break;
 156        case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
 157                ctr->h264_loop_filter_mode = ctrl->val;
 158                break;
 159        case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
 160                ctr->header_mode = ctrl->val;
 161                break;
 162        case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
 163                break;
 164        case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
 165                ret = venc_calc_bpframes(ctrl->val, ctr->num_b_frames, &bframes,
 166                                         &ctr->num_p_frames);
 167                if (ret)
 168                        return ret;
 169
 170                ctr->gop_size = ctrl->val;
 171                break;
 172        case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
 173                ctr->h264_i_period = ctrl->val;
 174                break;
 175        case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP:
 176                ctr->vp8_min_qp = ctrl->val;
 177                break;
 178        case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP:
 179                ctr->vp8_max_qp = ctrl->val;
 180                break;
 181        case V4L2_CID_MPEG_VIDEO_B_FRAMES:
 182                ret = venc_calc_bpframes(ctr->gop_size, ctrl->val, &bframes,
 183                                         &ctr->num_p_frames);
 184                if (ret)
 185                        return ret;
 186
 187                ctr->num_b_frames = bframes;
 188                break;
 189        case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
 190                mutex_lock(&inst->lock);
 191                if (inst->streamon_out && inst->streamon_cap) {
 192                        ptype = HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME;
 193                        ret = hfi_session_set_property(inst, ptype, &en);
 194
 195                        if (ret) {
 196                                mutex_unlock(&inst->lock);
 197                                return ret;
 198                        }
 199                }
 200                mutex_unlock(&inst->lock);
 201                break;
 202        case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
 203                ctr->rc_enable = ctrl->val;
 204                break;
 205        default:
 206                return -EINVAL;
 207        }
 208
 209        return 0;
 210}
 211
 212static const struct v4l2_ctrl_ops venc_ctrl_ops = {
 213        .s_ctrl = venc_op_s_ctrl,
 214};
 215
 216int venc_ctrl_init(struct venus_inst *inst)
 217{
 218        int ret;
 219
 220        ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 31);
 221        if (ret)
 222                return ret;
 223
 224        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 225                V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
 226                V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
 227                ~((1 << V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
 228                  (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)),
 229                V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
 230
 231        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 232                V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
 233                V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
 234                0, V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC);
 235
 236        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 237                V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
 238                V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY,
 239                ~((1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) |
 240                  (1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)),
 241                V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE);
 242
 243        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 244                V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
 245                V4L2_MPEG_VIDEO_MPEG4_LEVEL_5,
 246                0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0);
 247
 248        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 249                V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
 250                V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
 251                ~((1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
 252                  (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE) |
 253                  (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10)),
 254                V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN);
 255
 256        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 257                V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
 258                V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
 259                0, V4L2_MPEG_VIDEO_HEVC_LEVEL_1);
 260
 261        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 262                V4L2_CID_MPEG_VIDEO_H264_PROFILE,
 263                V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
 264                ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
 265                  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
 266                  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
 267                  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
 268                  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH) |
 269                  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH)),
 270                V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
 271
 272        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 273                V4L2_CID_MPEG_VIDEO_H264_LEVEL,
 274                V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
 275                0, V4L2_MPEG_VIDEO_H264_LEVEL_1_0);
 276
 277        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 278                V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
 279                AT_SLICE_BOUNDARY,
 280                0, V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED);
 281
 282        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 283                V4L2_CID_MPEG_VIDEO_HEADER_MODE,
 284                V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
 285                1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
 286                V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE);
 287
 288        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 289                V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
 290                V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES,
 291                0, V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE);
 292
 293        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 294                V4L2_CID_MPEG_VIDEO_VP8_PROFILE,
 295                V4L2_MPEG_VIDEO_VP8_PROFILE_3,
 296                0, V4L2_MPEG_VIDEO_VP8_PROFILE_0);
 297
 298        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 299                V4L2_CID_MPEG_VIDEO_BITRATE, BITRATE_MIN, BITRATE_MAX,
 300                BITRATE_STEP, BITRATE_DEFAULT);
 301
 302        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 303                V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, BITRATE_MIN, BITRATE_MAX,
 304                BITRATE_STEP, BITRATE_DEFAULT_PEAK);
 305
 306        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 307                V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 26);
 308
 309        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 310                V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 28);
 311
 312        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 313                V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, 1, 51, 1, 30);
 314
 315        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 316                V4L2_CID_MPEG_VIDEO_H264_MIN_QP, 1, 51, 1, 1);
 317
 318        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 319                V4L2_CID_MPEG_VIDEO_H264_MAX_QP, 1, 51, 1, 51);
 320
 321        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 322                V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES, SLICE_BYTE_SIZE_MIN,
 323                SLICE_BYTE_SIZE_MAX, 1, SLICE_BYTE_SIZE_MIN);
 324
 325        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 326                V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, 1,
 327                SLICE_MB_SIZE_MAX, 1, 1);
 328
 329        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 330                V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, -6, 6, 1, 0);
 331
 332        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 333                V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, -6, 6, 1, 0);
 334
 335        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 336                V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB,
 337                0, INTRA_REFRESH_MBS_MAX, 1, 0);
 338
 339        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 340                V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, (1 << 16) - 1, 1, 30);
 341
 342        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 343                V4L2_CID_MPEG_VIDEO_VPX_MIN_QP, 1, 128, 1, 1);
 344
 345        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 346                V4L2_CID_MPEG_VIDEO_VPX_MAX_QP, 1, 128, 1, 128);
 347
 348        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 349                V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0);
 350
 351        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 352                V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, 0, (1 << 16) - 1, 1, 0);
 353
 354        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 355                          V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 0, 0, 0, 0);
 356
 357        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 358                          V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, 0, 1, 1, 1);
 359
 360        ret = inst->ctrl_handler.error;
 361        if (ret)
 362                goto err;
 363
 364        ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
 365        if (ret)
 366                goto err;
 367
 368        return 0;
 369err:
 370        v4l2_ctrl_handler_free(&inst->ctrl_handler);
 371        return ret;
 372}
 373
 374void venc_ctrl_deinit(struct venus_inst *inst)
 375{
 376        v4l2_ctrl_handler_free(&inst->ctrl_handler);
 377}
 378