Make video providers report whether their file has audio tracks

Fixes errors when trying to automatically open audio from dummy video
and improves UX a little by disabling the Open Audio From Video menu
item when there are no audio tracks.
This commit is contained in:
Thomas Goyne 2014-05-23 06:34:52 -07:00
parent 692b354713
commit e2754bcd90
7 changed files with 34 additions and 23 deletions

View file

@ -111,6 +111,7 @@ public:
std::string GetWarning() const { return source_provider->GetWarning(); } std::string GetWarning() const { return source_provider->GetWarning(); }
std::string GetDecoderName() const { return source_provider->GetDecoderName(); } std::string GetDecoderName() const { return source_provider->GetDecoderName(); }
bool ShouldSetVideoProperties() const { return source_provider->ShouldSetVideoProperties(); } bool ShouldSetVideoProperties() const { return source_provider->ShouldSetVideoProperties(); }
bool HasAudio() const { return source_provider->HasAudio(); }
/// @brief Constructor /// @brief Constructor
/// @param videoFileName File to open /// @param videoFileName File to open

View file

@ -32,6 +32,7 @@
#include "command.h" #include "command.h"
#include "../ass_dialogue.h" #include "../ass_dialogue.h"
#include "../async_video_provider.h"
#include "../audio_box.h" #include "../audio_box.h"
#include "../audio_controller.h" #include "../audio_controller.h"
#include "../audio_karaoke.h" #include "../audio_karaoke.h"
@ -118,7 +119,7 @@ struct audio_open_video final : public Command {
CMD_TYPE(COMMAND_VALIDATE) CMD_TYPE(COMMAND_VALIDATE)
bool Validate(const agi::Context *c) override { bool Validate(const agi::Context *c) override {
return !c->project->VideoName().empty(); return c->project->VideoProvider() && c->project->VideoProvider()->HasAudio();
} }
void operator()(agi::Context *c) override { void operator()(agi::Context *c) override {

View file

@ -81,6 +81,9 @@ public:
/// Should the video properties in the script be set to this video's property if they already have values? /// Should the video properties in the script be set to this video's property if they already have values?
virtual bool ShouldSetVideoProperties() const { return true; } virtual bool ShouldSetVideoProperties() const { return true; }
/// Does the file which this provider is reading have an audio track?
virtual bool HasAudio() const { return false; }
}; };
DEFINE_BASE_EXCEPTION_NOINNER(VideoProviderError, agi::Exception) DEFINE_BASE_EXCEPTION_NOINNER(VideoProviderError, agi::Exception)

View file

@ -295,8 +295,9 @@ bool Project::DoLoadVideo(agi::fs::path const& path) {
} }
void Project::LoadVideo(agi::fs::path const& path) { void Project::LoadVideo(agi::fs::path const& path) {
if (path.empty()) return;
if (!DoLoadVideo(path)) return; if (!DoLoadVideo(path)) return;
if (OPT_GET("Video/Open Audio")->GetBool() && audio_file != video_file) if (OPT_GET("Video/Open Audio")->GetBool() && audio_file != video_file && video_provider->HasAudio())
DoLoadAudio(video_file, true); DoLoadAudio(video_file, true);
} }

View file

