From 4683c5a9d0d4ebe9642431d953afbacec35cebaf Mon Sep 17 00:00:00 2001
From: Fredrik Mellbin <fredrik.mellbin@gmail.com>
Date: Wed, 1 Oct 2008 19:07:59 +0000
Subject: [PATCH] FFmpegSource2: crash less

Originally committed to SVN as r2404.
---
 FFmpegSource2/ffavsfilters.cpp  | 44 ++++++++++++++++-----------------
 FFmpegSource2/ffvideosource.cpp |  2 +-
 FFmpegSource2/indexing.cpp      | 18 ++++++++++----
 3 files changed, 36 insertions(+), 28 deletions(-)

diff --git a/FFmpegSource2/ffavsfilters.cpp b/FFmpegSource2/ffavsfilters.cpp
index 99b843c1d..65866aad5 100644
--- a/FFmpegSource2/ffavsfilters.cpp
+++ b/FFmpegSource2/ffavsfilters.cpp
@@ -118,18 +118,18 @@ AVSValue __cdecl CreateFFVideoSource(AVSValue Args, void* UserData, IScriptEnvir
 	if (!strcmp(CacheFile, ""))
 		CacheFile = DefaultCache.c_str();
 
-	FrameIndex *Index;
-	if (Cache) {
-		if (!(Index = FFMS_ReadIndex(CacheFile, ErrorMsg, MsgSize))) {
-			if (!(Index = FFMS_MakeIndex(Source, 0, 0, NULL, true, NULL, NULL, ErrorMsg, MsgSize)))
-				Env->ThrowError("FFVideoSource: %s", ErrorMsg);
+	FrameIndex *Index = NULL;
+	if (Cache)
+		Index = FFMS_ReadIndex(CacheFile, ErrorMsg, MsgSize);
+	if (!Index) {
+		if (!(Index = FFMS_MakeIndex(Source, 0, 0, NULL, true, NULL, NULL, ErrorMsg, MsgSize)))
+			Env->ThrowError("FFVideoSource: %s", ErrorMsg);
 
-			if (Cache)
-				if (FFMS_WriteIndex(CacheFile, Index, ErrorMsg, MsgSize)) {
-					FFMS_DestroyFrameIndex(Index);
-					Env->ThrowError("FFVideoSource: %s", ErrorMsg);
-				}
-		}
+		if (Cache)
+			if (FFMS_WriteIndex(CacheFile, Index, ErrorMsg, MsgSize)) {
+				FFMS_DestroyFrameIndex(Index);
+				Env->ThrowError("FFVideoSource: %s", ErrorMsg);
+			}
 	}
 
 	if (Track == -1)
@@ -179,18 +179,18 @@ AVSValue __cdecl CreateFFAudioSource(AVSValue Args, void* UserData, IScriptEnvir
 	if (!strcmp(CacheFile, ""))
 		CacheFile = DefaultCache.c_str();
 
-	FrameIndex *Index;
-	if (Cache) {
-		if (!(Index = FFMS_ReadIndex(CacheFile, ErrorMsg, MsgSize))) {
-			if (!(Index = FFMS_MakeIndex(Source, -1, 0, CacheFile, true, NULL, NULL, ErrorMsg, MsgSize)))
-				Env->ThrowError("FFAudioSource: %s", ErrorMsg);
+	FrameIndex *Index = NULL;
+	if (Cache)
+		Index = FFMS_ReadIndex(CacheFile, ErrorMsg, MsgSize);
+	if (!Index) {
+		if (!(Index = FFMS_MakeIndex(Source, -1, 0, CacheFile, true, NULL, NULL, ErrorMsg, MsgSize)))
+			Env->ThrowError("FFAudioSource: %s", ErrorMsg);
 
-			if (Cache)
-				if (FFMS_WriteIndex(CacheFile, Index, ErrorMsg, MsgSize)) {
-					FFMS_DestroyFrameIndex(Index);
-					Env->ThrowError("FFAudioSource: %s", ErrorMsg);
-				}
-		}
+		if (Cache)
+			if (FFMS_WriteIndex(CacheFile, Index, ErrorMsg, MsgSize)) {
+				FFMS_DestroyFrameIndex(Index);
+				Env->ThrowError("FFAudioSource: %s", ErrorMsg);
+			}
 	}
 
 	if (Track == -1)
diff --git a/FFmpegSource2/ffvideosource.cpp b/FFmpegSource2/ffvideosource.cpp
index f0ed36654..c816451b1 100644
--- a/FFmpegSource2/ffvideosource.cpp
+++ b/FFmpegSource2/ffvideosource.cpp
@@ -110,7 +110,7 @@ VideoBase::~VideoBase() {
 }
 
 AVFrameLite *VideoBase::GetFrameByTime(double Time, char *ErrorMsg, unsigned MsgSize) {
-	int Frame = Frames.ClosestFrameFromDTS((Time * Frames.TB.Num) / Frames.TB.Den);
+	int Frame = Frames.ClosestFrameFromDTS((Time * Frames.TB.Num) / Frames.TB.Den + 0.5);
 	return GetFrame(Frame, ErrorMsg, MsgSize);
 }
 
diff --git a/FFmpegSource2/indexing.cpp b/FFmpegSource2/indexing.cpp
index 520bae729..44c3e8aea 100644
--- a/FFmpegSource2/indexing.cpp
+++ b/FFmpegSource2/indexing.cpp
@@ -60,7 +60,7 @@ public:
 
 	FFAudioContext() {
 		W64W = NULL;
-		CTX = 0;
+		CTX = NULL;
 		CurrentSample = 0;
 	}
 
@@ -206,6 +206,8 @@ static FrameIndex *MakeMatroskaIndex(const char *SourceFile, int IndexMask, int
 			if (mkv_GetTrackInfo(MF, i)->CompEnabled) {
 				AudioContexts[i].CS = cs_Create(MF, i, ErrorMessage, sizeof(ErrorMessage));
 				if (AudioContexts[i].CS == NULL) {
+					av_free(AudioCodecContext);
+					AudioContexts[i].CTX = NULL;
 					_snprintf(ErrorMsg, MsgSize, "Can't create decompressor: %s", ErrorMessage);
 					return NULL;
 				}
@@ -213,13 +215,17 @@ static FrameIndex *MakeMatroskaIndex(const char *SourceFile, int IndexMask, int
 
 			AVCodec *AudioCodec = avcodec_find_decoder(MatroskaToFFCodecID(mkv_GetTrackInfo(MF, i)));
 			if (AudioCodec == NULL) {
-					_snprintf(ErrorMsg, MsgSize, "Audio codec not found");
-					return NULL;
+				av_free(AudioCodecContext);
+				AudioContexts[i].CTX = NULL;
+				_snprintf(ErrorMsg, MsgSize, "Audio codec not found");
+				return NULL;
 			}
 
 			if (avcodec_open(AudioCodecContext, AudioCodec) < 0) {
-					_snprintf(ErrorMsg, MsgSize, "Could not open audio codec");
-					return NULL;
+				av_free(AudioCodecContext);
+				AudioContexts[i].CTX = NULL;
+				_snprintf(ErrorMsg, MsgSize, "Could not open audio codec");
+				return NULL;
 			}
 		} else {
 			IndexMask &= ~(1 << i);
@@ -350,6 +356,8 @@ FrameIndex *MakeIndex(const char *SourceFile, int IndexMask, int DumpMask, const
 				_snprintf(ErrorMsg, MsgSize, "Could not open audio codec");
 				return NULL;
 			}
+
+			AudioContexts[i].CTX = AudioCodecContext;
 		} else {
 			IndexMask &= ~(1 << i);
 		}
-- 
GitLab