annotate dnxhdenc.c @ 6693:6f13852a9161 libavcodec

Skip blocks in B-frames reuse motion vectors from next reference frame. So if referenced blocks is 16x8, 8x16 or 8x8 partitions, skip block will have them too.
author kostya
date Sat, 26 Apr 2008 13:09:36 +0000
parents dfdff1ca78a7
children a4104482ceef
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"
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
30 #include "dnxhddata.h"
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
31
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
32 typedef struct {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
33 uint16_t mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
34 int value;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
35 } RCCMPEntry;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
36
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
37 typedef struct {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
38 int ssd;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
39 int bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
40 } RCEntry;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
41
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
42 int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
43
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
44 typedef struct DNXHDEncContext {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
45 MpegEncContext m; ///< Used for quantization dsp functions
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
46
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
47 AVFrame frame;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
48 int cid;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
49 const CIDEntry *cid_table;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
50 uint8_t *msip; ///< Macroblock Scan Indices Payload
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
51 uint32_t *slice_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
52
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
53 struct DNXHDEncContext *thread[MAX_THREADS];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
54
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
55 unsigned dct_y_offset;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
56 unsigned dct_uv_offset;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
57 int interlaced;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
58 int cur_field;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
59
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
60 DECLARE_ALIGNED_16(DCTELEM, blocks[8][64]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
61
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
62 int (*qmatrix_c) [64];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
63 int (*qmatrix_l) [64];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
64 uint16_t (*qmatrix_l16)[2][64];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
65 uint16_t (*qmatrix_c16)[2][64];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
66
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
67 unsigned frame_bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
68 uint8_t *src[3];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
69
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
70 uint16_t *table_vlc_codes;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
71 uint8_t *table_vlc_bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
72 uint16_t *table_run_codes;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
73 uint8_t *table_run_bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
74
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
75 /** Rate control */
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
76 unsigned slice_bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
77 unsigned qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
78 unsigned lambda;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
79
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
80 unsigned thread_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
81
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
82 uint16_t *mb_bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
83 uint8_t *mb_qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
84
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
85 RCCMPEntry *mb_cmp;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
86 RCEntry (*mb_rc)[8160];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
87 } DNXHDEncContext;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
88
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
89 #define LAMBDA_FRAC_BITS 10
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
90
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
91 static int dnxhd_init_vlc(DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
92 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
93 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
94
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
95 CHECKED_ALLOCZ(ctx->table_vlc_codes, 449*2);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
96 CHECKED_ALLOCZ(ctx->table_vlc_bits, 449);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
97 CHECKED_ALLOCZ(ctx->table_run_codes, 63*2);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
98 CHECKED_ALLOCZ(ctx->table_run_bits, 63);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
99
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
100 for (i = 0; i < 257; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
101 int level = ctx->cid_table->ac_level[i] +
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
102 (ctx->cid_table->ac_run_flag[i] << 7) + (ctx->cid_table->ac_index_flag[i] << 8);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
103 assert(level < 449);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
104 if (ctx->cid_table->ac_level[i] == 64 && ctx->cid_table->ac_index_flag[i])
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
105 level -= 64; // use 0+(1<<8) level
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
106 ctx->table_vlc_codes[level] = ctx->cid_table->ac_codes[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
107 ctx->table_vlc_bits [level] = ctx->cid_table->ac_bits[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
108 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
109 for (i = 0; i < 62; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
110 int run = ctx->cid_table->run[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
111 assert(run < 63);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
112 ctx->table_run_codes[run] = ctx->cid_table->run_codes[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
113 ctx->table_run_bits [run] = ctx->cid_table->run_bits[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
114 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
115 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
116 fail:
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
117 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
118 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
119
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
120 static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
121 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
122 // init first elem to 1 to avoid div by 0 in convert_matrix
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
123 uint16_t weight_matrix[64] = {1,}; // convert_matrix needs uint16_t*
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
124 int qscale, i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
125
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
126 CHECKED_ALLOCZ(ctx->qmatrix_l, (ctx->m.avctx->qmax+1) * 64 * sizeof(int));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
127 CHECKED_ALLOCZ(ctx->qmatrix_c, (ctx->m.avctx->qmax+1) * 64 * sizeof(int));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
128 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
129 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
130
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
131 for (i = 1; i < 64; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
132 int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]];
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
133 weight_matrix[j] = ctx->cid_table->luma_weight[i];
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
134 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
135 ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_l, ctx->qmatrix_l16, weight_matrix,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
136 ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
137 for (i = 1; i < 64; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
138 int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]];
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
139 weight_matrix[j] = ctx->cid_table->chroma_weight[i];
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
140 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
141 ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_c, ctx->qmatrix_c16, weight_matrix,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
142 ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
143 for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
144 for (i = 0; i < 64; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
145 ctx->qmatrix_l [qscale] [i] <<= 2; ctx->qmatrix_c [qscale] [i] <<= 2;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
146 ctx->qmatrix_l16[qscale][0][i] <<= 2; ctx->qmatrix_l16[qscale][1][i] <<= 2;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
147 ctx->qmatrix_c16[qscale][0][i] <<= 2; ctx->qmatrix_c16[qscale][1][i] <<= 2;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
148 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
149 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
150 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
151 fail:
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
152 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
153 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
154
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
155 static int dnxhd_init_rc(DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
156 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
157 CHECKED_ALLOCZ(ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
158 if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
159 CHECKED_ALLOCZ(ctx->mb_cmp, ctx->m.mb_num*sizeof(RCCMPEntry));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
160
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
161 ctx->frame_bits = (ctx->cid_table->coding_unit_size - 640 - 4) * 8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
162 ctx->qscale = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
163 ctx->lambda = 2<<LAMBDA_FRAC_BITS; // qscale 2
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
164 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
165 fail:
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
166 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
167 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
168
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
169 static int dnxhd_encode_init(AVCodecContext *avctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
170 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
171 DNXHDEncContext *ctx = avctx->priv_data;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
172 int i, index;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
173
6041
bb4b486c6775 add bitrate helper to choose all dnxhd variants
bcoudurier
parents: 5972
diff changeset
174 ctx->cid = ff_dnxhd_find_cid(avctx);
5971
405be936dac4 dnxhd 720p encoding and decoding support
bcoudurier
parents: 5970
diff changeset
175 if (!ctx->cid || avctx->pix_fmt != PIX_FMT_YUV422P) {
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
176 av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD\n");
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
177 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
178 }
6041
bb4b486c6775 add bitrate helper to choose all dnxhd variants
bcoudurier
parents: 5972
diff changeset
179 av_log(avctx, AV_LOG_DEBUG, "cid %d\n", ctx->cid);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
180
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
181 index = ff_dnxhd_get_cid_table(ctx->cid);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
182 ctx->cid_table = &ff_dnxhd_cid_table[index];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
183
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
184 ctx->m.avctx = avctx;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
185 ctx->m.mb_intra = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
186 ctx->m.h263_aic = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
187
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
188 dsputil_init(&ctx->m.dsp, avctx);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
189 ff_dct_common_init(&ctx->m);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
190 if (!ctx->m.dct_quantize)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
191 ctx->m.dct_quantize = dct_quantize_c;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
192
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
193 ctx->m.mb_height = (avctx->height + 15) / 16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
194 ctx->m.mb_width = (avctx->width + 15) / 16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
195
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
196 if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
197 ctx->interlaced = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
198 ctx->m.mb_height /= 2;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
199 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
200
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
201 ctx->m.mb_num = ctx->m.mb_height * ctx->m.mb_width;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
202
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
203 if (avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
204 ctx->m.intra_quant_bias = avctx->intra_quant_bias;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
205 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
206 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
207
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
208 if (dnxhd_init_vlc(ctx) < 0)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
209 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
210 if (dnxhd_init_rc(ctx) < 0)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
211 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
212
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
213 CHECKED_ALLOCZ(ctx->slice_size, ctx->m.mb_height*sizeof(uint32_t));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
214 CHECKED_ALLOCZ(ctx->mb_bits, ctx->m.mb_num *sizeof(uint16_t));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
215 CHECKED_ALLOCZ(ctx->mb_qscale, ctx->m.mb_num *sizeof(uint8_t));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
216
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
217 ctx->frame.key_frame = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
218 ctx->frame.pict_type = FF_I_TYPE;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
219 ctx->m.avctx->coded_frame = &ctx->frame;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
220
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
221 if (avctx->thread_count > MAX_THREADS || (avctx->thread_count > ctx->m.mb_height)) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
222 av_log(avctx, AV_LOG_ERROR, "too many threads\n");
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
223 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
224 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
225
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
226 ctx->thread[0] = ctx;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
227 for (i = 1; i < avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
228 ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
229 memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
230 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
231
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
232 for (i = 0; i < avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
233 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
234 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
235 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
236
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
237 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
238 fail: //for CHECKED_ALLOCZ
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
239 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
240 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
241
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
242 static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
243 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
244 DNXHDEncContext *ctx = avctx->priv_data;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
245 const uint8_t header_prefix[5] = { 0x00,0x00,0x02,0x80,0x01 };
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
246
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
247 memcpy(buf, header_prefix, 5);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
248 buf[5] = ctx->interlaced ? ctx->cur_field+2 : 0x01;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
249 buf[6] = 0x80; // crc flag off
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
250 buf[7] = 0xa0; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
251 AV_WB16(buf + 0x18, avctx->height); // ALPF
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
252 AV_WB16(buf + 0x1a, avctx->width); // SPL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
253 AV_WB16(buf + 0x1d, avctx->height); // NAL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
254
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
255 buf[0x21] = 0x38; // FIXME 8 bit per comp
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
256 buf[0x22] = 0x88 + (ctx->frame.interlaced_frame<<2);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
257 AV_WB32(buf + 0x28, ctx->cid); // CID
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
258 buf[0x2c] = ctx->interlaced ? 0 : 0x80;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
259
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
260 buf[0x5f] = 0x01; // UDL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
261
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
262 buf[0x167] = 0x02; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
263 AV_WB16(buf + 0x16a, ctx->m.mb_height * 4 + 4); // MSIPS
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
264 buf[0x16d] = ctx->m.mb_height; // Ns
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
265 buf[0x16f] = 0x10; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
266
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
267 ctx->msip = buf + 0x170;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
268 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
269 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
270
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
271 static av_always_inline void dnxhd_encode_dc(DNXHDEncContext *ctx, int diff)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
272 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
273 int nbits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
274 if (diff < 0) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
275 nbits = av_log2_16bit(-2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
276 diff--;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
277 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
278 nbits = av_log2_16bit(2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
279 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
280 put_bits(&ctx->m.pb, ctx->cid_table->dc_bits[nbits] + nbits,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
281 (ctx->cid_table->dc_codes[nbits]<<nbits) + (diff & ((1 << nbits) - 1)));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
282 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
283
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
284 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
285 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
286 int last_non_zero = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
287 int offset = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
288 int slevel, i, j;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
289
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
290 dnxhd_encode_dc(ctx, block[0] - ctx->m.last_dc[n]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
291 ctx->m.last_dc[n] = block[0];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
292
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
293 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
294 j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
295 slevel = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
296 if (slevel) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
297 int run_level = i - last_non_zero - 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
298 int sign;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
299 MASK_ABS(sign, slevel);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
300 if (slevel > 64) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
301 offset = (slevel-1) >> 6;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
302 slevel = 256 | (slevel & 63); // level 64 is treated as 0
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
303 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
304 if (run_level)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
305 slevel |= 128;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
306 put_bits(&ctx->m.pb, ctx->table_vlc_bits[slevel]+1, (ctx->table_vlc_codes[slevel]<<1)|(sign&1));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
307 if (offset) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
308 put_bits(&ctx->m.pb, 4, offset);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
309 offset = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
310 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
311 if (run_level)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
312 put_bits(&ctx->m.pb, ctx->table_run_bits[run_level], ctx->table_run_codes[run_level]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
313 last_non_zero = i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
314 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
315 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
316 put_bits(&ctx->m.pb, ctx->table_vlc_bits[0], ctx->table_vlc_codes[0]); // EOB
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
317 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
318
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
319 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
320 {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
321 const uint8_t *weight_matrix;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
322 int level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
323 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
324
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
325 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
326
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
327 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
328 int j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
329 level = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
330 if (level) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
331 if (level < 0) {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
332 level = (1-2*level) * qscale * weight_matrix[i];
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
333 if (weight_matrix[i] != 32)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
334 level += 32;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
335 level >>= 6;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
336 level = -level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
337 } else {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
338 level = (2*level+1) * qscale * weight_matrix[i];
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
339 if (weight_matrix[i] != 32)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
340 level += 32;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
341 level >>= 6;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
342 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
343 block[j] = level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
344 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
345 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
346 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
347
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
348 static av_always_inline int dnxhd_ssd_block(DCTELEM *qblock, DCTELEM *block)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
349 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
350 int score = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
351 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
352 for (i = 0; i < 64; i++)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
353 score += (block[i]-qblock[i])*(block[i]-qblock[i]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
354 return score;
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 int dnxhd_calc_ac_bits(DNXHDEncContext *ctx, DCTELEM *block, int last_index)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
358 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
359 int last_non_zero = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
360 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
361 int i, j, level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
362 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
363 j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
364 level = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
365 if (level) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
366 int run_level = i - last_non_zero - 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
367 level = FFABS(level);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
368 if (level > 64) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
369 level = 256 | (level & 63); // level 64 is treated as 0
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
370 bits += 4;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
371 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
372 level |= (!!run_level)<<7;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
373 bits += ctx->table_vlc_bits[level]+1 + ctx->table_run_bits[run_level];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
374 last_non_zero = i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
375 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
376 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
377 return bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
378 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
379
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
380 static av_always_inline void dnxhd_get_pixels_4x8(DCTELEM *restrict block, const uint8_t *pixels, int line_size)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
381 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
382 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
383 for (i = 0; i < 4; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
384 block[0] = pixels[0];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
385 block[1] = pixels[1];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
386 block[2] = pixels[2];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
387 block[3] = pixels[3];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
388 block[4] = pixels[4];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
389 block[5] = pixels[5];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
390 block[6] = pixels[6];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
391 block[7] = pixels[7];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
392 pixels += line_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
393 block += 8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
394 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
395 memcpy(block , block- 8, sizeof(*block)*8);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
396 memcpy(block+ 8, block-16, sizeof(*block)*8);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
397 memcpy(block+16, block-24, sizeof(*block)*8);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
398 memcpy(block+24, block-32, sizeof(*block)*8);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
399 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
400
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
401 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
402 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
403 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
404 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
405 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
406 DSPContext *dsp = &ctx->m.dsp;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
407
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
408 dsp->get_pixels(ctx->blocks[0], ptr_y , ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
409 dsp->get_pixels(ctx->blocks[1], ptr_y + 8, ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
410 dsp->get_pixels(ctx->blocks[2], ptr_u , ctx->m.uvlinesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
411 dsp->get_pixels(ctx->blocks[3], ptr_v , ctx->m.uvlinesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
412
5971
405be936dac4 dnxhd 720p encoding and decoding support
bcoudurier
parents: 5970
diff changeset
413 if (mb_y+1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) {
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
414 if (ctx->interlaced) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
415 dnxhd_get_pixels_4x8(ctx->blocks[4], ptr_y + ctx->dct_y_offset , ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
416 dnxhd_get_pixels_4x8(ctx->blocks[5], ptr_y + ctx->dct_y_offset + 8, ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
417 dnxhd_get_pixels_4x8(ctx->blocks[6], ptr_u + ctx->dct_uv_offset , ctx->m.uvlinesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
418 dnxhd_get_pixels_4x8(ctx->blocks[7], ptr_v + ctx->dct_uv_offset , ctx->m.uvlinesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
419 } else
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
420 memset(ctx->blocks[4], 0, 4*64*sizeof(DCTELEM));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
421 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
422 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
423 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
424 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
425 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
426 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
427 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
428
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
429 static av_always_inline int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
430 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
431 if (i&2) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
432 ctx->m.q_intra_matrix16 = ctx->qmatrix_c16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
433 ctx->m.q_intra_matrix = ctx->qmatrix_c;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
434 return 1 + (i&1);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
435 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
436 ctx->m.q_intra_matrix16 = ctx->qmatrix_l16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
437 ctx->m.q_intra_matrix = ctx->qmatrix_l;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
438 return 0;
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
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
442 static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
443 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
444 DNXHDEncContext *ctx = arg;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
445 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
446 int qscale = ctx->thread[0]->qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
447
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
448 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
449 ctx->m.last_dc[0] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
450 ctx->m.last_dc[1] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
451 ctx->m.last_dc[2] = 1024;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
452
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
453 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
454 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
455 int ssd = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
456 int ac_bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
457 int dc_bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
458 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
459
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
460 dnxhd_get_blocks(ctx, mb_x, mb_y);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
461
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
462 for (i = 0; i < 8; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
463 DECLARE_ALIGNED_16(DCTELEM, block[64]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
464 DCTELEM *src_block = ctx->blocks[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
465 int overflow, nbits, diff, last_index;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
466 int n = dnxhd_switch_matrix(ctx, i);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
467
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
468 memcpy(block, src_block, sizeof(block));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
469 last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
470 ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
471
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
472 diff = block[0] - ctx->m.last_dc[n];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
473 if (diff < 0) nbits = av_log2_16bit(-2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
474 else nbits = av_log2_16bit( 2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
475 dc_bits += ctx->cid_table->dc_bits[nbits] + nbits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
476
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
477 ctx->m.last_dc[n] = block[0];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
478
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
479 if (avctx->mb_decision == FF_MB_DECISION_RD || !RC_VARIANCE) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
480 dnxhd_unquantize_c(ctx, block, i, qscale, last_index);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
481 ctx->m.dsp.idct(block);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
482 ssd += dnxhd_ssd_block(block, src_block);
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 ctx->mb_rc[qscale][mb].ssd = ssd;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
486 ctx->mb_rc[qscale][mb].bits = ac_bits+dc_bits+12+8*ctx->table_vlc_bits[0];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
487 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
488 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
489 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
490 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
491
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
492 static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
493 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
494 DNXHDEncContext *ctx = arg;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
495 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
496
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
497 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
498 ctx->m.last_dc[0] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
499 ctx->m.last_dc[1] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
500 ctx->m.last_dc[2] = 1024;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
501 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
502 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
503 int qscale = ctx->mb_qscale[mb];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
504 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
505
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
506 put_bits(&ctx->m.pb, 12, qscale<<1);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
507
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
508 dnxhd_get_blocks(ctx, mb_x, mb_y);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
509
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
510 for (i = 0; i < 8; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
511 DCTELEM *block = ctx->blocks[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
512 int last_index, overflow;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
513 int n = dnxhd_switch_matrix(ctx, i);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
514 last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
515 dnxhd_encode_block(ctx, block, last_index, n);
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 if (put_bits_count(&ctx->m.pb)&31)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
519 put_bits(&ctx->m.pb, 32-(put_bits_count(&ctx->m.pb)&31), 0);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
520 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
521 flush_put_bits(&ctx->m.pb);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
522 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
523 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
524
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
525 static void dnxhd_setup_threads_slices(DNXHDEncContext *ctx, uint8_t *buf)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
526 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
527 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
528 int i, offset = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
529 for (i = 0; i < ctx->m.avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
530 int thread_size = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
531 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
532 ctx->slice_size[mb_y] = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
533 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
534 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
535 ctx->slice_size[mb_y] += ctx->mb_bits[mb];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
536 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
537 ctx->slice_size[mb_y] = (ctx->slice_size[mb_y]+31)&~31;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
538 ctx->slice_size[mb_y] >>= 3;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
539 thread_size += ctx->slice_size[mb_y];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
540 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
541 init_put_bits(&ctx->thread[i]->m.pb, buf + 640 + offset, thread_size);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
542 offset += thread_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
543 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
544 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
545
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
546 static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
547 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
548 DNXHDEncContext *ctx = arg;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
549 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
550 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
551 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
552 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
553 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
554 int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
555 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
556 ctx->mb_cmp[mb].value = varc;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
557 ctx->mb_cmp[mb].mb = mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
558 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
559 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
560 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
561 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
562
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
563 static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
564 {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
565 int lambda, up_step, down_step;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
566 int last_lower = INT_MAX, last_higher = 0;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
567 int x, y, q;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
568
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
569 for (q = 1; q < avctx->qmax; q++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
570 ctx->qscale = q;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
571 avctx->execute(avctx, dnxhd_calc_bits_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
572 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
573 up_step = down_step = 2<<LAMBDA_FRAC_BITS;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
574 lambda = ctx->lambda;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
575
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
576 for (;;) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
577 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
578 int end = 0;
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
579 if (lambda == last_higher) {
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
580 lambda++;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
581 end = 1; // need to set final qscales/bits
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
582 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
583 for (y = 0; y < ctx->m.mb_height; y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
584 for (x = 0; x < ctx->m.mb_width; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
585 unsigned min = UINT_MAX;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
586 int qscale = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
587 int mb = y*ctx->m.mb_width+x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
588 for (q = 1; q < avctx->qmax; q++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
589 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
590 if (score < min) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
591 min = score;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
592 qscale = q;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
593 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
594 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
595 bits += ctx->mb_rc[qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
596 ctx->mb_qscale[mb] = qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
597 ctx->mb_bits[mb] = ctx->mb_rc[qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
598 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
599 bits = (bits+31)&~31; // padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
600 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
601 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
602 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
603 //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
604 // lambda, last_higher, last_lower, bits, ctx->frame_bits);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
605 if (end) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
606 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
607 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
608 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
609 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
610 if (bits < ctx->frame_bits) {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
611 last_lower = FFMIN(lambda, last_lower);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
612 if (last_higher != 0)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
613 lambda = (lambda+last_higher)>>1;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
614 else
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
615 lambda -= down_step;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
616 down_step *= 5; // XXX tune ?
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
617 up_step = 1<<LAMBDA_FRAC_BITS;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
618 lambda = FFMAX(1, lambda);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
619 if (lambda == last_lower)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
620 break;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
621 } else {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
622 last_higher = FFMAX(lambda, last_higher);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
623 if (last_lower != INT_MAX)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
624 lambda = (lambda+last_lower)>>1;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
625 else
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
626 lambda += up_step;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
627 up_step *= 5;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
628 down_step = 1<<LAMBDA_FRAC_BITS;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
629 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
630 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
631 //dprintf(ctx->m.avctx, "out lambda %d\n", lambda);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
632 ctx->lambda = lambda;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
633 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
634 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
635
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
636 static int dnxhd_find_qscale(DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
637 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
638 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
639 int up_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
640 int down_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
641 int last_higher = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
642 int last_lower = INT_MAX;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
643 int qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
644 int x, y;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
645
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
646 qscale = ctx->qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
647 for (;;) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
648 bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
649 ctx->qscale = qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
650 // XXX avoid recalculating bits
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
651 ctx->m.avctx->execute(ctx->m.avctx, dnxhd_calc_bits_thread, (void**)&ctx->thread[0], NULL, ctx->m.avctx->thread_count);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
652 for (y = 0; y < ctx->m.mb_height; y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
653 for (x = 0; x < ctx->m.mb_width; x++)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
654 bits += ctx->mb_rc[qscale][y*ctx->m.mb_width+x].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
655 bits = (bits+31)&~31; // padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
656 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
657 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
658 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
659 //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
660 // ctx->m.avctx->frame_number, qscale, bits, ctx->frame_bits, last_higher, last_lower);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
661 if (bits < ctx->frame_bits) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
662 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
663 return 1;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
664 if (last_higher == qscale - 1) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
665 qscale = last_higher;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
666 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
667 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
668 last_lower = FFMIN(qscale, last_lower);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
669 if (last_higher != 0)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
670 qscale = (qscale+last_higher)>>1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
671 else
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
672 qscale -= down_step++;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
673 if (qscale < 1)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
674 qscale = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
675 up_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
676 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
677 if (last_lower == qscale + 1)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
678 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
679 last_higher = FFMAX(qscale, last_higher);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
680 if (last_lower != INT_MAX)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
681 qscale = (qscale+last_lower)>>1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
682 else
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
683 qscale += up_step++;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
684 down_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
685 if (qscale >= ctx->m.avctx->qmax)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
686 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
687 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
688 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
689 //dprintf(ctx->m.avctx, "out qscale %d\n", qscale);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
690 ctx->qscale = qscale;
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
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
694 static int dnxhd_rc_cmp(const void *a, const void *b)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
695 {
6218
michael
parents: 6041
diff changeset
696 return ((const RCCMPEntry *)b)->value - ((const RCCMPEntry *)a)->value;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
697 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
698
5970
e1ac22f75cf6 cosmetics, encode_variance -> encode_fast
bcoudurier
parents: 5969
diff changeset
699 static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
700 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
701 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
702 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
703 if ((ret = dnxhd_find_qscale(ctx)) < 0)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
704 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
705 for (y = 0; y < ctx->m.mb_height; y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
706 for (x = 0; x < ctx->m.mb_width; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
707 int mb = y*ctx->m.mb_width+x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
708 int delta_bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
709 ctx->mb_qscale[mb] = ctx->qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
710 ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
711 max_bits += ctx->mb_rc[ctx->qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
712 if (!RC_VARIANCE) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
713 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
714 ctx->mb_cmp[mb].mb = mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
715 ctx->mb_cmp[mb].value = delta_bits ?
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
716 ((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
717 : INT_MIN; //avoid increasing qscale
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
718 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
719 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
720 max_bits += 31; //worst padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
721 }
5969
c5d11f6f6a3d fix corner case when qscale 1 bits < frame bits but max bits with worst padding > frame bits
bcoudurier
parents: 5802
diff changeset
722 if (!ret) {
5790
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 avctx->execute(avctx, dnxhd_mb_var_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
725 qsort(ctx->mb_cmp, ctx->m.mb_num, sizeof(RCEntry), dnxhd_rc_cmp);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
726 for (x = 0; x < ctx->m.mb_num && max_bits > ctx->frame_bits; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
727 int mb = ctx->mb_cmp[x].mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
728 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
729 ctx->mb_qscale[mb] = ctx->qscale+1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
730 ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale+1][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
731 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
732 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
733 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
734 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
735
6218
michael
parents: 6041
diff changeset
736 static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
737 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
738 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
739
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
740 for (i = 0; i < 3; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
741 ctx->frame.data[i] = frame->data[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
742 ctx->frame.linesize[i] = frame->linesize[i];
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 for (i = 0; i < ctx->m.avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
746 ctx->thread[i]->m.linesize = ctx->frame.linesize[0]<<ctx->interlaced;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
747 ctx->thread[i]->m.uvlinesize = ctx->frame.linesize[1]<<ctx->interlaced;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
748 ctx->thread[i]->dct_y_offset = ctx->m.linesize *8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
749 ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
750 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
751
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
752 ctx->frame.interlaced_frame = frame->interlaced_frame;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
753 ctx->cur_field = frame->interlaced_frame && !frame->top_field_first;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
754 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
755
6218
michael
parents: 6041
diff changeset
756 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
757 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
758 DNXHDEncContext *ctx = avctx->priv_data;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
759 int first_field = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
760 int offset, i, ret;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
761
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
762 if (buf_size < ctx->cid_table->frame_size) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
763 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
764 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
765 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
766
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
767 dnxhd_load_picture(ctx, data);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
768
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
769 encode_coding_unit:
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
770 for (i = 0; i < 3; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
771 ctx->src[i] = ctx->frame.data[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
772 if (ctx->interlaced && ctx->cur_field)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
773 ctx->src[i] += ctx->frame.linesize[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
774 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
775
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
776 dnxhd_write_header(avctx, buf);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
777
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
778 if (avctx->mb_decision == FF_MB_DECISION_RD)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
779 ret = dnxhd_encode_rdo(avctx, ctx);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
780 else
5970
e1ac22f75cf6 cosmetics, encode_variance -> encode_fast
bcoudurier
parents: 5969
diff changeset
781 ret = dnxhd_encode_fast(avctx, ctx);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
782 if (ret < 0) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
783 av_log(avctx, AV_LOG_ERROR, "picture could not fit ratecontrol constraints\n");
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
784 return -1;
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_setup_threads_slices(ctx, buf);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
788
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
789 offset = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
790 for (i = 0; i < ctx->m.mb_height; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
791 AV_WB32(ctx->msip + i * 4, offset);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
792 offset += ctx->slice_size[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
793 assert(!(ctx->slice_size[i] & 3));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
794 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
795
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
796 avctx->execute(avctx, dnxhd_encode_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
797
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
798 AV_WB32(buf + ctx->cid_table->coding_unit_size - 4, 0x600DC0DE); // EOF
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
799
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
800 if (ctx->interlaced && first_field) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
801 first_field = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
802 ctx->cur_field ^= 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
803 buf += ctx->cid_table->coding_unit_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
804 buf_size -= ctx->cid_table->coding_unit_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
805 goto encode_coding_unit;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
806 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
807
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
808 return ctx->cid_table->frame_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
809 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
810
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
811 static int dnxhd_encode_end(AVCodecContext *avctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
812 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
813 DNXHDEncContext *ctx = avctx->priv_data;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
814 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
815
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
816 av_freep(&ctx->table_vlc_codes);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
817 av_freep(&ctx->table_vlc_bits);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
818 av_freep(&ctx->table_run_codes);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
819 av_freep(&ctx->table_run_bits);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
820
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
821 av_freep(&ctx->mb_bits);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
822 av_freep(&ctx->mb_qscale);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
823 av_freep(&ctx->mb_rc);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
824 av_freep(&ctx->mb_cmp);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
825 av_freep(&ctx->slice_size);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
826
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
827 av_freep(&ctx->qmatrix_c);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
828 av_freep(&ctx->qmatrix_l);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
829 av_freep(&ctx->qmatrix_c16);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
830 av_freep(&ctx->qmatrix_l16);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
831
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
832 for (i = 1; i < avctx->thread_count; i++)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
833 av_freep(&ctx->thread[i]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
834
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
835 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
836 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
837
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
838 AVCodec dnxhd_encoder = {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
839 "dnxhd",
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
840 CODEC_TYPE_VIDEO,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
841 CODEC_ID_DNXHD,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
842 sizeof(DNXHDEncContext),
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
843 dnxhd_encode_init,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
844 dnxhd_encode_picture,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
845 dnxhd_encode_end,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
846 .pix_fmts = (enum PixelFormat[]){PIX_FMT_YUV422P, -1},
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
847 };