static double get_scene_score(AVFilterContext *ctx, AVFilterBufferRef *picref) { double ret = 0; SelectContext *select = ctx->priv; AVFilterBufferRef *prev_picref = select->prev_picref; if (prev_picref && picref->video->h == prev_picref->video->h && picref->video->w == prev_picref->video->w && picref->linesize[0] == prev_picref->linesize[0]) { int x, y, nb_sad = 0; int64_t sad = 0; double mafd, diff; uint8_t *p1 = picref->data[0]; uint8_t *p2 = prev_picref->data[0]; const int linesize = picref->linesize[0]; for (y = 0; y < picref->video->h - 8; y += 8) { for (x = 0; x < picref->video->w*3 - 8; x += 8) { sad += select->c.sad[1](select, p1 + x, p2 + x, linesize, 8); nb_sad += 8 * 8; } p1 += 8 * linesize; p2 += 8 * linesize; } emms_c(); mafd = nb_sad ? sad / nb_sad : 0; diff = fabs(mafd - select->prev_mafd); ret = av_clipf(FFMIN(mafd, diff) / 100., 0, 1); select->prev_mafd = mafd; avfilter_unref_buffer(prev_picref); } select->prev_picref = avfilter_ref_buffer(picref, ~0); return ret; }
static double get_scene_score(AVFilterContext *ctx, AVFrame *frame) { double ret = 0; SelectContext *select = ctx->priv; AVFrame *prev_picref = select->prev_picref; if (prev_picref && frame->height == prev_picref->height && frame->width == prev_picref->width && frame->linesize[0] == prev_picref->linesize[0]) { int x, y, nb_sad = 0; int64_t sad = 0; double mafd, diff; uint8_t *p1 = frame->data[0]; uint8_t *p2 = prev_picref->data[0]; const int linesize = frame->linesize[0]; for (y = 0; y < frame->height - 8; y += 8) { for (x = 0; x < frame->width*3 - 8; x += 8) { sad += select->c.sad[1](select, p1 + x, p2 + x, linesize, 8); nb_sad += 8 * 8; } p1 += 8 * linesize; p2 += 8 * linesize; } emms_c(); mafd = nb_sad ? (double)sad / nb_sad : 0; diff = fabs(mafd - select->prev_mafd); ret = av_clipf(FFMIN(mafd, diff) / 100., 0, 1); select->prev_mafd = mafd; av_frame_free(&prev_picref); } select->prev_picref = av_frame_clone(frame); return ret; }
float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run) { float q; int qmin, qmax; float br_compensation; double diff; double short_term_q; double fps; int picture_number = s->picture_number; int64_t wanted_bits; RateControlContext *rcc = &s->rc_context; AVCodecContext *a = s->avctx; RateControlEntry local_rce, *rce; double bits; double rate_factor; int64_t var; const int pict_type = s->pict_type; Picture * const pic = &s->current_picture; emms_c(); #if CONFIG_LIBXVID if ((s->avctx->flags & CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) return ff_xvid_rate_estimate_qscale(s, dry_run); #endif get_qminmax(&qmin, &qmax, s, pict_type); fps = get_fps(s->avctx); /* update predictors */ if (picture_number > 2 && !dry_run) { const int64_t last_var = s->last_pict_type == AV_PICTURE_TYPE_I ? rcc->last_mb_var_sum : rcc->last_mc_mb_var_sum; av_assert1(s->frame_bits >= s->stuffing_bits); update_predictor(&rcc->pred[s->last_pict_type], rcc->last_qscale, sqrt(last_var), s->frame_bits - s->stuffing_bits); } if (s->avctx->flags & CODEC_FLAG_PASS2) { av_assert0(picture_number >= 0); if (picture_number >= rcc->num_entries) { av_log(s, AV_LOG_ERROR, "Input is longer than 2-pass log file\n"); return -1; } rce = &rcc->entry[picture_number]; wanted_bits = rce->expected_bits; } else { Picture *dts_pic; rce = &local_rce; /* FIXME add a dts field to AVFrame and ensure it is set and use it * here instead of reordering but the reordering is simpler for now * until H.264 B-pyramid must be handled. */ if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) dts_pic = s->current_picture_ptr; else dts_pic = s->last_picture_ptr; if (!dts_pic || dts_pic->f->pts == AV_NOPTS_VALUE) wanted_bits = (uint64_t)(s->bit_rate * (double)picture_number / fps); else wanted_bits = (uint64_t)(s->bit_rate * (double)dts_pic->f->pts / fps); } diff = s->total_bits - wanted_bits; br_compensation = (a->bit_rate_tolerance - diff) / a->bit_rate_tolerance; if (br_compensation <= 0.0) br_compensation = 0.001; var = pict_type == AV_PICTURE_TYPE_I ? pic->mb_var_sum : pic->mc_mb_var_sum; short_term_q = 0; /* avoid warning */ if (s->avctx->flags & CODEC_FLAG_PASS2) { if (pict_type != AV_PICTURE_TYPE_I) av_assert0(pict_type == rce->new_pict_type); q = rce->new_qscale / br_compensation; ff_dlog(s, "%f %f %f last:%d var:%"PRId64" type:%d//\n", q, rce->new_qscale, br_compensation, s->frame_bits, var, pict_type); } else { rce->pict_type = rce->new_pict_type = pict_type; rce->mc_mb_var_sum = pic->mc_mb_var_sum; rce->mb_var_sum = pic->mb_var_sum; rce->qscale = FF_QP2LAMBDA * 2; rce->f_code = s->f_code; rce->b_code = s->b_code; rce->misc_bits = 1; bits = predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var)); if (pict_type == AV_PICTURE_TYPE_I) { rce->i_count = s->mb_num; rce->i_tex_bits = bits; rce->p_tex_bits = 0; rce->mv_bits = 0; } else { rce->i_count = 0; // FIXME we do know this approx rce->i_tex_bits = 0; rce->p_tex_bits = bits * 0.9; rce->mv_bits = bits * 0.1; } rcc->i_cplx_sum[pict_type] += rce->i_tex_bits * rce->qscale; rcc->p_cplx_sum[pict_type] += rce->p_tex_bits * rce->qscale; rcc->mv_bits_sum[pict_type] += rce->mv_bits; rcc->frame_count[pict_type]++; rate_factor = rcc->pass1_wanted_bits / rcc->pass1_rc_eq_output_sum * br_compensation; q = get_qscale(s, rce, rate_factor, picture_number); if (q < 0) return -1; av_assert0(q > 0.0); q = get_diff_limited_q(s, rce, q); av_assert0(q > 0.0); // FIXME type dependent blur like in 2-pass if (pict_type == AV_PICTURE_TYPE_P || s->intra_only) { rcc->short_term_qsum *= a->qblur; rcc->short_term_qcount *= a->qblur; rcc->short_term_qsum += q; rcc->short_term_qcount++; q = short_term_q = rcc->short_term_qsum / rcc->short_term_qcount; } av_assert0(q > 0.0); q = modify_qscale(s, rce, q, picture_number); rcc->pass1_wanted_bits += s->bit_rate / fps; av_assert0(q > 0.0); } if (s->avctx->debug & FF_DEBUG_RC) { av_log(s->avctx, AV_LOG_DEBUG, "%c qp:%d<%2.1f<%d %d want:%d total:%d comp:%f st_q:%2.2f " "size:%d var:%"PRId64"/%"PRId64" br:%d fps:%d\n", av_get_picture_type_char(pict_type), qmin, q, qmax, picture_number, (int)wanted_bits / 1000, (int)s->total_bits / 1000, br_compensation, short_term_q, s->frame_bits, pic->mb_var_sum, pic->mc_mb_var_sum, s->bit_rate / 1000, (int)fps); } if (q < qmin) q = qmin; else if (q > qmax) q = qmax; if (s->adaptive_quant) adaptive_quantization(s, q); else q = (int)(q + 0.5); if (!dry_run) { rcc->last_qscale = q; rcc->last_mc_mb_var_sum = pic->mc_mb_var_sum; rcc->last_mb_var_sum = pic->mb_var_sum; } return q; }
static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { MscEncoderContext * mscEncoderContext; MscCodecContext * mscContext; uint32_t arithBytesEncoded; PutBitContext pb; int mb_y, mb_x, value, lastNonZero, max, arithCoderIndex = -1, keyFrame; // initialize arithmetic encoder registers initialize_arithmetic_encoder(); mscEncoderContext = avctx->priv_data; mscContext = &mscEncoderContext->mscContext; init_put_bits(&pb, mscEncoderContext->arithBuff, mscEncoderContext->arithBuffSize); keyFrame = isKeyFrame(avctx->frame_number); if (avctx->frame_number == 0) { av_image_alloc(mscContext->referenceFrame->data, mscContext->referenceFrame->linesize, frame->width, frame->height, frame->format, 128); } avctx->coded_frame->reference = 0; avctx->coded_frame->key_frame = 1; avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; int * qmatrix = keyFrame ? mscContext->q_intra_matrix : mscContext->q_non_intra_matrix; for (mb_x = 0; mb_x < mscContext->mb_width; mb_x++) { for (mb_y = 0; mb_y < mscContext->mb_height; mb_y++) { get_blocks(mscEncoderContext, frame, mb_x, mb_y, mscContext->block); if (!keyFrame) { get_blocks(mscEncoderContext, mscContext->referenceFrame, mb_x, mb_y, mscContext->tmpBlock); diff_blocks(mscContext->block, mscContext->tmpBlock); } for (int n = 0; n < 6; ++n) { // if (avctx->frame_number == 1 && mb_x == 0 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "Block x=%d, y=%d, n=%d\n", mb_x, mb_y, n); // print_debug_block(avctx, mscContext->block[n]); // } mscContext->dsp.fdct(mscContext->block[n]); // if (avctx->frame_number == 0 && mb_x == 0 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "DCT block x=%d, y=%d, n=%d\n", mb_x, mb_y, n); // print_debug_block(avctx, mscContext->block[n]); // } lastNonZero = quantize(mscContext->block[n], qmatrix, &max); av_assert1(lastNonZero < 64); // if (overflow) { // clip_coeffs(m, m->block[n], m->block_last_index[n]); // av_log(avctx, AV_LOG_WARNING, "Overflow detected, frame: %d, mb_x: %d, mb_y: %d, n: %d\n", // avctx->frame_number, mb_x, mb_y, n); // } // if (avctx->frame_number == 0 && mb_x == 3 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "DCT quantized block x=%d, y=%d, n=%d\n", mb_x, mb_y, n); // print_debug_block(avctx, mscContext->block[n]); // } encode_arith_symbol(&mscContext->lastZeroCodingModel, &pb, lastNonZero); if (lastNonZero > 0) { arithCoderIndex = get_arith_model_index(max); encode_arith_symbol(&mscContext->arithModelIndexCodingModel, &pb, arithCoderIndex); } for (int i = 0; i <= lastNonZero; ++i) { int arithCoderBits = i == 0 ? ARITH_CODER_BITS : arithCoderIndex; value = mscContext->block[n][scantab[i]] + mscContext->arithModelAddValue[arithCoderBits]; encode_arith_symbol(&mscContext->arithModels[arithCoderBits], &pb, value); } dequantize(mscContext->block[n], mscContext, keyFrame); } if (keyFrame) { idct_put_block(mscContext, mscContext->referenceFrame, mb_x, mb_y); } else { idct_add_block(mscContext, mscContext->referenceFrame, mb_x, mb_y); } } } emms_c(); // flush arithmetic encoder flush_arithmetic_encoder(&pb); flush_put_bits(&pb); arithBytesEncoded = pb.buf_ptr - pb.buf; // alocate packet if ((value = ff_alloc_packet(avpkt, arithBytesEncoded)) < 0) { return value; } avpkt->flags |= AV_PKT_FLAG_KEY; // store encoded data memcpy(avpkt->data, mscEncoderContext->arithBuff, arithBytesEncoded); *got_packet_ptr = 1; return 0; }
static int decode(AVCodecContext * avctx, void *outdata, int *outdata_size, AVPacket *avpkt) { AVFrame *frame = avctx->coded_frame; MscDecoderContext * mscDecoderContext; MscCodecContext * mscContext; GetBitContext gb; int lastNonZero, value, arithCoderIndex = -1, keyFrame; mscDecoderContext = avctx->priv_data; mscContext = &mscDecoderContext->mscContext; if (frame->data[0]) { avctx->release_buffer(avctx, frame); } frame->reference = 0; if (avctx->get_buffer(avctx, frame) < 0) { av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); return AVERROR(ENOMEM); } keyFrame = isKeyFrame(avctx->frame_number); if (avctx->frame_number == 0) { av_image_alloc(mscContext->referenceFrame->data, mscContext->referenceFrame->linesize, frame->width, frame->height, PIX_FMT_YUV420P, 128); } if (!keyFrame) { av_image_copy(frame->data, frame->linesize, mscContext->referenceFrame->data, mscContext->referenceFrame->linesize, PIX_FMT_YUV420P, frame->width, frame->height); } frame->key_frame = 1; frame->pict_type = AV_PICTURE_TYPE_I; // init encoded data bit buffer init_get_bits(&gb, avpkt->data, avpkt->size * 8); initialize_arithmetic_decoder(&gb); for (int mb_x = 0; mb_x < mscContext->mb_width; mb_x++) { for (int mb_y = 0; mb_y < mscContext->mb_height; mb_y++) { for (int n = 0; n < 6; ++n) { mscContext->dsp.clear_block(mscContext->block[n]); lastNonZero = decode_arith_symbol(&mscContext->lastZeroCodingModel, &gb); if (lastNonZero > 0) { arithCoderIndex = decode_arith_symbol(&mscContext->arithModelIndexCodingModel, &gb); } for (int i = 0; i <= lastNonZero; ++i) { int arithCoderBits = i == 0 ? ARITH_CODER_BITS : arithCoderIndex; value = decode_arith_symbol(&mscContext->arithModels[arithCoderBits], &gb); mscContext->block[n][scantab[i]] = value - mscContext->arithModelAddValue[arithCoderBits]; } // if (avctx->frame_number == 0 && mb_x == 3 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "Quantized x=%d, y=%d, n=%d\n", mb_x, mb_y, n); // print_debug_block(avctx, mscContext->block[n]); // } dequantize(mscContext->block[n], mscContext, keyFrame); // if (avctx->frame_number == 0 && mb_x == 0 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "Dequantized x=%d, y=%d, n=%d\n", mb_x, mb_y, n); // print_debug_block(avctx, mscContext->block[n]); // } } // if (avctx->frame_number == 0 && mb_x == 0 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "IDCT x=%d, y=%d, n=%d\n", mb_x, mb_y, 0); // print_debug_block(avctx, mscContext->block[0]); // } if (keyFrame) { idct_put_block(mscContext, frame, mb_x, mb_y); } else { idct_add_block(mscContext, frame, mb_x, mb_y); } copy_macroblock(frame, mscContext->referenceFrame, mb_x, mb_y); } } emms_c(); *outdata_size = sizeof(AVFrame); *(AVFrame *) outdata = *frame; return avpkt->size; }
float ff_rate_estimate_qscale(MpegEncContext *s) { float q; int qmin, qmax; float br_compensation; double diff; double short_term_q; double fps; int picture_number= s->picture_number; int64_t wanted_bits; RateControlContext *rcc= &s->rc_context; AVCodecContext *a= s->avctx; RateControlEntry local_rce, *rce; double bits; double rate_factor; int var; const int pict_type= s->pict_type; Picture * const pic= &s->current_picture; emms_c(); get_qminmax(&qmin, &qmax, s, pict_type); fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base; //printf("input_pic_num:%d pic_num:%d frame_rate:%d\n", s->input_picture_number, s->picture_number, s->frame_rate); /* update predictors */ if(picture_number>2){ const int last_var= s->last_pict_type == I_TYPE ? rcc->last_mb_var_sum : rcc->last_mc_mb_var_sum; update_predictor(&rcc->pred[s->last_pict_type], rcc->last_qscale, sqrt(last_var), s->frame_bits); } if(s->flags&CODEC_FLAG_PASS2){ assert(picture_number>=0); assert(picture_number<rcc->num_entries); rce= &rcc->entry[picture_number]; wanted_bits= rce->expected_bits; }else{ rce= &local_rce; wanted_bits= (uint64_t)(s->bit_rate*(double)picture_number/fps); } diff= s->total_bits - wanted_bits; br_compensation= (a->bit_rate_tolerance - diff)/a->bit_rate_tolerance; if(br_compensation<=0.0) br_compensation=0.001; var= pict_type == I_TYPE ? pic->mb_var_sum : pic->mc_mb_var_sum; short_term_q = 0; /* avoid warning */ if(s->flags&CODEC_FLAG_PASS2){ if(pict_type!=I_TYPE) assert(pict_type == rce->new_pict_type); q= rce->new_qscale / br_compensation; //MEANX, take also constraint in pass 2 if(s->avctx->rc_buffer_size) { q=bitrate_constraint(s, rce, q, picture_number); } // /MEANX //printf("%f %f %f last:%d var:%d type:%d//\n", q, rce->new_qscale, br_compensation, s->frame_bits, var, pict_type); }else{ rce->pict_type= rce->new_pict_type= pict_type; rce->mc_mb_var_sum= pic->mc_mb_var_sum; rce->mb_var_sum = pic-> mb_var_sum; rce->qscale = FF_QP2LAMBDA * 2; rce->f_code = s->f_code; rce->b_code = s->b_code; rce->misc_bits= 1; bits= predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var)); if(pict_type== I_TYPE){ rce->i_count = s->mb_num; rce->i_tex_bits= bits; rce->p_tex_bits= 0; rce->mv_bits= 0; }else{ rce->i_count = 0; //FIXME we do know this approx rce->i_tex_bits= 0; rce->p_tex_bits= bits*0.9; rce->mv_bits= bits*0.1; } rcc->i_cplx_sum [pict_type] += rce->i_tex_bits*rce->qscale; rcc->p_cplx_sum [pict_type] += rce->p_tex_bits*rce->qscale; rcc->mv_bits_sum[pict_type] += rce->mv_bits; rcc->frame_count[pict_type] ++; bits= rce->i_tex_bits + rce->p_tex_bits; rate_factor= rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum * br_compensation; q= get_qscale(s, rce, rate_factor, picture_number); assert(q>0.0); //printf("%f ", q); q= get_diff_limited_q(s, rce, q); //printf("%f ", q); assert(q>0.0); if(pict_type==P_TYPE || s->intra_only){ //FIXME type dependant blur like in 2-pass rcc->short_term_qsum*=a->qblur; rcc->short_term_qcount*=a->qblur; rcc->short_term_qsum+= q; rcc->short_term_qcount++; //printf("%f ", q); q= short_term_q= rcc->short_term_qsum/rcc->short_term_qcount; //printf("%f ", q); } assert(q>0.0); q= modify_qscale(s, rce, q, picture_number); rcc->pass1_wanted_bits+= s->bit_rate/fps; assert(q>0.0); } if(s->avctx->debug&FF_DEBUG_RC){ av_log(s->avctx, AV_LOG_DEBUG, "%c qp:%d<%2.1f<%d %d want:%d total:%d comp:%f st_q:%2.2f size:%d var:%d/%d br:%d fps:%d\n", av_get_pict_type_char(pict_type), qmin, q, qmax, picture_number, (int)wanted_bits/1000, (int)s->total_bits/1000, br_compensation, short_term_q, s->frame_bits, pic->mb_var_sum, pic->mc_mb_var_sum, s->bit_rate/1000, (int)fps ); } if (q<qmin) q=qmin; else if(q>qmax) q=qmax; if(s->adaptive_quant) adaptive_quantization(s, q); else q= (int)(q + 0.5); rcc->last_qscale= q; rcc->last_mc_mb_var_sum= pic->mc_mb_var_sum; rcc->last_mb_var_sum= pic->mb_var_sum; #if 0 { static int mvsum=0, texsum=0; mvsum += s->mv_bits; texsum += s->i_tex_bits + s->p_tex_bits; printf("%d %d//\n\n", mvsum, texsum); } #endif return q; }
int ff_rate_control_init(MpegEncContext *s) { RateControlContext *rcc= &s->rc_context; int i; emms_c(); for(i=0; i<5; i++){ rcc->pred[i].coeff= FF_QP2LAMBDA * 7.0; rcc->pred[i].count= 1.0; rcc->pred[i].decay= 0.4; rcc->i_cplx_sum [i]= rcc->p_cplx_sum [i]= rcc->mv_bits_sum[i]= rcc->qscale_sum [i]= rcc->frame_count[i]= 1; // 1 is better cuz of 1/0 and such rcc->last_qscale_for[i]=FF_QP2LAMBDA * 5; } rcc->buffer_index= s->avctx->rc_initial_buffer_occupancy; if(s->flags&CODEC_FLAG_PASS2){ int i; char *p; /* find number of pics */ p= s->avctx->stats_in; for(i=-1; p; i++){ p= strchr(p+1, ';'); } i+= s->max_b_frames; rcc->entry = (RateControlEntry*)av_mallocz(i*sizeof(RateControlEntry)); rcc->num_entries= i; /* init all to skiped p frames (with b frames we might have a not encoded frame at the end FIXME) */ for(i=0; i<rcc->num_entries; i++){ RateControlEntry *rce= &rcc->entry[i]; rce->pict_type= rce->new_pict_type=P_TYPE; rce->qscale= rce->new_qscale=FF_QP2LAMBDA * 2; rce->misc_bits= s->mb_num + 10; rce->mb_var_sum= s->mb_num*100; } /* read stats */ p= s->avctx->stats_in; for(i=0; i<rcc->num_entries - s->max_b_frames; i++){ RateControlEntry *rce; int picture_number; int e; char *next; next= strchr(p, ';'); if(next){ (*next)=0; //sscanf in unbelieavle slow on looong strings //FIXME copy / dont write next++; } e= sscanf(p, " in:%d ", &picture_number); assert(picture_number >= 0); assert(picture_number < rcc->num_entries); rce= &rcc->entry[picture_number]; e+=sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d", &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits, &rce->mv_bits, &rce->misc_bits, &rce->f_code, &rce->b_code, &rce->mc_mb_var_sum, &rce->mb_var_sum, &rce->i_count); if(e!=12){ av_log(s->avctx, AV_LOG_ERROR, "statistics are damaged at line %d, parser out=%d\n", i, e); return -1; } p= next; } if(init_pass2(s) < 0) return -1; } if(!(s->flags&CODEC_FLAG_PASS2)){ rcc->short_term_qsum=0.001; rcc->short_term_qcount=0.001; rcc->pass1_rc_eq_output_sum= 0.001; rcc->pass1_wanted_bits=0.001; /* init stuff with the user specified complexity */ if(s->avctx->rc_initial_cplx){ for(i=0; i<60*30; i++){ double bits= s->avctx->rc_initial_cplx * (i/10000.0 + 1.0)*s->mb_num; RateControlEntry rce; double q; if (i%((s->gop_size+3)/4)==0) rce.pict_type= I_TYPE; else if(i%(s->max_b_frames+1)) rce.pict_type= B_TYPE; else rce.pict_type= P_TYPE; rce.new_pict_type= rce.pict_type; rce.mc_mb_var_sum= bits*s->mb_num/100000; rce.mb_var_sum = s->mb_num; rce.qscale = FF_QP2LAMBDA * 2; rce.f_code = 2; rce.b_code = 1; rce.misc_bits= 1; if(s->pict_type== I_TYPE){ rce.i_count = s->mb_num; rce.i_tex_bits= bits; rce.p_tex_bits= 0; rce.mv_bits= 0; }else{ rce.i_count = 0; //FIXME we do know this approx rce.i_tex_bits= 0; rce.p_tex_bits= bits*0.9; rce.mv_bits= bits*0.1; } rcc->i_cplx_sum [rce.pict_type] += rce.i_tex_bits*rce.qscale; rcc->p_cplx_sum [rce.pict_type] += rce.p_tex_bits*rce.qscale; rcc->mv_bits_sum[rce.pict_type] += rce.mv_bits; rcc->frame_count[rce.pict_type] ++; bits= rce.i_tex_bits + rce.p_tex_bits; q= get_qscale(s, &rce, rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum, i); rcc->pass1_wanted_bits+= s->bit_rate/(s->avctx->frame_rate / (double)s->avctx->frame_rate_base); } } } return 0; }
int ff_rate_control_init(MpegEncContext *s) { RateControlContext *rcc= &s->rc_context; int i; const char *error = NULL; static const char * const const_names[]={ "PI", "E", "iTex", "pTex", "tex", "mv", "fCode", "iCount", "mcVar", "var", "isI", "isP", "isB", "avgQP", "qComp", /* "lastIQP", "lastPQP", "lastBQP", "nextNonBQP",*/ "avgIITex", "avgPITex", "avgPPTex", "avgBPTex", "avgTex", NULL }; static double (* const func1[])(void *, double)={ (void *)bits2qp, (void *)qp2bits, NULL }; static const char * const func1_names[]={ "bits2qp", "qp2bits", NULL }; emms_c(); rcc->rc_eq_eval = ff_parse(s->avctx->rc_eq ? s->avctx->rc_eq : "tex^qComp", const_names, func1, func1_names, NULL, NULL, &error); if (!rcc->rc_eq_eval) { av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\": %s\n", s->avctx->rc_eq, error? error : ""); return -1; } for(i=0; i<5; i++){ rcc->pred[i].coeff= FF_QP2LAMBDA * 7.0; rcc->pred[i].count= 1.0; rcc->pred[i].decay= 0.4; rcc->i_cplx_sum [i]= rcc->p_cplx_sum [i]= rcc->mv_bits_sum[i]= rcc->qscale_sum [i]= rcc->frame_count[i]= 1; // 1 is better because of 1/0 and such rcc->last_qscale_for[i]=FF_QP2LAMBDA * 5; } rcc->buffer_index= s->avctx->rc_initial_buffer_occupancy; if(s->flags&CODEC_FLAG_PASS2){ int i; char *p; /* find number of pics */ p= s->avctx->stats_in; for(i=-1; p; i++){ p= strchr(p+1, ';'); } i+= s->max_b_frames; if(i<=0 || i>=INT_MAX / sizeof(RateControlEntry)) return -1; rcc->entry = av_mallocz(i*sizeof(RateControlEntry)); rcc->num_entries= i; /* init all to skipped p frames (with b frames we might have a not encoded frame at the end FIXME) */ for(i=0; i<rcc->num_entries; i++){ RateControlEntry *rce= &rcc->entry[i]; rce->pict_type= rce->new_pict_type=FF_P_TYPE; rce->qscale= rce->new_qscale=FF_QP2LAMBDA * 2; rce->misc_bits= s->mb_num + 10; rce->mb_var_sum= s->mb_num*100; } /* read stats */ p= s->avctx->stats_in; for(i=0; i<rcc->num_entries - s->max_b_frames; i++){ RateControlEntry *rce; int picture_number; int e; char *next; next= strchr(p, ';'); if(next){ (*next)=0; //sscanf in unbelievably slow on looong strings //FIXME copy / do not write next++; } e= sscanf(p, " in:%d ", &picture_number); assert(picture_number >= 0); assert(picture_number < rcc->num_entries); rce= &rcc->entry[picture_number]; e+=sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d", &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits, &rce->mv_bits, &rce->misc_bits, &rce->f_code, &rce->b_code, &rce->mc_mb_var_sum, &rce->mb_var_sum, &rce->i_count, &rce->skip_count, &rce->header_bits); if(e!=14){ av_log(s->avctx, AV_LOG_ERROR, "statistics are damaged at line %d, parser out=%d\n", i, e); return -1; } p= next; } if(init_pass2(s) < 0) return -1; //FIXME maybe move to end if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) { #if CONFIG_LIBXVID return ff_xvid_rate_control_init(s); #else av_log(s->avctx, AV_LOG_ERROR, "Xvid ratecontrol requires libavcodec compiled with Xvid support.\n"); return -1; #endif } for (i=0;i<s->avctx->rc_override_count;i++) { RcOverride *rco= &s->avctx->rc_override[i]; int rcoframe; if (rco->start_frame<0) rco->start_frame=0; else if (rco->start_frame>=rcc->num_entries) rco->start_frame=rcc->num_entries-1; if (rco->end_frame<0) rco->end_frame=0; else if (rco->end_frame>=rcc->num_entries) rco->end_frame=rcc->num_entries-1; for (rcoframe=rco->start_frame;rcoframe<=rco->end_frame;rcoframe++) { rcc->entry[rcoframe].rcOverrideIndex1=i+1; if (rco->qscale) rcc->entry[rcoframe].rcOverrideQscale=rco->qscale; } } if(init_pass2(s) < 0) return -1; } if(!(s->flags&CODEC_FLAG_PASS2)){ rcc->short_term_qsum=0.001; rcc->short_term_qcount=0.001; rcc->pass1_rc_eq_output_sum= 0.001; rcc->pass1_wanted_bits=0.001; if(s->avctx->qblur > 1.0){ av_log(s->avctx, AV_LOG_ERROR, "qblur too large\n"); return -1; } /* init stuff with the user specified complexity */ if(s->avctx->rc_initial_cplx){ for(i=0; i<60*30; i++){ double bits= s->avctx->rc_initial_cplx * (i/10000.0 + 1.0)*s->mb_num; RateControlEntry rce; double q; if (i%((s->gop_size+3)/4)==0) rce.pict_type= FF_I_TYPE; else if(i%(s->max_b_frames+1)) rce.pict_type= FF_B_TYPE; else rce.pict_type= FF_P_TYPE; rce.new_pict_type= rce.pict_type; rce.mc_mb_var_sum= bits*s->mb_num/100000; rce.mb_var_sum = s->mb_num; rce.qscale = FF_QP2LAMBDA * 2; rce.f_code = 2; rce.b_code = 1; rce.misc_bits= 1; if(s->pict_type== FF_I_TYPE){ rce.i_count = s->mb_num; rce.i_tex_bits= bits; rce.p_tex_bits= 0; rce.mv_bits= 0; }else{ rce.i_count = 0; //FIXME we do know this approx rce.i_tex_bits= 0; rce.p_tex_bits= bits*0.9; rce.mv_bits= bits*0.1; } rcc->i_cplx_sum [rce.pict_type] += rce.i_tex_bits*rce.qscale; rcc->p_cplx_sum [rce.pict_type] += rce.p_tex_bits*rce.qscale; rcc->mv_bits_sum[rce.pict_type] += rce.mv_bits; rcc->frame_count[rce.pict_type] ++; bits= rce.i_tex_bits + rce.p_tex_bits; q= get_qscale(s, &rce, rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum, i); rcc->pass1_wanted_bits+= s->bit_rate/(1/av_q2d(s->avctx->time_base)); //FIXME misbehaves a little for variable fps } } } return 0; }
/* * The core of the receive_frame_wrapper for the decoders implementing * the simple API. Certain decoders might consume partial packets without * returning any output, so this function needs to be called in a loop until it * returns EAGAIN. **/ static int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame) { AVCodecInternal *avci = avctx->internal; DecodeSimpleContext *ds = &avci->ds; AVPacket *pkt = ds->in_pkt; int got_frame; int ret; if (!pkt->data && !avci->draining) { av_packet_unref(pkt); ret = ff_decode_get_packet(avctx, pkt); if (ret < 0 && ret != AVERROR_EOF) return ret; } // Some codecs (at least wma lossless) will crash when feeding drain packets // after EOF was signaled. if (avci->draining_done) return AVERROR_EOF; if (!pkt->data && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY || avctx->active_thread_type & FF_THREAD_FRAME)) return AVERROR_EOF; got_frame = 0; if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) { ret = ff_thread_decode_frame(avctx, frame, &got_frame, pkt); } else { ret = avctx->codec->decode(avctx, frame, &got_frame, pkt); if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) frame->pkt_dts = pkt->dts; /* get_buffer is supposed to set frame parameters */ if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { frame->sample_aspect_ratio = avctx->sample_aspect_ratio; frame->width = avctx->width; frame->height = avctx->height; frame->format = avctx->codec->type == AVMEDIA_TYPE_VIDEO ? avctx->pix_fmt : avctx->sample_fmt; } } emms_c(); if (!got_frame) av_frame_unref(frame); if (ret >= 0 && avctx->codec->type == AVMEDIA_TYPE_VIDEO) ret = pkt->size; if (avctx->internal->draining && !got_frame) avci->draining_done = 1; avci->compat_decode_consumed += ret; if (ret >= pkt->size || ret < 0) { av_packet_unref(pkt); } else { int consumed = ret; pkt->data += consumed; pkt->size -= consumed; pkt->pts = AV_NOPTS_VALUE; pkt->dts = AV_NOPTS_VALUE; avci->last_pkt_props->pts = AV_NOPTS_VALUE; avci->last_pkt_props->dts = AV_NOPTS_VALUE; } if (got_frame) av_assert0(frame->buf[0]); return ret < 0 ? ret : 0; }
void ff_faandct(int16_t *data) { FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; FLOAT tmp10, tmp11, tmp12, tmp13; FLOAT z2, z4, z11, z13; FLOAT temp[64]; int i; emms_c(); row_fdct(temp, data); for (i=0; i<8; i++) { tmp0= temp[8*0 + i] + temp[8*7 + i]; tmp7= temp[8*0 + i] - temp[8*7 + i]; tmp1= temp[8*1 + i] + temp[8*6 + i]; tmp6= temp[8*1 + i] - temp[8*6 + i]; tmp2= temp[8*2 + i] + temp[8*5 + i]; tmp5= temp[8*2 + i] - temp[8*5 + i]; tmp3= temp[8*3 + i] + temp[8*4 + i]; tmp4= temp[8*3 + i] - temp[8*4 + i]; tmp10= tmp0 + tmp3; tmp13= tmp0 - tmp3; tmp11= tmp1 + tmp2; tmp12= tmp1 - tmp2; data[8*0 + i]= lrintf(postscale[8*0 + i] * (tmp10 + tmp11)); data[8*4 + i]= lrintf(postscale[8*4 + i] * (tmp10 - tmp11)); tmp12 += tmp13; tmp12 *= A1; data[8*2 + i]= lrintf(postscale[8*2 + i] * (tmp13 + tmp12)); data[8*6 + i]= lrintf(postscale[8*6 + i] * (tmp13 - tmp12)); tmp4 += tmp5; tmp5 += tmp6; tmp6 += tmp7; #if 0 { FLOAT z5; z5 = (tmp4 - tmp6) * A5; z2 = tmp4 * A2 + z5; z4 = tmp6 * A4 + z5; } #else z2= tmp4*(A2+A5) - tmp6*A5; z4= tmp6*(A4-A5) + tmp4*A5; #endif tmp5*=A1; z11= tmp7 + tmp5; z13= tmp7 - tmp5; data[8*5 + i]= lrintf(postscale[8*5 + i] * (z13 + z2)); data[8*3 + i]= lrintf(postscale[8*3 + i] * (z13 - z2)); data[8*1 + i]= lrintf(postscale[8*1 + i] * (z11 + z4)); data[8*7 + i]= lrintf(postscale[8*7 + i] * (z11 - z4)); } }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) { ASV1Context * const a = avctx->priv_data; AVFrame *picture = data; AVFrame * const p= (AVFrame*)&a->picture; int mb_x, mb_y; /* special case for last picture */ if (buf_size == 0) { return 0; } if(p->data[0]) avctx->release_buffer(avctx, p); p->reference= 0; if(avctx->get_buffer(avctx, p) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } p->pict_type= I_TYPE; p->key_frame= 1; a->bitstream_buffer= av_fast_realloc(a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); if(avctx->codec_id == CODEC_ID_ASV1) a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (uint32_t*)buf, buf_size/4); else{ int i; for(i=0; i<buf_size; i++) a->bitstream_buffer[i]= reverse[ buf[i] ]; } init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8); for(mb_y=0; mb_y<a->mb_height2; mb_y++){ for(mb_x=0; mb_x<a->mb_width2; mb_x++){ if( decode_mb(a, a->block) <0) return -1; idct_put(a, mb_x, mb_y); } } if(a->mb_width2 != a->mb_width){ mb_x= a->mb_width2; for(mb_y=0; mb_y<a->mb_height2; mb_y++){ if( decode_mb(a, a->block) <0) return -1; idct_put(a, mb_x, mb_y); } } if(a->mb_height2 != a->mb_height){ mb_y= a->mb_height2; for(mb_x=0; mb_x<a->mb_width; mb_x++){ if( decode_mb(a, a->block) <0) return -1; idct_put(a, mb_x, mb_y); } } #if 0 int i; printf("%d %d\n", 8*buf_size, get_bits_count(&a->gb)); for(i=get_bits_count(&a->gb); i<8*buf_size; i++){ printf("%d", get_bits1(&a->gb)); } for(i=0; i<s->avctx->extradata_size; i++){ printf("%c\n", ((uint8_t*)s->avctx->extradata)[i]); } #endif *picture= *(AVFrame*)&a->picture; *data_size = sizeof(AVPicture); emms_c(); return (get_bits_count(&a->gb)+31)/32*4; }
static int fir_quantum(AVFilterContext *ctx, AVFrame *out, int ch, int offset) { AudioFIRContext *s = ctx->priv; const float *in = (const float *)s->in[0]->extended_data[ch] + offset; float *block, *buf, *ptr = (float *)out->extended_data[ch] + offset; const int nb_samples = FFMIN(s->min_part_size, out->nb_samples - offset); int n, i, j; for (int segment = 0; segment < s->nb_segments; segment++) { AudioFIRSegment *seg = &s->seg[segment]; float *src = (float *)seg->input->extended_data[ch]; float *dst = (float *)seg->output->extended_data[ch]; float *sum = (float *)seg->sum->extended_data[ch]; s->fdsp->vector_fmul_scalar(src + seg->input_offset, in, s->dry_gain, FFALIGN(nb_samples, 4)); emms_c(); seg->output_offset[ch] += s->min_part_size; if (seg->output_offset[ch] == seg->part_size) { seg->output_offset[ch] = 0; } else { memmove(src, src + s->min_part_size, (seg->input_size - s->min_part_size) * sizeof(*src)); dst += seg->output_offset[ch]; for (n = 0; n < nb_samples; n++) { ptr[n] += dst[n]; } continue; } memset(sum, 0, sizeof(*sum) * seg->fft_length); block = (float *)seg->block->extended_data[ch] + seg->part_index[ch] * seg->block_size; memset(block + seg->part_size, 0, sizeof(*block) * (seg->fft_length - seg->part_size)); memcpy(block, src, sizeof(*src) * seg->part_size); av_rdft_calc(seg->rdft[ch], block); block[2 * seg->part_size] = block[1]; block[1] = 0; j = seg->part_index[ch]; for (i = 0; i < seg->nb_partitions; i++) { const int coffset = j * seg->coeff_size; const float *block = (const float *)seg->block->extended_data[ch] + i * seg->block_size; const FFTComplex *coeff = (const FFTComplex *)seg->coeff->extended_data[ch * !s->one2many] + coffset; s->afirdsp.fcmul_add(sum, block, (const float *)coeff, seg->part_size); if (j == 0) j = seg->nb_partitions; j--; } sum[1] = sum[2 * seg->part_size]; av_rdft_calc(seg->irdft[ch], sum); buf = (float *)seg->buffer->extended_data[ch]; for (n = 0; n < seg->part_size; n++) { buf[n] += sum[n]; } memcpy(dst, buf, seg->part_size * sizeof(*dst)); buf = (float *)seg->buffer->extended_data[ch]; memcpy(buf, sum + seg->part_size, seg->part_size * sizeof(*buf)); seg->part_index[ch] = (seg->part_index[ch] + 1) % seg->nb_partitions; memmove(src, src + s->min_part_size, (seg->input_size - s->min_part_size) * sizeof(*src)); for (n = 0; n < nb_samples; n++) { ptr[n] += dst[n]; } } s->fdsp->vector_fmul_scalar(ptr, ptr, s->wet_gain, FFALIGN(nb_samples, 4)); emms_c(); return 0; }
/** * \brief mjpeg encode an image * * This routine will take a 3-plane YUV422 image and encoded it with MJPEG * base line format, as suitable as input for the Zoran hardare MJPEG chips. * * It requires that the \a j parameter points the structure set up by the * jpeg_enc_init() routine. * * \param j pointer to jpeg_enc_t structure as created by jpeg_enc_init() * \param y_data pointer to Y component plane, packed one byte/pixel * \param u_data pointer to U component plane, packed one byte per every * other pixel * \param v_data pointer to V component plane, packed one byte per every * other pixel * \param bufr pointer to the buffer where the mjpeg encoded code is stored * * \returns the number of bytes stored into \a bufr * * If \a j->s->mjpeg_write_tables is set, it will also emit the mjpeg tables, * otherwise it will just emit the data. The \a j->s->mjpeg_write_tables * variable will be reset to 0 by the routine. */ static int jpeg_enc_frame(jpeg_enc_t *j, uint8_t *y_data, uint8_t *u_data, uint8_t *v_data, uint8_t *bufr) { int mb_x, mb_y, overflow; /* initialize the buffer */ init_put_bits(&j->s->pb, bufr, 1024*256); // Emit the mjpeg header blocks ff_mjpeg_encode_picture_header(j->s); j->s->header_bits = put_bits_count(&j->s->pb); j->s->last_dc[0] = 128; j->s->last_dc[1] = 128; j->s->last_dc[2] = 128; for (mb_y = 0; mb_y < j->s->mb_height; mb_y++) { for (mb_x = 0; mb_x < j->s->mb_width; mb_x++) { /* * Fill one DCT block (8x8 pixels) from * 2 Y macroblocks and one U and one V */ fill_block(j, mb_x, mb_y, y_data, u_data, v_data); emms_c(); /* is this really needed? */ j->s->block_last_index[0] = j->s->dct_quantize(j->s, j->s->block[0], 0, 8, &overflow); if (overflow) clip_coeffs(j->s, j->s->block[0], j->s->block_last_index[0]); j->s->block_last_index[1] = j->s->dct_quantize(j->s, j->s->block[1], 1, 8, &overflow); if (overflow) clip_coeffs(j->s, j->s->block[1], j->s->block_last_index[1]); if (!j->bw) { j->s->block_last_index[4] = j->s->dct_quantize(j->s, j->s->block[2], 4, 8, &overflow); if (overflow) clip_coeffs(j->s, j->s->block[2], j->s->block_last_index[2]); j->s->block_last_index[5] = j->s->dct_quantize(j->s, j->s->block[3], 5, 8, &overflow); if (overflow) clip_coeffs(j->s, j->s->block[3], j->s->block_last_index[3]); } zr_mjpeg_encode_mb(j); } } emms_c(); ff_mjpeg_encode_picture_trailer(j->s); flush_put_bits(&j->s->pb); //FIXME //if (j->s->mjpeg_write_tables == 1) // j->s->mjpeg_write_tables = 0; return put_bits_ptr(&(j->s->pb)) - j->s->pb.buf; }
static int multiple_resample(ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed){ int i; int av_unused mm_flags = av_get_cpu_flags(); int need_emms = c->format == AV_SAMPLE_FMT_S16P && ARCH_X86_32 && (mm_flags & (AV_CPU_FLAG_MMX2 | AV_CPU_FLAG_SSE2)) == AV_CPU_FLAG_MMX2; int64_t max_src_size = (INT64_MAX/2 / c->phase_count) / c->src_incr; if (c->compensation_distance) dst_size = FFMIN(dst_size, c->compensation_distance); src_size = FFMIN(src_size, max_src_size); *consumed = 0; if (c->filter_length == 1 && c->phase_count == 1) { int64_t index2= (1LL<<32)*c->frac/c->src_incr + (1LL<<32)*c->index; int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr; int new_size = (src_size * (int64_t)c->src_incr - c->frac + c->dst_incr - 1) / c->dst_incr; dst_size = FFMAX(FFMIN(dst_size, new_size), 0); if (dst_size > 0) { for (i = 0; i < dst->ch_count; i++) { c->dsp.resample_one(dst->ch[i], src->ch[i], dst_size, index2, incr); if (i+1 == dst->ch_count) { c->index += dst_size * c->dst_incr_div; c->index += (c->frac + dst_size * (int64_t)c->dst_incr_mod) / c->src_incr; av_assert2(c->index >= 0); *consumed = c->index; c->frac = (c->frac + dst_size * (int64_t)c->dst_incr_mod) % c->src_incr; c->index = 0; } } } } else { int64_t end_index = (1LL + src_size - c->filter_length) * c->phase_count; int64_t delta_frac = (end_index - c->index) * c->src_incr - c->frac; int delta_n = (delta_frac + c->dst_incr - 1) / c->dst_incr; int (*resample_func)(struct ResampleContext *c, void *dst, const void *src, int n, int update_ctx); dst_size = FFMAX(FFMIN(dst_size, delta_n), 0); if (dst_size > 0) { /* resample_linear and resample_common should have same behavior * when frac and dst_incr_mod are zero */ resample_func = (c->linear && (c->frac || c->dst_incr_mod)) ? c->dsp.resample_linear : c->dsp.resample_common; for (i = 0; i < dst->ch_count; i++) *consumed = resample_func(c, dst->ch[i], src->ch[i], dst_size, i+1 == dst->ch_count); } } if(need_emms) emms_c(); if (c->compensation_distance) { c->compensation_distance -= dst_size; if (!c->compensation_distance) { c->dst_incr = c->ideal_dst_incr; c->dst_incr_div = c->dst_incr / c->src_incr; c->dst_incr_mod = c->dst_incr % c->src_incr; } } return dst_size; }
av_cold int ff_rate_control_init(MpegEncContext *s) { RateControlContext *rcc = &s->rc_context; int i, res; static const char * const const_names[] = { "PI", "E", "iTex", "pTex", "tex", "mv", "fCode", "iCount", "mcVar", "var", "isI", "isP", "isB", "avgQP", "qComp", "avgIITex", "avgPITex", "avgPPTex", "avgBPTex", "avgTex", NULL }; static double (* const func1[])(void *, double) = { (void *)bits2qp, (void *)qp2bits, NULL }; static const char * const func1_names[] = { "bits2qp", "qp2bits", NULL }; emms_c(); res = av_expr_parse(&rcc->rc_eq_eval, s->rc_eq ? s->rc_eq : "tex^qComp", const_names, func1_names, func1, NULL, NULL, 0, s->avctx); if (res < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->rc_eq); return res; } for (i = 0; i < 5; i++) { rcc->pred[i].coeff = FF_QP2LAMBDA * 7.0; rcc->pred[i].count = 1.0; rcc->pred[i].decay = 0.4; rcc->i_cplx_sum [i] = rcc->p_cplx_sum [i] = rcc->mv_bits_sum[i] = rcc->qscale_sum [i] = rcc->frame_count[i] = 1; // 1 is better because of 1/0 and such rcc->last_qscale_for[i] = FF_QP2LAMBDA * 5; } rcc->buffer_index = s->avctx->rc_initial_buffer_occupancy; if (s->avctx->flags & AV_CODEC_FLAG_PASS2) { int i; char *p; /* find number of pics */ p = s->avctx->stats_in; for (i = -1; p; i++) p = strchr(p + 1, ';'); i += s->max_b_frames; if (i <= 0 || i >= INT_MAX / sizeof(RateControlEntry)) return -1; rcc->entry = av_mallocz(i * sizeof(RateControlEntry)); rcc->num_entries = i; if (!rcc->entry) return AVERROR(ENOMEM); /* init all to skipped P-frames * (with B-frames we might have a not encoded frame at the end FIXME) */ for (i = 0; i < rcc->num_entries; i++) { RateControlEntry *rce = &rcc->entry[i]; rce->pict_type = rce->new_pict_type = AV_PICTURE_TYPE_P; rce->qscale = rce->new_qscale = FF_QP2LAMBDA * 2; rce->misc_bits = s->mb_num + 10; rce->mb_var_sum = s->mb_num * 100; } /* read stats */ p = s->avctx->stats_in; for (i = 0; i < rcc->num_entries - s->max_b_frames; i++) { RateControlEntry *rce; int picture_number; int e; char *next; next = strchr(p, ';'); if (next) { (*next) = 0; // sscanf is unbelievably slow on looong strings // FIXME copy / do not write next++; } e = sscanf(p, " in:%d ", &picture_number); assert(picture_number >= 0); assert(picture_number < rcc->num_entries); rce = &rcc->entry[picture_number]; e += sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d", &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits, &rce->mv_bits, &rce->misc_bits, &rce->f_code, &rce->b_code, &rce->mc_mb_var_sum, &rce->mb_var_sum, &rce->i_count, &rce->skip_count, &rce->header_bits); if (e != 14) { av_log(s->avctx, AV_LOG_ERROR, "statistics are damaged at line %d, parser out=%d\n", i, e); return -1; } p = next; } if (init_pass2(s) < 0) { ff_rate_control_uninit(s); return -1; } } if (!(s->avctx->flags & AV_CODEC_FLAG_PASS2)) { rcc->short_term_qsum = 0.001; rcc->short_term_qcount = 0.001; rcc->pass1_rc_eq_output_sum = 0.001; rcc->pass1_wanted_bits = 0.001; if (s->avctx->qblur > 1.0) { av_log(s->avctx, AV_LOG_ERROR, "qblur too large\n"); return -1; } /* init stuff with the user specified complexity */ if (s->rc_initial_cplx) { for (i = 0; i < 60 * 30; i++) { double bits = s->rc_initial_cplx * (i / 10000.0 + 1.0) * s->mb_num; RateControlEntry rce; if (i % ((s->gop_size + 3) / 4) == 0) rce.pict_type = AV_PICTURE_TYPE_I; else if (i % (s->max_b_frames + 1)) rce.pict_type = AV_PICTURE_TYPE_B; else rce.pict_type = AV_PICTURE_TYPE_P; rce.new_pict_type = rce.pict_type; rce.mc_mb_var_sum = bits * s->mb_num / 100000; rce.mb_var_sum = s->mb_num; rce.qscale = FF_QP2LAMBDA * 2; rce.f_code = 2; rce.b_code = 1; rce.misc_bits = 1; if (s->pict_type == AV_PICTURE_TYPE_I) { rce.i_count = s->mb_num; rce.i_tex_bits = bits; rce.p_tex_bits = 0; rce.mv_bits = 0; } else { rce.i_count = 0; // FIXME we do know this approx rce.i_tex_bits = 0; rce.p_tex_bits = bits * 0.9; rce.mv_bits = bits * 0.1; } rcc->i_cplx_sum[rce.pict_type] += rce.i_tex_bits * rce.qscale; rcc->p_cplx_sum[rce.pict_type] += rce.p_tex_bits * rce.qscale; rcc->mv_bits_sum[rce.pict_type] += rce.mv_bits; rcc->frame_count[rce.pict_type]++; get_qscale(s, &rce, rcc->pass1_wanted_bits / rcc->pass1_rc_eq_output_sum, i); // FIXME misbehaves a little for variable fps rcc->pass1_wanted_bits += s->bit_rate / (1 / av_q2d(s->avctx->time_base)); } } } return 0; }
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { ASV1Context * const a = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AVFrame * const p = data; int mb_x, mb_y, ret; if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size); if (!a->bitstream_buffer) return AVERROR(ENOMEM); if (avctx->codec_id == AV_CODEC_ID_ASV1) a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (const uint32_t*)buf, buf_size/4); else { int i; for (i = 0; i < buf_size; i++) a->bitstream_buffer[i] = ff_reverse[buf[i]]; } init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8); for (mb_y = 0; mb_y < a->mb_height2; mb_y++) { for (mb_x = 0; mb_x < a->mb_width2; mb_x++) { if ((ret = decode_mb(a, a->block)) < 0) return ret; idct_put(a, p, mb_x, mb_y); } } if (a->mb_width2 != a->mb_width) { mb_x = a->mb_width2; for (mb_y = 0; mb_y < a->mb_height2; mb_y++) { if ((ret = decode_mb(a, a->block)) < 0) return ret; idct_put(a, p, mb_x, mb_y); } } if (a->mb_height2 != a->mb_height) { mb_y = a->mb_height2; for (mb_x = 0; mb_x < a->mb_width; mb_x++) { if ((ret = decode_mb(a, a->block)) < 0) return ret; idct_put(a, p, mb_x, mb_y); } } *got_frame = 1; emms_c(); return (get_bits_count(&a->gb) + 31) / 32 * 4; }
/** * Find the most likely shift in motion between two frames for a given * macroblock. Test each block against several shifts given by the rx * and ry attributes. Searches using a simple matrix of those shifts and * chooses the most likely shift by the smallest difference in blocks. */ static void find_block_motion(DeshakeContext *deshake, uint8_t *src1, uint8_t *src2, int cx, int cy, int stride, IntMotionVector *mv) { int x, y; int diff; int smallest = INT_MAX; int tmp, tmp2; #define CMP(i, j) deshake->c.sad[0](NULL, src1 + cy * stride + cx, \ src2 + (j) * stride + (i), stride, \ deshake->blocksize) if (deshake->search == EXHAUSTIVE) { // Compare every possible position - this is sloooow! for (y = -deshake->ry; y <= deshake->ry; y++) { for (x = -deshake->rx; x <= deshake->rx; x++) { diff = CMP(cx - x, cy - y); if (diff < smallest) { smallest = diff; mv->x = x; mv->y = y; } } } } else if (deshake->search == SMART_EXHAUSTIVE) { // Compare every other possible position and find the best match for (y = -deshake->ry + 1; y < deshake->ry; y += 2) { for (x = -deshake->rx + 1; x < deshake->rx; x += 2) { diff = CMP(cx - x, cy - y); if (diff < smallest) { smallest = diff; mv->x = x; mv->y = y; } } } // Hone in on the specific best match around the match we found above tmp = mv->x; tmp2 = mv->y; for (y = tmp2 - 1; y <= tmp2 + 1; y++) { for (x = tmp - 1; x <= tmp + 1; x++) { if (x == tmp && y == tmp2) continue; diff = CMP(cx - x, cy - y); if (diff < smallest) { smallest = diff; mv->x = x; mv->y = y; } } } } if (smallest > 512) { mv->x = -1; mv->y = -1; } emms_c(); //av_log(NULL, AV_LOG_ERROR, "%d\n", smallest); //av_log(NULL, AV_LOG_ERROR, "Final: (%d, %d) = %d x %d\n", cx, cy, mv->x, mv->y); }
static int filter_frame(AVFilterLink *inlink, AVFrame *buf) { VolumeContext *vol = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; int nb_samples = buf->nb_samples; AVFrame *out_buf; AVFrameSideData *sd = av_frame_get_side_data(buf, AV_FRAME_DATA_REPLAYGAIN); int ret; if (sd && vol->replaygain != REPLAYGAIN_IGNORE) { if (vol->replaygain != REPLAYGAIN_DROP) { AVReplayGain *replaygain = (AVReplayGain*)sd->data; int32_t gain = 100000; uint32_t peak = 100000; float g, p; if (vol->replaygain == REPLAYGAIN_TRACK && replaygain->track_gain != INT32_MIN) { gain = replaygain->track_gain; if (replaygain->track_peak != 0) peak = replaygain->track_peak; } else if (replaygain->album_gain != INT32_MIN) { gain = replaygain->album_gain; if (replaygain->album_peak != 0) peak = replaygain->album_peak; } else { av_log(inlink->dst, AV_LOG_WARNING, "Both ReplayGain gain " "values are unknown.\n"); } g = gain / 100000.0f; p = peak / 100000.0f; av_log(inlink->dst, AV_LOG_VERBOSE, "Using gain %f dB from replaygain side data.\n", g); vol->volume = pow(10, (g + vol->replaygain_preamp) / 20); if (vol->replaygain_noclip) vol->volume = FFMIN(vol->volume, 1.0 / p); vol->volume_i = (int)(vol->volume * 256 + 0.5); volume_init(vol); } av_frame_remove_side_data(buf, AV_FRAME_DATA_REPLAYGAIN); } if (vol->volume == 1.0 || vol->volume_i == 256) return ff_filter_frame(outlink, buf); /* do volume scaling in-place if input buffer is writable */ if (av_frame_is_writable(buf)) { out_buf = buf; } else { out_buf = ff_get_audio_buffer(inlink, nb_samples); if (!out_buf) return AVERROR(ENOMEM); ret = av_frame_copy_props(out_buf, buf); if (ret < 0) { av_frame_free(&out_buf); av_frame_free(&buf); return ret; } } if (vol->precision != PRECISION_FIXED || vol->volume_i > 0) { int p, plane_samples; if (av_sample_fmt_is_planar(buf->format)) plane_samples = FFALIGN(nb_samples, vol->samples_align); else plane_samples = FFALIGN(nb_samples * vol->channels, vol->samples_align); if (vol->precision == PRECISION_FIXED) { for (p = 0; p < vol->planes; p++) { vol->scale_samples(out_buf->extended_data[p], buf->extended_data[p], plane_samples, vol->volume_i); } } else if (av_get_packed_sample_fmt(vol->sample_fmt) == AV_SAMPLE_FMT_FLT) { for (p = 0; p < vol->planes; p++) { vol->fdsp.vector_fmul_scalar((float *)out_buf->extended_data[p], (const float *)buf->extended_data[p], vol->volume, plane_samples); } } else { for (p = 0; p < vol->planes; p++) { vol->fdsp.vector_dmul_scalar((double *)out_buf->extended_data[p], (const double *)buf->extended_data[p], vol->volume, plane_samples); } } } emms_c(); if (buf != out_buf) av_frame_free(&buf); return ff_filter_frame(outlink, out_buf); }
float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run) { float q; int qmin, qmax; float br_compensation; double diff; double short_term_q; double fps; int picture_number= s->picture_number; int64_t wanted_bits; RateControlContext *rcc= &s->rc_context; AVCodecContext *a= s->avctx; RateControlEntry local_rce, *rce; double bits; double rate_factor; int var; const int pict_type= s->pict_type; Picture * const pic= &s->current_picture; emms_c(); #if CONFIG_LIBXVID if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) return ff_xvid_rate_estimate_qscale(s, dry_run); #endif get_qminmax(&qmin, &qmax, s, pict_type, picture_number); fps= 1/av_q2d(s->avctx->time_base); //printf("input_pic_num:%d pic_num:%d frame_rate:%d\n", s->input_picture_number, s->picture_number, s->frame_rate); /* update predictors */ if(picture_number>2 && !dry_run){ const int last_var= s->last_pict_type == FF_I_TYPE ? rcc->last_mb_var_sum : rcc->last_mc_mb_var_sum; update_predictor(&rcc->pred[s->last_pict_type], rcc->last_qscale, sqrt(last_var), s->frame_bits); } if(s->flags&CODEC_FLAG_PASS2){ assert(picture_number>=0); assert(picture_number<rcc->num_entries); rce= &rcc->entry[picture_number]; wanted_bits= rce->expected_bits; }else{ Picture *dts_pic; rce= &local_rce; //FIXME add a dts field to AVFrame and ensure its set and use it here instead of reordering //but the reordering is simpler for now until h.264 b pyramid must be handeld if(s->pict_type == FF_B_TYPE || s->low_delay) dts_pic= s->current_picture_ptr; else dts_pic= s->last_picture_ptr; //if(dts_pic) // av_log(NULL, AV_LOG_ERROR, "%Ld %Ld %Ld %d\n", s->current_picture_ptr->pts, s->user_specified_pts, dts_pic->pts, picture_number); if(!dts_pic || dts_pic->pts == AV_NOPTS_VALUE) wanted_bits= (uint64_t)(s->bit_rate*(double)picture_number/fps); else wanted_bits= (uint64_t)(s->bit_rate*(double)dts_pic->pts/fps); } diff= s->total_bits - wanted_bits; br_compensation= (a->bit_rate_tolerance - diff)/a->bit_rate_tolerance; if(br_compensation<=0.0) br_compensation=0.001; var= pict_type == FF_I_TYPE ? pic->mb_var_sum : pic->mc_mb_var_sum; short_term_q = 0; /* avoid warning */ if(s->flags&CODEC_FLAG_PASS2){ if(pict_type!=FF_I_TYPE) assert(pict_type == rce->new_pict_type); q= rce->new_qscale / br_compensation; //printf("%f %f %f last:%d var:%d type:%d//\n", q, rce->new_qscale, br_compensation, s->frame_bits, var, pict_type); }else{ rce->pict_type= rce->new_pict_type= pict_type; rce->mc_mb_var_sum= pic->mc_mb_var_sum; rce->mb_var_sum = pic-> mb_var_sum; rce->qscale = FF_QP2LAMBDA * 2; rce->f_code = s->f_code; rce->b_code = s->b_code; rce->misc_bits= 1; bits= predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var)); if(pict_type== FF_I_TYPE){ rce->i_count = s->mb_num; rce->i_tex_bits= bits; rce->p_tex_bits= 0; rce->mv_bits= 0; }else{ rce->i_count = 0; //FIXME we do know this approx rce->i_tex_bits= 0; rce->p_tex_bits= bits*0.9; rce->mv_bits= bits*0.1; } rcc->i_cplx_sum [pict_type] += rce->i_tex_bits*rce->qscale; rcc->p_cplx_sum [pict_type] += rce->p_tex_bits*rce->qscale; rcc->mv_bits_sum[pict_type] += rce->mv_bits; rcc->frame_count[pict_type] ++; bits= rce->i_tex_bits + rce->p_tex_bits; rate_factor= rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum * br_compensation; q= get_qscale(s, rce, rate_factor, picture_number); if (q < 0) return -1; assert(q>0.0); //printf("%f ", q); q= get_diff_limited_q(s, rce, q); //printf("%f ", q); assert(q>0.0); if(pict_type==FF_P_TYPE || s->intra_only){ //FIXME type dependent blur like in 2-pass rcc->short_term_qsum*=a->qblur; rcc->short_term_qcount*=a->qblur; rcc->short_term_qsum+= q; rcc->short_term_qcount++; //printf("%f ", q); q= short_term_q= rcc->short_term_qsum/rcc->short_term_qcount; //printf("%f ", q); } assert(q>0.0); q= modify_qscale(s, rce, q, picture_number); rcc->pass1_wanted_bits+= s->bit_rate/fps; assert(q>0.0); } if(s->avctx->debug&FF_DEBUG_RC){ av_log(s->avctx, AV_LOG_DEBUG, "%c qp:%d<%2.1f<%d %d want:%d total:%d comp:%f st_q:%2.2f size:%d var:%d/%d br:%d fps:%d\n", av_get_pict_type_char(pict_type), qmin, q, qmax, picture_number, (int)wanted_bits/1000, (int)s->total_bits/1000, br_compensation, short_term_q, s->frame_bits, pic->mb_var_sum, pic->mc_mb_var_sum, s->bit_rate/1000, (int)fps ); } if (q<qmin) q=qmin; else if(q>qmax) q=qmax; if(s->adaptive_quant) ff_adaptive_quantization(s, q); else q= (int)(q + 0.5); if(!dry_run){ rcc->last_qscale= q; rcc->last_mc_mb_var_sum= pic->mc_mb_var_sum; rcc->last_mb_var_sum= pic->mb_var_sum; } #if 0 { static int mvsum=0, texsum=0; mvsum += s->mv_bits; texsum += s->i_tex_bits + s->p_tex_bits; printf("%d %d//\n\n", mvsum, texsum); } #endif return q; }
int jpeg_enc_frame(jpeg_enc_t *j, unsigned char *y_data, unsigned char *u_data, unsigned char *v_data, char *bufr) { int i, k, mb_x, mb_y, overflow; short int *dest; unsigned char *source; /* initialize the buffer */ init_put_bits(&j->s->pb, bufr, 1024*256); ff_mjpeg_encode_picture_header(j->s); j->s->header_bits = put_bits_count(&j->s->pb); j->s->last_dc[0] = 128; j->s->last_dc[1] = 128; j->s->last_dc[2] = 128; for (mb_y = 0; mb_y < j->s->mb_height; mb_y++) { for (mb_x = 0; mb_x < j->s->mb_width; mb_x++) { /* conversion 8 to 16 bit and filling of blocks * must be mmx optimized */ /* fill 2 Y macroblocks and one U and one V */ source = mb_y * 8 * j->y_rs + 16 * j->y_ps * mb_x + y_data; dest = j->s->block[0]; for (i = 0; i < 8; i++) { for (k = 0; k < 8; k++) { dest[k] = source[k*j->y_ps]; } dest += 8; source += j->y_rs; } source = mb_y * 8 * j->y_rs + (16*mb_x + 8)*j->y_ps + y_data; dest = j->s->block[1]; for (i = 0; i < 8; i++) { for (k = 0; k < 8; k++) { dest[k] = source[k*j->y_ps]; } dest += 8; source += j->y_rs; } if (!j->bw && j->cheap_upsample) { source = mb_y*4*j->u_rs + 8*mb_x*j->u_ps + u_data; dest = j->s->block[2]; for (i = 0; i < 4; i++) { for (k = 0; k < 8; k++) { dest[k] = source[k*j->u_ps]; dest[k+8] = source[k*j->u_ps]; } dest += 16; source += j->u_rs; } source = mb_y*4*j->v_rs + 8*mb_x*j->v_ps + v_data; dest = j->s->block[3]; for (i = 0; i < 4; i++) { for (k = 0; k < 8; k++) { dest[k] = source[k*j->v_ps]; dest[k+8] = source[k*j->v_ps]; } dest += 16; source += j->u_rs; } } else if (!j->bw && !j->cheap_upsample) { source = mb_y*8*j->u_rs + 8*mb_x*j->u_ps + u_data; dest = j->s->block[2]; for (i = 0; i < 8; i++) { for (k = 0; k < 8; k++) dest[k] = source[k*j->u_ps]; dest += 8; source += j->u_rs; } source = mb_y*8*j->v_rs + 8*mb_x*j->v_ps + v_data; dest = j->s->block[3]; for (i = 0; i < 8; i++) { for (k = 0; k < 8; k++) dest[k] = source[k*j->v_ps]; dest += 8; source += j->u_rs; } } emms_c(); /* is this really needed? */ j->s->block_last_index[0] = j->s->dct_quantize(j->s, j->s->block[0], 0, 8, &overflow); if (overflow) clip_coeffs(j->s, j->s->block[0], j->s->block_last_index[0]); j->s->block_last_index[1] = j->s->dct_quantize(j->s, j->s->block[1], 1, 8, &overflow); if (overflow) clip_coeffs(j->s, j->s->block[1], j->s->block_last_index[1]); if (!j->bw) { j->s->block_last_index[4] = j->s->dct_quantize(j->s, j->s->block[2], 4, 8, &overflow); if (overflow) clip_coeffs(j->s, j->s->block[2], j->s->block_last_index[2]); j->s->block_last_index[5] = j->s->dct_quantize(j->s, j->s->block[3], 5, 8, &overflow); if (overflow) clip_coeffs(j->s, j->s->block[3], j->s->block_last_index[3]); } zr_mjpeg_encode_mb(j); } } emms_c(); ff_mjpeg_encode_picture_trailer(j->s); flush_put_bits(&j->s->pb); //FIXME //if (j->s->mjpeg_write_tables == 1) // j->s->mjpeg_write_tables = 0; return pbBufPtr(&(j->s->pb)) - j->s->pb.buf; }