annotate dnxhdenc.c @ 9357:2108342734cc libavcodec

Move av_packet_*() functions from libavformat/ to libavcodec/, where the AVPacket structure now resides also. Patch by Thilo Borgmann thilo.borgmann googlemail com, see the mailinglist thread "Google Summer of Code participation" for additional discussion.
author rbultje
date Tue, 07 Apr 2009 18:31:14 +0000
parents 7a463923ecd1
children 85ad5d68ec98
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
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
58 CHECKED_ALLOCZ(ctx->vlc_codes, max_level*4*sizeof(*ctx->vlc_codes));
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
59 CHECKED_ALLOCZ(ctx->vlc_bits, max_level*4*sizeof(*ctx->vlc_bits));
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
60 CHECKED_ALLOCZ(ctx->run_codes, 63*2);
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
61 CHECKED_ALLOCZ(ctx->run_bits, 63);
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
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
114 CHECKED_ALLOCZ(ctx->qmatrix_l, (ctx->m.avctx->qmax+1) * 64 * sizeof(int));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
115 CHECKED_ALLOCZ(ctx->qmatrix_c, (ctx->m.avctx->qmax+1) * 64 * sizeof(int));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
116 CHECKED_ALLOCZ(ctx->qmatrix_l16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
117 CHECKED_ALLOCZ(ctx->qmatrix_c16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t));
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 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
145 CHECKED_ALLOCZ(ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
146 if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
147 CHECKED_ALLOCZ(ctx->mb_cmp, ctx->m.mb_num*sizeof(RCCMPEntry));
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
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
206 CHECKED_ALLOCZ(ctx->slice_size, ctx->m.mb_height*sizeof(uint32_t));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
207 CHECKED_ALLOCZ(ctx->mb_bits, ctx->m.mb_num *sizeof(uint16_t));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
208 CHECKED_ALLOCZ(ctx->mb_qscale, ctx->m.mb_num *sizeof(uint8_t));
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;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
231 fail: //for CHECKED_ALLOCZ
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
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
240 memcpy(buf, header_prefix, 5);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
241 buf[5] = ctx->interlaced ? ctx->cur_field+2 : 0x01;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
242 buf[6] = 0x80; // crc flag off
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
243 buf[7] = 0xa0; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
244 AV_WB16(buf + 0x18, avctx->height); // ALPF
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
245 AV_WB16(buf + 0x1a, avctx->width); // SPL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
246 AV_WB16(buf + 0x1d, avctx->height); // NAL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
247
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
248 buf[0x21] = 0x38; // FIXME 8 bit per comp
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
249 buf[0x22] = 0x88 + (ctx->frame.interlaced_frame<<2);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
250 AV_WB32(buf + 0x28, ctx->cid); // CID
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
251 buf[0x2c] = ctx->interlaced ? 0 : 0x80;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
252
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
253 buf[0x5f] = 0x01; // UDL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
254
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
255 buf[0x167] = 0x02; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
256 AV_WB16(buf + 0x16a, ctx->m.mb_height * 4 + 4); // MSIPS
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
257 buf[0x16d] = ctx->m.mb_height; // Ns
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
258 buf[0x16f] = 0x10; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
259
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
260 ctx->msip = buf + 0x170;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
261 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
262 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
263
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
264 static av_always_inline void dnxhd_encode_dc(DNXHDEncContext *ctx, int diff)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
265 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
266 int nbits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
267 if (diff < 0) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
268 nbits = av_log2_16bit(-2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
269 diff--;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
270 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
271 nbits = av_log2_16bit(2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
272 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
273 put_bits(&ctx->m.pb, ctx->cid_table->dc_bits[nbits] + nbits,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
274 (ctx->cid_table->dc_codes[nbits]<<nbits) + (diff & ((1 << nbits) - 1)));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
275 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
276
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
277 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
278 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
279 int last_non_zero = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
280 int slevel, i, j;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
281
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
282 dnxhd_encode_dc(ctx, block[0] - ctx->m.last_dc[n]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
283 ctx->m.last_dc[n] = block[0];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
284
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
285 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
286 j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
287 slevel = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
288 if (slevel) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
289 int run_level = i - last_non_zero - 1;
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
290 int rlevel = (slevel<<1)|!!run_level;
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
291 put_bits(&ctx->m.pb, ctx->vlc_bits[rlevel], ctx->vlc_codes[rlevel]);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
292 if (run_level)
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
293 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
294 last_non_zero = i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
295 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
296 }
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
297 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
298 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
299
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
300 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
301 {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
302 const uint8_t *weight_matrix;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
303 int level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
304 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
305
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
306 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
307
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
308 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
309 int j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
310 level = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
311 if (level) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
312 if (level < 0) {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
313 level = (1-2*level) * qscale * weight_matrix[i];
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
314 if (weight_matrix[i] != 32)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
315 level += 32;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
316 level >>= 6;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
317 level = -level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
318 } else {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
319 level = (2*level+1) * qscale * weight_matrix[i];
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
320 if (weight_matrix[i] != 32)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
321 level += 32;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
322 level >>= 6;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
323 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
324 block[j] = level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
325 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
326 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
327 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
328
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
329 static av_always_inline int dnxhd_ssd_block(DCTELEM *qblock, DCTELEM *block)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
330 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
331 int score = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
332 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
333 for (i = 0; i < 64; i++)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
334 score += (block[i]-qblock[i])*(block[i]-qblock[i]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
335 return score;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
336 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
337
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
338 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
339 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
340 int last_non_zero = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
341 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
342 int i, j, level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
343 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
344 j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
345 level = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
346 if (level) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
347 int run_level = i - last_non_zero - 1;
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
348 bits += ctx->vlc_bits[(level<<1)|!!run_level]+ctx->run_bits[run_level];
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
349 last_non_zero = i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
350 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
351 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
352 return bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
353 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
354
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
355 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
356 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
357 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
358 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
359 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
360 DSPContext *dsp = &ctx->m.dsp;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
361
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
362 dsp->get_pixels(ctx->blocks[0], ptr_y , ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
363 dsp->get_pixels(ctx->blocks[1], ptr_y + 8, ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
364 dsp->get_pixels(ctx->blocks[2], ptr_u , ctx->m.uvlinesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
365 dsp->get_pixels(ctx->blocks[3], ptr_v , ctx->m.uvlinesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
366
5971
405be936dac4 dnxhd 720p encoding and decoding support
bcoudurier
parents: 5970
diff changeset
367 if (mb_y+1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) {
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
368 if (ctx->interlaced) {
8303
bf6a78c6697b dnxhd get_pixels_8x4_sym sse2
bcoudurier
parents: 8302
diff changeset
369 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
370 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
371 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
372 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
373 } else {
d77ee820a5f1 use dsp clear_block
bcoudurier
parents: 8129
diff changeset
374 dsp->clear_block(ctx->blocks[4]); dsp->clear_block(ctx->blocks[5]);
d77ee820a5f1 use dsp clear_block
bcoudurier
parents: 8129
diff changeset
375 dsp->clear_block(ctx->blocks[6]); dsp->clear_block(ctx->blocks[7]);
d77ee820a5f1 use dsp clear_block
bcoudurier
parents: 8129
diff changeset
376 }
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
377 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
378 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
379 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
380 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
381 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
382 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
383 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
384
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
385 static av_always_inline int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
386 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
387 if (i&2) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
388 ctx->m.q_intra_matrix16 = ctx->qmatrix_c16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
389 ctx->m.q_intra_matrix = ctx->qmatrix_c;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
390 return 1 + (i&1);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
391 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
392 ctx->m.q_intra_matrix16 = ctx->qmatrix_l16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
393 ctx->m.q_intra_matrix = ctx->qmatrix_l;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
394 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
395 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
396 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
397
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
398 static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
399 {
8129
a9734fe0811e Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents: 7040
diff changeset
400 DNXHDEncContext *ctx = *(void**)arg;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
401 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
402 int qscale = ctx->thread[0]->qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
403
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
404 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
405 ctx->m.last_dc[0] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
406 ctx->m.last_dc[1] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
407 ctx->m.last_dc[2] = 1024;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
408
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
409 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
410 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
411 int ssd = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
412 int ac_bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
413 int dc_bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
414 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
415
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
416 dnxhd_get_blocks(ctx, mb_x, mb_y);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
417
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
418 for (i = 0; i < 8; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
419 DECLARE_ALIGNED_16(DCTELEM, block[64]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
420 DCTELEM *src_block = ctx->blocks[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
421 int overflow, nbits, diff, last_index;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
422 int n = dnxhd_switch_matrix(ctx, i);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
423
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
424 memcpy(block, src_block, sizeof(block));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
425 last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
426 ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
427
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
428 diff = block[0] - ctx->m.last_dc[n];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
429 if (diff < 0) nbits = av_log2_16bit(-2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
430 else nbits = av_log2_16bit( 2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
431 dc_bits += ctx->cid_table->dc_bits[nbits] + nbits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
432
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
433 ctx->m.last_dc[n] = block[0];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
434
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
435 if (avctx->mb_decision == FF_MB_DECISION_RD || !RC_VARIANCE) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
436 dnxhd_unquantize_c(ctx, block, i, qscale, last_index);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
437 ctx->m.dsp.idct(block);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
438 ssd += dnxhd_ssd_block(block, src_block);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
439 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
440 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
441 ctx->mb_rc[qscale][mb].ssd = ssd;
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
442 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
443 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
444 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
445 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
446 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
447
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
448 static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
449 {
8129
a9734fe0811e Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents: 7040
diff changeset
450 DNXHDEncContext *ctx = *(void**)arg;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
451 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
452
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
453 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
454 ctx->m.last_dc[0] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
455 ctx->m.last_dc[1] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
456 ctx->m.last_dc[2] = 1024;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
457 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
458 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
459 int qscale = ctx->mb_qscale[mb];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
460 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
461
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
462 put_bits(&ctx->m.pb, 12, qscale<<1);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
463
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
464 dnxhd_get_blocks(ctx, mb_x, mb_y);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
465
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
466 for (i = 0; i < 8; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
467 DCTELEM *block = ctx->blocks[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
468 int last_index, overflow;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
469 int n = dnxhd_switch_matrix(ctx, i);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
470 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
471 //START_TIMER;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
472 dnxhd_encode_block(ctx, block, last_index, n);
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
473 //STOP_TIMER("encode_block");
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
474 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
475 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
476 if (put_bits_count(&ctx->m.pb)&31)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
477 put_bits(&ctx->m.pb, 32-(put_bits_count(&ctx->m.pb)&31), 0);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
478 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
479 flush_put_bits(&ctx->m.pb);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
480 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
481 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
482
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
483 static void dnxhd_setup_threads_slices(DNXHDEncContext *ctx, uint8_t *buf)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
484 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
485 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
486 int i, offset = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
487 for (i = 0; i < ctx->m.avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
488 int thread_size = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
489 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
490 ctx->slice_size[mb_y] = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
491 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
492 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
493 ctx->slice_size[mb_y] += ctx->mb_bits[mb];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
494 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
495 ctx->slice_size[mb_y] = (ctx->slice_size[mb_y]+31)&~31;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
496 ctx->slice_size[mb_y] >>= 3;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
497 thread_size += ctx->slice_size[mb_y];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
498 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
499 init_put_bits(&ctx->thread[i]->m.pb, buf + 640 + offset, thread_size);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
500 offset += thread_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
501 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
502 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
503
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
504 static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
505 {
8129
a9734fe0811e Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents: 7040
diff changeset
506 DNXHDEncContext *ctx = *(void**)arg;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
507 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
508 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
509 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
510 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
511 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
512 int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
513 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
514 ctx->mb_cmp[mb].value = varc;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
515 ctx->mb_cmp[mb].mb = mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
516 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
517 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
518 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
519 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
520
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
521 static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
522 {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
523 int lambda, up_step, down_step;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
524 int last_lower = INT_MAX, last_higher = 0;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
525 int x, y, q;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
526
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
527 for (q = 1; q < avctx->qmax; q++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
528 ctx->qscale = q;
8129
a9734fe0811e Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents: 7040
diff changeset
529 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
530 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
531 up_step = down_step = 2<<LAMBDA_FRAC_BITS;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
532 lambda = ctx->lambda;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
533
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
534 for (;;) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
535 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
536 int end = 0;
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
537 if (lambda == last_higher) {
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
538 lambda++;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
539 end = 1; // need to set final qscales/bits
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
540 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
541 for (y = 0; y < ctx->m.mb_height; y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
542 for (x = 0; x < ctx->m.mb_width; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
543 unsigned min = UINT_MAX;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
544 int qscale = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
545 int mb = y*ctx->m.mb_width+x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
546 for (q = 1; q < avctx->qmax; q++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
547 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
548 if (score < min) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
549 min = score;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
550 qscale = q;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
551 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
552 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
553 bits += ctx->mb_rc[qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
554 ctx->mb_qscale[mb] = qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
555 ctx->mb_bits[mb] = ctx->mb_rc[qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
556 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
557 bits = (bits+31)&~31; // padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
558 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
559 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
560 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
561 //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
562 // lambda, last_higher, last_lower, bits, ctx->frame_bits);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
563 if (end) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
564 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
565 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
566 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
567 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
568 if (bits < ctx->frame_bits) {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
569 last_lower = FFMIN(lambda, last_lower);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
570 if (last_higher != 0)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
571 lambda = (lambda+last_higher)>>1;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
572 else
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
573 lambda -= down_step;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
574 down_step *= 5; // XXX tune ?
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
575 up_step = 1<<LAMBDA_FRAC_BITS;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
576 lambda = FFMAX(1, lambda);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
577 if (lambda == last_lower)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
578 break;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
579 } else {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
580 last_higher = FFMAX(lambda, last_higher);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
581 if (last_lower != INT_MAX)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
582 lambda = (lambda+last_lower)>>1;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
583 else
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
584 lambda += up_step;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
585 up_step *= 5;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
586 down_step = 1<<LAMBDA_FRAC_BITS;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
587 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
588 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
589 //dprintf(ctx->m.avctx, "out lambda %d\n", lambda);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
590 ctx->lambda = lambda;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
591 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
592 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
593
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
594 static int dnxhd_find_qscale(DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
595 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
596 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
597 int up_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
598 int down_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
599 int last_higher = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
600 int last_lower = INT_MAX;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
601 int qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
602 int x, y;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
603
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
604 qscale = ctx->qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
605 for (;;) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
606 bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
607 ctx->qscale = qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
608 // XXX avoid recalculating bits
8129
a9734fe0811e Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents: 7040
diff changeset
609 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
610 for (y = 0; y < ctx->m.mb_height; y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
611 for (x = 0; x < ctx->m.mb_width; x++)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
612 bits += ctx->mb_rc[qscale][y*ctx->m.mb_width+x].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
613 bits = (bits+31)&~31; // padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
614 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
615 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
616 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
617 //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
618 // ctx->m.avctx->frame_number, qscale, bits, ctx->frame_bits, last_higher, last_lower);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
619 if (bits < ctx->frame_bits) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
620 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
621 return 1;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
622 if (last_higher == qscale - 1) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
623 qscale = last_higher;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
624 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
625 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
626 last_lower = FFMIN(qscale, last_lower);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
627 if (last_higher != 0)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
628 qscale = (qscale+last_higher)>>1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
629 else
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
630 qscale -= down_step++;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
631 if (qscale < 1)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
632 qscale = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
633 up_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
634 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
635 if (last_lower == qscale + 1)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
636 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
637 last_higher = FFMAX(qscale, last_higher);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
638 if (last_lower != INT_MAX)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
639 qscale = (qscale+last_lower)>>1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
640 else
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
641 qscale += up_step++;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
642 down_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
643 if (qscale >= ctx->m.avctx->qmax)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
644 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
645 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
646 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
647 //dprintf(ctx->m.avctx, "out qscale %d\n", qscale);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
648 ctx->qscale = qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
649 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
650 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
651
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
652 static int dnxhd_rc_cmp(const void *a, const void *b)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
653 {
6218
michael
parents: 6041
diff changeset
654 return ((const RCCMPEntry *)b)->value - ((const RCCMPEntry *)a)->value;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
655 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
656
5970
e1ac22f75cf6 cosmetics, encode_variance -> encode_fast
bcoudurier
parents: 5969
diff changeset
657 static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
658 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
659 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
660 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
661 if ((ret = dnxhd_find_qscale(ctx)) < 0)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
662 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
663 for (y = 0; y < ctx->m.mb_height; y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
664 for (x = 0; x < ctx->m.mb_width; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
665 int mb = y*ctx->m.mb_width+x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
666 int delta_bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
667 ctx->mb_qscale[mb] = ctx->qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
668 ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
669 max_bits += ctx->mb_rc[ctx->qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
670 if (!RC_VARIANCE) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
671 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
672 ctx->mb_cmp[mb].mb = mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
673 ctx->mb_cmp[mb].value = delta_bits ?
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
674 ((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
675 : INT_MIN; //avoid increasing qscale
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
676 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
677 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
678 max_bits += 31; //worst padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
679 }
5969
c5d11f6f6a3d fix corner case when qscale 1 bits < frame bits but max bits with worst padding > frame bits
bcoudurier
parents: 5802
diff changeset
680 if (!ret) {
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
681 if (RC_VARIANCE)
8129
a9734fe0811e Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents: 7040
diff changeset
682 avctx->execute(avctx, dnxhd_mb_var_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count, sizeof(void*));
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
683 qsort(ctx->mb_cmp, ctx->m.mb_num, sizeof(RCEntry), dnxhd_rc_cmp);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
684 for (x = 0; x < ctx->m.mb_num && max_bits > ctx->frame_bits; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
685 int mb = ctx->mb_cmp[x].mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
686 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
687 ctx->mb_qscale[mb] = ctx->qscale+1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
688 ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale+1][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
689 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
690 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
691 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
692 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
693
6218
michael
parents: 6041
diff changeset
694 static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
695 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
696 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
697
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
698 for (i = 0; i < 3; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
699 ctx->frame.data[i] = frame->data[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
700 ctx->frame.linesize[i] = frame->linesize[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
701 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
702
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
703 for (i = 0; i < ctx->m.avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
704 ctx->thread[i]->m.linesize = ctx->frame.linesize[0]<<ctx->interlaced;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
705 ctx->thread[i]->m.uvlinesize = ctx->frame.linesize[1]<<ctx->interlaced;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
706 ctx->thread[i]->dct_y_offset = ctx->m.linesize *8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
707 ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
708 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
709
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
710 ctx->frame.interlaced_frame = frame->interlaced_frame;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
711 ctx->cur_field = frame->interlaced_frame && !frame->top_field_first;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
712 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
713
6218
michael
parents: 6041
diff changeset
714 static int dnxhd_encode_picture(AVCodecContext *avctx, unsigned char *buf, int buf_size, const void *data)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
715 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
716 DNXHDEncContext *ctx = avctx->priv_data;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
717 int first_field = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
718 int offset, i, ret;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
719
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
720 if (buf_size < ctx->cid_table->frame_size) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
721 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
722 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
723 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
724
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
725 dnxhd_load_picture(ctx, data);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
726
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
727 encode_coding_unit:
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
728 for (i = 0; i < 3; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
729 ctx->src[i] = ctx->frame.data[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
730 if (ctx->interlaced && ctx->cur_field)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
731 ctx->src[i] += ctx->frame.linesize[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
732 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
733
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
734 dnxhd_write_header(avctx, buf);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
735
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
736 if (avctx->mb_decision == FF_MB_DECISION_RD)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
737 ret = dnxhd_encode_rdo(avctx, ctx);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
738 else
5970
e1ac22f75cf6 cosmetics, encode_variance -> encode_fast
bcoudurier
parents: 5969
diff changeset
739 ret = dnxhd_encode_fast(avctx, ctx);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
740 if (ret < 0) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
741 av_log(avctx, AV_LOG_ERROR, "picture could not fit ratecontrol constraints\n");
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
742 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
743 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
744
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
745 dnxhd_setup_threads_slices(ctx, buf);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
746
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
747 offset = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
748 for (i = 0; i < ctx->m.mb_height; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
749 AV_WB32(ctx->msip + i * 4, offset);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
750 offset += ctx->slice_size[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
751 assert(!(ctx->slice_size[i] & 3));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
752 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
753
8129
a9734fe0811e Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents: 7040
diff changeset
754 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
755
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
756 AV_WB32(buf + ctx->cid_table->coding_unit_size - 4, 0x600DC0DE); // EOF
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
757
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
758 if (ctx->interlaced && first_field) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
759 first_field = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
760 ctx->cur_field ^= 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
761 buf += ctx->cid_table->coding_unit_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
762 buf_size -= ctx->cid_table->coding_unit_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
763 goto encode_coding_unit;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
764 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
765
6752
b2daf71037be export dnxhd encoded picture quality
bcoudurier
parents: 6710
diff changeset
766 ctx->frame.quality = ctx->qscale*FF_QP2LAMBDA;
b2daf71037be export dnxhd encoded picture quality
bcoudurier
parents: 6710
diff changeset
767
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
768 return ctx->cid_table->frame_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
769 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
770
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
771 static int dnxhd_encode_end(AVCodecContext *avctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
772 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
773 DNXHDEncContext *ctx = avctx->priv_data;
6978
9774d160f014 optimize, merge offset bits in vlc code
bcoudurier
parents: 6903
diff changeset
774 int max_level = 1<<(ctx->cid_table->bit_depth+2);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
775 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
776
6981
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
777 av_free(ctx->vlc_codes-max_level*2);
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
778 av_free(ctx->vlc_bits -max_level*2);
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
779 av_freep(&ctx->run_codes);
e897f60e5048 cosmetics, remove table_ prefix
bcoudurier
parents: 6978
diff changeset
780 av_freep(&ctx->run_bits);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
781
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
782 av_freep(&ctx->mb_bits);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
783 av_freep(&ctx->mb_qscale);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
784 av_freep(&ctx->mb_rc);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
785 av_freep(&ctx->mb_cmp);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
786 av_freep(&ctx->slice_size);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
787
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
788 av_freep(&ctx->qmatrix_c);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
789 av_freep(&ctx->qmatrix_l);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
790 av_freep(&ctx->qmatrix_c16);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
791 av_freep(&ctx->qmatrix_l16);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
792
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
793 for (i = 1; i < avctx->thread_count; i++)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
794 av_freep(&ctx->thread[i]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
795
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
796 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
797 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
798
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
799 AVCodec dnxhd_encoder = {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
800 "dnxhd",
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
801 CODEC_TYPE_VIDEO,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
802 CODEC_ID_DNXHD,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
803 sizeof(DNXHDEncContext),
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
804 dnxhd_encode_init,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
805 dnxhd_encode_picture,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
806 dnxhd_encode_end,
6792
13191e6b439c Replace one more occurrence of -1 with PIX_FMT_NONE.
cehoyos
parents: 6752
diff changeset
807 .pix_fmts = (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
808 .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
809 };