48#include <condition_variable>
67#define MOD_NAME "[capture filter preview] "
69#define DEFAULT_PREVIEW_FILENAME "ug_preview_cap_unix"
71#define DEFAULT_SCALE_W 960
72#define DEFAULT_SCALE_H 540
83 unsigned scale_factor);
85using clk = std::chrono::steady_clock;
124 std::unique_lock<std::mutex>
lock(s->
mut);
138 std::lock_guard<std::mutex>
lock(s->
mut);
144 col() <<
"preview capture filter\n";
146 col() <<
TBOLD(
TRED(
"\t--capture-filter preview")
"[:path=<path>][:target_size=<w>x<h>]\n\n");
147 col() <<
"options:\n";
148 col() <<
TBOLD(
"\tpath=<path>") <<
"\tpath to unix socket to connect to. Default is \""
150 col() <<
TBOLD(
"\ttarget_size=<w>x<h>")<<
"\tScales the video frame so that the total number of pixel is around <w>x<h>. If -1x-1 is passed, no scaling takes place."
152 col() <<
TBOLD(
"\thq") <<
"\tUse higher quality downscale\n";
157 auto s = std::make_unique<state_preview_filter>();
165 std::string_view cfg_sv = cfg ? cfg :
"";
166 while(!cfg_sv.empty()){
167 auto tok =
tokenize(cfg_sv,
':',
'"');
174 }
else if(
key ==
"path"){
176 }
else if(
key ==
"key"){
180 }
else if(
key ==
"target_size"){
183 }
else if(
key ==
"hq"){
185 }
else if(
key ==
"rate_limit"){
188 s->frame_time = std::chrono::duration_cast<clk::duration>(std::chrono::duration<double>(1 /
limit));
195 s->worker_thread = std::thread(
worker, s.get(), socket_path);
197 *
state = s.release();
206 std::lock_guard<std::mutex>
lock(s->mut);
207 s->frame_queue.push(
nullptr);
208 s->should_exit =
true;
211 s->worker_thread.join();
219 auto now = clk::now();
225 std::lock_guard<std::mutex>
lock(s->
mut);
242 std::lock_guard<std::mutex>
lock(s->
mut);
struct video_frame * frame
#define CAPTURE_FILTER_ABI_VERSION
void log_msg(int level, const char *format,...)
#define LOG_LEVEL_ERROR
general errors
#define LOG_LEVEL_VERBOSE
#define LOG_LEVEL_WARNING
less severe errors
static void * writer(void *arg)
Ipc_frame * ipc_frame_new()
std::unique_ptr< Ipc_frame, Ipc_frame_deleter > Ipc_frame_uniq
bool ipc_frame_from_ug_frame_hq(struct Ipc_frame *dst, const struct video_frame *src, codec_t codec, unsigned scale_factor)
Same as ipc_frame_from_ug_frame, but convert pixfmt first and scale later.
bool ipc_frame_from_ug_frame(struct Ipc_frame *dst, const struct video_frame *src, codec_t codec, unsigned scale_factor)
Make an ipc frame from ultragrid frame.
int ipc_frame_get_scale_factor(int src_w, int src_h, int target_w, int target_h)
bool ipc_frame_writer_write(struct Ipc_frame_writer *writer, const struct Ipc_frame *f)
Ipc_frame_writer * ipc_frame_writer_new(const char *path)
std::unique_ptr< Ipc_frame_writer, Ipc_frame_writer_deleter > Ipc_frame_writer_uniq
@ LIBRARY_CLASS_CAPTURE_FILTER
#define REGISTER_HIDDEN_MODULE(name, info, lclass, abi)
static const struct capture_filter_info capture_filter_preview
static struct video_frame * filter(void *state, struct video_frame *in)
bool(*)(struct Ipc_frame *dst, const struct video_frame *src, codec_t codec, unsigned scale_factor) ipc_frame_conv_func_t
static void worker(struct state_preview_filter *s, std::string path)
#define DEFAULT_PREVIEW_FILENAME
static void done(void *state)
std::chrono::steady_clock clk
static int init(struct module *parent, const char *cfg, void **state)
std::string_view tokenize(std::string_view &str, char delim, char quot)
Tokenizer for string_view.
bool parse_num(std::string_view sv, T &res, int base=10)
clk::time_point next_frame
std::condition_variable frame_submitted_cv
std::vector< Ipc_frame_uniq > free_frames
std::queue< Ipc_frame_uniq > frame_queue
std::atomic< bool > should_exit
ipc_frame_conv_func_t ipc_conv
std::thread worker_thread
Struct tile is an area of video_frame.
Struct video_frame represents a video frame and contains video description.
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
@ RGB
RGB 8-bit (packed into 24-bit word)
This is an umbrella header for video functions.