2024-08-08 13:12:37 -07:00
|
|
|
#pragma once
|
|
|
|
#include <any>
|
2024-09-28 10:31:06 -07:00
|
|
|
#include <google/protobuf/message.h>
|
2024-08-08 13:12:37 -07:00
|
|
|
#include <mutex>
|
|
|
|
#include <atomic>
|
|
|
|
#include <stdint.h>
|
2024-09-16 15:05:53 -07:00
|
|
|
#include <future>
|
2024-08-08 13:12:37 -07:00
|
|
|
#include <thread>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2024-09-16 15:05:53 -07:00
|
|
|
#include <memory>
|
2024-08-08 13:12:37 -07:00
|
|
|
#include "thirdparty/CRC.hpp"
|
|
|
|
#include "playback_backend.hpp"
|
|
|
|
#include "rpc.hpp"
|
2024-09-28 10:52:55 -07:00
|
|
|
#include <ipc/common.pb.h>
|
|
|
|
#include <ipc/internal.pb.h>
|
2024-08-08 13:12:37 -07:00
|
|
|
#include <log.hpp>
|
2024-09-28 10:31:06 -07:00
|
|
|
#include "options.hpp"
|
|
|
|
#include "util.hpp"
|
2024-08-08 13:12:37 -07:00
|
|
|
class PlaybackProcess;
|
2024-09-28 10:31:06 -07:00
|
|
|
class PlaybackProcessServiceImpl {
|
|
|
|
Lock<PlaybackBackend*> cur_backend_lock;
|
|
|
|
Lock<DynPtr*> render_ptr;
|
|
|
|
public:
|
|
|
|
PlaybackProcess *process;
|
|
|
|
RenderResponseOrError Render(const RenderCommand *cmd);
|
|
|
|
PropertyDataOrError Get(const GetProperty *request);
|
|
|
|
MaybeError Set(const SetProperty *request);
|
|
|
|
ResetResponse Reset(const ResetProperty *request);
|
|
|
|
MaybeError Quit(const QuitCmd *request);
|
|
|
|
MaybeError Init(const InitCommand *cmd);
|
2024-08-08 13:12:37 -07:00
|
|
|
};
|
|
|
|
template<class T>
|
|
|
|
inline T *resolve_any(google::protobuf::Any value) {
|
|
|
|
T *output = new T();
|
|
|
|
value.UnpackTo(output);
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
//#define DEBUG_PRINT_IPC
|
|
|
|
void print_ipc_message(const google::protobuf::Message &msg, size_t level = 0);
|
|
|
|
class PlaybackProcess {
|
|
|
|
friend class HostProcessImpl;
|
|
|
|
friend class PlaybackProcessServiceImpl;
|
|
|
|
void threadfunc();
|
2024-09-28 10:31:06 -07:00
|
|
|
PlaybackProcess *other_process = nullptr;
|
|
|
|
PlaybackProcessServiceImpl impl;
|
2024-08-08 13:12:37 -07:00
|
|
|
int pid;
|
2024-09-16 15:05:53 -07:00
|
|
|
std::mutex start_mutex;
|
|
|
|
std::condition_variable started;
|
2024-08-08 13:12:37 -07:00
|
|
|
bool is_playback_process = false;
|
2024-09-16 15:05:53 -07:00
|
|
|
std::atomic_bool done;
|
2024-09-28 10:31:06 -07:00
|
|
|
RPCResponse SendCommand(RPCCall *msg);
|
2024-08-08 13:12:37 -07:00
|
|
|
std::string get_version_code();
|
|
|
|
PropertyData get_property(PropertyId id, std::optional<uint64_t> idx = {});
|
|
|
|
inline google::protobuf::Any get_property_value_any(PropertyId id, std::optional<uint64_t> idx = {}) {
|
|
|
|
PropertyData data = get_property(id, idx);
|
|
|
|
return data.value();
|
|
|
|
}
|
|
|
|
template<class T>
|
|
|
|
inline T *get_property_value(PropertyId id, std::optional<uint64_t> idx = {}) {
|
|
|
|
if constexpr (std::is_same_v<T, std::string>) {
|
|
|
|
auto *property = get_property_value<StringProperty>(id, idx);
|
|
|
|
std::string *tmp = new std::string(property->value());
|
|
|
|
delete property;
|
|
|
|
return tmp;
|
|
|
|
} else {
|
|
|
|
return resolve_any<T>(get_property_value_any(id, idx));
|
|
|
|
}
|
|
|
|
}
|
2024-09-28 10:31:06 -07:00
|
|
|
inline double get_property_double(PropertyId id, std::optional<uint64_t> idx = {}) {
|
|
|
|
auto *property = get_property_value<DoubleProperty>(id, idx);
|
|
|
|
double output = double(property->value());
|
|
|
|
delete property;
|
|
|
|
return output;
|
|
|
|
}
|
2024-08-08 13:12:37 -07:00
|
|
|
inline std::string get_property_string(PropertyId id, std::optional<uint64_t> idx = {}) {
|
|
|
|
auto *property = get_property_value<StringProperty>(id, idx);
|
|
|
|
std::string output = std::string(property->value());
|
|
|
|
delete property;
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
void set_property(PropertyId id, PropertyData data, std::optional<uint64_t> idx = {});
|
|
|
|
template<class T>
|
|
|
|
inline void set_property_value(PropertyId id, T *value, std::optional<uint64_t> idx = {}) {
|
|
|
|
PropertyData data;
|
|
|
|
data.mutable_value()->PackFrom(*value);
|
|
|
|
set_property(id, data, idx);
|
|
|
|
}
|
2024-09-28 10:31:06 -07:00
|
|
|
inline void set_property_double(PropertyId id, double value, std::optional<uint64_t> idx = {}) {
|
|
|
|
PropertyData data;
|
|
|
|
DoubleProperty property;
|
|
|
|
property.set_value(value);
|
|
|
|
data.mutable_value()->PackFrom(property);
|
|
|
|
set_property(id, data, idx);
|
|
|
|
}
|
2024-08-08 13:12:37 -07:00
|
|
|
friend int looper_run_playback_process(std::vector<std::string> args);
|
2024-09-28 10:31:06 -07:00
|
|
|
PlaybackProcess(PlaybackProcess *parent);
|
2024-08-08 13:12:37 -07:00
|
|
|
PlaybackProcess(std::vector<std::string> args);
|
|
|
|
void run_playback_process();
|
|
|
|
public:
|
|
|
|
bool process_running();
|
|
|
|
double get_position();
|
2024-09-28 10:31:06 -07:00
|
|
|
double get_length();
|
2024-08-08 13:12:37 -07:00
|
|
|
void set_position(double pos);
|
|
|
|
size_t get_stream_idx();
|
|
|
|
void set_stream_idx(size_t idx);
|
|
|
|
std::string get_title();
|
|
|
|
std::string get_file_path();
|
|
|
|
std::string get_file_name();
|
|
|
|
std::string get_backend_id();
|
2024-09-28 10:31:06 -07:00
|
|
|
double get_cached_rate();
|
|
|
|
void set_rate(double value);
|
2024-08-08 13:12:37 -07:00
|
|
|
std::string get_backend_name();
|
|
|
|
PlaybackStream get_playback_stream(size_t idx);
|
|
|
|
std::vector<PlaybackStream> get_playback_streams();
|
|
|
|
AudioSpec *get_audio_spec();
|
|
|
|
size_t render(void *buf, size_t maxlen);
|
|
|
|
|
|
|
|
std::optional<google::protobuf::Any> get_property(std::string path);
|
|
|
|
bool set_property(std::string path, google::protobuf::Any value);
|
|
|
|
PlaybackProcess(std::string filename, int idx = 0);
|
|
|
|
~PlaybackProcess();
|
|
|
|
};
|