- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# plugins.cpp

    00001 /*
    00002  *      Copyright (C) 2003-2005 Gabest
    00003  *      http://www.gabest.org
    00004  *
    00005  *  This Program is free software; you can redistribute it and/or modify
    00006  *  it under the terms of the GNU General Public License as published by
    00007  *  the Free Software Foundation; either version 2, or (at your option)
    00008  *  any later version.
    00009  *
    00010  *  This Program is distributed in the hope that it will be useful,
    00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    00013  *  GNU General Public License for more details.
    00014  *
    00015  *  You should have received a copy of the GNU General Public License
    00016  *  along with GNU Make; see the file COPYING.  If not, write to
    00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
    00018  *  http://www.gnu.org/copyleft/gpl.html
    00019  *
    00020  */
    00021
    00022 #include "stdafx.h"
    00023 #include <afxdlgs.h>
    00024 #include <atlpath.h>
    00025 #include "resource.h"
    00026 #include "..\..\..\subtitles\VobSubFile.h"
    00027 #include "..\..\..\subtitles\RTS.h"
    00028 #include "..\..\..\SubPic\MemSubPic.h"
    00029
    00030 //
    00031 // Generic interface
    00032 //
    00033
    00034 namespace Plugin
    00035 {
    00036
    00037 class CFilter : public CAMThread, public CCritSec
    00038 {
    00039 private:
    00040         CString m_fn;
    00041
    00042 protected:
    00043         float m_fps;
    00044         CCritSec m_csSubLock;
    00045         CComPtr<ISubPicQueue> m_pSubPicQueue;
    00046         CComPtr<ISubPicProvider> m_pSubPicProvider;
    00047         DWORD_PTR m_SubPicProviderId;
    00048
    00049 public:
    00050         CFilter() : m_fps(-1), m_SubPicProviderId(0) {CAMThread::Create();}
    00051         virtual ~CFilter() {CAMThread::CallWorker(0);}
    00052
    00053         CString GetFileName() {CAutoLock cAutoLock(this); return m_fn;}
    00054         void SetFileName(CString fn) {CAutoLock cAutoLock(this); m_fn = fn;}
    00055
    00056         bool Render(SubPicDesc& dst, REFERENCE_TIME rt, float fps)
    00057         {
    00058                 if(!m_pSubPicProvider)
    00059                         return(false);
    00060
    00061                 CSize size(dst.w, dst.h);
    00062
    00063                 if(!m_pSubPicQueue)
    00064                 {
    00065                         CComPtr<ISubPicAllocator> pAllocator = new CMemSubPicAllocator(dst.type, size);
    00066
    00067                         HRESULT hr;
    00068                         if(!(m_pSubPicQueue = new CSubPicQueueNoThread(pAllocator, &hr)) || FAILED(hr))
    00069                         {
    00070                                 m_pSubPicQueue = NULL;
    00071                                 return(false);
    00072                         }
    00073                 }
    00074
    00075                 if(m_SubPicProviderId != (DWORD_PTR)(ISubPicProvider*)m_pSubPicProvider)
    00076                 {
    00077                         m_pSubPicQueue->SetSubPicProvider(m_pSubPicProvider);
    00078                         m_SubPicProviderId = (DWORD_PTR)(ISubPicProvider*)m_pSubPicProvider;
    00079                 }
    00080
    00081                 CComPtr<ISubPic> pSubPic;
    00082                 if(!m_pSubPicQueue->LookupSubPic(rt, &pSubPic))
    00083                         return(false);
    00084
    00085                 CRect r;
    00086                 pSubPic->GetDirtyRect(r);
    00087
    00088                 if(dst.type == MSP_RGB32 || dst.type == MSP_RGB24 || dst.type == MSP_RGB16 || dst.type == MSP_RGB15)
    00089                         dst.h = -dst.h;
    00090
    00091                 pSubPic->AlphaBlt(r, r, &dst);
    00092
    00093                 return(true);
    00094         }
    00095
    00096         DWORD ThreadProc()
    00097         {
    00098                 SetThreadPriority(m_hThread, THREAD_PRIORITY_LOWEST);
    00099
    00100                 CArray<HANDLE> handles;
    00101                 handles.Add(GetRequestHandle());
    00102
    00103                 CString fn = GetFileName();
    00104                 CFileStatus fs;
    00105                 fs.m_mtime = 0;
    00106                 CFileGetStatus(fn, fs);
    00107
    00108                 while(1)
    00109                 {
    00110                         DWORD i = WaitForMultipleObjects(handles.GetSize(), handles.GetData(), FALSE, 1000);
    00111
    00112                         if(WAIT_OBJECT_0 == i)
    00113                         {
    00114                                 Reply(S_OK);
    00115                                 break;
    00116                         }
    00117                         else if(WAIT_ABANDONED_0 == i)
    00118                         {
    00119                                 break;
    00120                         }
    00121                         else if(WAIT_OBJECT_0 + 1 >= i && i <= WAIT_OBJECT_0 + handles.GetCount())
    00122                         {
    00123                                 if(FindNextChangeNotification(handles[i - WAIT_OBJECT_0]))
    00124                                 {
    00125                                         CFileStatus fs2;
    00126                                         fs2.m_mtime = 0;
    00127                                         CFileGetStatus(fn, fs2);
    00128
    00129                                         if(fs.m_mtime < fs2.m_mtime)
    00130                                         {
    00131                                                 fs.m_mtime = fs2.m_mtime;
    00132
    00133                                                 if(CComQIPtr<ISubStream> pSubStream = m_pSubPicProvider)
    00134                                                 {
    00135                                                         CAutoLock cAutoLock(&m_csSubLock);
    00136                                                         pSubStream->Reload();
    00137                                                 }
    00138                                         }
    00139                                 }
    00140                         }
    00141                         else if(WAIT_TIMEOUT == i)
    00142                         {
    00143                                 CString fn2 = GetFileName();
    00144
    00145                                 if(fn != fn2)
    00146                                 {
    00147                                         CPath p(fn2);
    00148                                         p.RemoveFileSpec();
    00149                                         HANDLE h = FindFirstChangeNotification(p, FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE);
    00150                                         if(h != INVALID_HANDLE_VALUE)
    00151                                         {
    00152                                                 fn = fn2;
    00153                                                 handles.SetSize(1);
    00154                                                 handles.Add(h);
    00155                                         }
    00156                                 }
    00157                         }
    00158                 }
    00159
    00160                 for(int i = 1; i < handles.GetCount(); i++)
    00161                         FindCloseChangeNotification(handles[i]);
    00162
    00163                 return 0;
    00164         }
    00165 };
    00166
    00167 class CVobSubFilter : virtual public CFilter
    00168 {
    00169 public:
    00170         CVobSubFilter(CString fn = _T(""))
    00171         {
    00172                 if(!fn.IsEmpty()) Open(fn);
    00173         }
    00174
    00175         bool Open(CString fn)
    00176         {
    00177                 SetFileName(_T(""));
    00178                 m_pSubPicProvider = NULL;
    00179
    00180                 if(CVobSubFile* vsf = new CVobSubFile(&m_csSubLock))
    00181                 {
    00182                         m_pSubPicProvider = (ISubPicProvider*)vsf;
    00183                         if(vsf->Open(CString(fn))) SetFileName(fn);
    00184                         else m_pSubPicProvider = NULL;
    00185                 }
    00186
    00187                 return !!m_pSubPicProvider;
    00188         }
    00189 };
    00190
    00191 class CTextSubFilter : virtual public CFilter
    00192 {
    00193         int m_CharSet;
    00194
    00195 public:
    00196         CTextSubFilter(CString fn = _T(""), int CharSet = DEFAULT_CHARSET, float fps = -1)
    00197                 : m_CharSet(CharSet)
    00198         {
    00199                 m_fps = fps;
    00200                 if(!fn.IsEmpty()) Open(fn, CharSet);
    00201         }
    00202
    00203         int GetCharSet() {return(m_CharSet);}
    00204
    00205         bool Open(CString fn, int CharSet = DEFAULT_CHARSET)
    00206         {
    00207                 SetFileName(_T(""));
    00208                 m_pSubPicProvider = NULL;
    00209
    00210                 if(CRenderedTextSubtitle* rts = new CRenderedTextSubtitle(&m_csSubLock))
    00211                 {
    00212                         m_pSubPicProvider = (ISubPicProvider*)rts;
    00213                         if(rts->Open(CString(fn), CharSet)) SetFileName(fn);
    00214                         else m_pSubPicProvider = NULL;
    00215                 }
    00216
    00217                 return !!m_pSubPicProvider;
    00218         }
    00219 };
    00220
    00221 //
    00222 // VirtualDub interface
    00223 //
    00224
    00225 namespace VirtualDub
    00226 {
    00227         #include "..\..\..\..\include\VirtualDub\VirtualDub.h"
    00228
    00229         class CVirtualDubFilter : virtual public CFilter
    00230         {
    00231         public:
    00232                 CVirtualDubFilter() {}
    00233                 virtual ~CVirtualDubFilter() {}
    00234
    00235                 virtual int RunProc(const FilterActivation* fa, const FilterFunctions* ff)
    00236                 {
    00237                         SubPicDesc dst;
    00238                         dst.type = MSP_RGB32;
    00239                         dst.w = fa->src.w;
    00240                         dst.h = fa->src.h;
    00241                         dst.bpp = 32;
    00242                         dst.pitch = fa->src.pitch;
    00243                         dst.bits = (LPVOID)fa->src.data;
    00244
    00245                         Render(dst, 10000i64*fa->pfsi->lSourceFrameMS, (float)1000 / fa->pfsi->lMicrosecsPerFrame);
    00246
    00247                         return 0;
    00248                 }
    00249
    00250                 virtual long ParamProc(FilterActivation* fa, const FilterFunctions* ff)
    00251                 {
    00252                         fa->dst.offset  = fa->src.offset;
    00253                         fa->dst.modulo  = fa->src.modulo;
    00254                         fa->dst.pitch   = fa->src.pitch;
    00255
    00256                         return 0;
    00257                 }
    00258
    00259                 virtual int ConfigProc(FilterActivation* fa, const FilterFunctions* ff, HWND hwnd) = 0;
    00260                 virtual void StringProc(const FilterActivation* fa, const FilterFunctions* ff, char* str) = 0;
    00261                 virtual bool FssProc(FilterActivation* fa, const FilterFunctions* ff, char* buf, int buflen) = 0;
    00262         };
    00263
    00264         class CVobSubVirtualDubFilter : public CVobSubFilter, public CVirtualDubFilter
    00265         {
    00266         public:
    00267                 CVobSubVirtualDubFilter(CString fn = _T(""))
    00268                         : CVobSubFilter(fn) {}
    00269
    00270                 int ConfigProc(FilterActivation* fa, const FilterFunctions* ff, HWND hwnd)
    00271                 {
    00272                         AFX_MANAGE_STATE(AfxGetStaticModuleState());
    00273
    00274                         CFileDialog fd(TRUE, NULL, GetFileName(), OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY,
    00275                                 _T("VobSub files (*.idx;*.sub)|*.idx;*.sub||"), CWnd::FromHandle(hwnd), 0);
    00276
    00277                         if(fd.DoModal() != IDOK) return 1;
    00278
    00279                         return Open(fd.GetPathName()) ? 0 : 1;
    00280                 }
    00281
    00282                 void StringProc(const FilterActivation* fa, const FilterFunctions* ff, char* str)
    00283                 {
    00284                         sprintf(str, " (%s)", !GetFileName().IsEmpty() ? CStringA(GetFileName()) : " (empty)");
    00285                 }
    00286
    00287                 bool FssProc(FilterActivation* fa, const FilterFunctions* ff, char* buf, int buflen)
    00288                 {
    00289                         CStringA fn(GetFileName());
    00290                         fn.Replace("\\", "\\\\");
    00291                         _snprintf(buf, buflen, "Config(\"%s\")", fn);
    00292                         return(true);
    00293                 }
    00294         };
    00295
    00296         class CTextSubVirtualDubFilter : public CTextSubFilter, public CVirtualDubFilter
    00297         {
    00298         public:
    00299                 CTextSubVirtualDubFilter(CString fn = _T(""), int CharSet = DEFAULT_CHARSET)
    00300                         : CTextSubFilter(fn, CharSet) {}
    00301
    00302                 int ConfigProc(FilterActivation* fa, const FilterFunctions* ff, HWND hwnd)
    00303                 {
    00304                         AFX_MANAGE_STATE(AfxGetStaticModuleState());
    00305
    00306                         const TCHAR formats[] = _T("TextSub files (*.sub;*.srt;*.smi;*.ssa;*.ass;*.xss;*.psb;*.txt)|*.sub;*.srt;*.smi;*.ssa;*.ass;*.xss;*.psb;*.txt||");
    00307                         CFileDialog fd(TRUE, NULL, GetFileName(), OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_ENABLETEMPLATE|OFN_ENABLEHOOK,
    00308                                 formats, CWnd::FromHandle(hwnd), OPENFILENAME_SIZE_VERSION_400 /*0*/);
    00309
    00310                         UINT CALLBACK OpenHookProc(HWND hDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
    00311
    00312                         fd.m_pOFN->hInstance = AfxGetResourceHandle();
    00313                         fd.m_pOFN->lpTemplateName = MAKEINTRESOURCE(IDD_TEXTSUBOPENTEMPLATE);
    00314                         fd.m_pOFN->lpfnHook = OpenHookProc;
    00315                         fd.m_pOFN->lCustData = (LPARAM)DEFAULT_CHARSET;
    00316
    00317                         if(fd.DoModal() != IDOK) return 1;
    00318
    00319                         return Open(fd.GetPathName(), fd.m_pOFN->lCustData) ? 0 : 1;
    00320                 }
    00321
    00322                 void StringProc(const FilterActivation* fa, const FilterFunctions* ff, char* str)
    00323                 {
    00324                         if(!GetFileName().IsEmpty()) sprintf(str, " (%s, %d)", CStringA(GetFileName()), GetCharSet());
    00325                         else sprintf(str, " (empty)");
    00326                 }
    00327
    00328                 bool FssProc(FilterActivation* fa, const FilterFunctions* ff, char* buf, int buflen)
    00329                 {
    00330                         CStringA fn(GetFileName());
    00331                         fn.Replace("\\", "\\\\");
    00332                         _snprintf(buf, buflen, "Config(\"%s\", %d)", fn, GetCharSet());
    00333                         return(true);
    00334                 }
    00335         };
    00336
    00337         int vobsubInitProc(FilterActivation* fa, const FilterFunctions* ff)
    00338         {
    00339                 return !(*(CVirtualDubFilter**)fa->filter_data = new CVobSubVirtualDubFilter());
    00340         }
    00341
    00342         int textsubInitProc(FilterActivation* fa, const FilterFunctions* ff)
    00343         {
    00344                 return !(*(CVirtualDubFilter**)fa->filter_data = new CTextSubVirtualDubFilter());
    00345         }
    00346
    00347         void baseDeinitProc(FilterActivation* fa, const FilterFunctions* ff)
    00348         {
    00349                 CVirtualDubFilter* f = *(CVirtualDubFilter**)fa->filter_data;
    00350                 if(f) delete f, f = NULL;
    00351         }
    00352
    00353         int baseRunProc(const FilterActivation* fa, const FilterFunctions* ff)
    00354         {
    00355                 CVirtualDubFilter* f = *(CVirtualDubFilter**)fa->filter_data;
    00356                 return f ? f->RunProc(fa, ff) : 1;
    00357         }
    00358
    00359         long baseParamProc(FilterActivation* fa, const FilterFunctions* ff)
    00360         {
    00361                 CVirtualDubFilter* f = *(CVirtualDubFilter**)fa->filter_data;
    00362                 return f ? f->ParamProc(fa, ff) : 1;
    00363         }
    00364
    00365         int baseConfigProc(FilterActivation* fa, const FilterFunctions* ff, HWND hwnd)
    00366         {
    00367                 CVirtualDubFilter* f = *(CVirtualDubFilter**)fa->filter_data;
    00368                 return f ? f->ConfigProc(fa, ff, hwnd) : 1;
    00369         }
    00370
    00371         void baseStringProc(const FilterActivation* fa, const FilterFunctions* ff, char* str)
    00372         {
    00373                 CVirtualDubFilter* f = *(CVirtualDubFilter**)fa->filter_data;
    00374                 if(f) f->StringProc(fa, ff, str);
    00375         }
    00376
    00377         bool baseFssProc(FilterActivation* fa, const FilterFunctions* ff, char* buf, int buflen)
    00378         {
    00379                 CVirtualDubFilter* f = *(CVirtualDubFilter**)fa->filter_data;
    00380                 return f ? f->FssProc(fa, ff, buf, buflen) : false;
    00381         }
    00382
    00383         void vobsubScriptConfig(IScriptInterpreter* isi, void* lpVoid, CScriptValue* argv, int argc)
    00384         {
    00385                 FilterActivation* fa = (FilterActivation*)lpVoid;
    00386                 CVirtualDubFilter* f = *(CVirtualDubFilter**)fa->filter_data;
    00387                 if(f) delete f;
    00388                 f = new CVobSubVirtualDubFilter(CString(*argv[0].asString()));
    00389                 *(CVirtualDubFilter**)fa->filter_data = f;
    00390         }
    00391
    00392         void textsubScriptConfig(IScriptInterpreter* isi, void* lpVoid, CScriptValue* argv, int argc)
    00393         {
    00394                 FilterActivation* fa = (FilterActivation*)lpVoid;
    00395                 CVirtualDubFilter* f = *(CVirtualDubFilter**)fa->filter_data;
    00396                 if(f) delete f;
    00397                 f = new CTextSubVirtualDubFilter(CString(*argv[0].asString()), argv[1].asInt());
    00398                 *(CVirtualDubFilter**)fa->filter_data = f;
    00399         }
    00400
    00401         ScriptFunctionDef vobsub_func_defs[]={
    00402                 { (ScriptFunctionPtr)vobsubScriptConfig, "Config", "0s" },
    00403                 { NULL },
    00404         };
    00405
    00406         CScriptObject vobsub_obj={
    00407                 NULL, vobsub_func_defs
    00408         };
    00409
    00410         struct FilterDefinition filterDef_vobsub =
    00411         {
    00412                 NULL, NULL, NULL,       // next, prev, module
    00413                 "VobSub",                               // name
    00414                 "Adds subtitles from a vob sequence.", // desc
    00415                 "Gabest",               // maker
    00416                 NULL,                   // private_data
    00417                 sizeof(CVirtualDubFilter**), // inst_data_size
    00418                 vobsubInitProc,         // initProc
    00419                 baseDeinitProc,                 // deinitProc
    00420                 baseRunProc,                    // runProc
    00421                 baseParamProc,                  // paramProc
    00422                 baseConfigProc,                 // configProc
    00423                 baseStringProc,                 // stringProc
    00424                 NULL,                                   // startProc
    00425                 NULL,                                   // endProc
    00426                 &vobsub_obj,                    // script_obj
    00427                 baseFssProc,                    // fssProc
    00428         };
    00429
    00430         ScriptFunctionDef textsub_func_defs[]={
    00431                 { (ScriptFunctionPtr)textsubScriptConfig, "Config", "0si" },
    00432                 { NULL },
    00433         };
    00434
    00435         CScriptObject textsub_obj={
    00436                 NULL, textsub_func_defs
    00437         };
    00438
    00439         struct FilterDefinition filterDef_textsub =
    00440         {
    00441                 NULL, NULL, NULL,       // next, prev, module
    00442                 "TextSub",                              // name
    00443                 "Adds subtitles from srt, sub, psb, smi, ssa, ass file formats.", // desc
    00444                 "Gabest",               // maker
    00445                 NULL,                   // private_data
    00446                 sizeof(CVirtualDubFilter**), // inst_data_size
    00447                 textsubInitProc,        // initProc
    00448                 baseDeinitProc,                 // deinitProc
    00449                 baseRunProc,                    // runProc
    00450                 baseParamProc,                  // paramProc
    00451                 baseConfigProc,                 // configProc
    00452                 baseStringProc,                 // stringProc
    00453                 NULL,                                   // startProc
    00454                 NULL,                                   // endProc
    00455                 &textsub_obj,                   // script_obj
    00456                 baseFssProc,                    // fssProc
    00457         };
    00458
    00459         static FilterDefinition* fd_vobsub;
    00460         static FilterDefinition* fd_textsub;
    00461
    00462         extern "C" __declspec(dllexport) int __cdecl VirtualdubFilterModuleInit2(FilterModule *fm, const FilterFunctions *ff, int& vdfd_ver, int& vdfd_compat)
    00463         {
    00464                 if(!(fd_vobsub = ff->addFilter(fm, &filterDef_vobsub, sizeof(FilterDefinition)))
    00465                 || !(fd_textsub = ff->addFilter(fm, &filterDef_textsub, sizeof(FilterDefinition))))
    00466                         return 1;
    00467
    00468                 vdfd_ver = VIRTUALDUB_FILTERDEF_VERSION;
    00469                 vdfd_compat = VIRTUALDUB_FILTERDEF_COMPATIBLE;
    00470
    00471                 return 0;
    00472         }
    00473
    00474         extern "C" __declspec(dllexport) void __cdecl VirtualdubFilterModuleDeinit(FilterModule *fm, const FilterFunctions *ff)
    00475         {
    00476                 ff->removeFilter(fd_textsub);
    00477                 ff->removeFilter(fd_vobsub);
    00478         }
    00479 }
    00480
    00481 //
    00482 // Avisynth interface
    00483 //
    00484
    00485 namespace AviSynth1
    00486 {
    00487         #include "..\..\..\..\include\avisynth\avisynth1.h"
    00488
    00489         class CAvisynthFilter : public GenericVideoFilter, virtual public CFilter
    00490         {
    00491         public:
    00492                 CAvisynthFilter(PClip c, IScriptEnvironment* env) : GenericVideoFilter(c) {}
    00493
    00494                 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env)
    00495                 {
    00496                         PVideoFrame frame = child->GetFrame(n, env);
    00497
    00498                         env->MakeWritable(&frame);
    00499
    00500                         SubPicDesc dst;
    00501                         dst.w = vi.width;
    00502                         dst.h = vi.height;
    00503                         dst.pitch = frame->GetPitch();
    00504                         dst.bits = (void**)frame->GetWritePtr();
    00505                         dst.bpp = vi.BitsPerPixel();
    00506                         dst.type =
    00507                                 vi.IsRGB32() ? MSP_RGB32 :
    00508                                 vi.IsRGB24() ? MSP_RGB24 :
    00509                                 vi.IsYUY2() ? MSP_YUY2 :
    00510                                 -1;
    00511
    00512                         float fps = m_fps > 0 ? m_fps : (float)vi.fps_numerator / vi.fps_denominator;
    00513
    00514                         Render(dst, (REFERENCE_TIME)(10000000i64 * n / fps), fps);
    00515
    00516                         return(frame);
    00517                 }
    00518         };
    00519
    00520         class CVobSubAvisynthFilter : public CVobSubFilter, public CAvisynthFilter
    00521         {
    00522         public:
    00523                 CVobSubAvisynthFilter(PClip c, const char* fn, IScriptEnvironment* env)
    00524                         : CVobSubFilter(CString(fn))
    00525                         , CAvisynthFilter(c, env)
    00526                 {
    00527                         if(!m_pSubPicProvider)
    00528                                 env->ThrowError("VobSub: Can't open \"%s\"", fn);
    00529                 }
    00530         };
    00531
    00532         AVSValue __cdecl VobSubCreateS(AVSValue args, void* user_data, IScriptEnvironment* env)
    00533         {
    00534                 return(new CVobSubAvisynthFilter(args[0].AsClip(), args[1].AsString(), env));
    00535         }
    00536
    00537         class CTextSubAvisynthFilter : public CTextSubFilter, public CAvisynthFilter
    00538         {
    00539         public:
    00540                 CTextSubAvisynthFilter(PClip c, IScriptEnvironment* env, const char* fn, int CharSet = DEFAULT_CHARSET, float fps = -1)
    00541                         : CTextSubFilter(CString(fn), CharSet, fps)
    00542                         , CAvisynthFilter(c, env)
    00543                 {
    00544                         if(!m_pSubPicProvider)
    00545                                 env->ThrowError("TextSub: Can't open \"%s\"", fn);
    00546                 }
    00547         };
    00548
    00549         AVSValue __cdecl TextSubCreateS(AVSValue args, void* user_data, IScriptEnvironment* env)
    00550         {
    00551                 return(new CTextSubAvisynthFilter(args[0].AsClip(), env, args[1].AsString()));
    00552         }
    00553
    00554         AVSValue __cdecl TextSubCreateSI(AVSValue args, void* user_data, IScriptEnvironment* env)
    00555         {
    00556                 return(new CTextSubAvisynthFilter(args[0].AsClip(), env, args[1].AsString(), args[2].AsInt()));
    00557         }
    00558
    00559         AVSValue __cdecl TextSubCreateSIF(AVSValue args, void* user_data, IScriptEnvironment* env)
    00560         {
    00561                 return(new CTextSubAvisynthFilter(args[0].AsClip(), env, args[1].AsString(), args[2].AsInt(), args[3].AsFloat()));
    00562         }
    00563
    00564         extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit(IScriptEnvironment* env)
    00565         {
    00566                 env->AddFunction("VobSub", "cs", VobSubCreateS, 0);
    00567                 env->AddFunction("TextSub", "cs", TextSubCreateS, 0);
    00568                 env->AddFunction("TextSub", "csi", TextSubCreateSI, 0);
    00569                 env->AddFunction("TextSub", "csif", TextSubCreateSIF, 0);
    00570                 return(NULL);
    00571         }
    00572 }
    00573
    00574 namespace AviSynth25
    00575 {
    00576         #include "..\..\..\..\include\avisynth\avisynth25.h"
    00577
    00578         static bool s_fSwapUV = false;
    00579
    00580         class CAvisynthFilter : public GenericVideoFilter, virtual public CFilter
    00581         {
    00582         public:
    00583                 CAvisynthFilter(PClip c, IScriptEnvironment* env) : GenericVideoFilter(c) {}
    00584
    00585                 PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env)
    00586                 {
    00587                         PVideoFrame frame = child->GetFrame(n, env);
    00588
    00589                         env->MakeWritable(&frame);
    00590
    00591                         SubPicDesc dst;
    00592                         dst.w = vi.width;
    00593                         dst.h = vi.height;
    00594                         dst.pitch = frame->GetPitch();
    00595                         dst.pitchUV = frame->GetPitch(PLANAR_U);
    00596                         dst.bits = (void**)frame->GetWritePtr();
    00597                         dst.bitsU = frame->GetWritePtr(PLANAR_U);
    00598                         dst.bitsV = frame->GetWritePtr(PLANAR_V);
    00599                         dst.bpp = dst.pitch/dst.w*8; //vi.BitsPerPixel();
    00600                         dst.type =
    00601                                 vi.IsRGB32() ? MSP_RGB32 :
    00602                                 vi.IsRGB24() ? MSP_RGB24 :
    00603                                 vi.IsYUY2() ? MSP_YUY2 :
    00604                                 /*vi.IsYV12()*/ vi.pixel_type == VideoInfo::CS_YV12 ? (s_fSwapUV?MSP_IYUV:MSP_YV12) :
    00605                                 /*vi.IsIYUV()*/ vi.pixel_type == VideoInfo::CS_IYUV ? (s_fSwapUV?MSP_YV12:MSP_IYUV) :
    00606                                 -1;
    00607
    00608                         float fps = m_fps > 0 ? m_fps : (float)vi.fps_numerator / vi.fps_denominator;
    00609
    00610                         Render(dst, (REFERENCE_TIME)(10000000i64 * n / fps), fps);
    00611
    00612                         return(frame);
    00613                 }
    00614         };
    00615
    00616         class CVobSubAvisynthFilter : public CVobSubFilter, public CAvisynthFilter
    00617         {
    00618         public:
    00619                 CVobSubAvisynthFilter(PClip c, const char* fn, IScriptEnvironment* env)
    00620                         : CVobSubFilter(CString(fn))
    00621                         , CAvisynthFilter(c, env)
    00622                 {
    00623                         if(!m_pSubPicProvider)
    00624                                 env->ThrowError("VobSub: Can't open \"%s\"", fn);
    00625                 }
    00626         };
    00627
    00628         AVSValue __cdecl VobSubCreateS(AVSValue args, void* user_data, IScriptEnvironment* env)
    00629         {
    00630                 return(new CVobSubAvisynthFilter(args[0].AsClip(), args[1].AsString(), env));
    00631         }
    00632
    00633         class CTextSubAvisynthFilter : public CTextSubFilter, public CAvisynthFilter
    00634         {
    00635         public:
    00636                 CTextSubAvisynthFilter(PClip c, IScriptEnvironment* env, const char* fn, int CharSet = DEFAULT_CHARSET, float fps = -1)
    00637                         : CTextSubFilter(CString(fn), CharSet, fps)
    00638                         , CAvisynthFilter(c, env)
    00639                 {
    00640                         if(!m_pSubPicProvider)
    00641                                 env->ThrowError("TextSub: Can't open \"%s\"", fn);
    00642                 }
    00643         };
    00644
    00645         AVSValue __cdecl TextSubCreateS(AVSValue args, void* user_data, IScriptEnvironment* env)
    00646         {
    00647                 return(new CTextSubAvisynthFilter(args[0].AsClip(), env, args[1].AsString()));
    00648         }
    00649
    00650         AVSValue __cdecl TextSubCreateSI(AVSValue args, void* user_data, IScriptEnvironment* env)
    00651         {
    00652                 return(new CTextSubAvisynthFilter(args[0].AsClip(), env, args[1].AsString(), args[2].AsInt()));
    00653         }
    00654
    00655         AVSValue __cdecl TextSubCreateSIF(AVSValue args, void* user_data, IScriptEnvironment* env)
    00656         {
    00657                 return(new CTextSubAvisynthFilter(args[0].AsClip(), env, args[1].AsString(), args[2].AsInt(), args[3].AsFloat()));
    00658         }
    00659
    00660         AVSValue __cdecl TextSubSwapUV(AVSValue args, void* user_data, IScriptEnvironment* env)
    00661         {
    00662                 s_fSwapUV = args[0].AsBool(false);
    00663                 return(AVSValue());
    00664         }
    00665
    00666         extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env)
    00667         {
    00668                 env->AddFunction("VobSub", "cs", VobSubCreateS, 0);
    00669                 env->AddFunction("TextSub", "cs", TextSubCreateS, 0);
    00670                 env->AddFunction("TextSub", "csi", TextSubCreateSI, 0);
    00671                 env->AddFunction("TextSub", "csif", TextSubCreateSIF, 0);
    00672                 env->AddFunction("TextSubSwapUV", "b", TextSubSwapUV, 0);
    00673                 return(NULL);
    00674         }
    00675 }
    00676
    00677 }
    00678
    00679 UINT CALLBACK OpenHookProc(HWND hDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
    00680 {
    00681         switch(uiMsg)
    00682         {
    00683                 case WM_NOTIFY:
    00684                 {
    00685                         OPENFILENAME* ofn = ((OFNOTIFY *)lParam)->lpOFN;
    00686
    00687                         if(((NMHDR *)lParam)->code == CDN_FILEOK)
    00688                         {
    00689                                 ofn->lCustData = (LPARAM)CharSetList[SendMessage(GetDlgItem(hDlg, IDC_COMBO1), CB_GETCURSEL, 0, 0)];
    00690                         }
    00691
    00692                         break;
    00693                 }
    00694
    00695                 case WM_INITDIALOG:
    00696                 {
    00697                         SetWindowLong(hDlg, GWL_USERDATA, lParam);
    00698
    00699                         for(int i = 0; i < CharSetLen; i++)
    00700                         {
    00701                                 CString s;
    00702                                 s.Format(_T("%s (%d)"), CharSetNames[i], CharSetList[i]);
    00703                                 SendMessage(GetDlgItem(hDlg, IDC_COMBO1), CB_ADDSTRING, 0, (LONG)(LPCTSTR)s);
    00704                                 if(CharSetList[i] == (int)((OPENFILENAME*)lParam)->lCustData)
    00705                                         SendMessage(GetDlgItem(hDlg, IDC_COMBO1), CB_SETCURSEL, i, 0);
    00706                         }
    00707
    00708                         break;
    00709                 }
    00710
    00711                 default:
    00712                         break;
    00713         }
    00714
    00715         return FALSE;
    00716 }