std::unique_ptr<VideoProvider> VideoProviderFactory::GetProvider(agi::fs::path const& video_file, std::string const& colormatrix) {
	std::vector<std::string> factories = GetClasses(OPT_GET("Video/Provider")->GetString());
	factories.insert(factories.begin(), "YUV4MPEG");
	factories.insert(factories.begin(), "Dummy");

	bool found = false;
	bool supported = false;
	std::string errors;
	errors.reserve(1024);

	for (auto const& factory : factories) {
		std::string err;
		try {
			auto provider = Create(factory, video_file, colormatrix);
			LOG_I("manager/video/provider") << factory << ": opened " << video_file;
			return provider->WantsCaching() ? agi::util::make_unique<VideoProviderCache>(std::move(provider)) : std::move(provider);
		}
		catch (agi::fs::FileNotFound const&) {
			err = "file not found.";
			// Keep trying other providers as this one may just not be able to
			// open a valid path
		}
		catch (VideoNotSupported const&) {
			found = true;
			err = "video is not in a supported format.";
		}
		catch (VideoOpenError const& ex) {
			supported = true;
			err = ex.GetMessage();
		}
		catch (agi::vfr::Error const& ex) {
			supported = true;
			err = ex.GetMessage();
		}

		errors += factory + ": " + err + "\n";
		LOG_D("manager/video/provider") << factory << ": " << err;
	}

	// No provider could open the file
	LOG_E("manager/video/provider") << "Could not open " << video_file;
	std::string msg = "Could not open " + video_file.string() + ":\n" + errors;

	if (!found) throw agi::fs::FileNotFound(video_file.string());
	if (!supported) throw VideoNotSupported(msg);
	throw VideoOpenError(msg);
}
예제 #2
0
std::unique_ptr<VideoProvider> VideoProviderFactory::GetProvider(agi::fs::path const& filename, std::string const& colormatrix, agi::BackgroundRunner *br) {
	auto preferred = OPT_GET("Video/Provider")->GetString();
	auto sorted = GetSorted(boost::make_iterator_range(std::begin(providers), std::end(providers)), preferred);

	bool found = false;
	bool supported = false;
	std::string errors;
	errors.reserve(1024);

	for (auto factory : sorted) {
		std::string err;
		try {
			auto provider = factory->create(filename, colormatrix, br);
			if (!provider) continue;
			LOG_I("manager/video/provider") << factory->name << ": opened " << filename;
			return provider->WantsCaching() ? CreateCacheVideoProvider(std::move(provider)) : std::move(provider);
		}
		catch (agi::fs::FileNotFound const&) {
			err = "file not found.";
			// Keep trying other providers as this one may just not be able to
			// open a valid path
		}
		catch (VideoNotSupported const&) {
			found = true;
			err = "video is not in a supported format.";
		}
		catch (VideoOpenError const& ex) {
			supported = true;
			err = ex.GetMessage();
		}
		catch (agi::vfr::Error const& ex) {
			supported = true;
			err = ex.GetMessage();
		}

		errors += std::string(factory->name) + ": " + err + "\n";
		LOG_D("manager/video/provider") << factory->name << ": " << err;
	}

	// No provider could open the file
	LOG_E("manager/video/provider") << "Could not open " << filename;
	std::string msg = "Could not open " + filename.string() + ":\n" + errors;

	if (!found) throw agi::fs::FileNotFound(filename.string());
	if (!supported) throw VideoNotSupported(msg);
	throw VideoOpenError(msg);
}