From 45f19ed03d4c17dfbc0b8ab5e04fa9c1d11a6fe8 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Date: Tue, 18 Mar 2025 11:20:25 +0100 Subject: [PATCH 37/77] avcodec/mpegvideo: Move max_b_frames to MPVMainEncContext Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavcodec/mpeg4videoenc.c | 17 +++++++------- libavcodec/mpegvideo.h | 1 - libavcodec/mpegvideo_enc.c | 48 ++++++++++++++++++-------------------- libavcodec/mpegvideoenc.h | 1 + libavcodec/ratecontrol.c | 6 ++--- 5 files changed, 36 insertions(+), 37 deletions(-) diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c index 4f97199eba..d54064cd89 100644 --- a/libavcodec/mpeg4videoenc.c +++ b/libavcodec/mpeg4videoenc.c @@ -650,11 +650,11 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64], if ((cbp | motion_x | motion_y | s->dquant) == 0 && s->mv_type == MV_TYPE_16X16) { + const MPVMainEncContext *const m = slice_to_mainenc(s); /* Check if the B-frames can skip it too, as we must skip it * if we skip here why didn't they just compress * the skip-mb bits instead of reusing them ?! */ - if (s->max_b_frames > 0) { - int i; + if (m->max_b_frames > 0) { int x, y, offset; const uint8_t *p_pic; @@ -665,7 +665,7 @@ static void mpeg4_encode_mb(MpegEncContext *const s, int16_t block[][64], p_pic = s->new_pic->data[0] + offset; s->mb_skipped = 1; - for (i = 0; i < s->max_b_frames; i++) { + for (int i = 0; i < m->max_b_frames; i++) { const uint8_t *b_pic; int diff; const MPVPicture *pic = s->reordered_input_picture[i + 1]; @@ -929,14 +929,15 @@ static void mpeg4_encode_gop_header(MpegEncContext *s) ff_mpeg4_stuffing(&s->pb); } -static void mpeg4_encode_visual_object_header(MpegEncContext *s) +static void mpeg4_encode_visual_object_header(MPVMainEncContext *const m) { + MpegEncContext *const s = &m->s; int profile_and_level_indication; int vo_ver_id; if (s->avctx->profile != AV_PROFILE_UNKNOWN) { profile_and_level_indication = s->avctx->profile << 4; - } else if (s->max_b_frames || s->quarter_sample) { + } else if (m->max_b_frames || s->quarter_sample) { profile_and_level_indication = 0xF0; // adv simple } else { profile_and_level_indication = 0x00; // simple @@ -978,7 +979,7 @@ static void mpeg4_encode_vol_header(Mpeg4EncContext *const m4, MpegEncContext *const s = &m4->m.s; int vo_ver_id, vo_type, aspect_ratio_info; - if (s->max_b_frames || s->quarter_sample) { + if (m4->m.max_b_frames || s->quarter_sample) { vo_ver_id = 5; vo_type = ADV_SIMPLE_VO_TYPE; } else { @@ -1072,7 +1073,7 @@ static int mpeg4_encode_picture_header(MPVMainEncContext *const m) if (s->pict_type == AV_PICTURE_TYPE_I) { if (!(s->avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) { if (s->avctx->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT) // HACK, the reference sw is buggy - mpeg4_encode_visual_object_header(s); + mpeg4_encode_visual_object_header(m); if (s->avctx->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || s->picture_number == 0) // HACK, the reference sw is buggy mpeg4_encode_vol_header(m4, 0, 0); } @@ -1339,7 +1340,7 @@ static av_cold int encode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); init_put_bits(&s->pb, s->avctx->extradata, 1024); - mpeg4_encode_visual_object_header(s); + mpeg4_encode_visual_object_header(m); mpeg4_encode_vol_header(m4, 0, 0); // ff_mpeg4_stuffing(&s->pb); ? diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 04eade13aa..d25b5cdf3a 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -106,7 +106,6 @@ typedef struct MpegEncContext { enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */ int encoding; ///< true if we are encoding (vs decoding) - int max_b_frames; ///< max number of B-frames for encoding int luma_elim_threshold; int chroma_elim_threshold; int workaround_bugs; ///< workaround bugs in encoders which cannot be detected automatically diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 6650e5b35d..ffa652d02d 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -470,9 +470,9 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) "max b frames must be 0 or positive for mpegvideo based encoders\n"); return AVERROR(EINVAL); } - s->max_b_frames = avctx->max_b_frames; + m->max_b_frames = avctx->max_b_frames; s->codec_id = avctx->codec->id; - if (s->max_b_frames && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { + if (m->max_b_frames && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { av_log(avctx, AV_LOG_ERROR, "B-frames not supported by codec\n"); return AVERROR(EINVAL); } @@ -692,7 +692,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) "set strict_std_compliance to 'unofficial' or lower in order to allow it\n"); return AVERROR(EINVAL); } - if (s->max_b_frames != 0) { + if (m->max_b_frames != 0) { av_log(avctx, AV_LOG_ERROR, "B-frames cannot be used with low delay\n"); return AVERROR(EINVAL); @@ -744,7 +744,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) case AV_CODEC_ID_MPEG1VIDEO: s->out_format = FMT_MPEG1; s->low_delay = !!(avctx->flags & AV_CODEC_FLAG_LOW_DELAY); - avctx->delay = s->low_delay ? 0 : (s->max_b_frames + 1); + avctx->delay = s->low_delay ? 0 : (m->max_b_frames + 1); ff_mpeg1_encode_init(s); break; #endif @@ -834,8 +834,8 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) s->h263_pred = 1; s->unrestricted_mv = 1; s->flipflop_rounding = 1; - s->low_delay = s->max_b_frames ? 0 : 1; - avctx->delay = s->low_delay ? 0 : (s->max_b_frames + 1); + s->low_delay = m->max_b_frames ? 0 : 1; + avctx->delay = s->low_delay ? 0 : (m->max_b_frames + 1); break; case AV_CODEC_ID_MSMPEG4V2: s->out_format = FMT_H263; @@ -1013,7 +1013,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) return ret; if (m->b_frame_strategy == 2) { - for (i = 0; i < s->max_b_frames + 2; i++) { + for (int i = 0; i < m->max_b_frames + 2; i++) { m->tmp_frames[i] = av_frame_alloc(); if (!m->tmp_frames[i]) return AVERROR(ENOMEM); @@ -1255,7 +1255,7 @@ static int load_input_picture(MPVMainEncContext *const m, const AVFrame *pic_arg MPVPicture *pic = NULL; int64_t pts; int display_picture_number = 0, ret; - int encoding_delay = s->max_b_frames ? s->max_b_frames + int encoding_delay = m->max_b_frames ? m->max_b_frames : (s->low_delay ? 0 : 1); int flush_offset = 1; int direct = 1; @@ -1461,7 +1461,7 @@ static int estimate_best_b_count(MPVMainEncContext *const m) const int scale = m->brd_scale; int width = s->width >> scale; int height = s->height >> scale; - int i, j, out_size, p_lambda, b_lambda, lambda2; + int out_size, p_lambda, b_lambda, lambda2; int64_t best_rd = INT64_MAX; int best_b_count = -1; int ret = 0; @@ -1481,7 +1481,7 @@ static int estimate_best_b_count(MPVMainEncContext *const m) lambda2 = (b_lambda * b_lambda + (1 << FF_LAMBDA_SHIFT) / 2) >> FF_LAMBDA_SHIFT; - for (i = 0; i < s->max_b_frames + 2; i++) { + for (int i = 0; i < m->max_b_frames + 2; i++) { const MPVPicture *pre_input_ptr = i ? s->input_picture[i - 1] : s->next_pic.ptr; @@ -1513,7 +1513,7 @@ static int estimate_best_b_count(MPVMainEncContext *const m) } } - for (j = 0; j < s->max_b_frames + 1; j++) { + for (int j = 0; j < m->max_b_frames + 1; j++) { AVCodecContext *c; int64_t rd = 0; @@ -1536,7 +1536,7 @@ static int estimate_best_b_count(MPVMainEncContext *const m) c->me_sub_cmp = s->avctx->me_sub_cmp; c->pix_fmt = AV_PIX_FMT_YUV420P; c->time_base = s->avctx->time_base; - c->max_b_frames = s->max_b_frames; + c->max_b_frames = m->max_b_frames; ret = avcodec_open2(c, s->avctx->codec, NULL); if (ret < 0) @@ -1554,8 +1554,8 @@ static int estimate_best_b_count(MPVMainEncContext *const m) //rd += (out_size * lambda2) >> FF_LAMBDA_SHIFT; - for (i = 0; i < s->max_b_frames + 1; i++) { - int is_p = i % (j + 1) == j || i == s->max_b_frames; + for (int i = 0; i < m->max_b_frames + 1; i++) { + int is_p = i % (j + 1) == j || i == m->max_b_frames; m->tmp_frames[i + 1]->pict_type = is_p ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_B; @@ -1640,7 +1640,7 @@ static int set_bframe_chain_length(MPVMainEncContext *const m) int b_frames = 0; if (s->avctx->flags & AV_CODEC_FLAG_PASS2) { - for (int i = 0; i < s->max_b_frames + 1; i++) { + for (int i = 0; i < m->max_b_frames + 1; i++) { int pict_num = s->input_picture[0]->display_picture_number + i; if (pict_num >= m->rc_context.num_entries) @@ -1656,12 +1656,11 @@ static int set_bframe_chain_length(MPVMainEncContext *const m) } if (m->b_frame_strategy == 0) { - b_frames = s->max_b_frames; + b_frames = m->max_b_frames; while (b_frames && !s->input_picture[b_frames]) b_frames--; } else if (m->b_frame_strategy == 1) { - int i; - for (i = 1; i < s->max_b_frames + 1; i++) { + for (int i = 1; i < m->max_b_frames + 1; i++) { if (s->input_picture[i] && s->input_picture[i]->b_frame_score == 0) { s->input_picture[i]->b_frame_score = @@ -1671,19 +1670,18 @@ static int set_bframe_chain_length(MPVMainEncContext *const m) s->linesize) + 1; } } - for (i = 0; i < s->max_b_frames + 1; i++) { + for (int i = 0; i < m->max_b_frames + 1; i++) { if (!s->input_picture[i] || s->input_picture[i]->b_frame_score - 1 > - s->mb_num / m->b_sensitivity) + s->mb_num / m->b_sensitivity) { + b_frames = FFMAX(0, i - 1); break; + } } - b_frames = FFMAX(0, i - 1); - /* reset scores */ - for (i = 0; i < b_frames + 1; i++) { + for (int i = 0; i < b_frames + 1; i++) s->input_picture[i]->b_frame_score = 0; - } } else if (m->b_frame_strategy == 2) { b_frames = estimate_best_b_count(m); if (b_frames < 0) { @@ -1700,7 +1698,7 @@ static int set_bframe_chain_length(MPVMainEncContext *const m) b_frames = i; } if (s->input_picture[b_frames]->f->pict_type == AV_PICTURE_TYPE_B && - b_frames == s->max_b_frames) { + b_frames == m->max_b_frames) { av_log(s->avctx, AV_LOG_ERROR, "warning, too many B-frames in a row\n"); } diff --git a/libavcodec/mpegvideoenc.h b/libavcodec/mpegvideoenc.h index 65bb3447b3..27bd099aad 100644 --- a/libavcodec/mpegvideoenc.h +++ b/libavcodec/mpegvideoenc.h @@ -44,6 +44,7 @@ typedef struct MPVMainEncContext { int intra_only; ///< if true, only intra pictures are generated int gop_size; + int max_b_frames; ///< max number of B-frames int picture_in_gop_number; ///< 0-> first pic in gop, ... int input_picture_number; ///< used to set pic->display_picture_number int coded_picture_number; ///< used to set pic->coded_picture_number diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c index 895e557877..20e3ccabf8 100644 --- a/libavcodec/ratecontrol.c +++ b/libavcodec/ratecontrol.c @@ -581,7 +581,7 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m) p = s->avctx->stats_in; for (i = -1; p; i++) p = strchr(p + 1, ';'); - i += s->max_b_frames; + i += m->max_b_frames; if (i <= 0 || i >= INT_MAX / sizeof(RateControlEntry)) return -1; rcc->entry = av_mallocz(i * sizeof(RateControlEntry)); @@ -602,7 +602,7 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m) /* read stats */ p = s->avctx->stats_in; - for (i = 0; i < rcc->num_entries - s->max_b_frames; i++) { + for (i = 0; i < rcc->num_entries - m->max_b_frames; i++) { RateControlEntry *rce; int picture_number; int e; @@ -663,7 +663,7 @@ av_cold int ff_rate_control_init(MPVMainEncContext *const m) if (i % ((m->gop_size + 3) / 4) == 0) rce.pict_type = AV_PICTURE_TYPE_I; - else if (i % (s->max_b_frames + 1)) + else if (i % (m->max_b_frames + 1)) rce.pict_type = AV_PICTURE_TYPE_B; else rce.pict_type = AV_PICTURE_TYPE_P; -- 2.45.2