diff --git a/aegisub/video_context.cpp b/aegisub/video_context.cpp index 4e3ac8255..dba862540 100644 --- a/aegisub/video_context.cpp +++ b/aegisub/video_context.cpp @@ -428,31 +428,22 @@ AegiVideoFrame VideoContext::GetFrame(int n,bool raw) { // Current frame if -1 if (n == -1) n = frame_n; - // Get frame - AegiVideoFrame frame = provider->GetFrame(n); - AegiVideoFrame *srcFrame = &frame; + // Get available formats + int formats = FORMAT_RGB32; + if (yv12shader != 0 || OpenGLWrapper::UseShaders()) formats |= FORMAT_YV12; - // Convert to YV12 if it can't be handled - if (frame.format == FORMAT_YV12 && yv12shader == 0) { - if (!OpenGLWrapper::UseShaders()) { - tempRGBFrame.w = frame.w; - tempRGBFrame.h = frame.h; - tempRGBFrame.pitch[0] = frame.w * 4; - tempRGBFrame.format = FORMAT_RGB32; - tempRGBFrame.ConvertFrom(frame); - srcFrame = &tempRGBFrame; - } - } + // Get frame + AegiVideoFrame frame = provider->GetFrame(n,formats); // Raster subtitles if available/necessary if (!raw && subsProvider && subsProvider->CanRaster()) { - tempFrame.CopyFrom(*srcFrame); + tempFrame.CopyFrom(frame); subsProvider->DrawSubtitles(tempFrame,VFR_Input.GetTimeAtFrame(n,true,true)/1000.0); return tempFrame; } // Return pure frame - else return *srcFrame; + else return frame; } diff --git a/aegisub/video_context.h b/aegisub/video_context.h index 8254bf187..f17030591 100644 --- a/aegisub/video_context.h +++ b/aegisub/video_context.h @@ -74,7 +74,6 @@ private: wxGLContext *glContext; VideoFrameFormat vidFormat; AegiVideoFrame tempFrame; - AegiVideoFrame tempRGBFrame; wxString tempfile; VideoProvider *provider; diff --git a/aegisub/video_frame.h b/aegisub/video_frame.h index 728da9946..111ff2f6c 100644 --- a/aegisub/video_frame.h +++ b/aegisub/video_frame.h @@ -40,11 +40,11 @@ ////////////////////// // Video Frame format enum VideoFrameFormat { - FORMAT_NONE, - FORMAT_RGB24, - FORMAT_RGB32, - FORMAT_YUY2, - FORMAT_YV12 + FORMAT_NONE = 0, + FORMAT_RGB24 = 1, + FORMAT_RGB32 = 2, + FORMAT_YUY2 = 4, + FORMAT_YV12 = 8 }; diff --git a/aegisub/video_provider.cpp b/aegisub/video_provider.cpp index 3a7d8fc6c..9e400d42f 100644 --- a/aegisub/video_provider.cpp +++ b/aegisub/video_provider.cpp @@ -54,12 +54,13 @@ VideoProvider::VideoProvider() { // Destructor VideoProvider::~VideoProvider() { ClearCache(); + tempRGBFrame.Clear(); } ///////////// // Get frame -const AegiVideoFrame VideoProvider::GetFrame(int n) { +const AegiVideoFrame VideoProvider::GetFrame(int n,int format) { // See if frame is cached CachedFrame cached; for (std::list::iterator cur=cache.begin();cur!=cache.end();cur++) { @@ -73,8 +74,22 @@ const AegiVideoFrame VideoProvider::GetFrame(int n) { // Not cached, retrieve it const AegiVideoFrame frame = DoGetFrame(n); - Cache(n,frame); - return frame; + const AegiVideoFrame *srcFrame = &frame; + + // Convert to compatible format + if (!(frame.format & format)) { + if (format & FORMAT_RGB32) tempRGBFrame.format = FORMAT_RGB32; + else throw _T("Unable to negotiate formats."); + tempRGBFrame.w = frame.w; + tempRGBFrame.h = frame.h; + tempRGBFrame.pitch[0] = frame.w * 4; + tempRGBFrame.ConvertFrom(frame); + srcFrame = &tempRGBFrame; + } + + // Cache frame + Cache(n,*srcFrame); + return *srcFrame; } diff --git a/aegisub/video_provider.h b/aegisub/video_provider.h index fe0e82a65..5d76f8dec 100644 --- a/aegisub/video_provider.h +++ b/aegisub/video_provider.h @@ -63,6 +63,7 @@ class VideoProvider { private: unsigned int cacheMax; std::list cache; + AegiVideoFrame tempRGBFrame; void Cache(int n,const AegiVideoFrame frame); AegiVideoFrame GetCachedFrame(int n); @@ -78,7 +79,7 @@ protected: public: // Base methods void GetFloatFrame(float* Buffer, int n); // Get frame as float - const AegiVideoFrame GetFrame(int n); + const AegiVideoFrame GetFrame(int n, int formatMask=FORMAT_RGB32); VideoProvider(); virtual ~VideoProvider();