diff options
author | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2024-04-28 01:41:49 +0200 |
---|---|---|
committer | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2024-06-12 10:49:24 +0200 |
commit | 99543c93ec0984d190eb81b2ec5cfd8665bc14f2 (patch) | |
tree | 21b4af61ea7a5a1d2debc3dacff02e8d8a42efd6 /libavcodec | |
parent | a30c95ed8a51532d7360d0505a53ec62e8e7392c (diff) | |
download | ffmpeg-99543c93ec0984d190eb81b2ec5cfd8665bc14f2.tar.gz |
avcodec/mpegvideo_dec: Factor allocating dummy frames out
This will allow to reuse it to allocate dummy frames for
the second field (which can be a P-field even if the first
field was an intra field).
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/mpegvideo_dec.c | 85 | ||||
-rw-r--r-- | libavcodec/mpegvideodec.h | 4 |
2 files changed, 56 insertions, 33 deletions
diff --git a/libavcodec/mpegvideo_dec.c b/libavcodec/mpegvideo_dec.c index 597ffde7f8..efc257d43e 100644 --- a/libavcodec/mpegvideo_dec.c +++ b/libavcodec/mpegvideo_dec.c @@ -281,14 +281,21 @@ fail: return ret; } -static int av_cold alloc_dummy_frame(MpegEncContext *s, Picture **picp) +static int av_cold alloc_dummy_frame(MpegEncContext *s, Picture **picp, Picture *wpic) { Picture *pic; - int ret = alloc_picture(s, picp, 1); + int ret = alloc_picture(s, &pic, 1); if (ret < 0) return ret; - pic = *picp; + ff_mpeg_unref_picture(wpic); + ret = ff_mpeg_ref_picture(wpic, pic); + if (ret < 0) { + ff_mpeg_unref_picture(pic); + return ret; + } + + *picp = pic; ff_thread_report_progress(&pic->tf, INT_MAX, 0); ff_thread_report_progress(&pic->tf, INT_MAX, 1); @@ -314,6 +321,45 @@ static void color_frame(AVFrame *frame, int luma) } } +int ff_mpv_alloc_dummy_frames(MpegEncContext *s) +{ + AVCodecContext *avctx = s->avctx; + int ret; + + if ((!s->last_picture_ptr || !s->last_picture_ptr->f->buf[0]) && + (s->pict_type != AV_PICTURE_TYPE_I)) { + if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture_ptr && s->next_picture_ptr->f->buf[0]) + av_log(avctx, AV_LOG_DEBUG, + "allocating dummy last picture for B frame\n"); + else if (s->codec_id != AV_CODEC_ID_H261 /* H.261 has no keyframes */ && + (s->picture_structure == PICT_FRAME || s->first_field)) + av_log(avctx, AV_LOG_ERROR, + "warning: first frame is no keyframe\n"); + + /* Allocate a dummy frame */ + ret = alloc_dummy_frame(s, &s->last_picture_ptr, &s->last_picture); + if (ret < 0) + return ret; + + if (!avctx->hwaccel) { + int luma_val = s->codec_id == AV_CODEC_ID_FLV1 || s->codec_id == AV_CODEC_ID_H263 ? 16 : 0x80; + color_frame(s->last_picture_ptr->f, luma_val); + } + } + if ((!s->next_picture_ptr || !s->next_picture_ptr->f->buf[0]) && + s->pict_type == AV_PICTURE_TYPE_B) { + /* Allocate a dummy frame */ + ret = alloc_dummy_frame(s, &s->next_picture_ptr, &s->next_picture); + if (ret < 0) + return ret; + } + + av_assert0(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr && + s->last_picture_ptr->f->buf[0])); + + return 0; +} + /** * generic function called after decoding * the header and before a frame is decoded. @@ -382,34 +428,6 @@ int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx) s->current_picture_ptr ? s->current_picture_ptr->f->data[0] : NULL, s->pict_type, s->droppable); - if ((!s->last_picture_ptr || !s->last_picture_ptr->f->buf[0]) && - (s->pict_type != AV_PICTURE_TYPE_I)) { - if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture_ptr && s->next_picture_ptr->f->buf[0]) - av_log(avctx, AV_LOG_DEBUG, - "allocating dummy last picture for B frame\n"); - else if (s->codec_id != AV_CODEC_ID_H261) - av_log(avctx, AV_LOG_ERROR, - "warning: first frame is no keyframe\n"); - - /* Allocate a dummy frame */ - ret = alloc_dummy_frame(s, &s->last_picture_ptr); - if (ret < 0) - return ret; - - if (!avctx->hwaccel) { - int luma_val = s->codec_id == AV_CODEC_ID_FLV1 || s->codec_id == AV_CODEC_ID_H263 ? 16 : 0x80; - color_frame(s->last_picture_ptr->f, luma_val); - } - - } - if ((!s->next_picture_ptr || !s->next_picture_ptr->f->buf[0]) && - s->pict_type == AV_PICTURE_TYPE_B) { - /* Allocate a dummy frame */ - ret = alloc_dummy_frame(s, &s->next_picture_ptr); - if (ret < 0) - return ret; - } - if (s->last_picture_ptr) { if (s->last_picture_ptr->f->buf[0] && (ret = ff_mpeg_ref_picture(&s->last_picture, @@ -423,8 +441,9 @@ int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx) return ret; } - av_assert0(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr && - s->last_picture_ptr->f->buf[0])); + ret = ff_mpv_alloc_dummy_frames(s); + if (ret < 0) + return ret; /* set dequantizer, we can't do it during init as * it might change for MPEG-4 and we can't do it in the header diff --git a/libavcodec/mpegvideodec.h b/libavcodec/mpegvideodec.h index 0b841bc1a1..42c2697749 100644 --- a/libavcodec/mpegvideodec.h +++ b/libavcodec/mpegvideodec.h @@ -50,6 +50,10 @@ void ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx); int ff_mpv_common_frame_size_change(MpegEncContext *s); int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx); +/** + * Ensure that the dummy frames are allocated according to pict_type if necessary. + */ +int ff_mpv_alloc_dummy_frames(MpegEncContext *s); void ff_mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64]); void ff_mpv_report_decode_progress(MpegEncContext *s); void ff_mpv_frame_end(MpegEncContext *s); |