/* * Oak Video Editor - Non-Linear Video Editor * Copyright (C) 2026 Oak Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef OAK_PROXYMANAGER_H #define OAK_PROXYMANAGER_H #include #include #include #include #include "task/task.h" namespace olive { class ProxyTask; class ProxyManager : public QObject { Q_OBJECT public: static void create_instance() { if (!instance_) { instance_ = new ProxyManager(); } } static void destroy_instance() { delete instance_; instance_ = nullptr; } static ProxyManager *instance() { return instance_; } enum ProxyState { k_proxy_missing, k_proxy_generating, k_proxy_ready, k_proxy_failed }; struct ProxyParams { int width = 1280; int height = 720; int version = 1; QString extension = QStringLiteral("mp4"); int crf = 23; QString preset = QStringLiteral("veryfast"); bool include_audio = true; }; struct Proxy { ProxyState state = k_proxy_missing; QString filename; ProxyTask *task = nullptr; }; static QString get_proxy_directory(const QString &cache_path); static QString get_proxy_filename(const QString &cache_path, const QString &source_filename, int stream_index, const ProxyParams ¶ms); static QString get_working_proxy_filename(const QString &proxy_filename); static ProxyState get_proxy_state(const QString &proxy_filename); static QString proxy_state_to_string(ProxyState state); static ProxyState proxy_state_from_string(const QString &state); /** * @brief Returns true if a proxy filename generated by GetProxyFilename() * indicates the proxy contains audio streams */ static bool proxy_filename_has_audio(const QString &proxy_filename); /** * @brief Builds proxy parameters from the global application config */ static ProxyParams proxy_params_from_config(); /** * @brief Locates an ffmpeg executable for proxy generation * * Resolution order: the explicitly configured path (if non-empty and an * existing executable file), then the system PATH, then common * platform-specific install locations. Returns an empty string if no * executable could be found. */ static QString find_f_fmpeg_executable(const QString &configured_path); Proxy get_or_start_proxy(const QString &cache_path, const QString &source_filename, int stream_index, const ProxyParams ¶ms); signals: void proxy_ready(const QString &source_filename, int stream_index, const QString &proxy_filename); void proxy_finished(const QString &source_filename, int stream_index, const QString &proxy_filename, ProxyState state); private: ProxyManager() = default; static ProxyManager *instance_; struct ProxyData { QString source_filename; int stream_index = -1; ProxyParams params; ProxyTask *task = nullptr; QString working_filename; QString finished_filename; }; QMutex mutex_; QVector proxying_; private slots: void proxy_task_finished(Task *task, bool succeeded); }; } #endif // OAK_PROXYMANAGER_H