diff --git a/avs_core/filters/AviSource/AVIReadHandler.cpp b/avs_core/filters/AviSource/AVIReadHandler.cpp index 8b7189667..588bb0109 100644 --- a/avs_core/filters/AviSource/AVIReadHandler.cpp +++ b/avs_core/filters/AviSource/AVIReadHandler.cpp @@ -28,7 +28,7 @@ #include "File64.h" #include "clip_info.h" - +#include "..\avs_core\core\internal.h" #include #include @@ -329,7 +329,7 @@ class AVIReadHandler : public IAVIReadHandler, private File64 { public: bool fDisableFastIO; - AVIReadHandler(const char *); + AVIReadHandler(const wchar_t *); AVIReadHandler(PAVIFILE); ~AVIReadHandler(); @@ -340,7 +340,7 @@ class AVIReadHandler : public IAVIReadHandler, private File64 { bool isOptimizedForRealtime(); bool isStreaming(); bool isIndexFabricated(); - bool AppendFile(const char *pszFile); + bool AppendFile(const wchar_t *pszFile); bool getSegmentHint(const char **ppszPath); void EnableStreaming(int stream); @@ -380,7 +380,7 @@ class AVIReadHandler : public IAVIReadHandler, private File64 { List2 listStreams; List2 listFiles; - void _construct(const char *pszFile); + void _construct(const wchar_t *pszFile_w); void _parseFile(List2& streams); bool _parseStreamHeader(List2& streams, DWORD dwLengthLeft, bool& bIndexDamaged); bool _parseIndexBlock(List2& streams, int count, __int64); @@ -396,8 +396,8 @@ IAVIReadHandler *CreateAVIReadHandler(PAVIFILE paf) { return new AVIReadHandler(paf); } -IAVIReadHandler *CreateAVIReadHandler(const char *pszFile) { - return new AVIReadHandler(pszFile); +IAVIReadHandler *CreateAVIReadHandler(const wchar_t *pszFile_w) { + return new AVIReadHandler(pszFile_w); } /////////////////////////////////////////////////////////////////////////// @@ -1252,7 +1252,7 @@ bool AVIReadStream::getVBRInfo(double& bitrate_mean, double& bitrate_stddev, dou /////////////////////////////////////////////////////////////////////////// -AVIReadHandler::AVIReadHandler(const char *s) +AVIReadHandler::AVIReadHandler(const wchar_t *s) : pAvisynthClipInfo(0) , bAggressivelyRecovered(false) { @@ -1312,20 +1312,20 @@ AVIReadHandler::~AVIReadHandler() { _destruct(); } -void AVIReadHandler::_construct(const char *pszFile) { +void AVIReadHandler::_construct(const wchar_t *pszFile_w) { try { AVIFileDesc *pDesc; // open file - hFile = CreateFile(pszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); + hFile = CreateFileW(pszFile_w, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (INVALID_HANDLE_VALUE == hFile) - throw MyWin32Error("Couldn't open %s: %%s", GetLastError(), pszFile); + throw MyWin32Error("Couldn't open %s: %%s", GetLastError(), WideCharToAnsi(pszFile_w).get()); - hFileUnbuffered = CreateFile( - pszFile, + hFileUnbuffered = CreateFileW( + pszFile_w, GENERIC_READ, FILE_SHARE_READ, NULL, @@ -1357,7 +1357,7 @@ void AVIReadHandler::_construct(const char *pszFile) { } } -bool AVIReadHandler::AppendFile(const char *pszFile) { +bool AVIReadHandler::AppendFile(const wchar_t *pszFile_w) { List2 newstreams; AVIStreamNode *pasn_old, *pasn_new, *pasn_old_next=NULL, *pasn_new_next=NULL; AVIFileDesc *pDesc; @@ -1366,13 +1366,13 @@ bool AVIReadHandler::AppendFile(const char *pszFile) { // open file - hFile = CreateFile(pszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); + hFile = CreateFileW(pszFile_w, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (INVALID_HANDLE_VALUE == hFile) - throw MyWin32Error("Couldn't open %s: %%s", GetLastError(), pszFile); + throw MyWin32Error("Couldn't open %s: %%s", GetLastError(), WideCharToAnsi(pszFile_w).get()); - hFileUnbuffered = CreateFile( - pszFile, + hFileUnbuffered = CreateFileW( + pszFile_w, GENERIC_READ, FILE_SHARE_READ, NULL, diff --git a/avs_core/filters/AviSource/AVIReadHandler.h b/avs_core/filters/AviSource/AVIReadHandler.h index be6b3be8b..020a8cc5e 100644 --- a/avs_core/filters/AviSource/AVIReadHandler.h +++ b/avs_core/filters/AviSource/AVIReadHandler.h @@ -55,11 +55,11 @@ class IAVIReadHandler { virtual bool isOptimizedForRealtime()=0; virtual bool isStreaming()=0; virtual bool isIndexFabricated()=0; - virtual bool AppendFile(const char *pszFile)=0; + virtual bool AppendFile(const wchar_t *pszFile)=0; virtual bool getSegmentHint(const char **ppszPath)=0; }; IAVIReadHandler *CreateAVIReadHandler(PAVIFILE paf); -IAVIReadHandler *CreateAVIReadHandler(const char *pszFile); +IAVIReadHandler *CreateAVIReadHandler(const wchar_t *pszFile); #endif diff --git a/avs_core/filters/AviSource/avi_source.cpp b/avs_core/filters/AviSource/avi_source.cpp index a5c4a1863..4bf12ee8e 100644 --- a/avs_core/filters/AviSource/avi_source.cpp +++ b/avs_core/filters/AviSource/avi_source.cpp @@ -480,7 +480,7 @@ void AVISource::LocateVideoCodec(const char fourCC[], IScriptEnvironment* env) { } -AVISource::AVISource(const char filename[], bool fAudio, const char pixel_type[], const char fourCC[], int vtrack, int atrack, avi_mode_e mode, IScriptEnvironment* env) { +AVISource::AVISource(const char filename[], bool fAudio, const char pixel_type[], const char fourCC[], int vtrack, int atrack, avi_mode_e mode, bool utf8, IScriptEnvironment* env) { srcbuffer = 0; srcbuffer_size = 0; memset(&vi, 0, sizeof(vi)); ex = false; @@ -506,12 +506,14 @@ AVISource::AVISource(const char filename[], bool fAudio, const char pixel_type[] bMediaPad = false; frame = 0; + auto filename_w = utf8 ? Utf8ToWideChar(filename) : AnsiToWideChar(filename); + AVIFileInit(); try { if (mode == MODE_NORMAL) { // if it looks like an AVI file, open in OpenDML mode; otherwise AVIFile mode - HANDLE h = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + HANDLE h = CreateFileW(filename_w.get(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (h == INVALID_HANDLE_VALUE) { env->ThrowError("AVISource autodetect: couldn't open file '%s'\nError code: %d", filename, GetLastError()); } @@ -527,7 +529,7 @@ AVISource::AVISource(const char filename[], bool fAudio, const char pixel_type[] if (mode == MODE_AVIFILE || mode == MODE_WAV) { // AVIFile mode PAVIFILE paf = NULL; try { // The damn .WAV clsid handler has only a 48 byte buffer to parse the filename and GPF's - if (FAILED(AVIFileOpen(&paf, filename, OF_READ, 0))) + if (FAILED(AVIFileOpenW(&paf, filename_w.get(), OF_READ, 0))) env->ThrowError("AVIFileSource: couldn't open file '%s'", filename); } catch (AvisynthError) { @@ -538,7 +540,7 @@ AVISource::AVISource(const char filename[], bool fAudio, const char pixel_type[] } pfile = CreateAVIReadHandler(paf); } else { // OpenDML mode - pfile = CreateAVIReadHandler(filename); + pfile = CreateAVIReadHandler(filename_w.get()); } if (mode != MODE_WAV) { // check for video stream diff --git a/avs_core/filters/AviSource/avi_source.h b/avs_core/filters/AviSource/avi_source.h index 260899078..d25593aa1 100644 --- a/avs_core/filters/AviSource/avi_source.h +++ b/avs_core/filters/AviSource/avi_source.h @@ -100,6 +100,8 @@ class AVISource : public IClip { bool b64a; bool b48r; + bool utf8; + PVideoFrame last_frame; int last_frame_no; AudioSource* aSrc; @@ -124,7 +126,7 @@ class AVISource : public IClip { } avi_mode_e; AVISource(const char filename[], bool fAudio, const char pixel_type[], - const char fourCC[], int vtrack, int atrack, avi_mode_e mode, IScriptEnvironment* env); // mode: 0=detect, 1=avifile, 2=opendml, 3=avifile (audio only) + const char fourCC[], int vtrack, int atrack, avi_mode_e mode, bool utf8, IScriptEnvironment* env); // mode: 0=detect, 1=avifile, 2=opendml, 3=avifile (audio only) ~AVISource(); void CleanUp(); // Tritical - Jan 2006 const VideoInfo& __stdcall GetVideoInfo(); @@ -140,10 +142,11 @@ class AVISource : public IClip { const char* fourCC = (mode != MODE_WAV) ? args[3].AsString("") : ""; const int vtrack = args[4].AsInt(0); const int atrack = args[5].AsInt(0); + const int utf8 = args[6].AsBool(false); - PClip result = new AVISource(args[0][0].AsString(), fAudio, pixel_type, fourCC, vtrack, atrack, mode, env); + PClip result = new AVISource(args[0][0].AsString(), fAudio, pixel_type, fourCC, vtrack, atrack, mode, utf8, env); for (int i=1; iInvoke("DirectShowSource",AVSValue(inv_args, inv_args_count)).AsClip(); + clip = env->Invoke("DirectShowSource",AVSValue(inv_args, inv_args_count)).AsClip(); // no utf8 yet } else { - clip = (IClip*)(new AVISource(filename, bAudio, pixel_type, fourCC, vtrack, atrack, AVISource::MODE_NORMAL, env)); + clip = (IClip*)(new AVISource(filename, bAudio, pixel_type, fourCC, vtrack, atrack, AVISource::MODE_NORMAL, utf8, env)); } result = !result ? clip : new_Splice(result, clip, false, env); } catch (const AvisynthError &e) { @@ -1797,11 +1799,11 @@ AVSValue __cdecl Create_Version(AVSValue args, void*, IScriptEnvironment* env) { extern const AVSFunction Source_filters[] = { - { "AVISource", BUILTIN_FUNC_PREFIX, "s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i", AVISource::Create, (void*) AVISource::MODE_NORMAL }, - { "AVIFileSource", BUILTIN_FUNC_PREFIX, "s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i", AVISource::Create, (void*) AVISource::MODE_AVIFILE }, - { "WAVSource", BUILTIN_FUNC_PREFIX, "s+", AVISource::Create, (void*) AVISource::MODE_WAV }, - { "OpenDMLSource", BUILTIN_FUNC_PREFIX, "s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i", AVISource::Create, (void*) AVISource::MODE_OPENDML }, - { "SegmentedAVISource", BUILTIN_FUNC_PREFIX, "s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i", Create_SegmentedSource, (void*)0 }, + { "AVISource", BUILTIN_FUNC_PREFIX, "s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i[utf8]b", AVISource::Create, (void*) AVISource::MODE_NORMAL }, + { "AVIFileSource", BUILTIN_FUNC_PREFIX, "s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i[utf8]b", AVISource::Create, (void*) AVISource::MODE_AVIFILE }, + { "WAVSource", BUILTIN_FUNC_PREFIX, "s+[utf8]b", AVISource::Create, (void*) AVISource::MODE_WAV }, + { "OpenDMLSource", BUILTIN_FUNC_PREFIX, "s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i[utf8]b", AVISource::Create, (void*) AVISource::MODE_OPENDML }, + { "SegmentedAVISource", BUILTIN_FUNC_PREFIX, "s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i[utf8]b", Create_SegmentedSource, (void*)0 }, { "SegmentedDirectShowSource", BUILTIN_FUNC_PREFIX, // args 0 1 2 3 4 5 6 7 8 "s+[fps]f[seek]b[audio]b[video]b[convertfps]b[seekzero]b[timeout]i[pixel_type]s", diff --git a/distrib/Readme/readme_history.txt b/distrib/Readme/readme_history.txt index 51e419da6..90d553f37 100644 --- a/distrib/Readme/readme_history.txt +++ b/distrib/Readme/readme_history.txt @@ -4,7 +4,7 @@ Source: https://github.com/pinterf/AviSynthPlus/tree/MT For a more logical (non-historical) arrangement of changes see readme.txt -20181122 r27xx +20181204 r27xx -------------- - New: Expr: allow input clips to have more planes than an implicitely specified output format Expr(aYV12Clip, "x 255.0 /", format="Y32") # target is Y only which needs only Y plane from YV12 -> no error @@ -30,6 +30,9 @@ For a more logical (non-historical) arrangement of changes see readme.txt Default: process all planes. For RGB: luma and chroma parameters are ignored. Unprocessed planes are copied. Using alpha=false makes RGB32 processing faster, usually A channel is not needed. - GeneralConvolution: MT friendly parameter parsing +- New: UTF8 filename support in AviSource, AVIFileSource, WAVSource, OpenDMLSource and SegmentedAVISource + All the functions above have a new bool utf8 parameter. Default value is false. + Note: the avs script which contains UTF8 characters inside cannot be saved with UTF8 marker, save it without UTF8-BOM. - Experimental: new syntax element (by addewyd): assignment operator ":=" which returns the assigned value itself. Examples: w := h := 256