2 * Copyright (C) 2003-2006 Gabest
3 * http://www.gabest.org
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GNU Make; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
26 #include "../../../Subtitles/VobSubFile.h"
27 #include "../../../Subtitles/RTS.h"
28 #include "../../../Subtitles/SSF.h"
29 #include "../../../SubPic/PooledSubPic.h"
30 #include "../../../SubPic/SubPicQueueImpl.h"
31 #include "../../../subpic/color_conv_table.h"
32 #include "../../../subpic/SimpleSubPicWrapper.h"
33 #include "DirectVobSub.h"
43 class CFilter
: public CUnknown
, public CDirectVobSub
, public CAMThread
, public CCritSec
51 CComPtr
<ISubPicQueue
> m_pSubPicQueue
;
52 CComPtr
<ISubPicProvider
> m_pSubPicProvider
;
53 DWORD_PTR m_SubPicProviderId
;
55 CSimpleTextSubtitle::YCbCrMatrix m_script_selected_yuv
;
56 CSimpleTextSubtitle::YCbCrRange m_script_selected_range
;
60 CFilter() : CUnknown(NAME("CFilter"), NULL
), m_fps(-1), m_SubPicProviderId(0), m_fLazyInit(false)
62 //fix me: should not do init here
63 CacheManager::GetPathDataMruCache()->SetMaxItemNum(m_path_data_cache_max_item_num
);
64 CacheManager::GetScanLineData2MruCache()->SetMaxItemNum(m_scan_line_data_cache_max_item_num
);
65 CacheManager::GetOverlayNoBlurMruCache()->SetMaxItemNum(m_overlay_no_blur_cache_max_item_num
);
66 CacheManager::GetOverlayMruCache()->SetMaxItemNum(m_overlay_cache_max_item_num
);
67 SubpixelPositionControler::GetGlobalControler().SetSubpixelLevel( static_cast<SubpixelPositionControler::SUBPIXEL_LEVEL
>(m_subpixel_pos_level
) );
69 m_script_selected_yuv
= CSimpleTextSubtitle::YCbCrMatrix_AUTO
;
70 m_script_selected_range
= CSimpleTextSubtitle::YCbCrRange_AUTO
;
74 virtual ~CFilter() {CAMThread::CallWorker(0);}
77 STDMETHODIMP
NonDelegatingQueryInterface(REFIID riid
, void** ppv
)
79 CheckPointer(ppv
, E_POINTER
);
81 return QI(IDirectVobSub
)
85 __super::NonDelegatingQueryInterface(riid
, ppv
);
88 CString
GetFileName() {CAutoLock
cAutoLock(this); return m_fn
;}
89 void SetFileName(CString fn
) {CAutoLock
cAutoLock(this); m_fn
= fn
;}
91 void SetYuvMatrix(SubPicDesc
& dst
)
93 ColorConvTable::YuvMatrixType yuv_matrix
= ColorConvTable::BT601
;
94 ColorConvTable::YuvRangeType yuv_range
= ColorConvTable::RANGE_TV
;
96 if ( m_colorSpace
==CDirectVobSub::YuvMatrix_AUTO
)
98 switch(m_script_selected_yuv
)
100 case CSimpleTextSubtitle::YCbCrMatrix_BT601
:
101 yuv_matrix
= ColorConvTable::BT601
;
103 case CSimpleTextSubtitle::YCbCrMatrix_BT709
:
104 yuv_matrix
= ColorConvTable::BT709
;
106 case CSimpleTextSubtitle::YCbCrMatrix_AUTO
:
108 yuv_matrix
= ColorConvTable::BT601
;
116 case CDirectVobSub::BT_601
:
117 yuv_matrix
= ColorConvTable::BT601
;
119 case CDirectVobSub::BT_709
:
120 yuv_matrix
= ColorConvTable::BT709
;
122 case CDirectVobSub::GUESS
:
123 yuv_matrix
= (dst
.w
> m_bt601Width
|| dst
.h
> m_bt601Height
) ? ColorConvTable::BT709
: ColorConvTable::BT601
;
128 if( m_yuvRange
==CDirectVobSub::YuvRange_Auto
)
130 switch(m_script_selected_range
)
132 case CSimpleTextSubtitle::YCbCrRange_PC
:
133 yuv_range
= ColorConvTable::RANGE_PC
;
135 case CSimpleTextSubtitle::YCbCrRange_TV
:
136 yuv_range
= ColorConvTable::RANGE_TV
;
138 case CSimpleTextSubtitle::YCbCrRange_AUTO
:
140 yuv_range
= ColorConvTable::RANGE_TV
;
148 case CDirectVobSub::YuvRange_TV
:
149 yuv_range
= ColorConvTable::RANGE_TV
;
151 case CDirectVobSub::YuvRange_PC
:
152 yuv_range
= ColorConvTable::RANGE_PC
;
154 case CDirectVobSub::YuvRange_Auto
:
155 yuv_range
= ColorConvTable::RANGE_TV
;
160 ColorConvTable::SetDefaultConvType(yuv_matrix
, yuv_range
);
163 bool Render(SubPicDesc
& dst
, REFERENCE_TIME rt
, float fps
)
165 if(!m_pSubPicProvider
)
174 CSize
size(dst
.w
, dst
.h
);
178 CComPtr
<ISubPicExAllocator
> pAllocator
= new CPooledSubPicAllocator(dst
.type
, size
, 2);
181 if(!(m_pSubPicQueue
= new CSubPicQueueNoThread(pAllocator
, &hr
)) || FAILED(hr
))
183 m_pSubPicQueue
= NULL
;
188 if(m_SubPicProviderId
!= (DWORD_PTR
)(ISubPicProvider
*)m_pSubPicProvider
)
190 m_pSubPicQueue
->SetSubPicProvider(m_pSubPicProvider
);
191 m_SubPicProviderId
= (DWORD_PTR
)(ISubPicProvider
*)m_pSubPicProvider
;
194 CComPtr
<ISubPic
> pSubPic
;
195 if(!m_pSubPicQueue
->LookupSubPic(rt
, &pSubPic
))
198 if(dst
.type
== MSP_RGB32
|| dst
.type
== MSP_RGB24
|| dst
.type
== MSP_RGB16
|| dst
.type
== MSP_RGB15
)
200 SimpleSubPicWrapper
simple_subpic(pSubPic
);
201 simple_subpic
.AlphaBlt(&dst
);
208 SetThreadPriority(m_hThread
, THREAD_PRIORITY_LOWEST
);
210 CAtlArray
<HANDLE
> handles
;
211 handles
.Add(GetRequestHandle());
213 CString fn
= GetFileName();
216 CFileGetStatus(fn
, fs
);
220 DWORD i
= WaitForMultipleObjects(handles
.GetCount(), handles
.GetData(), FALSE
, 1000);
222 if(WAIT_OBJECT_0
== i
)
227 else if(WAIT_OBJECT_0
+ 1 >= i
&& i
<= WAIT_OBJECT_0
+ handles
.GetCount())
229 if(FindNextChangeNotification(handles
[i
- WAIT_OBJECT_0
]))
233 CFileGetStatus(fn
, fs2
);
235 if(fs
.m_mtime
< fs2
.m_mtime
)
237 fs
.m_mtime
= fs2
.m_mtime
;
239 if(CComQIPtr
<ISubStream
> pSubStream
= m_pSubPicProvider
)
241 CAutoLock
cAutoLock(&m_csSubLock
);
242 pSubStream
->Reload();
247 else if(WAIT_TIMEOUT
== i
)
249 CString fn2
= GetFileName();
255 HANDLE h
= FindFirstChangeNotification(p
, FALSE
, FILE_NOTIFY_CHANGE_LAST_WRITE
);
256 if(h
!= INVALID_HANDLE_VALUE
)
264 else // if(WAIT_ABANDONED_0 == i || WAIT_FAILED == i)
272 for(int i
= 1; i
< handles
.GetCount(); i
++)
273 FindCloseChangeNotification(handles
[i
]);
279 class CVobSubFilter
: virtual public CFilter
282 CVobSubFilter(CString fn
= _T(""))
284 if(!fn
.IsEmpty()) Open(fn
);
287 bool Open(CString fn
)
290 m_pSubPicProvider
= NULL
;
292 if(CVobSubFile
* vsf
= new CVobSubFile(&m_csSubLock
))
294 m_pSubPicProvider
= (ISubPicProvider
*)vsf
;
295 if(vsf
->Open(CString(fn
))) SetFileName(fn
);
296 else m_pSubPicProvider
= NULL
;
299 return !!m_pSubPicProvider
;
303 class CTextSubFilter
: virtual public CFilter
308 CTextSubFilter(CString fn
= _T(""), int CharSet
= DEFAULT_CHARSET
, float fps
= -1)
312 if(!fn
.IsEmpty()) Open(fn
, CharSet
);
315 int GetCharSet() {return(m_CharSet
);}
317 bool Open(CString fn
, int CharSet
= DEFAULT_CHARSET
)
320 m_pSubPicProvider
= NULL
;
322 if(!m_pSubPicProvider
)
324 if(ssf::CRenderer
* ssf
= new ssf::CRenderer(&m_csSubLock
))
326 m_pSubPicProvider
= (ISubPicProvider
*)ssf
;
327 if(ssf
->Open(CString(fn
))) SetFileName(fn
);
328 else m_pSubPicProvider
= NULL
;
332 if(!m_pSubPicProvider
)
334 if(CRenderedTextSubtitle
* rts
= new CRenderedTextSubtitle(&m_csSubLock
))
336 m_pSubPicProvider
= (ISubPicProvider
*)rts
;
337 if(rts
->Open(CString(fn
), CharSet
)) SetFileName(fn
);
338 else m_pSubPicProvider
= NULL
;
340 m_script_selected_yuv
= rts
->m_eYCbCrMatrix
;
341 m_script_selected_range
= rts
->m_eYCbCrRange
;
345 return !!m_pSubPicProvider
;
350 // VirtualDub interface
355 #include "..\..\..\..\include\VirtualDub\VirtualDub.h"
357 class CVirtualDubFilter
: virtual public CFilter
360 CVirtualDubFilter() {}
361 virtual ~CVirtualDubFilter() {}
363 virtual int RunProc(const FilterActivation
* fa
, const FilterFunctions
* ff
)
366 dst
.type
= MSP_RGB32
;
370 dst
.pitch
= fa
->src
.pitch
;
371 dst
.bits
= (LPVOID
)fa
->src
.data
;
373 Render(dst
, 10000i64
*fa
->pfsi
->lSourceFrameMS
, (float)1000 / fa
->pfsi
->lMicrosecsPerFrame
);
378 virtual long ParamProc(FilterActivation
* fa
, const FilterFunctions
* ff
)
380 fa
->dst
.offset
= fa
->src
.offset
;
381 fa
->dst
.modulo
= fa
->src
.modulo
;
382 fa
->dst
.pitch
= fa
->src
.pitch
;
387 virtual int ConfigProc(FilterActivation
* fa
, const FilterFunctions
* ff
, HWND hwnd
) = 0;
388 virtual void StringProc(const FilterActivation
* fa
, const FilterFunctions
* ff
, char* str
) = 0;
389 virtual bool FssProc(FilterActivation
* fa
, const FilterFunctions
* ff
, char* buf
, int buflen
) = 0;
392 class CVobSubVirtualDubFilter
: public CVobSubFilter
, public CVirtualDubFilter
395 CVobSubVirtualDubFilter(CString fn
= _T(""))
396 : CVobSubFilter(fn
) {}
398 int ConfigProc(FilterActivation
* fa
, const FilterFunctions
* ff
, HWND hwnd
)
400 AFX_MANAGE_STATE(AfxGetStaticModuleState());
402 CFileDialog
fd(TRUE
, NULL
, GetFileName(), OFN_EXPLORER
|OFN_ENABLESIZING
|OFN_HIDEREADONLY
,
403 _T("VobSub files (*.idx;*.sub)|*.idx;*.sub||"), CWnd::FromHandle(hwnd
), 0);
405 if(fd
.DoModal() != IDOK
) return 1;
407 return Open(fd
.GetPathName()) ? 0 : 1;
410 void StringProc(const FilterActivation
* fa
, const FilterFunctions
* ff
, char* str
)
412 sprintf(str
, " (%s)", !GetFileName().IsEmpty() ? CStringA(GetFileName()) : " (empty)");
415 bool FssProc(FilterActivation
* fa
, const FilterFunctions
* ff
, char* buf
, int buflen
)
417 CStringA
fn(GetFileName());
418 fn
.Replace("\\", "\\\\");
419 _snprintf(buf
, buflen
, "Config(\"%s\")", fn
);
424 class CTextSubVirtualDubFilter
: public CTextSubFilter
, public CVirtualDubFilter
427 CTextSubVirtualDubFilter(CString fn
= _T(""), int CharSet
= DEFAULT_CHARSET
)
428 : CTextSubFilter(fn
, CharSet
) {}
430 int ConfigProc(FilterActivation
* fa
, const FilterFunctions
* ff
, HWND hwnd
)
432 AFX_MANAGE_STATE(AfxGetStaticModuleState());
434 const TCHAR formats
[] = _T("TextSub files (*.sub;*.srt;*.smi;*.ssa;*.ass;*.xss;*.psb;*.txt)|*.sub;*.srt;*.smi;*.ssa;*.ass;*.xss;*.psb;*.txt||");
435 CFileDialog
fd(TRUE
, NULL
, GetFileName(), OFN_EXPLORER
|OFN_ENABLESIZING
|OFN_HIDEREADONLY
|OFN_ENABLETEMPLATE
|OFN_ENABLEHOOK
,
436 formats
, CWnd::FromHandle(hwnd
), OPENFILENAME_SIZE_VERSION_400
/*0*/);
438 UINT CALLBACK
OpenHookProc(HWND hDlg
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
);
440 fd
.m_pOFN
->hInstance
= AfxGetResourceHandle();
441 fd
.m_pOFN
->lpTemplateName
= MAKEINTRESOURCE(IDD_TEXTSUBOPENTEMPLATE
);
442 fd
.m_pOFN
->lpfnHook
= OpenHookProc
;
443 fd
.m_pOFN
->lCustData
= (LPARAM
)DEFAULT_CHARSET
;
445 if(fd
.DoModal() != IDOK
) return 1;
447 return Open(fd
.GetPathName(), fd
.m_pOFN
->lCustData
) ? 0 : 1;
450 void StringProc(const FilterActivation
* fa
, const FilterFunctions
* ff
, char* str
)
452 if(!GetFileName().IsEmpty()) sprintf(str
, " (%s, %d)", CStringA(GetFileName()), GetCharSet());
453 else sprintf(str
, " (empty)");
456 bool FssProc(FilterActivation
* fa
, const FilterFunctions
* ff
, char* buf
, int buflen
)
458 CStringA
fn(GetFileName());
459 fn
.Replace("\\", "\\\\");
460 _snprintf(buf
, buflen
, "Config(\"%s\", %d)", fn
, GetCharSet());
465 int vobsubInitProc(FilterActivation
* fa
, const FilterFunctions
* ff
)
467 return !(*(CVirtualDubFilter
**)fa
->filter_data
= new CVobSubVirtualDubFilter());
470 int textsubInitProc(FilterActivation
* fa
, const FilterFunctions
* ff
)
472 return !(*(CVirtualDubFilter
**)fa
->filter_data
= new CTextSubVirtualDubFilter());
475 void baseDeinitProc(FilterActivation
* fa
, const FilterFunctions
* ff
)
477 CVirtualDubFilter
* f
= *(CVirtualDubFilter
**)fa
->filter_data
;
478 if(f
) delete f
, f
= NULL
;
481 int baseRunProc(const FilterActivation
* fa
, const FilterFunctions
* ff
)
483 CVirtualDubFilter
* f
= *(CVirtualDubFilter
**)fa
->filter_data
;
484 return f
? f
->RunProc(fa
, ff
) : 1;
487 long baseParamProc(FilterActivation
* fa
, const FilterFunctions
* ff
)
489 CVirtualDubFilter
* f
= *(CVirtualDubFilter
**)fa
->filter_data
;
490 return f
? f
->ParamProc(fa
, ff
) : 1;
493 int baseConfigProc(FilterActivation
* fa
, const FilterFunctions
* ff
, HWND hwnd
)
495 CVirtualDubFilter
* f
= *(CVirtualDubFilter
**)fa
->filter_data
;
496 return f
? f
->ConfigProc(fa
, ff
, hwnd
) : 1;
499 void baseStringProc(const FilterActivation
* fa
, const FilterFunctions
* ff
, char* str
)
501 CVirtualDubFilter
* f
= *(CVirtualDubFilter
**)fa
->filter_data
;
502 if(f
) f
->StringProc(fa
, ff
, str
);
505 bool baseFssProc(FilterActivation
* fa
, const FilterFunctions
* ff
, char* buf
, int buflen
)
507 CVirtualDubFilter
* f
= *(CVirtualDubFilter
**)fa
->filter_data
;
508 return f
? f
->FssProc(fa
, ff
, buf
, buflen
) : false;
511 void vobsubScriptConfig(IScriptInterpreter
* isi
, void* lpVoid
, CScriptValue
* argv
, int argc
)
513 FilterActivation
* fa
= (FilterActivation
*)lpVoid
;
514 CVirtualDubFilter
* f
= *(CVirtualDubFilter
**)fa
->filter_data
;
516 f
= new CVobSubVirtualDubFilter(CString(*argv
[0].asString()));
517 *(CVirtualDubFilter
**)fa
->filter_data
= f
;
520 void textsubScriptConfig(IScriptInterpreter
* isi
, void* lpVoid
, CScriptValue
* argv
, int argc
)
522 FilterActivation
* fa
= (FilterActivation
*)lpVoid
;
523 CVirtualDubFilter
* f
= *(CVirtualDubFilter
**)fa
->filter_data
;
525 f
= new CTextSubVirtualDubFilter(CString(*argv
[0].asString()), argv
[1].asInt());
526 *(CVirtualDubFilter
**)fa
->filter_data
= f
;
529 ScriptFunctionDef vobsub_func_defs
[]={
530 { (ScriptFunctionPtr
)vobsubScriptConfig
, "Config", "0s" },
534 CScriptObject vobsub_obj
={
535 NULL
, vobsub_func_defs
538 struct FilterDefinition filterDef_vobsub
=
540 NULL
, NULL
, NULL
, // next, prev, module
542 "Adds subtitles from a vob sequence.", // desc
544 NULL
, // private_data
545 sizeof(CVirtualDubFilter
**), // inst_data_size
546 vobsubInitProc
, // initProc
547 baseDeinitProc
, // deinitProc
548 baseRunProc
, // runProc
549 baseParamProc
, // paramProc
550 baseConfigProc
, // configProc
551 baseStringProc
, // stringProc
554 &vobsub_obj
, // script_obj
555 baseFssProc
, // fssProc
558 ScriptFunctionDef textsub_func_defs
[]={
559 { (ScriptFunctionPtr
)textsubScriptConfig
, "Config", "0si" },
563 CScriptObject textsub_obj
={
564 NULL
, textsub_func_defs
567 struct FilterDefinition filterDef_textsub
=
569 NULL
, NULL
, NULL
, // next, prev, module
571 "Adds subtitles from srt, sub, psb, smi, ssa, ass file formats.", // desc
573 NULL
, // private_data
574 sizeof(CVirtualDubFilter
**), // inst_data_size
575 textsubInitProc
, // initProc
576 baseDeinitProc
, // deinitProc
577 baseRunProc
, // runProc
578 baseParamProc
, // paramProc
579 baseConfigProc
, // configProc
580 baseStringProc
, // stringProc
583 &textsub_obj
, // script_obj
584 baseFssProc
, // fssProc
587 static FilterDefinition
* fd_vobsub
;
588 static FilterDefinition
* fd_textsub
;
590 extern "C" __declspec(dllexport
) int __cdecl
VirtualdubFilterModuleInit2(FilterModule
*fm
, const FilterFunctions
*ff
, int& vdfd_ver
, int& vdfd_compat
)
592 if(!(fd_vobsub
= ff
->addFilter(fm
, &filterDef_vobsub
, sizeof(FilterDefinition
)))
593 || !(fd_textsub
= ff
->addFilter(fm
, &filterDef_textsub
, sizeof(FilterDefinition
))))
596 vdfd_ver
= VIRTUALDUB_FILTERDEF_VERSION
;
597 vdfd_compat
= VIRTUALDUB_FILTERDEF_COMPATIBLE
;
602 extern "C" __declspec(dllexport
) void __cdecl
VirtualdubFilterModuleDeinit(FilterModule
*fm
, const FilterFunctions
*ff
)
604 ff
->removeFilter(fd_textsub
);
605 ff
->removeFilter(fd_vobsub
);
610 // Avisynth interface
615 #include "..\..\..\..\include\avisynth\avisynth1.h"
617 class CAvisynthFilter
: public GenericVideoFilter
, virtual public CFilter
620 CAvisynthFilter(PClip c
, IScriptEnvironment
* env
) : GenericVideoFilter(c
) {}
622 PVideoFrame __stdcall
GetFrame(int n
, IScriptEnvironment
* env
)
624 PVideoFrame frame
= child
->GetFrame(n
, env
);
626 env
->MakeWritable(&frame
);
631 dst
.pitch
= frame
->GetPitch();
632 dst
.bits
= (void**)frame
->GetWritePtr();
633 dst
.bpp
= vi
.BitsPerPixel();
635 vi
.IsRGB32() ? ( env
->GetVar("RGBA").AsBool() ? MSP_RGBA
:MSP_RGB32
) :
636 vi
.IsRGB24() ? MSP_RGB24
:
637 vi
.IsYUY2() ? MSP_YUY2
:
640 float fps
= m_fps
> 0 ? m_fps
: (float)vi
.fps_numerator
/ vi
.fps_denominator
;
642 Render(dst
, (REFERENCE_TIME
)(10000000i64
* n
/ fps
), fps
);
648 class CVobSubAvisynthFilter
: public CVobSubFilter
, public CAvisynthFilter
651 CVobSubAvisynthFilter(PClip c
, const char* fn
, IScriptEnvironment
* env
)
652 : CVobSubFilter(CString(fn
))
653 , CAvisynthFilter(c
, env
)
655 if(!m_pSubPicProvider
)
656 env
->ThrowError("VobSub: Can't open \"%s\"", fn
);
660 AVSValue __cdecl
VobSubCreateS(AVSValue args
, void* user_data
, IScriptEnvironment
* env
)
662 return(new CVobSubAvisynthFilter(args
[0].AsClip(), args
[1].AsString(), env
));
665 class CTextSubAvisynthFilter
: public CTextSubFilter
, public CAvisynthFilter
668 CTextSubAvisynthFilter(PClip c
, IScriptEnvironment
* env
, const char* fn
, int CharSet
= DEFAULT_CHARSET
, float fps
= -1)
669 : CTextSubFilter(CString(fn
), CharSet
, fps
)
670 , CAvisynthFilter(c
, env
)
672 if(!m_pSubPicProvider
)
673 env
->ThrowError("TextSub: Can't open \"%s\"", fn
);
677 AVSValue __cdecl
TextSubCreateS(AVSValue args
, void* user_data
, IScriptEnvironment
* env
)
679 return(new CTextSubAvisynthFilter(args
[0].AsClip(), env
, args
[1].AsString()));
682 AVSValue __cdecl
TextSubCreateSI(AVSValue args
, void* user_data
, IScriptEnvironment
* env
)
684 return(new CTextSubAvisynthFilter(args
[0].AsClip(), env
, args
[1].AsString(), args
[2].AsInt()));
687 AVSValue __cdecl
TextSubCreateSIF(AVSValue args
, void* user_data
, IScriptEnvironment
* env
)
689 return(new CTextSubAvisynthFilter(args
[0].AsClip(), env
, args
[1].AsString(), args
[2].AsInt(), args
[3].AsFloat()));
692 AVSValue __cdecl
MaskSubCreateSIIFI(AVSValue args
, void* user_data
, IScriptEnvironment
* env
)
694 AVSValue
rgb32("RGB32");
702 AVSValue
value(tab
,5);
703 const char * nom
[5]={
710 AVSValue
clip(env
->Invoke("Blackness",value
,nom
));
711 env
->SetVar(env
->SaveString("RGBA"),true);
712 return(new CTextSubAvisynthFilter(clip
.AsClip(), env
, args
[0].AsString()));
715 extern "C" __declspec(dllexport
) const char* __stdcall
AvisynthPluginInit(IScriptEnvironment
* env
)
717 env
->AddFunction("VobSub", "cs", VobSubCreateS
, 0);
718 env
->AddFunction("TextSub", "cs", TextSubCreateS
, 0);
719 env
->AddFunction("TextSub", "csi", TextSubCreateSI
, 0);
720 env
->AddFunction("TextSub", "csif", TextSubCreateSIF
, 0);
721 env
->AddFunction("MaskSub", "siifi", MaskSubCreateSIIFI
, 0);
722 env
->SetVar(env
->SaveString("RGBA"),false);
729 #include "..\..\..\..\include\avisynth\avisynth25.h"
731 static bool s_fSwapUV
= false;
733 class CAvisynthFilter
: public GenericVideoFilter
, virtual public CFilter
738 CAvisynthFilter(PClip c
, IScriptEnvironment
* env
, VFRTranslator
*_vfr
=0) : GenericVideoFilter(c
), vfr(_vfr
) {}
740 PVideoFrame __stdcall
GetFrame(int n
, IScriptEnvironment
* env
)
742 PVideoFrame frame
= child
->GetFrame(n
, env
);
744 env
->MakeWritable(&frame
);
749 dst
.pitch
= frame
->GetPitch();
750 dst
.pitchUV
= frame
->GetPitch(PLANAR_U
);
751 dst
.bits
= (void**)frame
->GetWritePtr();
752 dst
.bitsU
= frame
->GetWritePtr(PLANAR_U
);
753 dst
.bitsV
= frame
->GetWritePtr(PLANAR_V
);
754 dst
.bpp
= dst
.pitch
/dst
.w
*8; //vi.BitsPerPixel();
756 vi
.IsRGB32() ?( env
->GetVar("RGBA").AsBool() ? MSP_RGBA
: MSP_RGB32
) :
757 vi
.IsRGB24() ? MSP_RGB24
:
758 vi
.IsYUY2() ? MSP_YUY2
:
759 /*vi.IsYV12()*/ vi
.pixel_type
== VideoInfo::CS_YV12
? (s_fSwapUV
?MSP_IYUV
:MSP_YV12
) :
760 /*vi.IsIYUV()*/ vi
.pixel_type
== VideoInfo::CS_IYUV
? (s_fSwapUV
?MSP_YV12
:MSP_IYUV
) :
763 REFERENCE_TIME timestamp
;
764 float fps
= m_fps
> 0 ? m_fps
: (float)vi
.fps_numerator
/ vi
.fps_denominator
;
766 timestamp
= (REFERENCE_TIME
)(10000000i64
* n
/ fps
);
768 timestamp
= (REFERENCE_TIME
)(10000000 * vfr
->TimeStampFromFrameNumber(n
));
770 Render(dst
, timestamp
, fps
);
776 class CVobSubAvisynthFilter
: public CVobSubFilter
, public CAvisynthFilter
779 CVobSubAvisynthFilter(PClip c
, const char* fn
, IScriptEnvironment
* env
)
780 : CVobSubFilter(CString(fn
))
781 , CAvisynthFilter(c
, env
)
783 if(!m_pSubPicProvider
)
784 env
->ThrowError("VobSub: Can't open \"%s\"", fn
);
788 AVSValue __cdecl
VobSubCreateS(AVSValue args
, void* user_data
, IScriptEnvironment
* env
)
790 return(new CVobSubAvisynthFilter(args
[0].AsClip(), args
[1].AsString(), env
));
793 class CTextSubAvisynthFilter
: public CTextSubFilter
, public CAvisynthFilter
796 CTextSubAvisynthFilter(PClip c
, IScriptEnvironment
* env
, const char* fn
, int CharSet
= DEFAULT_CHARSET
, float fps
= -1, VFRTranslator
*vfr
= 0)
797 : CTextSubFilter(CString(fn
), CharSet
, fps
)
798 , CAvisynthFilter(c
, env
, vfr
)
800 if(!m_pSubPicProvider
)
801 env
->ThrowError("TextSub: Can't open \"%s\"", fn
);
805 /*AVSValue __cdecl TextSubCreateS(AVSValue args, void* user_data, IScriptEnvironment* env)
807 return(new CTextSubAvisynthFilter(args[0].AsClip(), env, args[1].AsString()));
810 AVSValue __cdecl TextSubCreateSI(AVSValue args, void* user_data, IScriptEnvironment* env)
812 return(new CTextSubAvisynthFilter(args[0].AsClip(), env, args[1].AsString(), args[2].AsInt()));
815 AVSValue __cdecl TextSubCreateSIF(AVSValue args, void* user_data, IScriptEnvironment* env)
817 return(new CTextSubAvisynthFilter(args[0].AsClip(), env, args[1].AsString(), args[2].AsInt(), args[3].AsFloat()));
820 AVSValue __cdecl
TextSubCreateGeneral(AVSValue args
, void* user_data
, IScriptEnvironment
* env
)
822 if (!args
[1].Defined())
823 env
->ThrowError("TextSub: You must specify a subtitle file to use");
825 VFRTranslator
*vfr
= 0;
826 if (args
[4].Defined())
827 vfr
= GetVFRTranslator(args
[4].AsString());
829 return(new CTextSubAvisynthFilter(
833 args
[2].AsInt(DEFAULT_CHARSET
),
838 AVSValue __cdecl
TextSubSwapUV(AVSValue args
, void* user_data
, IScriptEnvironment
* env
)
840 s_fSwapUV
= args
[0].AsBool(false);
844 AVSValue __cdecl
MaskSubCreate(AVSValue args
, void* user_data
, IScriptEnvironment
* env
)
846 if (!args
[0].Defined())
847 env
->ThrowError("MaskSub: You must specify a subtitle file to use");
849 if (!args
[3].Defined() && !args
[6].Defined())
850 env
->ThrowError("MaskSub: You must specify either FPS or a VFR timecodes file");
852 VFRTranslator
*vfr
= 0;
853 if (args
[6].Defined())
854 vfr
= GetVFRTranslator(args
[6].AsString());
856 AVSValue
rgb32("RGB32");
857 AVSValue
fps(args
[3].AsFloat(25));
865 AVSValue
value(tab
,5);
866 const char * nom
[5]={
874 AVSValue
clip(env
->Invoke("Blackness",value
,nom
));
875 env
->SetVar(env
->SaveString("RGBA"),true);
877 return(new CTextSubAvisynthFilter(
881 args
[5].AsInt(DEFAULT_CHARSET
),
886 extern "C" __declspec(dllexport
) const char* __stdcall
AvisynthPluginInit2(IScriptEnvironment
* env
)
888 env
->AddFunction("VobSub", "cs", VobSubCreateS
, 0);
889 //env->AddFunction("TextSub", "cs", TextSubCreateS, 0);
890 //env->AddFunction("TextSub", "csi", TextSubCreateSI, 0);
891 //env->AddFunction("TextSub", "csif", TextSubCreateSIF, 0);
892 env
->AddFunction("TextSub", "c[file]s[charset]i[fps]f[vfr]s", TextSubCreateGeneral
, 0);
893 env
->AddFunction("TextSubSwapUV", "b", TextSubSwapUV
, 0);
894 env
->AddFunction("MaskSub", "[file]s[width]i[height]i[fps]f[length]i[charset]i[vfr]s", MaskSubCreate
, 0);
895 env
->SetVar(env
->SaveString("RGBA"),false);
902 UINT CALLBACK
OpenHookProc(HWND hDlg
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
908 OPENFILENAME
* ofn
= ((OFNOTIFY
*)lParam
)->lpOFN
;
910 if(((NMHDR
*)lParam
)->code
== CDN_FILEOK
)
912 ofn
->lCustData
= (LPARAM
)CharSetList
[SendMessage(GetDlgItem(hDlg
, IDC_COMBO1
), CB_GETCURSEL
, 0, 0)];
920 SetWindowLong(hDlg
, GWL_USERDATA
, lParam
);
922 for(int i
= 0; i
< CharSetLen
; i
++)
925 s
.Format(_T("%s (%d)"), CharSetNames
[i
], CharSetList
[i
]);
926 SendMessage(GetDlgItem(hDlg
, IDC_COMBO1
), CB_ADDSTRING
, 0, (LONG
)(LPCTSTR
)s
);
927 if(CharSetList
[i
] == (int)((OPENFILENAME
*)lParam
)->lCustData
)
928 SendMessage(GetDlgItem(hDlg
, IDC_COMBO1
), CB_SETCURSEL
, i
, 0);