00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "libavutil/opt.h"
00027 #include "avcodec.h"
00028 #include "put_bits.h"
00029 #include "bytestream.h"
00030 #include "internal.h"
00031 #include "proresdsp.h"
00032 #include "proresdata.h"
00033
00034 #define CFACTOR_Y422 2
00035 #define CFACTOR_Y444 3
00036
00037 #define MAX_MBS_PER_SLICE 8
00038
00039 #define MAX_PLANES 3 // should be increased to 4 when there's PIX_FMT_YUV444AP10
00040
00041 enum {
00042 PRORES_PROFILE_PROXY = 0,
00043 PRORES_PROFILE_LT,
00044 PRORES_PROFILE_STANDARD,
00045 PRORES_PROFILE_HQ,
00046 };
00047
00048 enum {
00049 QUANT_MAT_PROXY = 0,
00050 QUANT_MAT_LT,
00051 QUANT_MAT_STANDARD,
00052 QUANT_MAT_HQ,
00053 QUANT_MAT_DEFAULT,
00054 };
00055
00056 static const uint8_t prores_quant_matrices[][64] = {
00057 {
00058 4, 7, 9, 11, 13, 14, 15, 63,
00059 7, 7, 11, 12, 14, 15, 63, 63,
00060 9, 11, 13, 14, 15, 63, 63, 63,
00061 11, 11, 13, 14, 63, 63, 63, 63,
00062 11, 13, 14, 63, 63, 63, 63, 63,
00063 13, 14, 63, 63, 63, 63, 63, 63,
00064 13, 63, 63, 63, 63, 63, 63, 63,
00065 63, 63, 63, 63, 63, 63, 63, 63,
00066 },
00067 {
00068 4, 5, 6, 7, 9, 11, 13, 15,
00069 5, 5, 7, 8, 11, 13, 15, 17,
00070 6, 7, 9, 11, 13, 15, 15, 17,
00071 7, 7, 9, 11, 13, 15, 17, 19,
00072 7, 9, 11, 13, 14, 16, 19, 23,
00073 9, 11, 13, 14, 16, 19, 23, 29,
00074 9, 11, 13, 15, 17, 21, 28, 35,
00075 11, 13, 16, 17, 21, 28, 35, 41,
00076 },
00077 {
00078 4, 4, 5, 5, 6, 7, 7, 9,
00079 4, 4, 5, 6, 7, 7, 9, 9,
00080 5, 5, 6, 7, 7, 9, 9, 10,
00081 5, 5, 6, 7, 7, 9, 9, 10,
00082 5, 6, 7, 7, 8, 9, 10, 12,
00083 6, 7, 7, 8, 9, 10, 12, 15,
00084 6, 7, 7, 9, 10, 11, 14, 17,
00085 7, 7, 9, 10, 11, 14, 17, 21,
00086 },
00087 {
00088 4, 4, 4, 4, 4, 4, 4, 4,
00089 4, 4, 4, 4, 4, 4, 4, 4,
00090 4, 4, 4, 4, 4, 4, 4, 4,
00091 4, 4, 4, 4, 4, 4, 4, 5,
00092 4, 4, 4, 4, 4, 4, 5, 5,
00093 4, 4, 4, 4, 4, 5, 5, 6,
00094 4, 4, 4, 4, 5, 5, 6, 7,
00095 4, 4, 4, 4, 5, 6, 7, 7,
00096 },
00097 {
00098 4, 4, 4, 4, 4, 4, 4, 4,
00099 4, 4, 4, 4, 4, 4, 4, 4,
00100 4, 4, 4, 4, 4, 4, 4, 4,
00101 4, 4, 4, 4, 4, 4, 4, 4,
00102 4, 4, 4, 4, 4, 4, 4, 4,
00103 4, 4, 4, 4, 4, 4, 4, 4,
00104 4, 4, 4, 4, 4, 4, 4, 4,
00105 4, 4, 4, 4, 4, 4, 4, 4,
00106 },
00107 };
00108
00109 #define NUM_MB_LIMITS 4
00110 static const int prores_mb_limits[NUM_MB_LIMITS] = {
00111 1620,
00112 2700,
00113 6075,
00114 9216,
00115 };
00116
00117 static const struct prores_profile {
00118 const char *full_name;
00119 uint32_t tag;
00120 int min_quant;
00121 int max_quant;
00122 int br_tab[NUM_MB_LIMITS];
00123 int quant;
00124 } prores_profile_info[4] = {
00125 {
00126 .full_name = "proxy",
00127 .tag = MKTAG('a', 'p', 'c', 'o'),
00128 .min_quant = 4,
00129 .max_quant = 8,
00130 .br_tab = { 300, 242, 220, 194 },
00131 .quant = QUANT_MAT_PROXY,
00132 },
00133 {
00134 .full_name = "LT",
00135 .tag = MKTAG('a', 'p', 'c', 's'),
00136 .min_quant = 1,
00137 .max_quant = 9,
00138 .br_tab = { 720, 560, 490, 440 },
00139 .quant = QUANT_MAT_LT,
00140 },
00141 {
00142 .full_name = "standard",
00143 .tag = MKTAG('a', 'p', 'c', 'n'),
00144 .min_quant = 1,
00145 .max_quant = 6,
00146 .br_tab = { 1050, 808, 710, 632 },
00147 .quant = QUANT_MAT_STANDARD,
00148 },
00149 {
00150 .full_name = "high quality",
00151 .tag = MKTAG('a', 'p', 'c', 'h'),
00152 .min_quant = 1,
00153 .max_quant = 6,
00154 .br_tab = { 1566, 1216, 1070, 950 },
00155 .quant = QUANT_MAT_HQ,
00156 }
00157
00158 };
00159
00160 #define TRELLIS_WIDTH 16
00161 #define SCORE_LIMIT INT_MAX / 2
00162
00163 struct TrellisNode {
00164 int prev_node;
00165 int quant;
00166 int bits;
00167 int score;
00168 };
00169
00170 #define MAX_STORED_Q 16
00171
00172 typedef struct ProresThreadData {
00173 DECLARE_ALIGNED(16, DCTELEM, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
00174 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16 * 16];
00175 int16_t custom_q[64];
00176 struct TrellisNode *nodes;
00177 } ProresThreadData;
00178
00179 typedef struct ProresContext {
00180 AVClass *class;
00181 DECLARE_ALIGNED(16, DCTELEM, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
00182 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
00183 int16_t quants[MAX_STORED_Q][64];
00184 int16_t custom_q[64];
00185 const uint8_t *quant_mat;
00186
00187 ProresDSPContext dsp;
00188 ScanTable scantable;
00189
00190 int mb_width, mb_height;
00191 int mbs_per_slice;
00192 int num_chroma_blocks, chroma_factor;
00193 int slices_width;
00194 int num_slices;
00195 int num_planes;
00196 int bits_per_mb;
00197 int force_quant;
00198
00199 char *vendor;
00200 int quant_sel;
00201
00202 int frame_size;
00203
00204 int profile;
00205 const struct prores_profile *profile_info;
00206
00207 int *slice_q;
00208
00209 ProresThreadData *tdata;
00210 } ProresContext;
00211
00212 static void get_slice_data(ProresContext *ctx, const uint16_t *src,
00213 int linesize, int x, int y, int w, int h,
00214 DCTELEM *blocks, uint16_t *emu_buf,
00215 int mbs_per_slice, int blocks_per_mb, int is_chroma)
00216 {
00217 const uint16_t *esrc;
00218 const int mb_width = 4 * blocks_per_mb;
00219 int elinesize;
00220 int i, j, k;
00221
00222 for (i = 0; i < mbs_per_slice; i++, src += mb_width) {
00223 if (x >= w) {
00224 memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb
00225 * sizeof(*blocks));
00226 return;
00227 }
00228 if (x + mb_width <= w && y + 16 <= h) {
00229 esrc = src;
00230 elinesize = linesize;
00231 } else {
00232 int bw, bh, pix;
00233
00234 esrc = emu_buf;
00235 elinesize = 16 * sizeof(*emu_buf);
00236
00237 bw = FFMIN(w - x, mb_width);
00238 bh = FFMIN(h - y, 16);
00239
00240 for (j = 0; j < bh; j++) {
00241 memcpy(emu_buf + j * 16,
00242 (const uint8_t*)src + j * linesize,
00243 bw * sizeof(*src));
00244 pix = emu_buf[j * 16 + bw - 1];
00245 for (k = bw; k < mb_width; k++)
00246 emu_buf[j * 16 + k] = pix;
00247 }
00248 for (; j < 16; j++)
00249 memcpy(emu_buf + j * 16,
00250 emu_buf + (bh - 1) * 16,
00251 mb_width * sizeof(*emu_buf));
00252 }
00253 if (!is_chroma) {
00254 ctx->dsp.fdct(esrc, elinesize, blocks);
00255 blocks += 64;
00256 if (blocks_per_mb > 2) {
00257 ctx->dsp.fdct(src + 8, linesize, blocks);
00258 blocks += 64;
00259 }
00260 ctx->dsp.fdct(src + linesize * 4, linesize, blocks);
00261 blocks += 64;
00262 if (blocks_per_mb > 2) {
00263 ctx->dsp.fdct(src + linesize * 4 + 8, linesize, blocks);
00264 blocks += 64;
00265 }
00266 } else {
00267 ctx->dsp.fdct(esrc, elinesize, blocks);
00268 blocks += 64;
00269 ctx->dsp.fdct(src + linesize * 4, linesize, blocks);
00270 blocks += 64;
00271 if (blocks_per_mb > 2) {
00272 ctx->dsp.fdct(src + 8, linesize, blocks);
00273 blocks += 64;
00274 ctx->dsp.fdct(src + linesize * 4 + 8, linesize, blocks);
00275 blocks += 64;
00276 }
00277 }
00278
00279 x += mb_width;
00280 }
00281 }
00282
00286 static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
00287 {
00288 unsigned int rice_order, exp_order, switch_bits, switch_val;
00289 int exponent;
00290
00291
00292 switch_bits = (codebook & 3) + 1;
00293 rice_order = codebook >> 5;
00294 exp_order = (codebook >> 2) & 7;
00295
00296 switch_val = switch_bits << rice_order;
00297
00298 if (val >= switch_val) {
00299 val -= switch_val - (1 << exp_order);
00300 exponent = av_log2(val);
00301
00302 put_bits(pb, exponent - exp_order + switch_bits, 0);
00303 put_bits(pb, exponent + 1, val);
00304 } else {
00305 exponent = val >> rice_order;
00306
00307 if (exponent)
00308 put_bits(pb, exponent, 0);
00309 put_bits(pb, 1, 1);
00310 if (rice_order)
00311 put_sbits(pb, rice_order, val);
00312 }
00313 }
00314
00315 #define GET_SIGN(x) ((x) >> 31)
00316 #define MAKE_CODE(x) (((x) << 1) ^ GET_SIGN(x))
00317
00318 static void encode_dcs(PutBitContext *pb, DCTELEM *blocks,
00319 int blocks_per_slice, int scale)
00320 {
00321 int i;
00322 int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
00323
00324 prev_dc = (blocks[0] - 0x4000) / scale;
00325 encode_vlc_codeword(pb, FIRST_DC_CB, MAKE_CODE(prev_dc));
00326 sign = 0;
00327 codebook = 3;
00328 blocks += 64;
00329
00330 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
00331 dc = (blocks[0] - 0x4000) / scale;
00332 delta = dc - prev_dc;
00333 new_sign = GET_SIGN(delta);
00334 delta = (delta ^ sign) - sign;
00335 code = MAKE_CODE(delta);
00336 encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
00337 codebook = (code + (code & 1)) >> 1;
00338 codebook = FFMIN(codebook, 3);
00339 sign = new_sign;
00340 prev_dc = dc;
00341 }
00342 }
00343
00344 static void encode_acs(PutBitContext *pb, DCTELEM *blocks,
00345 int blocks_per_slice,
00346 int plane_size_factor,
00347 const uint8_t *scan, const int16_t *qmat)
00348 {
00349 int idx, i;
00350 int run, level, run_cb, lev_cb;
00351 int max_coeffs, abs_level;
00352
00353 max_coeffs = blocks_per_slice << 6;
00354 run_cb = ff_prores_run_to_cb_index[4];
00355 lev_cb = ff_prores_lev_to_cb_index[2];
00356 run = 0;
00357
00358 for (i = 1; i < 64; i++) {
00359 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
00360 level = blocks[idx] / qmat[scan[i]];
00361 if (level) {
00362 abs_level = FFABS(level);
00363 encode_vlc_codeword(pb, ff_prores_ac_codebook[run_cb], run);
00364 encode_vlc_codeword(pb, ff_prores_ac_codebook[lev_cb],
00365 abs_level - 1);
00366 put_sbits(pb, 1, GET_SIGN(level));
00367
00368 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
00369 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
00370 run = 0;
00371 } else {
00372 run++;
00373 }
00374 }
00375 }
00376 }
00377
00378 static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
00379 const uint16_t *src, int linesize,
00380 int mbs_per_slice, DCTELEM *blocks,
00381 int blocks_per_mb, int plane_size_factor,
00382 const int16_t *qmat)
00383 {
00384 int blocks_per_slice, saved_pos;
00385
00386 saved_pos = put_bits_count(pb);
00387 blocks_per_slice = mbs_per_slice * blocks_per_mb;
00388
00389 encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
00390 encode_acs(pb, blocks, blocks_per_slice, plane_size_factor,
00391 ctx->scantable.permutated, qmat);
00392 flush_put_bits(pb);
00393
00394 return (put_bits_count(pb) - saved_pos) >> 3;
00395 }
00396
00397 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
00398 PutBitContext *pb,
00399 int sizes[4], int x, int y, int quant,
00400 int mbs_per_slice)
00401 {
00402 ProresContext *ctx = avctx->priv_data;
00403 int i, xp, yp;
00404 int total_size = 0;
00405 const uint16_t *src;
00406 int slice_width_factor = av_log2(mbs_per_slice);
00407 int num_cblocks, pwidth;
00408 int plane_factor, is_chroma;
00409 uint16_t *qmat;
00410
00411 if (ctx->force_quant) {
00412 qmat = ctx->quants[0];
00413 } else if (quant < MAX_STORED_Q) {
00414 qmat = ctx->quants[quant];
00415 } else {
00416 qmat = ctx->custom_q;
00417 for (i = 0; i < 64; i++)
00418 qmat[i] = ctx->quant_mat[i] * quant;
00419 }
00420
00421 for (i = 0; i < ctx->num_planes; i++) {
00422 is_chroma = (i == 1 || i == 2);
00423 plane_factor = slice_width_factor + 2;
00424 if (is_chroma)
00425 plane_factor += ctx->chroma_factor - 3;
00426 if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
00427 xp = x << 4;
00428 yp = y << 4;
00429 num_cblocks = 4;
00430 pwidth = avctx->width;
00431 } else {
00432 xp = x << 3;
00433 yp = y << 4;
00434 num_cblocks = 2;
00435 pwidth = avctx->width >> 1;
00436 }
00437 src = (const uint16_t*)(pic->data[i] + yp * pic->linesize[i]) + xp;
00438
00439 get_slice_data(ctx, src, pic->linesize[i], xp, yp,
00440 pwidth, avctx->height, ctx->blocks[0], ctx->emu_buf,
00441 mbs_per_slice, num_cblocks, is_chroma);
00442 sizes[i] = encode_slice_plane(ctx, pb, src, pic->linesize[i],
00443 mbs_per_slice, ctx->blocks[0],
00444 num_cblocks, plane_factor,
00445 qmat);
00446 total_size += sizes[i];
00447 }
00448 return total_size;
00449 }
00450
00451 static inline int estimate_vlc(unsigned codebook, int val)
00452 {
00453 unsigned int rice_order, exp_order, switch_bits, switch_val;
00454 int exponent;
00455
00456
00457 switch_bits = (codebook & 3) + 1;
00458 rice_order = codebook >> 5;
00459 exp_order = (codebook >> 2) & 7;
00460
00461 switch_val = switch_bits << rice_order;
00462
00463 if (val >= switch_val) {
00464 val -= switch_val - (1 << exp_order);
00465 exponent = av_log2(val);
00466
00467 return exponent * 2 - exp_order + switch_bits + 1;
00468 } else {
00469 return (val >> rice_order) + rice_order + 1;
00470 }
00471 }
00472
00473 static int estimate_dcs(int *error, DCTELEM *blocks, int blocks_per_slice,
00474 int scale)
00475 {
00476 int i;
00477 int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
00478 int bits;
00479
00480 prev_dc = (blocks[0] - 0x4000) / scale;
00481 bits = estimate_vlc(FIRST_DC_CB, MAKE_CODE(prev_dc));
00482 sign = 0;
00483 codebook = 3;
00484 blocks += 64;
00485 *error += FFABS(blocks[0] - 0x4000) % scale;
00486
00487 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
00488 dc = (blocks[0] - 0x4000) / scale;
00489 *error += FFABS(blocks[0] - 0x4000) % scale;
00490 delta = dc - prev_dc;
00491 new_sign = GET_SIGN(delta);
00492 delta = (delta ^ sign) - sign;
00493 code = MAKE_CODE(delta);
00494 bits += estimate_vlc(ff_prores_dc_codebook[codebook], code);
00495 codebook = (code + (code & 1)) >> 1;
00496 codebook = FFMIN(codebook, 3);
00497 sign = new_sign;
00498 prev_dc = dc;
00499 }
00500
00501 return bits;
00502 }
00503
00504 static int estimate_acs(int *error, DCTELEM *blocks, int blocks_per_slice,
00505 int plane_size_factor,
00506 const uint8_t *scan, const int16_t *qmat)
00507 {
00508 int idx, i;
00509 int run, level, run_cb, lev_cb;
00510 int max_coeffs, abs_level;
00511 int bits = 0;
00512
00513 max_coeffs = blocks_per_slice << 6;
00514 run_cb = ff_prores_run_to_cb_index[4];
00515 lev_cb = ff_prores_lev_to_cb_index[2];
00516 run = 0;
00517
00518 for (i = 1; i < 64; i++) {
00519 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
00520 level = blocks[idx] / qmat[scan[i]];
00521 *error += FFABS(blocks[idx]) % qmat[scan[i]];
00522 if (level) {
00523 abs_level = FFABS(level);
00524 bits += estimate_vlc(ff_prores_ac_codebook[run_cb], run);
00525 bits += estimate_vlc(ff_prores_ac_codebook[lev_cb],
00526 abs_level - 1) + 1;
00527
00528 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
00529 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
00530 run = 0;
00531 } else {
00532 run++;
00533 }
00534 }
00535 }
00536
00537 return bits;
00538 }
00539
00540 static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
00541 const uint16_t *src, int linesize,
00542 int mbs_per_slice,
00543 int blocks_per_mb, int plane_size_factor,
00544 const int16_t *qmat, ProresThreadData *td)
00545 {
00546 int blocks_per_slice;
00547 int bits;
00548
00549 blocks_per_slice = mbs_per_slice * blocks_per_mb;
00550
00551 bits = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
00552 bits += estimate_acs(error, td->blocks[plane], blocks_per_slice,
00553 plane_size_factor, ctx->scantable.permutated, qmat);
00554
00555 return FFALIGN(bits, 8);
00556 }
00557
00558 static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
00559 int trellis_node, int x, int y, int mbs_per_slice,
00560 ProresThreadData *td)
00561 {
00562 ProresContext *ctx = avctx->priv_data;
00563 int i, q, pq, xp, yp;
00564 const uint16_t *src;
00565 int slice_width_factor = av_log2(mbs_per_slice);
00566 int num_cblocks[MAX_PLANES], pwidth;
00567 int plane_factor[MAX_PLANES], is_chroma[MAX_PLANES];
00568 const int min_quant = ctx->profile_info->min_quant;
00569 const int max_quant = ctx->profile_info->max_quant;
00570 int error, bits, bits_limit;
00571 int mbs, prev, cur, new_score;
00572 int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
00573 int overquant;
00574 uint16_t *qmat;
00575
00576 mbs = x + mbs_per_slice;
00577
00578 for (i = 0; i < ctx->num_planes; i++) {
00579 is_chroma[i] = (i == 1 || i == 2);
00580 plane_factor[i] = slice_width_factor + 2;
00581 if (is_chroma[i])
00582 plane_factor[i] += ctx->chroma_factor - 3;
00583 if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
00584 xp = x << 4;
00585 yp = y << 4;
00586 num_cblocks[i] = 4;
00587 pwidth = avctx->width;
00588 } else {
00589 xp = x << 3;
00590 yp = y << 4;
00591 num_cblocks[i] = 2;
00592 pwidth = avctx->width >> 1;
00593 }
00594 src = (const uint16_t*)(pic->data[i] + yp * pic->linesize[i]) + xp;
00595
00596 get_slice_data(ctx, src, pic->linesize[i], xp, yp,
00597 pwidth, avctx->height, td->blocks[i], td->emu_buf,
00598 mbs_per_slice, num_cblocks[i], is_chroma[i]);
00599 }
00600
00601 for (q = min_quant; q < max_quant + 2; q++) {
00602 td->nodes[trellis_node + q].prev_node = -1;
00603 td->nodes[trellis_node + q].quant = q;
00604 }
00605
00606
00607 for (q = min_quant; q <= max_quant; q++) {
00608 bits = 0;
00609 error = 0;
00610 for (i = 0; i < ctx->num_planes; i++) {
00611 bits += estimate_slice_plane(ctx, &error, i,
00612 src, pic->linesize[i],
00613 mbs_per_slice,
00614 num_cblocks[i], plane_factor[i],
00615 ctx->quants[q], td);
00616 }
00617 if (bits > 65000 * 8) {
00618 error = SCORE_LIMIT;
00619 break;
00620 }
00621 slice_bits[q] = bits;
00622 slice_score[q] = error;
00623 }
00624 if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
00625 slice_bits[max_quant + 1] = slice_bits[max_quant];
00626 slice_score[max_quant + 1] = slice_score[max_quant] + 1;
00627 overquant = max_quant;
00628 } else {
00629 for (q = max_quant + 1; q < 128; q++) {
00630 bits = 0;
00631 error = 0;
00632 if (q < MAX_STORED_Q) {
00633 qmat = ctx->quants[q];
00634 } else {
00635 qmat = td->custom_q;
00636 for (i = 0; i < 64; i++)
00637 qmat[i] = ctx->quant_mat[i] * q;
00638 }
00639 for (i = 0; i < ctx->num_planes; i++) {
00640 bits += estimate_slice_plane(ctx, &error, i,
00641 src, pic->linesize[i],
00642 mbs_per_slice,
00643 num_cblocks[i], plane_factor[i],
00644 qmat, td);
00645 }
00646 if (bits <= ctx->bits_per_mb * mbs_per_slice)
00647 break;
00648 }
00649
00650 slice_bits[max_quant + 1] = bits;
00651 slice_score[max_quant + 1] = error;
00652 overquant = q;
00653 }
00654 td->nodes[trellis_node + max_quant + 1].quant = overquant;
00655
00656 bits_limit = mbs * ctx->bits_per_mb;
00657 for (pq = min_quant; pq < max_quant + 2; pq++) {
00658 prev = trellis_node - TRELLIS_WIDTH + pq;
00659
00660 for (q = min_quant; q < max_quant + 2; q++) {
00661 cur = trellis_node + q;
00662
00663 bits = td->nodes[prev].bits + slice_bits[q];
00664 error = slice_score[q];
00665 if (bits > bits_limit)
00666 error = SCORE_LIMIT;
00667
00668 if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)
00669 new_score = td->nodes[prev].score + error;
00670 else
00671 new_score = SCORE_LIMIT;
00672 if (td->nodes[cur].prev_node == -1 ||
00673 td->nodes[cur].score >= new_score) {
00674
00675 td->nodes[cur].bits = bits;
00676 td->nodes[cur].score = new_score;
00677 td->nodes[cur].prev_node = prev;
00678 }
00679 }
00680 }
00681
00682 error = td->nodes[trellis_node + min_quant].score;
00683 pq = trellis_node + min_quant;
00684 for (q = min_quant + 1; q < max_quant + 2; q++) {
00685 if (td->nodes[trellis_node + q].score <= error) {
00686 error = td->nodes[trellis_node + q].score;
00687 pq = trellis_node + q;
00688 }
00689 }
00690
00691 return pq;
00692 }
00693
00694 static int find_quant_thread(AVCodecContext *avctx, void *arg,
00695 int jobnr, int threadnr)
00696 {
00697 ProresContext *ctx = avctx->priv_data;
00698 ProresThreadData *td = ctx->tdata + threadnr;
00699 int mbs_per_slice = ctx->mbs_per_slice;
00700 int x, y = jobnr, mb, q = 0;
00701
00702 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
00703 while (ctx->mb_width - x < mbs_per_slice)
00704 mbs_per_slice >>= 1;
00705 q = find_slice_quant(avctx, avctx->coded_frame,
00706 (mb + 1) * TRELLIS_WIDTH, x, y,
00707 mbs_per_slice, td);
00708 }
00709
00710 for (x = ctx->slices_width - 1; x >= 0; x--) {
00711 ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
00712 q = td->nodes[q].prev_node;
00713 }
00714
00715 return 0;
00716 }
00717
00718 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
00719 const AVFrame *pic, int *got_packet)
00720 {
00721 ProresContext *ctx = avctx->priv_data;
00722 uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
00723 uint8_t *picture_size_pos;
00724 PutBitContext pb;
00725 int x, y, i, mb, q = 0;
00726 int sizes[4] = { 0 };
00727 int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1);
00728 int frame_size, picture_size, slice_size;
00729 int mbs_per_slice = ctx->mbs_per_slice;
00730 int pkt_size, ret;
00731
00732 *avctx->coded_frame = *pic;
00733 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
00734 avctx->coded_frame->key_frame = 1;
00735
00736 pkt_size = ctx->frame_size + FF_MIN_BUFFER_SIZE;
00737
00738 if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size)) < 0)
00739 return ret;
00740
00741 orig_buf = pkt->data;
00742
00743
00744 orig_buf += 4;
00745 bytestream_put_be32 (&orig_buf, FRAME_ID);
00746 buf = orig_buf;
00747
00748
00749 tmp = buf;
00750 buf += 2;
00751 bytestream_put_be16 (&buf, 0);
00752 bytestream_put_buffer(&buf, ctx->vendor, 4);
00753 bytestream_put_be16 (&buf, avctx->width);
00754 bytestream_put_be16 (&buf, avctx->height);
00755 bytestream_put_byte (&buf, ctx->chroma_factor << 6);
00756 bytestream_put_byte (&buf, 0);
00757 bytestream_put_byte (&buf, avctx->color_primaries);
00758 bytestream_put_byte (&buf, avctx->color_trc);
00759 bytestream_put_byte (&buf, avctx->colorspace);
00760 bytestream_put_byte (&buf, 0x40);
00761 bytestream_put_byte (&buf, 0);
00762 if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
00763 bytestream_put_byte (&buf, 0x03);
00764
00765 for (i = 0; i < 64; i++)
00766 bytestream_put_byte(&buf, ctx->quant_mat[i]);
00767
00768 for (i = 0; i < 64; i++)
00769 bytestream_put_byte(&buf, ctx->quant_mat[i]);
00770 } else {
00771 bytestream_put_byte (&buf, 0x00);
00772 }
00773 bytestream_put_be16 (&tmp, buf - orig_buf);
00774
00775
00776 picture_size_pos = buf + 1;
00777 bytestream_put_byte (&buf, 0x40);
00778 buf += 4;
00779 bytestream_put_be16 (&buf, ctx->num_slices);
00780 bytestream_put_byte (&buf, av_log2(ctx->mbs_per_slice) << 4);
00781
00782
00783 slice_sizes = buf;
00784 buf += ctx->num_slices * 2;
00785
00786
00787 if (!ctx->force_quant) {
00788 ret = avctx->execute2(avctx, find_quant_thread, NULL, NULL,
00789 ctx->mb_height);
00790 if (ret)
00791 return ret;
00792 }
00793
00794 for (y = 0; y < ctx->mb_height; y++) {
00795 mbs_per_slice = ctx->mbs_per_slice;
00796 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
00797 q = ctx->force_quant ? ctx->force_quant
00798 : ctx->slice_q[mb + y * ctx->slices_width];
00799
00800 while (ctx->mb_width - x < mbs_per_slice)
00801 mbs_per_slice >>= 1;
00802
00803 bytestream_put_byte(&buf, slice_hdr_size << 3);
00804 slice_hdr = buf;
00805 buf += slice_hdr_size - 1;
00806 init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)) * 8);
00807 encode_slice(avctx, pic, &pb, sizes, x, y, q, mbs_per_slice);
00808
00809 bytestream_put_byte(&slice_hdr, q);
00810 slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
00811 for (i = 0; i < ctx->num_planes - 1; i++) {
00812 bytestream_put_be16(&slice_hdr, sizes[i]);
00813 slice_size += sizes[i];
00814 }
00815 bytestream_put_be16(&slice_sizes, slice_size);
00816 buf += slice_size - slice_hdr_size;
00817 }
00818 }
00819
00820 orig_buf -= 8;
00821 frame_size = buf - orig_buf;
00822 picture_size = buf - picture_size_pos - 6;
00823 bytestream_put_be32(&orig_buf, frame_size);
00824 bytestream_put_be32(&picture_size_pos, picture_size);
00825
00826 pkt->size = frame_size;
00827 pkt->flags |= AV_PKT_FLAG_KEY;
00828 *got_packet = 1;
00829
00830 return 0;
00831 }
00832
00833 static av_cold int encode_close(AVCodecContext *avctx)
00834 {
00835 ProresContext *ctx = avctx->priv_data;
00836 int i;
00837
00838 if (avctx->coded_frame->data[0])
00839 avctx->release_buffer(avctx, avctx->coded_frame);
00840
00841 av_freep(&avctx->coded_frame);
00842
00843 if (ctx->tdata) {
00844 for (i = 0; i < avctx->thread_count; i++)
00845 av_free(ctx->tdata[i].nodes);
00846 }
00847 av_freep(&ctx->tdata);
00848 av_freep(&ctx->slice_q);
00849
00850 return 0;
00851 }
00852
00853 static av_cold int encode_init(AVCodecContext *avctx)
00854 {
00855 ProresContext *ctx = avctx->priv_data;
00856 int mps;
00857 int i, j;
00858 int min_quant, max_quant;
00859
00860 avctx->bits_per_raw_sample = 10;
00861 avctx->coded_frame = avcodec_alloc_frame();
00862 if (!avctx->coded_frame)
00863 return AVERROR(ENOMEM);
00864
00865 ff_proresdsp_init(&ctx->dsp, avctx);
00866 ff_init_scantable(ctx->dsp.dct_permutation, &ctx->scantable,
00867 ff_prores_progressive_scan);
00868
00869 mps = ctx->mbs_per_slice;
00870 if (mps & (mps - 1)) {
00871 av_log(avctx, AV_LOG_ERROR,
00872 "there should be an integer power of two MBs per slice\n");
00873 return AVERROR(EINVAL);
00874 }
00875
00876 ctx->chroma_factor = avctx->pix_fmt == PIX_FMT_YUV422P10
00877 ? CFACTOR_Y422
00878 : CFACTOR_Y444;
00879 ctx->profile_info = prores_profile_info + ctx->profile;
00880 ctx->num_planes = 3;
00881
00882 ctx->mb_width = FFALIGN(avctx->width, 16) >> 4;
00883 ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
00884 ctx->slices_width = ctx->mb_width / mps;
00885 ctx->slices_width += av_popcount(ctx->mb_width - ctx->slices_width * mps);
00886 ctx->num_slices = ctx->mb_height * ctx->slices_width;
00887
00888 if (ctx->quant_sel == -1)
00889 ctx->quant_mat = prores_quant_matrices[ctx->profile_info->quant];
00890 else
00891 ctx->quant_mat = prores_quant_matrices[ctx->quant_sel];
00892
00893 if (strlen(ctx->vendor) != 4) {
00894 av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
00895 return AVERROR_INVALIDDATA;
00896 }
00897
00898 ctx->force_quant = avctx->global_quality / FF_QP2LAMBDA;
00899 if (!ctx->force_quant) {
00900 if (!ctx->bits_per_mb) {
00901 for (i = 0; i < NUM_MB_LIMITS - 1; i++)
00902 if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height)
00903 break;
00904 ctx->bits_per_mb = ctx->profile_info->br_tab[i];
00905 } else if (ctx->bits_per_mb < 128) {
00906 av_log(avctx, AV_LOG_ERROR, "too few bits per MB, please set at least 128\n");
00907 return AVERROR_INVALIDDATA;
00908 }
00909
00910 min_quant = ctx->profile_info->min_quant;
00911 max_quant = ctx->profile_info->max_quant;
00912 for (i = min_quant; i < MAX_STORED_Q; i++) {
00913 for (j = 0; j < 64; j++)
00914 ctx->quants[i][j] = ctx->quant_mat[j] * i;
00915 }
00916
00917 ctx->slice_q = av_malloc(ctx->num_slices * sizeof(*ctx->slice_q));
00918 if (!ctx->slice_q) {
00919 encode_close(avctx);
00920 return AVERROR(ENOMEM);
00921 }
00922
00923 ctx->tdata = av_mallocz(avctx->thread_count * sizeof(*ctx->tdata));
00924 if (!ctx->tdata) {
00925 encode_close(avctx);
00926 return AVERROR(ENOMEM);
00927 }
00928
00929 for (j = 0; j < avctx->thread_count; j++) {
00930 ctx->tdata[j].nodes = av_malloc((ctx->slices_width + 1)
00931 * TRELLIS_WIDTH
00932 * sizeof(*ctx->tdata->nodes));
00933 if (!ctx->tdata[j].nodes) {
00934 encode_close(avctx);
00935 return AVERROR(ENOMEM);
00936 }
00937 for (i = min_quant; i < max_quant + 2; i++) {
00938 ctx->tdata[j].nodes[i].prev_node = -1;
00939 ctx->tdata[j].nodes[i].bits = 0;
00940 ctx->tdata[j].nodes[i].score = 0;
00941 }
00942 }
00943 } else {
00944 int ls = 0;
00945
00946 if (ctx->force_quant > 64) {
00947 av_log(avctx, AV_LOG_ERROR, "too large quantiser, maximum is 64\n");
00948 return AVERROR_INVALIDDATA;
00949 }
00950
00951 for (j = 0; j < 64; j++) {
00952 ctx->quants[0][j] = ctx->quant_mat[j] * ctx->force_quant;
00953 ls += av_log2((1 << 11) / ctx->quants[0][j]) * 2 + 1;
00954 }
00955
00956 ctx->bits_per_mb = ls * 8;
00957 if (ctx->chroma_factor == CFACTOR_Y444)
00958 ctx->bits_per_mb += ls * 4;
00959 if (ctx->num_planes == 4)
00960 ctx->bits_per_mb += ls * 4;
00961 }
00962
00963 ctx->frame_size = ctx->num_slices * (2 + 2 * ctx->num_planes
00964 + (2 * mps * ctx->bits_per_mb) / 8)
00965 + 200;
00966
00967 avctx->codec_tag = ctx->profile_info->tag;
00968
00969 av_log(avctx, AV_LOG_DEBUG, "profile %d, %d slices, %d bits per MB\n",
00970 ctx->profile, ctx->num_slices, ctx->bits_per_mb);
00971 av_log(avctx, AV_LOG_DEBUG, "estimated frame size %d\n",
00972 ctx->frame_size);
00973
00974 return 0;
00975 }
00976
00977 #define OFFSET(x) offsetof(ProresContext, x)
00978 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
00979
00980 static const AVOption options[] = {
00981 { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
00982 AV_OPT_TYPE_INT, { 8 }, 1, MAX_MBS_PER_SLICE, VE },
00983 { "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT,
00984 { PRORES_PROFILE_STANDARD },
00985 PRORES_PROFILE_PROXY, PRORES_PROFILE_HQ, VE, "profile" },
00986 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { PRORES_PROFILE_PROXY },
00987 0, 0, VE, "profile" },
00988 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { PRORES_PROFILE_LT },
00989 0, 0, VE, "profile" },
00990 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { PRORES_PROFILE_STANDARD },
00991 0, 0, VE, "profile" },
00992 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { PRORES_PROFILE_HQ },
00993 0, 0, VE, "profile" },
00994 { "vendor", "vendor ID", OFFSET(vendor),
00995 AV_OPT_TYPE_STRING, { .str = "Lavc" }, CHAR_MIN, CHAR_MAX, VE },
00996 { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
00997 AV_OPT_TYPE_INT, { 0 }, 0, 8192, VE },
00998 { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
00999 { -1 }, -1, QUANT_MAT_DEFAULT, VE, "quant_mat" },
01000 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { -1 },
01001 0, 0, VE, "quant_mat" },
01002 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { QUANT_MAT_PROXY },
01003 0, 0, VE, "quant_mat" },
01004 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { QUANT_MAT_LT },
01005 0, 0, VE, "quant_mat" },
01006 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { QUANT_MAT_STANDARD },
01007 0, 0, VE, "quant_mat" },
01008 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { QUANT_MAT_HQ },
01009 0, 0, VE, "quant_mat" },
01010 { "default", NULL, 0, AV_OPT_TYPE_CONST, { QUANT_MAT_DEFAULT },
01011 0, 0, VE, "quant_mat" },
01012 { NULL }
01013 };
01014
01015 static const AVClass proresenc_class = {
01016 .class_name = "ProRes encoder",
01017 .item_name = av_default_item_name,
01018 .option = options,
01019 .version = LIBAVUTIL_VERSION_INT,
01020 };
01021
01022 AVCodec ff_prores_kostya_encoder = {
01023 .name = "prores_kostya",
01024 .type = AVMEDIA_TYPE_VIDEO,
01025 .id = CODEC_ID_PRORES,
01026 .priv_data_size = sizeof(ProresContext),
01027 .init = encode_init,
01028 .close = encode_close,
01029 .encode2 = encode_frame,
01030 .capabilities = CODEC_CAP_SLICE_THREADS,
01031 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"),
01032 .pix_fmts = (const enum PixelFormat[]) {
01033 PIX_FMT_YUV422P10, PIX_FMT_YUV444P10, PIX_FMT_NONE
01034 },
01035 .priv_class = &proresenc_class,
01036 };