// Copyright (c) 2007-2008 Fredrik Mellbin // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #include #include "ffms.h" #include "ffavisynth.h" #include "ffswscale.h" #include "ffpp.h" #include "utils.h" AVSValue __cdecl CreateFFIndex(AVSValue Args, void* UserData, IScriptEnvironment* Env) { FFMS_Init(); char ErrorMsg[1024]; unsigned MsgSize = sizeof(ErrorMsg); if (!Args[0].Defined()) Env->ThrowError("FFIndex: No source specified"); const char *Source = Args[0].AsString(); const char *CacheFile = Args[1].AsString(""); int TrackMask = Args[2].AsInt(0); const char *AudioFile = Args[3].AsString(""); bool OverWrite = Args[4].AsBool(false); std::string DefaultCache(Source); DefaultCache.append(".ffindex"); if (!strcmp(CacheFile, "")) CacheFile = DefaultCache.c_str(); if (!strcmp(AudioFile, "")) AudioFile = Source; // Return values // 0: Index already present // 1: Index generated // 2: Index forced to be overwritten FrameIndex *Index = FFMS_CreateFrameIndex(); if (OverWrite || FFMS_ReadIndex(CacheFile, Index, ErrorMsg, MsgSize)) { if (FFMS_MakeIndex(Source, Index, TrackMask, AudioFile, NULL, ErrorMsg, MsgSize)) Env->ThrowError("FFIndex: %s", ErrorMsg); if (FFMS_WriteIndex(CacheFile, Index, ErrorMsg, MsgSize)) Env->ThrowError("FFIndex: %s", ErrorMsg); FFMS_DestroyFrameIndex(Index); if (!OverWrite) return AVSValue(1); else return AVSValue(2); } else { FFMS_DestroyFrameIndex(Index); return AVSValue(0); } } AVSValue __cdecl CreateFFVideoSource(AVSValue Args, void* UserData, IScriptEnvironment* Env) { FFMS_Init(); char ErrorMsg[1024]; unsigned MsgSize = sizeof(ErrorMsg); if (!Args[0].Defined()) Env->ThrowError("FFVideoSource: No source specified"); const char *Source = Args[0].AsString(); int Track = Args[1].AsInt(-1); bool Cache = Args[2].AsBool(true); const char *CacheFile = Args[3].AsString(""); const char *PP = Args[4].AsString(""); int Threads = Args[5].AsInt(-1); const char *Timecodes = Args[6].AsString(""); int SeekMode = Args[7].AsInt(1); if (Track <= -2) Env->ThrowError("FFVideoSource: No video track selected"); if (SeekMode < -1 || SeekMode > 3) Env->ThrowError("FFVideoSource: Invalid seekmode selected"); if (Threads <= 0) Threads = GetNumberOfLogicalCPUs(); if (Threads < 1) Env->ThrowError("FFVideoSource: Invalid thread count"); std::string DefaultCache(Source); DefaultCache.append(".ffindex"); if (!strcmp(CacheFile, "")) CacheFile = DefaultCache.c_str(); FrameIndex *Index = FFMS_CreateFrameIndex(); if (Cache) { if (FFMS_ReadIndex(CacheFile, Index, ErrorMsg, MsgSize)) { if (FFMS_MakeIndex(Source, Index, 0, NULL, NULL, ErrorMsg, MsgSize)) Env->ThrowError("FFVideoSource: %s", ErrorMsg); if (Cache) if (FFMS_WriteIndex(CacheFile, Index, ErrorMsg, MsgSize)) Env->ThrowError("FFVideoSource: %s", ErrorMsg); } } AvisynthVideoSource *Filter = new AvisynthVideoSource(Source, Track, Index, PP, Threads, SeekMode, Env, ErrorMsg, MsgSize); if (strcmp(Timecodes, "")) if (FFMS_WriteTimecodes(FFMS_GetTITrackIndex(Index, Filter->GetTrack(), ErrorMsg, MsgSize), Timecodes, ErrorMsg, MsgSize)) Env->ThrowError("FFVideoSource: %s", ErrorMsg); return Filter; } AVSValue __cdecl CreateFFPP(AVSValue Args, void* UserData, IScriptEnvironment* Env) { return new FFPP(Args[0].AsClip(), Args[1].AsString(""), Env); } AVSValue __cdecl CreateSWScale(AVSValue Args, void* UserData, IScriptEnvironment* Env) { return new SWScale(Args[0].AsClip(), Args[1].AsInt(0), Args[2].AsInt(0), Args[3].AsString("BICUBIC"), Args[4].AsString(""), Env); } extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* Env) { Env->AddFunction("FFIndex", "[source]s[cachefile]s[trackmask]i[audiofile]s[overwrite]b", CreateFFIndex, 0); Env->AddFunction("FFVideoSource", "[source]s[track]i[cache]b[cachefile]s[pp]s[threads]i[timecodes]s[seekmode]i", CreateFFVideoSource, 0); Env->AddFunction("FFPP", "c[pp]s", CreateFFPP, 0); Env->AddFunction("SWScale", "c[width]i[height]i[resizer]s[colorspace]s", CreateSWScale, 0); return "FFmpegSource - The Second Coming"; }