From 38c420c7bde9fb0a2da9c0adb372fc47785b337e Mon Sep 17 00:00:00 2001 From: Fredrik Mellbin Date: Thu, 28 May 2009 19:33:14 +0000 Subject: [PATCH] FFMS2: Renamed a public api function just because I can Less access violations (AGAIN!) Dumping now implies indexing too Much better logic for automatically indexing files when FFAudioSource is used in avisynth Changed defaults for FFIndex Now FFmpeg's internal codec lists are used for lookup from the non-lavf based parts Originally committed to SVN as r2991. --- aegisub/FFmpegSource2/ffavisynth.cpp | 7 +- aegisub/FFmpegSource2/ffavsfilters.cpp | 43 +++- aegisub/FFmpegSource2/ffms.cpp | 30 ++- aegisub/FFmpegSource2/ffms.h | 2 +- aegisub/FFmpegSource2/ffms2.html | 25 +- aegisub/FFmpegSource2/ffms2rt.cpp | 2 +- aegisub/FFmpegSource2/ffmsindex.cpp | 8 +- aegisub/FFmpegSource2/utils.cpp | 318 +++---------------------- 8 files changed, 122 insertions(+), 313 deletions(-) diff --git a/aegisub/FFmpegSource2/ffavisynth.cpp b/aegisub/FFmpegSource2/ffavisynth.cpp index a4fc7df72..3c6473d0a 100644 --- a/aegisub/FFmpegSource2/ffavisynth.cpp +++ b/aegisub/FFmpegSource2/ffavisynth.cpp @@ -93,18 +93,17 @@ void AvisynthVideoSource::InitOutputFormat(IScriptEnvironment *Env) { VI.height = VP->Height; // Crop to obey avisynth's even width/height requirements - if (VP->VPixelFormat == FFMS_GetPixFmt("yuvj420p") || VP->VPixelFormat == FFMS_GetPixFmt("yuv420p")) { + if (VI.pixel_type == VideoInfo::CS_I420) { VI.height -= VI.height & 1; VI.width -= VI.width & 1; } - if (VP->VPixelFormat == FFMS_GetPixFmt("yuyv422")) { + if (VI.pixel_type == VideoInfo::CS_YUY2) { VI.width -= VI.width & 1; } } PVideoFrame AvisynthVideoSource::OutputFrame(const TAVFrameLite *Frame, IScriptEnvironment *Env) { - // Yes, this function is overly complex and could probably be simplified TAVFrameLite *SrcPicture = const_cast(Frame); PVideoFrame Dst = Env->NewVideoFrame(VI); @@ -114,7 +113,7 @@ PVideoFrame AvisynthVideoSource::OutputFrame(const TAVFrameLite *Frame, IScriptE Env->BitBlt(Dst->GetWritePtr(PLANAR_V), Dst->GetPitch(PLANAR_V), SrcPicture->Data[2], SrcPicture->Linesize[2], Dst->GetRowSize(PLANAR_V), Dst->GetHeight(PLANAR_V)); } else if (VI.IsRGB()) { Env->BitBlt(Dst->GetWritePtr() + Dst->GetPitch() * (Dst->GetHeight() - 1), -Dst->GetPitch(), SrcPicture->Data[0], SrcPicture->Linesize[0], Dst->GetRowSize(), Dst->GetHeight()); - } else { + } else { // YUY2 Env->BitBlt(Dst->GetWritePtr(), Dst->GetPitch(), SrcPicture->Data[0], SrcPicture->Linesize[0], Dst->GetRowSize(), Dst->GetHeight()); } diff --git a/aegisub/FFmpegSource2/ffavsfilters.cpp b/aegisub/FFmpegSource2/ffavsfilters.cpp index b90a5b21a..6329d74f1 100644 --- a/aegisub/FFmpegSource2/ffavsfilters.cpp +++ b/aegisub/FFmpegSource2/ffavsfilters.cpp @@ -42,7 +42,7 @@ static AVSValue __cdecl CreateFFIndex(AVSValue Args, void* UserData, IScriptEnvi const char *Source = Args[0].AsString(); const char *CacheFile = Args[1].AsString(""); - int IndexMask = Args[2].AsInt(0); + int IndexMask = Args[2].AsInt(-1); int DumpMask = Args[3].AsInt(0); const char *AudioFile = Args[4].AsString(""); bool OverWrite = Args[5].AsBool(false); @@ -65,16 +65,16 @@ static AVSValue __cdecl CreateFFIndex(AVSValue Args, void* UserData, IScriptEnvi if (!(Index = FFMS_MakeIndex(Source, IndexMask, DumpMask, FFMS_DefaultAudioFilename, NULL, true, NULL, NULL, ErrorMsg, MsgSize))) Env->ThrowError("FFIndex: %s", ErrorMsg); if (FFMS_WriteIndex(CacheFile, Index, ErrorMsg, MsgSize)) { - FFMS_DestroyFFIndex(Index); + FFMS_DestroyIndex(Index); Env->ThrowError("FFIndex: %s", ErrorMsg); } - FFMS_DestroyFFIndex(Index); + FFMS_DestroyIndex(Index); if (!OverWrite) return AVSValue(1); else return AVSValue(2); } else { - FFMS_DestroyFFIndex(Index); + FFMS_DestroyIndex(Index); return AVSValue(0); } } @@ -127,7 +127,7 @@ static AVSValue __cdecl CreateFFVideoSource(AVSValue Args, void* UserData, IScri if (Cache) if (FFMS_WriteIndex(CacheFile, Index, ErrorMsg, MsgSize)) { - FFMS_DestroyFFIndex(Index); + FFMS_DestroyIndex(Index); Env->ThrowError("FFVideoSource: %s", ErrorMsg); } } @@ -139,7 +139,7 @@ static AVSValue __cdecl CreateFFVideoSource(AVSValue Args, void* UserData, IScri if (strcmp(Timecodes, "")) { if (FFMS_WriteTimecodes(FFMS_GetTrackFromIndex(Index, Track), Timecodes, ErrorMsg, MsgSize)) { - FFMS_DestroyFFIndex(Index); + FFMS_DestroyIndex(Index); Env->ThrowError("FFVideoSource: %s", ErrorMsg); } } @@ -149,11 +149,11 @@ static AVSValue __cdecl CreateFFVideoSource(AVSValue Args, void* UserData, IScri try { Filter = new AvisynthVideoSource(Source, Track, Index, FPSNum, FPSDen, PP, Threads, SeekMode, Env, ErrorMsg, MsgSize); } catch (...) { - FFMS_DestroyFFIndex(Index); + FFMS_DestroyIndex(Index); throw; } - FFMS_DestroyFFIndex(Index); + FFMS_DestroyIndex(Index); return Filter; } @@ -182,13 +182,34 @@ static AVSValue __cdecl CreateFFAudioSource(AVSValue Args, void* UserData, IScri FFIndex *Index = NULL; if (Cache) Index = FFMS_ReadIndex(CacheFile, ErrorMsg, MsgSize); + + // Index needs to be remade if it is an unindexed audio track + if (Index && Track >= 0 && Track < FFMS_GetNumTracks(Index) + && FFMS_GetTrackType(FFMS_GetTrackFromIndex(Index, Track)) == FFMS_TYPE_AUDIO + && FFMS_GetNumFrames(FFMS_GetTrackFromIndex(Index, Track)) == 0) { + FFMS_DestroyIndex(Index); + Index = NULL; + } + + // More complicated for finding a default track, reindex the file if at least one audio track exists + if (Index && FFMS_GetFirstTrackOfType(Index, FFMS_TYPE_AUDIO, ErrorMsg, MsgSize) >= 0 + && FFMS_GetFirstIndexedTrackOfType(Index, FFMS_TYPE_AUDIO, ErrorMsg, MsgSize) < 0) { + for (int i = 0; i < FFMS_GetNumTracks(Index); i++) { + if (FFMS_GetTrackType(FFMS_GetTrackFromIndex(Index, i)) == FFMS_TYPE_AUDIO) { + FFMS_DestroyIndex(Index); + Index = NULL; + break; + } + } + } + if (!Index) { if (!(Index = FFMS_MakeIndex(Source, -1, 0, NULL, NULL, true, NULL, NULL, ErrorMsg, MsgSize))) Env->ThrowError("FFAudioSource: %s", ErrorMsg); if (Cache) if (FFMS_WriteIndex(CacheFile, Index, ErrorMsg, MsgSize)) { - FFMS_DestroyFFIndex(Index); + FFMS_DestroyIndex(Index); Env->ThrowError("FFAudioSource: %s", ErrorMsg); } } @@ -203,11 +224,11 @@ static AVSValue __cdecl CreateFFAudioSource(AVSValue Args, void* UserData, IScri try { Filter = new AvisynthAudioSource(Source, Track, Index, Env, ErrorMsg, MsgSize); } catch (...) { - FFMS_DestroyFFIndex(Index); + FFMS_DestroyIndex(Index); throw; } - FFMS_DestroyFFIndex(Index); + FFMS_DestroyIndex(Index); return Filter; } diff --git a/aegisub/FFmpegSource2/ffms.cpp b/aegisub/FFmpegSource2/ffms.cpp index 4ff2f4477..5f91316d6 100644 --- a/aegisub/FFmpegSource2/ffms.cpp +++ b/aegisub/FFmpegSource2/ffms.cpp @@ -50,6 +50,16 @@ FFMS_API(void) FFMS_SetLogLevel(int Level) { } FFMS_API(FFVideo *) FFMS_CreateVideoSource(const char *SourceFile, int Track, FFIndex *Index, const char *PP, int Threads, int SeekMode, char *ErrorMsg, unsigned MsgSize) { + if (Track < 0 || Track >= Index->size()) { + _snprintf(ErrorMsg, MsgSize, "Out of bounds track index selected"); + return NULL; + } + + if (Index->at(Track).TT != FFMS_TYPE_VIDEO) { + _snprintf(ErrorMsg, MsgSize, "Not a video track"); + return NULL; + } + try { switch (Index->Decoder) { case 0: return new FFLAVFVideo(SourceFile, Track, Index, PP, Threads, SeekMode, ErrorMsg, MsgSize); @@ -68,6 +78,16 @@ FFMS_API(FFVideo *) FFMS_CreateVideoSource(const char *SourceFile, int Track, FF } FFMS_API(FFAudio *) FFMS_CreateAudioSource(const char *SourceFile, int Track, FFIndex *Index, char *ErrorMsg, unsigned MsgSize) { + if (Track < 0 || Track >= Index->size()) { + _snprintf(ErrorMsg, MsgSize, "Out of bounds track index selected"); + return NULL; + } + + if (Index->at(Track).TT != FFMS_TYPE_AUDIO) { + _snprintf(ErrorMsg, MsgSize, "Not an audio track"); + return NULL; + } + try { switch (Index->Decoder) { case 0: return new FFLAVFAudio(SourceFile, Track, Index, ErrorMsg, MsgSize); @@ -121,7 +141,7 @@ FFMS_API(void) FFMS_ResetOutputFormat(FFVideo *V) { V->ResetOutputFormat(); } -FFMS_API(void) FFMS_DestroyFFIndex(FFIndex *Index) { +FFMS_API(void) FFMS_DestroyIndex(FFIndex *Index) { delete Index; } @@ -197,11 +217,11 @@ FFMS_API(FFIndex *) FFMS_MakeIndex(const char *SourceFile, int IndexMask, int Du } FFMS_API(int) FFMS_DefaultAudioFilename(const char *SourceFile, int Track, const TAudioProperties *AP, char *FileName, void *Private) { - const char * FormatString = "%s.%d2.w64"; + const char * FormatString = "%s.Track%d.delay%dms.w64"; if (FileName == NULL) - return _snprintf(NULL, 0, FormatString, SourceFile, Track) + 1; + return _snprintf(NULL, 0, FormatString, SourceFile, Track, (int)AP->FirstTime) + 1; else - return _snprintf(FileName, 999999, FormatString, SourceFile, Track) + 1; + return _snprintf(FileName, 999999, FormatString, SourceFile, Track, (int)AP->FirstTime) + 1; } FFMS_API(FFIndexer *) FFMS_CreateIndexer(const char *SourceFile, char *ErrorMsg, unsigned MsgSize) { @@ -213,7 +233,7 @@ FFMS_API(FFIndexer *) FFMS_CreateIndexer(const char *SourceFile, char *ErrorMsg, } FFMS_API(FFIndex *) FFMS_DoIndexing(FFIndexer *Indexer, int IndexMask, int DumpMask, TAudioNameCallback ANC, void *ANCPrivate, bool IgnoreDecodeErrors, TIndexCallback IC, void *ICPrivate, char *ErrorMsg, unsigned MsgSize) { - Indexer->SetIndexMask(IndexMask); + Indexer->SetIndexMask(IndexMask | DumpMask); Indexer->SetDumpMask(DumpMask); Indexer->SetIgnoreDecodeErrors(IgnoreDecodeErrors); Indexer->SetProgressCallback(IC, ICPrivate); diff --git a/aegisub/FFmpegSource2/ffms.h b/aegisub/FFmpegSource2/ffms.h index 50d0c8886..64ac35326 100644 --- a/aegisub/FFmpegSource2/ffms.h +++ b/aegisub/FFmpegSource2/ffms.h @@ -136,7 +136,7 @@ FFMS_API(const TAVFrameLite *) FFMS_GetFrameByTime(FFVideo *V, double Time, char FFMS_API(int) FFMS_GetAudio(FFAudio *A, void *Buf, int64_t Start, int64_t Count, char *ErrorMsg, unsigned MsgSize); FFMS_API(int) FFMS_SetOutputFormat(FFVideo *V, int64_t TargetFormats, int Width, int Height, char *ErrorMsg, unsigned MsgSize); FFMS_API(void) FFMS_ResetOutputFormat(FFVideo *V); -FFMS_API(void) FFMS_DestroyFFIndex(FFIndex *Index); +FFMS_API(void) FFMS_DestroyIndex(FFIndex *Index); FFMS_API(int) FFMS_GetFirstTrackOfType(FFIndex *Index, int TrackType, char *ErrorMsg, unsigned MsgSize); FFMS_API(int) FFMS_GetFirstIndexedTrackOfType(FFIndex *Index, int TrackType, char *ErrorMsg, unsigned MsgSize); FFMS_API(int) FFMS_GetNumTracks(FFIndex *Index); diff --git a/aegisub/FFmpegSource2/ffms2.html b/aegisub/FFmpegSource2/ffms2.html index 34ccc8f42..4e8b08f2d 100644 --- a/aegisub/FFmpegSource2/ffms2.html +++ b/aegisub/FFmpegSource2/ffms2.html @@ -12,9 +12,26 @@ Opens files using ffmpeg and nothing else. May be frame accurate on good days. T

Known issues

Compatibility - Video

@@ -36,7 +53,7 @@ Opens files using ffmpeg and nothing else. May be frame accurate on good days. T

Usage

-FFIndex(string source, string cachefile = source + ".ffindex", int indexmask = 0, int dumpmask = 0, string audiofile = source, bool overwrite = false)
+FFIndex(string source, string cachefile = source + ".ffindex", int indexmask = -1, int dumpmask = 0, string audiofile = source, bool overwrite = false)
Used to invoke indexing separately and to write audio tracks to disk as wave64 files

@@ -239,12 +256,16 @@ Note that --enable-w32threads or --enable-pthreads is required for multithreaded

Changes