annotate dnxhdenc.c @ 5876:731ee5ad6bde libavcodec

Correct assignment of interlaced_frame; was being set on output frames, in display order, based on decoding information in decoding order. Now set properly, immediately upon completion of decode. Based on original patch from Reinhard Nissl, rnisssl % gmx , de Original Thread: [FFmpeg-devel] H.264 + PAFF: BBC HD recording shows extreme interlacing artefacts, Thu, 01 Nov 2007 22:43:09
author heydowns
date Mon, 05 Nov 2007 18:16:42 +0000
parents d112d5c13ae8
children c5d11f6f6a3d
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
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
174 if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
175 if (avctx->bit_rate == 120000000)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
176 ctx->cid = 1242;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
177 else if (avctx->bit_rate == 185000000)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
178 ctx->cid = 1243;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
179 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
180 if (avctx->bit_rate == 120000000)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
181 ctx->cid = 1237;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
182 else if (avctx->bit_rate == 185000000)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
183 ctx->cid = 1238;
5796
5691b843e72a dnxhd 36mbit support
bcoudurier
parents: 5795
diff changeset
184 else if (avctx->bit_rate == 36000000)
5691b843e72a dnxhd 36mbit support
bcoudurier
parents: 5795
diff changeset
185 ctx->cid = 1253;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
186 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
187 if (!ctx->cid || avctx->width != 1920 || avctx->height != 1080 || avctx->pix_fmt != PIX_FMT_YUV422P) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
188 av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD\n");
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
189 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
190 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
191
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
192 index = ff_dnxhd_get_cid_table(ctx->cid);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
193 ctx->cid_table = &ff_dnxhd_cid_table[index];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
194
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
195 ctx->m.avctx = avctx;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
196 ctx->m.mb_intra = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
197 ctx->m.h263_aic = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
198
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
199 dsputil_init(&ctx->m.dsp, avctx);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
200 ff_dct_common_init(&ctx->m);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
201 if (!ctx->m.dct_quantize)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
202 ctx->m.dct_quantize = dct_quantize_c;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
203
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
204 ctx->m.mb_height = (avctx->height + 15) / 16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
205 ctx->m.mb_width = (avctx->width + 15) / 16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
206
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
207 if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
208 ctx->interlaced = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
209 ctx->m.mb_height /= 2;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
210 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
211
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
212 ctx->m.mb_num = ctx->m.mb_height * ctx->m.mb_width;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
213
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
214 if (avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
215 ctx->m.intra_quant_bias = avctx->intra_quant_bias;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
216 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
217 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
218
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
219 if (dnxhd_init_vlc(ctx) < 0)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
220 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
221 if (dnxhd_init_rc(ctx) < 0)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
222 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
223
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
224 CHECKED_ALLOCZ(ctx->slice_size, ctx->m.mb_height*sizeof(uint32_t));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
225 CHECKED_ALLOCZ(ctx->mb_bits, ctx->m.mb_num *sizeof(uint16_t));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
226 CHECKED_ALLOCZ(ctx->mb_qscale, ctx->m.mb_num *sizeof(uint8_t));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
227
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
228 ctx->frame.key_frame = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
229 ctx->frame.pict_type = FF_I_TYPE;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
230 ctx->m.avctx->coded_frame = &ctx->frame;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
231
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
232 if (avctx->thread_count > MAX_THREADS || (avctx->thread_count > ctx->m.mb_height)) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
233 av_log(avctx, AV_LOG_ERROR, "too many threads\n");
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
234 return -1;
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 ctx->thread[0] = ctx;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
238 for (i = 1; i < avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
239 ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
240 memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
241 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
242
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
243 for (i = 0; i < avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
244 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
245 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
246 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
247
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
248 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
249 fail: //for CHECKED_ALLOCZ
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
250 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
251 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
252
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
253 static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
254 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
255 DNXHDEncContext *ctx = avctx->priv_data;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
256 const uint8_t header_prefix[5] = { 0x00,0x00,0x02,0x80,0x01 };
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
257
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
258 memcpy(buf, header_prefix, 5);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
259 buf[5] = ctx->interlaced ? ctx->cur_field+2 : 0x01;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
260 buf[6] = 0x80; // crc flag off
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
261 buf[7] = 0xa0; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
262 AV_WB16(buf + 0x18, avctx->height); // ALPF
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
263 AV_WB16(buf + 0x1a, avctx->width); // SPL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
264 AV_WB16(buf + 0x1d, avctx->height); // NAL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
265
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
266 buf[0x21] = 0x38; // FIXME 8 bit per comp
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
267 buf[0x22] = 0x88 + (ctx->frame.interlaced_frame<<2);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
268 AV_WB32(buf + 0x28, ctx->cid); // CID
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
269 buf[0x2c] = ctx->interlaced ? 0 : 0x80;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
270
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
271 buf[0x5f] = 0x01; // UDL
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
272
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
273 buf[0x167] = 0x02; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
274 AV_WB16(buf + 0x16a, ctx->m.mb_height * 4 + 4); // MSIPS
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
275 buf[0x16d] = ctx->m.mb_height; // Ns
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
276 buf[0x16f] = 0x10; // reserved
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
277
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
278 ctx->msip = buf + 0x170;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
279 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
280 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
281
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
282 static av_always_inline void dnxhd_encode_dc(DNXHDEncContext *ctx, int diff)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
283 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
284 int nbits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
285 if (diff < 0) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
286 nbits = av_log2_16bit(-2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
287 diff--;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
288 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
289 nbits = av_log2_16bit(2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
290 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
291 put_bits(&ctx->m.pb, ctx->cid_table->dc_bits[nbits] + nbits,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
292 (ctx->cid_table->dc_codes[nbits]<<nbits) + (diff & ((1 << nbits) - 1)));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
293 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
294
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
295 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
296 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
297 int last_non_zero = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
298 int offset = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
299 int slevel, i, j;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
300
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
301 dnxhd_encode_dc(ctx, block[0] - ctx->m.last_dc[n]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
302 ctx->m.last_dc[n] = block[0];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
303
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
304 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
305 j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
306 slevel = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
307 if (slevel) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
308 int run_level = i - last_non_zero - 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
309 int sign;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
310 MASK_ABS(sign, slevel);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
311 if (slevel > 64) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
312 offset = (slevel-1) >> 6;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
313 slevel = 256 | (slevel & 63); // level 64 is treated as 0
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
314 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
315 if (run_level)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
316 slevel |= 128;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
317 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
318 if (offset) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
319 put_bits(&ctx->m.pb, 4, offset);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
320 offset = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
321 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
322 if (run_level)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
323 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
324 last_non_zero = i;
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 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
328 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
329
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
330 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
331 {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
332 const uint8_t *weight_matrix;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
333 int level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
334 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
335
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
336 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
337
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
338 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
339 int j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
340 level = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
341 if (level) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
342 if (level < 0) {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
343 level = (1-2*level) * qscale * weight_matrix[i];
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
344 if (weight_matrix[i] != 32)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
345 level += 32;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
346 level >>= 6;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
347 level = -level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
348 } else {
5795
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
349 level = (2*level+1) * qscale * weight_matrix[i];
8b6fe123be88 typo weigth->weight
bcoudurier
parents: 5790
diff changeset
350 if (weight_matrix[i] != 32)
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
351 level += 32;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
352 level >>= 6;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
353 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
354 block[j] = level;
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 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
358
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
359 static av_always_inline int dnxhd_ssd_block(DCTELEM *qblock, DCTELEM *block)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
360 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
361 int score = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
362 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
363 for (i = 0; i < 64; i++)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
364 score += (block[i]-qblock[i])*(block[i]-qblock[i]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
365 return score;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
366 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
367
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
368 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
369 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
370 int last_non_zero = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
371 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
372 int i, j, level;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
373 for (i = 1; i <= last_index; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
374 j = ctx->m.intra_scantable.permutated[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
375 level = block[j];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
376 if (level) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
377 int run_level = i - last_non_zero - 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
378 level = FFABS(level);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
379 if (level > 64) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
380 level = 256 | (level & 63); // level 64 is treated as 0
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
381 bits += 4;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
382 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
383 level |= (!!run_level)<<7;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
384 bits += ctx->table_vlc_bits[level]+1 + ctx->table_run_bits[run_level];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
385 last_non_zero = i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
386 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
387 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
388 return bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
389 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
390
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
391 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
392 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
393 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
394 for (i = 0; i < 4; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
395 block[0] = pixels[0];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
396 block[1] = pixels[1];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
397 block[2] = pixels[2];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
398 block[3] = pixels[3];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
399 block[4] = pixels[4];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
400 block[5] = pixels[5];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
401 block[6] = pixels[6];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
402 block[7] = pixels[7];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
403 pixels += line_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
404 block += 8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
405 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
406 memcpy(block , block- 8, sizeof(*block)*8);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
407 memcpy(block+ 8, block-16, sizeof(*block)*8);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
408 memcpy(block+16, block-24, sizeof(*block)*8);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
409 memcpy(block+24, block-32, sizeof(*block)*8);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
410 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
411
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
412 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
413 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
414 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
415 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
416 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
417 DSPContext *dsp = &ctx->m.dsp;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
418
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
419 dsp->get_pixels(ctx->blocks[0], ptr_y , ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
420 dsp->get_pixels(ctx->blocks[1], ptr_y + 8, ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
421 dsp->get_pixels(ctx->blocks[2], ptr_u , ctx->m.uvlinesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
422 dsp->get_pixels(ctx->blocks[3], ptr_v , ctx->m.uvlinesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
423
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
424 if (mb_y+1 == ctx->m.mb_height) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
425 if (ctx->interlaced) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
426 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
427 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
428 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
429 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
430 } else
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
431 memset(ctx->blocks[4], 0, 4*64*sizeof(DCTELEM));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
432 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
433 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
434 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
435 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
436 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
437 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
438 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
439
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
440 static av_always_inline int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
441 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
442 if (i&2) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
443 ctx->m.q_intra_matrix16 = ctx->qmatrix_c16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
444 ctx->m.q_intra_matrix = ctx->qmatrix_c;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
445 return 1 + (i&1);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
446 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
447 ctx->m.q_intra_matrix16 = ctx->qmatrix_l16;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
448 ctx->m.q_intra_matrix = ctx->qmatrix_l;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
449 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
450 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
451 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
452
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
453 static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
454 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
455 DNXHDEncContext *ctx = arg;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
456 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
457 int qscale = ctx->thread[0]->qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
458
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
459 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
460 ctx->m.last_dc[0] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
461 ctx->m.last_dc[1] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
462 ctx->m.last_dc[2] = 1024;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
463
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
464 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
465 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
466 int ssd = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
467 int ac_bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
468 int dc_bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
469 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
470
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
471 dnxhd_get_blocks(ctx, mb_x, mb_y);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
472
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
473 for (i = 0; i < 8; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
474 DECLARE_ALIGNED_16(DCTELEM, block[64]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
475 DCTELEM *src_block = ctx->blocks[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
476 int overflow, nbits, diff, last_index;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
477 int n = dnxhd_switch_matrix(ctx, i);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
478
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
479 memcpy(block, src_block, sizeof(block));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
480 last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
481 ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
482
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
483 diff = block[0] - ctx->m.last_dc[n];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
484 if (diff < 0) nbits = av_log2_16bit(-2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
485 else nbits = av_log2_16bit( 2*diff);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
486 dc_bits += ctx->cid_table->dc_bits[nbits] + nbits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
487
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
488 ctx->m.last_dc[n] = block[0];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
489
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
490 if (avctx->mb_decision == FF_MB_DECISION_RD || !RC_VARIANCE) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
491 dnxhd_unquantize_c(ctx, block, i, qscale, last_index);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
492 ctx->m.dsp.idct(block);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
493 ssd += dnxhd_ssd_block(block, src_block);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
494 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
495 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
496 ctx->mb_rc[qscale][mb].ssd = ssd;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
497 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
498 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
499 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
500 return 0;
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 static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
504 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
505 DNXHDEncContext *ctx = arg;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
506 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
507
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 ctx->m.last_dc[0] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
510 ctx->m.last_dc[1] =
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
511 ctx->m.last_dc[2] = 1024;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
512 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
513 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
514 int qscale = ctx->mb_qscale[mb];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
515 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
516
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
517 put_bits(&ctx->m.pb, 12, qscale<<1);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
518
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
519 dnxhd_get_blocks(ctx, mb_x, mb_y);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
520
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
521 for (i = 0; i < 8; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
522 DCTELEM *block = ctx->blocks[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
523 int last_index, overflow;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
524 int n = dnxhd_switch_matrix(ctx, i);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
525 last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
526 dnxhd_encode_block(ctx, block, last_index, n);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
527 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
528 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
529 if (put_bits_count(&ctx->m.pb)&31)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
530 put_bits(&ctx->m.pb, 32-(put_bits_count(&ctx->m.pb)&31), 0);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
531 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
532 flush_put_bits(&ctx->m.pb);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
533 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
534 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
535
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
536 static void dnxhd_setup_threads_slices(DNXHDEncContext *ctx, uint8_t *buf)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
537 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
538 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
539 int i, offset = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
540 for (i = 0; i < ctx->m.avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
541 int thread_size = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
542 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
543 ctx->slice_size[mb_y] = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
544 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
545 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
546 ctx->slice_size[mb_y] += ctx->mb_bits[mb];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
547 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
548 ctx->slice_size[mb_y] = (ctx->slice_size[mb_y]+31)&~31;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
549 ctx->slice_size[mb_y] >>= 3;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
550 thread_size += ctx->slice_size[mb_y];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
551 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
552 init_put_bits(&ctx->thread[i]->m.pb, buf + 640 + offset, thread_size);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
553 offset += thread_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
554 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
555 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
556
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
557 static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
558 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
559 DNXHDEncContext *ctx = arg;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
560 int mb_y, mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
561 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
562 for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
563 unsigned mb = mb_y * ctx->m.mb_width + mb_x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
564 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
565 int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
566 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
567 ctx->mb_cmp[mb].value = varc;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
568 ctx->mb_cmp[mb].mb = mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
569 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
570 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
571 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
572 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
573
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
574 static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
575 {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
576 int lambda, up_step, down_step;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
577 int last_lower = INT_MAX, last_higher = 0;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
578 int x, y, q;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
579
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
580 for (q = 1; q < avctx->qmax; q++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
581 ctx->qscale = q;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
582 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
583 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
584 up_step = down_step = 2<<LAMBDA_FRAC_BITS;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
585 lambda = ctx->lambda;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
586
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
587 for (;;) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
588 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
589 int end = 0;
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
590 if (lambda == last_higher) {
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
591 lambda++;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
592 end = 1; // need to set final qscales/bits
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
593 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
594 for (y = 0; y < ctx->m.mb_height; y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
595 for (x = 0; x < ctx->m.mb_width; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
596 unsigned min = UINT_MAX;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
597 int qscale = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
598 int mb = y*ctx->m.mb_width+x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
599 for (q = 1; q < avctx->qmax; q++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
600 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
601 if (score < min) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
602 min = score;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
603 qscale = q;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
604 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
605 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
606 bits += ctx->mb_rc[qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
607 ctx->mb_qscale[mb] = qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
608 ctx->mb_bits[mb] = ctx->mb_rc[qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
609 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
610 bits = (bits+31)&~31; // padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
611 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
612 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
613 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
614 //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
615 // lambda, last_higher, last_lower, bits, ctx->frame_bits);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
616 if (end) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
617 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
618 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
619 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
620 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
621 if (bits < ctx->frame_bits) {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
622 last_lower = FFMIN(lambda, last_lower);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
623 if (last_higher != 0)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
624 lambda = (lambda+last_higher)>>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 -= down_step;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
627 down_step *= 5; // XXX tune ?
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
628 up_step = 1<<LAMBDA_FRAC_BITS;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
629 lambda = FFMAX(1, lambda);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
630 if (lambda == last_lower)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
631 break;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
632 } else {
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
633 last_higher = FFMAX(lambda, last_higher);
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
634 if (last_lower != INT_MAX)
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
635 lambda = (lambda+last_lower)>>1;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
636 else
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
637 lambda += up_step;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
638 up_step *= 5;
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
639 down_step = 1<<LAMBDA_FRAC_BITS;
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
640 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
641 }
5802
d112d5c13ae8 better lambda search method
bcoudurier
parents: 5796
diff changeset
642 //dprintf(ctx->m.avctx, "out lambda %d\n", lambda);
5790
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
643 ctx->lambda = lambda;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
644 return 0;
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 static int dnxhd_find_qscale(DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
648 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
649 int bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
650 int up_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
651 int down_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
652 int last_higher = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
653 int last_lower = INT_MAX;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
654 int qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
655 int x, y;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
656
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
657 qscale = ctx->qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
658 for (;;) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
659 bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
660 ctx->qscale = qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
661 // XXX avoid recalculating bits
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
662 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
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 bits += ctx->mb_rc[qscale][y*ctx->m.mb_width+x].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
666 bits = (bits+31)&~31; // padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
667 if (bits > ctx->frame_bits)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
668 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
669 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
670 //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
671 // ctx->m.avctx->frame_number, qscale, bits, ctx->frame_bits, last_higher, last_lower);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
672 if (bits < ctx->frame_bits) {
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 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
675 if (last_higher == qscale - 1) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
676 qscale = last_higher;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
677 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
678 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
679 last_lower = FFMIN(qscale, last_lower);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
680 if (last_higher != 0)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
681 qscale = (qscale+last_higher)>>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 -= down_step++;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
684 if (qscale < 1)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
685 qscale = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
686 up_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
687 } else {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
688 if (last_lower == qscale + 1)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
689 break;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
690 last_higher = FFMAX(qscale, last_higher);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
691 if (last_lower != INT_MAX)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
692 qscale = (qscale+last_lower)>>1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
693 else
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
694 qscale += up_step++;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
695 down_step = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
696 if (qscale >= ctx->m.avctx->qmax)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
697 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
698 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
699 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
700 //dprintf(ctx->m.avctx, "out qscale %d\n", qscale);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
701 ctx->qscale = qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
702 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
703 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
704
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
705 static int dnxhd_rc_cmp(const void *a, const void *b)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
706 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
707 return ((RCCMPEntry *)b)->value - ((RCCMPEntry *)a)->value;
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 static int dnxhd_encode_variance(AVCodecContext *avctx, DNXHDEncContext *ctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
711 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
712 int max_bits = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
713 int x, y;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
714 if (dnxhd_find_qscale(ctx) < 0)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
715 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
716 for (y = 0; y < ctx->m.mb_height; y++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
717 for (x = 0; x < ctx->m.mb_width; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
718 int mb = y*ctx->m.mb_width+x;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
719 int delta_bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
720 ctx->mb_qscale[mb] = ctx->qscale;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
721 ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
722 max_bits += ctx->mb_rc[ctx->qscale][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
723 if (!RC_VARIANCE) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
724 delta_bits = ctx->mb_rc[ctx->qscale][mb].bits-ctx->mb_rc[ctx->qscale+1][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
725 ctx->mb_cmp[mb].mb = mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
726 ctx->mb_cmp[mb].value = delta_bits ?
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
727 ((ctx->mb_rc[ctx->qscale][mb].ssd-ctx->mb_rc[ctx->qscale+1][mb].ssd)*100)/delta_bits
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
728 : INT_MIN; //avoid increasing qscale
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
729 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
730 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
731 max_bits += 31; //worst padding
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
732 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
733 if (max_bits > ctx->frame_bits) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
734 if (RC_VARIANCE)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
735 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
736 qsort(ctx->mb_cmp, ctx->m.mb_num, sizeof(RCEntry), dnxhd_rc_cmp);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
737 for (x = 0; x < ctx->m.mb_num && max_bits > ctx->frame_bits; x++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
738 int mb = ctx->mb_cmp[x].mb;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
739 max_bits -= ctx->mb_rc[ctx->qscale][mb].bits - ctx->mb_rc[ctx->qscale+1][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
740 ctx->mb_qscale[mb] = ctx->qscale+1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
741 ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale+1][mb].bits;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
742 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
743 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
744 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
745 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
746
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
747 static void dnxhd_load_picture(DNXHDEncContext *ctx, AVFrame *frame)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
748 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
749 int i;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
750
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
751 for (i = 0; i < 3; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
752 ctx->frame.data[i] = frame->data[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
753 ctx->frame.linesize[i] = frame->linesize[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
754 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
755
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
756 for (i = 0; i < ctx->m.avctx->thread_count; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
757 ctx->thread[i]->m.linesize = ctx->frame.linesize[0]<<ctx->interlaced;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
758 ctx->thread[i]->m.uvlinesize = ctx->frame.linesize[1]<<ctx->interlaced;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
759 ctx->thread[i]->dct_y_offset = ctx->m.linesize *8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
760 ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
761 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
762
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
763 ctx->frame.interlaced_frame = frame->interlaced_frame;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
764 ctx->cur_field = frame->interlaced_frame && !frame->top_field_first;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
765 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
766
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
767 static int dnxhd_encode_picture(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
768 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
769 DNXHDEncContext *ctx = avctx->priv_data;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
770 int first_field = 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
771 int offset, i, ret;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
772
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
773 if (buf_size < ctx->cid_table->frame_size) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
774 av_log(avctx, AV_LOG_ERROR, "output buffer is too small to compress picture\n");
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
775 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
776 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
777
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
778 dnxhd_load_picture(ctx, data);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
779
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
780 encode_coding_unit:
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
781 for (i = 0; i < 3; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
782 ctx->src[i] = ctx->frame.data[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
783 if (ctx->interlaced && ctx->cur_field)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
784 ctx->src[i] += ctx->frame.linesize[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
785 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
786
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
787 dnxhd_write_header(avctx, buf);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
788
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
789 if (avctx->mb_decision == FF_MB_DECISION_RD)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
790 ret = dnxhd_encode_rdo(avctx, ctx);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
791 else
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
792 ret = dnxhd_encode_variance(avctx, ctx);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
793 if (ret < 0) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
794 av_log(avctx, AV_LOG_ERROR, "picture could not fit ratecontrol constraints\n");
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
795 return -1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
796 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
797
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
798 dnxhd_setup_threads_slices(ctx, buf);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
799
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
800 offset = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
801 for (i = 0; i < ctx->m.mb_height; i++) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
802 AV_WB32(ctx->msip + i * 4, offset);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
803 offset += ctx->slice_size[i];
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
804 assert(!(ctx->slice_size[i] & 3));
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
805 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
806
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
807 avctx->execute(avctx, dnxhd_encode_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
808
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
809 AV_WB32(buf + ctx->cid_table->coding_unit_size - 4, 0x600DC0DE); // EOF
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
810
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
811 if (ctx->interlaced && first_field) {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
812 first_field = 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
813 ctx->cur_field ^= 1;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
814 buf += ctx->cid_table->coding_unit_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
815 buf_size -= ctx->cid_table->coding_unit_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
816 goto encode_coding_unit;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
817 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
818
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
819 return ctx->cid_table->frame_size;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
820 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
821
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
822 static int dnxhd_encode_end(AVCodecContext *avctx)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
823 {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
824 DNXHDEncContext *ctx = avctx->priv_data;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
825 int i;
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->table_vlc_codes);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
828 av_freep(&ctx->table_vlc_bits);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
829 av_freep(&ctx->table_run_codes);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
830 av_freep(&ctx->table_run_bits);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
831
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
832 av_freep(&ctx->mb_bits);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
833 av_freep(&ctx->mb_qscale);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
834 av_freep(&ctx->mb_rc);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
835 av_freep(&ctx->mb_cmp);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
836 av_freep(&ctx->slice_size);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
837
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
838 av_freep(&ctx->qmatrix_c);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
839 av_freep(&ctx->qmatrix_l);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
840 av_freep(&ctx->qmatrix_c16);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
841 av_freep(&ctx->qmatrix_l16);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
842
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
843 for (i = 1; i < avctx->thread_count; i++)
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
844 av_freep(&ctx->thread[i]);
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
845
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
846 return 0;
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
847 }
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
848
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
849 AVCodec dnxhd_encoder = {
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
850 "dnxhd",
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
851 CODEC_TYPE_VIDEO,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
852 CODEC_ID_DNXHD,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
853 sizeof(DNXHDEncContext),
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
854 dnxhd_encode_init,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
855 dnxhd_encode_picture,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
856 dnxhd_encode_end,
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
857 .pix_fmts = (enum PixelFormat[]){PIX_FMT_YUV422P, -1},
c3f2a6425d2d DNxHD (SMPTE VC-3) encoder
bcoudurier
parents:
diff changeset
858 };