diff --git a/aegisub/src/include/aegisub/video_provider.h b/aegisub/src/include/aegisub/video_provider.h index 8a7a953be..ce7959e40 100644 --- a/aegisub/src/include/aegisub/video_provider.h +++ b/aegisub/src/include/aegisub/video_provider.h @@ -74,8 +74,9 @@ public: // How many frames does this provider want Aegisub to cache? Set to 0 if it doesn't require caching. virtual int GetDesiredCacheSize() { return 0; } - // For providers that are natively time-based (e.g. DirectShow) - virtual bool IsNativelyByFrames() { return true; } + // For "special" providers that don't deal well with VFR (i.e. Avisynth) + virtual bool NeedsVFRHack() { return false; }; // Returns true if provider needs special VFR treatment + virtual bool IsNativelyByFrames() { return true; }; virtual void OverrideFrameTimeList(Aegisub::IntArray list) {} // Override the list with the provided one, for VFR handling }; diff --git a/aegisub/src/video_context.cpp b/aegisub/src/video_context.cpp index d6794d4cd..dc2cd51d0 100644 --- a/aegisub/src/video_context.cpp +++ b/aegisub/src/video_context.cpp @@ -271,21 +271,23 @@ void VideoContext::SetVideo(const wxString &filename) { else { keyFramesLoaded = false; } - - bool isVfr = provider->IsVFR(); // Set frame rate fps = provider->GetFPS(); - // if the source is vfr and the provider isn't frame-based (i.e. is dshow), - // we need to jump through some hoops to make VFR work properly. - if (!provider->IsNativelyByFrames() && isVfr) { - FrameRate temp = provider->GetTrueFrameRate(); - provider->OverrideFrameTimeList(temp.GetFrameTimeList()); - } - // source not VFR? set as CFR - else if (!isVfr) { - VFR_Input.SetCFR(fps); - if (VFR_Output.GetFrameRateType() != VFR) VFR_Output.SetCFR(fps); + // does this provider need special vfr treatment? + if (provider->NeedsVFRHack()) { + // FIXME: + // Unfortunately, this hack does not actually work for the one + // provider that needs it (Avisynth). Go figure. + bool isVfr = provider->IsVFR(); + if (!isVfr || provider->IsNativelyByFrames()) { + VFR_Input.SetCFR(fps); + if (VFR_Output.GetFrameRateType() != VFR) VFR_Output.SetCFR(fps); + } + else { + FrameRate temp = provider->GetTrueFrameRate(); + provider->OverrideFrameTimeList(temp.GetFrameTimeList()); + } } // Gather video parameters diff --git a/aegisub/src/video_provider_avs.h b/aegisub/src/video_provider_avs.h index a46b9d7de..3152b9d41 100644 --- a/aegisub/src/video_provider_avs.h +++ b/aegisub/src/video_provider_avs.h @@ -89,6 +89,7 @@ public: void OverrideFrameTimeList(wxArrayInt list); bool IsNativelyByFrames() { return byFrame; } + bool NeedsVFRHack() { return true; } Aegisub::String GetWarning(); Aegisub::String GetDecoderName() { return Aegisub::String(L"Avisynth/") + decoderName; } }; diff --git a/aegisub/src/video_provider_cache.cpp b/aegisub/src/video_provider_cache.cpp index 9ff58b0b0..2a0f1eff2 100644 --- a/aegisub/src/video_provider_cache.cpp +++ b/aegisub/src/video_provider_cache.cpp @@ -167,6 +167,9 @@ void VideoProviderCache::OverrideFrameTimeList(Aegisub::IntArray list) { bool VideoProviderCache::IsNativelyByFrames() { return master->IsNativelyByFrames(); } +bool VideoProviderCache::NeedsVFRHack() { + return master->NeedsVFRHack(); +} Aegisub::String VideoProviderCache::GetWarning() { return master->GetWarning(); } diff --git a/aegisub/src/video_provider_cache.h b/aegisub/src/video_provider_cache.h index 6e21a1d83..dd286bc15 100644 --- a/aegisub/src/video_provider_cache.h +++ b/aegisub/src/video_provider_cache.h @@ -89,6 +89,7 @@ public: virtual FrameRate GetTrueFrameRate(); virtual void OverrideFrameTimeList(Aegisub::IntArray list); // Override the list with the provided one, for VFR handling virtual bool IsNativelyByFrames(); + virtual bool NeedsVFRHack(); virtual Aegisub::String GetWarning(); virtual Aegisub::String GetDecoderName(); }; diff --git a/aegisub/src/video_provider_ffmpegsource.h b/aegisub/src/video_provider_ffmpegsource.h index 9bbeb14f0..9aeab3ab1 100644 --- a/aegisub/src/video_provider_ffmpegsource.h +++ b/aegisub/src/video_provider_ffmpegsource.h @@ -85,7 +85,6 @@ public: bool IsVFR() { return true; }; FrameRate GetTrueFrameRate() { return Timecodes; }; Aegisub::String GetDecoderName() { return L"FFmpegSource"; } - bool IsNativelyByFrames() { return true; } int GetDesiredCacheSize() { return 8; } }; diff --git a/aegisub/src/video_provider_yuv4mpeg.h b/aegisub/src/video_provider_yuv4mpeg.h index 590290416..27b7ca92b 100644 --- a/aegisub/src/video_provider_yuv4mpeg.h +++ b/aegisub/src/video_provider_yuv4mpeg.h @@ -129,11 +129,10 @@ public: int GetHeight(); double GetFPS(); bool AreKeyFramesLoaded() { return false; } - wxArrayInt GetKeyFrames() { return wxArrayInt(); }; + wxArrayInt GetKeyFrames() { return wxArrayInt(); } bool IsVFR() { return false; }; - FrameRate GetTrueFrameRate() { return FrameRate(); }; + FrameRate GetTrueFrameRate() { return FrameRate(); } Aegisub::String GetDecoderName() { return L"YUV4MPEG"; } - bool IsNativelyByFrames() { return true; } int GetDesiredCacheSize() { return 8; } };