Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Schlaile <peter@schlaile.de>2012-12-02 19:15:44 +0400
committerPeter Schlaile <peter@schlaile.de>2012-12-02 19:15:44 +0400
commitecf89326e1f2650fe8fcd792f9bdabf3397e460d (patch)
tree22f7d1272d1d77866db85e4ee473e0fb3ef819c2 /source/blender/imbuf
parentd7960b8fd4adf5e066e0040203d1595d9b6dfc52 (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')
-rw-r--r--source/blender/imbuf/intern/IMB_anim.h1
-rw-r--r--source/blender/imbuf/intern/anim_movie.c59
-rw-r--r--source/blender/imbuf/intern/indexer.c9
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;