2006-01-22 13:44:53 +01:00
// Copyright (c) 2006, Fredrik Mellbin
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
# include <wx/filename.h>
# include <wx/msw/registry.h>
2006-12-26 02:08:46 +01:00
# include <wx/filename.h>
2006-02-23 04:41:29 +01:00
# include "video_provider_avs.h"
2006-01-22 13:44:53 +01:00
# include "options.h"
# include "main.h"
2007-01-01 04:29:20 +01:00
# include "vfr.h"
2006-01-22 13:44:53 +01:00
2006-02-24 09:30:08 +01:00
# ifdef __WINDOWS__
2006-12-19 18:30:25 +01:00
///////////////
// Constructor
2007-01-01 04:29:20 +01:00
AvisynthVideoProvider : : AvisynthVideoProvider ( wxString _filename , wxString _subfilename , double _fps ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( wxString : : Format ( _T ( " AvisynthVideoProvider: Creating new AvisynthVideoProvider: \" %s \" , \" %s \" " ) , _filename , _subfilename ) ) ;
2006-02-24 03:54:30 +01:00
bool mpeg2dec3_priority = true ;
2006-01-22 13:44:53 +01:00
RGB32Video = NULL ;
SubtitledVideo = NULL ;
ResizedVideo = NULL ;
data = NULL ;
2007-01-01 04:29:20 +01:00
fps = _fps ;
2006-03-11 17:20:40 +01:00
depth = 0 ;
2006-01-22 13:44:53 +01:00
last_fnum = - 1 ;
2007-01-01 04:29:20 +01:00
num_frames = 0 ;
2006-01-22 13:44:53 +01:00
subfilename = _subfilename ;
2006-02-24 09:43:44 +01:00
zoom = 1.0 ;
2006-01-22 13:44:53 +01:00
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider: Loading VSFilter " ) ) ;
2006-01-22 13:44:53 +01:00
LoadVSFilter ( ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider: VSFilter loaded " ) ) ;
2006-01-22 13:44:53 +01:00
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider: Opening video " ) ) ;
2006-02-25 21:48:32 +01:00
RGB32Video = OpenVideo ( _filename , mpeg2dec3_priority ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider: Video opened " ) ) ;
2006-01-22 13:44:53 +01:00
dar = GetSourceWidth ( ) / ( double ) GetSourceHeight ( ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider: Calculated aspect ratio " ) ) ;
2006-01-22 13:44:53 +01:00
2006-02-20 22:32:58 +01:00
if ( _subfilename . IsEmpty ( ) ) SubtitledVideo = RGB32Video ;
2006-01-28 20:48:35 +01:00
else SubtitledVideo = ApplySubtitles ( subfilename , RGB32Video ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider: Applied subtitles " ) ) ;
2006-03-11 17:20:40 +01:00
2006-01-22 13:44:53 +01:00
ResizedVideo = ApplyDARZoom ( zoom , dar , SubtitledVideo ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider: Applied zoom " ) ) ;
2006-01-28 20:48:35 +01:00
vi = ResizedVideo - > GetVideoInfo ( ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider: Got video info " ) ) ;
AVSTRACE ( _T ( " AvisynthVideoProvider: Done creating AvisynthVideoProvider " ) ) ;
2006-01-22 13:44:53 +01:00
}
2006-12-19 18:30:25 +01:00
//////////////
// Destructor
2006-02-23 04:41:29 +01:00
AvisynthVideoProvider : : ~ AvisynthVideoProvider ( ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider: Destroying AvisynthVideoProvider " ) ) ;
2006-01-22 13:44:53 +01:00
RGB32Video = NULL ;
SubtitledVideo = NULL ;
ResizedVideo = NULL ;
2006-01-28 20:48:35 +01:00
if ( data ) delete data ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider: AvisynthVideoProvider destroyed " ) ) ;
2006-01-22 13:44:53 +01:00
}
2006-12-19 18:30:25 +01:00
/////////////////////
// Refresh subtitles
2006-02-23 04:41:29 +01:00
void AvisynthVideoProvider : : RefreshSubtitles ( ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::RefreshSubtitles: Refreshing subtitles " ) ) ;
2006-01-22 13:44:53 +01:00
ResizedVideo = NULL ;
SubtitledVideo = NULL ;
SubtitledVideo = ApplySubtitles ( subfilename , RGB32Video ) ;
ResizedVideo = ApplyDARZoom ( zoom , dar , SubtitledVideo ) ;
GetFrame ( last_fnum , true ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::RefreshSubtitles: Subtitles refreshed " ) ) ;
2006-01-22 13:44:53 +01:00
}
2006-12-19 18:30:25 +01:00
////////////////////////////
// Set Display Aspect Ratio
2006-02-23 04:41:29 +01:00
void AvisynthVideoProvider : : SetDAR ( double _dar ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::SetDAR: Setting DAR " ) ) ;
2006-01-22 13:44:53 +01:00
dar = _dar ;
ResizedVideo = NULL ;
delete data ;
data = NULL ;
ResizedVideo = ApplyDARZoom ( zoom , dar , SubtitledVideo ) ;
GetFrame ( last_fnum , true ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::SetDAR: DAR set " ) ) ;
2006-01-22 13:44:53 +01:00
}
2006-12-19 18:30:25 +01:00
////////////
// Set Zoom
2006-02-23 04:41:29 +01:00
void AvisynthVideoProvider : : SetZoom ( double _zoom ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::SetZoom: Setting zoom " ) ) ;
2006-01-22 13:44:53 +01:00
zoom = _zoom ;
ResizedVideo = NULL ;
delete data ;
data = NULL ;
ResizedVideo = ApplyDARZoom ( zoom , dar , SubtitledVideo ) ;
GetFrame ( last_fnum , true ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::SetZoom: Zoom set " ) ) ;
2006-01-22 13:44:53 +01:00
}
2006-12-19 18:30:25 +01:00
/////////////////////////////////////////
// Actually open the video into Avisynth
2006-02-25 21:48:32 +01:00
PClip AvisynthVideoProvider : : OpenVideo ( wxString _filename , bool mpeg2dec3_priority ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Opening video " ) ) ;
2006-01-22 13:44:53 +01:00
wxMutexLocker lock ( AviSynthMutex ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Got AVS mutex " ) ) ;
2006-01-22 13:44:53 +01:00
AVSValue script ;
2006-02-25 21:48:32 +01:00
bool usedDirectshow = false ;
2006-01-22 13:44:53 +01:00
wxString extension = _filename . Right ( 4 ) ;
extension . LowerCase ( ) ;
try {
// Prepare filename
2006-12-26 02:08:46 +01:00
//char *videoFilename = env->SaveString(_filename.mb_str(wxConvLocal));
wxFileName fname ( _filename ) ;
char * videoFilename = env - > SaveString ( fname . GetShortPath ( ) . mb_str ( wxConvLocal ) ) ;
2006-01-22 13:44:53 +01:00
2006-12-19 18:30:25 +01:00
// Avisynth file, just import it
2006-01-22 13:44:53 +01:00
if ( extension = = _T ( " .avs " ) ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Opening .avs file with Import " ) ) ;
2006-01-22 13:44:53 +01:00
script = env - > Invoke ( " Import " , videoFilename ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Finished " ) ) ;
}
2006-12-19 18:30:25 +01:00
// Open avi file with AviSource
2006-12-17 05:58:10 +01:00
else if ( extension = = _T ( " .avi " ) ) {
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Opening .avi file with AviSource " ) ) ;
2006-01-22 13:44:53 +01:00
try {
const char * argnames [ 2 ] = { 0 , " audio " } ;
AVSValue args [ 2 ] = { videoFilename , false } ;
script = env - > Invoke ( " AviSource " , AVSValue ( args , 2 ) , argnames ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Successfully opened .avi file without audio " ) ) ;
2006-12-19 18:30:25 +01:00
}
// On Failure, fallback to DSS
catch ( AvisynthError & ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " Failed to open .avi file with AviSource, switching to DirectShowSource " ) ) ;
2006-01-22 13:44:53 +01:00
goto directshowOpen ;
}
}
2006-12-19 18:30:25 +01:00
// Open d2v with mpeg2dec3
else if ( extension = = _T ( " .d2v " ) & & env - > FunctionExists ( " mpeg2dec3_Mpeg2Source " ) & & mpeg2dec3_priority ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Opening .d2v file with mpeg2dec3_Mpeg2Source " ) ) ;
2006-01-22 13:44:53 +01:00
script = env - > Invoke ( " mpeg2dec3_Mpeg2Source " , videoFilename ) ;
2006-12-17 05:58:10 +01:00
}
2006-12-19 18:30:25 +01:00
// If that fails, try opening it with other mpeg2source
else if ( extension = = _T ( " .d2v " ) & & env - > FunctionExists ( " Mpeg2Source " ) ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Opening .d2v file with other Mpeg2Source " ) ) ;
2006-01-22 13:44:53 +01:00
script = env - > Invoke ( " Mpeg2Source " , videoFilename ) ;
2006-12-17 05:58:10 +01:00
}
2006-12-19 18:30:25 +01:00
// Some other format, such as mkv, mp4, ogm... try DirectShowSource
2006-01-22 13:44:53 +01:00
else {
directshowOpen :
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Opening file with DirectShowSource " ) ) ;
2006-01-22 13:44:53 +01:00
2006-12-19 18:30:25 +01:00
// Try loading DirectShowSource2
bool dss2 = false ;
if ( env - > FunctionExists ( " dss2 " ) ) dss2 = true ;
if ( ! dss2 ) {
wxFileName dss2path ( AegisubApp : : folderName + _T ( " avss.dll " ) ) ;
if ( dss2path . FileExists ( ) ) {
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Loading DirectShowSource2 " ) ) ;
env - > Invoke ( " LoadPlugin " , env - > SaveString ( dss2path . GetFullPath ( ) . mb_str ( wxConvLocal ) ) ) ;
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Loaded DirectShowSource2 " ) ) ;
}
2006-12-17 05:58:10 +01:00
}
2006-12-19 18:30:25 +01:00
// If DSS2 loaded properly, try using it
dss2 = false ;
if ( env - > FunctionExists ( " dss2 " ) ) {
AVSTRACE ( _T ( " visynthVideoProvider::OpenVideo: Invoking DSS2 " ) ) ;
2007-01-01 04:29:20 +01:00
if ( fps = = 0.0 ) script = env - > Invoke ( " DSS2 " , videoFilename ) ;
else {
const char * argnames [ 2 ] = { 0 , " fps " } ;
AVSValue args [ 2 ] = { videoFilename , fps } ;
script = env - > Invoke ( " DSS2 " , AVSValue ( args , 2 ) , argnames ) ;
}
2006-12-19 18:30:25 +01:00
AVSTRACE ( _T ( " visynthVideoProvider::OpenVideo: Successfully opened file with DSS2 " ) ) ;
dss2 = true ;
2006-12-17 05:58:10 +01:00
}
2006-12-19 18:30:25 +01:00
// Try DirectShowSource
if ( ! dss2 ) {
if ( env - > FunctionExists ( " DirectShowSource " ) ) {
2007-01-01 04:34:08 +01:00
if ( fps = = 0.0 ) {
const char * argnames [ 3 ] = { 0 , " video " , " audio " } ;
AVSValue args [ 3 ] = { videoFilename , true , false } ;
script = env - > Invoke ( " DirectShowSource " , AVSValue ( args , 3 ) , argnames ) ;
}
else {
const char * argnames [ 4 ] = { 0 , " video " , " audio " , " fps " } ;
AVSValue args [ 4 ] = { videoFilename , true , false , fps } ;
script = env - > Invoke ( " DirectShowSource " , AVSValue ( args , 4 ) , argnames ) ;
}
2006-12-19 18:30:25 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Successfully opened file with DSS without audio " ) ) ;
usedDirectshow = true ;
}
// Failed to find a suitable function
else {
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: DSS function not found " ) ) ;
throw AvisynthError ( " No function suitable for opening the video found " ) ;
}
}
}
}
// Catch errors
catch ( AvisynthError & err ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Avisynth error: " ) + wxString ( err . msg , wxConvLocal ) ) ;
2006-01-22 13:44:53 +01:00
throw _T ( " AviSynth error: " ) + wxString ( err . msg , wxConvLocal ) ;
}
2006-12-19 18:30:25 +01:00
// Check if video was loaded properly
2006-12-17 05:58:10 +01:00
if ( ! script . AsClip ( ) - > GetVideoInfo ( ) . HasVideo ( ) ) {
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: No suitable video found " ) ) ;
2006-01-22 13:44:53 +01:00
throw _T ( " No usable video found in " ) + _filename ;
2006-12-17 05:58:10 +01:00
}
2006-01-22 13:44:53 +01:00
// Convert to RGB32
script = env - > Invoke ( " ConvertToRGB32 " , script ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Converted to RGB32 " ) ) ;
2006-01-22 13:44:53 +01:00
2006-02-25 21:48:32 +01:00
// Directshow
2006-12-19 03:59:03 +01:00
//if (usedDirectshow) wxMessageBox(_T("Warning! The file is being opened using Avisynth's DirectShowSource, which has unreliable seeking. Frame numbers might not match the real number. PROCEED AT YOUR OWN RISK!"),_T("DirectShowSource warning"),wxICON_EXCLAMATION);
2006-02-25 21:48:32 +01:00
2006-01-22 13:44:53 +01:00
// Cache
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Finished opening video, AVS mutex will be released now " ) ) ;
2006-02-22 20:47:44 +01:00
return ( env - > Invoke ( " Cache " , script ) ) . AsClip ( ) ;
2006-01-22 13:44:53 +01:00
}
2006-12-19 18:30:25 +01:00
////////////////////////////////////////////////////////
// Apply VSFilter subtitles, or whatever is appropriate
2006-02-23 04:41:29 +01:00
PClip AvisynthVideoProvider : : ApplySubtitles ( wxString _filename , PClip videosource ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::ApplySutitles: Applying subtitles " ) ) ;
2006-01-22 13:44:53 +01:00
wxMutexLocker lock ( AviSynthMutex ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::ApplySutitles: Got AVS mutex " ) ) ;
2006-01-22 13:44:53 +01:00
// Insert subs
AVSValue script ;
char temp [ 512 ] ;
2006-12-26 02:08:46 +01:00
wxFileName fname ( _filename ) ;
strcpy ( temp , fname . GetShortPath ( ) . mb_str ( wxConvLocal ) ) ;
2006-01-22 13:44:53 +01:00
AVSValue args [ 2 ] = { videosource , temp } ;
try {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::ApplySutitles: Now invoking TextSub " ) ) ;
2006-01-22 13:44:53 +01:00
script = env - > Invoke ( " TextSub " , AVSValue ( args , 2 ) ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::ApplySutitles: TextSub invoked successfully " ) ) ;
2006-01-22 13:44:53 +01:00
} catch ( AvisynthError & err ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::ApplySutitles: Avisynth error: " ) + wxString ( err . msg , wxConvLocal ) ) ;
2006-01-22 13:44:53 +01:00
throw _T ( " AviSynth error: " ) + wxString ( err . msg , wxConvLocal ) ;
}
// Cache
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::ApplySutitles: Subtitles applied, AVS mutex will be released now " ) ) ;
2006-02-22 20:47:44 +01:00
return ( env - > Invoke ( " Cache " , script ) ) . AsClip ( ) ;
2006-01-22 13:44:53 +01:00
}
2006-12-19 18:30:25 +01:00
/////////////////////////////////////
// Apply Display Aspect Ratio + Zoom
2006-02-23 04:41:29 +01:00
PClip AvisynthVideoProvider : : ApplyDARZoom ( double _zoom , double _dar , PClip videosource ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::ApplyDARZoom: Applying DAR zoom " ) ) ;
2006-01-22 13:44:53 +01:00
wxMutexLocker lock ( AviSynthMutex ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::ApplyDARZoom: Got AVS mutex " ) ) ;
2006-01-22 13:44:53 +01:00
AVSValue script ;
VideoInfo vil = videosource - > GetVideoInfo ( ) ;
int w = vil . height * _zoom * _dar ;
int h = vil . height * _zoom ;
2007-01-08 22:11:06 +01:00
if ( w = = vil . width & & h = = vil . height ) {
vi = vil ;
return ( env - > Invoke ( " Cache " , videosource ) ) . AsClip ( ) ;
}
2006-01-22 13:44:53 +01:00
try {
// Resize
if ( ! env - > FunctionExists ( Options . AsText ( _T ( " Video resizer " ) ) . mb_str ( wxConvLocal ) ) )
throw AvisynthError ( " Selected resizer doesn't exist " ) ;
AVSValue args [ 3 ] = { videosource , w , h } ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::ApplyDARZoom: Invoking resizing function " ) ) ;
2006-01-22 13:44:53 +01:00
script = env - > Invoke ( Options . AsText ( _T ( " Video resizer " ) ) . mb_str ( wxConvLocal ) , AVSValue ( args , 3 ) ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::ApplyDARZoom: Resizer invoked successfully " ) ) ;
2006-01-22 13:44:53 +01:00
} catch ( AvisynthError & err ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::ApplyDARZoom: Avisynth error: " ) + wxString ( err . msg , wxConvLocal ) ) ;
2006-01-22 13:44:53 +01:00
throw _T ( " AviSynth error: " ) + wxString ( err . msg , wxConvLocal ) ;
}
vi = script . AsClip ( ) - > GetVideoInfo ( ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::ApplyDARZoom: DAR zoom applied successfully, AVS mutex will be released now " ) ) ;
2006-02-22 20:47:44 +01:00
return ( env - > Invoke ( " Cache " , script ) ) . AsClip ( ) ;
2006-01-22 13:44:53 +01:00
}
2006-12-19 18:30:25 +01:00
////////////////////////
// Actually get a frame
2007-01-01 04:29:20 +01:00
wxBitmap AvisynthVideoProvider : : GetFrame ( int _n , bool force ) {
// Transform n if overriden
int n = _n ;
if ( frameTime . Count ( ) ) {
if ( n < 0 ) n = 0 ;
if ( n > = ( signed ) frameTime . Count ( ) ) n = frameTime . Count ( ) - 1 ;
int time = frameTime [ n ] ;
double curFps = ( double ) vi . fps_numerator / ( double ) vi . fps_denominator ;
n = time * curFps / 1000.0 ;
}
// Get frame
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::GetFrame " ) ) ;
2006-01-22 13:44:53 +01:00
if ( n ! = last_fnum | | force ) {
wxMutexLocker lock ( AviSynthMutex ) ;
PVideoFrame frame = ResizedVideo - > GetFrame ( n , env ) ;
2006-03-11 17:20:40 +01:00
int ndepth = wxDisplayDepth ( ) ;
if ( depth ! = ndepth ) {
depth = ndepth ;
delete data ;
data = NULL ;
}
2006-01-22 13:44:53 +01:00
if ( ! data )
2006-03-11 17:20:40 +01:00
data = new unsigned char [ vi . width * vi . height * depth / 8 ] ;
unsigned char * dst = data + ( vi . width * ( vi . height - 1 ) * depth / 8 ) ;
2006-01-22 13:44:53 +01:00
2006-03-11 17:20:40 +01:00
if ( depth = = 32 ) {
int rs = vi . RowSize ( ) ;
const unsigned char * src = frame - > GetReadPtr ( ) ;
int srcpitch = frame - > GetPitch ( ) ;
2006-01-22 13:44:53 +01:00
2006-03-11 17:20:40 +01:00
for ( int y = 0 ; y < vi . height ; y + + ) {
memcpy ( dst , src , rs ) ;
src + = srcpitch ;
dst - = rs ;
}
2006-03-30 00:39:41 +02:00
}
else if ( depth = = 24 ) {
2006-03-11 17:20:40 +01:00
//fail
2006-03-30 00:39:41 +02:00
}
else if ( depth = = 16 ) {
2006-03-11 17:20:40 +01:00
const unsigned char * read_ptr = frame - > GetReadPtr ( ) ;
unsigned short * write_ptr = ( unsigned short * ) dst ;
unsigned char r , g , b ;
int srcpitch = frame - > GetPitch ( ) ;
int rs = vi . RowSize ( ) ;
for ( int y = 0 ; y < vi . height ; y + + ) {
for ( int x = 0 , dx = 0 ; x < rs ; x + = 4 , dx + + ) {
r = read_ptr [ x + 2 ] ;
g = read_ptr [ x + 1 ] ;
b = read_ptr [ x ] ;
write_ptr [ dx ] = ( ( r > > 3 ) < < 11 ) | ( ( g > > 2 ) < < 5 ) | b > > 3 ;
}
write_ptr - = vi . width ;
read_ptr + = srcpitch ;
}
2006-03-30 00:39:41 +02:00
}
else {
2006-03-11 17:20:40 +01:00
//fail
2006-01-22 13:44:53 +01:00
}
2006-03-11 17:20:40 +01:00
last_frame = wxBitmap ( ( const char * ) data , vi . width , vi . height , depth ) ;
2006-01-22 13:44:53 +01:00
last_fnum = n ;
}
return wxBitmap ( last_frame ) ;
}
2006-12-19 18:30:25 +01:00
///////////////////////////////////
// Get a frame intensity as floats
2006-02-23 04:41:29 +01:00
void AvisynthVideoProvider : : GetFloatFrame ( float * Buffer , int n ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::GetFloatFrame " ) ) ;
2006-01-28 20:48:35 +01:00
wxMutexLocker lock ( AviSynthMutex ) ;
PVideoFrame frame = ResizedVideo - > GetFrame ( n , env ) ;
int rs = vi . RowSize ( ) ;
const unsigned char * src = frame - > GetReadPtr ( ) ;
int srcpitch = frame - > GetPitch ( ) ;
for ( int i = 0 ; i < vi . height ; i + + )
{
for ( int x = 0 ; x < vi . width ; x + + )
{
Buffer [ ( vi . height - i - 1 ) * vi . width + x ] = src [ x * 4 + 0 ] * 0.3 + src [ x * 4 + 1 ] * 0.4 + src [ x * 4 + 2 ] * 0.3 ;
}
src + = srcpitch ;
}
}
2006-12-19 18:30:25 +01:00
/////////////////
// Load VSFilter
2006-02-23 04:41:29 +01:00
void AvisynthVideoProvider : : LoadVSFilter ( ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::LoadVSFilter: Loading VSFilter " ) ) ;
2006-01-22 13:44:53 +01:00
// Loading an avisynth plugin multiple times does almost nothing
wxFileName vsfilterPath ( AegisubApp : : folderName + _T ( " vsfilter.dll " ) ) ;
2006-12-17 05:58:10 +01:00
if ( vsfilterPath . FileExists ( ) ) {
AVSTRACE ( _T ( " AvisynthVideoProvider::LoadVSFilter: Invoking LoadPlugin " ) ) ;
2006-01-22 13:44:53 +01:00
env - > Invoke ( " LoadPlugin " , env - > SaveString ( vsfilterPath . GetFullPath ( ) . mb_str ( wxConvLocal ) ) ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::LoadVSFilter: Loaded " ) ) ;
} else {
AVSTRACE ( _T ( " AvisynthVideoProvider::LoadVSFilter: VSFilter.dll not found in Aegisub dir, trying to locate registered DShow filter " ) ) ;
2006-01-22 13:44:53 +01:00
wxRegKey reg ( _T ( " HKEY_CLASSES_ROOT \\ CLSID \\ {9852A670-F845-491B-9BE6-EBD841B8A613} \\ InprocServer32 " ) ) ;
if ( reg . Exists ( ) ) {
wxString fn ;
reg . QueryValue ( _T ( " " ) , fn ) ;
vsfilterPath = fn ;
if ( vsfilterPath . FileExists ( ) ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::LoadVSFilter: Found as DShow filter, loading " ) ) ;
2006-01-22 13:44:53 +01:00
env - > Invoke ( " LoadPlugin " , env - > SaveString ( vsfilterPath . GetFullPath ( ) . mb_str ( wxConvLocal ) ) ) ;
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::LoadVSFilter: Loaded " ) ) ;
2006-01-22 13:44:53 +01:00
return ;
}
vsfilterPath = _T ( " vsfilter.dll " ) ;
} else if ( vsfilterPath . FileExists ( ) )
env - > Invoke ( " LoadPlugin " , env - > SaveString ( vsfilterPath . GetFullPath ( ) . mb_str ( wxConvLocal ) ) ) ;
2006-12-17 05:58:10 +01:00
else if ( ! env - > FunctionExists ( " TextSub " ) ) {
AVSTRACE ( _T ( " AvisynthVideoProvider::LoadVSFilter: Couldn't locate VSFilter " ) ) ;
2006-01-22 13:44:53 +01:00
throw _T ( " Couldn't locate VSFilter " ) ;
2006-12-17 05:58:10 +01:00
}
2006-01-22 13:44:53 +01:00
}
}
2006-02-24 09:30:08 +01:00
2007-01-01 04:29:20 +01:00
////////////////////////
// Override frame times
void AvisynthVideoProvider : : OverrideFrameTimeList ( wxArrayInt list ) {
frameTime = list ;
num_frames = frameTime . Count ( ) ;
}
2006-02-24 09:30:08 +01:00
# endif