68struct compress_state_deleter{
78 std::string
host,
unsigned short rx_port,
80 const char *
fec,
long long bitrate);
86 std::chrono::steady_clock::time_point
t0{std::chrono::steady_clock::now()};
94 std::unique_ptr<compress_state, compress_state_deleter>
compress;
97 std::vector<recompress_output_port>
ports;
105 std::map<std::string, recompress_worker_ctx>
workers;
110 std::string host,
unsigned short rx_port,
111 unsigned short tx_port,
const struct common_opts *common,
112 const char *
fec,
long long bitrate) :
113 host(std::move(host)),
118 std::map<std::string, param_u>
params;
121 params[
"compression"].str =
"none";
125 params[
"common"].cptr = common;
126 params[
"receiver"].str = this->host.c_str();
127 params[
"rx_port"].i = rx_port;
130 params[
"bitrate"].ll = bitrate;
134 params[
"display_device"].ptr = NULL;
137 if (this->host.find(
':') != std::string::npos) {
138 rxtx->m_port_id =
"[" + this->host +
"]:" + to_string(
tx_port);
140 rxtx->m_port_id = this->host +
":" + to_string(
tx_port);
152 auto now = chrono::steady_clock::now();
154 double seconds = chrono::duration_cast<chrono::duration<double>>(now - port.
t0).
count();
156 double fps = port.
frames / seconds;
157 log_msg(
LOG_LEVEL_INFO,
"[0x%08" PRIx32
"->%s:%d:0x%08" PRIx32
"] %d frames in %g seconds = %g FPS\n",
161 port.
frames, seconds, fps);
175 for(
auto& port : ctx->
ports){
188 worker.compress_cfg = compress;
198 std::lock_guard<std::mutex>
lock(
worker.ports_mut);
199 int index_in_worker =
worker.ports.size();
200 worker.ports.push_back(std::move(port));
202 return index_in_worker;
206 const char *host,
const char *compress,
unsigned short rx_port,
207 unsigned short tx_port,
const struct common_opts *common,
208 const char *
fec,
long long bitrate)
214 common,
fec, bitrate);
219 std::lock_guard<std::mutex>
lock(s->
mut);
221 if(index_in_worker < 0)
227 return index_of_port;
231 const std::string& compress_cfg,
int i,
236 std::unique_lock<std::mutex>
lock(
worker.ports_mut);
238 *move_to = std::move(
worker.ports[i]);
245 s->
workers.erase(compress_cfg);
250 if(p.first == compress_cfg && p.second > i)
256 std::lock_guard<std::mutex>
lock(s->
mut);
264 std::lock_guard<std::mutex>
lock(s->
mut);
267 std::lock_guard<std::mutex> work_lock(s->
workers[compress_cfg].ports_mut);
268 return s->
workers[compress_cfg].ports[i].video_rxtx->get_ssrc();
272 int index,
bool active)
274 std::lock_guard<std::mutex>
lock(s->
mut);
277 std::unique_lock<std::mutex> worker_lock(s->
workers[compress_cfg].ports_mut);
278 s->
workers[compress_cfg].ports[i].active = active;
282 const char *new_compress)
284 std::lock_guard<std::mutex>
lock(s->
mut);
287 if(old_compress == new_compress)
294 if(index_in_worker < 0){
306 for(
const auto& port :
worker.ports){
314 std::lock_guard<std::mutex>
lock(s->
mut);
335 std::lock_guard<std::mutex>
lock(s->
mut);
344 std::lock_guard<std::mutex>
lock(s->
mut);
349 worker.second.thread.join();
struct video_frame * frame
void log_msg(int level, const char *format,...)
#define LOG_LEVEL_INFO
normal reporting
void module_done(struct module *module_data)
shared_ptr< video_frame > compress_pop(struct compress_state *proxy)
void compress_frame(struct compress_state *proxy, shared_ptr< video_frame > frame)
int compress_init(struct module *parent, const char *config_string, struct compress_state **state)
This function initializes video compression.
void compress_done(struct compress_state *proxy)
Video compression cleanup function.
int recompress_get_num_active_ports(struct state_recompress *s)
static void recompress_port_write(recompress_output_port &port, shared_ptr< video_frame > frame)
void recompress_port_set_active(struct state_recompress *s, int index, bool active)
static int move_port_to_worker(struct state_recompress *s, const char *compress, recompress_output_port &&port)
uint32_t recompress_get_port_ssrc(struct state_recompress *s, int idx)
static void recompress_worker(struct recompress_worker_ctx *ctx)
static void extract_port(struct state_recompress *s, const std::string &compress_cfg, int i, recompress_output_port *move_to=nullptr)
void recompress_remove_port(struct state_recompress *s, int index)
static int worker_get_num_active_ports(const recompress_worker_ctx &worker)
int recompress_add_port(struct state_recompress *s, const char *host, const char *compress, unsigned short rx_port, unsigned short tx_port, const struct common_opts *common, const char *fec, long long bitrate)
struct state_recompress * recompress_init(struct module *parent)
void recompress_process_async(state_recompress *s, std::shared_ptr< video_frame > frame)
void recompress_done(struct state_recompress *s)
bool recompress_port_change_compress(struct state_recompress *s, int index, const char *new_compress)
static struct @19 params[100]
static void * worker(void *args)
#define PROFILE_DETAIL(name)
std::unique_ptr< ultragrid_rtp_video_rxtx > video_rxtx
std::chrono::steady_clock::time_point t0
recompress_output_port()=default
std::unique_ptr< compress_state, compress_state_deleter > compress
std::vector< recompress_output_port > ports
std::vector< std::pair< std::string, int > > index_to_port
std::map< std::string, recompress_worker_ctx > workers
static video_rxtx * create(std::string const &name, std::map< std::string, param_u > const &)
@ VIDEO_NORMAL
normal video (one tile)
API for video compress drivers.