You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-04 22:03:09 +02:00
avcodec/mpegvideo: Move ratecontrol-adjacent fields to MPVMainEncContext
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
@ -101,7 +101,6 @@ typedef struct MpegEncContext {
|
||||
int h263_flv; ///< use flv H.263 header
|
||||
|
||||
enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */
|
||||
int fixed_qscale; ///< fixed qscale if non zero
|
||||
int encoding; ///< true if we are encoding (vs decoding)
|
||||
int max_b_frames; ///< max number of B-frames for encoding
|
||||
int luma_elim_threshold;
|
||||
@ -478,10 +477,6 @@ typedef struct MpegEncContext {
|
||||
me_cmp_func sse_cmp[2];
|
||||
int (*sum_abs_dctelem)(const int16_t *block);
|
||||
|
||||
float border_masking;
|
||||
int lmin, lmax;
|
||||
int vbv_ignore_qmax;
|
||||
|
||||
/// Bitfield containing information which frames to reconstruct.
|
||||
int frame_reconstruction_bitfield;
|
||||
|
||||
@ -493,7 +488,6 @@ typedef struct MpegEncContext {
|
||||
|
||||
int error_rate;
|
||||
|
||||
int scenechange_threshold;
|
||||
int noise_reduction;
|
||||
|
||||
int intra_penalty;
|
||||
|
@ -195,8 +195,10 @@ void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64],
|
||||
}
|
||||
}
|
||||
|
||||
static inline void update_qscale(MpegEncContext *s)
|
||||
static inline void update_qscale(MPVMainEncContext *const m)
|
||||
{
|
||||
MpegEncContext *const s = &m->s;
|
||||
|
||||
if (s->q_scale_type == 1 && 0) {
|
||||
int i;
|
||||
int bestdiff=INT_MAX;
|
||||
@ -205,7 +207,7 @@ static inline void update_qscale(MpegEncContext *s)
|
||||
for (i = 0 ; i<FF_ARRAY_ELEMS(ff_mpeg2_non_linear_qscale); i++) {
|
||||
int diff = FFABS((ff_mpeg2_non_linear_qscale[i]<<(FF_LAMBDA_SHIFT + 6)) - (int)s->lambda * 139);
|
||||
if (ff_mpeg2_non_linear_qscale[i] < s->avctx->qmin ||
|
||||
(ff_mpeg2_non_linear_qscale[i] > s->avctx->qmax && !s->vbv_ignore_qmax))
|
||||
(ff_mpeg2_non_linear_qscale[i] > s->avctx->qmax && !m->vbv_ignore_qmax))
|
||||
continue;
|
||||
if (diff < bestdiff) {
|
||||
bestdiff = diff;
|
||||
@ -216,7 +218,7 @@ static inline void update_qscale(MpegEncContext *s)
|
||||
} else {
|
||||
s->qscale = (s->lambda * 139 + FF_LAMBDA_SCALE * 64) >>
|
||||
(FF_LAMBDA_SHIFT + 7);
|
||||
s->qscale = av_clip(s->qscale, s->avctx->qmin, s->vbv_ignore_qmax ? 31 : s->avctx->qmax);
|
||||
s->qscale = av_clip(s->qscale, s->avctx->qmin, m->vbv_ignore_qmax ? 31 : s->avctx->qmax);
|
||||
}
|
||||
|
||||
s->lambda2 = (s->lambda * s->lambda + FF_LAMBDA_SCALE / 2) >>
|
||||
@ -507,16 +509,16 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
|
||||
}
|
||||
|
||||
/* Fixed QSCALE */
|
||||
s->fixed_qscale = !!(avctx->flags & AV_CODEC_FLAG_QSCALE);
|
||||
m->fixed_qscale = !!(avctx->flags & AV_CODEC_FLAG_QSCALE);
|
||||
|
||||
s->adaptive_quant = (avctx->lumi_masking ||
|
||||
avctx->dark_masking ||
|
||||
avctx->temporal_cplx_masking ||
|
||||
avctx->spatial_cplx_masking ||
|
||||
avctx->p_masking ||
|
||||
s->border_masking ||
|
||||
m->border_masking ||
|
||||
(s->mpv_flags & FF_MPV_FLAG_QP_RD)) &&
|
||||
!s->fixed_qscale;
|
||||
!m->fixed_qscale;
|
||||
|
||||
s->loop_filter = !!(avctx->flags & AV_CODEC_FLAG_LOOP_FILTER);
|
||||
|
||||
@ -580,7 +582,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
if (!s->fixed_qscale &&
|
||||
if (!m->fixed_qscale &&
|
||||
avctx->bit_rate * av_q2d(avctx->time_base) >
|
||||
avctx->bit_rate_tolerance) {
|
||||
double nbt = avctx->bit_rate * av_q2d(avctx->time_base) * 5;
|
||||
@ -675,7 +677,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
if (s->scenechange_threshold < 1000000000 &&
|
||||
if (m->scenechange_threshold < 1000000000 &&
|
||||
(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP)) {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"closed gop with scene change detection are not supported yet, "
|
||||
@ -890,9 +892,9 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
|
||||
s->frame_reconstruction_bitfield = 0;
|
||||
}
|
||||
|
||||
if (s->lmin > s->lmax) {
|
||||
av_log(avctx, AV_LOG_WARNING, "Clipping lmin value to %d\n", s->lmax);
|
||||
s->lmin = s->lmax;
|
||||
if (m->lmin > m->lmax) {
|
||||
av_log(avctx, AV_LOG_WARNING, "Clipping lmin value to %d\n", m->lmax);
|
||||
m->lmin = m->lmax;
|
||||
}
|
||||
|
||||
/* init */
|
||||
@ -1876,7 +1878,7 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
|
||||
|
||||
ff_mpv_unref_picture(&s->cur_pic);
|
||||
|
||||
s->vbv_ignore_qmax = 0;
|
||||
m->vbv_ignore_qmax = 0;
|
||||
|
||||
m->picture_in_gop_number++;
|
||||
|
||||
@ -1935,7 +1937,7 @@ vbv_retry:
|
||||
int min_step = hq ? 1 : (1<<(FF_LAMBDA_SHIFT + 7))/139;
|
||||
|
||||
if (put_bits_count(&s->pb) > max_size &&
|
||||
s->lambda < s->lmax) {
|
||||
s->lambda < m->lmax) {
|
||||
m->next_lambda = FFMAX(s->lambda + min_step, s->lambda *
|
||||
(s->qscale + 1) / s->qscale);
|
||||
if (s->adaptive_quant) {
|
||||
@ -1955,7 +1957,7 @@ vbv_retry:
|
||||
s->time_base = s->last_time_base;
|
||||
s->last_non_b_time = s->time - s->pp_time;
|
||||
}
|
||||
s->vbv_ignore_qmax = 1;
|
||||
m->vbv_ignore_qmax = 1;
|
||||
av_log(avctx, AV_LOG_VERBOSE, "reencoding frame due to VBV\n");
|
||||
goto vbv_retry;
|
||||
}
|
||||
@ -3616,7 +3618,7 @@ static int estimate_qp(MPVMainEncContext *const m, int dry_run)
|
||||
if (m->next_lambda){
|
||||
s->cur_pic.ptr->f->quality = m->next_lambda;
|
||||
if(!dry_run) m->next_lambda= 0;
|
||||
} else if (!s->fixed_qscale) {
|
||||
} else if (!m->fixed_qscale) {
|
||||
int quality = ff_rate_estimate_qscale(m, dry_run);
|
||||
s->cur_pic.ptr->f->quality = quality;
|
||||
if (s->cur_pic.ptr->f->quality < 0)
|
||||
@ -3643,7 +3645,7 @@ static int estimate_qp(MPVMainEncContext *const m, int dry_run)
|
||||
//FIXME broken
|
||||
}else
|
||||
s->lambda = s->cur_pic.ptr->f->quality;
|
||||
update_qscale(s);
|
||||
update_qscale(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3700,7 +3702,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
|
||||
s->lambda= s->last_lambda_for[s->pict_type];
|
||||
else
|
||||
s->lambda= s->last_lambda_for[s->last_non_b_pict_type];
|
||||
update_qscale(s);
|
||||
update_qscale(m);
|
||||
}
|
||||
|
||||
ff_me_init_pic(s);
|
||||
@ -3742,7 +3744,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
|
||||
for(i=0; i<s->mb_stride*s->mb_height; i++)
|
||||
s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA;
|
||||
|
||||
if(!s->fixed_qscale){
|
||||
if (!m->fixed_qscale) {
|
||||
/* finding spatial complexity for I-frame rate control */
|
||||
s->avctx->execute(s->avctx, mb_var_thread, &s->thread_context[0], NULL, context_count, sizeof(void*));
|
||||
}
|
||||
@ -3754,7 +3756,7 @@ static int encode_picture(MPVMainEncContext *const m, const AVPacket *pkt)
|
||||
s->mb_var_sum = s->me. mb_var_sum_temp;
|
||||
emms_c();
|
||||
|
||||
if (s->me.scene_change_score > s->scenechange_threshold &&
|
||||
if (s->me.scene_change_score > m->scenechange_threshold &&
|
||||
s->pict_type == AV_PICTURE_TYPE_P) {
|
||||
s->pict_type= AV_PICTURE_TYPE_I;
|
||||
for(i=0; i<s->mb_stride*s->mb_height; i++)
|
||||
|
@ -61,6 +61,12 @@ typedef struct MPVMainEncContext {
|
||||
int b_sensitivity;
|
||||
int brd_scale;
|
||||
|
||||
int scenechange_threshold;
|
||||
|
||||
float border_masking;
|
||||
int lmin, lmax;
|
||||
int vbv_ignore_qmax;
|
||||
|
||||
/* frame skip options */
|
||||
int frame_skip_threshold;
|
||||
int frame_skip_factor;
|
||||
@ -73,6 +79,7 @@ typedef struct MPVMainEncContext {
|
||||
int frame_bits; ///< bits used for the current frame
|
||||
int stuffing_bits; ///< bits used for stuffing
|
||||
int next_lambda; ///< next lambda used for retrying to encode a frame
|
||||
int fixed_qscale; ///< fixed qscale if non zero
|
||||
RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c
|
||||
} MPVMainEncContext;
|
||||
|
||||
@ -154,14 +161,14 @@ FF_MPV_OPT_CMP_FUNC, \
|
||||
FF_RC_OFFSET(rc_eq), AV_OPT_TYPE_STRING, .flags = FF_MPV_OPT_FLAGS }, \
|
||||
{"rc_init_cplx", "initial complexity for 1-pass encoding", FF_RC_OFFSET(initial_cplx), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
|
||||
{"rc_buf_aggressivity", "currently useless", FF_RC_OFFSET(buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
|
||||
{"border_mask", "increase the quantizer for macroblocks close to borders", FF_MPV_OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
|
||||
{"lmin", "minimum Lagrange factor (VBR)", FF_MPV_OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 = 2*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS }, \
|
||||
{"lmax", "maximum Lagrange factor (VBR)", FF_MPV_OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS }, \
|
||||
{"border_mask", "increase the quantizer for macroblocks close to borders", FF_MPV_MAIN_OFFSET(border_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, FF_MPV_OPT_FLAGS}, \
|
||||
{"lmin", "minimum Lagrange factor (VBR)", FF_MPV_MAIN_OFFSET(lmin), AV_OPT_TYPE_INT, {.i64 = 2*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS }, \
|
||||
{"lmax", "maximum Lagrange factor (VBR)", FF_MPV_MAIN_OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, FF_MPV_OPT_FLAGS }, \
|
||||
{"skip_threshold", "Frame skip threshold", FF_MPV_MAIN_OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
|
||||
{"skip_factor", "Frame skip factor", FF_MPV_MAIN_OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
|
||||
{"skip_exp", "Frame skip exponent", FF_MPV_MAIN_OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
|
||||
{"skip_cmp", "Frame skip compare function", FF_MPV_MAIN_OFFSET(frame_skip_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, .unit = "cmp_func" }, \
|
||||
{"sc_threshold", "Scene change threshold", FF_MPV_OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
|
||||
{"sc_threshold", "Scene change threshold", FF_MPV_MAIN_OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
|
||||
{"noise_reduction", "Noise reduction", FF_MPV_OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
|
||||
{"ps", "RTP payload size in bytes", FF_MPV_OFFSET(rtp_payload_size), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS }, \
|
||||
|
||||
|
@ -142,10 +142,11 @@ static double get_diff_limited_q(MPVMainEncContext *m, const RateControlEntry *r
|
||||
/**
|
||||
* Get the qmin & qmax for pict_type.
|
||||
*/
|
||||
static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pict_type)
|
||||
static void get_qminmax(int *qmin_ret, int *qmax_ret, MPVMainEncContext *const m, int pict_type)
|
||||
{
|
||||
int qmin = s->lmin;
|
||||
int qmax = s->lmax;
|
||||
MpegEncContext *const s = &m->s;
|
||||
int qmin = m->lmin;
|
||||
int qmax = m->lmax;
|
||||
|
||||
av_assert0(qmin <= qmax);
|
||||
|
||||
@ -182,7 +183,7 @@ static double modify_qscale(MPVMainEncContext *const m, const RateControlEntry *
|
||||
const int pict_type = rce->new_pict_type;
|
||||
int qmin, qmax;
|
||||
|
||||
get_qminmax(&qmin, &qmax, s, pict_type);
|
||||
get_qminmax(&qmin, &qmax, m, pict_type);
|
||||
|
||||
/* modulation */
|
||||
if (rcc->qmod_freq &&
|
||||
@ -784,15 +785,16 @@ static void update_predictor(Predictor *p, double q, double var, double size)
|
||||
}
|
||||
|
||||
static void adaptive_quantization(RateControlContext *const rcc,
|
||||
MpegEncContext *const s, double q)
|
||||
MPVMainEncContext *const m, double q)
|
||||
{
|
||||
MpegEncContext *const s = &m->s;
|
||||
int i;
|
||||
const float lumi_masking = s->avctx->lumi_masking / (128.0 * 128.0);
|
||||
const float dark_masking = s->avctx->dark_masking / (128.0 * 128.0);
|
||||
const float temp_cplx_masking = s->avctx->temporal_cplx_masking;
|
||||
const float spatial_cplx_masking = s->avctx->spatial_cplx_masking;
|
||||
const float p_masking = s->avctx->p_masking;
|
||||
const float border_masking = s->border_masking;
|
||||
const float border_masking = m->border_masking;
|
||||
float bits_sum = 0.0;
|
||||
float cplx_sum = 0.0;
|
||||
float *cplx_tab = rcc->cplx_tab;
|
||||
@ -932,7 +934,7 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
|
||||
const int pict_type = s->pict_type;
|
||||
emms_c();
|
||||
|
||||
get_qminmax(&qmin, &qmax, s, pict_type);
|
||||
get_qminmax(&qmin, &qmax, m, pict_type);
|
||||
|
||||
fps = get_fps(s->avctx);
|
||||
/* update predictors */
|
||||
@ -1068,7 +1070,7 @@ float ff_rate_estimate_qscale(MPVMainEncContext *const m, int dry_run)
|
||||
q = qmax;
|
||||
|
||||
if (s->adaptive_quant)
|
||||
adaptive_quantization(rcc, s, q);
|
||||
adaptive_quantization(rcc, m, q);
|
||||
else
|
||||
q = (int)(q + 0.5);
|
||||
|
||||
|
@ -228,8 +228,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
|
||||
|
||||
mpv->avctx = avctx;
|
||||
mpv->bit_rate= avctx->bit_rate;
|
||||
mpv->lmin = avctx->mb_lmin;
|
||||
mpv->lmax = avctx->mb_lmax;
|
||||
enc->m.lmin = avctx->mb_lmin;
|
||||
enc->m.lmax = avctx->mb_lmax;
|
||||
mpv->mb_num = (avctx->width * avctx->height + 255) / 256; // For ratecontrol
|
||||
|
||||
mpv->me.temp =
|
||||
|
Reference in New Issue
Block a user