Commit | Line | Data |
---|---|---|
fc4cbc16 BC |
1 | /* |
2 | * VC3/DNxHD encoder | |
3 | * Copyright (c) 2007 Baptiste Coudurier <baptiste dot coudurier at smartjog dot com> | |
5ab21439 | 4 | * Copyright (c) 2011 MirriAd Ltd |
fc4cbc16 BC |
5 | * |
6 | * VC-3 encoder funded by the British Broadcasting Corporation | |
5ab21439 | 7 | * 10 bit support added by MirriAd Ltd, Joseph Artsimovich <joseph@mirriad.com> |
fc4cbc16 | 8 | * |
2912e87a | 9 | * This file is part of Libav. |
fc4cbc16 | 10 | * |
2912e87a | 11 | * Libav is free software; you can redistribute it and/or |
fc4cbc16 BC |
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 | * | |
2912e87a | 16 | * Libav is distributed in the hope that it will be useful, |
fc4cbc16 BC |
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 | |
2912e87a | 22 | * License along with Libav; if not, write to the Free Software |
fc4cbc16 BC |
23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
24 | */ | |
25 | ||
26 | //#define DEBUG | |
27 | #define RC_VARIANCE 1 // use variance or ssd for fast rc | |
28 | ||
99bbc781 | 29 | #include "libavutil/opt.h" |
fc4cbc16 BC |
30 | #include "avcodec.h" |
31 | #include "dsputil.h" | |
32 | #include "mpegvideo.h" | |
828e2073 | 33 | #include "mpegvideo_common.h" |
09f6fc6b | 34 | #include "dnxhdenc.h" |
fc4cbc16 | 35 | |
99bbc781 | 36 | #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM |
5ab21439 | 37 | #define DNX10BIT_QMAT_SHIFT 18 // The largest value that will not lead to overflow for 10bit samples. |
99bbc781 BC |
38 | |
39 | static const AVOption options[]={ | |
b6675279 | 40 | {"nitris_compat", "encode with Avid Nitris compatibility", offsetof(DNXHDEncContext, nitris_compat), FF_OPT_TYPE_INT, {.dbl = 0}, 0, 1, VE}, |
99bbc781 BC |
41 | {NULL} |
42 | }; | |
43 | static const AVClass class = { "dnxhd", av_default_item_name, options, LIBAVUTIL_VERSION_INT }; | |
44 | ||
fc4cbc16 BC |
45 | #define LAMBDA_FRAC_BITS 10 |
46 | ||
5ab21439 | 47 | static void dnxhd_8bit_get_pixels_8x4_sym(DCTELEM *restrict block, const uint8_t *pixels, int line_size) |
e1b24cfd BC |
48 | { |
49 | int i; | |
50 | for (i = 0; i < 4; i++) { | |
51 | block[0] = pixels[0]; block[1] = pixels[1]; | |
52 | block[2] = pixels[2]; block[3] = pixels[3]; | |
53 | block[4] = pixels[4]; block[5] = pixels[5]; | |
54 | block[6] = pixels[6]; block[7] = pixels[7]; | |
55 | pixels += line_size; | |
56 | block += 8; | |
57 | } | |
10738239 MR |
58 | memcpy(block, block - 8, sizeof(*block) * 8); |
59 | memcpy(block + 8, block - 16, sizeof(*block) * 8); | |
60 | memcpy(block + 16, block - 24, sizeof(*block) * 8); | |
61 | memcpy(block + 24, block - 32, sizeof(*block) * 8); | |
e1b24cfd BC |
62 | } |
63 | ||
5ab21439 JA |
64 | static av_always_inline void dnxhd_10bit_get_pixels_8x4_sym(DCTELEM *restrict block, const uint8_t *pixels, int line_size) |
65 | { | |
66 | int i; | |
67 | ||
68 | block += 32; | |
69 | ||
70 | for (i = 0; i < 4; i++) { | |
71 | memcpy(block + i * 8, pixels + i * line_size, 8 * sizeof(*block)); | |
72 | memcpy(block - (i+1) * 8, pixels + i * line_size, 8 * sizeof(*block)); | |
73 | } | |
74 | } | |
75 | ||
76 | static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, DCTELEM *block, | |
77 | int n, int qscale, int *overflow) | |
78 | { | |
79 | const uint8_t *scantable= ctx->intra_scantable.scantable; | |
80 | const int *qmat = ctx->q_intra_matrix[qscale]; | |
81 | int last_non_zero = 0; | |
e72f3d10 | 82 | int i; |
5ab21439 JA |
83 | |
84 | ctx->dsp.fdct(block); | |
85 | ||
86 | // Divide by 4 with rounding, to compensate scaling of DCT coefficients | |
87 | block[0] = (block[0] + 2) >> 2; | |
88 | ||
e72f3d10 | 89 | for (i = 1; i < 64; ++i) { |
5ab21439 JA |
90 | int j = scantable[i]; |
91 | int sign = block[j] >> 31; | |
92 | int level = (block[j] ^ sign) - sign; | |
93 | level = level * qmat[j] >> DNX10BIT_QMAT_SHIFT; | |
94 | block[j] = (level ^ sign) - sign; | |
95 | if (level) | |
96 | last_non_zero = i; | |
97 | } | |
98 | ||
99 | return last_non_zero; | |
100 | } | |
101 | ||
fc4cbc16 BC |
102 | static int dnxhd_init_vlc(DNXHDEncContext *ctx) |
103 | { | |
556eec43 BC |
104 | int i, j, level, run; |
105 | int max_level = 1<<(ctx->cid_table->bit_depth+2); | |
106 | ||
d31dbec3 | 107 | FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->vlc_codes, max_level*4*sizeof(*ctx->vlc_codes), fail); |
10738239 MR |
108 | FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->vlc_bits, max_level*4*sizeof(*ctx->vlc_bits) , fail); |
109 | FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_codes, 63*2, fail); | |
110 | FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_bits, 63, fail); | |
556eec43 | 111 | |
b73e868b BC |
112 | ctx->vlc_codes += max_level*2; |
113 | ctx->vlc_bits += max_level*2; | |
556eec43 BC |
114 | for (level = -max_level; level < max_level; level++) { |
115 | for (run = 0; run < 2; run++) { | |
116 | int index = (level<<1)|run; | |
117 | int sign, offset = 0, alevel = level; | |
118 | ||
119 | MASK_ABS(sign, alevel); | |
120 | if (alevel > 64) { | |
121 | offset = (alevel-1)>>6; | |
122 | alevel -= offset<<6; | |
123 | } | |
124 | for (j = 0; j < 257; j++) { | |
125 | if (ctx->cid_table->ac_level[j] == alevel && | |
126 | (!offset || (ctx->cid_table->ac_index_flag[j] && offset)) && | |
127 | (!run || (ctx->cid_table->ac_run_flag [j] && run))) { | |
b73e868b | 128 | assert(!ctx->vlc_codes[index]); |
556eec43 | 129 | if (alevel) { |
b73e868b BC |
130 | ctx->vlc_codes[index] = (ctx->cid_table->ac_codes[j]<<1)|(sign&1); |
131 | ctx->vlc_bits [index] = ctx->cid_table->ac_bits[j]+1; | |
556eec43 | 132 | } else { |
b73e868b BC |
133 | ctx->vlc_codes[index] = ctx->cid_table->ac_codes[j]; |
134 | ctx->vlc_bits [index] = ctx->cid_table->ac_bits [j]; | |
556eec43 BC |
135 | } |
136 | break; | |
137 | } | |
138 | } | |
139 | assert(!alevel || j < 257); | |
140 | if (offset) { | |
b73e868b BC |
141 | ctx->vlc_codes[index] = (ctx->vlc_codes[index]<<ctx->cid_table->index_bits)|offset; |
142 | ctx->vlc_bits [index]+= ctx->cid_table->index_bits; | |
556eec43 BC |
143 | } |
144 | } | |
fc4cbc16 BC |
145 | } |
146 | for (i = 0; i < 62; i++) { | |
147 | int run = ctx->cid_table->run[i]; | |
148 | assert(run < 63); | |
b73e868b BC |
149 | ctx->run_codes[run] = ctx->cid_table->run_codes[i]; |
150 | ctx->run_bits [run] = ctx->cid_table->run_bits[i]; | |
fc4cbc16 BC |
151 | } |
152 | return 0; | |
153 | fail: | |
154 | return -1; | |
155 | } | |
156 | ||
157 | static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) | |
158 | { | |
159 | // init first elem to 1 to avoid div by 0 in convert_matrix | |
160 | uint16_t weight_matrix[64] = {1,}; // convert_matrix needs uint16_t* | |
161 | int qscale, i; | |
5ab21439 JA |
162 | const uint8_t *luma_weight_table = ctx->cid_table->luma_weight; |
163 | const uint8_t *chroma_weight_table = ctx->cid_table->chroma_weight; | |
fc4cbc16 | 164 | |
10738239 MR |
165 | FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l, (ctx->m.avctx->qmax+1) * 64 * sizeof(int), fail); |
166 | FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c, (ctx->m.avctx->qmax+1) * 64 * sizeof(int), fail); | |
d31dbec3 RP |
167 | FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t), fail); |
168 | FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t), fail); | |
fc4cbc16 | 169 | |
5ab21439 JA |
170 | if (ctx->cid_table->bit_depth == 8) { |
171 | for (i = 1; i < 64; i++) { | |
172 | int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]]; | |
173 | weight_matrix[j] = ctx->cid_table->luma_weight[i]; | |
174 | } | |
175 | ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_l, ctx->qmatrix_l16, weight_matrix, | |
176 | ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1); | |
177 | for (i = 1; i < 64; i++) { | |
178 | int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]]; | |
179 | weight_matrix[j] = ctx->cid_table->chroma_weight[i]; | |
180 | } | |
181 | ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_c, ctx->qmatrix_c16, weight_matrix, | |
182 | ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1); | |
183 | ||
184 | for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) { | |
185 | for (i = 0; i < 64; i++) { | |
186 | ctx->qmatrix_l [qscale] [i] <<= 2; ctx->qmatrix_c [qscale] [i] <<= 2; | |
187 | ctx->qmatrix_l16[qscale][0][i] <<= 2; ctx->qmatrix_l16[qscale][1][i] <<= 2; | |
188 | ctx->qmatrix_c16[qscale][0][i] <<= 2; ctx->qmatrix_c16[qscale][1][i] <<= 2; | |
189 | } | |
190 | } | |
191 | } else { | |
192 | // 10-bit | |
193 | for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) { | |
194 | for (i = 1; i < 64; i++) { | |
195 | int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]]; | |
196 | ||
197 | // The quantization formula from the VC-3 standard is: | |
198 | // quantized = sign(block[i]) * floor(abs(block[i]/s) * p / (qscale * weight_table[i])) | |
199 | // Where p is 32 for 8-bit samples and 8 for 10-bit ones. | |
200 | // The s factor compensates scaling of DCT coefficients done by the DCT routines, | |
201 | // and therefore is not present in standard. It's 8 for 8-bit samples and 4 for 10-bit ones. | |
202 | // We want values of ctx->qtmatrix_l and ctx->qtmatrix_r to be: | |
203 | // ((1 << DNX10BIT_QMAT_SHIFT) * (p / s)) / (qscale * weight_table[i]) | |
204 | // For 10-bit samples, p / s == 2 | |
205 | ctx->qmatrix_l[qscale][j] = (1 << (DNX10BIT_QMAT_SHIFT + 1)) / (qscale * luma_weight_table[i]); | |
206 | ctx->qmatrix_c[qscale][j] = (1 << (DNX10BIT_QMAT_SHIFT + 1)) / (qscale * chroma_weight_table[i]); | |
207 | } | |
fc4cbc16 BC |
208 | } |
209 | } | |
5ab21439 | 210 | |
fc4cbc16 BC |
211 | return 0; |
212 | fail: | |
213 | return -1; | |
214 | } | |
215 | ||
216 | static int dnxhd_init_rc(DNXHDEncContext *ctx) | |
217 | { | |
d31dbec3 | 218 | FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry), fail); |
fc4cbc16 | 219 | if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD) |
d31dbec3 | 220 | FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_cmp, ctx->m.mb_num*sizeof(RCCMPEntry), fail); |
fc4cbc16 | 221 | |
99bbc781 | 222 | ctx->frame_bits = (ctx->cid_table->coding_unit_size - 640 - 4 - ctx->min_padding) * 8; |
fc4cbc16 BC |
223 | ctx->qscale = 1; |
224 | ctx->lambda = 2<<LAMBDA_FRAC_BITS; // qscale 2 | |
225 | return 0; | |
226 | fail: | |
227 | return -1; | |
228 | } | |
229 | ||
230 | static int dnxhd_encode_init(AVCodecContext *avctx) | |
231 | { | |
232 | DNXHDEncContext *ctx = avctx->priv_data; | |
5ab21439 JA |
233 | int i, index, bit_depth; |
234 | ||
235 | switch (avctx->pix_fmt) { | |
236 | case PIX_FMT_YUV422P: | |
237 | bit_depth = 8; | |
238 | break; | |
239 | case PIX_FMT_YUV422P10: | |
240 | bit_depth = 10; | |
241 | break; | |
242 | default: | |
243 | av_log(avctx, AV_LOG_ERROR, "pixel format is incompatible with DNxHD\n"); | |
244 | return -1; | |
245 | } | |
fc4cbc16 | 246 | |
5ab21439 JA |
247 | ctx->cid = ff_dnxhd_find_cid(avctx, bit_depth); |
248 | if (!ctx->cid) { | |
fc4cbc16 BC |
249 | av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD\n"); |
250 | return -1; | |
251 | } | |
0c39c38b | 252 | av_log(avctx, AV_LOG_DEBUG, "cid %d\n", ctx->cid); |
fc4cbc16 BC |
253 | |
254 | index = ff_dnxhd_get_cid_table(ctx->cid); | |
255 | ctx->cid_table = &ff_dnxhd_cid_table[index]; | |
256 | ||
257 | ctx->m.avctx = avctx; | |
258 | ctx->m.mb_intra = 1; | |
259 | ctx->m.h263_aic = 1; | |
260 | ||
5ab21439 | 261 | avctx->bits_per_raw_sample = ctx->cid_table->bit_depth; |
193ce3ab | 262 | |
fc4cbc16 BC |
263 | dsputil_init(&ctx->m.dsp, avctx); |
264 | ff_dct_common_init(&ctx->m); | |
5ab21439 JA |
265 | if (!ctx->m.dct_quantize) |
266 | ctx->m.dct_quantize = dct_quantize_c; | |
267 | ||
268 | if (ctx->cid_table->bit_depth == 10) { | |
269 | ctx->m.dct_quantize = dnxhd_10bit_dct_quantize; | |
270 | ctx->get_pixels_8x4_sym = dnxhd_10bit_get_pixels_8x4_sym; | |
271 | ctx->block_width_l2 = 4; | |
272 | } else { | |
273 | ctx->get_pixels_8x4_sym = dnxhd_8bit_get_pixels_8x4_sym; | |
274 | ctx->block_width_l2 = 3; | |
275 | } | |
276 | ||
b250f9c6 | 277 | #if HAVE_MMX |
193ce3ab BC |
278 | ff_dnxhd_init_mmx(ctx); |
279 | #endif | |
fc4cbc16 BC |
280 | |
281 | ctx->m.mb_height = (avctx->height + 15) / 16; | |
282 | ctx->m.mb_width = (avctx->width + 15) / 16; | |
283 | ||
284 | if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) { | |
285 | ctx->interlaced = 1; | |
286 | ctx->m.mb_height /= 2; | |
287 | } | |
288 | ||
289 | ctx->m.mb_num = ctx->m.mb_height * ctx->m.mb_width; | |
290 | ||
291 | if (avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS) | |
292 | ctx->m.intra_quant_bias = avctx->intra_quant_bias; | |
293 | if (dnxhd_init_qmat(ctx, ctx->m.intra_quant_bias, 0) < 0) // XXX tune lbias/cbias | |
294 | return -1; | |
295 | ||
99bbc781 BC |
296 | // Avid Nitris hardware decoder requires a minimum amount of padding in the coding unit payload |
297 | if (ctx->nitris_compat) | |
298 | ctx->min_padding = 1600; | |
299 | ||
fc4cbc16 BC |
300 | if (dnxhd_init_vlc(ctx) < 0) |
301 | return -1; | |
302 | if (dnxhd_init_rc(ctx) < 0) | |
303 | return -1; | |
304 | ||
d31dbec3 | 305 | FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_size, ctx->m.mb_height*sizeof(uint32_t), fail); |
2a1294b9 | 306 | FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_offs, ctx->m.mb_height*sizeof(uint32_t), fail); |
d31dbec3 | 307 | FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_bits, ctx->m.mb_num *sizeof(uint16_t), fail); |
10738239 | 308 | FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_qscale, ctx->m.mb_num *sizeof(uint8_t), fail); |
fc4cbc16 BC |
309 | |
310 | ctx->frame.key_frame = 1; | |
975a1447 | 311 | ctx->frame.pict_type = AV_PICTURE_TYPE_I; |
fc4cbc16 BC |
312 | ctx->m.avctx->coded_frame = &ctx->frame; |
313 | ||
2a1294b9 | 314 | if (avctx->thread_count > MAX_THREADS) { |
fc4cbc16 BC |
315 | av_log(avctx, AV_LOG_ERROR, "too many threads\n"); |
316 | return -1; | |
317 | } | |
318 | ||
319 | ctx->thread[0] = ctx; | |
320 | for (i = 1; i < avctx->thread_count; i++) { | |
321 | ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext)); | |
322 | memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext)); | |
323 | } | |
324 | ||
fc4cbc16 | 325 | return 0; |
d31dbec3 | 326 | fail: //for FF_ALLOCZ_OR_GOTO |
fc4cbc16 BC |
327 | return -1; |
328 | } | |
329 | ||
330 | static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf) | |
331 | { | |
332 | DNXHDEncContext *ctx = avctx->priv_data; | |
333 | const uint8_t header_prefix[5] = { 0x00,0x00,0x02,0x80,0x01 }; | |
334 | ||
301a24de BC |
335 | memset(buf, 0, 640); |
336 | ||
fc4cbc16 BC |
337 | memcpy(buf, header_prefix, 5); |
338 | buf[5] = ctx->interlaced ? ctx->cur_field+2 : 0x01; | |
339 | buf[6] = 0x80; // crc flag off | |
340 | buf[7] = 0xa0; // reserved | |
9d9c3e1a | 341 | AV_WB16(buf + 0x18, avctx->height>>ctx->interlaced); // ALPF |
fc4cbc16 | 342 | AV_WB16(buf + 0x1a, avctx->width); // SPL |
9d9c3e1a | 343 | AV_WB16(buf + 0x1d, avctx->height>>ctx->interlaced); // NAL |
fc4cbc16 | 344 | |
5ab21439 | 345 | buf[0x21] = ctx->cid_table->bit_depth == 10 ? 0x58 : 0x38; |
9d9c3e1a | 346 | buf[0x22] = 0x88 + (ctx->interlaced<<2); |
fc4cbc16 BC |
347 | AV_WB32(buf + 0x28, ctx->cid); // CID |
348 | buf[0x2c] = ctx->interlaced ? 0 : 0x80; | |
349 | ||
350 | buf[0x5f] = 0x01; // UDL | |
351 | ||
352 | buf[0x167] = 0x02; // reserved | |
353 | AV_WB16(buf + 0x16a, ctx->m.mb_height * 4 + 4); // MSIPS | |
354 | buf[0x16d] = ctx->m.mb_height; // Ns | |
355 | buf[0x16f] = 0x10; // reserved | |
356 | ||
357 | ctx->msip = buf + 0x170; | |
358 | return 0; | |
359 | } | |
360 | ||
361 | static av_always_inline void dnxhd_encode_dc(DNXHDEncContext *ctx, int diff) | |
362 | { | |
363 | int nbits; | |
364 | if (diff < 0) { | |
365 | nbits = av_log2_16bit(-2*diff); | |
366 | diff--; | |
367 | } else { | |
368 | nbits = av_log2_16bit(2*diff); | |
369 | } | |
370 | put_bits(&ctx->m.pb, ctx->cid_table->dc_bits[nbits] + nbits, | |
371 | (ctx->cid_table->dc_codes[nbits]<<nbits) + (diff & ((1 << nbits) - 1))); | |
372 | } | |
373 | ||
374 | static av_always_inline void dnxhd_encode_block(DNXHDEncContext *ctx, DCTELEM *block, int last_index, int n) | |
375 | { | |
376 | int last_non_zero = 0; | |
fc4cbc16 BC |
377 | int slevel, i, j; |
378 | ||
379 | dnxhd_encode_dc(ctx, block[0] - ctx->m.last_dc[n]); | |
380 | ctx->m.last_dc[n] = block[0]; | |
381 | ||
382 | for (i = 1; i <= last_index; i++) { | |
383 | j = ctx->m.intra_scantable.permutated[i]; | |
384 | slevel = block[j]; | |
385 | if (slevel) { | |
386 | int run_level = i - last_non_zero - 1; | |
556eec43 | 387 | int rlevel = (slevel<<1)|!!run_level; |
b73e868b | 388 | put_bits(&ctx->m.pb, ctx->vlc_bits[rlevel], ctx->vlc_codes[rlevel]); |
fc4cbc16 | 389 | if (run_level) |
b73e868b | 390 | put_bits(&ctx->m.pb, ctx->run_bits[run_level], ctx->run_codes[run_level]); |
fc4cbc16 BC |
391 | last_non_zero = i; |
392 | } | |
393 | } | |
b73e868b | 394 | put_bits(&ctx->m.pb, ctx->vlc_bits[0], ctx->vlc_codes[0]); // EOB |
fc4cbc16 BC |
395 | } |
396 | ||
397 | static av_always_inline void dnxhd_unquantize_c(DNXHDEncContext *ctx, DCTELEM *block, int n, int qscale, int last_index) | |
398 | { | |
6cb1d361 | 399 | const uint8_t *weight_matrix; |
fc4cbc16 BC |
400 | int level; |
401 | int i; | |
402 | ||
6cb1d361 | 403 | weight_matrix = (n&2) ? ctx->cid_table->chroma_weight : ctx->cid_table->luma_weight; |
fc4cbc16 BC |
404 | |
405 | for (i = 1; i <= last_index; i++) { | |
406 | int j = ctx->m.intra_scantable.permutated[i]; | |
407 | level = block[j]; | |
408 | if (level) { | |
409 | if (level < 0) { | |
6cb1d361 | 410 | level = (1-2*level) * qscale * weight_matrix[i]; |
5ab21439 JA |
411 | if (ctx->cid_table->bit_depth == 10) { |
412 | if (weight_matrix[i] != 8) | |
413 | level += 8; | |
414 | level >>= 4; | |
415 | } else { | |
416 | if (weight_matrix[i] != 32) | |
417 | level += 32; | |
418 | level >>= 6; | |
419 | } | |
fc4cbc16 BC |
420 | level = -level; |
421 | } else { | |
6cb1d361 | 422 | level = (2*level+1) * qscale * weight_matrix[i]; |
5ab21439 JA |
423 | if (ctx->cid_table->bit_depth == 10) { |
424 | if (weight_matrix[i] != 8) | |
425 | level += 8; | |
426 | level >>= 4; | |
427 | } else { | |
428 | if (weight_matrix[i] != 32) | |
429 | level += 32; | |
430 | level >>= 6; | |
431 | } | |
fc4cbc16 BC |
432 | } |
433 | block[j] = level; | |
434 | } | |
435 | } | |
436 | } | |
437 | ||
438 | static av_always_inline int dnxhd_ssd_block(DCTELEM *qblock, DCTELEM *block) | |
439 | { | |
440 | int score = 0; | |
441 | int i; | |
442 | for (i = 0; i < 64; i++) | |
10738239 | 443 | score += (block[i] - qblock[i]) * (block[i] - qblock[i]); |
fc4cbc16 BC |
444 | return score; |
445 | } | |
446 | ||
447 | static av_always_inline int dnxhd_calc_ac_bits(DNXHDEncContext *ctx, DCTELEM *block, int last_index) | |
448 | { | |
449 | int last_non_zero = 0; | |
450 | int bits = 0; | |
451 | int i, j, level; | |
452 | for (i = 1; i <= last_index; i++) { | |
453 | j = ctx->m.intra_scantable.permutated[i]; | |
454 | level = block[j]; | |
455 | if (level) { | |
456 | int run_level = i - last_non_zero - 1; | |
b73e868b | 457 | bits += ctx->vlc_bits[(level<<1)|!!run_level]+ctx->run_bits[run_level]; |
fc4cbc16 BC |
458 | last_non_zero = i; |
459 | } | |
460 | } | |
461 | return bits; | |
462 | } | |
463 | ||
fc4cbc16 BC |
464 | static av_always_inline void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y) |
465 | { | |
5ab21439 JA |
466 | const int bs = ctx->block_width_l2; |
467 | const int bw = 1 << bs; | |
468 | const uint8_t *ptr_y = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.linesize) + (mb_x << bs+1); | |
469 | const uint8_t *ptr_u = ctx->thread[0]->src[1] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs); | |
470 | const uint8_t *ptr_v = ctx->thread[0]->src[2] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs); | |
fc4cbc16 BC |
471 | DSPContext *dsp = &ctx->m.dsp; |
472 | ||
5ab21439 JA |
473 | dsp->get_pixels(ctx->blocks[0], ptr_y, ctx->m.linesize); |
474 | dsp->get_pixels(ctx->blocks[1], ptr_y + bw, ctx->m.linesize); | |
475 | dsp->get_pixels(ctx->blocks[2], ptr_u, ctx->m.uvlinesize); | |
476 | dsp->get_pixels(ctx->blocks[3], ptr_v, ctx->m.uvlinesize); | |
fc4cbc16 | 477 | |
cc3a9708 | 478 | if (mb_y+1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) { |
fc4cbc16 | 479 | if (ctx->interlaced) { |
5ab21439 JA |
480 | ctx->get_pixels_8x4_sym(ctx->blocks[4], ptr_y + ctx->dct_y_offset, ctx->m.linesize); |
481 | ctx->get_pixels_8x4_sym(ctx->blocks[5], ptr_y + ctx->dct_y_offset + bw, ctx->m.linesize); | |
482 | ctx->get_pixels_8x4_sym(ctx->blocks[6], ptr_u + ctx->dct_uv_offset, ctx->m.uvlinesize); | |
483 | ctx->get_pixels_8x4_sym(ctx->blocks[7], ptr_v + ctx->dct_uv_offset, ctx->m.uvlinesize); | |
049a6c8b | 484 | } else { |
10738239 MR |
485 | dsp->clear_block(ctx->blocks[4]); |
486 | dsp->clear_block(ctx->blocks[5]); | |
487 | dsp->clear_block(ctx->blocks[6]); | |
488 | dsp->clear_block(ctx->blocks[7]); | |
049a6c8b | 489 | } |
fc4cbc16 | 490 | } else { |
5ab21439 JA |
491 | dsp->get_pixels(ctx->blocks[4], ptr_y + ctx->dct_y_offset, ctx->m.linesize); |
492 | dsp->get_pixels(ctx->blocks[5], ptr_y + ctx->dct_y_offset + bw, ctx->m.linesize); | |
493 | dsp->get_pixels(ctx->blocks[6], ptr_u + ctx->dct_uv_offset, ctx->m.uvlinesize); | |
494 | dsp->get_pixels(ctx->blocks[7], ptr_v + ctx->dct_uv_offset, ctx->m.uvlinesize); | |
fc4cbc16 BC |
495 | } |
496 | } | |
497 | ||
498 | static av_always_inline int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i) | |
499 | { | |
500 | if (i&2) { | |
501 | ctx->m.q_intra_matrix16 = ctx->qmatrix_c16; | |
502 | ctx->m.q_intra_matrix = ctx->qmatrix_c; | |
503 | return 1 + (i&1); | |
504 | } else { | |
505 | ctx->m.q_intra_matrix16 = ctx->qmatrix_l16; | |
506 | ctx->m.q_intra_matrix = ctx->qmatrix_l; | |
507 | return 0; | |
508 | } | |
509 | } | |
510 | ||
2a1294b9 | 511 | static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) |
fc4cbc16 | 512 | { |
2a1294b9 RD |
513 | DNXHDEncContext *ctx = avctx->priv_data; |
514 | int mb_y = jobnr, mb_x; | |
515 | int qscale = ctx->qscale; | |
40d11227 | 516 | LOCAL_ALIGNED_16(DCTELEM, block, [64]); |
2a1294b9 | 517 | ctx = ctx->thread[threadnr]; |
fc4cbc16 | 518 | |
b5ca9cd3 RD |
519 | ctx->m.last_dc[0] = |
520 | ctx->m.last_dc[1] = | |
5ab21439 | 521 | ctx->m.last_dc[2] = 1 << (ctx->cid_table->bit_depth + 2); |
b5ca9cd3 RD |
522 | |
523 | for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { | |
524 | unsigned mb = mb_y * ctx->m.mb_width + mb_x; | |
525 | int ssd = 0; | |
526 | int ac_bits = 0; | |
527 | int dc_bits = 0; | |
528 | int i; | |
529 | ||
530 | dnxhd_get_blocks(ctx, mb_x, mb_y); | |
531 | ||
532 | for (i = 0; i < 8; i++) { | |
b5ca9cd3 RD |
533 | DCTELEM *src_block = ctx->blocks[i]; |
534 | int overflow, nbits, diff, last_index; | |
535 | int n = dnxhd_switch_matrix(ctx, i); | |
536 | ||
40d11227 | 537 | memcpy(block, src_block, 64*sizeof(*block)); |
14cf9e69 | 538 | last_index = ctx->m.dct_quantize(&ctx->m, block, i, qscale, &overflow); |
b5ca9cd3 RD |
539 | ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index); |
540 | ||
541 | diff = block[0] - ctx->m.last_dc[n]; | |
542 | if (diff < 0) nbits = av_log2_16bit(-2*diff); | |
543 | else nbits = av_log2_16bit( 2*diff); | |
5ab21439 JA |
544 | |
545 | assert(nbits < ctx->cid_table->bit_depth + 4); | |
b5ca9cd3 RD |
546 | dc_bits += ctx->cid_table->dc_bits[nbits] + nbits; |
547 | ||
548 | ctx->m.last_dc[n] = block[0]; | |
549 | ||
550 | if (avctx->mb_decision == FF_MB_DECISION_RD || !RC_VARIANCE) { | |
551 | dnxhd_unquantize_c(ctx, block, i, qscale, last_index); | |
552 | ctx->m.dsp.idct(block); | |
553 | ssd += dnxhd_ssd_block(block, src_block); | |
fc4cbc16 | 554 | } |
fc4cbc16 | 555 | } |
b5ca9cd3 RD |
556 | ctx->mb_rc[qscale][mb].ssd = ssd; |
557 | ctx->mb_rc[qscale][mb].bits = ac_bits+dc_bits+12+8*ctx->vlc_bits[0]; | |
558 | } | |
fc4cbc16 BC |
559 | return 0; |
560 | } | |
561 | ||
2a1294b9 | 562 | static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) |
fc4cbc16 | 563 | { |
2a1294b9 RD |
564 | DNXHDEncContext *ctx = avctx->priv_data; |
565 | int mb_y = jobnr, mb_x; | |
566 | ctx = ctx->thread[threadnr]; | |
567 | init_put_bits(&ctx->m.pb, (uint8_t *)arg + 640 + ctx->slice_offs[jobnr], ctx->slice_size[jobnr]); | |
fc4cbc16 | 568 | |
b5ca9cd3 RD |
569 | ctx->m.last_dc[0] = |
570 | ctx->m.last_dc[1] = | |
5ab21439 | 571 | ctx->m.last_dc[2] = 1 << (ctx->cid_table->bit_depth + 2); |
b5ca9cd3 RD |
572 | for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { |
573 | unsigned mb = mb_y * ctx->m.mb_width + mb_x; | |
574 | int qscale = ctx->mb_qscale[mb]; | |
575 | int i; | |
576 | ||
577 | put_bits(&ctx->m.pb, 12, qscale<<1); | |
578 | ||
579 | dnxhd_get_blocks(ctx, mb_x, mb_y); | |
580 | ||
581 | for (i = 0; i < 8; i++) { | |
582 | DCTELEM *block = ctx->blocks[i]; | |
583 | int last_index, overflow; | |
584 | int n = dnxhd_switch_matrix(ctx, i); | |
14cf9e69 | 585 | last_index = ctx->m.dct_quantize(&ctx->m, block, i, qscale, &overflow); |
b5ca9cd3 RD |
586 | //START_TIMER; |
587 | dnxhd_encode_block(ctx, block, last_index, n); | |
588 | //STOP_TIMER("encode_block"); | |
fc4cbc16 | 589 | } |
b5ca9cd3 RD |
590 | } |
591 | if (put_bits_count(&ctx->m.pb)&31) | |
592 | put_bits(&ctx->m.pb, 32-(put_bits_count(&ctx->m.pb)&31), 0); | |
fc4cbc16 BC |
593 | flush_put_bits(&ctx->m.pb); |
594 | return 0; | |
595 | } | |
596 | ||
2a1294b9 | 597 | static void dnxhd_setup_threads_slices(DNXHDEncContext *ctx) |
fc4cbc16 BC |
598 | { |
599 | int mb_y, mb_x; | |
2a1294b9 RD |
600 | int offset = 0; |
601 | for (mb_y = 0; mb_y < ctx->m.mb_height; mb_y++) { | |
602 | int thread_size; | |
603 | ctx->slice_offs[mb_y] = offset; | |
10738239 MR |
604 | ctx->slice_size[mb_y] = 0; |
605 | for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { | |
606 | unsigned mb = mb_y * ctx->m.mb_width + mb_x; | |
607 | ctx->slice_size[mb_y] += ctx->mb_bits[mb]; | |
608 | } | |
609 | ctx->slice_size[mb_y] = (ctx->slice_size[mb_y]+31)&~31; | |
610 | ctx->slice_size[mb_y] >>= 3; | |
611 | thread_size = ctx->slice_size[mb_y]; | |
fc4cbc16 BC |
612 | offset += thread_size; |
613 | } | |
614 | } | |
615 | ||
2a1294b9 | 616 | static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) |
fc4cbc16 | 617 | { |
2a1294b9 RD |
618 | DNXHDEncContext *ctx = avctx->priv_data; |
619 | int mb_y = jobnr, mb_x; | |
620 | ctx = ctx->thread[threadnr]; | |
5ab21439 JA |
621 | if (ctx->cid_table->bit_depth == 8) { |
622 | uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y<<4) * ctx->m.linesize); | |
623 | for (mb_x = 0; mb_x < ctx->m.mb_width; ++mb_x, pix += 16) { | |
624 | unsigned mb = mb_y * ctx->m.mb_width + mb_x; | |
625 | int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize); | |
626 | int varc = (ctx->m.dsp.pix_norm1(pix, ctx->m.linesize) - (((unsigned)(sum*sum))>>8)+128)>>8; | |
627 | ctx->mb_cmp[mb].value = varc; | |
628 | ctx->mb_cmp[mb].mb = mb; | |
629 | } | |
630 | } else { // 10-bit | |
631 | int const linesize = ctx->m.linesize >> 1; | |
632 | for (mb_x = 0; mb_x < ctx->m.mb_width; ++mb_x) { | |
633 | uint16_t *pix = (uint16_t*)ctx->thread[0]->src[0] + ((mb_y << 4) * linesize) + (mb_x << 4); | |
634 | unsigned mb = mb_y * ctx->m.mb_width + mb_x; | |
635 | int sum = 0; | |
636 | int sqsum = 0; | |
637 | int mean, sqmean; | |
e72f3d10 | 638 | int i, j; |
5ab21439 | 639 | // Macroblocks are 16x16 pixels, unlike DCT blocks which are 8x8. |
e72f3d10 MR |
640 | for (i = 0; i < 16; ++i) { |
641 | for (j = 0; j < 16; ++j) { | |
5ab21439 JA |
642 | // Turn 16-bit pixels into 10-bit ones. |
643 | int const sample = (unsigned)pix[j] >> 6; | |
644 | sum += sample; | |
645 | sqsum += sample * sample; | |
646 | // 2^10 * 2^10 * 16 * 16 = 2^28, which is less than INT_MAX | |
647 | } | |
648 | pix += linesize; | |
649 | } | |
650 | mean = sum >> 8; // 16*16 == 2^8 | |
651 | sqmean = sqsum >> 8; | |
652 | ctx->mb_cmp[mb].value = sqmean - mean * mean; | |
653 | ctx->mb_cmp[mb].mb = mb; | |
654 | } | |
b5ca9cd3 | 655 | } |
fc4cbc16 BC |
656 | return 0; |
657 | } | |
658 | ||
659 | static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx) | |
660 | { | |
45b8e9e5 BC |
661 | int lambda, up_step, down_step; |
662 | int last_lower = INT_MAX, last_higher = 0; | |
fc4cbc16 BC |
663 | int x, y, q; |
664 | ||
665 | for (q = 1; q < avctx->qmax; q++) { | |
666 | ctx->qscale = q; | |
2a1294b9 | 667 | avctx->execute2(avctx, dnxhd_calc_bits_thread, NULL, NULL, ctx->m.mb_height); |
fc4cbc16 | 668 | } |
45b8e9e5 | 669 | up_step = down_step = 2<<LAMBDA_FRAC_BITS; |
fc4cbc16 BC |
670 | lambda = ctx->lambda; |
671 | ||
672 | for (;;) { | |
673 | int bits = 0; | |
674 | int end = 0; | |
45b8e9e5 | 675 | if (lambda == last_higher) { |
fc4cbc16 | 676 | lambda++; |
45b8e9e5 | 677 | end = 1; // need to set final qscales/bits |
fc4cbc16 BC |
678 | } |
679 | for (y = 0; y < ctx->m.mb_height; y++) { | |
680 | for (x = 0; x < ctx->m.mb_width; x++) { | |
681 | unsigned min = UINT_MAX; | |
682 | int qscale = 1; | |
683 | int mb = y*ctx->m.mb_width+x; | |
684 | for (q = 1; q < avctx->qmax; q++) { | |
685 | unsigned score = ctx->mb_rc[q][mb].bits*lambda+(ctx->mb_rc[q][mb].ssd<<LAMBDA_FRAC_BITS); | |
686 | if (score < min) { | |
687 | min = score; | |
688 | qscale = q; | |
689 | } | |
690 | } | |
691 | bits += ctx->mb_rc[qscale][mb].bits; | |
692 | ctx->mb_qscale[mb] = qscale; | |
693 | ctx->mb_bits[mb] = ctx->mb_rc[qscale][mb].bits; | |
694 | } | |
695 | bits = (bits+31)&~31; // padding | |
696 | if (bits > ctx->frame_bits) | |
697 | break; | |
698 | } | |
dfd2a005 | 699 | //av_dlog(ctx->m.avctx, "lambda %d, up %u, down %u, bits %d, frame %d\n", |
45b8e9e5 | 700 | // lambda, last_higher, last_lower, bits, ctx->frame_bits); |
fc4cbc16 BC |
701 | if (end) { |
702 | if (bits > ctx->frame_bits) | |
703 | return -1; | |
704 | break; | |
705 | } | |
706 | if (bits < ctx->frame_bits) { | |
45b8e9e5 BC |
707 | last_lower = FFMIN(lambda, last_lower); |
708 | if (last_higher != 0) | |
709 | lambda = (lambda+last_higher)>>1; | |
710 | else | |
711 | lambda -= down_step; | |
712 | down_step *= 5; // XXX tune ? | |
713 | up_step = 1<<LAMBDA_FRAC_BITS; | |
714 | lambda = FFMAX(1, lambda); | |
715 | if (lambda == last_lower) | |
716 | break; | |
fc4cbc16 | 717 | } else { |
45b8e9e5 BC |
718 | last_higher = FFMAX(lambda, last_higher); |
719 | if (last_lower != INT_MAX) | |
720 | lambda = (lambda+last_lower)>>1; | |
cb893cf3 BC |
721 | else if ((int64_t)lambda + up_step > INT_MAX) |
722 | return -1; | |
45b8e9e5 BC |
723 | else |
724 | lambda += up_step; | |
cb893cf3 | 725 | up_step = FFMIN((int64_t)up_step*5, INT_MAX); |
45b8e9e5 | 726 | down_step = 1<<LAMBDA_FRAC_BITS; |
fc4cbc16 BC |
727 | } |
728 | } | |
dfd2a005 | 729 | //av_dlog(ctx->m.avctx, "out lambda %d\n", lambda); |
fc4cbc16 BC |
730 | ctx->lambda = lambda; |
731 | return 0; | |
732 | } | |
733 | ||
734 | static int dnxhd_find_qscale(DNXHDEncContext *ctx) | |
735 | { | |
736 | int bits = 0; | |
737 | int up_step = 1; | |
738 | int down_step = 1; | |
739 | int last_higher = 0; | |
740 | int last_lower = INT_MAX; | |
741 | int qscale; | |
742 | int x, y; | |
743 | ||
744 | qscale = ctx->qscale; | |
745 | for (;;) { | |
746 | bits = 0; | |
747 | ctx->qscale = qscale; | |
748 | // XXX avoid recalculating bits | |
2a1294b9 | 749 | ctx->m.avctx->execute2(ctx->m.avctx, dnxhd_calc_bits_thread, NULL, NULL, ctx->m.mb_height); |
fc4cbc16 BC |
750 | for (y = 0; y < ctx->m.mb_height; y++) { |
751 | for (x = 0; x < ctx->m.mb_width; x++) | |
752 | bits += ctx->mb_rc[qscale][y*ctx->m.mb_width+x].bits; | |
753 | bits = (bits+31)&~31; // padding | |
754 | if (bits > ctx->frame_bits) | |
755 | break; | |
756 | } | |
dfd2a005 | 757 | //av_dlog(ctx->m.avctx, "%d, qscale %d, bits %d, frame %d, higher %d, lower %d\n", |
fc4cbc16 BC |
758 | // ctx->m.avctx->frame_number, qscale, bits, ctx->frame_bits, last_higher, last_lower); |
759 | if (bits < ctx->frame_bits) { | |
760 | if (qscale == 1) | |
78532b05 | 761 | return 1; |
fc4cbc16 BC |
762 | if (last_higher == qscale - 1) { |
763 | qscale = last_higher; | |
764 | break; | |
765 | } | |
766 | last_lower = FFMIN(qscale, last_lower); | |
767 | if (last_higher != 0) | |
768 | qscale = (qscale+last_higher)>>1; | |
769 | else | |
770 | qscale -= down_step++; | |
771 | if (qscale < 1) | |
772 | qscale = 1; | |
773 | up_step = 1; | |
774 | } else { | |
775 | if (last_lower == qscale + 1) | |
776 | break; | |
777 | last_higher = FFMAX(qscale, last_higher); | |
778 | if (last_lower != INT_MAX) | |
779 | qscale = (qscale+last_lower)>>1; | |
780 | else | |
781 | qscale += up_step++; | |
782 | down_step = 1; | |
783 | if (qscale >= ctx->m.avctx->qmax) | |
784 | return -1; | |
785 | } | |
786 | } | |
dfd2a005 | 787 | //av_dlog(ctx->m.avctx, "out qscale %d\n", qscale); |
fc4cbc16 BC |
788 | ctx->qscale = qscale; |
789 | return 0; | |
790 | } | |
791 | ||
40e26453 RD |
792 | #define BUCKET_BITS 8 |
793 | #define RADIX_PASSES 4 | |
794 | #define NBUCKETS (1 << BUCKET_BITS) | |
795 | ||
796 | static inline int get_bucket(int value, int shift) | |
797 | { | |
798 | value >>= shift; | |
799 | value &= NBUCKETS - 1; | |
800 | return NBUCKETS - 1 - value; | |
801 | } | |
802 | ||
803 | static void radix_count(const RCCMPEntry *data, int size, int buckets[RADIX_PASSES][NBUCKETS]) | |
804 | { | |
805 | int i, j; | |
806 | memset(buckets, 0, sizeof(buckets[0][0]) * RADIX_PASSES * NBUCKETS); | |
807 | for (i = 0; i < size; i++) { | |
808 | int v = data[i].value; | |
809 | for (j = 0; j < RADIX_PASSES; j++) { | |
810 | buckets[j][get_bucket(v, 0)]++; | |
811 | v >>= BUCKET_BITS; | |
812 | } | |
813 | assert(!v); | |
814 | } | |
815 | for (j = 0; j < RADIX_PASSES; j++) { | |
816 | int offset = size; | |
817 | for (i = NBUCKETS - 1; i >= 0; i--) | |
818 | buckets[j][i] = offset -= buckets[j][i]; | |
819 | assert(!buckets[j][0]); | |
820 | } | |
821 | } | |
822 | ||
823 | static void radix_sort_pass(RCCMPEntry *dst, const RCCMPEntry *data, int size, int buckets[NBUCKETS], int pass) | |
824 | { | |
825 | int shift = pass * BUCKET_BITS; | |
826 | int i; | |
827 | for (i = 0; i < size; i++) { | |
828 | int v = get_bucket(data[i].value, shift); | |
829 | int pos = buckets[v]++; | |
830 | dst[pos] = data[i]; | |
831 | } | |
832 | } | |
833 | ||
834 | static void radix_sort(RCCMPEntry *data, int size) | |
fc4cbc16 | 835 | { |
40e26453 RD |
836 | int buckets[RADIX_PASSES][NBUCKETS]; |
837 | RCCMPEntry *tmp = av_malloc(sizeof(*tmp) * size); | |
838 | radix_count(data, size, buckets); | |
839 | radix_sort_pass(tmp, data, size, buckets[0], 0); | |
840 | radix_sort_pass(data, tmp, size, buckets[1], 1); | |
841 | if (buckets[2][NBUCKETS - 1] || buckets[3][NBUCKETS - 1]) { | |
842 | radix_sort_pass(tmp, data, size, buckets[2], 2); | |
843 | radix_sort_pass(data, tmp, size, buckets[3], 3); | |
844 | } | |
845 | av_free(tmp); | |
fc4cbc16 BC |
846 | } |
847 | ||
df745b9c | 848 | static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx) |
fc4cbc16 BC |
849 | { |
850 | int max_bits = 0; | |
78532b05 BC |
851 | int ret, x, y; |
852 | if ((ret = dnxhd_find_qscale(ctx)) < 0) | |
fc4cbc16 BC |
853 | return -1; |
854 | for (y = 0; y < ctx->m.mb_height; y++) { | |
855 | for (x = 0; x < ctx->m.mb_width; x++) { | |
856 | int mb = y*ctx->m.mb_width+x; | |
857 | int delta_bits; | |
858 | ctx->mb_qscale[mb] = ctx->qscale; | |
859 | ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale][mb].bits; | |
860 | max_bits += ctx->mb_rc[ctx->qscale][mb].bits; | |
861 | if (!RC_VARIANCE) { | |
862 | delta_bits = ctx->mb_rc[ctx->qscale][mb].bits-ctx->mb_rc[ctx->qscale+1][mb].bits; | |
863 | ctx->mb_cmp[mb].mb = mb; | |
864 | ctx->mb_cmp[mb].value = delta_bits ? | |
865 | ((ctx->mb_rc[ctx->qscale][mb].ssd-ctx->mb_rc[ctx->qscale+1][mb].ssd)*100)/delta_bits | |
866 | : INT_MIN; //avoid increasing qscale | |
867 | } | |
868 | } | |
869 | max_bits += 31; //worst padding | |
870 | } | |
78532b05 | 871 | if (!ret) { |
fc4cbc16 | 872 | if (RC_VARIANCE) |
2a1294b9 | 873 | avctx->execute2(avctx, dnxhd_mb_var_thread, NULL, NULL, ctx->m.mb_height); |
40e26453 | 874 | radix_sort(ctx->mb_cmp, ctx->m.mb_num); |
fc4cbc16 BC |
875 | for (x = 0; x < ctx->m.mb_num && max_bits > ctx->frame_bits; x++) { |
876 | int mb = ctx->mb_cmp[x].mb; | |
877 | max_bits -= ctx->mb_rc[ctx->qscale][mb].bits - ctx->mb_rc[ctx->qscale+1][mb].bits; | |
878 | ctx->mb_qscale[mb] = ctx->qscale+1; | |
879 | ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale+1][mb].bits; | |
880 | } | |
881 | } | |
882 | return 0; | |
883 | } | |
884 | ||
7993df65 | 885 | static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame) |
fc4cbc16 BC |
886 | { |
887 | int i; | |
888 | ||
889 | for (i = 0; i < 3; i++) { | |
890 | ctx->frame.data[i] = frame->data[i]; | |
891 | ctx->frame.linesize[i] = frame->linesize[i]; | |
892 | } | |
893 | ||
894 | for (i = 0; i < ctx->m.avctx->thread_count; i++) { | |
895 | ctx->thread[i]->m.linesize = ctx->frame.linesize[0]<<ctx->interlaced; | |
896 | ctx->thread[i]->m.uvlinesize = ctx->frame.linesize[1]<<ctx->interlaced; | |
897 | ctx->thread[i]->dct_y_offset = ctx->m.linesize *8; | |
898 | ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8; | |
899 | } | |
900 | ||
901 | ctx->frame.interlaced_frame = frame->interlaced_frame; | |
902 | ctx->cur_field = frame->interlaced_frame && !frame->top_field_first; | |
903 | } | |
904 | ||
10ce9195 | 905 | static int dnxhd_encode_picture(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data) |
fc4cbc16 BC |
906 | { |
907 | DNXHDEncContext *ctx = avctx->priv_data; | |
908 | int first_field = 1; | |
909 | int offset, i, ret; | |
910 | ||
911 | if (buf_size < ctx->cid_table->frame_size) { | |
912 | av_log(avctx, AV_LOG_ERROR, "output buffer is too small to compress picture\n"); | |
913 | return -1; | |
914 | } | |
915 | ||
916 | dnxhd_load_picture(ctx, data); | |
917 | ||
918 | encode_coding_unit: | |
919 | for (i = 0; i < 3; i++) { | |
920 | ctx->src[i] = ctx->frame.data[i]; | |
921 | if (ctx->interlaced && ctx->cur_field) | |
922 | ctx->src[i] += ctx->frame.linesize[i]; | |
923 | } | |
924 | ||
925 | dnxhd_write_header(avctx, buf); | |
926 | ||
927 | if (avctx->mb_decision == FF_MB_DECISION_RD) | |
928 | ret = dnxhd_encode_rdo(avctx, ctx); | |
929 | else | |
df745b9c | 930 | ret = dnxhd_encode_fast(avctx, ctx); |
fc4cbc16 | 931 | if (ret < 0) { |
a4fcd996 BC |
932 | av_log(avctx, AV_LOG_ERROR, |
933 | "picture could not fit ratecontrol constraints, increase qmax\n"); | |
fc4cbc16 BC |
934 | return -1; |
935 | } | |
936 | ||
2a1294b9 | 937 | dnxhd_setup_threads_slices(ctx); |
fc4cbc16 BC |
938 | |
939 | offset = 0; | |
940 | for (i = 0; i < ctx->m.mb_height; i++) { | |
941 | AV_WB32(ctx->msip + i * 4, offset); | |
942 | offset += ctx->slice_size[i]; | |
943 | assert(!(ctx->slice_size[i] & 3)); | |
944 | } | |
945 | ||
2a1294b9 | 946 | avctx->execute2(avctx, dnxhd_encode_thread, buf, NULL, ctx->m.mb_height); |
fc4cbc16 | 947 | |
301a24de BC |
948 | assert(640 + offset + 4 <= ctx->cid_table->coding_unit_size); |
949 | memset(buf + 640 + offset, 0, ctx->cid_table->coding_unit_size - 4 - offset - 640); | |
950 | ||
fc4cbc16 BC |
951 | AV_WB32(buf + ctx->cid_table->coding_unit_size - 4, 0x600DC0DE); // EOF |
952 | ||
953 | if (ctx->interlaced && first_field) { | |
954 | first_field = 0; | |
955 | ctx->cur_field ^= 1; | |
956 | buf += ctx->cid_table->coding_unit_size; | |
957 | buf_size -= ctx->cid_table->coding_unit_size; | |
958 | goto encode_coding_unit; | |
959 | } | |
960 | ||
6650c4c3 BC |
961 | ctx->frame.quality = ctx->qscale*FF_QP2LAMBDA; |
962 | ||
fc4cbc16 BC |
963 | return ctx->cid_table->frame_size; |
964 | } | |
965 | ||
966 | static int dnxhd_encode_end(AVCodecContext *avctx) | |
967 | { | |
968 | DNXHDEncContext *ctx = avctx->priv_data; | |
556eec43 | 969 | int max_level = 1<<(ctx->cid_table->bit_depth+2); |
fc4cbc16 BC |
970 | int i; |
971 | ||
b73e868b BC |
972 | av_free(ctx->vlc_codes-max_level*2); |
973 | av_free(ctx->vlc_bits -max_level*2); | |
974 | av_freep(&ctx->run_codes); | |
975 | av_freep(&ctx->run_bits); | |
fc4cbc16 BC |
976 | |
977 | av_freep(&ctx->mb_bits); | |
978 | av_freep(&ctx->mb_qscale); | |
979 | av_freep(&ctx->mb_rc); | |
980 | av_freep(&ctx->mb_cmp); | |
981 | av_freep(&ctx->slice_size); | |
2a1294b9 | 982 | av_freep(&ctx->slice_offs); |
fc4cbc16 BC |
983 | |
984 | av_freep(&ctx->qmatrix_c); | |
985 | av_freep(&ctx->qmatrix_l); | |
986 | av_freep(&ctx->qmatrix_c16); | |
987 | av_freep(&ctx->qmatrix_l16); | |
988 | ||
989 | for (i = 1; i < avctx->thread_count; i++) | |
990 | av_freep(&ctx->thread[i]); | |
991 | ||
992 | return 0; | |
993 | } | |
994 | ||
d36beb3f | 995 | AVCodec ff_dnxhd_encoder = { |
fc4cbc16 | 996 | "dnxhd", |
72415b2a | 997 | AVMEDIA_TYPE_VIDEO, |
fc4cbc16 BC |
998 | CODEC_ID_DNXHD, |
999 | sizeof(DNXHDEncContext), | |
1000 | dnxhd_encode_init, | |
1001 | dnxhd_encode_picture, | |
1002 | dnxhd_encode_end, | |
94f7451a | 1003 | .capabilities = CODEC_CAP_SLICE_THREADS, |
5ab21439 | 1004 | .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_YUV422P10, PIX_FMT_NONE}, |
fe4bf374 | 1005 | .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), |
99bbc781 | 1006 | .priv_class = &class, |
fc4cbc16 | 1007 | }; |