UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
dummy.c
Go to the documentation of this file.
1
5/*
6 * Copyright (c) 2015-2023 CESNET, z. s. p. o.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, is permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * 3. Neither the name of CESNET nor the names of its contributors may be
21 * used to endorse or promote products derived from this software without
22 * specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
26 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
28 * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
35 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include "config.h"
39#include "config_unix.h"
40#include "config_win32.h"
41
42#include <assert.h>
43#include <stdlib.h>
44#include <string.h>
45
46#include "debug.h"
47#include "host.h"
48#include "lib_common.h"
49#include "pixfmt_conv.h"
50#include "utils/color_out.h"
51#include "utils/macros.h"
52#include "utils/misc.h"
53#include "utils/text.h"
54#include "video.h"
55#include "video_codec.h"
56#include "video_display.h"
57
58#define DEFAULT_DUMP_LEN 32
59#define MOD_NAME "[dummy] "
60
62
63static const codec_t codecs_decklink[] = { R12L, R10k, v210, RGBA, UYVY };
64static const codec_t codecs_gl[] = { UYVY, v210, R10k, RGBA, RGB, RG48, Y416, DXT1, DXT1_YUV, DXT5 };
65const struct codec_profile_t {
66 const char *name;
69} codec_profiles[] = {
70 { "decklink", codecs_decklink, sizeof codecs_decklink / sizeof(codec_t) },
71 { "gl", codecs_gl, sizeof codecs_gl / sizeof(codec_t) },
72};
73
86
87static _Bool parse_codecs(char *str, codec_t *codecs, size_t *codec_count) {
88 for (unsigned i = 0; i < sizeof codec_profiles / sizeof codec_profiles[0]; ++i) {
89 if (strcmp(str, codec_profiles[i].name) == 0) {
90 memcpy(codecs, codec_profiles[i].codecs, sizeof(codec_t) * codec_profiles[i].codec_count);
91 *codec_count = codec_profiles[i].codec_count;
92 return 1;
93 }
94 }
95 char *sptr = NULL;
96 char *tok = NULL;
97 *codec_count = 0;
98 while ((tok = strtok_r(str, ",", &sptr))) {
99 str = NULL;
100 assert(*codec_count < sizeof ((struct dummy_display_state *) 0)->codecs / sizeof(codec_t));
101 codecs[(*codec_count)++] = get_codec_from_name(tok);
102 if (codecs[*codec_count - 1] == VIDEO_CODEC_NONE) {
103 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Wrong codec spec: %s!\n", tok);
104 return 0;
105 }
106 }
107 return 1;
108}
109
110static _Bool dummy_parse_opts(struct dummy_display_state *s, char *fmt) {
111 char *item = NULL;
112 char *save_ptr = NULL;
113 while ((item = strtok_r(fmt, ":", &save_ptr)) != NULL) {
114 fmt = NULL;
115 if (strstr(item, "codec=") != NULL) {
116 if (!parse_codecs(strchr(item, '=') + 1, s->codecs, &s->codec_count)) {
117 return 0;
118 }
119 } else if (strstr(item, "dump") != NULL) {
120 s->dump_to_file = 1;
121 } else if (strstr(item, "hexdump") != NULL) {
122 if (strstr(item, "hexdump=") != NULL) {
123 s->dump_bytes = atoi(item + strlen("hexdump="));
124 } else {
126 }
127 } else if (strstr(item, "rgb_shift=") != NULL) {
128 item += strlen("rgb_shift=");
129 s->rgb_shift[0] = strtol(item, &item, 0);
130 item += 1;
131 s->rgb_shift[1] = strtol(item, &item, 0);
132 item += 1;
133 s->rgb_shift[2] = strtol(item, &item, 0);
134 } else if (strstr(item, "skip=") != NULL) {
135 s->dump_to_file_skip_frames = atoi(strchr(item, '=') + 1);
136 } else if (strcmp(item, "oneshot") == 0) {
137 s->oneshot = 1;
138 } else if (strcmp(item, "raw") == 0) {
139 s->raw = 1;
140 } else {
141 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Unrecognized option: %s\n", item);
142 return 0;
143 }
144 }
145 if (!s->dump_to_file && (s->oneshot || s->dump_to_file_skip_frames > 0 || s->raw)) {
146 log_msg(LOG_LEVEL_WARNING, MOD_NAME "Some of passed options don't do anything without \":dump\".\n");
147 }
148 return 1;
149}
150
151static void *display_dummy_init(struct module *parent, const char *cfg, unsigned int flags)
152{
154 if (strcmp(cfg, "help") == 0) {
155 char desc[] = "Display " TBOLD("dummy") " only consumes the video without displaying it. A difference to avoiding "
156 "display specification is that it forces decoding (otherwise it will be skipped altogether).\n\n"
157 "Additionally, options " TBOLD("hexdump") " and " TBOLD("dump") " are available for debugging.\n\n";
159 struct key_val options[] = {
160 { "codec=<codec>[,<codec2>] | codec=<setlist>", "force the use of a codec instead of default set; special set list also possible (see below)" },
161 { "rgb_shift=<r>,<g>,<b>", "if using output codec RGBA, use specified shifts instead of default (" TOSTRING(DEFAULT_R_SHIFT) ", " TOSTRING(DEFAULT_G_SHIFT) ", " TOSTRING(DEFAULT_B_SHIFT) ")" },
162 { "dump[:skip=<n>][:oneshot][:raw]", "dump first frame to file dummy.<ext> (optionally skip <n> first frames); 'oneshot' - exit after dumping the picture; 'raw' - dump raw data" },
163 { "hexdump[=<n>]", "dump first n (default " TOSTRING(DEFAULT_DUMP_LEN) ") bytes of every frame in hexadecimal format" },
164 { NULL, NULL }
165 };
166 print_module_usage("-d dummy", options, NULL, 0);
167 color_printf("\nAvailable codec sets:\n");
168 for (unsigned i = 0; i < sizeof codec_profiles / sizeof codec_profiles[0]; ++i) {
169 color_printf("\t- " TBOLD("%s") "\n", codec_profiles[i].name);
170 }
171 return INIT_NOERR;
172 }
173 struct dummy_display_state s = { .codec_count = sizeof default_codecs / sizeof default_codecs[0] };
174 memcpy(s.codecs, default_codecs, sizeof default_codecs);
175 int rgb_shift_init[] = DEFAULT_RGB_SHIFT_INIT;
176 memcpy(s.rgb_shift, &rgb_shift_init, sizeof s.rgb_shift);
177 char *ccpy = alloca(strlen(cfg) + 1);
178 strcpy(ccpy, cfg);
179
180 if (!dummy_parse_opts(&s, ccpy)) {
181 return NULL;
182 }
183
184 struct dummy_display_state *ret = malloc(sizeof s);
185 memcpy(ret, &s, sizeof s);
186
187 return ret;
188}
189
190static void display_dummy_done(void *state)
191{
192 struct dummy_display_state *s = state;
193
194 vf_free(s->f);
195 free(s);
196}
197
199{
200 return ((struct dummy_display_state *) state)->f;
201}
202
203static void dump_buf(unsigned char *buf, size_t len, int block_size) {
204 printf("Frame content: ");
205 for (size_t i = 0; i < len; ++i) {
206 printf("%02hhx ", *buf++);
207 if (block_size > 0 && (i + 1) % block_size == 0) {
208 printf(" ");
209 }
210 }
211 printf("\n");
212}
213
214static bool display_dummy_putf(void *state, struct video_frame *frame, long long flags)
215{
216 if (flags == PUTF_DISCARD || frame == NULL) {
217 return true;
218 }
219 struct dummy_display_state *s = state;
220 if (s->dump_bytes > 0) {
222 }
223 if (s->dump_to_file) {
224 if (s->dump_to_file_skip_frames-- == 0) {
225 const char *filename = save_video_frame(frame, "dummy", s->raw);
226 if (filename) {
227 log_msg(LOG_LEVEL_NOTICE, MOD_NAME "Written dump to file %s\n", filename);
228 } else {
229 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Unable to write dump!\n");
230 }
231 s->dump_to_file = false;
232 if (s->oneshot) {
233 exit_uv(0);
234 }
235 }
236 }
237
238 return true;
239}
240
241static bool display_dummy_get_property(void *state, int property, void *val, size_t *len)
242{
243 struct dummy_display_state *s = state;
244
245 switch (property) {
247 {
248 size_t req_len = s->codec_count * sizeof(codec_t);
249 if (req_len > *len) {
250 return false;
251 }
252 *len = req_len;
253 memcpy(val, s->codecs, *len);
254 }
255 break;
257 if (sizeof s->rgb_shift > *len) {
258 return false;
259 }
260 *len = sizeof s->rgb_shift;
261 memcpy(val, s->rgb_shift, *len);
262 break;
263 default:
264 return false;
265 }
266 return true;
267}
268
270{
271 struct dummy_display_state *s = state;
272 vf_free(s->f);
274
275 return true;
276}
277
278static void display_dummy_probe(struct device_info **available_cards, int *count, void (**deleter)(void *)) {
280 *available_cards = NULL;
281 *count = 0;
282}
283
287 NULL, // _run
293 NULL, // _put_audio_frame
294 NULL, // _reconfigure_audio
295 MOD_NAME,
296};
297
299
#define UNUSED(x)
void ** state
int void * val
struct video_desc desc
struct video_frame * frame
const char * fmt
int void size_t * len
const char unsigned int flags
int void(** deleter)(void *))
int property
void vf_free(struct video_frame *buf)
Frees video_frame structure.
struct video_frame * vf_alloc_desc_data(struct video_desc desc)
codec_t get_codec_from_name(const char *name)
#define MOD_NAME
Definition dummy.c:49
int color_printf(const char *format,...)
#define TBOLD(x)
Definition color_out.h:70
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_NOTICE
information that may be interesting
Definition debug.h:61
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
#define PUTF_DISCARD
#define VIDEO_DISPLAY_ABI_VERSION
@ DISPLAY_PROPERTY_RGB_SHIFT
red,green,blue shift - int[3] (bits)
@ DISPLAY_PROPERTY_CODECS
list of natively supported codecs - codec_t[]
int count
Definition hd-rum.c:44
void exit_uv(int status)
Definition host.cpp:625
#define INIT_NOERR
Definition host.h:73
@ LIBRARY_CLASS_VIDEO_DISPLAY
Definition lib_common.h:79
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
Definition lib_common.h:144
#define MIN(a, b)
Definition macros.h:63
#define TOSTRING(A)
Definition macros.h:49
void print_module_usage(const char *module_name, const struct key_val *options, const struct key_val *options_full, bool print_full_help)
Definition misc.cpp:242
#define DEFAULT_B_SHIFT
Definition pixfmt_conv.h:72
#define DEFAULT_R_SHIFT
Definition pixfmt_conv.h:70
#define DEFAULT_G_SHIFT
Definition pixfmt_conv.h:71
#define DEFAULT_RGB_SHIFT_INIT
Definition pixfmt_conv.h:73
const char * parent
Definition settings.cpp:198
const char * name
Definition settings.cpp:193
int codec_count
Definition dummy.c:68
const char * name
Definition dummy.c:66
const codec_t * codecs
Definition dummy.c:67
int dump_to_file_skip_frames
Definition dummy.c:84
int rgb_shift[3]
Definition dummy.c:78
size_t dump_bytes
Definition dummy.c:80
_Bool dump_to_file
Definition dummy.c:81
codec_t codecs[VIDEO_CODEC_COUNT]
Definition dummy.c:76
struct video_frame * f
Definition dummy.c:75
size_t codec_count
Definition dummy.c:77
Definition hd-rum.c:27
Definition misc.h:68
Definition rtp.c:253
char * data
Raw tile data. Pointer must be at least 4B aligned.
Definition types.h:287
unsigned int data_len
length of the data
Definition types.h:288
Struct video_frame represents a video frame and contains video description.
Definition types.h:305
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
Definition types.h:345
codec_t color_spec
Definition types.h:306
codec_t
Definition types.h:65
@ YUYV
YCbCr 422 8-bit - Y0 Cb Y1 Cr.
Definition types.h:72
@ DXT1
S3 Texture Compression DXT1.
Definition types.h:77
@ R10k
RGB 10-bit packed - RGBX, big-endian (2 bit padding)
Definition types.h:73
@ RGB
RGB 8-bit (packed into 24-bit word)
Definition types.h:80
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
Definition types.h:71
@ VIDEO_CODEC_NONE
dummy color spec
Definition types.h:66
@ BGR
8-bit BGR
Definition types.h:88
@ RG48
16-bit RGB little-endian (RlRhGl...)
Definition types.h:95
@ Y416
interleaved little-endian YCbCr 4444 16-bit - UYVA
Definition types.h:99
@ VIDEO_CODEC_COUNT
count of known video codecs (including VIDEO_CODEC_NONE)
Definition types.h:108
@ R12L
RGB 12-bit packed, little-endian.
Definition types.h:74
@ DXT5
S3 Texture Compression DXT5.
Definition types.h:79
@ I420
planar YCbCr 4:2:0
Definition types.h:97
@ DXT1_YUV
Structure same as DXT1, instead of RGB, YCbCr values are stored.
Definition types.h:78
@ RGBA
RGBA 8-bit, big-endian.
Definition types.h:70
@ v210
YCbCr 422 10-bit - xVY0U|xY2UY1|xUY3V|xY5VY4, little-endian (2 bit padding /'x'/),...
Definition types.h:75
char * wrap_paragraph(char *text)
Definition text.c:204
This is an umbrella header for video functions.
int get_pf_block_bytes(codec_t codec)
returns codec_info_t::block_size_bytes
static struct @76 codecs[]
static void dump_buf(unsigned char *buf, size_t len, int block_size)
Definition dummy.c:203
static const codec_t codecs_decklink[]
Definition dummy.c:63
#define DEFAULT_DUMP_LEN
Definition dummy.c:58
const struct codec_profile_t codec_profiles[]
static bool display_dummy_reconfigure(void *state, struct video_desc desc)
Definition dummy.c:269
static void display_dummy_done(void *state)
Definition dummy.c:190
static const codec_t codecs_gl[]
Definition dummy.c:64
static void display_dummy_probe(struct device_info **available_cards, int *count, void(**deleter)(void *))
Definition dummy.c:278
static void * display_dummy_init(struct module *parent, const char *cfg, unsigned int flags)
Definition dummy.c:151
static bool display_dummy_putf(void *state, struct video_frame *frame, long long flags)
Definition dummy.c:214
static struct video_frame * display_dummy_getf(void *state)
Definition dummy.c:198
static _Bool parse_codecs(char *str, codec_t *codecs, size_t *codec_count)
Definition dummy.c:87
static _Bool dummy_parse_opts(struct dummy_display_state *s, char *fmt)
Definition dummy.c:110
static const struct video_display_info display_dummy_info
Definition dummy.c:284
static bool display_dummy_get_property(void *state, int property, void *val, size_t *len)
Definition dummy.c:241
static const codec_t default_codecs[]
Definition dummy.c:61
const char * save_video_frame(struct video_frame *frame, const char *name, bool raw)