[Bf-blender-cvs] [e435593] master: Fix ffmpeg memory leaks

Campbell Barton noreply at git.blender.org
Fri Oct 23 09:46:46 CEST 2015


Commit: e435593fc02ca6c73f6e5152e5a3d017af8d14e2
Author: Campbell Barton
Date:   Fri Oct 23 18:36:46 2015 +1100
Branches: master
https://developer.blender.org/rBe435593fc02ca6c73f6e5152e5a3d017af8d14e2

Fix ffmpeg memory leaks

- audio_stream wasn't freed.
- audio/video stream + context weren't freed on failure.

===================================================================

M	source/blender/blenkernel/intern/writeffmpeg.c

===================================================================

diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 1f602ea..35fd94d 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -847,7 +847,10 @@ static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int
 		BKE_report(reports, RPT_ERROR, "Error opening output file");
 		return 0;
 	}
-	
+
+
+	/* Returns after this must 'goto fail;' */
+
 	of->oformat = fmt;
 	of->packet_size = rd->ffcodecdata.mux_packet_size;
 	if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE) {
@@ -900,15 +903,15 @@ static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int
 	if (fmt->video_codec == AV_CODEC_ID_DVVIDEO) {
 		if (rectx != 720) {
 			BKE_report(reports, RPT_ERROR, "Render width has to be 720 pixels for DV!");
-			return 0;
+			goto fail;
 		}
 		if (rd->frs_sec != 25 && recty != 480) {
 			BKE_report(reports, RPT_ERROR, "Render height has to be 480 pixels for DV-NTSC!");
-			return 0;
+			goto fail;
 		}
 		if (rd->frs_sec == 25 && recty != 576) {
 			BKE_report(reports, RPT_ERROR, "Render height has to be 576 pixels for DV-PAL!");
-			return 0;
+			goto fail;
 		}
 	}
 	
@@ -916,8 +919,7 @@ static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int
 		fmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
 		if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE && rd->ffcodecdata.audio_mixrate != 48000 && rd->ffcodecdata.audio_channels != 2) {
 			BKE_report(reports, RPT_ERROR, "FFMPEG only supports 48khz / stereo audio for DV!");
-			av_dict_free(&opts);
-			return 0;
+			goto fail;
 		}
 	}
 	
@@ -929,9 +931,7 @@ static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int
 				BKE_report(reports, RPT_ERROR, error);
 			else
 				BKE_report(reports, RPT_ERROR, "Error initializing video stream");
-
-			av_dict_free(&opts);
-			return 0;
+			goto fail;
 		}
 	}
 
@@ -942,22 +942,18 @@ static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int
 				BKE_report(reports, RPT_ERROR, error);
 			else
 				BKE_report(reports, RPT_ERROR, "Error initializing audio stream");
-			av_dict_free(&opts);
-			return 0;
+			goto fail;
 		}
 	}
 	if (!(fmt->flags & AVFMT_NOFILE)) {
 		if (avio_open(&of->pb, name, AVIO_FLAG_WRITE) < 0) {
 			BKE_report(reports, RPT_ERROR, "Could not open file for writing");
-			av_dict_free(&opts);
-			return 0;
+			goto fail;
 		}
 	}
 	if (avformat_write_header(of, NULL) < 0) {
 		BKE_report(reports, RPT_ERROR, "Could not initialize streams, probably unsupported codec combination");
-		av_dict_free(&opts);
-		avio_close(of->pb);
-		return 0;
+		goto fail;
 	}
 
 	context->outfile = of;
@@ -965,6 +961,26 @@ static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int
 	av_dict_free(&opts);
 
 	return 1;
+
+
+fail:
+	if (of->pb) {
+		avio_close(of->pb);
+	}
+
+	if (context->video_stream && context->video_stream->codec) {
+		avcodec_close(context->video_stream->codec);
+		context->video_stream = NULL;
+	}
+
+	if (context->audio_stream && context->audio_stream->codec) {
+		avcodec_close(context->audio_stream->codec);
+		context->audio_stream = NULL;
+	}
+
+	av_dict_free(&opts);
+	avformat_free_context(of);
+	return 0;
 }
 
 /**
@@ -1232,6 +1248,11 @@ static void end_ffmpeg_impl(FFMpegContext *context, int is_autosplit)
 		context->video_stream = 0;
 	}
 
+	if (context->audio_stream && context->audio_stream->codec) {
+		avcodec_close(context->audio_stream->codec);
+		context->audio_stream = 0;
+	}
+
 	/* free the temp buffer */
 	if (context->current_frame) {
 		delete_picture(context->current_frame);




More information about the Bf-blender-cvs mailing list