LCOV - code coverage report
Current view: top level - libavcodec - proresenc_kostya.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 472 667 70.8 %
Date: 2018-05-20 11:54:08 Functions: 16 22 72.7 %

          Line data    Source code
       1             : /*
       2             :  * Apple ProRes encoder
       3             :  *
       4             :  * Copyright (c) 2012 Konstantin Shishkov
       5             :  *
       6             :  * This encoder appears to be based on Anatoliy Wassermans considering
       7             :  * similarities in the bugs.
       8             :  *
       9             :  * This file is part of FFmpeg.
      10             :  *
      11             :  * FFmpeg is free software; you can redistribute it and/or
      12             :  * modify it under the terms of the GNU Lesser General Public
      13             :  * License as published by the Free Software Foundation; either
      14             :  * version 2.1 of the License, or (at your option) any later version.
      15             :  *
      16             :  * FFmpeg is distributed in the hope that it will be useful,
      17             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      19             :  * Lesser General Public License for more details.
      20             :  *
      21             :  * You should have received a copy of the GNU Lesser General Public
      22             :  * License along with FFmpeg; if not, write to the Free Software
      23             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      24             :  */
      25             : 
      26             : #include "libavutil/opt.h"
      27             : #include "libavutil/pixdesc.h"
      28             : #include "avcodec.h"
      29             : #include "fdctdsp.h"
      30             : #include "put_bits.h"
      31             : #include "bytestream.h"
      32             : #include "internal.h"
      33             : #include "proresdata.h"
      34             : 
      35             : #define CFACTOR_Y422 2
      36             : #define CFACTOR_Y444 3
      37             : 
      38             : #define MAX_MBS_PER_SLICE 8
      39             : 
      40             : #define MAX_PLANES 4
      41             : 
      42             : enum {
      43             :     PRORES_PROFILE_AUTO  = -1,
      44             :     PRORES_PROFILE_PROXY = 0,
      45             :     PRORES_PROFILE_LT,
      46             :     PRORES_PROFILE_STANDARD,
      47             :     PRORES_PROFILE_HQ,
      48             :     PRORES_PROFILE_4444,
      49             :     PRORES_PROFILE_4444XQ,
      50             : };
      51             : 
      52             : enum {
      53             :     QUANT_MAT_PROXY = 0,
      54             :     QUANT_MAT_PROXY_CHROMA,
      55             :     QUANT_MAT_LT,
      56             :     QUANT_MAT_STANDARD,
      57             :     QUANT_MAT_HQ,
      58             :     QUANT_MAT_XQ_LUMA,
      59             :     QUANT_MAT_DEFAULT,
      60             : };
      61             : 
      62             : static const uint8_t prores_quant_matrices[][64] = {
      63             :     { // proxy
      64             :          4,  7,  9, 11, 13, 14, 15, 63,
      65             :          7,  7, 11, 12, 14, 15, 63, 63,
      66             :          9, 11, 13, 14, 15, 63, 63, 63,
      67             :         11, 11, 13, 14, 63, 63, 63, 63,
      68             :         11, 13, 14, 63, 63, 63, 63, 63,
      69             :         13, 14, 63, 63, 63, 63, 63, 63,
      70             :         13, 63, 63, 63, 63, 63, 63, 63,
      71             :         63, 63, 63, 63, 63, 63, 63, 63,
      72             :     },
      73             :     { // proxy chromas
      74             :         4,  7,  9, 11, 13, 14, 63, 63,
      75             :         7,  7, 11, 12, 14, 63, 63, 63,
      76             :         9, 11, 13, 14, 63, 63, 63, 63,
      77             :         11, 11, 13, 14, 63, 63, 63, 63,
      78             :         11, 13, 14, 63, 63, 63, 63, 63,
      79             :         13, 14, 63, 63, 63, 63, 63, 63,
      80             :         13, 63, 63, 63, 63, 63, 63, 63,
      81             :         63, 63, 63, 63, 63, 63, 63, 63
      82             :     },
      83             :     { // LT
      84             :          4,  5,  6,  7,  9, 11, 13, 15,
      85             :          5,  5,  7,  8, 11, 13, 15, 17,
      86             :          6,  7,  9, 11, 13, 15, 15, 17,
      87             :          7,  7,  9, 11, 13, 15, 17, 19,
      88             :          7,  9, 11, 13, 14, 16, 19, 23,
      89             :          9, 11, 13, 14, 16, 19, 23, 29,
      90             :          9, 11, 13, 15, 17, 21, 28, 35,
      91             :         11, 13, 16, 17, 21, 28, 35, 41,
      92             :     },
      93             :     { // standard
      94             :          4,  4,  5,  5,  6,  7,  7,  9,
      95             :          4,  4,  5,  6,  7,  7,  9,  9,
      96             :          5,  5,  6,  7,  7,  9,  9, 10,
      97             :          5,  5,  6,  7,  7,  9,  9, 10,
      98             :          5,  6,  7,  7,  8,  9, 10, 12,
      99             :          6,  7,  7,  8,  9, 10, 12, 15,
     100             :          6,  7,  7,  9, 10, 11, 14, 17,
     101             :          7,  7,  9, 10, 11, 14, 17, 21,
     102             :     },
     103             :     { // high quality
     104             :          4,  4,  4,  4,  4,  4,  4,  4,
     105             :          4,  4,  4,  4,  4,  4,  4,  4,
     106             :          4,  4,  4,  4,  4,  4,  4,  4,
     107             :          4,  4,  4,  4,  4,  4,  4,  5,
     108             :          4,  4,  4,  4,  4,  4,  5,  5,
     109             :          4,  4,  4,  4,  4,  5,  5,  6,
     110             :          4,  4,  4,  4,  5,  5,  6,  7,
     111             :          4,  4,  4,  4,  5,  6,  7,  7,
     112             :     },
     113             :     { // XQ luma
     114             :         2,  2,  2,  2,  2,  2,  2,  2,
     115             :         2,  2,  2,  2,  2,  2,  2,  2,
     116             :         2,  2,  2,  2,  2,  2,  2,  2,
     117             :         2,  2,  2,  2,  2,  2,  2,  3,
     118             :         2,  2,  2,  2,  2,  2,  3,  3,
     119             :         2,  2,  2,  2,  2,  3,  3,  3,
     120             :         2,  2,  2,  2,  3,  3,  3,  4,
     121             :         2,  2,  2,  2,  3,  3,  4,  4,
     122             :     },
     123             :     { // codec default
     124             :          4,  4,  4,  4,  4,  4,  4,  4,
     125             :          4,  4,  4,  4,  4,  4,  4,  4,
     126             :          4,  4,  4,  4,  4,  4,  4,  4,
     127             :          4,  4,  4,  4,  4,  4,  4,  4,
     128             :          4,  4,  4,  4,  4,  4,  4,  4,
     129             :          4,  4,  4,  4,  4,  4,  4,  4,
     130             :          4,  4,  4,  4,  4,  4,  4,  4,
     131             :          4,  4,  4,  4,  4,  4,  4,  4,
     132             :     },
     133             : };
     134             : 
     135             : #define NUM_MB_LIMITS 4
     136             : static const int prores_mb_limits[NUM_MB_LIMITS] = {
     137             :     1620, // up to 720x576
     138             :     2700, // up to 960x720
     139             :     6075, // up to 1440x1080
     140             :     9216, // up to 2048x1152
     141             : };
     142             : 
     143             : static const struct prores_profile {
     144             :     const char *full_name;
     145             :     uint32_t    tag;
     146             :     int         min_quant;
     147             :     int         max_quant;
     148             :     int         br_tab[NUM_MB_LIMITS];
     149             :     int         quant;
     150             :     int         quant_chroma;
     151             : } prores_profile_info[6] = {
     152             :     {
     153             :         .full_name = "proxy",
     154             :         .tag       = MKTAG('a', 'p', 'c', 'o'),
     155             :         .min_quant = 4,
     156             :         .max_quant = 8,
     157             :         .br_tab    = { 300, 242, 220, 194 },
     158             :         .quant     = QUANT_MAT_PROXY,
     159             :         .quant_chroma = QUANT_MAT_PROXY_CHROMA,
     160             :     },
     161             :     {
     162             :         .full_name = "LT",
     163             :         .tag       = MKTAG('a', 'p', 'c', 's'),
     164             :         .min_quant = 1,
     165             :         .max_quant = 9,
     166             :         .br_tab    = { 720, 560, 490, 440 },
     167             :         .quant     = QUANT_MAT_LT,
     168             :         .quant_chroma = QUANT_MAT_LT,
     169             :     },
     170             :     {
     171             :         .full_name = "standard",
     172             :         .tag       = MKTAG('a', 'p', 'c', 'n'),
     173             :         .min_quant = 1,
     174             :         .max_quant = 6,
     175             :         .br_tab    = { 1050, 808, 710, 632 },
     176             :         .quant     = QUANT_MAT_STANDARD,
     177             :         .quant_chroma = QUANT_MAT_STANDARD,
     178             :     },
     179             :     {
     180             :         .full_name = "high quality",
     181             :         .tag       = MKTAG('a', 'p', 'c', 'h'),
     182             :         .min_quant = 1,
     183             :         .max_quant = 6,
     184             :         .br_tab    = { 1566, 1216, 1070, 950 },
     185             :         .quant     = QUANT_MAT_HQ,
     186             :         .quant_chroma = QUANT_MAT_HQ,
     187             :     },
     188             :     {
     189             :         .full_name = "4444",
     190             :         .tag       = MKTAG('a', 'p', '4', 'h'),
     191             :         .min_quant = 1,
     192             :         .max_quant = 6,
     193             :         .br_tab    = { 2350, 1828, 1600, 1425 },
     194             :         .quant     = QUANT_MAT_HQ,
     195             :         .quant_chroma = QUANT_MAT_HQ,
     196             :     },
     197             :     {
     198             :         .full_name = "4444XQ",
     199             :         .tag       = MKTAG('a', 'p', '4', 'x'),
     200             :         .min_quant = 1,
     201             :         .max_quant = 6,
     202             :         .br_tab    = { 3525, 2742, 2400, 2137 },
     203             :         .quant     = QUANT_MAT_HQ, /* Fix me : use QUANT_MAT_XQ_LUMA */
     204             :         .quant_chroma = QUANT_MAT_HQ,
     205             :     }
     206             : };
     207             : 
     208             : #define TRELLIS_WIDTH 16
     209             : #define SCORE_LIMIT   INT_MAX / 2
     210             : 
     211             : struct TrellisNode {
     212             :     int prev_node;
     213             :     int quant;
     214             :     int bits;
     215             :     int score;
     216             : };
     217             : 
     218             : #define MAX_STORED_Q 16
     219             : 
     220             : typedef struct ProresThreadData {
     221             :     DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
     222             :     DECLARE_ALIGNED(16, uint16_t, emu_buf)[16 * 16];
     223             :     int16_t custom_q[64];
     224             :     struct TrellisNode *nodes;
     225             : } ProresThreadData;
     226             : 
     227             : typedef struct ProresContext {
     228             :     AVClass *class;
     229             :     DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
     230             :     DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
     231             :     int16_t quants[MAX_STORED_Q][64];
     232             :     int16_t quants_chroma[MAX_STORED_Q][64];
     233             :     int16_t custom_q[64];
     234             :     const uint8_t *quant_mat;
     235             :     const uint8_t *quant_chroma_mat;
     236             :     const uint8_t *scantable;
     237             : 
     238             :     void (*fdct)(FDCTDSPContext *fdsp, const uint16_t *src,
     239             :                  ptrdiff_t linesize, int16_t *block);
     240             :     FDCTDSPContext fdsp;
     241             : 
     242             :     const AVFrame *pic;
     243             :     int mb_width, mb_height;
     244             :     int mbs_per_slice;
     245             :     int num_chroma_blocks, chroma_factor;
     246             :     int slices_width;
     247             :     int slices_per_picture;
     248             :     int pictures_per_frame; // 1 for progressive, 2 for interlaced
     249             :     int cur_picture_idx;
     250             :     int num_planes;
     251             :     int bits_per_mb;
     252             :     int force_quant;
     253             :     int alpha_bits;
     254             :     int warn;
     255             : 
     256             :     char *vendor;
     257             :     int quant_sel;
     258             : 
     259             :     int frame_size_upper_bound;
     260             : 
     261             :     int profile;
     262             :     const struct prores_profile *profile_info;
     263             : 
     264             :     int *slice_q;
     265             : 
     266             :     ProresThreadData *tdata;
     267             : } ProresContext;
     268             : 
     269       66600 : static void get_slice_data(ProresContext *ctx, const uint16_t *src,
     270             :                            ptrdiff_t linesize, int x, int y, int w, int h,
     271             :                            int16_t *blocks, uint16_t *emu_buf,
     272             :                            int mbs_per_slice, int blocks_per_mb, int is_chroma)
     273             : {
     274             :     const uint16_t *esrc;
     275       66600 :     const int mb_width = 4 * blocks_per_mb;
     276             :     ptrdiff_t elinesize;
     277             :     int i, j, k;
     278             : 
     279      425700 :     for (i = 0; i < mbs_per_slice; i++, src += mb_width) {
     280      359100 :         if (x >= w) {
     281           0 :             memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb
     282             :                               * sizeof(*blocks));
     283           0 :             return;
     284             :         }
     285      359100 :         if (x + mb_width <= w && y + 16 <= h) {
     286      357600 :             esrc      = src;
     287      357600 :             elinesize = linesize;
     288             :         } else {
     289             :             int bw, bh, pix;
     290             : 
     291        1500 :             esrc      = emu_buf;
     292        1500 :             elinesize = 16 * sizeof(*emu_buf);
     293             : 
     294        1500 :             bw = FFMIN(w - x, mb_width);
     295        1500 :             bh = FFMIN(h - y, 16);
     296             : 
     297       12900 :             for (j = 0; j < bh; j++) {
     298       22800 :                 memcpy(emu_buf + j * 16,
     299       11400 :                        (const uint8_t*)src + j * linesize,
     300             :                        bw * sizeof(*src));
     301       11400 :                 pix = emu_buf[j * 16 + bw - 1];
     302      106600 :                 for (k = bw; k < mb_width; k++)
     303       95200 :                     emu_buf[j * 16 + k] = pix;
     304             :             }
     305       14100 :             for (; j < 16; j++)
     306       37800 :                 memcpy(emu_buf + j * 16,
     307       25200 :                        emu_buf + (bh - 1) * 16,
     308             :                        mb_width * sizeof(*emu_buf));
     309             :         }
     310      359100 :         if (!is_chroma) {
     311      119700 :             ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
     312      119700 :             blocks += 64;
     313      119700 :             if (blocks_per_mb > 2) {
     314      119700 :                 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
     315      119700 :                 blocks += 64;
     316             :             }
     317      119700 :             ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
     318      119700 :             blocks += 64;
     319      119700 :             if (blocks_per_mb > 2) {
     320      119700 :                 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
     321      119700 :                 blocks += 64;
     322             :             }
     323             :         } else {
     324      239400 :             ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
     325      239400 :             blocks += 64;
     326      239400 :             ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
     327      239400 :             blocks += 64;
     328      239400 :             if (blocks_per_mb > 2) {
     329           0 :                 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
     330           0 :                 blocks += 64;
     331           0 :                 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
     332           0 :                 blocks += 64;
     333             :             }
     334             :         }
     335             : 
     336      359100 :         x += mb_width;
     337             :     }
     338             : }
     339             : 
     340           0 : static void get_alpha_data(ProresContext *ctx, const uint16_t *src,
     341             :                            ptrdiff_t linesize, int x, int y, int w, int h,
     342             :                            int16_t *blocks, int mbs_per_slice, int abits)
     343             : {
     344           0 :     const int slice_width = 16 * mbs_per_slice;
     345             :     int i, j, copy_w, copy_h;
     346             : 
     347           0 :     copy_w = FFMIN(w - x, slice_width);
     348           0 :     copy_h = FFMIN(h - y, 16);
     349           0 :     for (i = 0; i < copy_h; i++) {
     350           0 :         memcpy(blocks, src, copy_w * sizeof(*src));
     351           0 :         if (abits == 8)
     352           0 :             for (j = 0; j < copy_w; j++)
     353           0 :                 blocks[j] >>= 2;
     354             :         else
     355           0 :             for (j = 0; j < copy_w; j++)
     356           0 :                 blocks[j] = (blocks[j] << 6) | (blocks[j] >> 4);
     357           0 :         for (j = copy_w; j < slice_width; j++)
     358           0 :             blocks[j] = blocks[copy_w - 1];
     359           0 :         blocks += slice_width;
     360           0 :         src    += linesize >> 1;
     361             :     }
     362           0 :     for (; i < 16; i++) {
     363           0 :         memcpy(blocks, blocks - slice_width, slice_width * sizeof(*blocks));
     364           0 :         blocks += slice_width;
     365             :     }
     366           0 : }
     367             : 
     368             : /**
     369             :  * Write an unsigned rice/exp golomb codeword.
     370             :  */
     371    26885174 : static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
     372             : {
     373             :     unsigned int rice_order, exp_order, switch_bits, switch_val;
     374             :     int exponent;
     375             : 
     376             :     /* number of prefix bits to switch between Rice and expGolomb */
     377    26885174 :     switch_bits = (codebook & 3) + 1;
     378    26885174 :     rice_order  =  codebook >> 5;       /* rice code order */
     379    26885174 :     exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
     380             : 
     381    26885174 :     switch_val  = switch_bits << rice_order;
     382             : 
     383    26885174 :     if (val >= switch_val) {
     384     8074309 :         val -= switch_val - (1 << exp_order);
     385     8074309 :         exponent = av_log2(val);
     386             : 
     387     8074309 :         put_bits(pb, exponent - exp_order + switch_bits, 0);
     388     8074309 :         put_bits(pb, exponent + 1, val);
     389             :     } else {
     390    18810865 :         exponent = val >> rice_order;
     391             : 
     392    18810865 :         if (exponent)
     393     4838901 :             put_bits(pb, exponent, 0);
     394    18810865 :         put_bits(pb, 1, 1);
     395    18810865 :         if (rice_order)
     396     1904515 :             put_sbits(pb, rice_order, val);
     397             :     }
     398    26885174 : }
     399             : 
     400             : #define GET_SIGN(x)  ((x) >> 31)
     401             : #define MAKE_CODE(x) ((((x)) * 2) ^ GET_SIGN(x))
     402             : 
     403       33300 : static void encode_dcs(PutBitContext *pb, int16_t *blocks,
     404             :                        int blocks_per_slice, int scale)
     405             : {
     406             :     int i;
     407       33300 :     int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
     408             : 
     409       33300 :     prev_dc = (blocks[0] - 0x4000) / scale;
     410       33300 :     encode_vlc_codeword(pb, FIRST_DC_CB, MAKE_CODE(prev_dc));
     411       33300 :     sign     = 0;
     412       33300 :     codebook = 3;
     413       33300 :     blocks  += 64;
     414             : 
     415      478800 :     for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
     416      445500 :         dc       = (blocks[0] - 0x4000) / scale;
     417      445500 :         delta    = dc - prev_dc;
     418      445500 :         new_sign = GET_SIGN(delta);
     419      445500 :         delta    = (delta ^ sign) - sign;
     420      445500 :         code     = MAKE_CODE(delta);
     421      445500 :         encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
     422      445500 :         codebook = (code + (code & 1)) >> 1;
     423      445500 :         codebook = FFMIN(codebook, 3);
     424      445500 :         sign     = new_sign;
     425      445500 :         prev_dc  = dc;
     426             :     }
     427       33300 : }
     428             : 
     429       33300 : static void encode_acs(PutBitContext *pb, int16_t *blocks,
     430             :                        int blocks_per_slice,
     431             :                        int plane_size_factor,
     432             :                        const uint8_t *scan, const int16_t *qmat)
     433             : {
     434             :     int idx, i;
     435             :     int run, level, run_cb, lev_cb;
     436             :     int max_coeffs, abs_level;
     437             : 
     438       33300 :     max_coeffs = blocks_per_slice << 6;
     439       33300 :     run_cb     = ff_prores_run_to_cb_index[4];
     440       33300 :     lev_cb     = ff_prores_lev_to_cb_index[2];
     441       33300 :     run        = 0;
     442             : 
     443     2131200 :     for (i = 1; i < 64; i++) {
     444    32262300 :         for (idx = scan[i]; idx < max_coeffs; idx += 64) {
     445    30164400 :             level = blocks[idx] / qmat[scan[i]];
     446    30164400 :             if (level) {
     447    13203187 :                 abs_level = FFABS(level);
     448    13203187 :                 encode_vlc_codeword(pb, ff_prores_ac_codebook[run_cb], run);
     449    13203187 :                 encode_vlc_codeword(pb, ff_prores_ac_codebook[lev_cb],
     450             :                                     abs_level - 1);
     451    13203187 :                 put_sbits(pb, 1, GET_SIGN(level));
     452             : 
     453    13203187 :                 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
     454    13203187 :                 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
     455    13203187 :                 run    = 0;
     456             :             } else {
     457    16961213 :                 run++;
     458             :             }
     459             :         }
     460             :     }
     461       33300 : }
     462             : 
     463       33300 : static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
     464             :                               const uint16_t *src, ptrdiff_t linesize,
     465             :                               int mbs_per_slice, int16_t *blocks,
     466             :                               int blocks_per_mb, int plane_size_factor,
     467             :                               const int16_t *qmat)
     468             : {
     469             :     int blocks_per_slice, saved_pos;
     470             : 
     471       33300 :     saved_pos = put_bits_count(pb);
     472       33300 :     blocks_per_slice = mbs_per_slice * blocks_per_mb;
     473             : 
     474       33300 :     encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
     475       33300 :     encode_acs(pb, blocks, blocks_per_slice, plane_size_factor,
     476             :                ctx->scantable, qmat);
     477       33300 :     flush_put_bits(pb);
     478             : 
     479       33300 :     return (put_bits_count(pb) - saved_pos) >> 3;
     480             : }
     481             : 
     482           0 : static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
     483             : {
     484           0 :     const int dbits = (abits == 8) ? 4 : 7;
     485           0 :     const int dsize = 1 << dbits - 1;
     486           0 :     int diff = cur - prev;
     487             : 
     488           0 :     diff = av_mod_uintp2(diff, abits);
     489           0 :     if (diff >= (1 << abits) - dsize)
     490           0 :         diff -= 1 << abits;
     491           0 :     if (diff < -dsize || diff > dsize || !diff) {
     492           0 :         put_bits(pb, 1, 1);
     493           0 :         put_bits(pb, abits, diff);
     494             :     } else {
     495           0 :         put_bits(pb, 1, 0);
     496           0 :         put_bits(pb, dbits - 1, FFABS(diff) - 1);
     497           0 :         put_bits(pb, 1, diff < 0);
     498             :     }
     499           0 : }
     500             : 
     501           0 : static void put_alpha_run(PutBitContext *pb, int run)
     502             : {
     503           0 :     if (run) {
     504           0 :         put_bits(pb, 1, 0);
     505           0 :         if (run < 0x10)
     506           0 :             put_bits(pb, 4, run);
     507             :         else
     508           0 :             put_bits(pb, 15, run);
     509             :     } else {
     510           0 :         put_bits(pb, 1, 1);
     511             :     }
     512           0 : }
     513             : 
     514             : // todo alpha quantisation for high quants
     515           0 : static int encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
     516             :                               int mbs_per_slice, uint16_t *blocks,
     517             :                               int quant)
     518             : {
     519           0 :     const int abits = ctx->alpha_bits;
     520           0 :     const int mask  = (1 << abits) - 1;
     521           0 :     const int num_coeffs = mbs_per_slice * 256;
     522           0 :     int saved_pos = put_bits_count(pb);
     523           0 :     int prev = mask, cur;
     524           0 :     int idx = 0;
     525           0 :     int run = 0;
     526             : 
     527           0 :     cur = blocks[idx++];
     528           0 :     put_alpha_diff(pb, cur, prev, abits);
     529           0 :     prev = cur;
     530             :     do {
     531           0 :         cur = blocks[idx++];
     532           0 :         if (cur != prev) {
     533           0 :             put_alpha_run (pb, run);
     534           0 :             put_alpha_diff(pb, cur, prev, abits);
     535           0 :             prev = cur;
     536           0 :             run  = 0;
     537             :         } else {
     538           0 :             run++;
     539             :         }
     540           0 :     } while (idx < num_coeffs);
     541           0 :     if (run)
     542           0 :         put_alpha_run(pb, run);
     543           0 :     flush_put_bits(pb);
     544           0 :     return (put_bits_count(pb) - saved_pos) >> 3;
     545             : }
     546             : 
     547       11100 : static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
     548             :                         PutBitContext *pb,
     549             :                         int sizes[4], int x, int y, int quant,
     550             :                         int mbs_per_slice)
     551             : {
     552       11100 :     ProresContext *ctx = avctx->priv_data;
     553             :     int i, xp, yp;
     554       11100 :     int total_size = 0;
     555             :     const uint16_t *src;
     556       11100 :     int slice_width_factor = av_log2(mbs_per_slice);
     557             :     int num_cblocks, pwidth, line_add;
     558             :     ptrdiff_t linesize;
     559             :     int plane_factor, is_chroma;
     560             :     uint16_t *qmat;
     561             :     uint16_t *qmat_chroma;
     562             : 
     563       11100 :     if (ctx->pictures_per_frame == 1)
     564       11100 :         line_add = 0;
     565             :     else
     566           0 :         line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
     567             : 
     568       11100 :     if (ctx->force_quant) {
     569           0 :         qmat = ctx->quants[0];
     570           0 :         qmat_chroma = ctx->quants_chroma[0];
     571       11100 :     } else if (quant < MAX_STORED_Q) {
     572        8353 :         qmat = ctx->quants[quant];
     573        8353 :         qmat_chroma = ctx->quants_chroma[quant];
     574             :     } else {
     575        2747 :         qmat = ctx->custom_q;
     576        2747 :         qmat_chroma = ctx->custom_q;
     577      178555 :         for (i = 0; i < 64; i++) {
     578      175808 :             qmat[i] = ctx->quant_mat[i] * quant;
     579      175808 :             qmat_chroma[i] = ctx->quant_chroma_mat[i] * quant;
     580             :         }
     581             :     }
     582             : 
     583       44400 :     for (i = 0; i < ctx->num_planes; i++) {
     584       33300 :         is_chroma    = (i == 1 || i == 2);
     585       33300 :         plane_factor = slice_width_factor + 2;
     586       33300 :         if (is_chroma)
     587       22200 :             plane_factor += ctx->chroma_factor - 3;
     588       33300 :         if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
     589       11100 :             xp          = x << 4;
     590       11100 :             yp          = y << 4;
     591       11100 :             num_cblocks = 4;
     592       11100 :             pwidth      = avctx->width;
     593             :         } else {
     594       22200 :             xp          = x << 3;
     595       22200 :             yp          = y << 4;
     596       22200 :             num_cblocks = 2;
     597       22200 :             pwidth      = avctx->width >> 1;
     598             :         }
     599             : 
     600       33300 :         linesize = pic->linesize[i] * ctx->pictures_per_frame;
     601       99900 :         src = (const uint16_t*)(pic->data[i] + yp * linesize +
     602       66600 :                                 line_add * pic->linesize[i]) + xp;
     603             : 
     604       33300 :         if (i < 3) {
     605       33300 :             get_slice_data(ctx, src, linesize, xp, yp,
     606       33300 :                            pwidth, avctx->height / ctx->pictures_per_frame,
     607       33300 :                            ctx->blocks[0], ctx->emu_buf,
     608             :                            mbs_per_slice, num_cblocks, is_chroma);
     609       33300 :             if (!is_chroma) {/* luma quant */
     610       11100 :                 sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
     611       11100 :                                               mbs_per_slice, ctx->blocks[0],
     612             :                                               num_cblocks, plane_factor,
     613             :                                               qmat);
     614             :             } else { /* chroma plane */
     615       22200 :                 sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
     616       22200 :                                               mbs_per_slice, ctx->blocks[0],
     617             :                                               num_cblocks, plane_factor,
     618             :                                               qmat_chroma);
     619             :             }
     620             :         } else {
     621           0 :             get_alpha_data(ctx, src, linesize, xp, yp,
     622           0 :                            pwidth, avctx->height / ctx->pictures_per_frame,
     623           0 :                            ctx->blocks[0], mbs_per_slice, ctx->alpha_bits);
     624           0 :             sizes[i] = encode_alpha_plane(ctx, pb, mbs_per_slice,
     625           0 :                                           ctx->blocks[0], quant);
     626             :         }
     627       33300 :         total_size += sizes[i];
     628       33300 :         if (put_bits_left(pb) < 0) {
     629           0 :             av_log(avctx, AV_LOG_ERROR,
     630             :                    "Underestimated required buffer size.\n");
     631           0 :             return AVERROR_BUG;
     632             :         }
     633             :     }
     634       11100 :     return total_size;
     635             : }
     636             : 
     637   390320122 : static inline int estimate_vlc(unsigned codebook, int val)
     638             : {
     639             :     unsigned int rice_order, exp_order, switch_bits, switch_val;
     640             :     int exponent;
     641             : 
     642             :     /* number of prefix bits to switch between Rice and expGolomb */
     643   390320122 :     switch_bits = (codebook & 3) + 1;
     644   390320122 :     rice_order  =  codebook >> 5;       /* rice code order */
     645   390320122 :     exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
     646             : 
     647   390320122 :     switch_val  = switch_bits << rice_order;
     648             : 
     649   390320122 :     if (val >= switch_val) {
     650   135366530 :         val -= switch_val - (1 << exp_order);
     651   135366530 :         exponent = av_log2(val);
     652             : 
     653   135366530 :         return exponent * 2 - exp_order + switch_bits + 1;
     654             :     } else {
     655   254953592 :         return (val >> rice_order) + rice_order + 1;
     656             :     }
     657             : }
     658             : 
     659      379686 : static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice,
     660             :                         int scale)
     661             : {
     662             :     int i;
     663      379686 :     int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
     664             :     int bits;
     665             : 
     666      379686 :     prev_dc  = (blocks[0] - 0x4000) / scale;
     667      379686 :     bits     = estimate_vlc(FIRST_DC_CB, MAKE_CODE(prev_dc));
     668      379686 :     sign     = 0;
     669      379686 :     codebook = 3;
     670      379686 :     blocks  += 64;
     671      379686 :     *error  += FFABS(blocks[0] - 0x4000) % scale;
     672             : 
     673     5449672 :     for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
     674     5069986 :         dc       = (blocks[0] - 0x4000) / scale;
     675     5069986 :         *error  += FFABS(blocks[0] - 0x4000) % scale;
     676     5069986 :         delta    = dc - prev_dc;
     677     5069986 :         new_sign = GET_SIGN(delta);
     678     5069986 :         delta    = (delta ^ sign) - sign;
     679     5069986 :         code     = MAKE_CODE(delta);
     680     5069986 :         bits    += estimate_vlc(ff_prores_dc_codebook[codebook], code);
     681     5069986 :         codebook = (code + (code & 1)) >> 1;
     682     5069986 :         codebook = FFMIN(codebook, 3);
     683     5069986 :         sign     = new_sign;
     684     5069986 :         prev_dc  = dc;
     685             :     }
     686             : 
     687      379686 :     return bits;
     688             : }
     689             : 
     690      379686 : static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
     691             :                         int plane_size_factor,
     692             :                         const uint8_t *scan, const int16_t *qmat)
     693             : {
     694             :     int idx, i;
     695             :     int run, level, run_cb, lev_cb;
     696             :     int max_coeffs, abs_level;
     697      379686 :     int bits = 0;
     698             : 
     699      379686 :     max_coeffs = blocks_per_slice << 6;
     700      379686 :     run_cb     = ff_prores_run_to_cb_index[4];
     701      379686 :     lev_cb     = ff_prores_lev_to_cb_index[2];
     702      379686 :     run        = 0;
     703             : 
     704    24299904 :     for (i = 1; i < 64; i++) {
     705   367249554 :         for (idx = scan[i]; idx < max_coeffs; idx += 64) {
     706   343329336 :             level   = blocks[idx] / qmat[scan[i]];
     707   343329336 :             *error += FFABS(blocks[idx]) % qmat[scan[i]];
     708   343329336 :             if (level) {
     709   192435225 :                 abs_level = FFABS(level);
     710   192435225 :                 bits += estimate_vlc(ff_prores_ac_codebook[run_cb], run);
     711   384870450 :                 bits += estimate_vlc(ff_prores_ac_codebook[lev_cb],
     712   192435225 :                                      abs_level - 1) + 1;
     713             : 
     714   192435225 :                 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
     715   192435225 :                 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
     716   192435225 :                 run    = 0;
     717             :             } else {
     718   150894111 :                 run++;
     719             :             }
     720             :         }
     721             :     }
     722             : 
     723      379686 :     return bits;
     724             : }
     725             : 
     726      379686 : static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
     727             :                                 const uint16_t *src, ptrdiff_t linesize,
     728             :                                 int mbs_per_slice,
     729             :                                 int blocks_per_mb, int plane_size_factor,
     730             :                                 const int16_t *qmat, ProresThreadData *td)
     731             : {
     732             :     int blocks_per_slice;
     733             :     int bits;
     734             : 
     735      379686 :     blocks_per_slice = mbs_per_slice * blocks_per_mb;
     736             : 
     737      379686 :     bits  = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
     738      379686 :     bits += estimate_acs(error, td->blocks[plane], blocks_per_slice,
     739             :                          plane_size_factor, ctx->scantable, qmat);
     740             : 
     741      379686 :     return FFALIGN(bits, 8);
     742             : }
     743             : 
     744           0 : static int est_alpha_diff(int cur, int prev, int abits)
     745             : {
     746           0 :     const int dbits = (abits == 8) ? 4 : 7;
     747           0 :     const int dsize = 1 << dbits - 1;
     748           0 :     int diff = cur - prev;
     749             : 
     750           0 :     diff = av_mod_uintp2(diff, abits);
     751           0 :     if (diff >= (1 << abits) - dsize)
     752           0 :         diff -= 1 << abits;
     753           0 :     if (diff < -dsize || diff > dsize || !diff)
     754           0 :         return abits + 1;
     755             :     else
     756           0 :         return dbits + 1;
     757             : }
     758             : 
     759           0 : static int estimate_alpha_plane(ProresContext *ctx,
     760             :                                 const uint16_t *src, ptrdiff_t linesize,
     761             :                                 int mbs_per_slice, int16_t *blocks)
     762             : {
     763           0 :     const int abits = ctx->alpha_bits;
     764           0 :     const int mask  = (1 << abits) - 1;
     765           0 :     const int num_coeffs = mbs_per_slice * 256;
     766           0 :     int prev = mask, cur;
     767           0 :     int idx = 0;
     768           0 :     int run = 0;
     769             :     int bits;
     770             : 
     771           0 :     cur = blocks[idx++];
     772           0 :     bits = est_alpha_diff(cur, prev, abits);
     773           0 :     prev = cur;
     774             :     do {
     775           0 :         cur = blocks[idx++];
     776           0 :         if (cur != prev) {
     777           0 :             if (!run)
     778           0 :                 bits++;
     779           0 :             else if (run < 0x10)
     780           0 :                 bits += 4;
     781             :             else
     782           0 :                 bits += 15;
     783           0 :             bits += est_alpha_diff(cur, prev, abits);
     784           0 :             prev = cur;
     785           0 :             run  = 0;
     786             :         } else {
     787           0 :             run++;
     788             :         }
     789           0 :     } while (idx < num_coeffs);
     790             : 
     791           0 :     if (run) {
     792           0 :         if (run < 0x10)
     793           0 :             bits += 4;
     794             :         else
     795           0 :             bits += 15;
     796             :     }
     797             : 
     798           0 :     return bits;
     799             : }
     800             : 
     801       11100 : static int find_slice_quant(AVCodecContext *avctx,
     802             :                             int trellis_node, int x, int y, int mbs_per_slice,
     803             :                             ProresThreadData *td)
     804             : {
     805       11100 :     ProresContext *ctx = avctx->priv_data;
     806             :     int i, q, pq, xp, yp;
     807             :     const uint16_t *src;
     808       11100 :     int slice_width_factor = av_log2(mbs_per_slice);
     809             :     int num_cblocks[MAX_PLANES], pwidth;
     810             :     int plane_factor[MAX_PLANES], is_chroma[MAX_PLANES];
     811       11100 :     const int min_quant = ctx->profile_info->min_quant;
     812       11100 :     const int max_quant = ctx->profile_info->max_quant;
     813             :     int error, bits, bits_limit;
     814             :     int mbs, prev, cur, new_score;
     815             :     int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
     816             :     int overquant;
     817             :     uint16_t *qmat;
     818             :     uint16_t *qmat_chroma;
     819             :     int linesize[4], line_add;
     820       11100 :     int alpha_bits = 0;
     821             : 
     822       11100 :     if (ctx->pictures_per_frame == 1)
     823       11100 :         line_add = 0;
     824             :     else
     825           0 :         line_add = ctx->cur_picture_idx ^ !ctx->pic->top_field_first;
     826       11100 :     mbs = x + mbs_per_slice;
     827             : 
     828       44400 :     for (i = 0; i < ctx->num_planes; i++) {
     829       33300 :         is_chroma[i]    = (i == 1 || i == 2);
     830       33300 :         plane_factor[i] = slice_width_factor + 2;
     831       33300 :         if (is_chroma[i])
     832       22200 :             plane_factor[i] += ctx->chroma_factor - 3;
     833       33300 :         if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
     834       11100 :             xp             = x << 4;
     835       11100 :             yp             = y << 4;
     836       11100 :             num_cblocks[i] = 4;
     837       11100 :             pwidth         = avctx->width;
     838             :         } else {
     839       22200 :             xp             = x << 3;
     840       22200 :             yp             = y << 4;
     841       22200 :             num_cblocks[i] = 2;
     842       22200 :             pwidth         = avctx->width >> 1;
     843             :         }
     844             : 
     845       33300 :         linesize[i] = ctx->pic->linesize[i] * ctx->pictures_per_frame;
     846       99900 :         src = (const uint16_t *)(ctx->pic->data[i] + yp * linesize[i] +
     847       66600 :                                  line_add * ctx->pic->linesize[i]) + xp;
     848             : 
     849       33300 :         if (i < 3) {
     850       66600 :             get_slice_data(ctx, src, linesize[i], xp, yp,
     851       33300 :                            pwidth, avctx->height / ctx->pictures_per_frame,
     852       33300 :                            td->blocks[i], td->emu_buf,
     853             :                            mbs_per_slice, num_cblocks[i], is_chroma[i]);
     854             :         } else {
     855           0 :             get_alpha_data(ctx, src, linesize[i], xp, yp,
     856           0 :                            pwidth, avctx->height / ctx->pictures_per_frame,
     857           0 :                            td->blocks[i], mbs_per_slice, ctx->alpha_bits);
     858             :         }
     859             :     }
     860             : 
     861       88800 :     for (q = min_quant; q < max_quant + 2; q++) {
     862       77700 :         td->nodes[trellis_node + q].prev_node = -1;
     863       77700 :         td->nodes[trellis_node + q].quant     = q;
     864             :     }
     865             : 
     866       11100 :     if (ctx->alpha_bits)
     867           0 :         alpha_bits = estimate_alpha_plane(ctx, src, linesize[3],
     868           0 :                                           mbs_per_slice, td->blocks[3]);
     869             :     // todo: maybe perform coarser quantising to fit into frame size when needed
     870       77700 :     for (q = min_quant; q <= max_quant; q++) {
     871       66600 :         bits  = alpha_bits;
     872       66600 :         error = 0;
     873      133200 :         bits += estimate_slice_plane(ctx, &error, 0,
     874       66600 :                                      src, linesize[0],
     875             :                                      mbs_per_slice,
     876             :                                      num_cblocks[0], plane_factor[0],
     877       66600 :                                      ctx->quants[q], td); /* estimate luma plane */
     878      199800 :         for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
     879      266400 :             bits += estimate_slice_plane(ctx, &error, i,
     880      133200 :                                          src, linesize[i],
     881             :                                          mbs_per_slice,
     882             :                                          num_cblocks[i], plane_factor[i],
     883      133200 :                                          ctx->quants_chroma[q], td);
     884             :         }
     885       66600 :         if (bits > 65000 * 8)
     886           0 :             error = SCORE_LIMIT;
     887             : 
     888       66600 :         slice_bits[q]  = bits;
     889       66600 :         slice_score[q] = error;
     890             :     }
     891       11100 :     if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
     892        3643 :         slice_bits[max_quant + 1]  = slice_bits[max_quant];
     893        3643 :         slice_score[max_quant + 1] = slice_score[max_quant] + 1;
     894        3643 :         overquant = max_quant;
     895             :     } else {
     896       59962 :         for (q = max_quant + 1; q < 128; q++) {
     897       59962 :             bits  = alpha_bits;
     898       59962 :             error = 0;
     899       59962 :             if (q < MAX_STORED_Q) {
     900       44939 :                 qmat = ctx->quants[q];
     901       44939 :                 qmat_chroma = ctx->quants_chroma[q];
     902             :             } else {
     903       15023 :                 qmat = td->custom_q;
     904       15023 :                 qmat_chroma = td->custom_q;
     905      976495 :                 for (i = 0; i < 64; i++) {
     906      961472 :                     qmat[i] = ctx->quant_mat[i] * q;
     907      961472 :                     qmat_chroma[i] = ctx->quant_chroma_mat[i] * q;
     908             :                 }
     909             :             }
     910      119924 :             bits += estimate_slice_plane(ctx, &error, 0,
     911       59962 :                                          src, linesize[0],
     912             :                                          mbs_per_slice,
     913             :                                          num_cblocks[0], plane_factor[0],
     914             :                                          qmat, td);/* estimate luma plane */
     915      179886 :             for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
     916      239848 :                 bits += estimate_slice_plane(ctx, &error, i,
     917      119924 :                                              src, linesize[i],
     918             :                                              mbs_per_slice,
     919             :                                              num_cblocks[i], plane_factor[i],
     920             :                                              qmat_chroma, td);
     921             :             }
     922       59962 :             if (bits <= ctx->bits_per_mb * mbs_per_slice)
     923        7457 :                 break;
     924             :         }
     925             : 
     926        7457 :         slice_bits[max_quant + 1]  = bits;
     927        7457 :         slice_score[max_quant + 1] = error;
     928        7457 :         overquant = q;
     929             :     }
     930       11100 :     td->nodes[trellis_node + max_quant + 1].quant = overquant;
     931             : 
     932       11100 :     bits_limit = mbs * ctx->bits_per_mb;
     933       88800 :     for (pq = min_quant; pq < max_quant + 2; pq++) {
     934       77700 :         prev = trellis_node - TRELLIS_WIDTH + pq;
     935             : 
     936      621600 :         for (q = min_quant; q < max_quant + 2; q++) {
     937      543900 :             cur = trellis_node + q;
     938             : 
     939      543900 :             bits  = td->nodes[prev].bits + slice_bits[q];
     940      543900 :             error = slice_score[q];
     941      543900 :             if (bits > bits_limit)
     942      438632 :                 error = SCORE_LIMIT;
     943             : 
     944      543900 :             if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)
     945       98480 :                 new_score = td->nodes[prev].score + error;
     946             :             else
     947      445420 :                 new_score = SCORE_LIMIT;
     948     1010100 :             if (td->nodes[cur].prev_node == -1 ||
     949      466200 :                 td->nodes[cur].score >= new_score) {
     950             : 
     951      505564 :                 td->nodes[cur].bits      = bits;
     952      505564 :                 td->nodes[cur].score     = new_score;
     953      505564 :                 td->nodes[cur].prev_node = prev;
     954             :             }
     955             :         }
     956             :     }
     957             : 
     958       11100 :     error = td->nodes[trellis_node + min_quant].score;
     959       11100 :     pq    = trellis_node + min_quant;
     960       77700 :     for (q = min_quant + 1; q < max_quant + 2; q++) {
     961       66600 :         if (td->nodes[trellis_node + q].score <= error) {
     962       52033 :             error = td->nodes[trellis_node + q].score;
     963       52033 :             pq    = trellis_node + q;
     964             :         }
     965             :     }
     966             : 
     967       11100 :     return pq;
     968             : }
     969             : 
     970        2850 : static int find_quant_thread(AVCodecContext *avctx, void *arg,
     971             :                              int jobnr, int threadnr)
     972             : {
     973        2850 :     ProresContext *ctx = avctx->priv_data;
     974        2850 :     ProresThreadData *td = ctx->tdata + threadnr;
     975        2850 :     int mbs_per_slice = ctx->mbs_per_slice;
     976        2850 :     int x, y = jobnr, mb, q = 0;
     977             : 
     978       13950 :     for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
     979       28050 :         while (ctx->mb_width - x < mbs_per_slice)
     980        5850 :             mbs_per_slice >>= 1;
     981       11100 :         q = find_slice_quant(avctx,
     982       11100 :                              (mb + 1) * TRELLIS_WIDTH, x, y,
     983             :                              mbs_per_slice, td);
     984             :     }
     985             : 
     986       13950 :     for (x = ctx->slices_width - 1; x >= 0; x--) {
     987       11100 :         ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
     988       11100 :         q = td->nodes[q].prev_node;
     989             :     }
     990             : 
     991        2850 :     return 0;
     992             : }
     993             : 
     994         200 : static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     995             :                         const AVFrame *pic, int *got_packet)
     996             : {
     997         200 :     ProresContext *ctx = avctx->priv_data;
     998             :     uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
     999             :     uint8_t *picture_size_pos;
    1000             :     PutBitContext pb;
    1001         200 :     int x, y, i, mb, q = 0;
    1002         200 :     int sizes[4] = { 0 };
    1003         200 :     int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1);
    1004             :     int frame_size, picture_size, slice_size;
    1005             :     int pkt_size, ret;
    1006         200 :     int max_slice_size = (ctx->frame_size_upper_bound - 200) / (ctx->pictures_per_frame * ctx->slices_per_picture + 1);
    1007             :     uint8_t frame_flags;
    1008             : 
    1009         200 :     ctx->pic = pic;
    1010         200 :     pkt_size = ctx->frame_size_upper_bound;
    1011             : 
    1012         200 :     if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
    1013           0 :         return ret;
    1014             : 
    1015         200 :     orig_buf = pkt->data;
    1016             : 
    1017             :     // frame atom
    1018         200 :     orig_buf += 4;                              // frame size
    1019         200 :     bytestream_put_be32  (&orig_buf, FRAME_ID); // frame container ID
    1020         200 :     buf = orig_buf;
    1021             : 
    1022             :     // frame header
    1023         200 :     tmp = buf;
    1024         200 :     buf += 2;                                   // frame header size will be stored here
    1025         200 :     bytestream_put_be16  (&buf, 0);             // version 1
    1026         200 :     bytestream_put_buffer(&buf, ctx->vendor, 4);
    1027         200 :     bytestream_put_be16  (&buf, avctx->width);
    1028         200 :     bytestream_put_be16  (&buf, avctx->height);
    1029             : 
    1030         200 :     frame_flags = ctx->chroma_factor << 6;
    1031         200 :     if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT)
    1032           0 :         frame_flags |= pic->top_field_first ? 0x04 : 0x08;
    1033         200 :     bytestream_put_byte  (&buf, frame_flags);
    1034             : 
    1035         200 :     bytestream_put_byte  (&buf, 0);             // reserved
    1036         200 :     bytestream_put_byte  (&buf, pic->color_primaries);
    1037         200 :     bytestream_put_byte  (&buf, pic->color_trc);
    1038         200 :     bytestream_put_byte  (&buf, pic->colorspace);
    1039         200 :     bytestream_put_byte  (&buf, 0x40 | (ctx->alpha_bits >> 3));
    1040         200 :     bytestream_put_byte  (&buf, 0);             // reserved
    1041         200 :     if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
    1042         200 :         bytestream_put_byte  (&buf, 0x03);      // matrix flags - both matrices are present
    1043             :         // luma quantisation matrix
    1044       13000 :         for (i = 0; i < 64; i++)
    1045       12800 :             bytestream_put_byte(&buf, ctx->quant_mat[i]);
    1046             :         // chroma quantisation matrix
    1047       13000 :         for (i = 0; i < 64; i++)
    1048       12800 :             bytestream_put_byte(&buf, ctx->quant_mat[i]);
    1049             :     } else {
    1050           0 :         bytestream_put_byte  (&buf, 0x00);      // matrix flags - default matrices are used
    1051             :     }
    1052         200 :     bytestream_put_be16  (&tmp, buf - orig_buf); // write back frame header size
    1053             : 
    1054         600 :     for (ctx->cur_picture_idx = 0;
    1055         400 :          ctx->cur_picture_idx < ctx->pictures_per_frame;
    1056         200 :          ctx->cur_picture_idx++) {
    1057             :         // picture header
    1058         200 :         picture_size_pos = buf + 1;
    1059         200 :         bytestream_put_byte  (&buf, 0x40);          // picture header size (in bits)
    1060         200 :         buf += 4;                                   // picture data size will be stored here
    1061         200 :         bytestream_put_be16  (&buf, ctx->slices_per_picture);
    1062         200 :         bytestream_put_byte  (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
    1063             : 
    1064             :         // seek table - will be filled during slice encoding
    1065         200 :         slice_sizes = buf;
    1066         200 :         buf += ctx->slices_per_picture * 2;
    1067             : 
    1068             :         // slices
    1069         200 :         if (!ctx->force_quant) {
    1070         200 :             ret = avctx->execute2(avctx, find_quant_thread, (void*)pic, NULL,
    1071             :                                   ctx->mb_height);
    1072         200 :             if (ret)
    1073           0 :                 return ret;
    1074             :         }
    1075             : 
    1076        3050 :         for (y = 0; y < ctx->mb_height; y++) {
    1077        2850 :             int mbs_per_slice = ctx->mbs_per_slice;
    1078       13950 :             for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
    1079       22200 :                 q = ctx->force_quant ? ctx->force_quant
    1080       11100 :                                      : ctx->slice_q[mb + y * ctx->slices_width];
    1081             : 
    1082       28050 :                 while (ctx->mb_width - x < mbs_per_slice)
    1083        5850 :                     mbs_per_slice >>= 1;
    1084             : 
    1085       11100 :                 bytestream_put_byte(&buf, slice_hdr_size << 3);
    1086       11100 :                 slice_hdr = buf;
    1087       11100 :                 buf += slice_hdr_size - 1;
    1088       11100 :                 if (pkt_size <= buf - orig_buf + 2 * max_slice_size) {
    1089           0 :                     uint8_t *start = pkt->data;
    1090             :                     // Recompute new size according to max_slice_size
    1091             :                     // and deduce delta
    1092           0 :                     int delta = 200 + (ctx->pictures_per_frame *
    1093           0 :                                 ctx->slices_per_picture + 1) *
    1094             :                                 max_slice_size - pkt_size;
    1095             : 
    1096           0 :                     delta = FFMAX(delta, 2 * max_slice_size);
    1097           0 :                     ctx->frame_size_upper_bound += delta;
    1098             : 
    1099           0 :                     if (!ctx->warn) {
    1100           0 :                         avpriv_request_sample(avctx,
    1101             :                                               "Packet too small: is %i,"
    1102             :                                               " needs %i (slice: %i). "
    1103             :                                               "Correct allocation",
    1104             :                                               pkt_size, delta, max_slice_size);
    1105           0 :                         ctx->warn = 1;
    1106             :                     }
    1107             : 
    1108           0 :                     ret = av_grow_packet(pkt, delta);
    1109           0 :                     if (ret < 0)
    1110           0 :                         return ret;
    1111             : 
    1112           0 :                     pkt_size += delta;
    1113             :                     // restore pointers
    1114           0 :                     orig_buf         = pkt->data + (orig_buf         - start);
    1115           0 :                     buf              = pkt->data + (buf              - start);
    1116           0 :                     picture_size_pos = pkt->data + (picture_size_pos - start);
    1117           0 :                     slice_sizes      = pkt->data + (slice_sizes      - start);
    1118           0 :                     slice_hdr        = pkt->data + (slice_hdr        - start);
    1119           0 :                     tmp              = pkt->data + (tmp              - start);
    1120             :                 }
    1121       11100 :                 init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)));
    1122       11100 :                 ret = encode_slice(avctx, pic, &pb, sizes, x, y, q,
    1123             :                                    mbs_per_slice);
    1124       11100 :                 if (ret < 0)
    1125           0 :                     return ret;
    1126             : 
    1127       11100 :                 bytestream_put_byte(&slice_hdr, q);
    1128       11100 :                 slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
    1129       33300 :                 for (i = 0; i < ctx->num_planes - 1; i++) {
    1130       22200 :                     bytestream_put_be16(&slice_hdr, sizes[i]);
    1131       22200 :                     slice_size += sizes[i];
    1132             :                 }
    1133       11100 :                 bytestream_put_be16(&slice_sizes, slice_size);
    1134       11100 :                 buf += slice_size - slice_hdr_size;
    1135       11100 :                 if (max_slice_size < slice_size)
    1136         216 :                     max_slice_size = slice_size;
    1137             :             }
    1138             :         }
    1139             : 
    1140         200 :         picture_size = buf - (picture_size_pos - 1);
    1141         200 :         bytestream_put_be32(&picture_size_pos, picture_size);
    1142             :     }
    1143             : 
    1144         200 :     orig_buf -= 8;
    1145         200 :     frame_size = buf - orig_buf;
    1146         200 :     bytestream_put_be32(&orig_buf, frame_size);
    1147             : 
    1148         200 :     pkt->size   = frame_size;
    1149         200 :     pkt->flags |= AV_PKT_FLAG_KEY;
    1150         200 :     *got_packet = 1;
    1151             : 
    1152         200 :     return 0;
    1153             : }
    1154             : 
    1155           4 : static av_cold int encode_close(AVCodecContext *avctx)
    1156             : {
    1157           4 :     ProresContext *ctx = avctx->priv_data;
    1158             :     int i;
    1159             : 
    1160           4 :     if (ctx->tdata) {
    1161           8 :         for (i = 0; i < avctx->thread_count; i++)
    1162           4 :             av_freep(&ctx->tdata[i].nodes);
    1163             :     }
    1164           4 :     av_freep(&ctx->tdata);
    1165           4 :     av_freep(&ctx->slice_q);
    1166             : 
    1167           4 :     return 0;
    1168             : }
    1169             : 
    1170      957600 : static void prores_fdct(FDCTDSPContext *fdsp, const uint16_t *src,
    1171             :                         ptrdiff_t linesize, int16_t *block)
    1172             : {
    1173             :     int x, y;
    1174      957600 :     const uint16_t *tsrc = src;
    1175             : 
    1176     8618400 :     for (y = 0; y < 8; y++) {
    1177    68947200 :         for (x = 0; x < 8; x++)
    1178    61286400 :             block[y * 8 + x] = tsrc[x];
    1179     7660800 :         tsrc += linesize >> 1;
    1180             :     }
    1181      957600 :     fdsp->fdct(block);
    1182      957600 : }
    1183             : 
    1184           4 : static av_cold int encode_init(AVCodecContext *avctx)
    1185             : {
    1186           4 :     ProresContext *ctx = avctx->priv_data;
    1187             :     int mps;
    1188             :     int i, j;
    1189             :     int min_quant, max_quant;
    1190           4 :     int interlaced = !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT);
    1191             : 
    1192           4 :     avctx->bits_per_raw_sample = 10;
    1193             : #if FF_API_CODED_FRAME
    1194             : FF_DISABLE_DEPRECATION_WARNINGS
    1195           4 :     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
    1196           4 :     avctx->coded_frame->key_frame = 1;
    1197             : FF_ENABLE_DEPRECATION_WARNINGS
    1198             : #endif
    1199             : 
    1200           4 :     ctx->fdct      = prores_fdct;
    1201           4 :     ctx->scantable = interlaced ? ff_prores_interlaced_scan
    1202           4 :                                 : ff_prores_progressive_scan;
    1203           4 :     ff_fdctdsp_init(&ctx->fdsp, avctx);
    1204             : 
    1205           4 :     mps = ctx->mbs_per_slice;
    1206           4 :     if (mps & (mps - 1)) {
    1207           0 :         av_log(avctx, AV_LOG_ERROR,
    1208             :                "there should be an integer power of two MBs per slice\n");
    1209           0 :         return AVERROR(EINVAL);
    1210             :     }
    1211           4 :     if (ctx->profile == PRORES_PROFILE_AUTO) {
    1212           0 :         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
    1213           0 :         ctx->profile = (desc->flags & AV_PIX_FMT_FLAG_ALPHA ||
    1214           0 :                         !(desc->log2_chroma_w + desc->log2_chroma_h))
    1215           0 :                      ? PRORES_PROFILE_4444 : PRORES_PROFILE_HQ;
    1216           0 :         av_log(avctx, AV_LOG_INFO, "Autoselected %s. It can be overridden "
    1217           0 :                "through -profile option.\n", ctx->profile == PRORES_PROFILE_4444
    1218             :                ? "4:4:4:4 profile because of the used input colorspace"
    1219             :                : "HQ profile to keep best quality");
    1220             :     }
    1221           4 :     if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA) {
    1222           0 :         if (ctx->profile != PRORES_PROFILE_4444 &&
    1223           0 :             ctx->profile != PRORES_PROFILE_4444XQ) {
    1224             :             // force alpha and warn
    1225           0 :             av_log(avctx, AV_LOG_WARNING, "Profile selected will not "
    1226             :                    "encode alpha. Override with -profile if needed.\n");
    1227           0 :             ctx->alpha_bits = 0;
    1228             :         }
    1229           0 :         if (ctx->alpha_bits & 7) {
    1230           0 :             av_log(avctx, AV_LOG_ERROR, "alpha bits should be 0, 8 or 16\n");
    1231           0 :             return AVERROR(EINVAL);
    1232             :         }
    1233           0 :         avctx->bits_per_coded_sample = 32;
    1234             :     } else {
    1235           4 :         ctx->alpha_bits = 0;
    1236             :     }
    1237             : 
    1238           8 :     ctx->chroma_factor = avctx->pix_fmt == AV_PIX_FMT_YUV422P10
    1239             :                          ? CFACTOR_Y422
    1240           4 :                          : CFACTOR_Y444;
    1241           4 :     ctx->profile_info  = prores_profile_info + ctx->profile;
    1242           4 :     ctx->num_planes    = 3 + !!ctx->alpha_bits;
    1243             : 
    1244           4 :     ctx->mb_width      = FFALIGN(avctx->width,  16) >> 4;
    1245             : 
    1246           4 :     if (interlaced)
    1247           0 :         ctx->mb_height = FFALIGN(avctx->height, 32) >> 5;
    1248             :     else
    1249           4 :         ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
    1250             : 
    1251           4 :     ctx->slices_width  = ctx->mb_width / mps;
    1252           4 :     ctx->slices_width += av_popcount(ctx->mb_width - ctx->slices_width * mps);
    1253           4 :     ctx->slices_per_picture = ctx->mb_height * ctx->slices_width;
    1254           4 :     ctx->pictures_per_frame = 1 + interlaced;
    1255             : 
    1256           4 :     if (ctx->quant_sel == -1) {
    1257           4 :         ctx->quant_mat = prores_quant_matrices[ctx->profile_info->quant];
    1258           4 :         ctx->quant_chroma_mat = prores_quant_matrices[ctx->profile_info->quant_chroma];
    1259             :     } else {
    1260           0 :         ctx->quant_mat = prores_quant_matrices[ctx->quant_sel];
    1261           0 :         ctx->quant_chroma_mat = prores_quant_matrices[ctx->quant_sel];
    1262             :     }
    1263             : 
    1264           4 :     if (strlen(ctx->vendor) != 4) {
    1265           0 :         av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
    1266           0 :         return AVERROR_INVALIDDATA;
    1267             :     }
    1268             : 
    1269           4 :     ctx->force_quant = avctx->global_quality / FF_QP2LAMBDA;
    1270           4 :     if (!ctx->force_quant) {
    1271           4 :         if (!ctx->bits_per_mb) {
    1272           4 :             for (i = 0; i < NUM_MB_LIMITS - 1; i++)
    1273           8 :                 if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height *
    1274           4 :                                            ctx->pictures_per_frame)
    1275           4 :                     break;
    1276           4 :             ctx->bits_per_mb   = ctx->profile_info->br_tab[i];
    1277           4 :             if (ctx->alpha_bits)
    1278           0 :                 ctx->bits_per_mb *= 20;
    1279           0 :         } else if (ctx->bits_per_mb < 128) {
    1280           0 :             av_log(avctx, AV_LOG_ERROR, "too few bits per MB, please set at least 128\n");
    1281           0 :             return AVERROR_INVALIDDATA;
    1282             :         }
    1283             : 
    1284           4 :         min_quant = ctx->profile_info->min_quant;
    1285           4 :         max_quant = ctx->profile_info->max_quant;
    1286          64 :         for (i = min_quant; i < MAX_STORED_Q; i++) {
    1287        3900 :             for (j = 0; j < 64; j++) {
    1288        3840 :                 ctx->quants[i][j] = ctx->quant_mat[j] * i;
    1289        3840 :                 ctx->quants_chroma[i][j] = ctx->quant_chroma_mat[j] * i;
    1290             :             }
    1291             :         }
    1292             : 
    1293           4 :         ctx->slice_q = av_malloc(ctx->slices_per_picture * sizeof(*ctx->slice_q));
    1294           4 :         if (!ctx->slice_q) {
    1295           0 :             encode_close(avctx);
    1296           0 :             return AVERROR(ENOMEM);
    1297             :         }
    1298             : 
    1299           4 :         ctx->tdata = av_mallocz(avctx->thread_count * sizeof(*ctx->tdata));
    1300           4 :         if (!ctx->tdata) {
    1301           0 :             encode_close(avctx);
    1302           0 :             return AVERROR(ENOMEM);
    1303             :         }
    1304             : 
    1305           8 :         for (j = 0; j < avctx->thread_count; j++) {
    1306           4 :             ctx->tdata[j].nodes = av_malloc((ctx->slices_width + 1)
    1307             :                                             * TRELLIS_WIDTH
    1308             :                                             * sizeof(*ctx->tdata->nodes));
    1309           4 :             if (!ctx->tdata[j].nodes) {
    1310           0 :                 encode_close(avctx);
    1311           0 :                 return AVERROR(ENOMEM);
    1312             :             }
    1313          32 :             for (i = min_quant; i < max_quant + 2; i++) {
    1314          28 :                 ctx->tdata[j].nodes[i].prev_node = -1;
    1315          28 :                 ctx->tdata[j].nodes[i].bits      = 0;
    1316          28 :                 ctx->tdata[j].nodes[i].score     = 0;
    1317             :             }
    1318             :         }
    1319             :     } else {
    1320           0 :         int ls = 0;
    1321           0 :         int ls_chroma = 0;
    1322             : 
    1323           0 :         if (ctx->force_quant > 64) {
    1324           0 :             av_log(avctx, AV_LOG_ERROR, "too large quantiser, maximum is 64\n");
    1325           0 :             return AVERROR_INVALIDDATA;
    1326             :         }
    1327             : 
    1328           0 :         for (j = 0; j < 64; j++) {
    1329           0 :             ctx->quants[0][j] = ctx->quant_mat[j] * ctx->force_quant;
    1330           0 :             ctx->quants_chroma[0][j] = ctx->quant_chroma_mat[j] * ctx->force_quant;
    1331           0 :             ls += av_log2((1 << 11)  / ctx->quants[0][j]) * 2 + 1;
    1332           0 :             ls_chroma += av_log2((1 << 11)  / ctx->quants_chroma[0][j]) * 2 + 1;
    1333             :         }
    1334             : 
    1335           0 :         ctx->bits_per_mb = ls * 4 + ls_chroma * 4;
    1336           0 :         if (ctx->chroma_factor == CFACTOR_Y444)
    1337           0 :             ctx->bits_per_mb += ls_chroma * 4;
    1338             :     }
    1339             : 
    1340          12 :     ctx->frame_size_upper_bound = (ctx->pictures_per_frame *
    1341          12 :                                    ctx->slices_per_picture + 1) *
    1342           8 :                                   (2 + 2 * ctx->num_planes +
    1343           4 :                                    (mps * ctx->bits_per_mb) / 8)
    1344           4 :                                   + 200;
    1345             : 
    1346           4 :     if (ctx->alpha_bits) {
    1347             :          // The alpha plane is run-coded and might exceed the bit budget.
    1348           0 :          ctx->frame_size_upper_bound += (ctx->pictures_per_frame *
    1349           0 :                                          ctx->slices_per_picture + 1) *
    1350           0 :          /* num pixels per slice */     (ctx->mbs_per_slice * 256 *
    1351           0 :          /* bits per pixel */            (1 + ctx->alpha_bits + 1) + 7 >> 3);
    1352             :     }
    1353             : 
    1354           4 :     avctx->codec_tag   = ctx->profile_info->tag;
    1355             : 
    1356           8 :     av_log(avctx, AV_LOG_DEBUG,
    1357             :            "profile %d, %d slices, interlacing: %s, %d bits per MB\n",
    1358           4 :            ctx->profile, ctx->slices_per_picture * ctx->pictures_per_frame,
    1359             :            interlaced ? "yes" : "no", ctx->bits_per_mb);
    1360           4 :     av_log(avctx, AV_LOG_DEBUG, "frame size upper bound: %d\n",
    1361             :            ctx->frame_size_upper_bound);
    1362             : 
    1363           4 :     return 0;
    1364             : }
    1365             : 
    1366             : #define OFFSET(x) offsetof(ProresContext, x)
    1367             : #define VE     AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
    1368             : 
    1369             : static const AVOption options[] = {
    1370             :     { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
    1371             :         AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
    1372             :     { "profile",       NULL, OFFSET(profile), AV_OPT_TYPE_INT,
    1373             :         { .i64 = PRORES_PROFILE_AUTO },
    1374             :         PRORES_PROFILE_AUTO, PRORES_PROFILE_4444XQ, VE, "profile" },
    1375             :     { "auto",         NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_AUTO },
    1376             :         0, 0, VE, "profile" },
    1377             :     { "proxy",         NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
    1378             :         0, 0, VE, "profile" },
    1379             :     { "lt",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
    1380             :         0, 0, VE, "profile" },
    1381             :     { "standard",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_STANDARD },
    1382             :         0, 0, VE, "profile" },
    1383             :     { "hq",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
    1384             :         0, 0, VE, "profile" },
    1385             :     { "4444",          NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 },
    1386             :         0, 0, VE, "profile" },
    1387             :     { "4444xq",        NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444XQ },
    1388             :         0, 0, VE, "profile" },
    1389             :     { "vendor", "vendor ID", OFFSET(vendor),
    1390             :         AV_OPT_TYPE_STRING, { .str = "Lavc" }, CHAR_MIN, CHAR_MAX, VE },
    1391             :     { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
    1392             :         AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8192, VE },
    1393             :     { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
    1394             :         { .i64 = -1 }, -1, QUANT_MAT_DEFAULT, VE, "quant_mat" },
    1395             :     { "auto",          NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 },
    1396             :         0, 0, VE, "quant_mat" },
    1397             :     { "proxy",         NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_PROXY },
    1398             :         0, 0, VE, "quant_mat" },
    1399             :     { "lt",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_LT },
    1400             :         0, 0, VE, "quant_mat" },
    1401             :     { "standard",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_STANDARD },
    1402             :         0, 0, VE, "quant_mat" },
    1403             :     { "hq",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_HQ },
    1404             :         0, 0, VE, "quant_mat" },
    1405             :     { "default",       NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
    1406             :         0, 0, VE, "quant_mat" },
    1407             :     { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT,
    1408             :         { .i64 = 16 }, 0, 16, VE },
    1409             :     { NULL }
    1410             : };
    1411             : 
    1412             : static const AVClass proresenc_class = {
    1413             :     .class_name = "ProRes encoder",
    1414             :     .item_name  = av_default_item_name,
    1415             :     .option     = options,
    1416             :     .version    = LIBAVUTIL_VERSION_INT,
    1417             : };
    1418             : 
    1419             : AVCodec ff_prores_ks_encoder = {
    1420             :     .name           = "prores_ks",
    1421             :     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"),
    1422             :     .type           = AVMEDIA_TYPE_VIDEO,
    1423             :     .id             = AV_CODEC_ID_PRORES,
    1424             :     .priv_data_size = sizeof(ProresContext),
    1425             :     .init           = encode_init,
    1426             :     .close          = encode_close,
    1427             :     .encode2        = encode_frame,
    1428             :     .capabilities   = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
    1429             :     .pix_fmts       = (const enum AVPixelFormat[]) {
    1430             :                           AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
    1431             :                           AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
    1432             :                       },
    1433             :     .priv_class     = &proresenc_class,
    1434             : };

Generated by: LCOV version 1.13