linux/drivers/media/platform/qcom/venus/venc_ctrls.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
   3 * Copyright (C) 2017 Linaro Ltd.
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 and
   7 * only version 2 as published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 */
  15#include <linux/types.h>
  16#include <media/v4l2-ctrls.h>
  17
  18#include "core.h"
  19#include "venc.h"
  20
  21#define BITRATE_MIN             32000
  22#define BITRATE_MAX             160000000
  23#define BITRATE_DEFAULT         1000000
  24#define BITRATE_DEFAULT_PEAK    (BITRATE_DEFAULT * 2)
  25#define BITRATE_STEP            100
  26#define SLICE_BYTE_SIZE_MAX     1024
  27#define SLICE_BYTE_SIZE_MIN     1024
  28#define SLICE_MB_SIZE_MAX       300
  29#define INTRA_REFRESH_MBS_MAX   300
  30#define AT_SLICE_BOUNDARY       \
  31        V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
  32
  33static int venc_calc_bpframes(u32 gop_size, u32 conseq_b, u32 *bf, u32 *pf)
  34{
  35        u32 half = (gop_size - 1) >> 1;
  36        u32 b, p, ratio;
  37        bool found = false;
  38
  39        if (!gop_size)
  40                return -EINVAL;
  41
  42        *bf = *pf = 0;
  43
  44        if (!conseq_b) {
  45                *pf = gop_size -  1;
  46                return 0;
  47        }
  48
  49        b = p = half;
  50
  51        for (; b <= gop_size - 1; b++, p--) {
  52                if (b % p)
  53                        continue;
  54
  55                ratio = b / p;
  56
  57                if (ratio == conseq_b) {
  58                        found = true;
  59                        break;
  60                }
  61
  62                if (ratio > conseq_b)
  63                        break;
  64        }
  65
  66        if (!found)
  67                return -EINVAL;
  68
  69        if (b + p + 1 != gop_size)
  70                return -EINVAL;
  71
  72        *bf = b;
  73        *pf = p;
  74
  75        return 0;
  76}
  77
  78static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
  79{
  80        struct venus_inst *inst = ctrl_to_inst(ctrl);
  81        struct venc_controls *ctr = &inst->controls.enc;
  82        u32 bframes;
  83        int ret;
  84
  85        switch (ctrl->id) {
  86        case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
  87                ctr->bitrate_mode = ctrl->val;
  88                break;
  89        case V4L2_CID_MPEG_VIDEO_BITRATE:
  90                ctr->bitrate = ctrl->val;
  91                break;
  92        case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
  93                ctr->bitrate_peak = ctrl->val;
  94                break;
  95        case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
  96                ctr->h264_entropy_mode = ctrl->val;
  97                break;
  98        case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
  99                ctr->profile.mpeg4 = ctrl->val;
 100                break;
 101        case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
 102                ctr->profile.h264 = ctrl->val;
 103                break;
 104        case V4L2_CID_MPEG_VIDEO_VPX_PROFILE:
 105                ctr->profile.vpx = ctrl->val;
 106                break;
 107        case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
 108                ctr->level.mpeg4 = ctrl->val;
 109                break;
 110        case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
 111                ctr->level.h264 = ctrl->val;
 112                break;
 113        case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
 114                ctr->h264_i_qp = ctrl->val;
 115                break;
 116        case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
 117                ctr->h264_p_qp = ctrl->val;
 118                break;
 119        case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
 120                ctr->h264_b_qp = ctrl->val;
 121                break;
 122        case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
 123                ctr->h264_min_qp = ctrl->val;
 124                break;
 125        case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
 126                ctr->h264_max_qp = ctrl->val;
 127                break;
 128        case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
 129                ctr->multi_slice_mode = ctrl->val;
 130                break;
 131        case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
 132                ctr->multi_slice_max_bytes = ctrl->val;
 133                break;
 134        case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
 135                ctr->multi_slice_max_mb = ctrl->val;
 136                break;
 137        case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
 138                ctr->h264_loop_filter_alpha = ctrl->val;
 139                break;
 140        case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
 141                ctr->h264_loop_filter_beta = ctrl->val;
 142                break;
 143        case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
 144                ctr->h264_loop_filter_mode = ctrl->val;
 145                break;
 146        case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
 147                ctr->header_mode = ctrl->val;
 148                break;
 149        case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
 150                break;
 151        case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
 152                ret = venc_calc_bpframes(ctrl->val, ctr->num_b_frames, &bframes,
 153                                         &ctr->num_p_frames);
 154                if (ret)
 155                        return ret;
 156
 157                ctr->gop_size = ctrl->val;
 158                break;
 159        case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
 160                ctr->h264_i_period = ctrl->val;
 161                break;
 162        case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP:
 163                ctr->vp8_min_qp = ctrl->val;
 164                break;
 165        case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP:
 166                ctr->vp8_max_qp = ctrl->val;
 167                break;
 168        case V4L2_CID_MPEG_VIDEO_B_FRAMES:
 169                ret = venc_calc_bpframes(ctr->gop_size, ctrl->val, &bframes,
 170                                         &ctr->num_p_frames);
 171                if (ret)
 172                        return ret;
 173
 174                ctr->num_b_frames = bframes;
 175                break;
 176        default:
 177                return -EINVAL;
 178        }
 179
 180        return 0;
 181}
 182
 183static const struct v4l2_ctrl_ops venc_ctrl_ops = {
 184        .s_ctrl = venc_op_s_ctrl,
 185};
 186
 187int venc_ctrl_init(struct venus_inst *inst)
 188{
 189        int ret;
 190
 191        ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 27);
 192        if (ret)
 193                return ret;
 194
 195        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 196                V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
 197                V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
 198                ~((1 << V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
 199                  (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)),
 200                V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
 201
 202        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 203                V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
 204                V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
 205                0, V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC);
 206
 207        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 208                V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
 209                V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY,
 210                ~((1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) |
 211                  (1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)),
 212                V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE);
 213
 214        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 215                V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
 216                V4L2_MPEG_VIDEO_MPEG4_LEVEL_5,
 217                0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0);
 218
 219        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 220                V4L2_CID_MPEG_VIDEO_H264_PROFILE,
 221                V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
 222                ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
 223                  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
 224                  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
 225                  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
 226                  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH) |
 227                  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH)),
 228                V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
 229
 230        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 231                V4L2_CID_MPEG_VIDEO_H264_LEVEL,
 232                V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
 233                0, V4L2_MPEG_VIDEO_H264_LEVEL_1_0);
 234
 235        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 236                V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
 237                AT_SLICE_BOUNDARY,
 238                0, V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED);
 239
 240        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 241                V4L2_CID_MPEG_VIDEO_HEADER_MODE,
 242                V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
 243                1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
 244                V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE);
 245
 246        v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
 247                V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
 248                V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES,
 249                0, V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE);
 250
 251        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 252                V4L2_CID_MPEG_VIDEO_BITRATE, BITRATE_MIN, BITRATE_MAX,
 253                BITRATE_STEP, BITRATE_DEFAULT);
 254
 255        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 256                V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, BITRATE_MIN, BITRATE_MAX,
 257                BITRATE_STEP, BITRATE_DEFAULT_PEAK);
 258
 259        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 260                V4L2_CID_MPEG_VIDEO_VPX_PROFILE, 0, 3, 1, 0);
 261
 262        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 263                V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 26);
 264
 265        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 266                V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 28);
 267
 268        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 269                V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, 1, 51, 1, 30);
 270
 271        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 272                V4L2_CID_MPEG_VIDEO_H264_MIN_QP, 1, 51, 1, 1);
 273
 274        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 275                V4L2_CID_MPEG_VIDEO_H264_MAX_QP, 1, 51, 1, 51);
 276
 277        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 278                V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES, SLICE_BYTE_SIZE_MIN,
 279                SLICE_BYTE_SIZE_MAX, 1, SLICE_BYTE_SIZE_MIN);
 280
 281        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 282                V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, 1,
 283                SLICE_MB_SIZE_MAX, 1, 1);
 284
 285        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 286                V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, -6, 6, 1, 0);
 287
 288        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 289                V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, -6, 6, 1, 0);
 290
 291        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 292                V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB,
 293                0, INTRA_REFRESH_MBS_MAX, 1, 0);
 294
 295        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 296                V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, (1 << 16) - 1, 1, 12);
 297
 298        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 299                V4L2_CID_MPEG_VIDEO_VPX_MIN_QP, 1, 128, 1, 1);
 300
 301        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 302                V4L2_CID_MPEG_VIDEO_VPX_MAX_QP, 1, 128, 1, 128);
 303
 304        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 305                V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0);
 306
 307        v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
 308                V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, 0, (1 << 16) - 1, 1, 0);
 309
 310        ret = inst->ctrl_handler.error;
 311        if (ret)
 312                goto err;
 313
 314        ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
 315        if (ret)
 316                goto err;
 317
 318        return 0;
 319err:
 320        v4l2_ctrl_handler_free(&inst->ctrl_handler);
 321        return ret;
 322}
 323
 324void venc_ctrl_deinit(struct venus_inst *inst)
 325{
 326        v4l2_ctrl_handler_free(&inst->ctrl_handler);
 327}
 328