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
//
2007-01-21 08:12:47 +01:00
///////////
// Headers
2009-01-04 07:31:48 +01:00
# include "config.h"
2007-01-21 07:30:19 +01:00
# include <wx/wxprec.h>
2008-01-22 03:54:16 +01:00
# ifdef WITH_AVISYNTH
2006-01-22 13:44:53 +01:00
# include <wx/filename.h>
# include <wx/msw/registry.h>
2006-12-26 02:08:46 +01:00
# include <wx/filename.h>
2008-03-05 03:05:01 +01:00
# include "video_provider_avs.h"
2007-01-21 07:30:19 +01:00
# include "video_context.h"
2006-01-22 13:44:53 +01:00
# include "options.h"
2007-06-21 02:46:50 +02:00
# include "standard_paths.h"
2007-01-01 04:29:20 +01:00
# include "vfr.h"
2007-01-27 07:15:25 +01:00
# include "gl_wrap.h"
2008-07-15 02:08:05 +02:00
# include "mkv_wrap.h"
# include "vfw_wrap.h"
2006-01-22 13:44:53 +01:00
2006-12-19 18:30:25 +01:00
///////////////
// Constructor
2008-03-07 22:24:14 +01:00
AvisynthVideoProvider : : AvisynthVideoProvider ( Aegisub : : String _filename , 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 ;
2007-01-01 04:29:20 +01:00
fps = _fps ;
num_frames = 0 ;
2007-01-21 07:30:19 +01:00
last_fnum = - 1 ;
2007-07-29 11:06:38 +02:00
byFrame = false ;
2008-07-15 02:08:05 +02:00
KeyFrames . Clear ( ) ;
keyFramesLoaded = false ;
isVfr = false ;
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
2009-05-15 14:44:36 +02:00
vi = RGB32Video - > 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 ;
2007-01-21 07:30:19 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider: Destroying frame " ) ) ;
iframe . Clear ( ) ;
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
2006-01-22 13:44:53 +01:00
2007-01-21 07:30:19 +01:00
////////////////////////////////////// VIDEO PROVIDER //////////////////////////////////////
2006-01-22 13:44:53 +01:00
2006-12-19 18:30:25 +01:00
/////////////////////////////////////////
// Actually open the video into Avisynth
2008-03-07 22:24:14 +01:00
PClip AvisynthVideoProvider : : OpenVideo ( Aegisub : : String _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 ;
2007-07-29 11:06:38 +02:00
byFrame = false ;
usedDirectShow = false ;
2007-08-20 00:21:41 +02:00
decoderName = _ ( " Unknown " ) ;
2006-01-22 13:44:53 +01:00
2008-03-07 22:24:14 +01:00
wxString extension = wxString ( _filename . c_str ( ) ) . Right ( 4 ) ;
2006-01-22 13:44:53 +01:00
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 " ) ) ;
2007-10-19 02:55:03 +02:00
decoderName = _T ( " Import " ) ;
2006-12-17 05:58:10 +01:00
}
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 " ) ) ;
2007-07-29 11:06:38 +02:00
byFrame = true ;
2007-08-20 00:21:41 +02:00
decoderName = _T ( " AviSource " ) ;
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
2007-01-11 20:49:37 +01:00
else if ( extension = = _T ( " .d2v " ) & & env - > FunctionExists ( " Mpeg2Dec3_Mpeg2Source " ) & & mpeg2dec3_priority ) {
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Opening .d2v file with Mpeg2Dec3_Mpeg2Source " ) ) ;
script = env - > Invoke ( " Mpeg2Dec3_Mpeg2Source " , videoFilename ) ;
2007-08-20 00:21:41 +02:00
decoderName = _T ( " Mpeg2Dec3_Mpeg2Source " ) ;
2007-01-11 20:49:37 +01:00
//if avisynth is 2.5.7 beta 2 or newer old mpeg2decs will crash without this
2007-01-15 21:48:58 +01:00
if ( env - > FunctionExists ( " SetPlanarLegacyAlignment " ) ) {
AVSValue args [ 2 ] = { script , true } ;
script = env - > Invoke ( " SetPlanarLegacyAlignment " , AVSValue ( args , 2 ) ) ;
}
2007-01-11 20:49:37 +01:00
}
// If that fails, try opening it with DGDecode
else if ( extension = = _T ( " .d2v " ) & & env - > FunctionExists ( " DGDecode_Mpeg2Source " ) ) {
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Opening .d2v file with DGDecode_Mpeg2Source " ) ) ;
script = env - > Invoke ( " Mpeg2Source " , videoFilename ) ;
2007-08-20 00:21:41 +02:00
decoderName = _T ( " DGDecode_Mpeg2Source " ) ;
2007-01-11 20:49:37 +01:00
//note that DGDecode will also have issues like if the version is too ancient but no sane person
//would use that anyway
2006-12-17 05:58:10 +01:00
}
2006-12-19 18:30:25 +01:00
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 ) ;
2007-08-20 00:21:41 +02:00
decoderName = _T ( " Mpeg2Source " ) ;
2007-01-11 20:49:37 +01:00
//if avisynth is 2.5.7 beta 2 or newer old mpeg2decs will crash without this
if ( env - > FunctionExists ( " SetPlanarLegacyAlignment " ) )
script = env - > Invoke ( " SetPlanarLegacyAlignment " , script ) ;
2006-12-17 05:58:10 +01:00
}
2006-12-19 18:30:25 +01:00
2007-06-17 00:07:43 +02:00
// Some other format, such as mkv, mp4, ogm... try FFMpegSource and DirectShowSource
2006-01-22 13:44:53 +01:00
else {
2007-06-17 00:07:43 +02:00
// Try loading FFMpegSource
2007-08-20 00:56:22 +02:00
directshowOpen :
2007-06-17 00:07:43 +02:00
bool ffsource = false ;
2009-04-23 04:09:05 +02:00
if ( env - > FunctionExists ( " ffvideosource " ) ) ffsource = true ;
2007-06-17 00:07:43 +02:00
if ( ! ffsource ) {
2009-04-23 04:09:05 +02:00
wxFileName ffsourcepath ( StandardPaths : : DecodePath ( _T ( " ?data/ffms2.dll " ) ) ) ;
2007-06-17 00:07:43 +02:00
if ( ffsourcepath . FileExists ( ) ) {
2009-04-23 04:09:05 +02:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Loading FFMpegSource2 " ) ) ;
2007-06-17 00:07:43 +02:00
env - > Invoke ( " LoadPlugin " , env - > SaveString ( ffsourcepath . GetFullPath ( ) . mb_str ( wxConvLocal ) ) ) ;
2009-04-23 04:09:05 +02:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Loaded FFMpegSource2 " ) ) ;
2007-07-29 11:06:38 +02:00
byFrame = true ;
2006-12-19 18:30:25 +01:00
}
2006-12-17 05:58:10 +01:00
}
2006-12-19 18:30:25 +01:00
2007-06-17 00:07:43 +02:00
// If FFMpegSource loaded properly, try using it
ffsource = false ;
2009-04-23 04:09:05 +02:00
if ( env - > FunctionExists ( " ffvideosource " ) ) {
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Invoking FFMpegSource2 " ) ) ;
const char * argnames [ 2 ] = { " source " , " cache " } ;
2007-10-18 22:19:06 +02:00
AVSValue args [ 2 ] = { videoFilename , false } ;
2009-04-23 04:09:05 +02:00
script = env - > Invoke ( " ffvideosource " , AVSValue ( args , 2 ) , argnames ) ;
2007-10-18 22:19:06 +02:00
//script = env->Invoke("ffmpegsource", videoFilename);
2009-04-23 04:09:05 +02:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Successfully opened file with FFMpegSource2 " ) ) ;
2007-06-17 00:07:43 +02:00
ffsource = true ;
2009-04-23 04:09:05 +02:00
decoderName = _T ( " FFmpegSource2 " ) ;
2006-12-17 05:58:10 +01:00
}
2006-12-19 18:30:25 +01:00
2007-06-17 00:07:43 +02:00
// DirectShowSource
if ( ! ffsource ) {
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Opening file with DirectShowSource " ) ) ;
// Try loading DirectShowSource2
bool dss2 = false ;
if ( env - > FunctionExists ( " dss2 " ) ) dss2 = true ;
if ( ! dss2 ) {
2007-06-21 02:46:50 +02:00
wxFileName dss2path ( StandardPaths : : DecodePath ( _T ( " ?data/avss.dll " ) ) ) ;
2007-06-17 00:07:43 +02:00
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 " ) ) ;
2007-01-01 04:34:08 +01:00
}
2007-06-17 00:07:43 +02:00
}
// If DSS2 loaded properly, try using it
dss2 = false ;
if ( env - > FunctionExists ( " dss2 " ) ) {
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Invoking DSS2 " ) ) ;
if ( fps = = 0.0 ) script = env - > Invoke ( " DSS2 " , videoFilename ) ;
2007-01-01 04:34:08 +01:00
else {
2007-06-17 00:07:43 +02:00
const char * argnames [ 2 ] = { 0 , " fps " } ;
AVSValue args [ 2 ] = { videoFilename , fps } ;
script = env - > Invoke ( " DSS2 " , AVSValue ( args , 2 ) , argnames ) ;
2007-01-01 04:34:08 +01:00
}
2007-06-17 00:07:43 +02:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Successfully opened file with DSS2 " ) ) ;
dss2 = true ;
2007-08-20 00:21:41 +02:00
decoderName = _T ( " DSS2 " ) ;
2006-12-19 18:30:25 +01:00
}
2007-06-17 00:07:43 +02:00
// Try DirectShowSource
if ( ! dss2 ) {
2007-08-28 23:34:44 +02:00
// Load DirectShowSource.dll from app dir if it exists
wxFileName dsspath ( StandardPaths : : DecodePath ( _T ( " ?data/DirectShowSource.dll " ) ) ) ;
if ( dsspath . FileExists ( ) ) {
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Loading DirectShowSource " ) ) ;
env - > Invoke ( " LoadPlugin " , env - > SaveString ( dsspath . GetFullPath ( ) . mb_str ( wxConvLocal ) ) ) ;
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Loaded DirectShowSource " ) ) ;
}
// Then try using DSS
2007-06-17 00:07:43 +02:00
if ( env - > FunctionExists ( " DirectShowSource " ) ) {
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 ) ;
}
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Successfully opened file with DSS without audio " ) ) ;
2007-07-29 11:06:38 +02:00
usedDirectShow = true ;
2007-08-20 00:21:41 +02:00
decoderName = _T ( " DirectShowSource " ) ;
2007-06-17 00:07:43 +02:00
}
// 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 " ) ;
}
2006-12-19 18:30:25 +01:00
}
}
}
}
// 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
2008-03-06 22:38:40 +01:00
if ( ! script . IsClip ( ) | | ! script . AsClip ( ) - > GetVideoInfo ( ) . HasVideo ( ) ) {
2006-12-17 05:58:10 +01:00
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: No suitable video found " ) ) ;
2007-07-18 15:46:38 +02:00
throw _T ( " Avisynth: No usable video found in " ) + _filename ;
2006-12-17 05:58:10 +01:00
}
2006-01-22 13:44:53 +01:00
2008-07-15 02:08:05 +02:00
// Read keyframes and timecodes from MKV file
isVfr = false ;
FrameRate temp ;
double overFps = 0 ;
bool mkvOpen = MatroskaWrapper : : wrapper . IsOpen ( ) ;
KeyFrames . Clear ( ) ;
if ( extension = = _T ( " .mkv " ) | | mkvOpen ) {
// Parse mkv
if ( ! mkvOpen ) MatroskaWrapper : : wrapper . Open ( _filename ) ;
// Get keyframes
KeyFrames = MatroskaWrapper : : wrapper . GetKeyFrames ( ) ;
keyFramesLoaded = true ;
// Ask to override timecodes
int override = wxYES ;
if ( VFR_Output . IsLoaded ( ) ) override = wxMessageBox ( _ ( " You already have timecodes loaded. Replace them with the timecodes from the Matroska file? " ) , _ ( " Replace timecodes? " ) , wxYES_NO | wxICON_QUESTION ) ;
if ( override = = wxYES ) {
MatroskaWrapper : : wrapper . SetToTimecodes ( temp ) ;
isVfr = temp . GetFrameRateType ( ) = = VFR ;
if ( isVfr ) {
overFps = temp . GetCommonFPS ( ) ;
MatroskaWrapper : : wrapper . SetToTimecodes ( VFR_Input ) ;
MatroskaWrapper : : wrapper . SetToTimecodes ( VFR_Output ) ;
trueFrameRate = temp ;
}
}
// Close mkv
MatroskaWrapper : : wrapper . Close ( ) ;
}
// check if we have windows, if so we can load keyframes from AVI files using VFW
# ifdef __WINDOWS__
else if ( extension = = _T ( " .avi " ) ) {
keyFramesLoaded = false ;
KeyFrames . Clear ( ) ;
KeyFrames = VFWWrapper : : GetKeyFrames ( _filename ) ;
keyFramesLoaded = true ;
}
# endif /* __WINDOWS__ */
// Check if the file is all keyframes
bool isAllKeyFrames = true ;
for ( unsigned int i = 1 ; i < KeyFrames . GetCount ( ) ; i + + ) {
// Is the last keyframe not this keyframe -1?
if ( KeyFrames [ i - 1 ] ! = ( int ) ( i - 1 ) ) {
// It's not all keyframes, go ahead
isAllKeyFrames = false ;
break ;
}
}
// If it is all keyframes, discard the keyframe info as it is useless
if ( isAllKeyFrames ) {
KeyFrames . Clear ( ) ;
keyFramesLoaded = false ;
}
2006-01-22 13:44:53 +01:00
// Convert to RGB32
2007-01-27 08:13:29 +01:00
if ( ! OpenGLWrapper : : UseShaders ( ) ) {
2007-01-27 07:15:25 +01:00
script = env - > Invoke ( " ConvertToRGB32 " , script ) ;
AVSTRACE ( _T ( " AvisynthVideoProvider::OpenVideo: Converted to RGB32 " ) ) ;
}
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
2007-01-21 07:30:19 +01:00
////////////////////////
// Actually get a frame
2008-03-06 20:20:25 +01:00
const AegiVideoFrame AvisynthVideoProvider : : GetFrame ( int _n , int formatMask ) {
2007-01-21 07:30:19 +01:00
// 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 avs frame
AVSTRACE ( _T ( " AvisynthVideoProvider::GetFrame " ) ) ;
wxMutexLocker lock ( AviSynthMutex ) ;
2009-05-15 14:44:36 +02:00
PVideoFrame frame = RGB32Video - > GetFrame ( n , env ) ;
2007-01-21 07:30:19 +01:00
int Bpp = vi . BitsPerPixel ( ) / 8 ;
// Aegisub's video frame
AegiVideoFrame & final = iframe ;
final . flipped = false ;
final . cppAlloc = true ;
2007-01-29 06:47:29 +01:00
final . invertChannels = false ;
2007-01-21 07:30:19 +01:00
// Format
if ( vi . IsRGB32 ( ) ) {
final . format = FORMAT_RGB32 ;
final . flipped = true ;
2007-01-29 06:47:29 +01:00
final . invertChannels = true ;
2007-01-21 07:30:19 +01:00
}
else if ( vi . IsRGB24 ( ) ) {
final . format = FORMAT_RGB24 ;
final . flipped = true ;
2007-01-29 06:47:29 +01:00
final . invertChannels = true ;
2007-01-21 07:30:19 +01:00
}
else if ( vi . IsYV12 ( ) ) final . format = FORMAT_YV12 ;
else if ( vi . IsYUY2 ( ) ) final . format = FORMAT_YUY2 ;
// Set size properties
int uvpitch = 0 ;
if ( final . format = = FORMAT_YV12 ) uvpitch = frame - > GetPitch ( PLANAR_U ) ;
final . pitch [ 0 ] = frame - > GetPitch ( ) ;
final . pitch [ 1 ] = uvpitch ;
final . pitch [ 2 ] = uvpitch ;
final . w = frame - > GetRowSize ( ) / Bpp ;
final . h = frame - > GetHeight ( ) ;
// Allocate
final . Allocate ( ) ;
// Copy
memcpy ( final . data [ 0 ] , frame - > GetReadPtr ( ) , final . pitch [ 0 ] * final . h ) ;
// Copy second and third planes for YV12
if ( final . format = = FORMAT_YV12 ) {
int uvh = frame - > GetHeight ( PLANAR_U ) ;
memcpy ( final . data [ 1 ] , frame - > GetReadPtr ( PLANAR_U ) , uvpitch * uvh ) ;
memcpy ( final . data [ 2 ] , frame - > GetReadPtr ( PLANAR_V ) , uvpitch * uvh ) ;
}
// Set last number
last_fnum = n ;
return final ;
}
2007-01-01 04:29:20 +01:00
////////////////////////
// Override frame times
void AvisynthVideoProvider : : OverrideFrameTimeList ( wxArrayInt list ) {
frameTime = list ;
num_frames = frameTime . Count ( ) ;
}
2007-01-23 05:42:08 +01:00
2007-07-29 11:06:38 +02:00
///////////////
// Get warning
2008-03-07 22:24:14 +01:00
Aegisub : : String AvisynthVideoProvider : : GetWarning ( ) {
if ( usedDirectShow ) return L " 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! " ;
else return L " " ;
2007-07-29 11:06:38 +02:00
}
2007-01-23 05:42:08 +01:00
# endif