Re-fix the VFR fix in r3084 by restoring the old behavior (which was correct for the only existing providers at the time it was implemented, I think) under a special condition that only triggers for the AVS provider. This does not really actually fix any bugs; the new behavior wasn't any better (in fact it was probably incorrect in some cases) but at least this way doesn't have any of the regressions the new way might have introduced.

Originally committed to SVN as r3211.
This commit is contained in:
Karl Blomster 2009-07-23 02:06:47 +00:00
parent 0475b95e60
commit 7157d50e73
7 changed files with 24 additions and 18 deletions

View File

@ -74,8 +74,9 @@ public:
// How many frames does this provider want Aegisub to cache? Set to 0 if it doesn't require caching. // How many frames does this provider want Aegisub to cache? Set to 0 if it doesn't require caching.
virtual int GetDesiredCacheSize() { return 0; } virtual int GetDesiredCacheSize() { return 0; }
// For providers that are natively time-based (e.g. DirectShow) // For "special" providers that don't deal well with VFR (i.e. Avisynth)
virtual bool IsNativelyByFrames() { return true; } 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 virtual void OverrideFrameTimeList(Aegisub::IntArray list) {} // Override the list with the provided one, for VFR handling
}; };

View File

@ -271,21 +271,23 @@ void VideoContext::SetVideo(const wxString &filename) {
else { else {
keyFramesLoaded = false; keyFramesLoaded = false;
} }
bool isVfr = provider->IsVFR();
// Set frame rate // Set frame rate
fps = provider->GetFPS(); fps = provider->GetFPS();
// if the source is vfr and the provider isn't frame-based (i.e. is dshow), // does this provider need special vfr treatment?
// we need to jump through some hoops to make VFR work properly. if (provider->NeedsVFRHack()) {
if (!provider->IsNativelyByFrames() && isVfr) { // FIXME:
FrameRate temp = provider->GetTrueFrameRate(); // Unfortunately, this hack does not actually work for the one
provider->OverrideFrameTimeList(temp.GetFrameTimeList()); // provider that needs it (Avisynth). Go figure.
} bool isVfr = provider->IsVFR();
// source not VFR? set as CFR if (!isVfr || provider->IsNativelyByFrames()) {
else if (!isVfr) { VFR_Input.SetCFR(fps);
VFR_Input.SetCFR(fps); if (VFR_Output.GetFrameRateType() != VFR) VFR_Output.SetCFR(fps);
if (VFR_Output.GetFrameRateType() != VFR) VFR_Output.SetCFR(fps); }
else {
FrameRate temp = provider->GetTrueFrameRate();
provider->OverrideFrameTimeList(temp.GetFrameTimeList());
}
} }
// Gather video parameters // Gather video parameters

View File

@ -89,6 +89,7 @@ public:
void OverrideFrameTimeList(wxArrayInt list); void OverrideFrameTimeList(wxArrayInt list);
bool IsNativelyByFrames() { return byFrame; } bool IsNativelyByFrames() { return byFrame; }
bool NeedsVFRHack() { return true; }
Aegisub::String GetWarning(); Aegisub::String GetWarning();
Aegisub::String GetDecoderName() { return Aegisub::String(L"Avisynth/") + decoderName; } Aegisub::String GetDecoderName() { return Aegisub::String(L"Avisynth/") + decoderName; }
}; };

View File

@ -167,6 +167,9 @@ void VideoProviderCache::OverrideFrameTimeList(Aegisub::IntArray list) {
bool VideoProviderCache::IsNativelyByFrames() { bool VideoProviderCache::IsNativelyByFrames() {
return master->IsNativelyByFrames(); return master->IsNativelyByFrames();
} }
bool VideoProviderCache::NeedsVFRHack() {
return master->NeedsVFRHack();
}
Aegisub::String VideoProviderCache::GetWarning() { Aegisub::String VideoProviderCache::GetWarning() {
return master->GetWarning(); return master->GetWarning();
} }

View File

@ -89,6 +89,7 @@ public:
virtual FrameRate GetTrueFrameRate(); virtual FrameRate GetTrueFrameRate();
virtual void OverrideFrameTimeList(Aegisub::IntArray list); // Override the list with the provided one, for VFR handling virtual void OverrideFrameTimeList(Aegisub::IntArray list); // Override the list with the provided one, for VFR handling
virtual bool IsNativelyByFrames(); virtual bool IsNativelyByFrames();
virtual bool NeedsVFRHack();
virtual Aegisub::String GetWarning(); virtual Aegisub::String GetWarning();
virtual Aegisub::String GetDecoderName(); virtual Aegisub::String GetDecoderName();
}; };

View File

@ -85,7 +85,6 @@ public:
bool IsVFR() { return true; }; bool IsVFR() { return true; };
FrameRate GetTrueFrameRate() { return Timecodes; }; FrameRate GetTrueFrameRate() { return Timecodes; };
Aegisub::String GetDecoderName() { return L"FFmpegSource"; } Aegisub::String GetDecoderName() { return L"FFmpegSource"; }
bool IsNativelyByFrames() { return true; }
int GetDesiredCacheSize() { return 8; } int GetDesiredCacheSize() { return 8; }
}; };

View File

@ -129,11 +129,10 @@ public:
int GetHeight(); int GetHeight();
double GetFPS(); double GetFPS();
bool AreKeyFramesLoaded() { return false; } bool AreKeyFramesLoaded() { return false; }
wxArrayInt GetKeyFrames() { return wxArrayInt(); }; wxArrayInt GetKeyFrames() { return wxArrayInt(); }
bool IsVFR() { return false; }; bool IsVFR() { return false; };
FrameRate GetTrueFrameRate() { return FrameRate(); }; FrameRate GetTrueFrameRate() { return FrameRate(); }
Aegisub::String GetDecoderName() { return L"YUV4MPEG"; } Aegisub::String GetDecoderName() { return L"YUV4MPEG"; }
bool IsNativelyByFrames() { return true; }
int GetDesiredCacheSize() { return 8; } int GetDesiredCacheSize() { return 8; }
}; };