diff --git a/aegisub/video_provider.cpp b/aegisub/video_provider.cpp index b6b9915f3..7975454b4 100644 --- a/aegisub/video_provider.cpp +++ b/aegisub/video_provider.cpp @@ -40,6 +40,16 @@ #include "video_provider_dummy.h" #include "options.h" #include "vfr.h" +#ifdef WITH_AVISYNTH +#include "video_provider_avs.h" +#endif +#ifdef WITH_DIRECTSHOW +#include "video_provider_dshow.h" +#endif +#ifdef WITH_FFMPEG +#include "video_provider_lavc.h" +#endif +#include "video_provider_dummy.h" /////////////// @@ -149,6 +159,12 @@ VideoProvider *VideoProviderFactory::GetProvider(wxString video,double fps) { return new DummyVideoProvider(video, fps); } + // Register the first time + // HACK: move this into program initialization later + static bool init = false; + if (!init) RegisterProviders(); + init = true; + // List of providers wxArrayString list = GetFactoryList(Options.AsText(_T("Video provider"))); @@ -172,6 +188,21 @@ VideoProvider *VideoProviderFactory::GetProvider(wxString video,double fps) { } +////////////////////////// +// Register all providers +void VideoProviderFactory::RegisterProviders() { +#ifdef WITH_AVISYNTH + new AvisynthVideoProviderFactory(); +#endif +#ifdef WITH_DIRECTSHOW + new DirectShowVideoProviderFactory(); +#endif +#ifdef WITH_FFMPEG + new LAVCVideoProviderFactory(); +#endif +} + + ////////// // Static template std::map* AegisubFactory::factories=NULL; diff --git a/aegisub/video_provider.h b/aegisub/video_provider.h index 66387df12..41f65475e 100644 --- a/aegisub/video_provider.h +++ b/aegisub/video_provider.h @@ -111,4 +111,6 @@ protected: public: virtual ~VideoProviderFactory() {} static VideoProvider *GetProvider(wxString video,double fps=0.0); + + static void RegisterProviders(); }; diff --git a/aegisub/video_provider_avs.cpp b/aegisub/video_provider_avs.cpp index b5300c2b0..536b6212e 100644 --- a/aegisub/video_provider_avs.cpp +++ b/aegisub/video_provider_avs.cpp @@ -41,9 +41,7 @@ #include #include #include -#include "avisynth_wrap.h" -#include "video_provider.h" -#include "subtitles_provider.h" +#include "video_provider_avs.h" #include "video_context.h" #include "options.h" #include "standard_paths.h" @@ -52,68 +50,6 @@ #include "gl_wrap.h" -//////////// -// Provider -class AvisynthVideoProvider: public VideoProvider, SubtitlesProvider, AviSynthWrapper { -private: - VideoInfo vi; - AegiVideoFrame iframe; - - bool usedDirectShow; - wxString rendererCallString; - wxString decoderName; - - int num_frames; - int last_fnum; - - double fps; - wxArrayInt frameTime; - bool byFrame; - - PClip RGB32Video; - PClip SubtitledVideo; - - PClip OpenVideo(wxString _filename, bool mpeg2dec3_priority = true); - PClip ApplySubtitles(wxString _filename, PClip videosource); - - void LoadVSFilter(); - void LoadASA(); - void LoadRenderer(); - -public: - AvisynthVideoProvider(wxString _filename, double fps=0.0); - ~AvisynthVideoProvider(); - - SubtitlesProvider *GetAsSubtitlesProvider(); - void LoadSubtitles(AssFile *subs); - bool LockedToVideo() { return true; } - - const AegiVideoFrame DoGetFrame(int n); - void GetFloatFrame(float* Buffer, int n); - - // properties - int GetPosition() { return last_fnum; }; - int GetFrameCount() { return num_frames? num_frames: vi.num_frames; }; - double GetFPS() { return (double)vi.fps_numerator/(double)vi.fps_denominator; }; - int GetWidth() { return vi.width; }; - int GetHeight() { return vi.height; }; - - void OverrideFrameTimeList(wxArrayInt list); - bool IsNativelyByFrames() { return byFrame; } - wxString GetWarning(); - wxString GetDecoderName() { return _T("Avisynth/") + decoderName; } -}; - - -/////////// -// Factory -class AvisynthVideoProviderFactory : public VideoProviderFactory { -public: - VideoProvider *CreateProvider(wxString video,double fps=0.0) { return new AvisynthVideoProvider(video,fps); } - AvisynthVideoProviderFactory() : VideoProviderFactory(_T("avisynth")) {} -} registerAVS; - - /////////////// // Constructor AvisynthVideoProvider::AvisynthVideoProvider(wxString _filename, double _fps) { diff --git a/aegisub/video_provider_avs.h b/aegisub/video_provider_avs.h new file mode 100644 index 000000000..2b6b3d20e --- /dev/null +++ b/aegisub/video_provider_avs.h @@ -0,0 +1,108 @@ +// 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 +// + + +/////////// +// Headers +#include +#ifdef WITH_AVISYNTH +#include "avisynth_wrap.h" +#include "video_provider.h" +#include "subtitles_provider.h" + + +//////////// +// Provider +class AvisynthVideoProvider: public VideoProvider, SubtitlesProvider, AviSynthWrapper { +private: + VideoInfo vi; + AegiVideoFrame iframe; + + bool usedDirectShow; + wxString rendererCallString; + wxString decoderName; + + int num_frames; + int last_fnum; + + double fps; + wxArrayInt frameTime; + bool byFrame; + + PClip RGB32Video; + PClip SubtitledVideo; + + PClip OpenVideo(wxString _filename, bool mpeg2dec3_priority = true); + PClip ApplySubtitles(wxString _filename, PClip videosource); + + void LoadVSFilter(); + void LoadASA(); + void LoadRenderer(); + +public: + AvisynthVideoProvider(wxString _filename, double fps=0.0); + ~AvisynthVideoProvider(); + + SubtitlesProvider *GetAsSubtitlesProvider(); + void LoadSubtitles(AssFile *subs); + bool LockedToVideo() { return true; } + + const AegiVideoFrame DoGetFrame(int n); + void GetFloatFrame(float* Buffer, int n); + + // properties + int GetPosition() { return last_fnum; }; + int GetFrameCount() { return num_frames? num_frames: vi.num_frames; }; + double GetFPS() { return (double)vi.fps_numerator/(double)vi.fps_denominator; }; + int GetWidth() { return vi.width; }; + int GetHeight() { return vi.height; }; + + void OverrideFrameTimeList(wxArrayInt list); + bool IsNativelyByFrames() { return byFrame; } + wxString GetWarning(); + wxString GetDecoderName() { return _T("Avisynth/") + decoderName; } +}; + + +/////////// +// Factory +class AvisynthVideoProviderFactory : public VideoProviderFactory { +public: + VideoProvider *CreateProvider(wxString video,double fps=0.0) { return new AvisynthVideoProvider(video,fps); } + AvisynthVideoProviderFactory() : VideoProviderFactory(_T("avisynth")) {} +}; + + +#endif diff --git a/aegisub/video_provider_dshow.cpp b/aegisub/video_provider_dshow.cpp index 9178b5f01..739fe4347 100644 --- a/aegisub/video_provider_dshow.cpp +++ b/aegisub/video_provider_dshow.cpp @@ -51,12 +51,12 @@ #include #include #include -#include "video_provider.h" #include "utils.h" #include "vfr.h" #include "videosink.h" #include "gl_wrap.h" #include "options.h" +#include "video_provider_dshow.h" /////////////////////////////////// diff --git a/aegisub/video_provider_dshow.h b/aegisub/video_provider_dshow.h new file mode 100644 index 000000000..33ad2ffcf --- /dev/null +++ b/aegisub/video_provider_dshow.h @@ -0,0 +1,128 @@ +// Copyright (c) 2006, Rodrigo Braz Monteiro, Mike Matsnev +// 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 +// + + +/////////// +// Headers + +#ifdef WITH_DIRECTSHOW + +#pragma warning(disable: 4995) +#include +#ifdef __WINDOWS__ +#include +#include +#include +#include +#include +#include +#include +#include +#include "video_provider.h" +#include "videosink.h" + + +/////////////////////////////////// +// DirectShow Video Provider class +class DirectShowVideoProvider: public VideoProvider { + struct DF { + public: + REFERENCE_TIME timestamp; // DS timestamp that we used for this frame + AegiVideoFrame frame; + + DF() : timestamp(-1) { } + DF(AegiVideoFrame f) : timestamp(-1), frame(f) { } + DF(const DF& f) { operator=(f); } + DF& operator=(const DF& f) { timestamp = f.timestamp; frame = f.frame; return *this; } + }; + +private: + wxArrayInt frameTime; + + unsigned int last_fnum; + unsigned int width; + unsigned int height; + unsigned int num_frames; + double fps; + int64_t defd; + + HRESULT OpenVideo(wxString _filename); + void CloseVideo(); + + static void ReadFrame(__int64 timestamp, unsigned format, unsigned bpp, const unsigned char *frame, unsigned width, unsigned height, int stride, unsigned arx, unsigned ary, void *arg); + int NextFrame(DF &df,int &fn); + + void RegROT(); + void UnregROT(); + + REFERENCE_TIME duration; + DF rdf; + CComPtr m_pR; + CComPtr m_pGC; + CComPtr m_pGS; + HANDLE m_hFrameReady; + bool m_registered; + DWORD m_rot_cookie; + +public: + DirectShowVideoProvider(wxString _filename, double _fps=0.0); + ~DirectShowVideoProvider(); + + void RefreshSubtitles(); + + const AegiVideoFrame DoGetFrame(int n); + void GetFloatFrame(float* Buffer, int n); + + int GetPosition() { return last_fnum; }; + int GetFrameCount() { return num_frames; }; + double GetFPS() { return fps; }; + int GetWidth() { return width; }; + int GetHeight() { return height; }; + wxString GetDecoderName() { return _("DirectShow"); } + + void OverrideFrameTimeList(wxArrayInt list); +}; + + + +/////////// +// Factory +class DirectShowVideoProviderFactory : public VideoProviderFactory { +public: + VideoProvider *CreateProvider(wxString video,double fps=0.0) { return new DirectShowVideoProvider(video,fps); } + DirectShowVideoProviderFactory() : VideoProviderFactory(_T("dshow")) {} +}; + +#endif diff --git a/aegisub/video_provider_lavc.cpp b/aegisub/video_provider_lavc.cpp index 2ea5c153b..63da0a7e7 100644 --- a/aegisub/video_provider_lavc.cpp +++ b/aegisub/video_provider_lavc.cpp @@ -42,11 +42,6 @@ #ifdef WIN32 #define EMULATE_INTTYPES #endif -extern "C" { -#include -#include -#include -} #include #include #include @@ -58,74 +53,6 @@ extern "C" { #include "ass_file.h" -/////////////////////// -// LibAVCodec provider -class LAVCVideoProvider : public VideoProvider { - friend class LAVCAudioProvider; -private: - MatroskaWrapper mkv; - - LAVCFile *lavcfile; - AVCodecContext *codecContext; - AVStream *stream; - AVCodec *codec; - AVFrame *frame; - int vidStream; - - AVFrame *frameRGB; - uint8_t *bufferRGB; - SwsContext *sws_context; - - int display_w; - int display_h; - - wxArrayInt bytePos; - - bool isMkv; - int64_t lastDecodeTime; - int frameNumber; - int length; - AegiVideoFrame curFrame; - bool validFrame; - - uint8_t *buffer1; - uint8_t *buffer2; - int buffer1Size; - int buffer2Size; - - bool GetNextFrame(); - void LoadVideo(wxString filename, double fps); - void Close(); - -protected: - const AegiVideoFrame DoGetFrame(int n); - -public: - LAVCVideoProvider(wxString filename, double fps); - ~LAVCVideoProvider(); - - int GetPosition(); - int GetFrameCount(); - - int GetWidth(); - int GetHeight(); - double GetFPS(); - wxString GetDecoderName() { return _T("FFMpeg/libavcodec"); } - bool IsNativelyByFrames() { return true; } -}; - - - - -/////////// -// Factory -class LAVCVideoProviderFactory : public VideoProviderFactory { -public: - VideoProvider *CreateProvider(wxString video,double fps=0.0) { return new LAVCVideoProvider(video,fps); } - LAVCVideoProviderFactory() : VideoProviderFactory(_T("ffmpeg")) {} -} registerLAVCVideo; - - /////////////// // Constructor LAVCVideoProvider::LAVCVideoProvider(wxString filename,double fps) { diff --git a/aegisub/video_provider_lavc.h b/aegisub/video_provider_lavc.h new file mode 100644 index 000000000..c357b5f7c --- /dev/null +++ b/aegisub/video_provider_lavc.h @@ -0,0 +1,122 @@ +// Copyright (c) 2006-2007, Rodrigo Braz Monteiro +// 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 +// + + +/////////// +// Headers + +#ifdef WITH_FFMPEG + +#ifdef WIN32 +#define EMULATE_INTTYPES +#endif +extern "C" { +#include +#include +#include +} +#include "video_provider.h" +#include "mkv_wrap.h" +#include "lavc_file.h" + + +/////////////////////// +// LibAVCodec provider +class LAVCVideoProvider : public VideoProvider { + friend class LAVCAudioProvider; +private: + MatroskaWrapper mkv; + + LAVCFile *lavcfile; + AVCodecContext *codecContext; + AVStream *stream; + AVCodec *codec; + AVFrame *frame; + int vidStream; + + AVFrame *frameRGB; + uint8_t *bufferRGB; + SwsContext *sws_context; + + int display_w; + int display_h; + + wxArrayInt bytePos; + + bool isMkv; + int64_t lastDecodeTime; + int frameNumber; + int length; + AegiVideoFrame curFrame; + bool validFrame; + + uint8_t *buffer1; + uint8_t *buffer2; + int buffer1Size; + int buffer2Size; + + bool GetNextFrame(); + void LoadVideo(wxString filename, double fps); + void Close(); + +protected: + const AegiVideoFrame DoGetFrame(int n); + +public: + LAVCVideoProvider(wxString filename, double fps); + ~LAVCVideoProvider(); + + int GetPosition(); + int GetFrameCount(); + + int GetWidth(); + int GetHeight(); + double GetFPS(); + wxString GetDecoderName() { return _T("FFMpeg/libavcodec"); } + bool IsNativelyByFrames() { return true; } +}; + + + + +/////////// +// Factory +class LAVCVideoProviderFactory : public VideoProviderFactory { +public: + VideoProvider *CreateProvider(wxString video,double fps=0.0) { return new LAVCVideoProvider(video,fps); } + LAVCVideoProviderFactory() : VideoProviderFactory(_T("ffmpeg")) {} +}; + +#endif diff --git a/build/aegisub_vs2008/aegisub_vs2008.vcproj b/build/aegisub_vs2008/aegisub_vs2008.vcproj index ab9cb2fb2..a872bfdb4 100644 --- a/build/aegisub_vs2008/aegisub_vs2008.vcproj +++ b/build/aegisub_vs2008/aegisub_vs2008.vcproj @@ -1471,6 +1471,14 @@ + + + + + + + @@ -1584,6 +1600,10 @@ RelativePath="..\..\aegisub\video_provider_lavc.cpp" > + +