UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
ug_input.cpp File Reference
#include <cassert>
#include <chrono>
#include <memory>
#include <mutex>
#include <queue>
#include <string>
#include <thread>
#include "audio/audio.h"
#include "audio/types.h"
#include "debug.h"
#include "host.h"
#include "lib_common.h"
#include "tv.h"
#include "video.h"
#include "utils/color_out.h"
#include "video_capture.h"
#include "video_display.h"
#include "video_display/pipe.hpp"
#include "video_rxtx.hpp"
#include "video_rxtx/ultragrid_rtp.hpp"
Include dependency graph for ug_input.cpp:

Go to the source code of this file.

Classes

struct  ug_input_state
 

Macros

#define MOD_NAME   "[ug_input] "
 

Functions

static bool parse_fmt (char *fmt, uint16_t *port, codec_t *decode_to)
 
 REGISTER_MODULE (ug_input, &vidcap_ug_input_info, LIBRARY_CLASS_VIDEO_CAPTURE, VIDEO_CAPTURE_ABI_VERSION)
 
static void usage ()
 
static void vidcap_ug_input_done (void *state)
 
static struct video_frame * vidcap_ug_input_grab (void *state, struct audio_frame **audio)
 
static int vidcap_ug_input_init (struct vidcap_params *cap_params, void **state)
 
static void vidcap_ug_input_probe (device_info **available_cards, int *count, void(**deleter)(void *))
 

Variables

static constexpr int MAX_QUEUE_SIZE = 2
 
static const struct video_capture_info vidcap_ug_input_info
 

Detailed Description

Author
Martin Pulec pulec.nosp@m.@ces.nosp@m.net.c.nosp@m.z

Definition in file ug_input.cpp.

Macro Definition Documentation

◆ MOD_NAME

#define MOD_NAME   "[ug_input] "

Definition at line 60 of file ug_input.cpp.

Function Documentation

◆ parse_fmt()

static bool parse_fmt ( char * fmt,
uint16_t * port,
codec_t * decode_to )
static

Definition at line 118 of file ug_input.cpp.

119{
120 char *tok = nullptr;
121 char *saveptr = nullptr;
122 while ((tok = strtok_r(fmt, ":", &saveptr)) != nullptr) {
123 fmt = nullptr;
124 const char *val = strchr(tok, '=') + 1;
125 if (isdigit(tok[0])) {
126 *port = stoi(tok);
127 } else if (IS_KEY_PREFIX(tok, "codec")) {
128 *decode_to = get_codec_from_name(val);
129 if (*decode_to == VIDEO_CODEC_NONE) {
130 MSG(ERROR, "Invalid codec: %s\n", val);
131 return false;
132 }
133 } else {
134 MSG(ERROR, "Invalid option: %s\n", tok);
135 return false;
136 }
137 }
138 return true;
139}
int void * val
const char * fmt
codec_t get_codec_from_name(const char *name)
#define MSG(l, fmt,...)
Definition debug.h:96
#define IS_KEY_PREFIX(tok, key)
expands to true value if <k> from tok in format <k>=<v> is prefix of key
Definition macros.h:138
@ VIDEO_CODEC_NONE
dummy color spec
Definition types.h:66

References fmt, get_codec_from_name(), IS_KEY_PREFIX, MSG, val, and VIDEO_CODEC_NONE.

Referenced by vidcap_ug_input_init().

Here is the call graph for this function:

◆ REGISTER_MODULE()

REGISTER_MODULE ( ug_input ,
& vidcap_ug_input_info,
LIBRARY_CLASS_VIDEO_CAPTURE ,
VIDEO_CAPTURE_ABI_VERSION  )

◆ usage()

static void usage ( void )
static

Definition at line 107 of file ug_input.cpp.

108{
109 printf("Usage:\n");
110 color_printf("\t" TBOLD(
111 TRED("-t ug_input") "[:<port>[:codec=<c>]] [-s embedded]") "\n");
112 printf("where:\n");
113 color_printf("\t" TBOLD("<port>") " - UG port to listen to\n");
114 color_printf("\t" TBOLD("<c>") " - enforce pixfmt to decode to\n");
115}
int color_printf(const char *format,...)
#define TRED(x)
Definition color_out.h:75
#define TBOLD(x)
Definition color_out.h:70

References color_printf(), TBOLD, and TRED.

Referenced by vidcap_ug_input_init().

Here is the call graph for this function:

◆ vidcap_ug_input_done()

static void vidcap_ug_input_done ( void * state)
static

Definition at line 232 of file ug_input.cpp.

