Up until now, an initialized MpegEncContext had an array of MPVPictures (way more than were ever needed) and the MPVPicture* contained in the MPVWorkPictures as well as the input_picture and reordered_input_picture arrays (for the encoder) pointed into this array. Several of the pointers could point to the same slot and because there was no reference counting involved, one had to check for aliasing before unreferencing. Furthermore, given that these pointers were not ownership pointers the pointers were often simply reset without unreferencing the slot (happened e.g. for the RV30 and RV40 decoders) or there were moved without resetting the src pointer (happened for the encoders where the entries in the input_picture and reordered_input_picture arrays were not reset). Instead actually releasing these pictures was performed by looping over the whole array and checking which one of the entries needed to be kept. Given that the array had way too many slots (36), this meant that more than 30 MPVPictures have been unnecessarily unreferenced in every ff_mpv_frame_start(); something similar happened for the encoder. This commit changes this by making the MPVPictures refcounted via the RefStruct API. The MPVPictures itself are part of a pool so that this does not entail constant allocations; instead, the amount of allocations actually goes down, because the earlier code used such a large array of MPVPictures (36 entries) and allocated an AVFrame for every one of these on every ff_mpv_common_init(). In fact, the pool is only freed when closing the codec, so that reinitializations don't lead to new allocations (this avoids having to sync the pool in update_thread_context). Making MPVPictures refcounted also has another key benefit: It makes it possible to directly share them across threads (when using frame-threaded decoding), eliminating ugly code with underlying av_frame_ref()'s; sharing these pictures can't fail any more. The pool is allocated in ff_mpv_decode_init() for decoders, which therefore can fail now. This and the fact that the pool is not unreferenced in ff_mpv_common_end() also necessitated to mark several mpegvideo-decoders with the FF_CODEC_CAP_INIT_CLEANUP flag. *: This also means that there is no good reason any more for ff_mpv_common_frame_size_change() to exist.
Unified · Split
| @@ -121,6 +121,7 @@ const FFCodec ff_flv_decoder = { · 120 unmodified lines | ||
| 121 | 121 | FF_CODEC_DECODE_CB(ff_h263_decode_frame), |
| 122 | 122 | .close = ff_mpv_decode_close, |
| 123 | 123 | .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, |
| 124 | − .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 124 | + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | | |
| 125 | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 125 | 126 | .p.max_lowres = 3, |
| 126 | 127 | }; |
| @@ -84,10 +84,13 @@ static av_cold int h261_decode_init(AVCodecContext *avctx) · 83 unmodified lines | ||
| 84 | 84 | static AVOnce init_static_once = AV_ONCE_INIT; |
| 85 | 85 | H261DecContext *const h = avctx->priv_data; |
| 86 | 86 | MpegEncContext *const s = &h->s; |
| 87 | + int ret; | |
| 87 | 88 | |
| 88 | 89 | s->private_ctx = &h->common; |
| 89 | 90 | // set defaults |
| 90 | − ff_mpv_decode_init(s, avctx); | |
| 91 | + ret = ff_mpv_decode_init(s, avctx); | |
| 92 | + if (ret < 0) | |
| 93 | + return ret; | |
| 91 | 94 | |
| 92 | 95 | s->out_format = FMT_H261; |
| 93 | 96 | s->low_delay = 1; |
| @@ -95,7 +95,9 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx) · 94 unmodified lines | ||
| 95 | 95 | s->out_format = FMT_H263; |
| 96 | 96 | |
| 97 | 97 | // set defaults |
| 98 | − ff_mpv_decode_init(s, avctx); | |
| 98 | + ret = ff_mpv_decode_init(s, avctx); | |
| 99 | + if (ret < 0) | |
| 100 | + return ret; | |
| 99 | 101 | |
| 100 | 102 | s->quant_precision = 5; |
| 101 | 103 | s->decode_mb = ff_h263_decode_mb; |
| @@ -427,7 +429,7 @@ int ff_h263_decode_frame(AVCodecContext *avctx, AVFrame *pict, · 325 unmodified lines | ||
| 427 | 429 | if (s->low_delay == 0 && s->next_pic.ptr) { |
| 428 | 430 | if ((ret = av_frame_ref(pict, s->next_pic.ptr->f)) < 0) |
| 429 | 431 | return ret; |
| 430 | − s->next_pic.ptr = NULL; | |
| 432 | + ff_mpv_unref_picture(&s->next_pic); | |
| 431 | 433 | |
| 432 | 434 | *got_frame = 1; |
| 433 | 435 | } else if (s->skipped_last_frame && s->cur_pic.ptr) { |
| @@ -439,7 +441,7 @@ int ff_h263_decode_frame(AVCodecContext *avctx, AVFrame *pict, · 5 unmodified lines | ||
| 439 | 441 | * returned picture would be reused */ |
| 440 | 442 | if ((ret = ff_decode_frame_props(avctx, pict)) < 0) |
| 441 | 443 | return ret; |
| 442 | − s->cur_pic.ptr = NULL; | |
| 444 | + ff_mpv_unref_picture(&s->cur_pic); | |
| 443 | 445 | |
| 444 | 446 | *got_frame = 1; |
| 445 | 447 | } |
| @@ -698,7 +700,8 @@ const FFCodec ff_h263_decoder = { · 252 unmodified lines | ||
| 698 | 700 | .close = ff_mpv_decode_close, |
| 699 | 701 | .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | |
| 700 | 702 | AV_CODEC_CAP_DELAY, |
| 701 | − .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 703 | + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | | |
| 704 | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 702 | 705 | .flush = ff_mpeg_flush, |
| 703 | 706 | .p.max_lowres = 3, |
| 704 | 707 | .hw_configs = h263_hw_config_list, |
| @@ -715,7 +718,8 @@ const FFCodec ff_h263p_decoder = { · 10 unmodified lines | ||
| 715 | 718 | .close = ff_mpv_decode_close, |
| 716 | 719 | .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | |
| 717 | 720 | AV_CODEC_CAP_DELAY, |
| 718 | − .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 721 | + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | | |
| 722 | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 719 | 723 | .flush = ff_mpeg_flush, |
| 720 | 724 | .p.max_lowres = 3, |
| 721 | 725 | .hw_configs = h263_hw_config_list, |
| @@ -135,5 +135,6 @@ const FFCodec ff_h263i_decoder = { · 134 unmodified lines | ||
| 135 | 135 | FF_CODEC_DECODE_CB(ff_h263_decode_frame), |
| 136 | 136 | .close = ff_mpv_decode_close, |
| 137 | 137 | .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, |
| 138 | − .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 138 | + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | | |
| 139 | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 139 | 140 | }; |
| @@ -80,7 +80,7 @@ static av_cold void init_uni_ac_vlc(const uint8_t huff_size_ac[256], · 79 unmodified lines | ||
| 80 | 80 | |
| 81 | 81 | static void mjpeg_encode_picture_header(MpegEncContext *s) |
| 82 | 82 | { |
| 83 | − ff_mjpeg_encode_picture_header(s->avctx, &s->pb, s->picture->f, s->mjpeg_ctx, | |
| 83 | + ff_mjpeg_encode_picture_header(s->avctx, &s->pb, s->cur_pic.ptr->f, s->mjpeg_ctx, | |
| 84 | 84 | s->intra_scantable.permutated, 0, |
| 85 | 85 | s->intra_matrix, s->chroma_intra_matrix, |
| 86 | 86 | s->slice_context_count > 1); |
| @@ -793,13 +793,16 @@ static av_cold int mpeg_decode_init(AVCodecContext *avctx) · 792 unmodified lines | ||
| 793 | 793 | { |
| 794 | 794 | Mpeg1Context *s = avctx->priv_data; |
| 795 | 795 | MpegEncContext *s2 = &s->mpeg_enc_ctx; |
| 796 | + int ret; | |
| 796 | 797 | |
| 797 | 798 | s2->out_format = FMT_MPEG1; |
| 798 | 799 | |
| 799 | 800 | if ( avctx->codec_tag != AV_RL32("VCR2") |
| 800 | 801 | && avctx->codec_tag != AV_RL32("BW10")) |
| 801 | 802 | avctx->coded_width = avctx->coded_height = 0; // do not trust dimensions from input |
| 802 | − ff_mpv_decode_init(s2, avctx); | |
| 803 | + ret = ff_mpv_decode_init(s2, avctx); | |
| 804 | + if (ret < 0) | |
| 805 | + return ret; | |
| 803 | 806 | |
| 804 | 807 | ff_mpeg12_init_vlcs(); |
| 805 | 808 | |
| @@ -2529,7 +2532,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, AVFrame *picture, · 1723 unmodified lines | ||
| 2529 | 2532 | if (ret < 0) |
| 2530 | 2533 | return ret; |
| 2531 | 2534 | |
| 2532 | − s2->next_pic.ptr = NULL; | |
| 2535 | + ff_mpv_unref_picture(&s2->next_pic); | |
| 2533 | 2536 | |
| 2534 | 2537 | *got_output = 1; |
| 2535 | 2538 | } |
| @@ -2552,14 +2555,14 @@ static int mpeg_decode_frame(AVCodecContext *avctx, AVFrame *picture, · 16 unmodified lines | ||
| 2552 | 2555 | } |
| 2553 | 2556 | s->extradata_decoded = 1; |
| 2554 | 2557 | if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) { |
| 2555 | − s2->cur_pic.ptr = NULL; | |
| 2558 | + ff_mpv_unref_picture(&s2->cur_pic); | |
| 2556 | 2559 | return ret; |
| 2557 | 2560 | } |
| 2558 | 2561 | } |
| 2559 | 2562 | |
| 2560 | 2563 | ret = decode_chunks(avctx, picture, got_output, buf, buf_size); |
| 2561 | 2564 | if (ret<0 || *got_output) { |
| 2562 | − s2->cur_pic.ptr = NULL; | |
| 2565 | + ff_mpv_unref_picture(&s2->cur_pic); | |
| 2563 | 2566 | |
| 2564 | 2567 | if (s->timecode_frame_start != -1 && *got_output) { |
| 2565 | 2568 | char tcbuf[AV_TIMECODE_STR_SIZE]; |
| @@ -3866,7 +3866,8 @@ const FFCodec ff_mpeg4_decoder = { · 3865 unmodified lines | ||
| 3866 | 3866 | .close = ff_mpv_decode_close, |
| 3867 | 3867 | .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | |
| 3868 | 3868 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_FRAME_THREADS, |
| 3869 | − .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 3869 | + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | | |
| 3870 | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 3870 | 3871 | .flush = ff_mpeg_flush, |
| 3871 | 3872 | .p.max_lowres = 3, |
| 3872 | 3873 | .p.profiles = NULL_IF_CONFIG_SMALL(ff_mpeg4_video_profiles), |
| @@ -30,8 +30,14 @@ · 29 unmodified lines | ||
| 30 | 30 | #include "refstruct.h" |
| 31 | 31 | #include "threadframe.h" |
| 32 | 32 | |
| 33 | −static void av_noinline free_picture_tables(MPVPicture *pic) | |
| 33 | +static void mpv_pic_reset(FFRefStructOpaque unused, void *obj) | |
| 34 | 34 | { |
| 35 | + MPVPicture *pic = obj; | |
| 36 | + | |
| 37 | + ff_thread_release_ext_buffer(&pic->tf); | |
| 38 | + | |
| 39 | + ff_refstruct_unref(&pic->hwaccel_picture_private); | |
| 40 | + | |
| 35 | 41 | ff_refstruct_unref(&pic->mbskip_table); |
| 36 | 42 | ff_refstruct_unref(&pic->qscale_table_base); |
| 37 | 43 | ff_refstruct_unref(&pic->mb_type_base); |
| @@ -39,16 +45,53 @@ static void av_noinline free_picture_tables(MPVPicture *pic) · 1 unmodified line | ||
| 39 | 45 | for (int i = 0; i < 2; i++) { |
| 40 | 46 | ff_refstruct_unref(&pic->motion_val_base[i]); |
| 41 | 47 | ff_refstruct_unref(&pic->ref_index[i]); |
| 48 | + | |
| 49 | + pic->motion_val[i] = NULL; | |
| 42 | 50 | } |
| 43 | 51 | |
| 52 | + pic->mb_type = NULL; | |
| 53 | + pic->qscale_table = NULL; | |
| 54 | + | |
| 55 | + pic->mb_stride = | |
| 44 | 56 | pic->mb_width = |
| 45 | 57 | pic->mb_height = 0; |
| 58 | + | |
| 59 | + pic->dummy = 0; | |
| 60 | + pic->field_picture = 0; | |
| 61 | + pic->b_frame_score = 0; | |
| 62 | + pic->reference = 0; | |
| 63 | + pic->shared = 0; | |
| 64 | + pic->display_picture_number = 0; | |
| 65 | + pic->coded_picture_number = 0; | |
| 66 | +} | |
| 67 | + | |
| 68 | +static int av_cold mpv_pic_init(FFRefStructOpaque unused, void *obj) | |
| 69 | +{ | |
| 70 | + MPVPicture *pic = obj; | |
| 71 | + | |
| 72 | + pic->f = av_frame_alloc(); | |
| 73 | + if (!pic->f) | |
| 74 | + return AVERROR(ENOMEM); | |
| 75 | + pic->tf.f = pic->f; | |
| 76 | + return 0; | |
| 77 | +} | |
| 78 | + | |
| 79 | +static void av_cold mpv_pic_free(FFRefStructOpaque unused, void *obj) | |
| 80 | +{ | |
| 81 | + MPVPicture *pic = obj; | |
| 82 | + | |
| 83 | + av_frame_free(&pic->f); | |
| 84 | +} | |
| 85 | + | |
| 86 | +av_cold FFRefStructPool *ff_mpv_alloc_pic_pool(void) | |
| 87 | +{ | |
| 88 | + return ff_refstruct_pool_alloc_ext(sizeof(MPVPicture), 0, NULL, | |
| 89 | + mpv_pic_init, mpv_pic_reset, mpv_pic_free, NULL); | |
| 46 | 90 | } |
| 47 | 91 | |
| 48 | 92 | void ff_mpv_unref_picture(MPVWorkPicture *pic) |
| 49 | 93 | { |
| 50 | − if (pic->ptr) | |
| 51 | − ff_mpeg_unref_picture(pic->ptr); | |
| 94 | + ff_refstruct_unref(&pic->ptr); | |
| 52 | 95 | memset(pic, 0, sizeof(*pic)); |
| 53 | 96 | } |
| 54 | 97 | |
| @@ -71,16 +114,18 @@ static void set_workpic_from_pic(MPVWorkPicture *wpic, const MPVPicture *pic) · 16 unmodified lines | ||
| 71 | 114 | |
| 72 | 115 | void ff_mpv_replace_picture(MPVWorkPicture *dst, const MPVWorkPicture *src) |
| 73 | 116 | { |
| 117 | + av_assert1(dst != src); | |
| 118 | + ff_refstruct_replace(&dst->ptr, src->ptr); | |
| 74 | 119 | memcpy(dst, src, sizeof(*dst)); |
| 75 | 120 | } |
| 76 | 121 | |
| 77 | 122 | void ff_mpv_workpic_from_pic(MPVWorkPicture *wpic, MPVPicture *pic) |
| 78 | 123 | { |
| 124 | + ff_refstruct_replace(&wpic->ptr, pic); | |
| 79 | 125 | if (!pic) { |
| 80 | 126 | memset(wpic, 0, sizeof(*wpic)); |
| 81 | 127 | return; |
| 82 | 128 | } |
| 83 | − wpic->ptr = pic; | |
| 84 | 129 | set_workpic_from_pic(wpic, pic); |
| 85 | 130 | } |
| 86 | 131 | |
| @@ -212,107 +257,3 @@ fail: · 125 unmodified lines | ||
| 212 | 257 | av_log(avctx, AV_LOG_ERROR, "Error allocating picture accessories.\n"); |
| 213 | 258 | return ret; |
| 214 | 259 | } |
| 215 | − | |
| 216 | −/** | |
| 217 | − * Deallocate a picture; frees the picture tables in case they | |
| 218 | − * need to be reallocated anyway. | |
| 219 | − */ | |
| 220 | −void ff_mpeg_unref_picture(MPVPicture *pic) | |
| 221 | −{ | |
| 222 | − pic->tf.f = pic->f; | |
| 223 | − ff_thread_release_ext_buffer(&pic->tf); | |
| 224 | − | |
| 225 | − ff_refstruct_unref(&pic->hwaccel_picture_private); | |
| 226 | − | |
| 227 | − free_picture_tables(pic); | |
| 228 | − | |
| 229 | − pic->dummy = 0; | |
| 230 | − | |
| 231 | − pic->field_picture = 0; | |
| 232 | − pic->b_frame_score = 0; | |
| 233 | − pic->reference = 0; | |
| 234 | − pic->shared = 0; | |
| 235 | − pic->display_picture_number = 0; | |
| 236 | − pic->coded_picture_number = 0; | |
| 237 | −} | |
| 238 | − | |
| 239 | −static void update_picture_tables(MPVPicture *dst, const MPVPicture *src) | |
| 240 | −{ | |
| 241 | − ff_refstruct_replace(&dst->mbskip_table, src->mbskip_table); | |
| 242 | − ff_refstruct_replace(&dst->qscale_table_base, src->qscale_table_base); | |
| 243 | − ff_refstruct_replace(&dst->mb_type_base, src->mb_type_base); | |
| 244 | − for (int i = 0; i < 2; i++) { | |
| 245 | − ff_refstruct_replace(&dst->motion_val_base[i], src->motion_val_base[i]); | |
| 246 | − ff_refstruct_replace(&dst->ref_index[i], src->ref_index[i]); | |
| 247 | − } | |
| 248 | − | |
| 249 | − dst->qscale_table = src->qscale_table; | |
| 250 | − dst->mb_type = src->mb_type; | |
| 251 | − for (int i = 0; i < 2; i++) | |
| 252 | − dst->motion_val[i] = src->motion_val[i]; | |
| 253 | − | |
| 254 | − dst->mb_width = src->mb_width; | |
| 255 | − dst->mb_height = src->mb_height; | |
| 256 | − dst->mb_stride = src->mb_stride; | |
| 257 | −} | |
| 258 | − | |
| 259 | −int ff_mpeg_ref_picture(MPVPicture *dst, MPVPicture *src) | |
| 260 | −{ | |
| 261 | − int ret; | |
| 262 | − | |
| 263 | − av_assert0(!dst->f->buf[0]); | |
| 264 | − av_assert0(src->f->buf[0]); | |
| 265 | − | |
| 266 | − src->tf.f = src->f; | |
| 267 | − dst->tf.f = dst->f; | |
| 268 | − ret = ff_thread_ref_frame(&dst->tf, &src->tf); | |
| 269 | − if (ret < 0) | |
| 270 | − goto fail; | |
| 271 | − | |
| 272 | − update_picture_tables(dst, src); | |
| 273 | − | |
| 274 | − ff_refstruct_replace(&dst->hwaccel_picture_private, | |
| 275 | − src->hwaccel_picture_private); | |
| 276 | − | |
| 277 | − dst->dummy = src->dummy; | |
| 278 | − dst->field_picture = src->field_picture; | |
| 279 | − dst->b_frame_score = src->b_frame_score; | |
| 280 | − dst->reference = src->reference; | |
| 281 | − dst->shared = src->shared; | |
| 282 | − dst->display_picture_number = src->display_picture_number; | |
| 283 | − dst->coded_picture_number = src->coded_picture_number; | |
| 284 | − | |
| 285 | − return 0; | |
| 286 | −fail: | |
| 287 | − ff_mpeg_unref_picture(dst); | |
| 288 | − return ret; | |
| 289 | −} | |
| 290 | − | |
| 291 | −int ff_find_unused_picture(AVCodecContext *avctx, MPVPicture *picture, int shared) | |
| 292 | −{ | |
| 293 | − for (int i = 0; i < MAX_PICTURE_COUNT; i++) | |
| 294 | − if (!picture[i].f->buf[0]) | |
| 295 | − return i; | |
| 296 | − | |
| 297 | − av_log(avctx, AV_LOG_FATAL, | |
| 298 | − "Internal error, picture buffer overflow\n"); | |
| 299 | − /* We could return -1, but the codec would crash trying to draw into a | |
| 300 | − * non-existing frame anyway. This is safer than waiting for a random crash. | |
| 301 | − * Also the return of this is never useful, an encoder must only allocate | |
| 302 | − * as much as allowed in the specification. This has no relationship to how | |
| 303 | − * much libavcodec could allocate (and MAX_PICTURE_COUNT is always large | |
| 304 | − * enough for such valid streams). | |
| 305 | − * Plus, a decoder has to check stream validity and remove frames if too | |
| 306 | − * many reference frames are around. Waiting for "OOM" is not correct at | |
| 307 | − * all. Similarly, missing reference frames have to be replaced by | |
| 308 | − * interpolated/MC frames, anything else is a bug in the codec ... | |
| 309 | − */ | |
| 310 | − abort(); | |
| 311 | − return -1; | |
| 312 | −} | |
| 313 | − | |
| 314 | −void av_cold ff_mpv_picture_free(MPVPicture *pic) | |
| 315 | −{ | |
| 316 | − ff_mpeg_unref_picture(pic); | |
| 317 | − av_frame_free(&pic->f); | |
| 318 | −} | |
| @@ -29,7 +29,6 @@ · 28 unmodified lines | ||
| 29 | 29 | #include "threadframe.h" |
| 30 | 30 | |
| 31 | 31 | #define MPV_MAX_PLANES 3 |
| 32 | −#define MAX_PICTURE_COUNT 36 | |
| 33 | 32 | #define EDGE_WIDTH 16 |
| 34 | 33 | |
| 35 | 34 | typedef struct ScratchpadContext { |
| @@ -94,7 +93,7 @@ typedef struct MPVWorkPicture { · 58 unmodified lines | ||
| 94 | 93 | uint8_t *data[MPV_MAX_PLANES]; |
| 95 | 94 | ptrdiff_t linesize[MPV_MAX_PLANES]; |
| 96 | 95 | |
| 97 | − MPVPicture *ptr; | |
| 96 | + MPVPicture *ptr; ///< RefStruct reference | |
| 98 | 97 | |
| 99 | 98 | int8_t *qscale_table; |
| 100 | 99 | |
| @@ -109,6 +108,11 @@ typedef struct MPVWorkPicture { · 8 unmodified lines | ||
| 109 | 108 | int reference; |
| 110 | 109 | } MPVWorkPicture; |
| 111 | 110 | |
| 111 | +/** | |
| 112 | + * Allocate a pool of MPVPictures. | |
| 113 | + */ | |
| 114 | +struct FFRefStructPool *ff_mpv_alloc_pic_pool(void); | |
| 115 | + | |
| 112 | 116 | /** |
| 113 | 117 | * Allocate an MPVPicture's accessories (but not the AVFrame's buffer itself) |
| 114 | 118 | * and set the MPVWorkPicture's fields. |
| @@ -129,14 +133,8 @@ int ff_mpv_pic_check_linesize(void *logctx, const struct AVFrame *f, · 14 unmodified lines | ||
| 129 | 133 | int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, |
| 130 | 134 | ScratchpadContext *sc, int linesize); |
| 131 | 135 | |
| 132 | −int ff_mpeg_ref_picture(MPVPicture *dst, MPVPicture *src); | |
| 133 | 136 | void ff_mpv_unref_picture(MPVWorkPicture *pic); |
| 134 | 137 | void ff_mpv_workpic_from_pic(MPVWorkPicture *wpic, MPVPicture *pic); |
| 135 | 138 | void ff_mpv_replace_picture(MPVWorkPicture *dst, const MPVWorkPicture *src); |
| 136 | −void ff_mpeg_unref_picture(MPVPicture *picture); | |
| 137 | − | |
| 138 | −void ff_mpv_picture_free(MPVPicture *pic); | |
| 139 | − | |
| 140 | −int ff_find_unused_picture(AVCodecContext *avctx, MPVPicture *picture, int shared); | |
| 141 | 139 | |
| 142 | 140 | #endif /* AVCODEC_MPEGPICTURE_H */ |
| @@ -701,7 +701,6 @@ static void clear_context(MpegEncContext *s) · 700 unmodified lines | ||
| 701 | 701 | |
| 702 | 702 | s->bitstream_buffer = NULL; |
| 703 | 703 | s->allocated_bitstream_buffer_size = 0; |
| 704 | − s->picture = NULL; | |
| 705 | 704 | s->p_field_mv_table_base = NULL; |
| 706 | 705 | for (int i = 0; i < 2; i++) |
| 707 | 706 | for (int j = 0; j < 2; j++) |
| @@ -726,10 +725,10 @@ static void clear_context(MpegEncContext *s) · 18 unmodified lines | ||
| 726 | 725 | */ |
| 727 | 726 | av_cold int ff_mpv_common_init(MpegEncContext *s) |
| 728 | 727 | { |
| 729 | − int i, ret; | |
| 730 | 728 | int nb_slices = (HAVE_THREADS && |
| 731 | 729 | s->avctx->active_thread_type & FF_THREAD_SLICE) ? |
| 732 | 730 | s->avctx->thread_count : 1; |
| 731 | + int ret; | |
| 733 | 732 | |
| 734 | 733 | clear_context(s); |
| 735 | 734 | |
| @@ -755,14 +754,6 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) · 19 unmodified lines | ||
| 755 | 754 | if (ret) |
| 756 | 755 | return ret; |
| 757 | 756 | |
| 758 | − if (!FF_ALLOCZ_TYPED_ARRAY(s->picture, MAX_PICTURE_COUNT)) | |
| 759 | − return AVERROR(ENOMEM); | |
| 760 | − for (i = 0; i < MAX_PICTURE_COUNT; i++) { | |
| 761 | − s->picture[i].f = av_frame_alloc(); | |
| 762 | − if (!s->picture[i].f) | |
| 763 | − goto fail_nomem; | |
| 764 | − } | |
| 765 | − | |
| 766 | 757 | if ((ret = ff_mpv_init_context_frame(s))) |
| 767 | 758 | goto fail; |
| 768 | 759 | |
| @@ -789,8 +780,6 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) · 20 unmodified lines | ||
| 789 | 780 | // } |
| 790 | 781 | |
| 791 | 782 | return 0; |
| 792 | − fail_nomem: | |
| 793 | − ret = AVERROR(ENOMEM); | |
| 794 | 783 | fail: |
| 795 | 784 | ff_mpv_common_end(s); |
| 796 | 785 | return ret; |
| @@ -830,11 +819,9 @@ void ff_mpv_common_end(MpegEncContext *s) · 33 unmodified lines | ||
| 830 | 819 | av_freep(&s->bitstream_buffer); |
| 831 | 820 | s->allocated_bitstream_buffer_size = 0; |
| 832 | 821 | |
| 833 | − if (s->picture) { | |
| 834 | − for (int i = 0; i < MAX_PICTURE_COUNT; i++) | |
| 835 | − ff_mpv_picture_free(&s->picture[i]); | |
| 836 | − } | |
| 837 | − av_freep(&s->picture); | |
| 822 | + ff_mpv_unref_picture(&s->last_pic); | |
| 823 | + ff_mpv_unref_picture(&s->cur_pic); | |
| 824 | + ff_mpv_unref_picture(&s->next_pic); | |
| 838 | 825 | |
| 839 | 826 | s->context_initialized = 0; |
| 840 | 827 | s->context_reinit = 0; |
| @@ -128,7 +128,7 @@ typedef struct MpegEncContext { · 127 unmodified lines | ||
| 128 | 128 | int mb_num; ///< number of MBs of a picture |
| 129 | 129 | ptrdiff_t linesize; ///< line size, in bytes, may be different from width |
| 130 | 130 | ptrdiff_t uvlinesize; ///< line size, for chroma in bytes, may be different from width |
| 131 | − MPVPicture *picture; ///< main picture buffer | |
| 131 | + struct FFRefStructPool *picture_pool; ///< Pool for MPVPictures | |
| 132 | 132 | MPVPicture **input_picture;///< next pictures on display order for encoding |
| 133 | 133 | MPVPicture **reordered_input_picture; ///< pointer to the next pictures in coded order for encoding |
| 134 | 134 | |
| @@ -38,11 +38,12 @@ · 37 unmodified lines | ||
| 38 | 38 | #include "mpegvideo.h" |
| 39 | 39 | #include "mpegvideodec.h" |
| 40 | 40 | #include "mpeg4videodec.h" |
| 41 | +#include "refstruct.h" | |
| 41 | 42 | #include "thread.h" |
| 42 | 43 | #include "threadframe.h" |
| 43 | 44 | #include "wmv2dec.h" |
| 44 | 45 | |
| 45 | −void ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx) | |
| 46 | +int ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx) | |
| 46 | 47 | { |
| 47 | 48 | ff_mpv_common_defaults(s); |
| 48 | 49 | |
| @@ -57,6 +58,14 @@ void ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx) · 8 unmodified lines | ||
| 57 | 58 | |
| 58 | 59 | ff_mpv_idct_init(s); |
| 59 | 60 | ff_h264chroma_init(&s->h264chroma, 8); //for lowres |
| 61 | + | |
| 62 | + if (!s->picture_pool && // VC-1 can call this multiple times | |
| 63 | + ff_thread_sync_ref(avctx, offsetof(MpegEncContext, picture_pool))) { | |
| 64 | + s->picture_pool = ff_mpv_alloc_pic_pool(); | |
| 65 | + if (!s->picture_pool) | |
| 66 | + return AVERROR(ENOMEM); | |
| 67 | + } | |
| 68 | + return 0; | |
| 60 | 69 | } |
| 61 | 70 | |
| 62 | 71 | int ff_mpeg_update_thread_context(AVCodecContext *dst, |
| @@ -103,26 +112,9 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, · 40 unmodified lines | ||
| 103 | 112 | s->coded_picture_number = s1->coded_picture_number; |
| 104 | 113 | s->picture_number = s1->picture_number; |
| 105 | 114 | |
| 106 | − av_assert0(!s->picture || s->picture != s1->picture); | |
| 107 | − if (s->picture) | |
| 108 | − for (int i = 0; i < MAX_PICTURE_COUNT; i++) { | |
| 109 | − ff_mpeg_unref_picture(&s->picture[i]); | |
| 110 | − if (s1->picture && s1->picture[i].f->buf[0] && | |
| 111 | − (ret = ff_mpeg_ref_picture(&s->picture[i], &s1->picture[i])) < 0) | |
| 112 | − return ret; | |
| 113 | − } | |
| 114 | − | |
| 115 | −#define UPDATE_PICTURE(pic)\ | |
| 116 | −do {\ | |
| 117 | − if (s->picture && s1->picture && s1->pic.ptr && s1->pic.ptr->f->buf[0]) {\ | |
| 118 | − ff_mpv_workpic_from_pic(&s->pic, &s->picture[s1->pic.ptr - s1->picture]);\ | |
| 119 | − } else\ | |
| 120 | − ff_mpv_unref_picture(&s->pic);\ | |
| 121 | −} while (0) | |
| 122 | − | |
| 123 | − UPDATE_PICTURE(cur_pic); | |
| 124 | − UPDATE_PICTURE(last_pic); | |
| 125 | − UPDATE_PICTURE(next_pic); | |
| 115 | + ff_mpv_replace_picture(&s->cur_pic, &s1->cur_pic); | |
| 116 | + ff_mpv_replace_picture(&s->last_pic, &s1->last_pic); | |
| 117 | + ff_mpv_replace_picture(&s->next_pic, &s1->next_pic); | |
| 126 | 118 | |
| 127 | 119 | s->linesize = s1->linesize; |
| 128 | 120 | s->uvlinesize = s1->uvlinesize; |
| @@ -177,6 +169,7 @@ int ff_mpv_decode_close(AVCodecContext *avctx) · 48 unmodified lines | ||
| 177 | 169 | { |
| 178 | 170 | MpegEncContext *s = avctx->priv_data; |
| 179 | 171 | |
| 172 | + ff_refstruct_pool_uninit(&s->picture_pool); | |
| 180 | 173 | ff_mpv_common_end(s); |
| 181 | 174 | return 0; |
| 182 | 175 | } |
| @@ -190,9 +183,9 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) · 7 unmodified lines | ||
| 190 | 183 | |
| 191 | 184 | ff_mpv_free_context_frame(s); |
| 192 | 185 | |
| 193 | − s->last_pic.ptr = | |
| 194 | − s->next_pic.ptr = | |
| 195 | − s->cur_pic.ptr = NULL; | |
| 186 | + ff_mpv_unref_picture(&s->last_pic); | |
| 187 | + ff_mpv_unref_picture(&s->next_pic); | |
| 188 | + ff_mpv_unref_picture(&s->cur_pic); | |
| 196 | 189 | |
| 197 | 190 | if ((s->width || s->height) && |
| 198 | 191 | (err = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0) |
| @@ -228,14 +221,12 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) · 29 unmodified lines | ||
| 228 | 221 | static int alloc_picture(MpegEncContext *s, MPVWorkPicture *dst, int reference) |
| 229 | 222 | { |
| 230 | 223 | AVCodecContext *avctx = s->avctx; |
| 231 | − int idx = ff_find_unused_picture(s->avctx, s->picture, 0); | |
| 232 | − MPVPicture *pic; | |
| 224 | + MPVPicture *pic = ff_refstruct_pool_get(s->picture_pool); | |
| 233 | 225 | int ret; |
| 234 | 226 | |
| 235 | − if (idx < 0) | |
| 236 | − return idx; | |
| 227 | + if (!pic) | |
| 228 | + return AVERROR(ENOMEM); | |
| 237 | 229 | |
| 238 | − pic = &s->picture[idx]; | |
| 239 | 230 | dst->ptr = pic; |
| 240 | 231 | |
| 241 | 232 | pic->tf.f = pic->f; |
| @@ -368,22 +359,7 @@ int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx) · 126 unmodified lines | ||
| 368 | 359 | return AVERROR_BUG; |
| 369 | 360 | } |
| 370 | 361 | |
| 371 | − /* mark & release old frames */ | |
| 372 | − if (s->pict_type != AV_PICTURE_TYPE_B && s->last_pic.ptr && | |
| 373 | − s->last_pic.ptr != s->next_pic.ptr && | |
| 374 | − s->last_pic.ptr->f->buf[0]) { | |
| 375 | − ff_mpeg_unref_picture(s->last_pic.ptr); | |
| 376 | − } | |
| 377 | − | |
| 378 | − /* release non reference/forgotten frames */ | |
| 379 | − for (int i = 0; i < MAX_PICTURE_COUNT; i++) { | |
| 380 | − if (!s->picture[i].reference || | |
| 381 | − (&s->picture[i] != s->last_pic.ptr && | |
| 382 | − &s->picture[i] != s->next_pic.ptr)) { | |
| 383 | − ff_mpeg_unref_picture(&s->picture[i]); | |
| 384 | − } | |
| 385 | − } | |
| 386 | − | |
| 362 | + ff_mpv_unref_picture(&s->cur_pic); | |
| 387 | 363 | ret = alloc_picture(s, &s->cur_pic, |
| 388 | 364 | s->pict_type != AV_PICTURE_TYPE_B && !s->droppable); |
| 389 | 365 | if (ret < 0) |
| @@ -495,12 +471,6 @@ void ff_mpeg_flush(AVCodecContext *avctx) · 105 unmodified lines | ||
| 495 | 471 | { |
| 496 | 472 | MpegEncContext *const s = avctx->priv_data; |
| 497 | 473 | |
| 498 | − if (!s->picture) | |
| 499 | − return; | |
| 500 | − | |
| 501 | − for (int i = 0; i < MAX_PICTURE_COUNT; i++) | |
| 502 | − ff_mpeg_unref_picture(&s->picture[i]); | |
| 503 | − | |
| 504 | 474 | ff_mpv_unref_picture(&s->cur_pic); |
| 505 | 475 | ff_mpv_unref_picture(&s->last_pic); |
| 506 | 476 | ff_mpv_unref_picture(&s->next_pic); |
| @@ -75,6 +75,7 @@ · 74 unmodified lines | ||
| 75 | 75 | #include "wmv2enc.h" |
| 76 | 76 | #include "rv10enc.h" |
| 77 | 77 | #include "packet_internal.h" |
| 78 | +#include "refstruct.h" | |
| 78 | 79 | #include <limits.h> |
| 79 | 80 | #include "sp5x.h" |
| 80 | 81 | |
| @@ -821,7 +822,8 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) · 740 unmodified lines | ||
| 821 | 822 | !FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix16, 32) || |
| 822 | 823 | !FF_ALLOCZ_TYPED_ARRAY(s->input_picture, MAX_B_FRAMES + 1) || |
| 823 | 824 | !FF_ALLOCZ_TYPED_ARRAY(s->reordered_input_picture, MAX_B_FRAMES + 1) || |
| 824 | − !(s->new_pic = av_frame_alloc())) | |
| 825 | + !(s->new_pic = av_frame_alloc()) || | |
| 826 | + !(s->picture_pool = ff_mpv_alloc_pic_pool())) | |
| 825 | 827 | return AVERROR(ENOMEM); |
| 826 | 828 | |
| 827 | 829 | /* Allocate MV tables; the MV and MB tables will be copied |
| @@ -992,7 +994,14 @@ av_cold int ff_mpv_encode_end(AVCodecContext *avctx) · 164 unmodified lines | ||
| 992 | 994 | ff_rate_control_uninit(&s->rc_context); |
| 993 | 995 | |
| 994 | 996 | ff_mpv_common_end(s); |
| 997 | + ff_refstruct_pool_uninit(&s->picture_pool); | |
| 995 | 998 | |
| 999 | + if (s->input_picture && s->reordered_input_picture) { | |
| 1000 | + for (int i = 0; i < MAX_B_FRAMES + 1; i++) { | |
| 1001 | + ff_refstruct_unref(&s->input_picture[i]); | |
| 1002 | + ff_refstruct_unref(&s->reordered_input_picture[i]); | |
| 1003 | + } | |
| 1004 | + } | |
| 996 | 1005 | for (i = 0; i < FF_ARRAY_ELEMS(s->tmp_frames); i++) |
| 997 | 1006 | av_frame_free(&s->tmp_frames[i]); |
| 998 | 1007 | |
| @@ -1131,12 +1140,14 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) · 132 unmodified lines | ||
| 1131 | 1140 | { |
| 1132 | 1141 | MPVPicture *pic = NULL; |
| 1133 | 1142 | int64_t pts; |
| 1134 | − int i, display_picture_number = 0, ret; | |
| 1143 | + int display_picture_number = 0, ret; | |
| 1135 | 1144 | int encoding_delay = s->max_b_frames ? s->max_b_frames |
| 1136 | 1145 | : (s->low_delay ? 0 : 1); |
| 1137 | 1146 | int flush_offset = 1; |
| 1138 | 1147 | int direct = 1; |
| 1139 | 1148 | |
| 1149 | + av_assert1(!s->input_picture[0]); | |
| 1150 | + | |
| 1140 | 1151 | if (pic_arg) { |
| 1141 | 1152 | pts = pic_arg->pts; |
| 1142 | 1153 | display_picture_number = s->input_picture_number++; |
| @@ -1182,16 +1193,13 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) · 39 unmodified lines | ||
| 1182 | 1193 | ff_dlog(s->avctx, "%d %d %"PTRDIFF_SPECIFIER" %"PTRDIFF_SPECIFIER"\n", pic_arg->linesize[0], |
| 1183 | 1194 | pic_arg->linesize[1], s->linesize, s->uvlinesize); |
| 1184 | 1195 | |
| 1185 | − i = ff_find_unused_picture(s->avctx, s->picture, direct); | |
| 1186 | − if (i < 0) | |
| 1187 | − return i; | |
| 1188 | − | |
| 1189 | − pic = &s->picture[i]; | |
| 1190 | − pic->reference = 3; | |
| 1196 | + pic = ff_refstruct_pool_get(s->picture_pool); | |
| 1197 | + if (!pic) | |
| 1198 | + return AVERROR(ENOMEM); | |
| 1191 | 1199 | |
| 1192 | 1200 | if (direct) { |
| 1193 | 1201 | if ((ret = av_frame_ref(pic->f, pic_arg)) < 0) |
| 1194 | − return ret; | |
| 1202 | + goto fail; | |
| 1195 | 1203 | pic->shared = 1; |
| 1196 | 1204 | } else { |
| 1197 | 1205 | ret = prepare_picture(s, pic->f, pic_arg); |
| @@ -1241,17 +1249,17 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) · 43 unmodified lines | ||
| 1241 | 1249 | |
| 1242 | 1250 | pic->display_picture_number = display_picture_number; |
| 1243 | 1251 | pic->f->pts = pts; // we set this here to avoid modifying pic_arg |
| 1244 | − } else { | |
| 1245 | − /* Flushing: When we have not received enough input frames, | |
| 1246 | − * ensure s->input_picture[0] contains the first picture */ | |
| 1252 | + } else if (!s->reordered_input_picture[1]) { | |
| 1253 | + /* Flushing: When the above check is true, the encoder is about to run | |
| 1254 | + * out of frames to encode. Check if there are input_pictures left; | |
| 1255 | + * if so, ensure s->input_picture[0] contains the first picture. | |
| 1256 | + * A flush_offset != 1 will only happen if we did not receive enough | |
| 1257 | + * input frames. */ | |
| 1247 | 1258 | for (flush_offset = 0; flush_offset < encoding_delay + 1; flush_offset++) |
| 1248 | 1259 | if (s->input_picture[flush_offset]) |
| 1249 | 1260 | break; |
| 1250 | 1261 | |
| 1251 | − if (flush_offset <= 1) | |
| 1252 | − flush_offset = 1; | |
| 1253 | − else | |
| 1254 | − encoding_delay = encoding_delay - flush_offset + 1; | |
| 1262 | + encoding_delay -= flush_offset - 1; | |
| 1255 | 1263 | } |
| 1256 | 1264 | |
| 1257 | 1265 | /* shift buffer entries */ |
| @@ -1262,7 +1270,7 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) · 4 unmodified lines | ||
| 1262 | 1270 | |
| 1263 | 1271 | return 0; |
| 1264 | 1272 | fail: |
| 1265 | − ff_mpeg_unref_picture(pic); | |
| 1273 | + ff_refstruct_unref(&pic); | |
| 1266 | 1274 | return ret; |
| 1267 | 1275 | } |
| 1268 | 1276 | |
| @@ -1475,8 +1483,10 @@ fail: · 206 unmodified lines | ||
| 1475 | 1483 | /** |
| 1476 | 1484 | * Determines whether an input picture is discarded or not |
| 1477 | 1485 | * and if not determines the length of the next chain of B frames |
| 1478 | − * and puts these pictures (including the P frame) into | |
| 1486 | + * and moves these pictures (including the P frame) into | |
| 1479 | 1487 | * reordered_input_picture. |
| 1488 | + * input_picture[0] is always NULL when exiting this function, even on error; | |
| 1489 | + * reordered_input_picture[0] is always NULL when exiting this function on error. | |
| 1480 | 1490 | */ |
| 1481 | 1491 | static int set_bframe_chain_length(MpegEncContext *s) |
| 1482 | 1492 | { |
| @@ -1490,7 +1500,7 @@ static int set_bframe_chain_length(MpegEncContext *s) · 7 unmodified lines | ||
| 1490 | 1500 | s->next_pic.ptr && |
| 1491 | 1501 | skip_check(s, s->input_picture[0], s->next_pic.ptr)) { |
| 1492 | 1502 | // FIXME check that the gop check above is +-1 correct |
| 1493 | − ff_mpeg_unref_picture(s->input_picture[0]); | |
| 1503 | + ff_refstruct_unref(&s->input_picture[0]); | |
| 1494 | 1504 | |
| 1495 | 1505 | ff_vbv_update(s, 0); |
| 1496 | 1506 | |
| @@ -1501,6 +1511,7 @@ static int set_bframe_chain_length(MpegEncContext *s) · 4 unmodified lines | ||
| 1501 | 1511 | if (/*s->picture_in_gop_number >= s->gop_size ||*/ |
| 1502 | 1512 | !s->next_pic.ptr || s->intra_only) { |
| 1503 | 1513 | s->reordered_input_picture[0] = s->input_picture[0]; |
| 1514 | + s->input_picture[0] = NULL; | |
| 1504 | 1515 | s->reordered_input_picture[0]->f->pict_type = AV_PICTURE_TYPE_I; |
| 1505 | 1516 | s->reordered_input_picture[0]->coded_picture_number = |
| 1506 | 1517 | s->coded_picture_number++; |
| @@ -1555,7 +1566,7 @@ static int set_bframe_chain_length(MpegEncContext *s) · 48 unmodified lines | ||
| 1555 | 1566 | } else if (s->b_frame_strategy == 2) { |
| 1556 | 1567 | b_frames = estimate_best_b_count(s); |
| 1557 | 1568 | if (b_frames < 0) { |
| 1558 | − ff_mpeg_unref_picture(s->input_picture[0]); | |
| 1569 | + ff_refstruct_unref(&s->input_picture[0]); | |
| 1559 | 1570 | return b_frames; |
| 1560 | 1571 | } |
| 1561 | 1572 | } |
| @@ -1589,12 +1600,14 @@ static int set_bframe_chain_length(MpegEncContext *s) · 27 unmodified lines | ||
| 1589 | 1600 | b_frames--; |
| 1590 | 1601 | |
| 1591 | 1602 | s->reordered_input_picture[0] = s->input_picture[b_frames]; |
| 1603 | + s->input_picture[b_frames] = NULL; | |
| 1592 | 1604 | if (s->reordered_input_picture[0]->f->pict_type != AV_PICTURE_TYPE_I) |
| 1593 | 1605 | s->reordered_input_picture[0]->f->pict_type = AV_PICTURE_TYPE_P; |
| 1594 | 1606 | s->reordered_input_picture[0]->coded_picture_number = |
| 1595 | 1607 | s->coded_picture_number++; |
| 1596 | 1608 | for (int i = 0; i < b_frames; i++) { |
| 1597 | 1609 | s->reordered_input_picture[i + 1] = s->input_picture[i]; |
| 1610 | + s->input_picture[i] = NULL; | |
| 1598 | 1611 | s->reordered_input_picture[i + 1]->f->pict_type = |
| 1599 | 1612 | AV_PICTURE_TYPE_B; |
| 1600 | 1613 | s->reordered_input_picture[i + 1]->coded_picture_number = |
| @@ -1609,11 +1622,14 @@ static int select_input_picture(MpegEncContext *s) · 8 unmodified lines | ||
| 1609 | 1622 | { |
| 1610 | 1623 | int ret; |
| 1611 | 1624 | |
| 1625 | + av_assert1(!s->reordered_input_picture[0]); | |
| 1626 | + | |
| 1612 | 1627 | for (int i = 1; i <= MAX_B_FRAMES; i++) |
| 1613 | 1628 | s->reordered_input_picture[i - 1] = s->reordered_input_picture[i]; |
| 1614 | 1629 | s->reordered_input_picture[MAX_B_FRAMES] = NULL; |
| 1615 | 1630 | |
| 1616 | 1631 | ret = set_bframe_chain_length(s); |
| 1632 | + av_assert1(!s->input_picture[0]); | |
| 1617 | 1633 | if (ret < 0) |
| 1618 | 1634 | return ret; |
| 1619 | 1635 | |
| @@ -1643,6 +1659,7 @@ static int select_input_picture(MpegEncContext *s) · 23 unmodified lines | ||
| 1643 | 1659 | } |
| 1644 | 1660 | } |
| 1645 | 1661 | s->cur_pic.ptr = s->reordered_input_picture[0]; |
| 1662 | + s->reordered_input_picture[0] = NULL; | |
| 1646 | 1663 | av_assert1(s->mb_width == s->buffer_pools.alloc_mb_width); |
| 1647 | 1664 | av_assert1(s->mb_height == s->buffer_pools.alloc_mb_height); |
| 1648 | 1665 | av_assert1(s->mb_stride == s->buffer_pools.alloc_mb_stride); |
| @@ -1657,7 +1674,7 @@ static int select_input_picture(MpegEncContext *s) · 8 unmodified lines | ||
| 1657 | 1674 | } |
| 1658 | 1675 | return 0; |
| 1659 | 1676 | fail: |
| 1660 | − ff_mpeg_unref_picture(s->reordered_input_picture[0]); | |
| 1677 | + ff_refstruct_unref(&s->reordered_input_picture[0]); | |
| 1661 | 1678 | return ret; |
| 1662 | 1679 | } |
| 1663 | 1680 | |
| @@ -1720,13 +1737,6 @@ static void update_noise_reduction(MpegEncContext *s) · 56 unmodified lines | ||
| 1720 | 1737 | |
| 1721 | 1738 | static void frame_start(MpegEncContext *s) |
| 1722 | 1739 | { |
| 1723 | − /* mark & release old frames */ | |
| 1724 | − if (s->pict_type != AV_PICTURE_TYPE_B && s->last_pic.ptr && | |
| 1725 | − s->last_pic.ptr != s->next_pic.ptr && | |
| 1726 | − s->last_pic.ptr->f->buf[0]) { | |
| 1727 | − ff_mpv_unref_picture(&s->last_pic); | |
| 1728 | − } | |
| 1729 | − | |
| 1730 | 1740 | s->cur_pic.ptr->f->pict_type = s->pict_type; |
| 1731 | 1741 | |
| 1732 | 1742 | if (s->pict_type != AV_PICTURE_TYPE_B) { |
| @@ -1747,6 +1757,8 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt, · 14 unmodified lines | ||
| 1747 | 1757 | int i, stuffing_count, ret; |
| 1748 | 1758 | int context_count = s->slice_context_count; |
| 1749 | 1759 | |
| 1760 | + ff_mpv_unref_picture(&s->cur_pic); | |
| 1761 | + | |
| 1750 | 1762 | s->vbv_ignore_qmax = 0; |
| 1751 | 1763 | |
| 1752 | 1764 | s->picture_in_gop_number++; |
| @@ -1973,11 +1985,7 @@ vbv_retry: · 220 unmodified lines | ||
| 1973 | 1985 | s->frame_bits = 0; |
| 1974 | 1986 | } |
| 1975 | 1987 | |
| 1976 | − /* release non-reference frames */ | |
| 1977 | − for (i = 0; i < MAX_PICTURE_COUNT; i++) { | |
| 1978 | − if (!s->picture[i].reference) | |
| 1979 | − ff_mpeg_unref_picture(&s->picture[i]); | |
| 1980 | − } | |
| 1988 | + ff_mpv_unref_picture(&s->cur_pic); | |
| 1981 | 1989 | |
| 1982 | 1990 | av_assert1((s->frame_bits & 7) == 0); |
| 1983 | 1991 | |
| @@ -44,8 +44,10 @@ · 43 unmodified lines | ||
| 44 | 44 | * Initialize the given MpegEncContext for decoding. |
| 45 | 45 | * the changed fields will not depend upon |
| 46 | 46 | * the prior state of the MpegEncContext. |
| 47 | + * | |
| 48 | + * Also initialize the picture pool. | |
| 47 | 49 | */ |
| 48 | −void ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx); | |
| 50 | +int ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx); | |
| 49 | 51 | |
| 50 | 52 | int ff_mpv_common_frame_size_change(MpegEncContext *s); |
| 51 | 53 | |
| @@ -852,7 +852,8 @@ const FFCodec ff_msmpeg4v1_decoder = { · 851 unmodified lines | ||
| 852 | 852 | FF_CODEC_DECODE_CB(ff_h263_decode_frame), |
| 853 | 853 | .close = ff_mpv_decode_close, |
| 854 | 854 | .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, |
| 855 | − .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 855 | + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | | |
| 856 | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 856 | 857 | .p.max_lowres = 3, |
| 857 | 858 | }; |
| 858 | 859 | |
| @@ -866,7 +867,8 @@ const FFCodec ff_msmpeg4v2_decoder = { · 7 unmodified lines | ||
| 866 | 867 | FF_CODEC_DECODE_CB(ff_h263_decode_frame), |
| 867 | 868 | .close = ff_mpv_decode_close, |
| 868 | 869 | .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, |
| 869 | − .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 870 | + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | | |
| 871 | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 870 | 872 | .p.max_lowres = 3, |
| 871 | 873 | }; |
| 872 | 874 | |
| @@ -880,7 +882,8 @@ const FFCodec ff_msmpeg4v3_decoder = { · 7 unmodified lines | ||
| 880 | 882 | FF_CODEC_DECODE_CB(ff_h263_decode_frame), |
| 881 | 883 | .close = ff_mpv_decode_close, |
| 882 | 884 | .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, |
| 883 | − .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 885 | + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | | |
| 886 | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 884 | 887 | .p.max_lowres = 3, |
| 885 | 888 | }; |
| 886 | 889 | |
| @@ -894,6 +897,7 @@ const FFCodec ff_wmv1_decoder = { · 7 unmodified lines | ||
| 894 | 897 | FF_CODEC_DECODE_CB(ff_h263_decode_frame), |
| 895 | 898 | .close = ff_mpv_decode_close, |
| 896 | 899 | .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, |
| 897 | − .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 900 | + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | | |
| 901 | + FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, | |
| 898 | 902 | .p.max_lowres = 3, |
| 899 | 903 | }; |
| @@ -364,7 +364,9 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) · 363 unmodified lines | ||
| 364 | 364 | avctx->coded_height, 0, avctx)) < 0) |
| 365 | 365 | return ret; |
| 366 | 366 | |
| 367 | − ff_mpv_decode_init(s, avctx); | |
| 367 | + ret = ff_mpv_decode_init(s, avctx); | |
| 368 | + if (ret < 0) | |
| 369 | + return ret; | |
| 368 | 370 | |
| 369 | 371 | s->out_format = FMT_H263; |
| 370 | 372 | |
| @@ -645,7 +647,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, AVFrame *pict, · 274 unmodified lines | ||
| 645 | 647 | } |
| 646 | 648 | |
| 647 | 649 | // so we can detect if frame_end was not called (find some nicer solution...) |
| 648 | − s->cur_pic.ptr = NULL; | |
| 650 | + ff_mpv_unref_picture(&s->cur_pic); | |
| 649 | 651 | } |
| 650 | 652 | |
| 651 | 653 | return avpkt->size; |
| @@ -662,6 +664,7 @@ const FFCodec ff_rv10_decoder = { · 10 unmodified lines | ||
| 662 | 664 | .close = ff_mpv_decode_close, |
| 663 | 665 | .p.capabilities = AV_CODEC_CAP_DR1, |
| 664 | 666 | .p.max_lowres = 3, |
| 667 | + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, | |
| 665 | 668 | }; |
| 666 | 669 | |
| 667 | 670 | const FFCodec ff_rv20_decoder = { |
| @@ -676,4 +679,5 @@ const FFCodec ff_rv20_decoder = { · 8 unmodified lines | ||
| 676 | 679 | .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, |
| 677 | 680 | .flush = ff_mpeg_flush, |
| 678 | 681 | .p.max_lowres = 3, |
| 682 | + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, | |
| 679 | 683 | }; |
| @@ -1510,7 +1510,9 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx) · 1509 unmodified lines | ||
| 1510 | 1510 | MpegEncContext *s = &r->s; |
| 1511 | 1511 | int ret; |
| 1512 | 1512 | |
| 1513 | − ff_mpv_decode_init(s, avctx); | |
| 1513 | + ret = ff_mpv_decode_init(s, avctx); | |
| 1514 | + if (ret < 0) | |
| 1515 | + return ret; | |
| 1514 | 1516 | s->out_format = FMT_H263; |
| 1515 | 1517 | |
| 1516 | 1518 | avctx->pix_fmt = AV_PIX_FMT_YUV420P; |
| @@ -1632,7 +1634,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, AVFrame *pict, · 115 unmodified lines | ||
| 1632 | 1634 | if (s->next_pic.ptr) { |
| 1633 | 1635 | if ((ret = av_frame_ref(pict, s->next_pic.ptr->f)) < 0) |
| 1634 | 1636 | return ret; |
| 1635 | − s->next_pic.ptr = NULL; | |
| 1637 | + ff_mpv_unref_picture(&s->next_pic); | |
| 1636 | 1638 | |
| 1637 | 1639 | *got_picture_ptr = 1; |
| 1638 | 1640 | } |
| @@ -60,7 +60,6 @@ typedef struct SVQ1EncContext { · 59 unmodified lines | ||
| 60 | 60 | * else, the idea is to make the motion estimation eventually independent |
| 61 | 61 | * of MpegEncContext, so this will be removed then. */ |
| 62 | 62 | MpegEncContext m; |
| 63 | − MPVPicture cur_pic, last_pic; | |
| 64 | 63 | AVCodecContext *avctx; |
| 65 | 64 | MECmpContext mecc; |
| 66 | 65 | HpelDSPContext hdsp; |
| @@ -327,8 +326,6 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane, · 260 unmodified lines | ||
| 327 | 326 | |
| 328 | 327 | if (s->pict_type == AV_PICTURE_TYPE_P) { |
| 329 | 328 | s->m.avctx = s->avctx; |
| 330 | − s->m.cur_pic.ptr = &s->cur_pic; | |
| 331 | − s->m.last_pic.ptr = &s->last_pic; | |
| 332 | 329 | s->m.last_pic.data[0] = ref_plane; |
| 333 | 330 | s->m.linesize = |
| 334 | 331 | s->m.last_pic.linesize[0] = |
| @@ -461,7 +461,9 @@ av_cold int ff_vc1_decode_init(AVCodecContext *avctx) · 460 unmodified lines | ||
| 461 | 461 | if (ret < 0) |
| 462 | 462 | return ret; |
| 463 | 463 | |
| 464 | − ff_mpv_decode_init(s, avctx); | |
| 464 | + ret = ff_mpv_decode_init(s, avctx); | |
| 465 | + if (ret < 0) | |
| 466 | + return ret; | |
| 465 | 467 | |
| 466 | 468 | avctx->pix_fmt = vc1_get_format(avctx); |
| 467 | 469 | |
| @@ -846,7 +848,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, AVFrame *pict, · 378 unmodified lines | ||
| 846 | 848 | if (s->low_delay == 0 && s->next_pic.ptr) { |
| 847 | 849 | if ((ret = av_frame_ref(pict, s->next_pic.ptr->f)) < 0) |
| 848 | 850 | return ret; |
| 849 | − s->next_pic.ptr = NULL; | |
| 851 | + ff_mpv_unref_picture(&s->next_pic); | |
| 850 | 852 | |
| 851 | 853 | *got_frame = 1; |
| 852 | 854 | } |
| @@ -997,7 +999,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, AVFrame *pict, · 144 unmodified lines | ||
| 997 | 999 | if (s->context_initialized && |
| 998 | 1000 | (s->width != avctx->coded_width || |
| 999 | 1001 | s->height != avctx->coded_height)) { |
| 1000 | − ff_vc1_decode_end(avctx); | |
| 1002 | + vc1_decode_reset(avctx); | |
| 1001 | 1003 | } |
| 1002 | 1004 | |
| 1003 | 1005 | if (!s->context_initialized) { |