annotate dnxhdenc.c @ 10320:44f31c1c9acc libavcodec

Make sure that dv encoder initializes all encoded packet data. The specification does not say which value to use for unused parts, so fill all unused bytes with 0xff, which is consistent with what DV usually uses for reserved or unused parts.
author reimar
date Tue, 29 Sep 2009 19:17:18 +0000
parents 97f38ca4ed14
children 59ec306245a4
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);
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
207 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
208 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
209
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
210 ctx->frame.key_frame = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
211 ctx->frame.pict_type = FF_I_TYPE;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
212 ctx->m.avctx->coded_frame = &ctx->frame;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
213
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
214 if (avctx->thread_count > MAX_THREADS || (avctx->thread_count > ctx->m.mb_height)) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
215 av_log(avctx, AV_LOG_ERROR, "too many threads\n");
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
216 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
217 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
218
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
219 ctx->thread[0] = ctx;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
220 for (i = 1; i < avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
221 ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
222 memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
223 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
224
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
225 for (i = 0; i < avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
226 ctx->thread[i]->m.start_mb_y = (ctx->m.mb_height*(i ) + avctx->thread_count/2) / avctx->thread_count;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
227 ctx->thread[i]->m.end_mb_y = (ctx->m.mb_height*(i+1) + avctx->thread_count/2) / avctx->thread_count;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
228 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
229
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
230 return 0;
10137
9a670cfd1941 Rename CHECKED_ALLOC(Z) to FF_ALLOC(Z)_OR_GOTO and add context and label
ramiro
parents: 9618
diff changeset
231 fail: //for FF_ALLOCZ_OR_GOTO
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
232 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
233 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
234
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
235 static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
236 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
237 DNXHDEncContext *ctx = avctx->priv_data;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
238 const uint8_t header_prefix[5] = { 0x00,0x00,0x02,0x80,0x01 };
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
239
10186
f01415f3f9a8 fix uninitialized memory in dnxhd encoder
bcoudurier
parents: 10146
diff changeset
240 memset(buf, 0, 640);
f01415f3f9a8 fix uninitialized memory in dnxhd encoder
bcoudurier
parents: 10146
diff changeset
241
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
242 memcpy(buf, header_prefix, 5);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
243 buf[5] = ctx->interlaced ? ctx->cur_field+2 : 0x01;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
244 buf[6] = 0x80; // crc flag off
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
245 buf[7] = 0xa0; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
246 AV_WB16(buf + 0x18, avctx->height); // ALPF
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
247 AV_WB16(buf + 0x1a, avctx->width); // SPL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
248 AV_WB16(buf + 0x1d, avctx->height); // NAL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
249
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
250 buf[0x21] = 0x38; // FIXME 8 bit per comp
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
251 buf[0x22] = 0x88 + (ctx->frame.interlaced_frame<<2);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
252 AV_WB32(buf + 0x28, ctx->cid); // CID
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
253 buf[0x2c] = ctx->interlaced ? 0 : 0x80;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
254
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
255 buf[0x5f] = 0x01; // UDL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
256
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
257 buf[0x167] = 0x02; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
258 AV_WB16(buf + 0x16a, ctx->m.mb_height * 4 + 4); // MSIPS
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
259 buf[0x16d] = ctx->m.mb_height; // Ns
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
260 buf[0x16f] = 0x10; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
261
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
262 ctx->msip = buf + 0x170;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
263 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
264 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
265
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
266 static av_always_inline void dnxhd_encode_dc(DNXHDEncContext *ctx, int diff)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
267 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
268 int nbits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
269 if (diff < 0) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
270 nbits = av_log2_16bit(-2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
271 diff--;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
272 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
273 nbits = av_log2_16bit(2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
274 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
275 put_bits(&ctx->m.pb, ctx->cid_table->dc_bits[nbits] + nbits,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
276 (ctx->cid_table->dc_codes[nbits]<<nbits) + (diff & ((1 << nbits) - 1)));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
277 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
278
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
279 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
280 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
281 int last_non_zero = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
282 int slevel, i, j;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
283
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
284 dnxhd_encode_dc(ctx, block[0] - ctx->m.last_dc[n]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
285 ctx->m.last_dc[n] = block[0];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
286
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
287 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
288 j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
289 slevel = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
290 if (slevel) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
291 int run_level = i - last_non_zero - 1;
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
292 int rlevel = (slevel<<1)|!!run_level;
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
293 put_bits(&ctx->m.pb, ctx->vlc_bits[rlevel], ctx->vlc_codes[rlevel]);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
294 if (run_level)
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
295 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
296 last_non_zero = i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
297 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
298 }
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
299 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
300 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
301
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
302 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
303 {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
304 const uint8_t *weight_matrix;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
305 int level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
306 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
307
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
308 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
309
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
310 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
311 int j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
312 level = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
313 if (level) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
314 if (level < 0) {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
315 level = (1-2*level) * qscale * weight_matrix[i];
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
316 if (weight_matrix[i] != 32)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
317 level += 32;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
318 level >>= 6;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
319 level = -level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
320 } else {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
321 level = (2*level+1) * qscale * weight_matrix[i];
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
322 if (weight_matrix[i] != 32)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
323 level += 32;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
324 level >>= 6;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
325 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
326 block[j] = level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
327 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
328 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
329 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
330
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
331 static av_always_inline int dnxhd_ssd_block(DCTELEM *qblock, DCTELEM *block)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
332 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
333 int score = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
334 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
335 for (i = 0; i < 64; i++)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
336 score += (block[i]-qblock[i])*(block[i]-qblock[i]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
337 return score;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
338 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
339
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
340 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
341 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
342 int last_non_zero = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
343 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
344 int i, j, level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
345 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
346 j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
347 level = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
348 if (level) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
349 int run_level = i - last_non_zero - 1;
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
350 bits += ctx->vlc_bits[(level<<1)|!!run_level]+ctx->run_bits[run_level];
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
351 last_non_zero = i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
352 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
353 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
354 return bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
355 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
356
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
357 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
358 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
359 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
360 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
361 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
362 DSPContext *dsp = &ctx->m.dsp;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
363
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
364 dsp->get_pixels(ctx->blocks[0], ptr_y , ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
365 dsp->get_pixels(ctx->blocks[1], ptr_y + 8, ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
366 dsp->get_pixels(ctx->blocks[2], ptr_u , ctx->m.uvlinesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
367 dsp->get_pixels(ctx->blocks[3], ptr_v , ctx->m.uvlinesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
368
5971
405be936dac4 dnxhd 720p encoding and decoding support
bcoudurier
parents: 5970
diff changeset
369 if (mb_y+1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) {
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
370 if (ctx->interlaced) {
8303
bf6a78c6697b dnxhd get_pixels_8x4_sym sse2
bcoudurier
parents: 8302
diff changeset
371 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
372 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
373 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
374 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
375 } else {
d77ee820a5f1 use dsp clear_block
bcoudurier
parents: 8129
diff changeset
376 dsp->clear_block(ctx->blocks[4]); dsp->clear_block(ctx->blocks[5]);
d77ee820a5f1 use dsp clear_block
bcoudurier
parents: 8129
diff changeset
377 dsp->clear_block(ctx->blocks[6]); dsp->clear_block(ctx->blocks[7]);
d77ee820a5f1 use dsp clear_block
bcoudurier
parents: 8129
diff changeset
378 }
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
379 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
380 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
381 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
382 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
383 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
384 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
385 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
386
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
387 static av_always_inline int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
388 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
389 if (i&2) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
390 ctx->m.q_intra_matrix16 = ctx->qmatrix_c16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
391 ctx->m.q_intra_matrix = ctx->qmatrix_c;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
392 return 1 + (i&1);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
393 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
394 ctx->m.q_intra_matrix16 = ctx->qmatrix_l16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
395 ctx->m.q_intra_matrix = ctx->qmatrix_l;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
396 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
397 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
398 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
399
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
400 static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
401 {
8129
a9734fe0811e Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents: 7040
diff changeset
402 DNXHDEncContext *ctx = *(void**)arg;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
403 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
404 int qscale = ctx->thread[0]->qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
405
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
406 for (mb_y = ctx->m.start_mb_y; mb_y < ctx->m.end_mb_y; mb_y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
407 ctx->m.last_dc[0] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
408 ctx->m.last_dc[1] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
409 ctx->m.last_dc[2] = 1024;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
410
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
411 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
412 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
413 int ssd = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
414 int ac_bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
415 int dc_bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
416 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
417
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
418 dnxhd_get_blocks(ctx, mb_x, mb_y);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
419
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
420 for (i = 0; i < 8; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
421 DECLARE_ALIGNED_16(DCTELEM, block[64]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
422 DCTELEM *src_block = ctx->blocks[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
423 int overflow, nbits, diff, last_index;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
424 int n = dnxhd_switch_matrix(ctx, i);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
425
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
426 memcpy(block, src_block, sizeof(block));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
427 last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
428 ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
429
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
430 diff = block[0] - ctx->m.last_dc[n];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
431 if (diff < 0) nbits = av_log2_16bit(-2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
432 else nbits = av_log2_16bit( 2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
433 dc_bits += ctx->cid_table->dc_bits[nbits] + nbits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
434
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
435 ctx->m.last_dc[n] = block[0];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
436
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
437 if (avctx->mb_decision == FF_MB_DECISION_RD || !RC_VARIANCE) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
438 dnxhd_unquantize_c(ctx, block, i, qscale, last_index);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
439 ctx->m.dsp.idct(block);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
440 ssd += dnxhd_ssd_block(block, src_block);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
441 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
442 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
443 ctx->mb_rc[qscale][mb].ssd = ssd;
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
444 ctx->mb_rc[qscale][mb].bits = ac_bits+dc_bits+12+8*ctx->vlc_bits[0];
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
445 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
446 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
447 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
448 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
449
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
450 static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
451 {
8129
a9734fe0811e Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents: 7040
diff changeset
452 DNXHDEncContext *ctx = *(void**)arg;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
453 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
454
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
455 for (mb_y = ctx->m.start_mb_y; mb_y < ctx->m.end_mb_y; mb_y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
456 ctx->m.last_dc[0] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
457 ctx->m.last_dc[1] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
458 ctx->m.last_dc[2] = 1024;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
459 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
460 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
461 int qscale = ctx->mb_qscale[mb];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
462 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
463
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
464 put_bits(&ctx->m.pb, 12, qscale<<1);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
465
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
466 dnxhd_get_blocks(ctx, mb_x, mb_y);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
467
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
468 for (i = 0; i < 8; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
469 DCTELEM *block = ctx->blocks[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
470 int last_index, overflow;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
471 int n = dnxhd_switch_matrix(ctx, i);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
472 last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow);
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
473 //START_TIMER;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
474 dnxhd_encode_block(ctx, block, last_index, n);
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
475 //STOP_TIMER("encode_block");
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
476 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
477 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
478 if (put_bits_count(&ctx->m.pb)&31)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
479 put_bits(&ctx->m.pb, 32-(put_bits_count(&ctx->m.pb)&31), 0);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
480 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
481 flush_put_bits(&ctx->m.pb);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
482 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
483 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
484
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
485 static void dnxhd_setup_threads_slices(DNXHDEncContext *ctx, uint8_t *buf)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
486 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
487 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
488 int i, offset = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
489 for (i = 0; i < ctx->m.avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
490 int thread_size = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
491 for (mb_y = ctx->thread[i]->m.start_mb_y; mb_y < ctx->thread[i]->m.end_mb_y; mb_y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
492 ctx->slice_size[mb_y] = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
493 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
494 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
495 ctx->slice_size[mb_y] += ctx->mb_bits[mb];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
496 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
497 ctx->slice_size[mb_y] = (ctx->slice_size[mb_y]+31)&~31;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
498 ctx->slice_size[mb_y] >>= 3;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
499 thread_size += ctx->slice_size[mb_y];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
500 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
501 init_put_bits(&ctx->thread[i]->m.pb, buf + 640 + offset, thread_size);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
502 offset += thread_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
503 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
504 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
505
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
506 static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
507 {
8129
a9734fe0811e Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents: 7040
diff changeset
508 DNXHDEncContext *ctx = *(void**)arg;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
509 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
510 for (mb_y = ctx->m.start_mb_y; mb_y < ctx->m.end_mb_y; mb_y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
511 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
512 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
513 uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y<<4) * ctx->m.linesize) + (mb_x<<4);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
514 int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
515 int varc = (ctx->m.dsp.pix_norm1(pix, ctx->m.linesize) - (((unsigned)(sum*sum))>>8)+128)>>8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
516 ctx->mb_cmp[mb].value = varc;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
517 ctx->mb_cmp[mb].mb = mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
518 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
519 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
520 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
521 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
522
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
523 static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
524 {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
525 int lambda, up_step, down_step;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
526 int last_lower = INT_MAX, last_higher = 0;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
527 int x, y, q;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
528
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
529 for (q = 1; q < avctx->qmax; q++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
530 ctx->qscale = q;
8129
a9734fe0811e Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents: 7040
diff changeset
531 avctx->execute(avctx, dnxhd_calc_bits_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count, sizeof(void*));
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
532 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
533 up_step = down_step = 2<<LAMBDA_FRAC_BITS;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
534 lambda = ctx->lambda;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
535
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
536 for (;;) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
537 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
538 int end = 0;
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
539 if (lambda == last_higher) {
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
540 lambda++;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
541 end = 1; // need to set final qscales/bits
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
542 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
543 for (y = 0; y < ctx->m.mb_height; y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
544 for (x = 0; x < ctx->m.mb_width; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
545 unsigned min = UINT_MAX;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
546 int qscale = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
547 int mb = y*ctx->m.mb_width+x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
548 for (q = 1; q < avctx->qmax; q++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
549 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
550 if (score < min) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
551 min = score;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
552 qscale = q;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
553 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
554 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
555 bits += ctx->mb_rc[qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
556 ctx->mb_qscale[mb] = qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
557 ctx->mb_bits[mb] = ctx->mb_rc[qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
558 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
559 bits = (bits+31)&~31; // padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
560 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
561 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
562 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
563 //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
564 // lambda, last_higher, last_lower, bits, ctx->frame_bits);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
565 if (end) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
566 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
567 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
568 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
569 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
570 if (bits < ctx->frame_bits) {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
571 last_lower = FFMIN(lambda, last_lower);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
572 if (last_higher != 0)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
573 lambda = (lambda+last_higher)>>1;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
574 else
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
575 lambda -= down_step;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
576 down_step *= 5; // XXX tune ?
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
577 up_step = 1<<LAMBDA_FRAC_BITS;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
578 lambda = FFMAX(1, lambda);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
579 if (lambda == last_lower)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
580 break;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
581 } else {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
582 last_higher = FFMAX(lambda, last_higher);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
583 if (last_lower != INT_MAX)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
584 lambda = (lambda+last_lower)>>1;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
585 else
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
586 lambda += up_step;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
587 up_step *= 5;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
588 down_step = 1<<LAMBDA_FRAC_BITS;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
589 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
590 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
591 //dprintf(ctx->m.avctx, "out lambda %d\n", lambda);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
592 ctx->lambda = lambda;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
593 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
594 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
595
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
596 static int dnxhd_find_qscale(DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
597 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
598 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
599 int up_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
600 int down_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
601 int last_higher = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
602 int last_lower = INT_MAX;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
603 int qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
604 int x, y;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
605
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
606 qscale = ctx->qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
607 for (;;) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
608 bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
609 ctx->qscale = qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
610 // XXX avoid recalculating bits
8129
a9734fe0811e Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents: 7040
diff changeset
611 ctx->m.avctx->execute(ctx->m.avctx, dnxhd_calc_bits_thread, (void**)&ctx->thread[0], NULL, ctx->m.avctx->thread_count, sizeof(void*));
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
612 for (y = 0; y < ctx->m.mb_height; y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
613 for (x = 0; x < ctx->m.mb_width; x++)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
614 bits += ctx->mb_rc[qscale][y*ctx->m.mb_width+x].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
615 bits = (bits+31)&~31; // padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
616 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
617 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
618 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
619 //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
620 // ctx->m.avctx->frame_number, qscale, bits, ctx->frame_bits, last_higher, last_lower);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
621 if (bits < ctx->frame_bits) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
622 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
623 return 1;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
624 if (last_higher == qscale - 1) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
625 qscale = last_higher;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
626 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
627 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
628 last_lower = FFMIN(qscale, last_lower);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
629 if (last_higher != 0)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
630 qscale = (qscale+last_higher)>>1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
631 else
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
632 qscale -= down_step++;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
633 if (qscale < 1)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
634 qscale = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
635 up_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
636 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
637 if (last_lower == qscale + 1)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
638 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
639 last_higher = FFMAX(qscale, last_higher);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
640 if (last_lower != INT_MAX)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
641 qscale = (qscale+last_lower)>>1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
642 else
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
643 qscale += up_step++;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
644 down_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
645 if (qscale >= ctx->m.avctx->qmax)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
646 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
647 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
648 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
649 //dprintf(ctx->m.avctx, "out qscale %d\n", qscale);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
650 ctx->qscale = qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
651 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
652 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
653
10214
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
654 #define BUCKET_BITS 8
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
655 #define RADIX_PASSES 4
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
656 #define NBUCKETS (1 << BUCKET_BITS)
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 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
659 {
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
660 value >>= shift;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
661 value &= NBUCKETS - 1;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
662 return NBUCKETS - 1 - value;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
663 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
664
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
665 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
666 {
10214
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
667 int i, j;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
668 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
669 for (i = 0; i < size; i++) {
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
670 int v = data[i].value;
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 buckets[j][get_bucket(v, 0)]++;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
673 v >>= BUCKET_BITS;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
674 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
675 assert(!v);
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 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
678 int offset = size;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
679 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
680 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
681 assert(!buckets[j][0]);
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
682 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
683 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
684
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
685 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
686 {
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
687 int shift = pass * BUCKET_BITS;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
688 int i;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
689 for (i = 0; i < size; i++) {
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
690 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
691 int pos = buckets[v]++;
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
692 dst[pos] = data[i];
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
693 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
694 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
695
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
696 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
697 {
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
698 int buckets[RADIX_PASSES][NBUCKETS];
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
699 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
700 radix_count(data, size, buckets);
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
701 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
702 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
703 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
704 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
705 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
706 }
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
707 av_free(tmp);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
708 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
709
5970
e1ac22f75cf6 cosmetics, encode_variance -> encode_fast
bcoudurier
parents: 5969
diff changeset
710 static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
711 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
712 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
713 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
714 if ((ret = dnxhd_find_qscale(ctx)) < 0)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
715 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
716 for (y = 0; y < ctx->m.mb_height; y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
717 for (x = 0; x < ctx->m.mb_width; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
718 int mb = y*ctx->m.mb_width+x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
719 int delta_bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
720 ctx->mb_qscale[mb] = ctx->qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
721 ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
722 max_bits += ctx->mb_rc[ctx->qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
723 if (!RC_VARIANCE) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
724 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
725 ctx->mb_cmp[mb].mb = mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
726 ctx->mb_cmp[mb].value = delta_bits ?
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
727 ((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
728 : INT_MIN; //avoid increasing qscale
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
729 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
730 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
731 max_bits += 31; //worst padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
732 }
5969
c5d11f6f6a3d fix corner case when qscale 1 bits < frame bits but max bits with worst padding > frame bits
bcoudurier
parents: 5802
diff changeset
733 if (!ret) {
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
734 if (RC_VARIANCE)
8129
a9734fe0811e Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents: 7040
diff changeset
735 avctx->execute(avctx, dnxhd_mb_var_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count, sizeof(void*));
10214
97f38ca4ed14 Use a custom radix sort implementation instead of qsort in dnxhd encoder.
reimar
parents: 10186
diff changeset
736 radix_sort(ctx->mb_cmp, ctx->m.mb_num);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
737 for (x = 0; x < ctx->m.mb_num && max_bits > ctx->frame_bits; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
738 int mb = ctx->mb_cmp[x].mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
739 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
740 ctx->mb_qscale[mb] = ctx->qscale+1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
741 ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale+1][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
742 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
743 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
744 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
745 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
746
6218
michael
parents: 6041
diff changeset
747 static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
748 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
749 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
750
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
751 for (i = 0; i < 3; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
752 ctx->frame.data[i] = frame->data[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
753 ctx->frame.linesize[i] = frame->linesize[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
754 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
755
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
756 for (i = 0; i < ctx->m.avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
757 ctx->thread[i]->m.linesize = ctx->frame.linesize[0]<<ctx->interlaced;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
758 ctx->thread[i]->m.uvlinesize = ctx->frame.linesize[1]<<ctx->interlaced;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
759 ctx->thread[i]->dct_y_offset = ctx->m.linesize *8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
760 ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
761 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
762
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
763 ctx->frame.interlaced_frame = frame->interlaced_frame;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
764 ctx->cur_field = frame->interlaced_frame && !frame->top_field_first;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
765 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
766
9618
85ad5d68ec98 data parameter of dnxhd_encode_picture() should not be const.
diego
parents: 8590
diff changeset
767 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
768 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
769 DNXHDEncContext *ctx = avctx->priv_data;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
770 int first_field = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
771 int offset, i, ret;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
772
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
773 if (buf_size < ctx->cid_table->frame_size) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
774 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
775 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
776 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
777
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
778 dnxhd_load_picture(ctx, data);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
779
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
780 encode_coding_unit:
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
781 for (i = 0; i < 3; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
782 ctx->src[i] = ctx->frame.data[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
783 if (ctx->interlaced && ctx->cur_field)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
784 ctx->src[i] += ctx->frame.linesize[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
785 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
786
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
787 dnxhd_write_header(avctx, buf);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
788
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
789 if (avctx->mb_decision == FF_MB_DECISION_RD)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
790 ret = dnxhd_encode_rdo(avctx, ctx);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
791 else
5970
e1ac22f75cf6 cosmetics, encode_variance -> encode_fast
bcoudurier
parents: 5969
diff changeset
792 ret = dnxhd_encode_fast(avctx, ctx);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
793 if (ret < 0) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
794 av_log(avctx, AV_LOG_ERROR, "picture could not fit ratecontrol constraints\n");
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
795 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
796 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
797
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
798 dnxhd_setup_threads_slices(ctx, buf);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
799
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
800 offset = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
801 for (i = 0; i < ctx->m.mb_height; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
802 AV_WB32(ctx->msip + i * 4, offset);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
803 offset += ctx->slice_size[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
804 assert(!(ctx->slice_size[i] & 3));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
805 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
806
8129
a9734fe0811e Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents: 7040
diff changeset
807 avctx->execute(avctx, dnxhd_encode_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count, sizeof(void*));
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
808
10186
f01415f3f9a8 fix uninitialized memory in dnxhd encoder
bcoudurier
parents: 10146
diff changeset
809 assert(640 + offset + 4 <= ctx->cid_table->coding_unit_size);
f01415f3f9a8 fix uninitialized memory in dnxhd encoder
bcoudurier
parents: 10146
diff changeset
810 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
811
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
812 AV_WB32(buf + ctx->cid_table->coding_unit_size - 4, 0x600DC0DE); // EOF
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
813
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
814 if (ctx->interlaced && first_field) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
815 first_field = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
816 ctx->cur_field ^= 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
817 buf += ctx->cid_table->coding_unit_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
818 buf_size -= ctx->cid_table->coding_unit_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
819 goto encode_coding_unit;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
820 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
821
6752
b2daf71037be export dnxhd encoded picture quality
bcoudurier
parents: 6710
diff changeset
822 ctx->frame.quality = ctx->qscale*FF_QP2LAMBDA;
b2daf71037be export dnxhd encoded picture quality
bcoudurier
parents: 6710
diff changeset
823
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
824 return ctx->cid_table->frame_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
825 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
826
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
827 static int dnxhd_encode_end(AVCodecContext *avctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
828 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
829 DNXHDEncContext *ctx = avctx->priv_data;
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
830 int max_level = 1<<(ctx->cid_table->bit_depth+2);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
831 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
832
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
833 av_free(ctx->vlc_codes-max_level*2);
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
834 av_free(ctx->vlc_bits -max_level*2);
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
835 av_freep(&ctx->run_codes);
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
836 av_freep(&ctx->run_bits);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
837
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
838 av_freep(&ctx->mb_bits);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
839 av_freep(&ctx->mb_qscale);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
840 av_freep(&ctx->mb_rc);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
841 av_freep(&ctx->mb_cmp);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
842 av_freep(&ctx->slice_size);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
843
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
844 av_freep(&ctx->qmatrix_c);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
845 av_freep(&ctx->qmatrix_l);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
846 av_freep(&ctx->qmatrix_c16);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
847 av_freep(&ctx->qmatrix_l16);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
848
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
849 for (i = 1; i < avctx->thread_count; i++)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
850 av_freep(&ctx->thread[i]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
851
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
852 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
853 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
854
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
855 AVCodec dnxhd_encoder = {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
856 "dnxhd",
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
857 CODEC_TYPE_VIDEO,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
858 CODEC_ID_DNXHD,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
859 sizeof(DNXHDEncContext),
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
860 dnxhd_encode_init,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
861 dnxhd_encode_picture,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
862 dnxhd_encode_end,
10146
38cfe222e1a4 Mark all pix_fmts and supported_framerates compound literals as const.
reimar
parents: 10137
diff changeset
863 .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
864 .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
865 };