233{
234 auto s = (ug_input_state *) state;
235
236 audio_join(s->audio);
237 s->receiver_thread.join();
238
239 display_put_frame(s->display, NULL, 0);
240 display_join(s->display);
241 display_done(s->display);
242
243 s->video_rxtx->join();
244
245 while (!s->frame_queue.empty()) {
246 auto item = s->frame_queue.front();
247 s->frame_queue.pop();
250 }
251 audio_done(s->audio);
252
253 delete s;
254}
void ** state
#define AUDIO_FRAME_DISPOSE(frame)
Definition types.h:117
void audio_join(struct state_audio *s)
Definition audio.cpp:502
void audio_done(struct state_audio *s)
Definition audio.cpp:512
bool display_put_frame(struct display *d, struct video_frame *frame, long long timeout_ns)
Puts filled video frame. After calling this function, video frame cannot be used.
void display_done(struct display *d)
This function performs cleanup after done.
void display_join(struct display *d)
Definition hd-rum.c:27
#define VIDEO_FRAME_DISPOSE(frame)
Definition video_frame.h:76

References audio_done(), AUDIO_FRAME_DISPOSE, audio_join(), display_done(), display_join(), display_put_frame(), state, and VIDEO_FRAME_DISPOSE.

Here is the call graph for this function:

◆ vidcap_ug_input_grab()

static struct video_frame * vidcap_ug_input_grab ( void * state,
struct audio_frame ** audio )
static

Definition at line 256 of file ug_input.cpp.

257{
258 auto s = (ug_input_state *) state;
259 *audio = NULL;
260 lock_guard<mutex> lk(s->lock);
261 if (s->frame_queue.empty()) {
262 return NULL;
263 } else {
264 auto item = s->frame_queue.front();
265 struct video_frame *frame = item.first;
266 *audio = item.second;
267 s->frame_queue.pop();
269
270 s->frames++;
271 auto curr_time = steady_clock::now();
272 double seconds = duration_cast<duration<double>>(curr_time - s->t0).count();
273 if (seconds >= 5.0) {
274 float fps = s->frames / seconds;
275 log_msg(LOG_LEVEL_INFO, "[ug_input] %d frames in %g seconds = %g FPS\n",
276 s->frames, seconds, fps);
277 s->t0 = curr_time;
278 s->frames = 0;
279 }
280
281 return frame;
282 }
283}
struct video_frame * frame
struct audio_frame ** audio
void vf_free(struct video_frame *buf)
Frees video_frame structure.
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62
int count
Definition hd-rum.c:44
void(* dispose)(struct video_frame *)
Definition types.h:245
Struct video_frame represents a video frame and contains video description.
Definition types.h:305
double fps
Definition types.h:308
struct video_frame_callbacks callbacks
Definition types.h:324

References audio, video_frame::callbacks, count, video_frame_callbacks::dispose, video_frame::fps, frame, LOG_LEVEL_INFO, log_msg(), state, and vf_free().

Here is the call graph for this function:

◆ vidcap_ug_input_init()

static int vidcap_ug_input_init ( struct vidcap_params * cap_params,
void ** state )
static

Definition at line 141 of file ug_input.cpp.

