root/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. h264_read_reg
  2. h264_get_profile
  3. h264_get_level
  4. h264_enc_free_work_buf
  5. h264_enc_alloc_work_buf
  6. h264_enc_wait_venc_done
  7. h264_encode_sps
  8. h264_encode_pps
  9. h264_encode_header
  10. h264_encode_frame
  11. h264_encode_filler
  12. h264_enc_init
  13. h264_enc_encode
  14. h264_enc_set_param
  15. h264_enc_deinit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (c) 2016 MediaTek Inc.
   4  * Author: Jungchang Tsao <jungchang.tsao@mediatek.com>
   5  *         Daniel Hsiao <daniel.hsiao@mediatek.com>
   6  *         PoChun Lin <pochun.lin@mediatek.com>
   7  */
   8 
   9 #include <linux/interrupt.h>
  10 #include <linux/kernel.h>
  11 #include <linux/slab.h>
  12 
  13 #include "../mtk_vcodec_drv.h"
  14 #include "../mtk_vcodec_util.h"
  15 #include "../mtk_vcodec_intr.h"
  16 #include "../mtk_vcodec_enc.h"
  17 #include "../mtk_vcodec_enc_pm.h"
  18 #include "../venc_drv_base.h"
  19 #include "../venc_ipi_msg.h"
  20 #include "../venc_vpu_if.h"
  21 #include "mtk_vpu.h"
  22 
  23 static const char h264_filler_marker[] = {0x0, 0x0, 0x0, 0x1, 0xc};
  24 
  25 #define H264_FILLER_MARKER_SIZE ARRAY_SIZE(h264_filler_marker)
  26 #define VENC_PIC_BITSTREAM_BYTE_CNT 0x0098
  27 
  28 /*
  29  * enum venc_h264_vpu_work_buf - h264 encoder buffer index
  30  */
  31 enum venc_h264_vpu_work_buf {
  32         VENC_H264_VPU_WORK_BUF_RC_INFO,
  33         VENC_H264_VPU_WORK_BUF_RC_CODE,
  34         VENC_H264_VPU_WORK_BUF_REC_LUMA,
  35         VENC_H264_VPU_WORK_BUF_REC_CHROMA,
  36         VENC_H264_VPU_WORK_BUF_REF_LUMA,
  37         VENC_H264_VPU_WORK_BUF_REF_CHROMA,
  38         VENC_H264_VPU_WORK_BUF_MV_INFO_1,
  39         VENC_H264_VPU_WORK_BUF_MV_INFO_2,
  40         VENC_H264_VPU_WORK_BUF_SKIP_FRAME,
  41         VENC_H264_VPU_WORK_BUF_MAX,
  42 };
  43 
  44 /*
  45  * enum venc_h264_bs_mode - for bs_mode argument in h264_enc_vpu_encode
  46  */
  47 enum venc_h264_bs_mode {
  48         H264_BS_MODE_SPS,
  49         H264_BS_MODE_PPS,
  50         H264_BS_MODE_FRAME,
  51 };
  52 
  53 /*
  54  * struct venc_h264_vpu_config - Structure for h264 encoder configuration
  55  *                               AP-W/R : AP is writer/reader on this item
  56  *                               VPU-W/R: VPU is write/reader on this item
  57  * @input_fourcc: input fourcc
  58  * @bitrate: target bitrate (in bps)
  59  * @pic_w: picture width. Picture size is visible stream resolution, in pixels,
  60  *         to be used for display purposes; must be smaller or equal to buffer
  61  *         size.
  62  * @pic_h: picture height
  63  * @buf_w: buffer width. Buffer size is stream resolution in pixels aligned to
  64  *         hardware requirements.
  65  * @buf_h: buffer height
  66  * @gop_size: group of picture size (idr frame)
  67  * @intra_period: intra frame period
  68  * @framerate: frame rate in fps
  69  * @profile: as specified in standard
  70  * @level: as specified in standard
  71  * @wfd: WFD mode 1:on, 0:off
  72  */
  73 struct venc_h264_vpu_config {
  74         u32 input_fourcc;
  75         u32 bitrate;
  76         u32 pic_w;
  77         u32 pic_h;
  78         u32 buf_w;
  79         u32 buf_h;
  80         u32 gop_size;
  81         u32 intra_period;
  82         u32 framerate;
  83         u32 profile;
  84         u32 level;
  85         u32 wfd;
  86 };
  87 
  88 /*
  89  * struct venc_h264_vpu_buf - Structure for buffer information
  90  *                            AP-W/R : AP is writer/reader on this item
  91  *                            VPU-W/R: VPU is write/reader on this item
  92  * @iova: IO virtual address
  93  * @vpua: VPU side memory addr which is used by RC_CODE
  94  * @size: buffer size (in bytes)
  95  */
  96 struct venc_h264_vpu_buf {
  97         u32 iova;
  98         u32 vpua;
  99         u32 size;
 100 };
 101 
 102 /*
 103  * struct venc_h264_vsi - Structure for VPU driver control and info share
 104  *                        AP-W/R : AP is writer/reader on this item
 105  *                        VPU-W/R: VPU is write/reader on this item
 106  * This structure is allocated in VPU side and shared to AP side.
 107  * @config: h264 encoder configuration
 108  * @work_bufs: working buffer information in VPU side
 109  * The work_bufs here is for storing the 'size' info shared to AP side.
 110  * The similar item in struct venc_h264_inst is for memory allocation
 111  * in AP side. The AP driver will copy the 'size' from here to the one in
 112  * struct mtk_vcodec_mem, then invoke mtk_vcodec_mem_alloc to allocate
 113  * the buffer. After that, bypass the 'dma_addr' to the 'iova' field here for
 114  * register setting in VPU side.
 115  */
 116 struct venc_h264_vsi {
 117         struct venc_h264_vpu_config config;
 118         struct venc_h264_vpu_buf work_bufs[VENC_H264_VPU_WORK_BUF_MAX];
 119 };
 120 
 121 /*
 122  * struct venc_h264_inst - h264 encoder AP driver instance
 123  * @hw_base: h264 encoder hardware register base
 124  * @work_bufs: working buffer
 125  * @pps_buf: buffer to store the pps bitstream
 126  * @work_buf_allocated: working buffer allocated flag
 127  * @frm_cnt: encoded frame count
 128  * @prepend_hdr: when the v4l2 layer send VENC_SET_PARAM_PREPEND_HEADER cmd
 129  *  through h264_enc_set_param interface, it will set this flag and prepend the
 130  *  sps/pps in h264_enc_encode function.
 131  * @vpu_inst: VPU instance to exchange information between AP and VPU
 132  * @vsi: driver structure allocated by VPU side and shared to AP side for
 133  *       control and info share
 134  * @ctx: context for v4l2 layer integration
 135  */
 136 struct venc_h264_inst {
 137         void __iomem *hw_base;
 138         struct mtk_vcodec_mem work_bufs[VENC_H264_VPU_WORK_BUF_MAX];
 139         struct mtk_vcodec_mem pps_buf;
 140         bool work_buf_allocated;
 141         unsigned int frm_cnt;
 142         unsigned int prepend_hdr;
 143         struct venc_vpu_inst vpu_inst;
 144         struct venc_h264_vsi *vsi;
 145         struct mtk_vcodec_ctx *ctx;
 146 };
 147 
 148 static inline u32 h264_read_reg(struct venc_h264_inst *inst, u32 addr)
 149 {
 150         return readl(inst->hw_base + addr);
 151 }
 152 
 153 static unsigned int h264_get_profile(struct venc_h264_inst *inst,
 154                                      unsigned int profile)
 155 {
 156         switch (profile) {
 157         case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
 158                 return 66;
 159         case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
 160                 return 77;
 161         case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
 162                 return 100;
 163         case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
 164                 mtk_vcodec_err(inst, "unsupported CONSTRAINED_BASELINE");
 165                 return 0;
 166         case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
 167                 mtk_vcodec_err(inst, "unsupported EXTENDED");
 168                 return 0;
 169         default:
 170                 mtk_vcodec_debug(inst, "unsupported profile %d", profile);
 171                 return 100;
 172         }
 173 }
 174 
 175 static unsigned int h264_get_level(struct venc_h264_inst *inst,
 176                                    unsigned int level)
 177 {
 178         switch (level) {
 179         case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
 180                 mtk_vcodec_err(inst, "unsupported 1B");
 181                 return 0;
 182         case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
 183                 return 10;
 184         case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
 185                 return 11;
 186         case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
 187                 return 12;
 188         case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
 189                 return 13;
 190         case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
 191                 return 20;
 192         case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
 193                 return 21;
 194         case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
 195                 return 22;
 196         case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
 197                 return 30;
 198         case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
 199                 return 31;
 200         case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
 201                 return 32;
 202         case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
 203                 return 40;
 204         case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
 205                 return 41;
 206         case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
 207                 return 42;
 208         default:
 209                 mtk_vcodec_debug(inst, "unsupported level %d", level);
 210                 return 31;
 211         }
 212 }
 213 
 214 static void h264_enc_free_work_buf(struct venc_h264_inst *inst)
 215 {
 216         int i;
 217 
 218         mtk_vcodec_debug_enter(inst);
 219 
 220         /* Except the SKIP_FRAME buffers,
 221          * other buffers need to be freed by AP.
 222          */
 223         for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) {
 224                 if (i != VENC_H264_VPU_WORK_BUF_SKIP_FRAME)
 225                         mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]);
 226         }
 227 
 228         mtk_vcodec_mem_free(inst->ctx, &inst->pps_buf);
 229 
 230         mtk_vcodec_debug_leave(inst);
 231 }
 232 
 233 static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst)
 234 {
 235         int i;
 236         int ret = 0;
 237         struct venc_h264_vpu_buf *wb = inst->vsi->work_bufs;
 238 
 239         mtk_vcodec_debug_enter(inst);
 240 
 241         for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) {
 242                 /*
 243                  * This 'wb' structure is set by VPU side and shared to AP for
 244                  * buffer allocation and IO virtual addr mapping. For most of
 245                  * the buffers, AP will allocate the buffer according to 'size'
 246                  * field and store the IO virtual addr in 'iova' field. There
 247                  * are two exceptions:
 248                  * (1) RC_CODE buffer, it's pre-allocated in the VPU side, and
 249                  * save the VPU addr in the 'vpua' field. The AP will translate
 250                  * the VPU addr to the corresponding IO virtual addr and store
 251                  * in 'iova' field for reg setting in VPU side.
 252                  * (2) SKIP_FRAME buffer, it's pre-allocated in the VPU side,
 253                  * and save the VPU addr in the 'vpua' field. The AP will
 254                  * translate the VPU addr to the corresponding AP side virtual
 255                  * address and do some memcpy access to move to bitstream buffer
 256                  * assigned by v4l2 layer.
 257                  */
 258                 inst->work_bufs[i].size = wb[i].size;
 259                 if (i == VENC_H264_VPU_WORK_BUF_SKIP_FRAME) {
 260                         inst->work_bufs[i].va = vpu_mapping_dm_addr(
 261                                 inst->vpu_inst.dev, wb[i].vpua);
 262                         inst->work_bufs[i].dma_addr = 0;
 263                 } else {
 264                         ret = mtk_vcodec_mem_alloc(inst->ctx,
 265                                                    &inst->work_bufs[i]);
 266                         if (ret) {
 267                                 mtk_vcodec_err(inst,
 268                                                "cannot allocate buf %d", i);
 269                                 goto err_alloc;
 270                         }
 271                         /*
 272                          * This RC_CODE is pre-allocated by VPU and saved in VPU
 273                          * addr. So we need use memcpy to copy RC_CODE from VPU
 274                          * addr into IO virtual addr in 'iova' field for reg
 275                          * setting in VPU side.
 276                          */
 277                         if (i == VENC_H264_VPU_WORK_BUF_RC_CODE) {
 278                                 void *tmp_va;
 279 
 280                                 tmp_va = vpu_mapping_dm_addr(inst->vpu_inst.dev,
 281                                                              wb[i].vpua);
 282                                 memcpy(inst->work_bufs[i].va, tmp_va,
 283                                        wb[i].size);
 284                         }
 285                 }
 286                 wb[i].iova = inst->work_bufs[i].dma_addr;
 287 
 288                 mtk_vcodec_debug(inst,
 289                                  "work_buf[%d] va=0x%p iova=%pad size=%zu",
 290                                  i, inst->work_bufs[i].va,
 291                                  &inst->work_bufs[i].dma_addr,
 292                                  inst->work_bufs[i].size);
 293         }
 294 
 295         /* the pps_buf is used by AP side only */
 296         inst->pps_buf.size = 128;
 297         ret = mtk_vcodec_mem_alloc(inst->ctx, &inst->pps_buf);
 298         if (ret) {
 299                 mtk_vcodec_err(inst, "cannot allocate pps_buf");
 300                 goto err_alloc;
 301         }
 302 
 303         mtk_vcodec_debug_leave(inst);
 304 
 305         return ret;
 306 
 307 err_alloc:
 308         h264_enc_free_work_buf(inst);
 309 
 310         return ret;
 311 }
 312 
 313 static unsigned int h264_enc_wait_venc_done(struct venc_h264_inst *inst)
 314 {
 315         unsigned int irq_status = 0;
 316         struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
 317 
 318         if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
 319                                           WAIT_INTR_TIMEOUT_MS)) {
 320                 irq_status = ctx->irq_status;
 321                 mtk_vcodec_debug(inst, "irq_status %x <-", irq_status);
 322         }
 323         return irq_status;
 324 }
 325 
 326 static int h264_encode_sps(struct venc_h264_inst *inst,
 327                            struct mtk_vcodec_mem *bs_buf,
 328                            unsigned int *bs_size)
 329 {
 330         int ret = 0;
 331         unsigned int irq_status;
 332 
 333         mtk_vcodec_debug_enter(inst);
 334 
 335         ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_SPS, NULL,
 336                              bs_buf, bs_size);
 337         if (ret)
 338                 return ret;
 339 
 340         irq_status = h264_enc_wait_venc_done(inst);
 341         if (irq_status != MTK_VENC_IRQ_STATUS_SPS) {
 342                 mtk_vcodec_err(inst, "expect irq status %d",
 343                                MTK_VENC_IRQ_STATUS_SPS);
 344                 return -EINVAL;
 345         }
 346 
 347         *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT);
 348         mtk_vcodec_debug(inst, "bs size %d <-", *bs_size);
 349 
 350         return ret;
 351 }
 352 
 353 static int h264_encode_pps(struct venc_h264_inst *inst,
 354                            struct mtk_vcodec_mem *bs_buf,
 355                            unsigned int *bs_size)
 356 {
 357         int ret = 0;
 358         unsigned int irq_status;
 359 
 360         mtk_vcodec_debug_enter(inst);
 361 
 362         ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_PPS, NULL,
 363                              bs_buf, bs_size);
 364         if (ret)
 365                 return ret;
 366 
 367         irq_status = h264_enc_wait_venc_done(inst);
 368         if (irq_status != MTK_VENC_IRQ_STATUS_PPS) {
 369                 mtk_vcodec_err(inst, "expect irq status %d",
 370                                MTK_VENC_IRQ_STATUS_PPS);
 371                 return -EINVAL;
 372         }
 373 
 374         *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT);
 375         mtk_vcodec_debug(inst, "bs size %d <-", *bs_size);
 376 
 377         return ret;
 378 }
 379 
 380 static int h264_encode_header(struct venc_h264_inst *inst,
 381                               struct mtk_vcodec_mem *bs_buf,
 382                               unsigned int *bs_size)
 383 {
 384         int ret = 0;
 385         unsigned int bs_size_sps;
 386         unsigned int bs_size_pps;
 387 
 388         ret = h264_encode_sps(inst, bs_buf, &bs_size_sps);
 389         if (ret)
 390                 return ret;
 391 
 392         ret = h264_encode_pps(inst, &inst->pps_buf, &bs_size_pps);
 393         if (ret)
 394                 return ret;
 395 
 396         memcpy(bs_buf->va + bs_size_sps, inst->pps_buf.va, bs_size_pps);
 397         *bs_size = bs_size_sps + bs_size_pps;
 398 
 399         return ret;
 400 }
 401 
 402 static int h264_encode_frame(struct venc_h264_inst *inst,
 403                              struct venc_frm_buf *frm_buf,
 404                              struct mtk_vcodec_mem *bs_buf,
 405                              unsigned int *bs_size)
 406 {
 407         int ret = 0;
 408         unsigned int irq_status;
 409 
 410         mtk_vcodec_debug_enter(inst);
 411 
 412         ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_FRAME, frm_buf,
 413                              bs_buf, bs_size);
 414         if (ret)
 415                 return ret;
 416 
 417         /*
 418          * skip frame case: The skip frame buffer is composed by vpu side only,
 419          * it does not trigger the hw, so skip the wait interrupt operation.
 420          */
 421         if (inst->vpu_inst.state == VEN_IPI_MSG_ENC_STATE_SKIP) {
 422                 *bs_size = inst->vpu_inst.bs_size;
 423                 memcpy(bs_buf->va,
 424                        inst->work_bufs[VENC_H264_VPU_WORK_BUF_SKIP_FRAME].va,
 425                        *bs_size);
 426                 ++inst->frm_cnt;
 427                 return ret;
 428         }
 429 
 430         irq_status = h264_enc_wait_venc_done(inst);
 431         if (irq_status != MTK_VENC_IRQ_STATUS_FRM) {
 432                 mtk_vcodec_err(inst, "irq_status=%d failed", irq_status);
 433                 return -EIO;
 434         }
 435 
 436         *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT);
 437 
 438         ++inst->frm_cnt;
 439         mtk_vcodec_debug(inst, "frm %d bs_size %d key_frm %d <-",
 440                          inst->frm_cnt, *bs_size, inst->vpu_inst.is_key_frm);
 441 
 442         return ret;
 443 }
 444 
 445 static void h264_encode_filler(struct venc_h264_inst *inst, void *buf,
 446                                int size)
 447 {
 448         unsigned char *p = buf;
 449 
 450         if (size < H264_FILLER_MARKER_SIZE) {
 451                 mtk_vcodec_err(inst, "filler size too small %d", size);
 452                 return;
 453         }
 454 
 455         memcpy(p, h264_filler_marker, ARRAY_SIZE(h264_filler_marker));
 456         size -= H264_FILLER_MARKER_SIZE;
 457         p += H264_FILLER_MARKER_SIZE;
 458         memset(p, 0xff, size);
 459 }
 460 
 461 static int h264_enc_init(struct mtk_vcodec_ctx *ctx)
 462 {
 463         int ret = 0;
 464         struct venc_h264_inst *inst;
 465 
 466         inst = kzalloc(sizeof(*inst), GFP_KERNEL);
 467         if (!inst)
 468                 return -ENOMEM;
 469 
 470         inst->ctx = ctx;
 471         inst->vpu_inst.ctx = ctx;
 472         inst->vpu_inst.dev = ctx->dev->vpu_plat_dev;
 473         inst->vpu_inst.id = IPI_VENC_H264;
 474         inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx, VENC_SYS);
 475 
 476         mtk_vcodec_debug_enter(inst);
 477 
 478         ret = vpu_enc_init(&inst->vpu_inst);
 479 
 480         inst->vsi = (struct venc_h264_vsi *)inst->vpu_inst.vsi;
 481 
 482         mtk_vcodec_debug_leave(inst);
 483 
 484         if (ret)
 485                 kfree(inst);
 486         else
 487                 ctx->drv_handle = inst;
 488 
 489         return ret;
 490 }
 491 
 492 static int h264_enc_encode(void *handle,
 493                            enum venc_start_opt opt,
 494                            struct venc_frm_buf *frm_buf,
 495                            struct mtk_vcodec_mem *bs_buf,
 496                            struct venc_done_result *result)
 497 {
 498         int ret = 0;
 499         struct venc_h264_inst *inst = (struct venc_h264_inst *)handle;
 500         struct mtk_vcodec_ctx *ctx = inst->ctx;
 501 
 502         mtk_vcodec_debug(inst, "opt %d ->", opt);
 503 
 504         enable_irq(ctx->dev->enc_irq);
 505 
 506         switch (opt) {
 507         case VENC_START_OPT_ENCODE_SEQUENCE_HEADER: {
 508                 unsigned int bs_size_hdr;
 509 
 510                 ret = h264_encode_header(inst, bs_buf, &bs_size_hdr);
 511                 if (ret)
 512                         goto encode_err;
 513 
 514                 result->bs_size = bs_size_hdr;
 515                 result->is_key_frm = false;
 516                 break;
 517         }
 518 
 519         case VENC_START_OPT_ENCODE_FRAME: {
 520                 int hdr_sz;
 521                 int hdr_sz_ext;
 522                 int filler_sz = 0;
 523                 const int bs_alignment = 128;
 524                 struct mtk_vcodec_mem tmp_bs_buf;
 525                 unsigned int bs_size_hdr;
 526                 unsigned int bs_size_frm;
 527 
 528                 if (!inst->prepend_hdr) {
 529                         ret = h264_encode_frame(inst, frm_buf, bs_buf,
 530                                                 &result->bs_size);
 531                         if (ret)
 532                                 goto encode_err;
 533                         result->is_key_frm = inst->vpu_inst.is_key_frm;
 534                         break;
 535                 }
 536 
 537                 mtk_vcodec_debug(inst, "h264_encode_frame prepend SPS/PPS");
 538 
 539                 ret = h264_encode_header(inst, bs_buf, &bs_size_hdr);
 540                 if (ret)
 541                         goto encode_err;
 542 
 543                 hdr_sz = bs_size_hdr;
 544                 hdr_sz_ext = (hdr_sz & (bs_alignment - 1));
 545                 if (hdr_sz_ext) {
 546                         filler_sz = bs_alignment - hdr_sz_ext;
 547                         if (hdr_sz_ext + H264_FILLER_MARKER_SIZE > bs_alignment)
 548                                 filler_sz += bs_alignment;
 549                         h264_encode_filler(inst, bs_buf->va + hdr_sz,
 550                                            filler_sz);
 551                 }
 552 
 553                 tmp_bs_buf.va = bs_buf->va + hdr_sz + filler_sz;
 554                 tmp_bs_buf.dma_addr = bs_buf->dma_addr + hdr_sz + filler_sz;
 555                 tmp_bs_buf.size = bs_buf->size - (hdr_sz + filler_sz);
 556 
 557                 ret = h264_encode_frame(inst, frm_buf, &tmp_bs_buf,
 558                                         &bs_size_frm);
 559                 if (ret)
 560                         goto encode_err;
 561 
 562                 result->bs_size = hdr_sz + filler_sz + bs_size_frm;
 563 
 564                 mtk_vcodec_debug(inst, "hdr %d filler %d frame %d bs %d",
 565                                  hdr_sz, filler_sz, bs_size_frm,
 566                                  result->bs_size);
 567 
 568                 inst->prepend_hdr = 0;
 569                 result->is_key_frm = inst->vpu_inst.is_key_frm;
 570                 break;
 571         }
 572 
 573         default:
 574                 mtk_vcodec_err(inst, "venc_start_opt %d not supported", opt);
 575                 ret = -EINVAL;
 576                 break;
 577         }
 578 
 579 encode_err:
 580 
 581         disable_irq(ctx->dev->enc_irq);
 582         mtk_vcodec_debug(inst, "opt %d <-", opt);
 583 
 584         return ret;
 585 }
 586 
 587 static int h264_enc_set_param(void *handle,
 588                               enum venc_set_param_type type,
 589                               struct venc_enc_param *enc_prm)
 590 {
 591         int ret = 0;
 592         struct venc_h264_inst *inst = (struct venc_h264_inst *)handle;
 593 
 594         mtk_vcodec_debug(inst, "->type=%d", type);
 595 
 596         switch (type) {
 597         case VENC_SET_PARAM_ENC:
 598                 inst->vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
 599                 inst->vsi->config.bitrate = enc_prm->bitrate;
 600                 inst->vsi->config.pic_w = enc_prm->width;
 601                 inst->vsi->config.pic_h = enc_prm->height;
 602                 inst->vsi->config.buf_w = enc_prm->buf_width;
 603                 inst->vsi->config.buf_h = enc_prm->buf_height;
 604                 inst->vsi->config.gop_size = enc_prm->gop_size;
 605                 inst->vsi->config.framerate = enc_prm->frm_rate;
 606                 inst->vsi->config.intra_period = enc_prm->intra_period;
 607                 inst->vsi->config.profile =
 608                         h264_get_profile(inst, enc_prm->h264_profile);
 609                 inst->vsi->config.level =
 610                         h264_get_level(inst, enc_prm->h264_level);
 611                 inst->vsi->config.wfd = 0;
 612                 ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
 613                 if (ret)
 614                         break;
 615                 if (inst->work_buf_allocated) {
 616                         h264_enc_free_work_buf(inst);
 617                         inst->work_buf_allocated = false;
 618                 }
 619                 ret = h264_enc_alloc_work_buf(inst);
 620                 if (ret)
 621                         break;
 622                 inst->work_buf_allocated = true;
 623                 break;
 624 
 625         case VENC_SET_PARAM_PREPEND_HEADER:
 626                 inst->prepend_hdr = 1;
 627                 mtk_vcodec_debug(inst, "set prepend header mode");
 628                 break;
 629 
 630         default:
 631                 ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
 632                 break;
 633         }
 634 
 635         mtk_vcodec_debug_leave(inst);
 636 
 637         return ret;
 638 }
 639 
 640 static int h264_enc_deinit(void *handle)
 641 {
 642         int ret = 0;
 643         struct venc_h264_inst *inst = (struct venc_h264_inst *)handle;
 644 
 645         mtk_vcodec_debug_enter(inst);
 646 
 647         ret = vpu_enc_deinit(&inst->vpu_inst);
 648 
 649         if (inst->work_buf_allocated)
 650                 h264_enc_free_work_buf(inst);
 651 
 652         mtk_vcodec_debug_leave(inst);
 653         kfree(inst);
 654 
 655         return ret;
 656 }
 657 
 658 const struct venc_common_if venc_h264_if = {
 659         .init = h264_enc_init,
 660         .encode = h264_enc_encode,
 661         .set_param = h264_enc_set_param,
 662         .deinit = h264_enc_deinit,
 663 };

/* [<][>][^][v][top][bottom][index][help] */