diff options
author | Peter Schlaile <peter@schlaile.de> | 2012-12-02 19:15:44 +0400 |
---|---|---|
committer | Peter Schlaile <peter@schlaile.de> | 2012-12-02 19:15:44 +0400 |
commit | ecf89326e1f2650fe8fcd792f9bdabf3397e460d (patch) | |
tree | 22f7d1272d1d77866db85e4ee473e0fb3ef819c2 /source/blender/imbuf/intern | |
parent | d7960b8fd4adf5e066e0040203d1595d9b6dfc52 (diff) |
== FFMPEG ==
This fixes a memory leak caused by the last packet on stream EOF not freed.
(Memory leak occurs on ffmpeg heap managed by av_malloc / av_free, so it is
invisible to Blender)
Also: clean up the code a little bit (anim->next_packet was never really used,
so could be moved into a local variable)
Diffstat (limited to 'source/blender/imbuf/intern')
-rw-r--r-- | source/blender/imbuf/intern/IMB_anim.h | 1 | ||||
-rw-r--r-- | source/blender/imbuf/intern/anim_movie.c | 59 | ||||
-rw-r--r-- | source/blender/imbuf/intern/indexer.c | 9 |
3 files changed, 30 insertions, 39 deletions
diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h index ed349e8f7eb..684a1476e44 100644 --- a/source/blender/imbuf/intern/IMB_anim.h +++ b/source/blender/imbuf/intern/IMB_anim.h @@ -178,7 +178,6 @@ struct anim { struct ImBuf *last_frame; int64_t last_pts; int64_t next_pts; - AVPacket next_packet; #endif #ifdef WITH_REDCODE diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index 5b64416c309..900ad6c6313 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -557,7 +557,6 @@ static int startffmpeg(struct anim *anim) anim->last_frame = 0; anim->last_pts = -1; anim->next_pts = -1; - anim->next_packet.stream_index = -1; anim->pFormatCtx = pFormatCtx; anim->pCodecCtx = pCodecCtx; @@ -764,41 +763,39 @@ static void ffmpeg_postprocess(struct anim *anim) } } -/* decode one video frame also considering the packet read into next_packet */ +/* decode one video frame */ static int ffmpeg_decode_video_frame(struct anim *anim) { int rval = 0; + AVPacket next_packet; + + memset(&next_packet, 0, sizeof(AVPacket)); av_log(anim->pFormatCtx, AV_LOG_DEBUG, " DECODE VIDEO FRAME\n"); - if (anim->next_packet.stream_index == anim->videoStream) { - av_free_packet(&anim->next_packet); - anim->next_packet.stream_index = -1; - } - - while ((rval = av_read_frame(anim->pFormatCtx, &anim->next_packet)) >= 0) { + while ((rval = av_read_frame(anim->pFormatCtx, &next_packet)) >= 0) { av_log(anim->pFormatCtx, AV_LOG_DEBUG, "%sREAD: strID=%d (VID: %d) dts=%lld pts=%lld " "%s\n", - (anim->next_packet.stream_index == anim->videoStream) + (next_packet.stream_index == anim->videoStream) ? "->" : " ", - anim->next_packet.stream_index, + next_packet.stream_index, anim->videoStream, - (anim->next_packet.dts == AV_NOPTS_VALUE) ? -1 : - (long long int)anim->next_packet.dts, - (anim->next_packet.pts == AV_NOPTS_VALUE) ? -1 : - (long long int)anim->next_packet.pts, - (anim->next_packet.flags & AV_PKT_FLAG_KEY) ? + (next_packet.dts == AV_NOPTS_VALUE) ? -1 : + (long long int)next_packet.dts, + (next_packet.pts == AV_NOPTS_VALUE) ? -1 : + (long long int)next_packet.pts, + (next_packet.flags & AV_PKT_FLAG_KEY) ? " KEY" : ""); - if (anim->next_packet.stream_index == anim->videoStream) { + if (next_packet.stream_index == anim->videoStream) { anim->pFrameComplete = 0; avcodec_decode_video2( anim->pCodecCtx, anim->pFrame, &anim->pFrameComplete, - &anim->next_packet); + &next_packet); if (anim->pFrameComplete) { anim->next_pts = av_get_pts_from_frame( @@ -816,20 +813,24 @@ static int ffmpeg_decode_video_frame(struct anim *anim) break; } } - av_free_packet(&anim->next_packet); - anim->next_packet.stream_index = -1; + av_free_packet(&next_packet); } + + /* this sets size and data fields to zero, + which is necessary to decode the remaining data + in the decoder engine after EOF. It also prevents a memory + leak, since av_read_frame spills out a full size packet even + on EOF... (and: it's save to call on NULL packets) */ + + av_free_packet(&next_packet); if (rval == AVERROR_EOF) { - anim->next_packet.size = 0; - anim->next_packet.data = 0; - anim->pFrameComplete = 0; avcodec_decode_video2( anim->pCodecCtx, anim->pFrame, &anim->pFrameComplete, - &anim->next_packet); + &next_packet); if (anim->pFrameComplete) { anim->next_pts = av_get_pts_from_frame( @@ -849,8 +850,6 @@ static int ffmpeg_decode_video_frame(struct anim *anim) } if (rval < 0) { - anim->next_packet.stream_index = -1; - av_log(anim->pFormatCtx, AV_LOG_ERROR, " DECODE READ FAILED: av_read_frame() " "returned error: %d\n", rval); @@ -1087,13 +1086,6 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position, anim->next_pts = -1; - if (anim->next_packet.stream_index == anim->videoStream) { - av_free_packet(&anim->next_packet); - anim->next_packet.stream_index = -1; - } - - /* memset(anim->pFrame, ...) ?? */ - if (ret >= 0) { ffmpeg_decode_video_frame_scan(anim, pts_to_search); } @@ -1140,9 +1132,6 @@ static void free_anim_ffmpeg(struct anim *anim) av_free(anim->pFrameDeinterlaced); sws_freeContext(anim->img_convert_ctx); IMB_freeImBuf(anim->last_frame); - if (anim->next_packet.stream_index != -1) { - av_free_packet(&anim->next_packet); - } } anim->duration = 0; } diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index 38bd28452f3..277f50bcdbc 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -912,6 +912,8 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context, AVPacket next_packet; uint64_t stream_size; + memset(&next_packet, 0, sizeof(AVPacket)); + in_frame = avcodec_alloc_frame(); stream_size = avio_size(context->iFormatCtx->pb); @@ -959,12 +961,13 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context, * according to ffmpeg docs using 0-size packets. * * At least, if we haven't already stopped... */ + + /* this creates the 0-size packet and prevents a memory leak. */ + av_free_packet(&next_packet); + if (!*stop) { int frame_finished; - next_packet.size = 0; - next_packet.data = 0; - do { frame_finished = 0; |