Skip to content

Commit

Permalink
fix: unify ffmpeg and image producer file searching #1455
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Jan 5, 2024
1 parent e731ab5 commit 4fef571
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 64 deletions.
47 changes: 47 additions & 0 deletions src/common/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,60 @@
*/
#include "except.h"

#include "./os/filesystem.h"
#include "filesystem.h"

#include <boost/algorithm/string.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>

namespace caspar {

std::optional<boost::filesystem::path>
probe_path(const boost::filesystem::path& full_path,
const std::function<bool(const boost::filesystem::path&)>& is_valid_file)
{
auto parent = find_case_insensitive(full_path.parent_path().wstring());

if (!parent)
return {};

auto dir = boost::filesystem::path(*parent);
auto loc = std::locale(""); // Use system locale

auto leaf_name = full_path.filename().stem().wstring();
auto has_extension = !full_path.filename().extension().wstring().empty();
auto leaf_filename = full_path.filename().wstring();

for (auto it = boost::filesystem::directory_iterator(dir); it != boost::filesystem::directory_iterator(); ++it) {
if (has_extension) {
auto it_path = it->path().filename().wstring();
if (boost::iequals(it_path, leaf_filename, loc) && is_valid_file(it->path().wstring()))
return it->path();
} else if (boost::iequals(it->path().stem().wstring(), leaf_name, loc) && is_valid_file(it->path().wstring()))
return it->path();
}

return {};
}

std::optional<boost::filesystem::path>
find_file_within_dir_or_absolute(const std::wstring& parent_dir,
const std::wstring& filename,
const std::function<bool(const boost::filesystem::path&)>& is_valid_file)
{
// Try it assuming an absolute path was given
auto file_path = boost::filesystem::path(filename);
auto file_path_match = probe_path(file_path, is_valid_file);
if (file_path_match) {
return file_path_match;
}

// Try and find within the default parent directory
auto full_path = boost::filesystem::path(parent_dir) / boost::filesystem::path(filename);
return probe_path(full_path, is_valid_file);
}

boost::filesystem::path get_relative(const boost::filesystem::path& file, const boost::filesystem::path& relative_to)
{
auto result = file.filename();
Expand Down
7 changes: 7 additions & 0 deletions src/common/filesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,15 @@

#include <boost/filesystem/path.hpp>

#include <optional>

namespace caspar {

std::optional<boost::filesystem::path>
find_file_within_dir_or_absolute(const std::wstring& parent_dir,
const std::wstring& filename,
const std::function<bool(const boost::filesystem::path&)>& is_valid_file);

boost::filesystem::path get_relative(const boost::filesystem::path& file, const boost::filesystem::path& relative_to);
boost::filesystem::path get_relative_without_extension(const boost::filesystem::path& file,
const boost::filesystem::path& relative_to);
Expand Down
29 changes: 5 additions & 24 deletions src/modules/ffmpeg/producer/ffmpeg_producer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/logic/tribool.hpp>
#include <common/filesystem.h>

#pragma warning(push, 1)

Expand Down Expand Up @@ -281,38 +282,18 @@ bool is_valid_file(const boost::filesystem::path& filename)
return av_probe_input_format2(&pb, true, &score) != nullptr;
}

boost::filesystem::path probe_stem(const boost::filesystem::path& stem)
{
auto parent = find_case_insensitive(stem.parent_path().wstring());

if (!parent)
return L"";

auto dir = boost::filesystem::path(*parent);
auto loc = std::locale(""); // Use system locale

for (auto it = boost::filesystem::directory_iterator(dir); it != boost::filesystem::directory_iterator(); ++it) {
if (boost::iequals(it->path().stem().wstring(), stem.filename().wstring(), loc) &&
is_valid_file(it->path().wstring()))
return it->path();
}
return L"";
}

spl::shared_ptr<core::frame_producer> create_producer(const core::frame_producer_dependencies& dependencies,
const std::vector<std::wstring>& params)
{
auto name = params.at(0);
auto path = name;

if (!boost::contains(path, L"://")) {
auto mediaPath = boost::filesystem::absolute(env::media_folder() + L"/" + path);
auto fullMediaPath = find_case_insensitive(mediaPath.generic_wstring());
if (fullMediaPath && is_valid_file(*fullMediaPath)) {
path = *fullMediaPath;
auto fullMediaPath = find_file_within_dir_or_absolute(env::media_folder(), path, is_valid_file);
if (fullMediaPath) {
path = fullMediaPath->wstring();
} else {
path = probe_stem(mediaPath).generic_wstring();
name += boost::filesystem::path(path).extension().wstring();
return core::frame_producer::empty();
}
} else if (!has_valid_extension(path) || has_invalid_protocol(path)) {
return core::frame_producer::empty();
Expand Down
29 changes: 6 additions & 23 deletions src/modules/image/producer/image_producer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

#include <common/array.h>
#include <common/env.h>
#include <common/filesystem.h>
#include <common/log.h>
#include <common/os/filesystem.h>
#include <common/param.h>
Expand Down Expand Up @@ -199,31 +200,13 @@ spl::shared_ptr<core::frame_producer> create_producer(const core::frame_producer
// return spl::make_shared<image_producer>(dependencies.frame_factory, png_data.data(), png_data.size(), length);
//}

std::wstring filename = env::media_folder() + params.at(0);

auto resolvedFilename = caspar::find_case_insensitive(filename);
if (resolvedFilename && boost::filesystem::is_regular_file(*resolvedFilename)) {
auto ext = boost::to_lower_copy(boost::filesystem::path(filename).extension().wstring());
if (std::find(supported_extensions().begin(), supported_extensions().end(), ext) ==
supported_extensions().end()) {
return core::frame_producer::empty();
}
} else {
auto ext = std::find_if(
supported_extensions().begin(), supported_extensions().end(), [&](const std::wstring& ex) -> bool {
auto file = caspar::find_case_insensitive(boost::filesystem::path(filename).wstring() + ex);

return static_cast<bool>(file);
});

if (ext == supported_extensions().end()) {
return core::frame_producer::empty();
}

filename = *caspar::find_case_insensitive(filename + *ext);
std::optional<boost::filesystem::path> filename =
find_file_within_dir_or_absolute(env::media_folder(), params.at(0), is_valid_file);
if (!filename) {
return core::frame_producer::empty();
}

return spl::make_shared<image_producer>(dependencies.frame_factory, filename, length);
return spl::make_shared<image_producer>(dependencies.frame_factory, filename->wstring(), length);
}

}} // namespace caspar::image
19 changes: 7 additions & 12 deletions src/modules/image/producer/image_scroll_producer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <common/array.h>
#include <common/env.h>
#include <common/except.h>
#include <common/filesystem.h>
#include <common/future.h>
#include <common/log.h>
#include <common/os/filesystem.h>
Expand All @@ -60,6 +61,7 @@
#include <algorithm>
#include <array>
#include <cstdint>
#include <optional>
#include <utility>

namespace caspar { namespace image {
Expand Down Expand Up @@ -411,18 +413,11 @@ spl::shared_ptr<core::frame_producer> create_scroll_producer(const core::frame_p
return core::frame_producer::empty();
}

std::wstring filename = env::media_folder() + params.at(0);

auto ext =
std::find_if(supported_extensions().begin(), supported_extensions().end(), [&](const std::wstring& ex) -> bool {
auto file =
caspar::find_case_insensitive(boost::filesystem::path(filename).replace_extension(ex).wstring());

return static_cast<bool>(file);
});

if (ext == supported_extensions().end())
std::optional<boost::filesystem::path> filename =
find_file_within_dir_or_absolute(env::media_folder(), params.at(0), is_valid_file);
if (!filename) {
return core::frame_producer::empty();
}

double duration = 0.0;
double speed = get_param(L"SPEED", params, 0.0);
Expand All @@ -448,7 +443,7 @@ spl::shared_ptr<core::frame_producer> create_scroll_producer(const core::frame_p

return spl::make_shared<image_scroll_producer>(dependencies.frame_factory,
dependencies.format_desc,
*caspar::find_case_insensitive(filename + *ext),
filename->wstring(),
-speed,
-duration,
end_time,
Expand Down
10 changes: 8 additions & 2 deletions src/modules/image/util/image_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#pragma warning(disable : 4714) // marked as __forceinline not inlined
#endif

#include <boost/algorithm/string.hpp>
#include <boost/exception/errinfo_file_name.hpp>
#include <boost/filesystem.hpp>

Expand Down Expand Up @@ -109,12 +110,17 @@ std::shared_ptr<FIBITMAP> load_png_from_memory(const void* memory_location, size
return bitmap;
}

const std::set<std::wstring>& supported_extensions()
bool is_valid_file(const boost::filesystem::path& filename)
{
static const std::set<std::wstring> extensions = {
L".png", L".tga", L".bmp", L".jpg", L".jpeg", L".gif", L".tiff", L".tif", L".jp2", L".jpx", L".j2k", L".j2c"};

return extensions;
auto ext = boost::to_lower_copy(boost::filesystem::path(filename).extension().wstring());
if (extensions.find(ext) == extensions.end()) {
return false;
}

return true;
}

}} // namespace caspar::image
9 changes: 6 additions & 3 deletions src/modules/image/util/image_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@
#include <set>
#include <string>

#include <boost/filesystem.hpp>

struct FIBITMAP;

namespace caspar { namespace image {

std::shared_ptr<FIBITMAP> load_image(const std::wstring& filename);
std::shared_ptr<FIBITMAP> load_png_from_memory(const void* memory_location, size_t size);
const std::set<std::wstring>& supported_extensions();
std::shared_ptr<FIBITMAP> load_image(const std::wstring& filename);
std::shared_ptr<FIBITMAP> load_png_from_memory(const void* memory_location, size_t size);

bool is_valid_file(const boost::filesystem::path& filename);

}} // namespace caspar::image

0 comments on commit 4fef571

Please sign in to comment.