@ -27,11 +27,6 @@
// //
// Aegisub Project http://www.aegisub.org/ // Aegisub Project http://www.aegisub.org/
/// @file video_provider_avs.cpp
/// @brief Avisynth-based video provider
/// @ingroup video_input
///
#ifdef WITH_AVISYNTH #ifdef WITH_AVISYNTH
#include "include/aegisub/video_provider.h" #include "include/aegisub/video_provider.h"
@ -66,6 +61,7 @@ class AvisynthVideoProvider: public VideoProvider {
std::string warning; std::string warning;
std::string colorspace; std::string colorspace;
std::string real_colorspace; std::string real_colorspace;
bool has_audio = false;
AVSValue source_clip; AVSValue source_clip;
PClip RGB32Video; PClip RGB32Video;
@ -94,6 +90,7 @@ public:
std::string GetDecoderName() const override { return decoder_name; } std::string GetDecoderName() const override { return decoder_name; }
std::string GetColorSpace() const override { return colorspace; } std::string GetColorSpace() const override { return colorspace; }
std::string GetRealColorSpace() const override { return real_colorspace; } std::string GetRealColorSpace() const override { return real_colorspace; }
bool HasAudio() const override { return has_audio; }
}; };
AvisynthVideoProvider::AvisynthVideoProvider(agi::fs::path const& filename, std::string const& colormatrix) { AvisynthVideoProvider::AvisynthVideoProvider(agi::fs::path const& filename, std::string const& colormatrix) {
@ -189,6 +186,7 @@ file_exit:
void AvisynthVideoProvider::Init(std::string const& colormatrix) { void AvisynthVideoProvider::Init(std::string const& colormatrix) {
auto script = source_clip; auto script = source_clip;
vi = script.AsClip()->GetVideoInfo(); vi = script.AsClip()->GetVideoInfo();
has_audio = vi.HasAudio();
if (vi.IsRGB()) if (vi.IsRGB())
real_colorspace = colorspace = "None"; real_colorspace = colorspace = "None";
else { else {

View file

@ -74,6 +74,8 @@ public:
std::string GetDecoderName() const override { return master->GetDecoderName(); } std::string GetDecoderName() const override { return master->GetDecoderName(); }
std::string GetColorSpace() const override { return master->GetColorSpace(); } std::string GetColorSpace() const override { return master->GetColorSpace(); }
std::string GetRealColorSpace() const override { return master->GetRealColorSpace(); } std::string GetRealColorSpace() const override { return master->GetRealColorSpace(); }
bool ShouldSetVideoProperties() const override { return master->ShouldSetVideoProperties(); }
bool HasAudio() const override { return master->HasAudio(); }
}; };
std::shared_ptr<VideoFrame> VideoProviderCache::GetFrame(int n) { std::shared_ptr<VideoFrame> VideoProviderCache::GetFrame(int n) {

View file

@ -63,6 +63,7 @@ class FFmpegSourceVideoProvider final : public VideoProvider, FFmpegSourceProvid
char FFMSErrMsg[1024]; ///< FFMS error message char FFMSErrMsg[1024]; ///< FFMS error message
FFMS_ErrorInfo ErrInfo; ///< FFMS error codes/messages FFMS_ErrorInfo ErrInfo; ///< FFMS error codes/messages
bool has_audio = false;
void LoadVideo(agi::fs::path const& filename, std::string const& colormatrix); void LoadVideo(agi::fs::path const& filename, std::string const& colormatrix);
@ -94,6 +95,7 @@ public:
std::vector<int> GetKeyFrames() const override { return KeyFramesList; }; std::vector<int> GetKeyFrames() const override { return KeyFramesList; };
std::string GetDecoderName() const override { return "FFmpegSource"; } std::string GetDecoderName() const override { return "FFmpegSource"; }
bool WantsCaching() const override { return true; } bool WantsCaching() const override { return true; }
bool HasAudio() const override { return has_audio; }
}; };
std::string colormatrix_description(int cs, int cr) { std::string colormatrix_description(int cs, int cr) {
@ -204,6 +206,9 @@ void FFmpegSourceVideoProvider::LoadVideo(agi::fs::path const& filename, std::st
throw VideoNotSupported(std::string("Couldn't find any video tracks: ") + ErrInfo.Buffer); throw VideoNotSupported(std::string("Couldn't find any video tracks: ") + ErrInfo.Buffer);
} }
// Check if there's an audio track
has_audio = FFMS_GetFirstTrackOfType(Index, FFMS_TYPE_AUDIO, nullptr) != -1;
// set thread count // set thread count
int Threads = OPT_GET("Provider/Video/FFmpegSource/Decoding Threads")->GetInt(); int Threads = OPT_GET("Provider/Video/FFmpegSource/Decoding Threads")->GetInt();
if (FFMS_GetVersion() < ((2 << 24) | (17 << 16) | (2 << 8) | 1) && FFMS_GetSourceType(Index) == FFMS_SOURCE_LAVF) if (FFMS_GetVersion() < ((2 << 24) | (17 << 16) | (2 << 8) | 1) && FFMS_GetSourceType(Index) == FFMS_SOURCE_LAVF)