diff options
author | Janne Grunau <janne-libav@jannau.net> | 2012-01-10 15:08:20 +0100 |
---|---|---|
committer | Janne Grunau <janne-libav@jannau.net> | 2012-01-10 22:51:56 +0100 |
commit | 3ab770001817e0f52114a9876819f07fcd8ed93a (patch) | |
tree | 6fc11dd2cdc5f692a6eb6631cd79cc0c17a85103 /libavcodec/mpegvideo.c | |
parent | 17ce52912f59a74ecc265e062578fb1181456e18 (diff) | |
download | ffmpeg-3ab770001817e0f52114a9876819f07fcd8ed93a.tar.gz |
mpegvideo: claim ownership of referenced pictures
Under certain conditions pictures could be released before they were
returned with frame-threading. Broken mv computation in the upcoming
rv34 frame-threading patch was caused by this.
To prevent contexts from running out of available pictures the loop
releasing "unused" pictures has to be run for B frames too.
Diffstat (limited to 'libavcodec/mpegvideo.c')
-rw-r--r-- | libavcodec/mpegvideo.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index e4c45886dc..f711d36aec 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -1170,25 +1170,26 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) s->codec_id == CODEC_ID_SVQ3); /* mark & release old frames */ - if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr && - s->last_picture_ptr != s->next_picture_ptr && - s->last_picture_ptr->f.data[0]) { - if (s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3) { + if (s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3) { + if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr && + s->last_picture_ptr != s->next_picture_ptr && + s->last_picture_ptr->f.data[0]) { if (s->last_picture_ptr->owner2 == s) free_frame_buffer(s, s->last_picture_ptr); + } - /* release forgotten pictures */ - /* if (mpeg124/h263) */ - if (!s->encoding) { - for (i = 0; i < s->picture_count; i++) { - if (s->picture[i].owner2 == s && s->picture[i].f.data[0] && - &s->picture[i] != s->next_picture_ptr && - s->picture[i].f.reference) { - if (!(avctx->active_thread_type & FF_THREAD_FRAME)) - av_log(avctx, AV_LOG_ERROR, - "releasing zombie picture\n"); - free_frame_buffer(s, &s->picture[i]); - } + /* release forgotten pictures */ + /* if (mpeg124/h263) */ + if (!s->encoding) { + for (i = 0; i < s->picture_count; i++) { + if (s->picture[i].owner2 == s && s->picture[i].f.data[0] && + &s->picture[i] != s->last_picture_ptr && + &s->picture[i] != s->next_picture_ptr && + s->picture[i].f.reference) { + if (!(avctx->active_thread_type & FF_THREAD_FRAME)) + av_log(avctx, AV_LOG_ERROR, + "releasing zombie picture\n"); + free_frame_buffer(s, &s->picture[i]); } } } @@ -1295,6 +1296,14 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) if (s->next_picture_ptr) ff_copy_picture(&s->next_picture, s->next_picture_ptr); + if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME) && + (s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3)) { + if (s->next_picture_ptr) + s->next_picture_ptr->owner2 = s; + if (s->last_picture_ptr) + s->last_picture_ptr->owner2 = s; + } + assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr && s->last_picture_ptr->f.data[0])); |