| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * VC3/DNxHD encoder | ||
| 3 | * Copyright (c) 2007 Baptiste Coudurier <baptiste dot coudurier at smartjog dot com> | ||
| 4 | * Copyright (c) 2011 MirriAd Ltd | ||
| 5 | * | ||
| 6 | * VC-3 encoder funded by the British Broadcasting Corporation | ||
| 7 | * 10 bit support added by MirriAd Ltd, Joseph Artsimovich <joseph@mirriad.com> | ||
| 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/attributes.h" | ||
| 27 | #include "libavutil/internal.h" | ||
| 28 | #include "libavutil/mem.h" | ||
| 29 | #include "libavutil/mem_internal.h" | ||
| 30 | #include "libavutil/opt.h" | ||
| 31 | |||
| 32 | #include "avcodec.h" | ||
| 33 | #include "blockdsp.h" | ||
| 34 | #include "codec_internal.h" | ||
| 35 | #include "encode.h" | ||
| 36 | #include "fdctdsp.h" | ||
| 37 | #include "mathops.h" | ||
| 38 | #include "mpegvideo.h" | ||
| 39 | #include "mpegvideoenc.h" | ||
| 40 | #include "pixblockdsp.h" | ||
| 41 | #include "profiles.h" | ||
| 42 | #include "dnxhdenc.h" | ||
| 43 | |||
| 44 | // The largest value that will not lead to overflow for 10-bit samples. | ||
| 45 | #define DNX10BIT_QMAT_SHIFT 18 | ||
| 46 | #define RC_VARIANCE 1 // use variance or ssd for fast rc | ||
| 47 | #define LAMBDA_FRAC_BITS 10 | ||
| 48 | |||
| 49 | #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM | ||
| 50 | static const AVOption options[] = { | ||
| 51 | { "nitris_compat", "encode with Avid Nitris compatibility", | ||
| 52 | offsetof(DNXHDEncContext, nitris_compat), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, | ||
| 53 | { "ibias", "intra quant bias", | ||
| 54 | offsetof(DNXHDEncContext, intra_quant_bias), AV_OPT_TYPE_INT, | ||
| 55 | { .i64 = 0 }, INT_MIN, INT_MAX, VE }, | ||
| 56 | { "profile", NULL, offsetof(DNXHDEncContext, profile), AV_OPT_TYPE_INT, | ||
| 57 | { .i64 = AV_PROFILE_DNXHD }, | ||
| 58 | AV_PROFILE_DNXHD, AV_PROFILE_DNXHR_444, VE, .unit = "profile" }, | ||
| 59 | { "dnxhd", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_PROFILE_DNXHD }, | ||
| 60 | 0, 0, VE, .unit = "profile" }, | ||
| 61 | { "dnxhr_444", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_PROFILE_DNXHR_444 }, | ||
| 62 | 0, 0, VE, .unit = "profile" }, | ||
| 63 | { "dnxhr_hqx", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_PROFILE_DNXHR_HQX }, | ||
| 64 | 0, 0, VE, .unit = "profile" }, | ||
| 65 | { "dnxhr_hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_PROFILE_DNXHR_HQ }, | ||
| 66 | 0, 0, VE, .unit = "profile" }, | ||
| 67 | { "dnxhr_sq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_PROFILE_DNXHR_SQ }, | ||
| 68 | 0, 0, VE, .unit = "profile" }, | ||
| 69 | { "dnxhr_lb", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_PROFILE_DNXHR_LB }, | ||
| 70 | 0, 0, VE, .unit = "profile" }, | ||
| 71 | { NULL } | ||
| 72 | }; | ||
| 73 | |||
| 74 | static const AVClass dnxhd_class = { | ||
| 75 | .class_name = "dnxhd", | ||
| 76 | .item_name = av_default_item_name, | ||
| 77 | .option = options, | ||
| 78 | .version = LIBAVUTIL_VERSION_INT, | ||
| 79 | }; | ||
| 80 | |||
| 81 | 97920 | static void dnxhd_8bit_get_pixels_8x4_sym(int16_t *restrict block, | |
| 82 | const uint8_t *pixels, | ||
| 83 | ptrdiff_t line_size) | ||
| 84 | { | ||
| 85 | int i; | ||
| 86 |
2/2✓ Branch 0 taken 391680 times.
✓ Branch 1 taken 97920 times.
|
489600 | for (i = 0; i < 4; i++) { |
| 87 | 391680 | block[0] = pixels[0]; | |
| 88 | 391680 | block[1] = pixels[1]; | |
| 89 | 391680 | block[2] = pixels[2]; | |
| 90 | 391680 | block[3] = pixels[3]; | |
| 91 | 391680 | block[4] = pixels[4]; | |
| 92 | 391680 | block[5] = pixels[5]; | |
| 93 | 391680 | block[6] = pixels[6]; | |
| 94 | 391680 | block[7] = pixels[7]; | |
| 95 | 391680 | pixels += line_size; | |
| 96 | 391680 | block += 8; | |
| 97 | } | ||
| 98 | 97920 | memcpy(block, block - 8, sizeof(*block) * 8); | |
| 99 | 97920 | memcpy(block + 8, block - 16, sizeof(*block) * 8); | |
| 100 | 97920 | memcpy(block + 16, block - 24, sizeof(*block) * 8); | |
| 101 | 97920 | memcpy(block + 24, block - 32, sizeof(*block) * 8); | |
| 102 | 97920 | } | |
| 103 | |||
| 104 | static av_always_inline | ||
| 105 | 43200 | void dnxhd_10bit_get_pixels_8x4_sym(int16_t *restrict block, | |
| 106 | const uint8_t *pixels, | ||
| 107 | ptrdiff_t line_size) | ||
| 108 | { | ||
| 109 | 43200 | memcpy(block + 0 * 8, pixels + 0 * line_size, 8 * sizeof(*block)); | |
| 110 | 43200 | memcpy(block + 7 * 8, pixels + 0 * line_size, 8 * sizeof(*block)); | |
| 111 | 43200 | memcpy(block + 1 * 8, pixels + 1 * line_size, 8 * sizeof(*block)); | |
| 112 | 43200 | memcpy(block + 6 * 8, pixels + 1 * line_size, 8 * sizeof(*block)); | |
| 113 | 43200 | memcpy(block + 2 * 8, pixels + 2 * line_size, 8 * sizeof(*block)); | |
| 114 | 43200 | memcpy(block + 5 * 8, pixels + 2 * line_size, 8 * sizeof(*block)); | |
| 115 | 43200 | memcpy(block + 3 * 8, pixels + 3 * line_size, 8 * sizeof(*block)); | |
| 116 | 43200 | memcpy(block + 4 * 8, pixels + 3 * line_size, 8 * sizeof(*block)); | |
| 117 | 43200 | } | |
| 118 | |||
| 119 | ✗ | static int dnxhd_10bit_dct_quantize_444(MPVEncContext *ctx, int16_t *block, | |
| 120 | int n, int qscale, int *overflow) | ||
| 121 | { | ||
| 122 | int i, j, level, last_non_zero, start_i; | ||
| 123 | const int *qmat; | ||
| 124 | ✗ | const uint8_t *scantable = ctx->c.intra_scantable.scantable; | |
| 125 | int bias; | ||
| 126 | ✗ | int max = 0; | |
| 127 | unsigned int threshold1, threshold2; | ||
| 128 | |||
| 129 | ✗ | ctx->fdsp.fdct(block); | |
| 130 | |||
| 131 | ✗ | block[0] = (block[0] + 2) >> 2; | |
| 132 | ✗ | start_i = 1; | |
| 133 | ✗ | last_non_zero = 0; | |
| 134 | ✗ | qmat = n < 4 ? ctx->q_intra_matrix[qscale] : ctx->q_chroma_intra_matrix[qscale]; | |
| 135 | ✗ | bias= ctx->intra_quant_bias * (1 << (16 - 8)); | |
| 136 | ✗ | threshold1 = (1 << 16) - bias - 1; | |
| 137 | ✗ | threshold2 = (threshold1 << 1); | |
| 138 | |||
| 139 | ✗ | for (i = 63; i >= start_i; i--) { | |
| 140 | ✗ | j = scantable[i]; | |
| 141 | ✗ | level = block[j] * qmat[j]; | |
| 142 | |||
| 143 | ✗ | if (((unsigned)(level + threshold1)) > threshold2) { | |
| 144 | ✗ | last_non_zero = i; | |
| 145 | ✗ | break; | |
| 146 | } else{ | ||
| 147 | ✗ | block[j]=0; | |
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 151 | ✗ | for (i = start_i; i <= last_non_zero; i++) { | |
| 152 | ✗ | j = scantable[i]; | |
| 153 | ✗ | level = block[j] * qmat[j]; | |
| 154 | |||
| 155 | ✗ | if (((unsigned)(level + threshold1)) > threshold2) { | |
| 156 | ✗ | if (level > 0) { | |
| 157 | ✗ | level = (bias + level) >> 16; | |
| 158 | ✗ | block[j] = level; | |
| 159 | } else{ | ||
| 160 | ✗ | level = (bias - level) >> 16; | |
| 161 | ✗ | block[j] = -level; | |
| 162 | } | ||
| 163 | ✗ | max |= level; | |
| 164 | } else { | ||
| 165 | ✗ | block[j] = 0; | |
| 166 | } | ||
| 167 | } | ||
| 168 | ✗ | *overflow = ctx->max_qcoeff < max; //overflow might have happened | |
| 169 | |||
| 170 | /* we need this permutation so that we correct the IDCT, we only permute the !=0 elements */ | ||
| 171 | ✗ | if (ctx->c.idsp.perm_type != FF_IDCT_PERM_NONE) | |
| 172 | ✗ | ff_block_permute(block, ctx->c.idsp.idct_permutation, | |
| 173 | scantable, last_non_zero); | ||
| 174 | |||
| 175 | ✗ | return last_non_zero; | |
| 176 | } | ||
| 177 | |||
| 178 | 3945600 | static int dnxhd_10bit_dct_quantize(MPVEncContext *ctx, int16_t *block, | |
| 179 | int n, int qscale, int *overflow) | ||
| 180 | { | ||
| 181 | 3945600 | const uint8_t *scantable = ctx->c.intra_scantable.scantable; | |
| 182 |
2/2✓ Branch 0 taken 1972800 times.
✓ Branch 1 taken 1972800 times.
|
3945600 | const int *qmat = n<4 ? ctx->q_intra_matrix[qscale] : ctx->q_chroma_intra_matrix[qscale]; |
| 183 | 3945600 | int last_non_zero = 0; | |
| 184 | int i; | ||
| 185 | |||
| 186 | 3945600 | ctx->fdsp.fdct(block); | |
| 187 | |||
| 188 | // Divide by 4 with rounding, to compensate scaling of DCT coefficients | ||
| 189 | 3945600 | block[0] = (block[0] + 2) >> 2; | |
| 190 | |||
| 191 |
2/2✓ Branch 0 taken 248572800 times.
✓ Branch 1 taken 3945600 times.
|
252518400 | for (i = 1; i < 64; ++i) { |
| 192 | 248572800 | int j = scantable[i]; | |
| 193 | 248572800 | int sign = FF_SIGNBIT(block[j]); | |
| 194 | 248572800 | int level = (block[j] ^ sign) - sign; | |
| 195 | 248572800 | level = level * qmat[j] >> DNX10BIT_QMAT_SHIFT; | |
| 196 | 248572800 | block[j] = (level ^ sign) - sign; | |
| 197 |
2/2✓ Branch 0 taken 32824223 times.
✓ Branch 1 taken 215748577 times.
|
248572800 | if (level) |
| 198 | 32824223 | last_non_zero = i; | |
| 199 | } | ||
| 200 | |||
| 201 | /* we need this permutation so that we correct the IDCT, we only permute the !=0 elements */ | ||
| 202 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3945600 times.
|
3945600 | if (ctx->c.idsp.perm_type != FF_IDCT_PERM_NONE) |
| 203 | ✗ | ff_block_permute(block, ctx->c.idsp.idct_permutation, | |
| 204 | scantable, last_non_zero); | ||
| 205 | |||
| 206 | 3945600 | return last_non_zero; | |
| 207 | } | ||
| 208 | |||
| 209 | 73 | static av_cold int dnxhd_init_vlc(DNXHDEncContext *ctx) | |
| 210 | { | ||
| 211 | int i, j, level, run; | ||
| 212 | 73 | int max_level = 1 << (ctx->bit_depth + 2); | |
| 213 | |||
| 214 |
1/2✓ Branch 1 taken 73 times.
✗ Branch 2 not taken.
|
73 | if (!FF_ALLOCZ_TYPED_ARRAY(ctx->orig_vlc_codes, max_level * 4) || |
| 215 |
1/2✓ Branch 1 taken 73 times.
✗ Branch 2 not taken.
|
73 | !FF_ALLOCZ_TYPED_ARRAY(ctx->orig_vlc_bits, max_level * 4) || |
| 216 |
1/2✓ Branch 1 taken 73 times.
✗ Branch 2 not taken.
|
73 | !(ctx->run_codes = av_mallocz(63 * 2)) || |
| 217 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 73 times.
|
73 | !(ctx->run_bits = av_mallocz(63))) |
| 218 | ✗ | return AVERROR(ENOMEM); | |
| 219 | 73 | ctx->vlc_codes = ctx->orig_vlc_codes + max_level * 2; | |
| 220 | 73 | ctx->vlc_bits = ctx->orig_vlc_bits + max_level * 2; | |
| 221 |
2/2✓ Branch 0 taken 192512 times.
✓ Branch 1 taken 73 times.
|
192585 | for (level = -max_level; level < max_level; level++) { |
| 222 |
2/2✓ Branch 0 taken 385024 times.
✓ Branch 1 taken 192512 times.
|
577536 | for (run = 0; run < 2; run++) { |
| 223 | 385024 | int index = level * (1 << 1) | run; | |
| 224 | 385024 | int sign, offset = 0, alevel = level; | |
| 225 | |||
| 226 | 385024 | MASK_ABS(sign, alevel); | |
| 227 |
2/2✓ Branch 0 taken 366190 times.
✓ Branch 1 taken 18834 times.
|
385024 | if (alevel > 64) { |
| 228 | 366190 | offset = (alevel - 1) >> 6; | |
| 229 | 366190 | alevel -= offset << 6; | |
| 230 | } | ||
| 231 |
2/2✓ Branch 0 taken 65136947 times.
✓ Branch 1 taken 73 times.
|
65137020 | for (j = 0; j < 257; j++) { |
| 232 |
4/4✓ Branch 0 taken 1197496 times.
✓ Branch 1 taken 63939451 times.
✓ Branch 2 taken 1163352 times.
✓ Branch 3 taken 34144 times.
|
65136947 | if (ctx->cid_table->ac_info[2*j+0] >> 1 == alevel && |
| 233 |
5/6✓ Branch 0 taken 549285 times.
✓ Branch 1 taken 614067 times.
✓ Branch 2 taken 549285 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 390917 times.
✓ Branch 5 taken 192512 times.
|
1197496 | (!offset || (ctx->cid_table->ac_info[2*j+1] & 1) && offset) && |
| 234 |
3/4✓ Branch 0 taken 192439 times.
✓ Branch 1 taken 198478 times.
✓ Branch 2 taken 192439 times.
✗ Branch 3 not taken.
|
390917 | (!run || (ctx->cid_table->ac_info[2*j+1] & 2) && run)) { |
| 235 | av_assert1(!ctx->vlc_codes[index]); | ||
| 236 |
2/2✓ Branch 0 taken 384878 times.
✓ Branch 1 taken 73 times.
|
384951 | if (alevel) { |
| 237 | 384878 | ctx->vlc_codes[index] = | |
| 238 | 384878 | (ctx->cid_table->ac_codes[j] << 1) | (sign & 1); | |
| 239 | 384878 | ctx->vlc_bits[index] = ctx->cid_table->ac_bits[j] + 1; | |
| 240 | } else { | ||
| 241 | 73 | ctx->vlc_codes[index] = ctx->cid_table->ac_codes[j]; | |
| 242 | 73 | ctx->vlc_bits[index] = ctx->cid_table->ac_bits[j]; | |
| 243 | } | ||
| 244 | 384951 | break; | |
| 245 | } | ||
| 246 | } | ||
| 247 |
3/4✓ Branch 0 taken 384878 times.
✓ Branch 1 taken 146 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 384878 times.
|
385024 | av_assert0(!alevel || j < 257); |
| 248 |
2/2✓ Branch 0 taken 366190 times.
✓ Branch 1 taken 18834 times.
|
385024 | if (offset) { |
| 249 | 366190 | ctx->vlc_codes[index] = | |
| 250 | 366190 | (ctx->vlc_codes[index] << ctx->cid_table->index_bits) | offset; | |
| 251 | 366190 | ctx->vlc_bits[index] += ctx->cid_table->index_bits; | |
| 252 | } | ||
| 253 | } | ||
| 254 | } | ||
| 255 |
2/2✓ Branch 0 taken 4526 times.
✓ Branch 1 taken 73 times.
|
4599 | for (i = 0; i < 62; i++) { |
| 256 | 4526 | int run = ctx->cid_table->run[i]; | |
| 257 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4526 times.
|
4526 | av_assert0(run < 63); |
| 258 | 4526 | ctx->run_codes[run] = ctx->cid_table->run_codes[i]; | |
| 259 | 4526 | ctx->run_bits[run] = ctx->cid_table->run_bits[i]; | |
| 260 | } | ||
| 261 | 73 | return 0; | |
| 262 | } | ||
| 263 | |||
| 264 | 73 | static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) | |
| 265 | { | ||
| 266 | // init first elem to 1 to avoid div by 0 in convert_matrix | ||
| 267 | 73 | uint16_t weight_matrix[64] = { 1, }; // convert_matrix needs uint16_t* | |
| 268 | 73 | const uint8_t *luma_weight_table = ctx->cid_table->luma_weight; | |
| 269 | 73 | const uint8_t *chroma_weight_table = ctx->cid_table->chroma_weight; | |
| 270 | |||
| 271 |
1/2✓ Branch 1 taken 73 times.
✗ Branch 2 not taken.
|
73 | if (!FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_l, ctx->m.c.avctx->qmax + 1) || |
| 272 |
1/2✓ Branch 1 taken 73 times.
✗ Branch 2 not taken.
|
73 | !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_c, ctx->m.c.avctx->qmax + 1) || |
| 273 |
1/2✓ Branch 1 taken 73 times.
✗ Branch 2 not taken.
|
73 | !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_l16, ctx->m.c.avctx->qmax + 1) || |
| 274 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 73 times.
|
73 | !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_c16, ctx->m.c.avctx->qmax + 1)) |
| 275 | ✗ | return AVERROR(ENOMEM); | |
| 276 | |||
| 277 |
2/2✓ Branch 0 taken 66 times.
✓ Branch 1 taken 7 times.
|
73 | if (ctx->bit_depth == 8) { |
| 278 |
2/2✓ Branch 0 taken 4158 times.
✓ Branch 1 taken 66 times.
|
4224 | for (int i = 1; i < 64; i++) { |
| 279 | 4158 | int j = ctx->m.c.idsp.idct_permutation[ff_zigzag_direct[i]]; | |
| 280 | 4158 | weight_matrix[j] = ctx->cid_table->luma_weight[i]; | |
| 281 | } | ||
| 282 | 66 | ff_convert_matrix(&ctx->m, ctx->qmatrix_l, ctx->qmatrix_l16, | |
| 283 | weight_matrix, ctx->intra_quant_bias, 1, | ||
| 284 | 66 | ctx->m.c.avctx->qmax, 1); | |
| 285 |
2/2✓ Branch 0 taken 4158 times.
✓ Branch 1 taken 66 times.
|
4224 | for (int i = 1; i < 64; i++) { |
| 286 | 4158 | int j = ctx->m.c.idsp.idct_permutation[ff_zigzag_direct[i]]; | |
| 287 | 4158 | weight_matrix[j] = ctx->cid_table->chroma_weight[i]; | |
| 288 | } | ||
| 289 | 66 | ff_convert_matrix(&ctx->m, ctx->qmatrix_c, ctx->qmatrix_c16, | |
| 290 | weight_matrix, ctx->intra_quant_bias, 1, | ||
| 291 | 66 | ctx->m.c.avctx->qmax, 1); | |
| 292 | |||
| 293 |
2/2✓ Branch 0 taken 42184 times.
✓ Branch 1 taken 66 times.
|
42250 | for (int qscale = 1; qscale <= ctx->m.c.avctx->qmax; qscale++) { |
| 294 |
2/2✓ Branch 0 taken 2699776 times.
✓ Branch 1 taken 42184 times.
|
2741960 | for (int i = 0; i < 64; i++) { |
| 295 | 2699776 | ctx->qmatrix_l[qscale][i] <<= 2; | |
| 296 | 2699776 | ctx->qmatrix_c[qscale][i] <<= 2; | |
| 297 | 2699776 | ctx->qmatrix_l16[qscale][0][i] <<= 2; | |
| 298 | 2699776 | ctx->qmatrix_l16[qscale][1][i] <<= 2; | |
| 299 | 2699776 | ctx->qmatrix_c16[qscale][0][i] <<= 2; | |
| 300 | 2699776 | ctx->qmatrix_c16[qscale][1][i] <<= 2; | |
| 301 | } | ||
| 302 | } | ||
| 303 | } else { | ||
| 304 | // 10-bit | ||
| 305 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 7 times.
|
63 | for (int qscale = 1; qscale <= ctx->m.c.avctx->qmax; qscale++) { |
| 306 |
2/2✓ Branch 0 taken 3528 times.
✓ Branch 1 taken 56 times.
|
3584 | for (int i = 1; i < 64; i++) { |
| 307 | 3528 | int j = ff_zigzag_direct[i]; | |
| 308 | |||
| 309 | /* The quantization formula from the VC-3 standard is: | ||
| 310 | * quantized = sign(block[i]) * floor(abs(block[i]/s) * p / | ||
| 311 | * (qscale * weight_table[i])) | ||
| 312 | * Where p is 32 for 8-bit samples and 8 for 10-bit ones. | ||
| 313 | * The s factor compensates scaling of DCT coefficients done by | ||
| 314 | * the DCT routines, and therefore is not present in standard. | ||
| 315 | * It's 8 for 8-bit samples and 4 for 10-bit ones. | ||
| 316 | * We want values of ctx->qtmatrix_l and ctx->qtmatrix_r to be: | ||
| 317 | * ((1 << DNX10BIT_QMAT_SHIFT) * (p / s)) / | ||
| 318 | * (qscale * weight_table[i]) | ||
| 319 | * For 10-bit samples, p / s == 2 */ | ||
| 320 | 3528 | ctx->qmatrix_l[qscale][j] = (1 << (DNX10BIT_QMAT_SHIFT + 1)) / | |
| 321 | 3528 | (qscale * luma_weight_table[i]); | |
| 322 | 3528 | ctx->qmatrix_c[qscale][j] = (1 << (DNX10BIT_QMAT_SHIFT + 1)) / | |
| 323 | 3528 | (qscale * chroma_weight_table[i]); | |
| 324 | } | ||
| 325 | } | ||
| 326 | } | ||
| 327 | |||
| 328 | 73 | ctx->m.q_chroma_intra_matrix16 = ctx->qmatrix_c16; | |
| 329 | 73 | ctx->m.q_chroma_intra_matrix = ctx->qmatrix_c; | |
| 330 | 73 | ctx->m.q_intra_matrix16 = ctx->qmatrix_l16; | |
| 331 | 73 | ctx->m.q_intra_matrix = ctx->qmatrix_l; | |
| 332 | |||
| 333 | 73 | return 0; | |
| 334 | } | ||
| 335 | |||
| 336 | 73 | static av_cold int dnxhd_init_rc(DNXHDEncContext *ctx) | |
| 337 | { | ||
| 338 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 73 times.
|
73 | if (!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_rc, (ctx->m.c.avctx->qmax + 1) * ctx->m.c.mb_num)) |
| 339 | ✗ | return AVERROR(ENOMEM); | |
| 340 | |||
| 341 |
2/2✓ Branch 0 taken 58 times.
✓ Branch 1 taken 15 times.
|
73 | if (ctx->m.c.avctx->mb_decision != FF_MB_DECISION_RD) { |
| 342 |
1/2✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
|
58 | if (!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_cmp, ctx->m.c.mb_num) || |
| 343 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
|
58 | !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_cmp_tmp, ctx->m.c.mb_num)) |
| 344 | ✗ | return AVERROR(ENOMEM); | |
| 345 | } | ||
| 346 | 73 | ctx->frame_bits = (ctx->coding_unit_size - | |
| 347 | 73 | ctx->data_offset - 4 - ctx->min_padding) * 8; | |
| 348 | 73 | ctx->qscale = 1; | |
| 349 | 73 | ctx->lambda = 2 << LAMBDA_FRAC_BITS; // qscale 2 | |
| 350 | 73 | return 0; | |
| 351 | } | ||
| 352 | |||
| 353 | 73 | static av_cold int dnxhd_encode_init(AVCodecContext *avctx) | |
| 354 | { | ||
| 355 | 73 | DNXHDEncContext *ctx = avctx->priv_data; | |
| 356 | int i, ret; | ||
| 357 | |||
| 358 |
2/3✓ Branch 0 taken 66 times.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
73 | switch (avctx->pix_fmt) { |
| 359 | 66 | case AV_PIX_FMT_YUV422P: | |
| 360 | 66 | ctx->bit_depth = 8; | |
| 361 | 66 | break; | |
| 362 | 7 | case AV_PIX_FMT_YUV422P10: | |
| 363 | case AV_PIX_FMT_YUV444P10: | ||
| 364 | case AV_PIX_FMT_GBRP10: | ||
| 365 | 7 | ctx->bit_depth = 10; | |
| 366 | 7 | break; | |
| 367 | } | ||
| 368 | |||
| 369 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
73 | if ((ctx->profile == AV_PROFILE_DNXHR_444 && (avctx->pix_fmt != AV_PIX_FMT_YUV444P10 && |
| 370 | ✗ | avctx->pix_fmt != AV_PIX_FMT_GBRP10)) || | |
| 371 |
2/4✓ Branch 0 taken 73 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 73 times.
✗ Branch 3 not taken.
|
73 | (ctx->profile != AV_PROFILE_DNXHR_444 && (avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || |
| 372 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
|
73 | avctx->pix_fmt == AV_PIX_FMT_GBRP10))) { |
| 373 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
| 374 | "pixel format is incompatible with DNxHD profile\n"); | ||
| 375 | ✗ | return AVERROR(EINVAL); | |
| 376 | } | ||
| 377 | |||
| 378 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
73 | if (ctx->profile == AV_PROFILE_DNXHR_HQX && avctx->pix_fmt != AV_PIX_FMT_YUV422P10) { |
| 379 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
| 380 | "pixel format is incompatible with DNxHR HQX profile\n"); | ||
| 381 | ✗ | return AVERROR(EINVAL); | |
| 382 | } | ||
| 383 | |||
| 384 |
2/2✓ Branch 0 taken 61 times.
✓ Branch 1 taken 12 times.
|
73 | if ((ctx->profile == AV_PROFILE_DNXHR_LB || |
| 385 |
2/2✓ Branch 0 taken 53 times.
✓ Branch 1 taken 8 times.
|
61 | ctx->profile == AV_PROFILE_DNXHR_SQ || |
| 386 |
3/4✓ Branch 0 taken 20 times.
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 40 times.
|
73 | ctx->profile == AV_PROFILE_DNXHR_HQ) && avctx->pix_fmt != AV_PIX_FMT_YUV422P) { |
| 387 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
| 388 | "pixel format is incompatible with DNxHR LB/SQ/HQ profile\n"); | ||
| 389 | ✗ | return AVERROR(EINVAL); | |
| 390 | } | ||
| 391 | |||
| 392 | 73 | ctx->is_444 = ctx->profile == AV_PROFILE_DNXHR_444; | |
| 393 | 73 | avctx->profile = ctx->profile; | |
| 394 | 73 | ctx->cid = ff_dnxhd_find_cid(avctx, ctx->bit_depth); | |
| 395 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
|
73 | if (!ctx->cid) { |
| 396 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
| 397 | "video parameters incompatible with DNxHD. Valid DNxHD profiles:\n"); | ||
| 398 | ✗ | ff_dnxhd_print_profiles(avctx, AV_LOG_ERROR); | |
| 399 | ✗ | return AVERROR(EINVAL); | |
| 400 | } | ||
| 401 | 73 | av_log(avctx, AV_LOG_DEBUG, "cid %d\n", ctx->cid); | |
| 402 | |||
| 403 |
3/4✓ Branch 0 taken 40 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
|
73 | if (ctx->cid >= 1270 && ctx->cid <= 1274) |
| 404 | 40 | avctx->codec_tag = MKTAG('A','V','d','h'); | |
| 405 | |||
| 406 |
2/4✓ Branch 0 taken 73 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 73 times.
|
73 | if (avctx->width < 256 || avctx->height < 120) { |
| 407 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
| 408 | "Input dimensions too small, input must be at least 256x120\n"); | ||
| 409 | ✗ | return AVERROR(EINVAL); | |
| 410 | } | ||
| 411 | |||
| 412 | 73 | ctx->cid_table = ff_dnxhd_get_cid_table(ctx->cid); | |
| 413 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
|
73 | av_assert0(ctx->cid_table); |
| 414 | |||
| 415 | 73 | ctx->m.c.avctx = avctx; | |
| 416 | 73 | ctx->m.c.mb_intra = 1; | |
| 417 | 73 | ctx->m.c.h263_aic = 1; | |
| 418 | |||
| 419 | 73 | avctx->bits_per_raw_sample = ctx->bit_depth; | |
| 420 | |||
| 421 | 73 | ff_blockdsp_init(&ctx->m.c.bdsp); | |
| 422 | 73 | ff_fdctdsp_init(&ctx->m.fdsp, avctx); | |
| 423 | 73 | ff_mpv_idct_init(&ctx->m.c); | |
| 424 | 73 | ff_mpegvideoencdsp_init(&ctx->m.mpvencdsp, avctx); | |
| 425 | 73 | ff_pixblockdsp_init(&ctx->m.pdsp, ctx->bit_depth); | |
| 426 | 73 | ff_dct_encode_init(&ctx->m); | |
| 427 | |||
| 428 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 33 times.
|
73 | if (ctx->profile != AV_PROFILE_DNXHD) |
| 429 | 40 | ff_videodsp_init(&ctx->m.c.vdsp, ctx->bit_depth); | |
| 430 | |||
| 431 |
2/4✓ Branch 0 taken 73 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 73 times.
|
73 | if (ctx->is_444 || ctx->profile == AV_PROFILE_DNXHR_HQX) { |
| 432 | ✗ | ctx->m.dct_quantize = dnxhd_10bit_dct_quantize_444; | |
| 433 | ✗ | ctx->get_pixels_8x4_sym = dnxhd_10bit_get_pixels_8x4_sym; | |
| 434 | ✗ | ctx->block_width_l2 = 4; | |
| 435 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 66 times.
|
73 | } else if (ctx->bit_depth == 10) { |
| 436 | 7 | ctx->m.dct_quantize = dnxhd_10bit_dct_quantize; | |
| 437 | 7 | ctx->get_pixels_8x4_sym = dnxhd_10bit_get_pixels_8x4_sym; | |
| 438 | 7 | ctx->block_width_l2 = 4; | |
| 439 | } else { | ||
| 440 | 66 | ctx->get_pixels_8x4_sym = dnxhd_8bit_get_pixels_8x4_sym; | |
| 441 | 66 | ctx->block_width_l2 = 3; | |
| 442 | } | ||
| 443 | |||
| 444 | 73 | ff_dnxhdenc_init(ctx); | |
| 445 | |||
| 446 | 73 | ctx->m.c.mb_height = (avctx->height + 15) / 16; | |
| 447 | 73 | ctx->m.c.mb_width = (avctx->width + 15) / 16; | |
| 448 | |||
| 449 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 62 times.
|
73 | if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) { |
| 450 | 11 | ctx->interlaced = 1; | |
| 451 | 11 | ctx->m.c.mb_height /= 2; | |
| 452 | } | ||
| 453 | |||
| 454 |
3/4✓ Branch 0 taken 11 times.
✓ Branch 1 taken 62 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
|
73 | if (ctx->interlaced && ctx->profile != AV_PROFILE_DNXHD) { |
| 455 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
| 456 | "Interlaced encoding is not supported for DNxHR profiles.\n"); | ||
| 457 | ✗ | return AVERROR(EINVAL); | |
| 458 | } | ||
| 459 | |||
| 460 | 73 | ctx->m.c.mb_num = ctx->m.c.mb_height * ctx->m.c.mb_width; | |
| 461 | |||
| 462 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 33 times.
|
73 | if (ctx->cid_table->frame_size == DNXHD_VARIABLE) { |
| 463 | 40 | ctx->frame_size = ff_dnxhd_get_hr_frame_size(ctx->cid, | |
| 464 | avctx->width, avctx->height); | ||
| 465 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
|
40 | av_assert0(ctx->frame_size >= 0); |
| 466 | 40 | ctx->coding_unit_size = ctx->frame_size; | |
| 467 | } else { | ||
| 468 | 33 | ctx->frame_size = ctx->cid_table->frame_size; | |
| 469 | 33 | ctx->coding_unit_size = ctx->cid_table->coding_unit_size; | |
| 470 | } | ||
| 471 | |||
| 472 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 61 times.
|
73 | if (ctx->m.c.mb_height > 68) |
| 473 | 12 | ctx->data_offset = 0x170 + (ctx->m.c.mb_height << 2); | |
| 474 | else | ||
| 475 | 61 | ctx->data_offset = 0x280; | |
| 476 | |||
| 477 | // XXX tune lbias/cbias | ||
| 478 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 73 times.
|
73 | if ((ret = dnxhd_init_qmat(ctx, ctx->intra_quant_bias, 0)) < 0) |
| 479 | ✗ | return ret; | |
| 480 | |||
| 481 | /* Avid Nitris hardware decoder requires a minimum amount of padding | ||
| 482 | * in the coding unit payload */ | ||
| 483 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
|
73 | if (ctx->nitris_compat) |
| 484 | ✗ | ctx->min_padding = 1600; | |
| 485 | |||
| 486 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 73 times.
|
73 | if ((ret = dnxhd_init_vlc(ctx)) < 0) |
| 487 | ✗ | return ret; | |
| 488 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 73 times.
|
73 | if ((ret = dnxhd_init_rc(ctx)) < 0) |
| 489 | ✗ | return ret; | |
| 490 | |||
| 491 |
1/2✓ Branch 1 taken 73 times.
✗ Branch 2 not taken.
|
73 | if (!FF_ALLOCZ_TYPED_ARRAY(ctx->slice_size, ctx->m.c.mb_height) || |
| 492 |
1/2✓ Branch 1 taken 73 times.
✗ Branch 2 not taken.
|
73 | !FF_ALLOCZ_TYPED_ARRAY(ctx->slice_offs, ctx->m.c.mb_height) || |
| 493 |
1/2✓ Branch 1 taken 73 times.
✗ Branch 2 not taken.
|
73 | !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_bits, ctx->m.c.mb_num) || |
| 494 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 73 times.
|
73 | !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_qscale, ctx->m.c.mb_num)) |
| 495 | ✗ | return AVERROR(ENOMEM); | |
| 496 | |||
| 497 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
|
73 | if (avctx->active_thread_type == FF_THREAD_SLICE) { |
| 498 | ✗ | if (avctx->thread_count > MAX_THREADS) { | |
| 499 | ✗ | av_log(avctx, AV_LOG_ERROR, "too many threads\n"); | |
| 500 | ✗ | return AVERROR(EINVAL); | |
| 501 | } | ||
| 502 | } | ||
| 503 | |||
| 504 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
|
73 | if (avctx->qmax <= 1) { |
| 505 | ✗ | av_log(avctx, AV_LOG_ERROR, "qmax must be at least 2\n"); | |
| 506 | ✗ | return AVERROR(EINVAL); | |
| 507 | } | ||
| 508 | |||
| 509 | 73 | ctx->thread[0] = ctx; | |
| 510 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
|
73 | if (avctx->active_thread_type == FF_THREAD_SLICE) { |
| 511 | ✗ | for (i = 1; i < avctx->thread_count; i++) { | |
| 512 | ✗ | ctx->thread[i] = av_memdup(ctx, sizeof(DNXHDEncContext)); | |
| 513 | ✗ | if (!ctx->thread[i]) | |
| 514 | ✗ | return AVERROR(ENOMEM); | |
| 515 | } | ||
| 516 | } | ||
| 517 | |||
| 518 | 73 | return 0; | |
| 519 | } | ||
| 520 | |||
| 521 | 380 | static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf) | |
| 522 | { | ||
| 523 | 380 | DNXHDEncContext *ctx = avctx->priv_data; | |
| 524 | |||
| 525 | 380 | memset(buf, 0, ctx->data_offset); | |
| 526 | |||
| 527 | // * write prefix */ | ||
| 528 | 380 | AV_WB16(buf + 0x02, ctx->data_offset); | |
| 529 |
3/4✓ Branch 0 taken 200 times.
✓ Branch 1 taken 180 times.
✓ Branch 2 taken 200 times.
✗ Branch 3 not taken.
|
380 | if (ctx->cid >= 1270 && ctx->cid <= 1274) |
| 530 | 200 | buf[4] = 0x03; | |
| 531 | else | ||
| 532 | 180 | buf[4] = 0x01; | |
| 533 | |||
| 534 |
2/2✓ Branch 0 taken 110 times.
✓ Branch 1 taken 270 times.
|
380 | buf[5] = ctx->interlaced ? ctx->cur_field + 2 : 0x01; |
| 535 | 380 | buf[6] = 0x80; // crc flag off | |
| 536 | 380 | buf[7] = 0xa0; // reserved | |
| 537 | 380 | AV_WB16(buf + 0x18, avctx->height >> ctx->interlaced); // ALPF | |
| 538 | 380 | AV_WB16(buf + 0x1a, avctx->width); // SPL | |
| 539 | 380 | AV_WB16(buf + 0x1d, avctx->height >> ctx->interlaced); // NAL | |
| 540 | |||
| 541 |
2/2✓ Branch 0 taken 55 times.
✓ Branch 1 taken 325 times.
|
380 | buf[0x21] = ctx->bit_depth == 10 ? 0x58 : 0x38; |
| 542 | 380 | buf[0x22] = 0x88 + (ctx->interlaced << 2); | |
| 543 | 380 | AV_WB32(buf + 0x28, ctx->cid); // CID | |
| 544 |
2/2✓ Branch 0 taken 270 times.
✓ Branch 1 taken 110 times.
|
380 | buf[0x2c] = (!ctx->interlaced << 7) | (ctx->is_444 << 6) | (avctx->pix_fmt == AV_PIX_FMT_YUV444P10); |
| 545 | |||
| 546 | 380 | buf[0x5f] = 0x01; // UDL | |
| 547 | |||
| 548 | 380 | buf[0x167] = 0x02; // reserved | |
| 549 | 380 | AV_WB16(buf + 0x16a, ctx->m.c.mb_height * 4 + 4); // MSIPS | |
| 550 | 380 | AV_WB16(buf + 0x16c, ctx->m.c.mb_height); // Ns | |
| 551 | 380 | buf[0x16f] = 0x10; // reserved | |
| 552 | |||
| 553 | 380 | ctx->msip = buf + 0x170; | |
| 554 | 380 | return 0; | |
| 555 | } | ||
| 556 | |||
| 557 | 26918560 | static av_always_inline void dnxhd_encode_dc(PutBitContext *pb, DNXHDEncContext *ctx, int diff) | |
| 558 | { | ||
| 559 | int nbits; | ||
| 560 |
2/2✓ Branch 0 taken 12317800 times.
✓ Branch 1 taken 14600760 times.
|
26918560 | if (diff < 0) { |
| 561 | 12317800 | nbits = av_log2_16bit(-2 * diff); | |
| 562 | 12317800 | diff--; | |
| 563 | } else { | ||
| 564 | 14600760 | nbits = av_log2_16bit(2 * diff); | |
| 565 | } | ||
| 566 | 26918560 | put_bits(pb, ctx->cid_table->dc_bits[nbits] + nbits, | |
| 567 | 26918560 | (ctx->cid_table->dc_codes[nbits] << nbits) + | |
| 568 | 26918560 | av_zero_extend(diff, nbits)); | |
| 569 | 26918560 | } | |
| 570 | |||
| 571 | static av_always_inline | ||
| 572 | 26918560 | void dnxhd_encode_block(PutBitContext *pb, DNXHDEncContext *ctx, | |
| 573 | int16_t *block, int last_index, int n) | ||
| 574 | { | ||
| 575 | 26918560 | int last_non_zero = 0; | |
| 576 | int slevel, i, j; | ||
| 577 | |||
| 578 | 26918560 | dnxhd_encode_dc(pb, ctx, block[0] - ctx->m.last_dc[n]); | |
| 579 | 26918560 | ctx->m.last_dc[n] = block[0]; | |
| 580 | |||
| 581 |
2/2✓ Branch 0 taken 296815535 times.
✓ Branch 1 taken 26918560 times.
|
323734095 | for (i = 1; i <= last_index; i++) { |
| 582 | 296815535 | j = ctx->m.c.intra_scantable.permutated[i]; | |
| 583 | 296815535 | slevel = block[j]; | |
| 584 |
2/2✓ Branch 0 taken 111020901 times.
✓ Branch 1 taken 185794634 times.
|
296815535 | if (slevel) { |
| 585 | 111020901 | int run_level = i - last_non_zero - 1; | |
| 586 | 111020901 | int rlevel = slevel * (1 << 1) | !!run_level; | |
| 587 | 111020901 | put_bits(pb, ctx->vlc_bits[rlevel], ctx->vlc_codes[rlevel]); | |
| 588 |
2/2✓ Branch 0 taken 36001883 times.
✓ Branch 1 taken 75019018 times.
|
111020901 | if (run_level) |
| 589 | 36001883 | put_bits(pb, ctx->run_bits[run_level], | |
| 590 | 36001883 | ctx->run_codes[run_level]); | |
| 591 | 111020901 | last_non_zero = i; | |
| 592 | } | ||
| 593 | } | ||
| 594 | 26918560 | put_bits(pb, ctx->vlc_bits[0], ctx->vlc_codes[0]); // EOB | |
| 595 | 26918560 | } | |
| 596 | |||
| 597 | static av_always_inline | ||
| 598 | 3024000 | void dnxhd_unquantize_c(DNXHDEncContext *ctx, int16_t *block, int n, | |
| 599 | int qscale, int last_index) | ||
| 600 | { | ||
| 601 | const uint8_t *weight_matrix; | ||
| 602 | int level; | ||
| 603 | int i; | ||
| 604 | |||
| 605 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3024000 times.
|
3024000 | if (ctx->is_444) { |
| 606 | ✗ | weight_matrix = ((n % 6) < 2) ? ctx->cid_table->luma_weight | |
| 607 | ✗ | : ctx->cid_table->chroma_weight; | |
| 608 | } else { | ||
| 609 | 3024000 | weight_matrix = (n & 2) ? ctx->cid_table->chroma_weight | |
| 610 |
2/2✓ Branch 0 taken 1512000 times.
✓ Branch 1 taken 1512000 times.
|
3024000 | : ctx->cid_table->luma_weight; |
| 611 | } | ||
| 612 | |||
| 613 |
2/2✓ Branch 0 taken 32773315 times.
✓ Branch 1 taken 3024000 times.
|
35797315 | for (i = 1; i <= last_index; i++) { |
| 614 | 32773315 | int j = ctx->m.c.intra_scantable.permutated[i]; | |
| 615 | 32773315 | level = block[j]; | |
| 616 |
2/2✓ Branch 0 taken 16774641 times.
✓ Branch 1 taken 15998674 times.
|
32773315 | if (level) { |
| 617 |
2/2✓ Branch 0 taken 8458215 times.
✓ Branch 1 taken 8316426 times.
|
16774641 | if (level < 0) { |
| 618 | 8458215 | level = (1 - 2 * level) * qscale * weight_matrix[i]; | |
| 619 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8458215 times.
|
8458215 | if (ctx->bit_depth == 10) { |
| 620 | ✗ | if (weight_matrix[i] != 8) | |
| 621 | ✗ | level += 8; | |
| 622 | ✗ | level >>= 4; | |
| 623 | } else { | ||
| 624 |
2/2✓ Branch 0 taken 6479585 times.
✓ Branch 1 taken 1978630 times.
|
8458215 | if (weight_matrix[i] != 32) |
| 625 | 6479585 | level += 32; | |
| 626 | 8458215 | level >>= 6; | |
| 627 | } | ||
| 628 | 8458215 | level = -level; | |
| 629 | } else { | ||
| 630 | 8316426 | level = (2 * level + 1) * qscale * weight_matrix[i]; | |
| 631 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8316426 times.
|
8316426 | if (ctx->bit_depth == 10) { |
| 632 | ✗ | if (weight_matrix[i] != 8) | |
| 633 | ✗ | level += 8; | |
| 634 | ✗ | level >>= 4; | |
| 635 | } else { | ||
| 636 |
2/2✓ Branch 0 taken 6813970 times.
✓ Branch 1 taken 1502456 times.
|
8316426 | if (weight_matrix[i] != 32) |
| 637 | 6813970 | level += 32; | |
| 638 | 8316426 | level >>= 6; | |
| 639 | } | ||
| 640 | } | ||
| 641 | 16774641 | block[j] = level; | |
| 642 | } | ||
| 643 | } | ||
| 644 | 3024000 | } | |
| 645 | |||
| 646 | 3024000 | static av_always_inline int dnxhd_ssd_block(int16_t *qblock, int16_t *block) | |
| 647 | { | ||
| 648 | 3024000 | int score = 0; | |
| 649 | int i; | ||
| 650 |
2/2✓ Branch 0 taken 193536000 times.
✓ Branch 1 taken 3024000 times.
|
196560000 | for (i = 0; i < 64; i++) |
| 651 | 193536000 | score += (block[i] - qblock[i]) * (block[i] - qblock[i]); | |
| 652 | 3024000 | return score; | |
| 653 | } | ||
| 654 | |||
| 655 | static av_always_inline | ||
| 656 | 51881432 | int dnxhd_calc_ac_bits(DNXHDEncContext *ctx, int16_t *block, int last_index) | |
| 657 | { | ||
| 658 | 51881432 | int last_non_zero = 0; | |
| 659 | 51881432 | int bits = 0; | |
| 660 | int i, j, level; | ||
| 661 |
2/2✓ Branch 0 taken 463138205 times.
✓ Branch 1 taken 51881432 times.
|
515019637 | for (i = 1; i <= last_index; i++) { |
| 662 | 463138205 | j = ctx->m.c.intra_scantable.permutated[i]; | |
| 663 | 463138205 | level = block[j]; | |
| 664 |
2/2✓ Branch 0 taken 191817206 times.
✓ Branch 1 taken 271320999 times.
|
463138205 | if (level) { |
| 665 | 191817206 | int run_level = i - last_non_zero - 1; | |
| 666 | 191817206 | bits += ctx->vlc_bits[level * (1 << 1) | | |
| 667 | 191817206 | !!run_level] + ctx->run_bits[run_level]; | |
| 668 | 191817206 | last_non_zero = i; | |
| 669 | } | ||
| 670 | } | ||
| 671 | 51881432 | return bits; | |
| 672 | } | ||
| 673 | |||
| 674 | static av_always_inline | ||
| 675 | 9849999 | void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y) | |
| 676 | { | ||
| 677 | 9849999 | const int bs = ctx->block_width_l2; | |
| 678 | 9849999 | const int bw = 1 << bs; | |
| 679 | 9849999 | int dct_y_offset = ctx->dct_y_offset; | |
| 680 | 9849999 | int dct_uv_offset = ctx->dct_uv_offset; | |
| 681 | 9849999 | int linesize = ctx->m.c.linesize; | |
| 682 | 9849999 | int uvlinesize = ctx->m.c.uvlinesize; | |
| 683 | 9849999 | const uint8_t *ptr_y = ctx->thread[0]->src[0] + | |
| 684 | 9849999 | ((mb_y << 4) * ctx->m.c.linesize) + (mb_x << bs + 1); | |
| 685 | 9849999 | const uint8_t *ptr_u = ctx->thread[0]->src[1] + | |
| 686 | 9849999 | ((mb_y << 4) * ctx->m.c.uvlinesize) + (mb_x << bs + ctx->is_444); | |
| 687 | 9849999 | const uint8_t *ptr_v = ctx->thread[0]->src[2] + | |
| 688 | 9849999 | ((mb_y << 4) * ctx->m.c.uvlinesize) + (mb_x << bs + ctx->is_444); | |
| 689 | 9849999 | PixblockDSPContext *pdsp = &ctx->m.pdsp; | |
| 690 | 9849999 | VideoDSPContext *vdsp = &ctx->m.c.vdsp; | |
| 691 | |||
| 692 |
6/6✓ Branch 0 taken 9356799 times.
✓ Branch 1 taken 493200 times.
✓ Branch 2 taken 7207599 times.
✓ Branch 3 taken 2149200 times.
✓ Branch 4 taken 7203152 times.
✓ Branch 5 taken 4447 times.
|
9849999 | if (ctx->bit_depth != 10 && vdsp->emulated_edge_mc && ((mb_x << 4) + 16 > ctx->m.c.avctx->width || |
| 693 |
2/2✓ Branch 0 taken 18064 times.
✓ Branch 1 taken 7185088 times.
|
7203152 | (mb_y << 4) + 16 > ctx->m.c.avctx->height)) { |
| 694 | 22511 | int y_w = ctx->m.c.avctx->width - (mb_x << 4); | |
| 695 | 22511 | int y_h = ctx->m.c.avctx->height - (mb_y << 4); | |
| 696 | 22511 | int uv_w = (y_w + 1) / 2; | |
| 697 | 22511 | int uv_h = y_h; | |
| 698 | 22511 | linesize = 16; | |
| 699 | 22511 | uvlinesize = 8; | |
| 700 | |||
| 701 | 22511 | vdsp->emulated_edge_mc(&ctx->edge_buf_y[0], ptr_y, | |
| 702 | linesize, ctx->m.c.linesize, | ||
| 703 | linesize, 16, | ||
| 704 | 0, 0, y_w, y_h); | ||
| 705 | 22511 | vdsp->emulated_edge_mc(&ctx->edge_buf_uv[0][0], ptr_u, | |
| 706 | uvlinesize, ctx->m.c.uvlinesize, | ||
| 707 | uvlinesize, 16, | ||
| 708 | 0, 0, uv_w, uv_h); | ||
| 709 | 22511 | vdsp->emulated_edge_mc(&ctx->edge_buf_uv[1][0], ptr_v, | |
| 710 | uvlinesize, ctx->m.c.uvlinesize, | ||
| 711 | uvlinesize, 16, | ||
| 712 | 0, 0, uv_w, uv_h); | ||
| 713 | |||
| 714 | 22511 | dct_y_offset = bw * linesize; | |
| 715 | 22511 | dct_uv_offset = bw * uvlinesize; | |
| 716 | 22511 | ptr_y = &ctx->edge_buf_y[0]; | |
| 717 | 22511 | ptr_u = &ctx->edge_buf_uv[0][0]; | |
| 718 | 22511 | ptr_v = &ctx->edge_buf_uv[1][0]; | |
| 719 |
3/6✓ Branch 0 taken 493200 times.
✓ Branch 1 taken 9334288 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 493200 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
9827488 | } else if (ctx->bit_depth == 10 && vdsp->emulated_edge_mc && ((mb_x << 4) + 16 > ctx->m.c.avctx->width || |
| 720 | ✗ | (mb_y << 4) + 16 > ctx->m.c.avctx->height)) { | |
| 721 | ✗ | int y_w = ctx->m.c.avctx->width - (mb_x << 4); | |
| 722 | ✗ | int y_h = ctx->m.c.avctx->height - (mb_y << 4); | |
| 723 | ✗ | int uv_w = ctx->is_444 ? y_w : (y_w + 1) / 2; | |
| 724 | ✗ | int uv_h = y_h; | |
| 725 | ✗ | linesize = 32; | |
| 726 | ✗ | uvlinesize = 16 + 16 * ctx->is_444; | |
| 727 | |||
| 728 | ✗ | vdsp->emulated_edge_mc(&ctx->edge_buf_y[0], ptr_y, | |
| 729 | linesize, ctx->m.c.linesize, | ||
| 730 | linesize / 2, 16, | ||
| 731 | 0, 0, y_w, y_h); | ||
| 732 | ✗ | vdsp->emulated_edge_mc(&ctx->edge_buf_uv[0][0], ptr_u, | |
| 733 | uvlinesize, ctx->m.c.uvlinesize, | ||
| 734 | uvlinesize / 2, 16, | ||
| 735 | 0, 0, uv_w, uv_h); | ||
| 736 | ✗ | vdsp->emulated_edge_mc(&ctx->edge_buf_uv[1][0], ptr_v, | |
| 737 | uvlinesize, ctx->m.c.uvlinesize, | ||
| 738 | uvlinesize / 2, 16, | ||
| 739 | 0, 0, uv_w, uv_h); | ||
| 740 | |||
| 741 | ✗ | dct_y_offset = bw * linesize / 2; | |
| 742 | ✗ | dct_uv_offset = bw * uvlinesize / 2; | |
| 743 | ✗ | ptr_y = &ctx->edge_buf_y[0]; | |
| 744 | ✗ | ptr_u = &ctx->edge_buf_uv[0][0]; | |
| 745 | ✗ | ptr_v = &ctx->edge_buf_uv[1][0]; | |
| 746 | } | ||
| 747 | |||
| 748 |
1/2✓ Branch 0 taken 9849999 times.
✗ Branch 1 not taken.
|
9849999 | if (!ctx->is_444) { |
| 749 | 9849999 | pdsp->get_pixels(ctx->blocks[0], ptr_y, linesize); | |
| 750 | 9849999 | pdsp->get_pixels(ctx->blocks[1], ptr_y + bw, linesize); | |
| 751 | 9849999 | pdsp->get_pixels(ctx->blocks[2], ptr_u, uvlinesize); | |
| 752 | 9849999 | pdsp->get_pixels(ctx->blocks[3], ptr_v, uvlinesize); | |
| 753 | |||
| 754 |
4/4✓ Branch 0 taken 131663 times.
✓ Branch 1 taken 9718336 times.
✓ Branch 2 taken 56560 times.
✓ Branch 3 taken 75103 times.
|
9849999 | if (mb_y + 1 == ctx->m.c.mb_height && ctx->m.c.avctx->height == 1080) { |
| 755 |
2/2✓ Branch 0 taken 35280 times.
✓ Branch 1 taken 21280 times.
|
56560 | if (ctx->interlaced) { |
| 756 | 35280 | ctx->get_pixels_8x4_sym(ctx->blocks[4], | |
| 757 | ptr_y + dct_y_offset, | ||
| 758 | linesize); | ||
| 759 | 35280 | ctx->get_pixels_8x4_sym(ctx->blocks[5], | |
| 760 | 35280 | ptr_y + dct_y_offset + bw, | |
| 761 | linesize); | ||
| 762 | 35280 | ctx->get_pixels_8x4_sym(ctx->blocks[6], | |
| 763 | ptr_u + dct_uv_offset, | ||
| 764 | uvlinesize); | ||
| 765 | 35280 | ctx->get_pixels_8x4_sym(ctx->blocks[7], | |
| 766 | ptr_v + dct_uv_offset, | ||
| 767 | uvlinesize); | ||
| 768 | } else { | ||
| 769 | 21280 | ctx->m.c.bdsp.clear_block(ctx->blocks[4]); | |
| 770 | 21280 | ctx->m.c.bdsp.clear_block(ctx->blocks[5]); | |
| 771 | 21280 | ctx->m.c.bdsp.clear_block(ctx->blocks[6]); | |
| 772 | 21280 | ctx->m.c.bdsp.clear_block(ctx->blocks[7]); | |
| 773 | } | ||
| 774 | } else { | ||
| 775 | 9793439 | pdsp->get_pixels(ctx->blocks[4], | |
| 776 | ptr_y + dct_y_offset, linesize); | ||
| 777 | 9793439 | pdsp->get_pixels(ctx->blocks[5], | |
| 778 | 9793439 | ptr_y + dct_y_offset + bw, linesize); | |
| 779 | 9793439 | pdsp->get_pixels(ctx->blocks[6], | |
| 780 | ptr_u + dct_uv_offset, uvlinesize); | ||
| 781 | 9793439 | pdsp->get_pixels(ctx->blocks[7], | |
| 782 | ptr_v + dct_uv_offset, uvlinesize); | ||
| 783 | } | ||
| 784 | } else { | ||
| 785 | ✗ | pdsp->get_pixels(ctx->blocks[0], ptr_y, linesize); | |
| 786 | ✗ | pdsp->get_pixels(ctx->blocks[1], ptr_y + bw, linesize); | |
| 787 | ✗ | pdsp->get_pixels(ctx->blocks[6], ptr_y + dct_y_offset, linesize); | |
| 788 | ✗ | pdsp->get_pixels(ctx->blocks[7], ptr_y + dct_y_offset + bw, linesize); | |
| 789 | |||
| 790 | ✗ | pdsp->get_pixels(ctx->blocks[2], ptr_u, uvlinesize); | |
| 791 | ✗ | pdsp->get_pixels(ctx->blocks[3], ptr_u + bw, uvlinesize); | |
| 792 | ✗ | pdsp->get_pixels(ctx->blocks[8], ptr_u + dct_uv_offset, uvlinesize); | |
| 793 | ✗ | pdsp->get_pixels(ctx->blocks[9], ptr_u + dct_uv_offset + bw, uvlinesize); | |
| 794 | |||
| 795 | ✗ | pdsp->get_pixels(ctx->blocks[4], ptr_v, uvlinesize); | |
| 796 | ✗ | pdsp->get_pixels(ctx->blocks[5], ptr_v + bw, uvlinesize); | |
| 797 | ✗ | pdsp->get_pixels(ctx->blocks[10], ptr_v + dct_uv_offset, uvlinesize); | |
| 798 | ✗ | pdsp->get_pixels(ctx->blocks[11], ptr_v + dct_uv_offset + bw, uvlinesize); | |
| 799 | } | ||
| 800 | 9849999 | } | |
| 801 | |||
| 802 | static av_always_inline | ||
| 803 | 78799992 | int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i) | |
| 804 | { | ||
| 805 | int x; | ||
| 806 | |||
| 807 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 78799992 times.
|
78799992 | if (ctx->is_444) { |
| 808 | ✗ | x = (i >> 1) % 3; | |
| 809 | } else { | ||
| 810 | const static uint8_t component[8]={0,0,1,2,0,0,1,2}; | ||
| 811 | 78799992 | x = component[i]; | |
| 812 | } | ||
| 813 | 78799992 | return x; | |
| 814 | } | ||
| 815 | |||
| 816 | 41557 | static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, | |
| 817 | int jobnr, int threadnr) | ||
| 818 | { | ||
| 819 | 41557 | DNXHDEncContext *ctx = avctx->priv_data; | |
| 820 | 41557 | int mb_y = jobnr; | |
| 821 | 41557 | int qscale = ctx->qscale; | |
| 822 | 41557 | LOCAL_ALIGNED_16(int16_t, block, [64]); | |
| 823 | 41557 | ctx = ctx->thread[threadnr]; | |
| 824 | |||
| 825 | 41557 | ctx->m.last_dc[0] = | |
| 826 | 41557 | ctx->m.last_dc[1] = | |
| 827 | 41557 | ctx->m.last_dc[2] = 1 << (ctx->bit_depth + 2); | |
| 828 | |||
| 829 |
2/2✓ Branch 0 taken 6485179 times.
✓ Branch 1 taken 41557 times.
|
6526736 | for (int mb_x = 0; mb_x < ctx->m.c.mb_width; mb_x++) { |
| 830 | 6485179 | unsigned mb = mb_y * ctx->m.c.mb_width + mb_x; | |
| 831 | 6485179 | int ssd = 0; | |
| 832 | 6485179 | int ac_bits = 0; | |
| 833 | 6485179 | int dc_bits = 0; | |
| 834 | int i; | ||
| 835 | |||
| 836 | 6485179 | dnxhd_get_blocks(ctx, mb_x, mb_y); | |
| 837 | |||
| 838 |
2/2✓ Branch 0 taken 51881432 times.
✓ Branch 1 taken 6485179 times.
|
58366611 | for (i = 0; i < 8 + 4 * ctx->is_444; i++) { |
| 839 | 51881432 | int16_t *src_block = ctx->blocks[i]; | |
| 840 | int overflow, nbits, diff, last_index; | ||
| 841 | 51881432 | int n = dnxhd_switch_matrix(ctx, i); | |
| 842 | |||
| 843 | 51881432 | memcpy(block, src_block, 64 * sizeof(*block)); | |
| 844 | 51881432 | last_index = ctx->m.dct_quantize(&ctx->m, block, | |
| 845 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 51881432 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
51881432 | ctx->is_444 ? 4 * (n > 0): 4 & (2*i), |
| 846 | qscale, &overflow); | ||
| 847 | 51881432 | ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index); | |
| 848 | |||
| 849 | 51881432 | diff = block[0] - ctx->m.last_dc[n]; | |
| 850 |
2/2✓ Branch 0 taken 23766663 times.
✓ Branch 1 taken 28114769 times.
|
51881432 | if (diff < 0) |
| 851 | 23766663 | nbits = av_log2_16bit(-2 * diff); | |
| 852 | else | ||
| 853 | 28114769 | nbits = av_log2_16bit(2 * diff); | |
| 854 | |||
| 855 | av_assert1(nbits < ctx->bit_depth + 4); | ||
| 856 | 51881432 | dc_bits += ctx->cid_table->dc_bits[nbits] + nbits; | |
| 857 | |||
| 858 | 51881432 | ctx->m.last_dc[n] = block[0]; | |
| 859 | |||
| 860 |
2/2✓ Branch 0 taken 3024000 times.
✓ Branch 1 taken 48857432 times.
|
51881432 | if (avctx->mb_decision == FF_MB_DECISION_RD || !RC_VARIANCE) { |
| 861 | 3024000 | dnxhd_unquantize_c(ctx, block, i, qscale, last_index); | |
| 862 | 3024000 | ctx->m.c.idsp.idct(block); | |
| 863 | 3024000 | ssd += dnxhd_ssd_block(block, src_block); | |
| 864 | } | ||
| 865 | } | ||
| 866 | 6485179 | ctx->mb_rc[(qscale * ctx->m.c.mb_num) + mb].ssd = ssd; | |
| 867 | 6485179 | ctx->mb_rc[(qscale * ctx->m.c.mb_num) + mb].bits = ac_bits + dc_bits + 12 + | |
| 868 | 6485179 | (1 + ctx->is_444) * 8 * ctx->vlc_bits[0]; | |
| 869 | } | ||
| 870 | 41557 | return 0; | |
| 871 | } | ||
| 872 | |||
| 873 | 20765 | static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg, | |
| 874 | int jobnr, int threadnr) | ||
| 875 | { | ||
| 876 | 20765 | DNXHDEncContext *ctx = avctx->priv_data; | |
| 877 | 20765 | PutBitContext pb0, *const pb = &pb0; | |
| 878 | 20765 | int mb_y = jobnr; | |
| 879 | 20765 | ctx = ctx->thread[threadnr]; | |
| 880 | 20765 | init_put_bits(pb, (uint8_t *)arg + ctx->data_offset + ctx->slice_offs[jobnr], | |
| 881 | 20765 | ctx->slice_size[jobnr]); | |
| 882 | |||
| 883 | 20765 | ctx->m.last_dc[0] = | |
| 884 | 20765 | ctx->m.last_dc[1] = | |
| 885 | 20765 | ctx->m.last_dc[2] = 1 << (ctx->bit_depth + 2); | |
| 886 |
2/2✓ Branch 0 taken 3364820 times.
✓ Branch 1 taken 20765 times.
|
3385585 | for (int mb_x = 0; mb_x < ctx->m.c.mb_width; mb_x++) { |
| 887 | 3364820 | unsigned mb = mb_y * ctx->m.c.mb_width + mb_x; | |
| 888 | 3364820 | int qscale = ctx->mb_qscale[mb]; | |
| 889 | int i; | ||
| 890 | |||
| 891 | 3364820 | put_bits(pb, 11, qscale); | |
| 892 | 3364820 | put_bits(pb, 1, avctx->pix_fmt == AV_PIX_FMT_YUV444P10); | |
| 893 | |||
| 894 | 3364820 | dnxhd_get_blocks(ctx, mb_x, mb_y); | |
| 895 | |||
| 896 |
2/2✓ Branch 0 taken 26918560 times.
✓ Branch 1 taken 3364820 times.
|
30283380 | for (i = 0; i < 8 + 4 * ctx->is_444; i++) { |
| 897 | 26918560 | int16_t *block = ctx->blocks[i]; | |
| 898 | 26918560 | int overflow, n = dnxhd_switch_matrix(ctx, i); | |
| 899 | 26918560 | int last_index = ctx->m.dct_quantize(&ctx->m, block, | |
| 900 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 26918560 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
26918560 | ctx->is_444 ? (((i >> 1) % 3) < 1 ? 0 : 4): 4 & (2*i), |
| 901 | qscale, &overflow); | ||
| 902 | |||
| 903 | 26918560 | dnxhd_encode_block(pb, ctx, block, last_index, n); | |
| 904 | } | ||
| 905 | } | ||
| 906 | 20765 | flush_put_bits(pb); | |
| 907 | 20765 | memset(put_bits_ptr(pb), 0, put_bytes_left(pb, 0)); | |
| 908 | 20765 | return 0; | |
| 909 | } | ||
| 910 | |||
| 911 | 380 | static void dnxhd_setup_threads_slices(DNXHDEncContext *ctx) | |
| 912 | { | ||
| 913 |
2/2✓ Branch 0 taken 20765 times.
✓ Branch 1 taken 380 times.
|
21145 | for (int mb_y = 0, offset = 0; mb_y < ctx->m.c.mb_height; mb_y++) { |
| 914 | int thread_size; | ||
| 915 | 20765 | ctx->slice_offs[mb_y] = offset; | |
| 916 | 20765 | ctx->slice_size[mb_y] = 0; | |
| 917 |
2/2✓ Branch 0 taken 3364820 times.
✓ Branch 1 taken 20765 times.
|
3385585 | for (int mb_x = 0; mb_x < ctx->m.c.mb_width; mb_x++) { |
| 918 | 3364820 | unsigned mb = mb_y * ctx->m.c.mb_width + mb_x; | |
| 919 | 3364820 | ctx->slice_size[mb_y] += ctx->mb_bits[mb]; | |
| 920 | } | ||
| 921 | 20765 | ctx->slice_size[mb_y] = (ctx->slice_size[mb_y] + 31U) & ~31U; | |
| 922 | 20765 | ctx->slice_size[mb_y] >>= 3; | |
| 923 | 20765 | thread_size = ctx->slice_size[mb_y]; | |
| 924 | 20765 | offset += thread_size; | |
| 925 | } | ||
| 926 | 380 | } | |
| 927 | |||
| 928 | 11520 | static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg, | |
| 929 | int jobnr, int threadnr) | ||
| 930 | { | ||
| 931 | 11520 | DNXHDEncContext *ctx = avctx->priv_data; | |
| 932 | 11520 | int mb_y = jobnr, x, y; | |
| 933 |
2/2✓ Branch 0 taken 220 times.
✓ Branch 1 taken 11300 times.
|
11740 | int partial_last_row = (mb_y == ctx->m.c.mb_height - 1) && |
| 934 |
2/2✓ Branch 0 taken 135 times.
✓ Branch 1 taken 85 times.
|
220 | ((avctx->height >> ctx->interlaced) & 0xF); |
| 935 | |||
| 936 | 11520 | ctx = ctx->thread[threadnr]; | |
| 937 |
2/2✓ Branch 0 taken 10955 times.
✓ Branch 1 taken 565 times.
|
11520 | if (ctx->bit_depth == 8) { |
| 938 | 10955 | const uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.c.linesize); | |
| 939 |
2/2✓ Branch 0 taken 1919700 times.
✓ Branch 1 taken 10955 times.
|
1930655 | for (int mb_x = 0; mb_x < ctx->m.c.mb_width; ++mb_x, pix += 16) { |
| 940 | 1919700 | unsigned mb = mb_y * ctx->m.c.mb_width + mb_x; | |
| 941 | int sum; | ||
| 942 | int varc; | ||
| 943 | |||
| 944 |
6/6✓ Branch 0 taken 1908265 times.
✓ Branch 1 taken 11435 times.
✓ Branch 2 taken 1907880 times.
✓ Branch 3 taken 385 times.
✓ Branch 4 taken 1901720 times.
✓ Branch 5 taken 6160 times.
|
1919700 | if (!partial_last_row && mb_x * 16 <= avctx->width - 16 && (avctx->width % 16) == 0) { |
| 945 | 1901720 | sum = ctx->m.mpvencdsp.pix_sum(pix, ctx->m.c.linesize); | |
| 946 | 1901720 | varc = ctx->m.mpvencdsp.pix_norm1(pix, ctx->m.c.linesize); | |
| 947 | } else { | ||
| 948 | 17980 | int bw = FFMIN(avctx->width - 16 * mb_x, 16); | |
| 949 | 17980 | int bh = FFMIN((avctx->height >> ctx->interlaced) - 16 * mb_y, 16); | |
| 950 | 17980 | sum = varc = 0; | |
| 951 |
2/2✓ Branch 0 taken 226195 times.
✓ Branch 1 taken 17980 times.
|
244175 | for (y = 0; y < bh; y++) { |
| 952 |
2/2✓ Branch 0 taken 3573835 times.
✓ Branch 1 taken 226195 times.
|
3800030 | for (x = 0; x < bw; x++) { |
| 953 | 3573835 | uint8_t val = pix[x + y * ctx->m.c.linesize]; | |
| 954 | 3573835 | sum += val; | |
| 955 | 3573835 | varc += val * val; | |
| 956 | } | ||
| 957 | } | ||
| 958 | } | ||
| 959 | 1919700 | varc = (varc - (((unsigned) sum * sum) >> 8) + 128) >> 8; | |
| 960 | |||
| 961 | 1919700 | ctx->mb_cmp[mb].value = varc; | |
| 962 | 1919700 | ctx->mb_cmp[mb].mb = mb; | |
| 963 | } | ||
| 964 | } else { // 10-bit | ||
| 965 | 565 | const int linesize = ctx->m.c.linesize >> 1; | |
| 966 |
2/2✓ Branch 0 taken 58800 times.
✓ Branch 1 taken 565 times.
|
59365 | for (int mb_x = 0; mb_x < ctx->m.c.mb_width; ++mb_x) { |
| 967 | 58800 | const uint16_t *pix = (const uint16_t *)ctx->thread[0]->src[0] + | |
| 968 | 58800 | ((mb_y << 4) * linesize) + (mb_x << 4); | |
| 969 | 58800 | unsigned mb = mb_y * ctx->m.c.mb_width + mb_x; | |
| 970 | 58800 | int sum = 0; | |
| 971 | 58800 | int sqsum = 0; | |
| 972 | 58800 | int bw = FFMIN(avctx->width - 16 * mb_x, 16); | |
| 973 | 58800 | int bh = FFMIN((avctx->height >> ctx->interlaced) - 16 * mb_y, 16); | |
| 974 | int mean, sqmean; | ||
| 975 | int i, j; | ||
| 976 | // Macroblocks are 16x16 pixels, unlike DCT blocks which are 8x8. | ||
| 977 |
2/2✓ Branch 0 taken 936000 times.
✓ Branch 1 taken 58800 times.
|
994800 | for (i = 0; i < bh; ++i) { |
| 978 |
2/2✓ Branch 0 taken 14976000 times.
✓ Branch 1 taken 936000 times.
|
15912000 | for (j = 0; j < bw; ++j) { |
| 979 | // Turn 16-bit pixels into 10-bit ones. | ||
| 980 | 14976000 | const int sample = (unsigned) pix[j] >> 6; | |
| 981 | 14976000 | sum += sample; | |
| 982 | 14976000 | sqsum += sample * sample; | |
| 983 | // 2^10 * 2^10 * 16 * 16 = 2^28, which is less than INT_MAX | ||
| 984 | } | ||
| 985 | 936000 | pix += linesize; | |
| 986 | } | ||
| 987 | 58800 | mean = sum >> 8; // 16*16 == 2^8 | |
| 988 | 58800 | sqmean = sqsum >> 8; | |
| 989 | 58800 | ctx->mb_cmp[mb].value = sqmean - mean * mean; | |
| 990 | 58800 | ctx->mb_cmp[mb].mb = mb; | |
| 991 | } | ||
| 992 | } | ||
| 993 | 11520 | return 0; | |
| 994 | } | ||
| 995 | |||
| 996 | 15 | static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx) | |
| 997 | { | ||
| 998 | int lambda, up_step, down_step; | ||
| 999 | 15 | int last_lower = INT_MAX, last_higher = 0; | |
| 1000 | |||
| 1001 |
2/2✓ Branch 0 taken 105 times.
✓ Branch 1 taken 15 times.
|
120 | for (int q = 1; q < avctx->qmax; q++) { |
| 1002 | 105 | ctx->qscale = q; | |
| 1003 | 105 | avctx->execute2(avctx, dnxhd_calc_bits_thread, | |
| 1004 | NULL, NULL, ctx->m.c.mb_height); | ||
| 1005 | } | ||
| 1006 | 15 | up_step = down_step = 2 << LAMBDA_FRAC_BITS; | |
| 1007 | 15 | lambda = ctx->lambda; | |
| 1008 | |||
| 1009 | 73 | for (;;) { | |
| 1010 | 88 | int bits = 0; | |
| 1011 | 88 | int end = 0; | |
| 1012 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 83 times.
|
88 | if (lambda == last_higher) { |
| 1013 | 5 | lambda++; | |
| 1014 | 5 | end = 1; // need to set final qscales/bits | |
| 1015 | } | ||
| 1016 |
2/2✓ Branch 0 taken 3948 times.
✓ Branch 1 taken 61 times.
|
4009 | for (int y = 0; y < ctx->m.c.mb_height; y++) { |
| 1017 |
2/2✓ Branch 0 taken 315840 times.
✓ Branch 1 taken 3948 times.
|
319788 | for (int x = 0; x < ctx->m.c.mb_width; x++) { |
| 1018 | 315840 | unsigned min = UINT_MAX; | |
| 1019 | 315840 | int qscale = 1; | |
| 1020 | 315840 | int mb = y * ctx->m.c.mb_width + x; | |
| 1021 | 315840 | int rc = 0; | |
| 1022 |
2/2✓ Branch 0 taken 2210880 times.
✓ Branch 1 taken 315840 times.
|
2526720 | for (int q = 1; q < avctx->qmax; q++) { |
| 1023 | 2210880 | int i = (q*ctx->m.c.mb_num) + mb; | |
| 1024 | 2210880 | unsigned score = ctx->mb_rc[i].bits * lambda + | |
| 1025 | 2210880 | ((unsigned) ctx->mb_rc[i].ssd << LAMBDA_FRAC_BITS); | |
| 1026 |
2/2✓ Branch 0 taken 532068 times.
✓ Branch 1 taken 1678812 times.
|
2210880 | if (score < min) { |
| 1027 | 532068 | min = score; | |
| 1028 | 532068 | qscale = q; | |
| 1029 | 532068 | rc = i; | |
| 1030 | } | ||
| 1031 | } | ||
| 1032 | 315840 | bits += ctx->mb_rc[rc].bits; | |
| 1033 | 315840 | ctx->mb_qscale[mb] = qscale; | |
| 1034 | 315840 | ctx->mb_bits[mb] = ctx->mb_rc[rc].bits; | |
| 1035 | } | ||
| 1036 | 3948 | bits = (bits + 31) & ~31; // padding | |
| 1037 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 3921 times.
|
3948 | if (bits > ctx->frame_bits) |
| 1038 | 27 | break; | |
| 1039 | } | ||
| 1040 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 83 times.
|
88 | if (end) { |
| 1041 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | if (bits > ctx->frame_bits) |
| 1042 | ✗ | return AVERROR(EINVAL); | |
| 1043 | 5 | break; | |
| 1044 | } | ||
| 1045 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 27 times.
|
83 | if (bits < ctx->frame_bits) { |
| 1046 | 56 | last_lower = FFMIN(lambda, last_lower); | |
| 1047 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 22 times.
|
56 | if (last_higher != 0) |
| 1048 | 34 | lambda = (lambda+last_higher)>>1; | |
| 1049 | else | ||
| 1050 | 22 | lambda -= down_step; | |
| 1051 | 56 | down_step = FFMIN((int64_t)down_step*5, INT_MAX); | |
| 1052 | 56 | up_step = 1<<LAMBDA_FRAC_BITS; | |
| 1053 | 56 | lambda = FFMAX(1, lambda); | |
| 1054 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 46 times.
|
56 | if (lambda == last_lower) |
| 1055 | 10 | break; | |
| 1056 | } else { | ||
| 1057 | 27 | last_higher = FFMAX(lambda, last_higher); | |
| 1058 |
2/2✓ Branch 0 taken 26 times.
✓ Branch 1 taken 1 times.
|
27 | if (last_lower != INT_MAX) |
| 1059 | 26 | lambda = (lambda+last_lower)>>1; | |
| 1060 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | else if ((int64_t)lambda + up_step > INT_MAX) |
| 1061 | ✗ | return AVERROR(EINVAL); | |
| 1062 | else | ||
| 1063 | 1 | lambda += up_step; | |
| 1064 | 27 | up_step = FFMIN((int64_t)up_step*5, INT_MAX); | |
| 1065 | 27 | down_step = 1<<LAMBDA_FRAC_BITS; | |
| 1066 | } | ||
| 1067 | } | ||
| 1068 | 15 | ctx->lambda = lambda; | |
| 1069 | 15 | return 0; | |
| 1070 | } | ||
| 1071 | |||
| 1072 | 365 | static int dnxhd_find_qscale(DNXHDEncContext *ctx) | |
| 1073 | { | ||
| 1074 | 365 | int bits = 0; | |
| 1075 | 365 | int up_step = 1; | |
| 1076 | 365 | int down_step = 1; | |
| 1077 | 365 | int last_higher = 0; | |
| 1078 | 365 | int last_lower = INT_MAX; | |
| 1079 | int qscale; | ||
| 1080 | |||
| 1081 | 365 | qscale = ctx->qscale; | |
| 1082 | for (;;) { | ||
| 1083 | 691 | bits = 0; | |
| 1084 | 691 | ctx->qscale = qscale; | |
| 1085 | // XXX avoid recalculating bits | ||
| 1086 | 691 | ctx->m.c.avctx->execute2(ctx->m.c.avctx, dnxhd_calc_bits_thread, | |
| 1087 | NULL, NULL, ctx->m.c.mb_height); | ||
| 1088 |
2/2✓ Branch 0 taken 34838 times.
✓ Branch 1 taken 393 times.
|
35231 | for (int y = 0; y < ctx->m.c.mb_height; y++) { |
| 1089 |
2/2✓ Branch 0 taken 5760121 times.
✓ Branch 1 taken 34838 times.
|
5794959 | for (int x = 0; x < ctx->m.c.mb_width; x++) |
| 1090 | 5760121 | bits += ctx->mb_rc[(qscale*ctx->m.c.mb_num) + (y*ctx->m.c.mb_width+x)].bits; | |
| 1091 | 34838 | bits = (bits+31)&~31; // padding | |
| 1092 |
2/2✓ Branch 0 taken 298 times.
✓ Branch 1 taken 34540 times.
|
34838 | if (bits > ctx->frame_bits) |
| 1093 | 298 | break; | |
| 1094 | } | ||
| 1095 |
2/2✓ Branch 0 taken 393 times.
✓ Branch 1 taken 298 times.
|
691 | if (bits < ctx->frame_bits) { |
| 1096 |
2/2✓ Branch 0 taken 145 times.
✓ Branch 1 taken 248 times.
|
393 | if (qscale == 1) |
| 1097 | 145 | return 1; | |
| 1098 |
2/2✓ Branch 0 taken 195 times.
✓ Branch 1 taken 53 times.
|
248 | if (last_higher == qscale - 1) { |
| 1099 | 195 | qscale = last_higher; | |
| 1100 | 195 | break; | |
| 1101 | } | ||
| 1102 | 53 | last_lower = FFMIN(qscale, last_lower); | |
| 1103 |
2/2✓ Branch 0 taken 38 times.
✓ Branch 1 taken 15 times.
|
53 | if (last_higher != 0) |
| 1104 | 38 | qscale = (qscale + last_higher) >> 1; | |
| 1105 | else | ||
| 1106 | 15 | qscale -= down_step++; | |
| 1107 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 53 times.
|
53 | if (qscale < 1) |
| 1108 | ✗ | qscale = 1; | |
| 1109 | 53 | up_step = 1; | |
| 1110 | } else { | ||
| 1111 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 273 times.
|
298 | if (last_lower == qscale + 1) |
| 1112 | 25 | break; | |
| 1113 | 273 | last_higher = FFMAX(qscale, last_higher); | |
| 1114 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 268 times.
|
273 | if (last_lower != INT_MAX) |
| 1115 | 5 | qscale = (qscale + last_lower) >> 1; | |
| 1116 | else | ||
| 1117 | 268 | qscale += up_step++; | |
| 1118 | 273 | down_step = 1; | |
| 1119 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 273 times.
|
273 | if (qscale >= ctx->m.c.avctx->qmax) |
| 1120 | ✗ | return AVERROR(EINVAL); | |
| 1121 | } | ||
| 1122 | } | ||
| 1123 | 220 | ctx->qscale = qscale; | |
| 1124 | 220 | return 0; | |
| 1125 | } | ||
| 1126 | |||
| 1127 | #define BUCKET_BITS 8 | ||
| 1128 | #define RADIX_PASSES 4 | ||
| 1129 | #define NBUCKETS (1 << BUCKET_BITS) | ||
| 1130 | |||
| 1131 | 11871000 | static inline int get_bucket(int value, int shift) | |
| 1132 | { | ||
| 1133 | 11871000 | value >>= shift; | |
| 1134 | 11871000 | value &= NBUCKETS - 1; | |
| 1135 | 11871000 | return NBUCKETS - 1 - value; | |
| 1136 | } | ||
| 1137 | |||
| 1138 | 220 | static void radix_count(const RCCMPEntry *data, int size, | |
| 1139 | int buckets[RADIX_PASSES][NBUCKETS]) | ||
| 1140 | { | ||
| 1141 | int i, j; | ||
| 1142 | 220 | memset(buckets, 0, sizeof(buckets[0][0]) * RADIX_PASSES * NBUCKETS); | |
| 1143 |
2/2✓ Branch 0 taken 1978500 times.
✓ Branch 1 taken 220 times.
|
1978720 | for (i = 0; i < size; i++) { |
| 1144 | 1978500 | int v = data[i].value; | |
| 1145 |
2/2✓ Branch 0 taken 7914000 times.
✓ Branch 1 taken 1978500 times.
|
9892500 | for (j = 0; j < RADIX_PASSES; j++) { |
| 1146 | 7914000 | buckets[j][get_bucket(v, 0)]++; | |
| 1147 | 7914000 | v >>= BUCKET_BITS; | |
| 1148 | } | ||
| 1149 | av_assert1(!v); | ||
| 1150 | } | ||
| 1151 |
2/2✓ Branch 0 taken 880 times.
✓ Branch 1 taken 220 times.
|
1100 | for (j = 0; j < RADIX_PASSES; j++) { |
| 1152 | 880 | int offset = size; | |
| 1153 |
2/2✓ Branch 0 taken 225280 times.
✓ Branch 1 taken 880 times.
|
226160 | for (i = NBUCKETS - 1; i >= 0; i--) |
| 1154 | 225280 | buckets[j][i] = offset -= buckets[j][i]; | |
| 1155 | av_assert1(!buckets[j][0]); | ||
| 1156 | } | ||
| 1157 | 220 | } | |
| 1158 | |||
| 1159 | 440 | static void radix_sort_pass(RCCMPEntry *dst, const RCCMPEntry *data, | |
| 1160 | int size, int buckets[NBUCKETS], int pass) | ||
| 1161 | { | ||
| 1162 | 440 | int shift = pass * BUCKET_BITS; | |
| 1163 | int i; | ||
| 1164 |
2/2✓ Branch 0 taken 3957000 times.
✓ Branch 1 taken 440 times.
|
3957440 | for (i = 0; i < size; i++) { |
| 1165 | 3957000 | int v = get_bucket(data[i].value, shift); | |
| 1166 | 3957000 | int pos = buckets[v]++; | |
| 1167 | 3957000 | dst[pos] = data[i]; | |
| 1168 | } | ||
| 1169 | 440 | } | |
| 1170 | |||
| 1171 | 220 | static void radix_sort(RCCMPEntry *data, RCCMPEntry *tmp, int size) | |
| 1172 | { | ||
| 1173 | int buckets[RADIX_PASSES][NBUCKETS]; | ||
| 1174 | 220 | radix_count(data, size, buckets); | |
| 1175 | 220 | radix_sort_pass(tmp, data, size, buckets[0], 0); | |
| 1176 | 220 | radix_sort_pass(data, tmp, size, buckets[1], 1); | |
| 1177 |
2/4✓ Branch 0 taken 220 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 220 times.
|
220 | if (buckets[2][NBUCKETS - 1] || buckets[3][NBUCKETS - 1]) { |
| 1178 | ✗ | radix_sort_pass(tmp, data, size, buckets[2], 2); | |
| 1179 | ✗ | radix_sort_pass(data, tmp, size, buckets[3], 3); | |
| 1180 | } | ||
| 1181 | 220 | } | |
| 1182 | |||
| 1183 | 365 | static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx) | |
| 1184 | { | ||
| 1185 | 365 | int max_bits = 0; | |
| 1186 | int ret; | ||
| 1187 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 365 times.
|
365 | if ((ret = dnxhd_find_qscale(ctx)) < 0) |
| 1188 | ✗ | return ret; | |
| 1189 |
2/2✓ Branch 0 taken 20090 times.
✓ Branch 1 taken 365 times.
|
20455 | for (int y = 0; y < ctx->m.c.mb_height; y++) { |
| 1190 |
2/2✓ Branch 0 taken 3310820 times.
✓ Branch 1 taken 20090 times.
|
3330910 | for (int x = 0; x < ctx->m.c.mb_width; x++) { |
| 1191 | 3310820 | int mb = y * ctx->m.c.mb_width + x; | |
| 1192 | 3310820 | int rc = (ctx->qscale * ctx->m.c.mb_num ) + mb; | |
| 1193 | int delta_bits; | ||
| 1194 | 3310820 | ctx->mb_qscale[mb] = ctx->qscale; | |
| 1195 | 3310820 | ctx->mb_bits[mb] = ctx->mb_rc[rc].bits; | |
| 1196 | 3310820 | max_bits += ctx->mb_rc[rc].bits; | |
| 1197 | if (!RC_VARIANCE) { | ||
| 1198 | delta_bits = ctx->mb_rc[rc].bits - | ||
| 1199 | ctx->mb_rc[rc + ctx->m.c.mb_num].bits; | ||
| 1200 | ctx->mb_cmp[mb].mb = mb; | ||
| 1201 | ctx->mb_cmp[mb].value = | ||
| 1202 | delta_bits ? ((ctx->mb_rc[rc].ssd - | ||
| 1203 | ctx->mb_rc[rc + ctx->m.c.mb_num].ssd) * 100) / | ||
| 1204 | delta_bits | ||
| 1205 | : INT_MIN; // avoid increasing qscale | ||
| 1206 | } | ||
| 1207 | } | ||
| 1208 | 20090 | max_bits += 31; // worst padding | |
| 1209 | } | ||
| 1210 |
2/2✓ Branch 0 taken 220 times.
✓ Branch 1 taken 145 times.
|
365 | if (!ret) { |
| 1211 | if (RC_VARIANCE) | ||
| 1212 | 220 | avctx->execute2(avctx, dnxhd_mb_var_thread, | |
| 1213 | NULL, NULL, ctx->m.c.mb_height); | ||
| 1214 | 220 | radix_sort(ctx->mb_cmp, ctx->mb_cmp_tmp, ctx->m.c.mb_num); | |
| 1215 | 222 | retry: | |
| 1216 |
4/4✓ Branch 0 taken 647231 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 647011 times.
✓ Branch 3 taken 220 times.
|
647233 | for (int x = 0; x < ctx->m.c.mb_num && max_bits > ctx->frame_bits; x++) { |
| 1217 | 647011 | int mb = ctx->mb_cmp[x].mb; | |
| 1218 | 647011 | int rc = (ctx->qscale * ctx->m.c.mb_num ) + mb; | |
| 1219 | 647011 | max_bits -= ctx->mb_rc[rc].bits - | |
| 1220 | 647011 | ctx->mb_rc[rc + ctx->m.c.mb_num].bits; | |
| 1221 |
1/2✓ Branch 0 taken 647011 times.
✗ Branch 1 not taken.
|
647011 | if (ctx->mb_qscale[mb] < 255) |
| 1222 | 647011 | ctx->mb_qscale[mb]++; | |
| 1223 | 647011 | ctx->mb_bits[mb] = ctx->mb_rc[rc + ctx->m.c.mb_num].bits; | |
| 1224 | } | ||
| 1225 | |||
| 1226 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 220 times.
|
222 | if (max_bits > ctx->frame_bits) |
| 1227 | 2 | goto retry; | |
| 1228 | } | ||
| 1229 | 365 | return 0; | |
| 1230 | } | ||
| 1231 | |||
| 1232 | 325 | static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame) | |
| 1233 | { | ||
| 1234 |
2/2✓ Branch 0 taken 325 times.
✓ Branch 1 taken 325 times.
|
650 | for (int i = 0; i < ctx->m.c.avctx->thread_count; i++) { |
| 1235 | 325 | ctx->thread[i]->m.c.linesize = frame->linesize[0] << ctx->interlaced; | |
| 1236 | 325 | ctx->thread[i]->m.c.uvlinesize = frame->linesize[1] << ctx->interlaced; | |
| 1237 | 325 | ctx->thread[i]->dct_y_offset = ctx->m.c.linesize *8; | |
| 1238 | 325 | ctx->thread[i]->dct_uv_offset = ctx->m.c.uvlinesize*8; | |
| 1239 | } | ||
| 1240 | |||
| 1241 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
|
325 | ctx->cur_field = (frame->flags & AV_FRAME_FLAG_INTERLACED) && |
| 1242 | ✗ | !(frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST); | |
| 1243 | 325 | } | |
| 1244 | |||
| 1245 | 325 | static int dnxhd_encode_picture(AVCodecContext *avctx, AVPacket *pkt, | |
| 1246 | const AVFrame *frame, int *got_packet) | ||
| 1247 | { | ||
| 1248 | 325 | DNXHDEncContext *ctx = avctx->priv_data; | |
| 1249 | 325 | int first_field = 1; | |
| 1250 | int offset, i, ret; | ||
| 1251 | uint8_t *buf; | ||
| 1252 | |||
| 1253 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 325 times.
|
325 | if ((ret = ff_get_encode_buffer(avctx, pkt, ctx->frame_size, 0)) < 0) |
| 1254 | ✗ | return ret; | |
| 1255 | 325 | buf = pkt->data; | |
| 1256 | |||
| 1257 | 325 | dnxhd_load_picture(ctx, frame); | |
| 1258 | |||
| 1259 | 380 | encode_coding_unit: | |
| 1260 |
2/2✓ Branch 0 taken 1140 times.
✓ Branch 1 taken 380 times.
|
1520 | for (i = 0; i < 3; i++) { |
| 1261 | 1140 | ctx->src[i] = frame->data[i]; | |
| 1262 |
4/4✓ Branch 0 taken 330 times.
✓ Branch 1 taken 810 times.
✓ Branch 2 taken 165 times.
✓ Branch 3 taken 165 times.
|
1140 | if (ctx->interlaced && ctx->cur_field) |
| 1263 | 165 | ctx->src[i] += frame->linesize[i]; | |
| 1264 | } | ||
| 1265 | |||
| 1266 | 380 | dnxhd_write_header(avctx, buf); | |
| 1267 | |||
| 1268 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 365 times.
|
380 | if (avctx->mb_decision == FF_MB_DECISION_RD) |
| 1269 | 15 | ret = dnxhd_encode_rdo(avctx, ctx); | |
| 1270 | else | ||
| 1271 | 365 | ret = dnxhd_encode_fast(avctx, ctx); | |
| 1272 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 380 times.
|
380 | if (ret < 0) { |
| 1273 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
| 1274 | "picture could not fit ratecontrol constraints, increase qmax\n"); | ||
| 1275 | ✗ | return ret; | |
| 1276 | } | ||
| 1277 | |||
| 1278 | 380 | dnxhd_setup_threads_slices(ctx); | |
| 1279 | |||
| 1280 | 380 | offset = 0; | |
| 1281 |
2/2✓ Branch 0 taken 20765 times.
✓ Branch 1 taken 380 times.
|
21145 | for (i = 0; i < ctx->m.c.mb_height; i++) { |
| 1282 | 20765 | AV_WB32(ctx->msip + i * 4, offset); | |
| 1283 | 20765 | offset += ctx->slice_size[i]; | |
| 1284 | av_assert1(!(ctx->slice_size[i] & 3)); | ||
| 1285 | } | ||
| 1286 | |||
| 1287 | 380 | avctx->execute2(avctx, dnxhd_encode_thread, buf, NULL, ctx->m.c.mb_height); | |
| 1288 | |||
| 1289 | av_assert1(ctx->data_offset + offset + 4 <= ctx->coding_unit_size); | ||
| 1290 | 380 | memset(buf + ctx->data_offset + offset, 0, | |
| 1291 | 380 | ctx->coding_unit_size - 4 - offset - ctx->data_offset); | |
| 1292 | |||
| 1293 | 380 | AV_WB32(buf + ctx->coding_unit_size - 4, 0x600DC0DE); // EOF | |
| 1294 | |||
| 1295 |
4/4✓ Branch 0 taken 110 times.
✓ Branch 1 taken 270 times.
✓ Branch 2 taken 55 times.
✓ Branch 3 taken 55 times.
|
380 | if (ctx->interlaced && first_field) { |
| 1296 | 55 | first_field = 0; | |
| 1297 | 55 | ctx->cur_field ^= 1; | |
| 1298 | 55 | buf += ctx->coding_unit_size; | |
| 1299 | 55 | goto encode_coding_unit; | |
| 1300 | } | ||
| 1301 | |||
| 1302 | 325 | ff_encode_add_stats_side_data(pkt, ctx->qscale * FF_QP2LAMBDA, NULL, 0, AV_PICTURE_TYPE_I); | |
| 1303 | |||
| 1304 | 325 | *got_packet = 1; | |
| 1305 | 325 | return 0; | |
| 1306 | } | ||
| 1307 | |||
| 1308 | 73 | static av_cold int dnxhd_encode_end(AVCodecContext *avctx) | |
| 1309 | { | ||
| 1310 | 73 | DNXHDEncContext *ctx = avctx->priv_data; | |
| 1311 | int i; | ||
| 1312 | |||
| 1313 | 73 | av_freep(&ctx->orig_vlc_codes); | |
| 1314 | 73 | av_freep(&ctx->orig_vlc_bits); | |
| 1315 | 73 | av_freep(&ctx->run_codes); | |
| 1316 | 73 | av_freep(&ctx->run_bits); | |
| 1317 | |||
| 1318 | 73 | av_freep(&ctx->mb_bits); | |
| 1319 | 73 | av_freep(&ctx->mb_qscale); | |
| 1320 | 73 | av_freep(&ctx->mb_rc); | |
| 1321 | 73 | av_freep(&ctx->mb_cmp); | |
| 1322 | 73 | av_freep(&ctx->mb_cmp_tmp); | |
| 1323 | 73 | av_freep(&ctx->slice_size); | |
| 1324 | 73 | av_freep(&ctx->slice_offs); | |
| 1325 | |||
| 1326 | 73 | av_freep(&ctx->qmatrix_c); | |
| 1327 | 73 | av_freep(&ctx->qmatrix_l); | |
| 1328 | 73 | av_freep(&ctx->qmatrix_c16); | |
| 1329 | 73 | av_freep(&ctx->qmatrix_l16); | |
| 1330 | |||
| 1331 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
|
73 | if (ctx->thread[1]) { |
| 1332 | ✗ | for (i = 1; i < avctx->thread_count; i++) | |
| 1333 | ✗ | av_freep(&ctx->thread[i]); | |
| 1334 | } | ||
| 1335 | |||
| 1336 | 73 | return 0; | |
| 1337 | } | ||
| 1338 | |||
| 1339 | static const FFCodecDefault dnxhd_defaults[] = { | ||
| 1340 | { "qmax", "1024" }, /* Maximum quantization scale factor allowed for VC-3 */ | ||
| 1341 | { NULL }, | ||
| 1342 | }; | ||
| 1343 | |||
| 1344 | const FFCodec ff_dnxhd_encoder = { | ||
| 1345 | .p.name = "dnxhd", | ||
| 1346 | CODEC_LONG_NAME("VC3/DNxHD"), | ||
| 1347 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
| 1348 | .p.id = AV_CODEC_ID_DNXHD, | ||
| 1349 | .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | | ||
| 1350 | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, | ||
| 1351 | .priv_data_size = sizeof(DNXHDEncContext), | ||
| 1352 | .init = dnxhd_encode_init, | ||
| 1353 | FF_CODEC_ENCODE_CB(dnxhd_encode_picture), | ||
| 1354 | .close = dnxhd_encode_end, | ||
| 1355 | CODEC_PIXFMTS(AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P10, | ||
| 1356 | AV_PIX_FMT_YUV444P10, AV_PIX_FMT_GBRP10), | ||
| 1357 | .color_ranges = AVCOL_RANGE_MPEG, | ||
| 1358 | .p.priv_class = &dnxhd_class, | ||
| 1359 | .defaults = dnxhd_defaults, | ||
| 1360 | .p.profiles = NULL_IF_CONFIG_SMALL(ff_dnxhd_profiles), | ||
| 1361 | .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, | ||
| 1362 | }; | ||
| 1363 | |||
| 1364 | 73 | void ff_dnxhdenc_init(DNXHDEncContext *ctx) | |
| 1365 | { | ||
| 1366 | #if ARCH_X86 && HAVE_X86ASM | ||
| 1367 | 73 | ff_dnxhdenc_init_x86(ctx); | |
| 1368 | #endif | ||
| 1369 | 73 | } | |
| 1370 |