142{
143 uint16_t port = 5004;
144 codec_t decode_to = VIDEO_CODEC_NONE;
145
146 if (strcmp("help", vidcap_params_get_fmt(cap_params)) == 0) {
147 usage();
148 return VIDCAP_INIT_NOERR;
149 }
150 char *fmt_cpy = strdup(vidcap_params_get_fmt(cap_params));
151 const bool parse_ret = parse_fmt(fmt_cpy, &port, &decode_to);
152 free(fmt_cpy);
153 if (!parse_ret) {
154 return VIDCAP_INIT_FAIL;
155 }
156
157 auto *s = new ug_input_state();
158
159 char cfg[128] = "";
160 snprintf(cfg, sizeof cfg, "%p", s);
161 if (decode_to != VIDEO_CODEC_NONE) {
162 snprintf(cfg + strlen(cfg), sizeof cfg - strlen(cfg),
163 ":codec=%s", get_codec_name(decode_to));
164 }
165 int ret = initialize_video_display(vidcap_params_get_parent(cap_params), "pipe", cfg, 0, NULL, &s->display);
166 assert(ret == 0 && "Unable to initialize proxy display");
167
168 map<string, param_u> params;
169
170 // common
171 s->common.parent = vidcap_params_get_parent(cap_params);
172 params["exporter"].ptr = NULL;
173 params["compression"].str = "none";
174 params["rxtx_mode"].i = MODE_RECEIVER;
175
176 //RTP
177 params["common"].ptr = &s->common;
178 // should be localhost and RX TX ports the same (here dynamic) in order to work like a pipe
179 params["receiver"].str = "localhost";
180 params["rx_port"].i = port;
181 params["tx_port"].i = 0;
182 params["fec"].str = "none";
183 params["bitrate"].ll = 0;
184
185 // UltraGrid RTP
186 params["decoder_mode"].l = VIDEO_NORMAL;
187 params["display_device"].ptr = s->display;
188
189 s->video_rxtx = unique_ptr<ultragrid_rtp_video_rxtx>(dynamic_cast<ultragrid_rtp_video_rxtx *>(video_rxtx::create("ultragrid_rtp", params)));
190 assert (s->video_rxtx);
191
193 struct audio_options opt = {
194 .host = "localhost",
195 .recv_port = port + 2,
196 .send_port = 0,
197 .recv_cfg = "embedded",
198 .send_cfg = "none",
199 .proto = "ultragrid_rtp",
200 .proto_cfg = "",
201 .fec_cfg = "none",
202 .channel_map = NULL,
203 .scale = "none",
204 .echo_cancellation = false,
205 .codec_cfg = "PCM"
206 };
207 if (audio_init(&s->audio, &opt, &s->common) != 0) {
208 delete s;
209 return VIDCAP_INIT_FAIL;
210 }
211
212 struct additional_audio_data aux_aud_data = {
213 { s->display, display_put_audio_frame,
215
216 },
217 s->video_rxtx.get()
218 };
219 audio_register_aux_data(s->audio, aux_aud_data);
220
221 audio_start(s->audio);
222 }
223 s->t0 = steady_clock::now();
224
225 s->receiver_thread = thread(&video_rxtx::receiver_thread, s->video_rxtx.get());
226 display_run_new_thread(s->display);
227
228 *state = s;
229 return VIDCAP_INIT_OK;
230}
const char * get_codec_name(codec_t codec)
void audio_register_aux_data(struct state_audio *s, struct additional_audio_data data)
Definition audio.cpp:1191
int audio_init(struct state_audio **ret, const struct audio_options *opt, const struct common_opts *common)
Definition audio.cpp:272
void audio_start(struct state_audio *s)
Definition audio.cpp:463
bool display_reconfigure_audio(struct display *d, int quant_samples, int channels, int sample_rate)
void display_put_audio_frame(struct display *d, const struct audio_frame *frame)
Puts audio data.
bool display_ctl_property(struct display *d, int property, void *val, size_t *len)
Gets property from video display.
void display_run_new_thread(struct display *d)
int initialize_video_display(struct module *parent, const char *requested_display, const char *fmt, unsigned int flags, const char *postprocess, struct display **out)
Initializes video display.
#define VIDCAP_INIT_NOERR
state not initialized, other action performed (typically help)
#define VIDCAP_INIT_OK
initialization successful
#define VIDCAP_INIT_FAIL
error ocured
static struct @19 params[100]
#define MODE_RECEIVER
Definition host.h:103
static video_rxtx * create(std::string const &name, std::map< std::string, param_u > const &)
static void * receiver_thread(void *arg)
@ VIDEO_NORMAL
normal video (one tile)
Definition types.h:356
codec_t
Definition types.h:65
static void usage()
Definition ug_input.cpp:107
static bool parse_fmt(char *fmt, uint16_t *port, codec_t *decode_to)
Definition ug_input.cpp:118
struct module * vidcap_params_get_parent(const struct vidcap_params *params)
const char * vidcap_params_get_fmt(const struct vidcap_params *params)
unsigned int vidcap_params_get_flags(const struct vidcap_params *params)
#define VIDCAP_FLAG_AUDIO_ANY

References audio_init(), audio_register_aux_data(), audio_start(), video_rxtx::create(), display_ctl_property(), display_put_audio_frame(), display_reconfigure_audio(), display_run_new_thread(), get_codec_name(), initialize_video_display(), MODE_RECEIVER, params, parse_fmt(), video_rxtx::receiver_thread(), state, usage(), VIDCAP_FLAG_AUDIO_ANY, VIDCAP_INIT_FAIL, VIDCAP_INIT_NOERR, VIDCAP_INIT_OK, vidcap_params_get_flags(), vidcap_params_get_fmt(), vidcap_params_get_parent(), VIDEO_CODEC_NONE, and VIDEO_NORMAL.

Here is the call graph for this function:

◆ vidcap_ug_input_probe()

static void vidcap_ug_input_probe ( device_info ** available_cards,
int * count,
void(** deleter )(void *) )
static

Definition at line 285 of file ug_input.cpp.

286{
287 *deleter = free;
288 *count = 0;
289 *available_cards = nullptr;
290}
int void(** deleter)(void *))

References count, and deleter.

Variable Documentation

◆ MAX_QUEUE_SIZE

int MAX_QUEUE_SIZE = 2
staticconstexpr

Definition at line 61 of file ug_input.cpp.

Referenced by ug_input_state::frame_arrived().

◆ vidcap_ug_input_info

const struct video_capture_info vidcap_ug_input_info
static
Initial value:
= {
}
#define VIDCAP_NO_GENERIC_FPS_INDICATOR
static int vidcap_ug_input_init(struct vidcap_params *cap_params, void **state)
Definition ug_input.cpp:141
static void vidcap_ug_input_probe(device_info **available_cards, int *count, void(**deleter)(void *))
Definition ug_input.cpp:285
static void vidcap_ug_input_done(void *state)
Definition ug_input.cpp:232
static struct video_frame * vidcap_ug_input_grab(void *state, struct audio_frame **audio)
Definition ug_input.cpp:256

Definition at line 292 of file ug_input.cpp.