DNXHDEncContext *ctx = avctx->priv_data;
int i, index;
- if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
- if (avctx->bit_rate == 120000000)
- ctx->cid = 1242;
- else if (avctx->bit_rate == 185000000)
- ctx->cid = 1243;
- } else {
- if (avctx->bit_rate == 120000000)
- ctx->cid = 1237;
- else if (avctx->bit_rate == 185000000)
- ctx->cid = 1238;
- else if (avctx->bit_rate == 36000000)
- ctx->cid = 1253;
- }
- if (!ctx->cid || avctx->width != 1920 || avctx->height != 1080 || avctx->pix_fmt != PIX_FMT_YUV422P) {
+ ctx->cid = ff_dnxhd_find_cid(avctx);
+ if (!ctx->cid || avctx->pix_fmt != PIX_FMT_YUV422P) {
av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD\n");
return -1;
}
+ av_log(avctx, AV_LOG_DEBUG, "cid %d\n", ctx->cid);
index = ff_dnxhd_get_cid_table(ctx->cid);
ctx->cid_table = &ff_dnxhd_cid_table[index];
dsp->get_pixels(ctx->blocks[2], ptr_u , ctx->m.uvlinesize);
dsp->get_pixels(ctx->blocks[3], ptr_v , ctx->m.uvlinesize);
- if (mb_y+1 == ctx->m.mb_height) {
+ if (mb_y+1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) {
if (ctx->interlaced) {
dnxhd_get_pixels_4x8(ctx->blocks[4], ptr_y + ctx->dct_y_offset , ctx->m.linesize);
dnxhd_get_pixels_4x8(ctx->blocks[5], ptr_y + ctx->dct_y_offset + 8, ctx->m.linesize);
static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx)
{
- unsigned lambda, up_lambda, down_lambda;
+ int lambda, up_step, down_step;
+ int last_lower = INT_MAX, last_higher = 0;
int x, y, q;
for (q = 1; q < avctx->qmax; q++) {
ctx->qscale = q;
avctx->execute(avctx, dnxhd_calc_bits_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count);
}
- up_lambda = avctx->qmax<<LAMBDA_FRAC_BITS;
- down_lambda = 1; // higher ?
+ up_step = down_step = 2<<LAMBDA_FRAC_BITS;
lambda = ctx->lambda;
for (;;) {
int bits = 0;
int end = 0;
- if (lambda == up_lambda) {
- lambda--;
- end = 1; // need to set final qscales/bits
- }
- if (lambda == down_lambda) {
+ if (lambda == last_higher) {
lambda++;
- end = 1;
+ end = 1; // need to set final qscales/bits
}
for (y = 0; y < ctx->m.mb_height; y++) {
for (x = 0; x < ctx->m.mb_width; x++) {
if (bits > ctx->frame_bits)
break;
}
- //dprintf(ctx->m.avctx, "lambda %d, up %d, down %d, bits %d, frame %d\n", lambda, up_lambda, down_lambda, bits, ctx->frame_bits);
+ //dprintf(ctx->m.avctx, "lambda %d, up %u, down %u, bits %d, frame %d\n",
+ // lambda, last_higher, last_lower, bits, ctx->frame_bits);
if (end) {
if (bits > ctx->frame_bits)
return -1;
break;
}
if (bits < ctx->frame_bits) {
- up_lambda = lambda;
- lambda = (down_lambda+lambda)>>1;
+ last_lower = FFMIN(lambda, last_lower);
+ if (last_higher != 0)
+ lambda = (lambda+last_higher)>>1;
+ else
+ lambda -= down_step;
+ down_step *= 5; // XXX tune ?
+ up_step = 1<<LAMBDA_FRAC_BITS;
+ lambda = FFMAX(1, lambda);
+ if (lambda == last_lower)
+ break;
} else {
- down_lambda = lambda;
- lambda = (up_lambda+lambda)>>1;
+ last_higher = FFMAX(lambda, last_higher);
+ if (last_lower != INT_MAX)
+ lambda = (lambda+last_lower)>>1;
+ else
+ lambda += up_step;
+ up_step *= 5;
+ down_step = 1<<LAMBDA_FRAC_BITS;
}
}
+ //dprintf(ctx->m.avctx, "out lambda %d\n", lambda);
ctx->lambda = lambda;
return 0;
}
// ctx->m.avctx->frame_number, qscale, bits, ctx->frame_bits, last_higher, last_lower);
if (bits < ctx->frame_bits) {
if (qscale == 1)
- break;
+ return 1;
if (last_higher == qscale - 1) {
qscale = last_higher;
break;
static int dnxhd_rc_cmp(const void *a, const void *b)
{
- return ((RCCMPEntry *)b)->value - ((RCCMPEntry *)a)->value;
+ return ((const RCCMPEntry *)b)->value - ((const RCCMPEntry *)a)->value;
}
-static int dnxhd_encode_variance(AVCodecContext *avctx, DNXHDEncContext *ctx)
+static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx)
{
int max_bits = 0;
- int x, y;
- if (dnxhd_find_qscale(ctx) < 0)
+ int ret, x, y;
+ if ((ret = dnxhd_find_qscale(ctx)) < 0)
return -1;
for (y = 0; y < ctx->m.mb_height; y++) {
for (x = 0; x < ctx->m.mb_width; x++) {
}
max_bits += 31; //worst padding
}
- if (max_bits > ctx->frame_bits) {
+ if (!ret) {
if (RC_VARIANCE)
avctx->execute(avctx, dnxhd_mb_var_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count);
qsort(ctx->mb_cmp, ctx->m.mb_num, sizeof(RCEntry), dnxhd_rc_cmp);
return 0;
}
-static void dnxhd_load_picture(DNXHDEncContext *ctx, AVFrame *frame)
+static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame)
{
int i;
ctx->cur_field = frame->interlaced_frame && !frame->top_field_first;
}
-static int dnxhd_encode_picture(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data)
+static int dnxhd_encode_picture(AVCodecContext *avctx, unsigned char *buf, int buf_size, const void *data)
{
DNXHDEncContext *ctx = avctx->priv_data;
int first_field = 1;
if (avctx->mb_decision == FF_MB_DECISION_RD)
ret = dnxhd_encode_rdo(avctx, ctx);
else
- ret = dnxhd_encode_variance(avctx, ctx);
+ ret = dnxhd_encode_fast(avctx, ctx);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "picture could not fit ratecontrol constraints\n");
return -1;