annotate dnxhdenc.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents 8a4984c5cacc
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
1 /*
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
2 * VC3/DNxHD encoder
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
3 * Copyright (c) 2007 Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
4 *
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
5 * VC-3 encoder funded by the British Broadcasting Corporation
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
6 *
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
7 * This file is part of FFmpeg.
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
8 *
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
9 * FFmpeg is free software; you can redistribute it and/or
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
10 * modify it under the terms of the GNU Lesser General Public
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
11 * License as published by the Free Software Foundation; either
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
12 * version 2.1 of the License, or (at your option) any later version.
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
13 *
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
14 * FFmpeg is distributed in the hope that it will be useful,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
17 * Lesser General Public License for more details.
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
18 *
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
19 * You should have received a copy of the GNU Lesser General Public
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
20 * License along with FFmpeg; if not, write to the Free Software
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
22 */
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
23
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
24 //#define DEBUG
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
25 #define RC_VARIANCE 1 // use variance or ssd for fast rc
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
26
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
27 #include "avcodec.h"
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
28 #include "dsputil.h"
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
29 #include "mpegvideo.h"
8294
f92b595af7eb move structure definitions in their own header
bcoudurier
parents: 8293
diff changeset
30 #include "dnxhdenc.h"
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
31
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
32 int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
33
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
34 #define LAMBDA_FRAC_BITS 10
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
35
8302
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
36 static av_always_inline void dnxhd_get_pixels_8x4(DCTELEM *restrict block, const uint8_t *pixels, int line_size)
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
37 {
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
38 int i;
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
39 for (i = 0; i < 4; i++) {
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
40 block[0] = pixels[0]; block[1] = pixels[1];
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
41 block[2] = pixels[2]; block[3] = pixels[3];
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
42 block[4] = pixels[4]; block[5] = pixels[5];
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
43 block[6] = pixels[6]; block[7] = pixels[7];
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
44 pixels += line_size;
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
45 block += 8;
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
46 }
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
47 memcpy(block , block- 8, sizeof(*block)*8);
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
48 memcpy(block+ 8, block-16, sizeof(*block)*8);
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
49 memcpy(block+16, block-24, sizeof(*block)*8);
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
50 memcpy(block+24, block-32, sizeof(*block)*8);
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
51 }
f54976d6a8a5 Move get_pixels_8x4 before init func to avoid useless forward declaration.
bcoudurier
parents: 8301
diff changeset
52
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
53 static int dnxhd_init_vlc(DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
54 {
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
55 int i, j, level, run;
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
56 int max_level = 1<<(ctx->cid_table->bit_depth+2);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
57
10137
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
58 FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->vlc_codes, max_level*4*sizeof(*ctx->vlc_codes), fail);
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
59 FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->vlc_bits , max_level*4*sizeof(*ctx->vlc_bits ), fail);
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
60 FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_codes, 63*2 , fail);
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
61 FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_bits , 63 , fail);
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
62
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
63 ctx->vlc_codes += max_level*2;
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
64 ctx->vlc_bits += max_level*2;
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
65 for (level = -max_level; level < max_level; level++) {
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
66 for (run = 0; run < 2; run++) {
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
67 int index = (level<<1)|run;
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
68 int sign, offset = 0, alevel = level;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
69
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
70 MASK_ABS(sign, alevel);
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
71 if (alevel > 64) {
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
72 offset = (alevel-1)>>6;
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
73 alevel -= offset<<6;
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
74 }
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
75 for (j = 0; j < 257; j++) {
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
76 if (ctx->cid_table->ac_level[j] == alevel &&
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
77 (!offset || (ctx->cid_table->ac_index_flag[j] && offset)) &&
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
78 (!run || (ctx->cid_table->ac_run_flag [j] && run))) {
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
79 assert(!ctx->vlc_codes[index]);
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
80 if (alevel) {
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
81 ctx->vlc_codes[index] = (ctx->cid_table->ac_codes[j]<<1)|(sign&1);
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
82 ctx->vlc_bits [index] = ctx->cid_table->ac_bits[j]+1;
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
83 } else {
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
84 ctx->vlc_codes[index] = ctx->cid_table->ac_codes[j];
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
85 ctx->vlc_bits [index] = ctx->cid_table->ac_bits [j];
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
86 }
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
87 break;
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
88 }
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
89 }
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
90 assert(!alevel || j < 257);
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
91 if (offset) {
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
92 ctx->vlc_codes[index] = (ctx->vlc_codes[index]<<ctx->cid_table->index_bits)|offset;
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
93 ctx->vlc_bits [index]+= ctx->cid_table->index_bits;
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
94 }
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
95 }
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
96 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
97 for (i = 0; i < 62; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
98 int run = ctx->cid_table->run[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
99 assert(run < 63);
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
100 ctx->run_codes[run] = ctx->cid_table->run_codes[i];
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
101 ctx->run_bits [run] = ctx->cid_table->run_bits[i];
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
102 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
103 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
104 fail:
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
105 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
106 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
107
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
108 static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
109 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
110 // init first elem to 1 to avoid div by 0 in convert_matrix
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
111 uint16_t weight_matrix[64] = {1,}; // convert_matrix needs uint16_t*
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
112 int qscale, i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
113
10137
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
114 FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l, (ctx->m.avctx->qmax+1) * 64 * sizeof(int) , fail);
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
115 FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c, (ctx->m.avctx->qmax+1) * 64 * sizeof(int) , fail);
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
116 FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t), fail);
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
117 FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t), fail);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
118
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
119 for (i = 1; i < 64; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
120 int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]];
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
121 weight_matrix[j] = ctx->cid_table->luma_weight[i];
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
122 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
123 ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_l, ctx->qmatrix_l16, weight_matrix,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
124 ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
125 for (i = 1; i < 64; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
126 int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]];
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
127 weight_matrix[j] = ctx->cid_table->chroma_weight[i];
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
128 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
129 ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_c, ctx->qmatrix_c16, weight_matrix,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
130 ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
131 for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
132 for (i = 0; i < 64; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
133 ctx->qmatrix_l [qscale] [i] <<= 2; ctx->qmatrix_c [qscale] [i] <<= 2;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
134 ctx->qmatrix_l16[qscale][0][i] <<= 2; ctx->qmatrix_l16[qscale][1][i] <<= 2;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
135 ctx->qmatrix_c16[qscale][0][i] <<= 2; ctx->qmatrix_c16[qscale][1][i] <<= 2;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
136 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
137 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
138 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
139 fail:
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
140 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
141 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
142
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
143 static int dnxhd_init_rc(DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
144 {
10137
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
145 FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry), fail);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
146 if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD)
10137
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
147 FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_cmp, ctx->m.mb_num*sizeof(RCCMPEntry), fail);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
148
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
149 ctx->frame_bits = (ctx->cid_table->coding_unit_size - 640 - 4) * 8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
150 ctx->qscale = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
151 ctx->lambda = 2<<LAMBDA_FRAC_BITS; // qscale 2
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
152 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
153 fail:
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
154 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
155 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
156
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
157 static int dnxhd_encode_init(AVCodecContext *avctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
158 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
159 DNXHDEncContext *ctx = avctx->priv_data;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
160 int i, index;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
161
6041
bb4b486c6775 add bitrate helper to choose all dnxhd variants
bcoudurier
parents: 5972
diff changeset
162 ctx->cid = ff_dnxhd_find_cid(avctx);
5971
405be936dac4 dnxhd 720p encoding and decoding support
bcoudurier
parents: 5970
diff changeset
163 if (!ctx->cid || avctx->pix_fmt != PIX_FMT_YUV422P) {
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
164 av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD\n");
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
165 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
166 }
6041
bb4b486c6775 add bitrate helper to choose all dnxhd variants
bcoudurier
parents: 5972
diff changeset
167 av_log(avctx, AV_LOG_DEBUG, "cid %d\n", ctx->cid);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
168
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
169 index = ff_dnxhd_get_cid_table(ctx->cid);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
170 ctx->cid_table = &ff_dnxhd_cid_table[index];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
171
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
172 ctx->m.avctx = avctx;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
173 ctx->m.mb_intra = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
174 ctx->m.h263_aic = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
175
8303
bf6a78c6697b dnxhd get_pixels_8x4_sym sse2
bcoudurier
parents: 8302
diff changeset
176 ctx->get_pixels_8x4_sym = dnxhd_get_pixels_8x4;
bf6a78c6697b dnxhd get_pixels_8x4_sym sse2
bcoudurier
parents: 8302
diff changeset
177
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
178 dsputil_init(&ctx->m.dsp, avctx);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
179 ff_dct_common_init(&ctx->m);
8590
7a463923ecd1 Change semantic of CONFIG_*, HAVE_* and ARCH_*.
aurel
parents: 8303
diff changeset
180 #if HAVE_MMX
8303
bf6a78c6697b dnxhd get_pixels_8x4_sym sse2
bcoudurier
parents: 8302
diff changeset
181 ff_dnxhd_init_mmx(ctx);
bf6a78c6697b dnxhd get_pixels_8x4_sym sse2
bcoudurier
parents: 8302
diff changeset
182 #endif
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
183 if (!ctx->m.dct_quantize)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
184 ctx->m.dct_quantize = dct_quantize_c;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
185
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
186 ctx->m.mb_height = (avctx->height + 15) / 16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
187 ctx->m.mb_width = (avctx->width + 15) / 16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
188
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
189 if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
190 ctx->interlaced = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
191 ctx->m.mb_height /= 2;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
192 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
193
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
194 ctx->m.mb_num = ctx->m.mb_height * ctx->m.mb_width;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
195
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
196 if (avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
197 ctx->m.intra_quant_bias = avctx->intra_quant_bias;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
198 if (dnxhd_init_qmat(ctx, ctx->m.intra_quant_bias, 0) < 0) // XXX tune lbias/cbias
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
199 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
200
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
201 if (dnxhd_init_vlc(ctx) < 0)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
202 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
203 if (dnxhd_init_rc(ctx) < 0)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
204 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
205
10137
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
206 FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_size, ctx->m.mb_height*sizeof(uint32_t), fail);
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
207 FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_offs, ctx->m.mb_height*sizeof(uint32_t), fail);
10137
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
208 FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_bits, ctx->m.mb_num *sizeof(uint16_t), fail);
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
209 FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_qscale, ctx->m.mb_num *sizeof(uint8_t) , fail);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
210
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
211 ctx->frame.key_frame = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
212 ctx->frame.pict_type = FF_I_TYPE;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
213 ctx->m.avctx->coded_frame = &ctx->frame;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
214
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
215 if (avctx->thread_count > MAX_THREADS) {
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
216 av_log(avctx, AV_LOG_ERROR, "too many threads\n");
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
217 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
218 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
219
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
220 ctx->thread[0] = ctx;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
221 for (i = 1; i < avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
222 ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
223 memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
224 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
225
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
226 return 0;
10137
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
227 fail: //for FF_ALLOCZ_OR_GOTO
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
228 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
229 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
230
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
231 static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
232 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
233 DNXHDEncContext *ctx = avctx->priv_data;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
234 const uint8_t header_prefix[5] = { 0x00,0x00,0x02,0x80,0x01 };
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
235
10186
f01415f3f9a8 fix uninitialized memory in dnxhd encoder
bcoudurier
parents: 10146
diff changeset
236 memset(buf, 0, 640);
f01415f3f9a8 fix uninitialized memory in dnxhd encoder
bcoudurier
parents: 10146
diff changeset
237
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
238 memcpy(buf, header_prefix, 5);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
239 buf[5] = ctx->interlaced ? ctx->cur_field+2 : 0x01;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
240 buf[6] = 0x80; // crc flag off
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
241 buf[7] = 0xa0; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
242 AV_WB16(buf + 0x18, avctx->height); // ALPF
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
243 AV_WB16(buf + 0x1a, avctx->width); // SPL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
244 AV_WB16(buf + 0x1d, avctx->height); // NAL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
245
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
246 buf[0x21] = 0x38; // FIXME 8 bit per comp
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
247 buf[0x22] = 0x88 + (ctx->frame.interlaced_frame<<2);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
248 AV_WB32(buf + 0x28, ctx->cid); // CID
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
249 buf[0x2c] = ctx->interlaced ? 0 : 0x80;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
250
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
251 buf[0x5f] = 0x01; // UDL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
252
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
253 buf[0x167] = 0x02; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
254 AV_WB16(buf + 0x16a, ctx->m.mb_height * 4 + 4); // MSIPS
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
255 buf[0x16d] = ctx->m.mb_height; // Ns
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
256 buf[0x16f] = 0x10; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
257
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
258 ctx->msip = buf + 0x170;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
259 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
260 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
261
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
262 static av_always_inline void dnxhd_encode_dc(DNXHDEncContext *ctx, int diff)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
263 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
264 int nbits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
265 if (diff < 0) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
266 nbits = av_log2_16bit(-2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
267 diff--;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
268 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
269 nbits = av_log2_16bit(2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
270 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
271 put_bits(&ctx->m.pb, ctx->cid_table->dc_bits[nbits] + nbits,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
272 (ctx->cid_table->dc_codes[nbits]<<nbits) + (diff & ((1 << nbits) - 1)));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
273 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
274
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
275 static av_always_inline void dnxhd_encode_block(DNXHDEncContext *ctx, DCTELEM *block, int last_index, int n)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
276 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
277 int last_non_zero = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
278 int slevel, i, j;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
279
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
280 dnxhd_encode_dc(ctx, block[0] - ctx->m.last_dc[n]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
281 ctx->m.last_dc[n] = block[0];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
282
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
283 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
284 j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
285 slevel = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
286 if (slevel) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
287 int run_level = i - last_non_zero - 1;
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
288 int rlevel = (slevel<<1)|!!run_level;
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
289 put_bits(&ctx->m.pb, ctx->vlc_bits[rlevel], ctx->vlc_codes[rlevel]);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
290 if (run_level)
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
291 put_bits(&ctx->m.pb, ctx->run_bits[run_level], ctx->run_codes[run_level]);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
292 last_non_zero = i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
293 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
294 }
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
295 put_bits(&ctx->m.pb, ctx->vlc_bits[0], ctx->vlc_codes[0]); // EOB
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
296 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
297
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
298 static av_always_inline void dnxhd_unquantize_c(DNXHDEncContext *ctx, DCTELEM *block, int n, int qscale, int last_index)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
299 {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
300 const uint8_t *weight_matrix;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
301 int level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
302 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
303
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
304 weight_matrix = (n&2) ? ctx->cid_table->chroma_weight : ctx->cid_table->luma_weight;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
305
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
306 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
307 int j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
308 level = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
309 if (level) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
310 if (level < 0) {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
311 level = (1-2*level) * qscale * weight_matrix[i];
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
312 if (weight_matrix[i] != 32)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
313 level += 32;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
314 level >>= 6;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
315 level = -level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
316 } else {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
317 level = (2*level+1) * qscale * weight_matrix[i];
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
318 if (weight_matrix[i] != 32)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
319 level += 32;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
320 level >>= 6;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
321 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
322 block[j] = level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
323 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
324 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
325 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
326
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
327 static av_always_inline int dnxhd_ssd_block(DCTELEM *qblock, DCTELEM *block)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
328 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
329 int score = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
330 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
331 for (i = 0; i < 64; i++)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
332 score += (block[i]-qblock[i])*(block[i]-qblock[i]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
333 return score;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
334 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
335
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
336 static av_always_inline int dnxhd_calc_ac_bits(DNXHDEncContext *ctx, DCTELEM *block, int last_index)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
337 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
338 int last_non_zero = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
339 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
340 int i, j, level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
341 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
342 j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
343 level = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
344 if (level) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
345 int run_level = i - last_non_zero - 1;
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
346 bits += ctx->vlc_bits[(level<<1)|!!run_level]+ctx->run_bits[run_level];
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
347 last_non_zero = i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
348 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
349 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
350 return bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
351 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
352
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
353 static av_always_inline void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
354 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
355 const uint8_t *ptr_y = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.linesize) + (mb_x << 4);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
356 const uint8_t *ptr_u = ctx->thread[0]->src[1] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << 3);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
357 const uint8_t *ptr_v = ctx->thread[0]->src[2] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << 3);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
358 DSPContext *dsp = &ctx->m.dsp;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
359
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
360 dsp->get_pixels(ctx->blocks[0], ptr_y , ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
361 dsp->get_pixels(ctx->blocks[1], ptr_y + 8, ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
362 dsp->get_pixels(ctx->blocks[2], ptr_u , ctx->m.uvlinesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
363 dsp->get_pixels(ctx->blocks[3], ptr_v , ctx->m.uvlinesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
364
5971
405be936dac4 dnxhd 720p encoding and decoding support
bcoudurier
parents: 5970
diff changeset
365 if (mb_y+1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) {
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
366 if (ctx->interlaced) {
8303
bf6a78c6697b dnxhd get_pixels_8x4_sym sse2
bcoudurier
parents: 8302
diff changeset
367 ctx->get_pixels_8x4_sym(ctx->blocks[4], ptr_y + ctx->dct_y_offset , ctx->m.linesize);
bf6a78c6697b dnxhd get_pixels_8x4_sym sse2
bcoudurier
parents: 8302
diff changeset
368 ctx->get_pixels_8x4_sym(ctx->blocks[5], ptr_y + ctx->dct_y_offset + 8, ctx->m.linesize);
bf6a78c6697b dnxhd get_pixels_8x4_sym sse2
bcoudurier
parents: 8302
diff changeset
369 ctx->get_pixels_8x4_sym(ctx->blocks[6], ptr_u + ctx->dct_uv_offset , ctx->m.uvlinesize);
bf6a78c6697b dnxhd get_pixels_8x4_sym sse2
bcoudurier
parents: 8302
diff changeset
370 ctx->get_pixels_8x4_sym(ctx->blocks[7], ptr_v + ctx->dct_uv_offset , ctx->m.uvlinesize);
8292
d77ee820a5f1 use dsp clear_block
bcoudurier
parents: 8129
diff changeset
371 } else {
d77ee820a5f1 use dsp clear_block
bcoudurier
parents: 8129
diff changeset
372 dsp->clear_block(ctx->blocks[4]); dsp->clear_block(ctx->blocks[5]);
d77ee820a5f1 use dsp clear_block
bcoudurier
parents: 8129
diff changeset
373 dsp->clear_block(ctx->blocks[6]); dsp->clear_block(ctx->blocks[7]);
d77ee820a5f1 use dsp clear_block
bcoudurier
parents: 8129
diff changeset
374 }
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
375 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
376 dsp->get_pixels(ctx->blocks[4], ptr_y + ctx->dct_y_offset , ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
377 dsp->get_pixels(ctx->blocks[5], ptr_y + ctx->dct_y_offset + 8, ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
378 dsp->get_pixels(ctx->blocks[6], ptr_u + ctx->dct_uv_offset , ctx->m.uvlinesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
379 dsp->get_pixels(ctx->blocks[7], ptr_v + ctx->dct_uv_offset , ctx->m.uvlinesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
380 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
381 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
382
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
383 static av_always_inline int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
384 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
385 if (i&2) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
386 ctx->m.q_intra_matrix16 = ctx->qmatrix_c16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
387 ctx->m.q_intra_matrix = ctx->qmatrix_c;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
388 return 1 + (i&1);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
389 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
390 ctx->m.q_intra_matrix16 = ctx->qmatrix_l16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
391 ctx->m.q_intra_matrix = ctx->qmatrix_l;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
392 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
393 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
394 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
395
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
396 static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
397 {
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
398 DNXHDEncContext *ctx = avctx->priv_data;
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
399 int mb_y = jobnr, mb_x;
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
400 int qscale = ctx->qscale;
11195
d464f498e19f Use LOCAL_ALIGNED macro for local arrays
mru
parents: 10961
diff changeset
401 LOCAL_ALIGNED_16(DCTELEM, block, [64]);
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
402 ctx = ctx->thread[threadnr];
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
403
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
404 ctx->m.last_dc[0] =
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
405 ctx->m.last_dc[1] =
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
406 ctx->m.last_dc[2] = 1024;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
407
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
408 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
409 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
410 int ssd = 0;
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
411 int ac_bits = 0;
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
412 int dc_bits = 0;
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
413 int i;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
414
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
415 dnxhd_get_blocks(ctx, mb_x, mb_y);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
416
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
417 for (i = 0; i < 8; i++) {
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
418 DCTELEM *src_block = ctx->blocks[i];
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
419 int overflow, nbits, diff, last_index;
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
420 int n = dnxhd_switch_matrix(ctx, i);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
421
11195
d464f498e19f Use LOCAL_ALIGNED macro for local arrays
mru
parents: 10961
diff changeset
422 memcpy(block, src_block, 64*sizeof(*block));
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
423 last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow);
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
424 ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
425
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
426 diff = block[0] - ctx->m.last_dc[n];
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
427 if (diff < 0) nbits = av_log2_16bit(-2*diff);
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
428 else nbits = av_log2_16bit( 2*diff);
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
429 dc_bits += ctx->cid_table->dc_bits[nbits] + nbits;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
430
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
431 ctx->m.last_dc[n] = block[0];
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
432
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
433 if (avctx->mb_decision == FF_MB_DECISION_RD || !RC_VARIANCE) {
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
434 dnxhd_unquantize_c(ctx, block, i, qscale, last_index);
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
435 ctx->m.dsp.idct(block);
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
436 ssd += dnxhd_ssd_block(block, src_block);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
437 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
438 }
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
439 ctx->mb_rc[qscale][mb].ssd = ssd;
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
440 ctx->mb_rc[qscale][mb].bits = ac_bits+dc_bits+12+8*ctx->vlc_bits[0];
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
441 }
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
442 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
443 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
444
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
445 static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
446 {
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
447 DNXHDEncContext *ctx = avctx->priv_data;
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
448 int mb_y = jobnr, mb_x;
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
449 ctx = ctx->thread[threadnr];
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
450 init_put_bits(&ctx->m.pb, (uint8_t *)arg + 640 + ctx->slice_offs[jobnr], ctx->slice_size[jobnr]);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
451
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
452 ctx->m.last_dc[0] =
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
453 ctx->m.last_dc[1] =
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
454 ctx->m.last_dc[2] = 1024;
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
455 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
456 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
457 int qscale = ctx->mb_qscale[mb];
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
458 int i;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
459
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
460 put_bits(&ctx->m.pb, 12, qscale<<1);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
461
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
462 dnxhd_get_blocks(ctx, mb_x, mb_y);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
463
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
464 for (i = 0; i < 8; i++) {
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
465 DCTELEM *block = ctx->blocks[i];
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
466 int last_index, overflow;
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
467 int n = dnxhd_switch_matrix(ctx, i);
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
468 last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow);
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
469 //START_TIMER;
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
470 dnxhd_encode_block(ctx, block, last_index, n);
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
471 //STOP_TIMER("encode_block");
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
472 }
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
473 }
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
474 if (put_bits_count(&ctx->m.pb)&31)
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
475 put_bits(&ctx->m.pb, 32-(put_bits_count(&ctx->m.pb)&31), 0);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
476 flush_put_bits(&ctx->m.pb);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
477 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
478 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
479
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
480 static void dnxhd_setup_threads_slices(DNXHDEncContext *ctx)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
481 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
482 int mb_y, mb_x;
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
483 int offset = 0;
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
484 for (mb_y = 0; mb_y < ctx->m.mb_height; mb_y++) {
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
485 int thread_size;
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
486 ctx->slice_offs[mb_y] = offset;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
487 ctx->slice_size[mb_y] = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
488 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
489 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
490 ctx->slice_size[mb_y] += ctx->mb_bits[mb];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
491 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
492 ctx->slice_size[mb_y] = (ctx->slice_size[mb_y]+31)&~31;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
493 ctx->slice_size[mb_y] >>= 3;
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
494 thread_size = ctx->slice_size[mb_y];
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
495 offset += thread_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
496 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
497 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
498
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
499 static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
500 {
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
501 DNXHDEncContext *ctx = avctx->priv_data;
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
502 int mb_y = jobnr, mb_x;
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
503 ctx = ctx->thread[threadnr];
10388
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
504 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
505 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
506 uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y<<4) * ctx->m.linesize) + (mb_x<<4);
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
507 int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize);
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
508 int varc = (ctx->m.dsp.pix_norm1(pix, ctx->m.linesize) - (((unsigned)(sum*sum))>>8)+128)>>8;
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
509 ctx->mb_cmp[mb].value = varc;
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
510 ctx->mb_cmp[mb].mb = mb;
08e50bcdcbf1 Reindent after removing the outer for loops in the execute2 patch
reimar
parents: 10387
diff changeset
511 }
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
512 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
513 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
514
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
515 static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
516 {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
517 int lambda, up_step, down_step;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
518 int last_lower = INT_MAX, last_higher = 0;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
519 int x, y, q;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
520
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
521 for (q = 1; q < avctx->qmax; q++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
522 ctx->qscale = q;
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
523 avctx->execute2(avctx, dnxhd_calc_bits_thread, NULL, NULL, ctx->m.mb_height);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
524 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
525 up_step = down_step = 2<<LAMBDA_FRAC_BITS;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
526 lambda = ctx->lambda;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
527
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
528 for (;;) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
529 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
530 int end = 0;
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
531 if (lambda == last_higher) {
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
532 lambda++;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
533 end = 1; // need to set final qscales/bits
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
534 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
535 for (y = 0; y < ctx->m.mb_height; y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
536 for (x = 0; x < ctx->m.mb_width; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
537 unsigned min = UINT_MAX;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
538 int qscale = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
539 int mb = y*ctx->m.mb_width+x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
540 for (q = 1; q < avctx->qmax; q++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
541 unsigned score = ctx->mb_rc[q][mb].bits*lambda+(ctx->mb_rc[q][mb].ssd<<LAMBDA_FRAC_BITS);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
542 if (score < min) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
543 min = score;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
544 qscale = q;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
545 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
546 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
547 bits += ctx->mb_rc[qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
548 ctx->mb_qscale[mb] = qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
549 ctx->mb_bits[mb] = ctx->mb_rc[qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
550 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
551 bits = (bits+31)&~31; // padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
552 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
553 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
554 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
555 //dprintf(ctx->m.avctx, "lambda %d, up %u, down %u, bits %d, frame %d\n",
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
556 // lambda, last_higher, last_lower, bits, ctx->frame_bits);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
557 if (end) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
558 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
559 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
560 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
561 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
562 if (bits < ctx->frame_bits) {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
563 last_lower = FFMIN(lambda, last_lower);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
564 if (last_higher != 0)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
565 lambda = (lambda+last_higher)>>1;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
566 else
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
567 lambda -= down_step;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
568 down_step *= 5; // XXX tune ?
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
569 up_step = 1<<LAMBDA_FRAC_BITS;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
570 lambda = FFMAX(1, lambda);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
571 if (lambda == last_lower)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
572 break;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
573 } else {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
574 last_higher = FFMAX(lambda, last_higher);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
575 if (last_lower != INT_MAX)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
576 lambda = (lambda+last_lower)>>1;
10542
5a298a61c6cc avoid integer overflow in dnxhd encoder, fixes #1557
bcoudurier
parents: 10541
diff changeset
577 else if ((int64_t)lambda + up_step > INT_MAX)
5a298a61c6cc avoid integer overflow in dnxhd encoder, fixes #1557
bcoudurier
parents: 10541
diff changeset
578 return -1;
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
579 else
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
580 lambda += up_step;
10542
5a298a61c6cc avoid integer overflow in dnxhd encoder, fixes #1557
bcoudurier
parents: 10541
diff changeset
581 up_step = FFMIN((int64_t)up_step*5, INT_MAX);
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
582 down_step = 1<<LAMBDA_FRAC_BITS;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
583 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
584 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
585 //dprintf(ctx->m.avctx, "out lambda %d\n", lambda);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
586 ctx->lambda = lambda;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
587 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
588 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
589
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
590 static int dnxhd_find_qscale(DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
591 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
592 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
593 int up_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
594 int down_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
595 int last_higher = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
596 int last_lower = INT_MAX;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
597 int qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
598 int x, y;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
599
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
600 qscale = ctx->qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
601 for (;;) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
602 bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
603 ctx->qscale = qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
604 // XXX avoid recalculating bits
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
605 ctx->m.avctx->execute2(ctx->m.avctx, dnxhd_calc_bits_thread, NULL, NULL, ctx->m.mb_height);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
606 for (y = 0; y < ctx->m.mb_height; y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
607 for (x = 0; x < ctx->m.mb_width; x++)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
608 bits += ctx->mb_rc[qscale][y*ctx->m.mb_width+x].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
609 bits = (bits+31)&~31; // padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
610 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
611 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
612 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
613 //dprintf(ctx->m.avctx, "%d, qscale %d, bits %d, frame %d, higher %d, lower %d\n",
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
614 // ctx->m.avctx->frame_number, qscale, bits, ctx->frame_bits, last_higher, last_lower);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
615 if (bits < ctx->frame_bits) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
616 if (qscale == 1)
5969
c5d11f6f6a3d fix corner case when qscale 1 bits < frame bits but max bits with worst padding > frame bits
bcoudurier
parents: 5802
diff changeset
617 return 1;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
618 if (last_higher == qscale - 1) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
619 qscale = last_higher;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
620 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
621 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
622 last_lower = FFMIN(qscale, last_lower);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
623 if (last_higher != 0)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
624 qscale = (qscale+last_higher)>>1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
625 else
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
626 qscale -= down_step++;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
627 if (qscale < 1)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
628 qscale = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
629 up_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
630 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
631 if (last_lower == qscale + 1)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
632 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
633 last_higher = FFMAX(qscale, last_higher);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
634 if (last_lower != INT_MAX)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
635 qscale = (qscale+last_lower)>>1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
636 else
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
637 qscale += up_step++;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
638 down_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
639 if (qscale >= ctx->m.avctx->qmax)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
640 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
641 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
642 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
643 //dprintf(ctx->m.avctx, "out qscale %d\n", qscale);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
644 ctx->qscale = qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
645 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
646 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
647
10214
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
648 #define BUCKET_BITS 8
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
649 #define RADIX_PASSES 4
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
650 #define NBUCKETS (1 << BUCKET_BITS)
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
651
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
652 static inline int get_bucket(int value, int shift)
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
653 {
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
654 value >>= shift;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
655 value &= NBUCKETS - 1;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
656 return NBUCKETS - 1 - value;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
657 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
658
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
659 static void radix_count(const RCCMPEntry *data, int size, int buckets[RADIX_PASSES][NBUCKETS])
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
660 {
10214
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
661 int i, j;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
662 memset(buckets, 0, sizeof(buckets[0][0]) * RADIX_PASSES * NBUCKETS);
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
663 for (i = 0; i < size; i++) {
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
664 int v = data[i].value;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
665 for (j = 0; j < RADIX_PASSES; j++) {
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
666 buckets[j][get_bucket(v, 0)]++;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
667 v >>= BUCKET_BITS;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
668 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
669 assert(!v);
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
670 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
671 for (j = 0; j < RADIX_PASSES; j++) {
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
672 int offset = size;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
673 for (i = NBUCKETS - 1; i >= 0; i--)
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
674 buckets[j][i] = offset -= buckets[j][i];
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
675 assert(!buckets[j][0]);
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
676 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
677 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
678
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
679 static void radix_sort_pass(RCCMPEntry *dst, const RCCMPEntry *data, int size, int buckets[NBUCKETS], int pass)
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
680 {
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
681 int shift = pass * BUCKET_BITS;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
682 int i;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
683 for (i = 0; i < size; i++) {
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
684 int v = get_bucket(data[i].value, shift);
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
685 int pos = buckets[v]++;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
686 dst[pos] = data[i];
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
687 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
688 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
689
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
690 static void radix_sort(RCCMPEntry *data, int size)
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
691 {
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
692 int buckets[RADIX_PASSES][NBUCKETS];
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
693 RCCMPEntry *tmp = av_malloc(sizeof(*tmp) * size);
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
694 radix_count(data, size, buckets);
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
695 radix_sort_pass(tmp, data, size, buckets[0], 0);
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
696 radix_sort_pass(data, tmp, size, buckets[1], 1);
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
697 if (buckets[2][NBUCKETS - 1] || buckets[3][NBUCKETS - 1]) {
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
698 radix_sort_pass(tmp, data, size, buckets[2], 2);
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
699 radix_sort_pass(data, tmp, size, buckets[3], 3);
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
700 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
701 av_free(tmp);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
702 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
703
5970
e1ac22f75cf6 cosmetics, encode_variance -> encode_fast
bcoudurier
parents: 5969
diff changeset
704 static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
705 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
706 int max_bits = 0;
5969
c5d11f6f6a3d fix corner case when qscale 1 bits < frame bits but max bits with worst padding > frame bits
bcoudurier
parents: 5802
diff changeset
707 int ret, x, y;
c5d11f6f6a3d fix corner case when qscale 1 bits < frame bits but max bits with worst padding > frame bits
bcoudurier
parents: 5802
diff changeset
708 if ((ret = dnxhd_find_qscale(ctx)) < 0)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
709 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
710 for (y = 0; y < ctx->m.mb_height; y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
711 for (x = 0; x < ctx->m.mb_width; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
712 int mb = y*ctx->m.mb_width+x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
713 int delta_bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
714 ctx->mb_qscale[mb] = ctx->qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
715 ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
716 max_bits += ctx->mb_rc[ctx->qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
717 if (!RC_VARIANCE) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
718 delta_bits = ctx->mb_rc[ctx->qscale][mb].bits-ctx->mb_rc[ctx->qscale+1][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
719 ctx->mb_cmp[mb].mb = mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
720 ctx->mb_cmp[mb].value = delta_bits ?
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
721 ((ctx->mb_rc[ctx->qscale][mb].ssd-ctx->mb_rc[ctx->qscale+1][mb].ssd)*100)/delta_bits
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
722 : INT_MIN; //avoid increasing qscale
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
723 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
724 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
725 max_bits += 31; //worst padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
726 }
5969
c5d11f6f6a3d fix corner case when qscale 1 bits < frame bits but max bits with worst padding > frame bits
bcoudurier
parents: 5802
diff changeset
727 if (!ret) {
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
728 if (RC_VARIANCE)
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
729 avctx->execute2(avctx, dnxhd_mb_var_thread, NULL, NULL, ctx->m.mb_height);
10214
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
730 radix_sort(ctx->mb_cmp, ctx->m.mb_num);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
731 for (x = 0; x < ctx->m.mb_num && max_bits > ctx->frame_bits; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
732 int mb = ctx->mb_cmp[x].mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
733 max_bits -= ctx->mb_rc[ctx->qscale][mb].bits - ctx->mb_rc[ctx->qscale+1][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
734 ctx->mb_qscale[mb] = ctx->qscale+1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
735 ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale+1][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
736 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
737 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
738 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
739 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
740
6218
michael
parents: 6041
diff changeset
741 static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
742 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
743 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
744
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
745 for (i = 0; i < 3; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
746 ctx->frame.data[i] = frame->data[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
747 ctx->frame.linesize[i] = frame->linesize[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
748 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
749
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
750 for (i = 0; i < ctx->m.avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
751 ctx->thread[i]->m.linesize = ctx->frame.linesize[0]<<ctx->interlaced;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
752 ctx->thread[i]->m.uvlinesize = ctx->frame.linesize[1]<<ctx->interlaced;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
753 ctx->thread[i]->dct_y_offset = ctx->m.linesize *8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
754 ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
755 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
756
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
757 ctx->frame.interlaced_frame = frame->interlaced_frame;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
758 ctx->cur_field = frame->interlaced_frame && !frame->top_field_first;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
759 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
760
9618
85ad5d68ec98 data parameter of dnxhd_encode_picture() should not be const.
diego
parents: 8590
diff changeset
761 static int dnxhd_encode_picture(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
762 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
763 DNXHDEncContext *ctx = avctx->priv_data;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
764 int first_field = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
765 int offset, i, ret;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
766
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
767 if (buf_size < ctx->cid_table->frame_size) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
768 av_log(avctx, AV_LOG_ERROR, "output buffer is too small to compress picture\n");
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
769 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
770 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
771
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
772 dnxhd_load_picture(ctx, data);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
773
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
774 encode_coding_unit:
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
775 for (i = 0; i < 3; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
776 ctx->src[i] = ctx->frame.data[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
777 if (ctx->interlaced && ctx->cur_field)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
778 ctx->src[i] += ctx->frame.linesize[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
779 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
780
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
781 dnxhd_write_header(avctx, buf);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
782
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
783 if (avctx->mb_decision == FF_MB_DECISION_RD)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
784 ret = dnxhd_encode_rdo(avctx, ctx);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
785 else
5970
e1ac22f75cf6 cosmetics, encode_variance -> encode_fast
bcoudurier
parents: 5969
diff changeset
786 ret = dnxhd_encode_fast(avctx, ctx);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
787 if (ret < 0) {
10541
5afea08b89d4 clarify why the encoder is failing
bcoudurier
parents: 10388
diff changeset
788 av_log(avctx, AV_LOG_ERROR,
5afea08b89d4 clarify why the encoder is failing
bcoudurier
parents: 10388
diff changeset
789 "picture could not fit ratecontrol constraints, increase qmax\n");
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
790 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
791 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
792
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
793 dnxhd_setup_threads_slices(ctx);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
794
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
795 offset = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
796 for (i = 0; i < ctx->m.mb_height; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
797 AV_WB32(ctx->msip + i * 4, offset);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
798 offset += ctx->slice_size[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
799 assert(!(ctx->slice_size[i] & 3));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
800 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
801
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
802 avctx->execute2(avctx, dnxhd_encode_thread, buf, NULL, ctx->m.mb_height);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
803
10186
f01415f3f9a8 fix uninitialized memory in dnxhd encoder
bcoudurier
parents: 10146
diff changeset
804 assert(640 + offset + 4 <= ctx->cid_table->coding_unit_size);
f01415f3f9a8 fix uninitialized memory in dnxhd encoder
bcoudurier
parents: 10146
diff changeset
805 memset(buf + 640 + offset, 0, ctx->cid_table->coding_unit_size - 4 - offset - 640);
f01415f3f9a8 fix uninitialized memory in dnxhd encoder
bcoudurier
parents: 10146
diff changeset
806
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
807 AV_WB32(buf + ctx->cid_table->coding_unit_size - 4, 0x600DC0DE); // EOF
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
808
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
809 if (ctx->interlaced && first_field) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
810 first_field = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
811 ctx->cur_field ^= 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
812 buf += ctx->cid_table->coding_unit_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
813 buf_size -= ctx->cid_table->coding_unit_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
814 goto encode_coding_unit;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
815 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
816
6752
b2daf71037be export dnxhd encoded picture quality
bcoudurier
parents: 6710
diff changeset
817 ctx->frame.quality = ctx->qscale*FF_QP2LAMBDA;
b2daf71037be export dnxhd encoded picture quality
bcoudurier
parents: 6710
diff changeset
818
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
819 return ctx->cid_table->frame_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
820 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
821
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
822 static int dnxhd_encode_end(AVCodecContext *avctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
823 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
824 DNXHDEncContext *ctx = avctx->priv_data;
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
825 int max_level = 1<<(ctx->cid_table->bit_depth+2);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
826 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
827
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
828 av_free(ctx->vlc_codes-max_level*2);
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
829 av_free(ctx->vlc_bits -max_level*2);
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
830 av_freep(&ctx->run_codes);
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
831 av_freep(&ctx->run_bits);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
832
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
833 av_freep(&ctx->mb_bits);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
834 av_freep(&ctx->mb_qscale);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
835 av_freep(&ctx->mb_rc);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
836 av_freep(&ctx->mb_cmp);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
837 av_freep(&ctx->slice_size);
10387
19a4f1ecd8fe Move dnxhdenc to execute2 multithreading API.
reimar
parents: 10368
diff changeset
838 av_freep(&ctx->slice_offs);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
839
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
840 av_freep(&ctx->qmatrix_c);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
841 av_freep(&ctx->qmatrix_l);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
842 av_freep(&ctx->qmatrix_c16);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
843 av_freep(&ctx->qmatrix_l16);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
844
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
845 for (i = 1; i < avctx->thread_count; i++)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
846 av_freep(&ctx->thread[i]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
847
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
848 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
849 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
850
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
851 AVCodec dnxhd_encoder = {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
852 "dnxhd",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 11195
diff changeset
853 AVMEDIA_TYPE_VIDEO,
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
854 CODEC_ID_DNXHD,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
855 sizeof(DNXHDEncContext),
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
856 dnxhd_encode_init,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
857 dnxhd_encode_picture,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
858 dnxhd_encode_end,
10146
38cfe222e1a4 Mark all pix_fmts and supported_framerates compound literals as const.
reimar
parents: 10137
diff changeset
859 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_NONE},
7040
e943e1409077 Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents: 6981
diff changeset
860 .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
861 };