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 }

Generated on Tue Dec 13 14:47:52 2005 for guliverkli by  doxygen 1.4.5