Skip to content

Commit f0decbd

Browse files
committed
vcap/testcard2: invert bar colors when audio plays
Invert the bars when tone is playing (1 out of 5 seconds) if embedded audio capture is enabled to help when audio synchronization needed to check. Do not advetise it much now, it is not necessarily 100% accurate - didn't check thoroughly, there may be +/- frame diff) so it should be used only for a coarse approximation. The fill_bg_buffer() is just moved code from _init + added a if-branch generating the inverted bars if audio is enabled.
1 parent ab93c4d commit f0decbd

3 files changed

Lines changed: 57 additions & 30 deletions

File tree

src/video_capture/testcard2.c

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ struct testcard_state2 {
117117
#endif
118118
int count;
119119
unsigned char *bg; ///< bars converted to dest color_spec
120+
unsigned char *bg_inv; ///< used if grab_audio == true
120121
unsigned noise; ///< add noise if >0; the magnitude is distance
121122
struct timeval t0;
122123
struct video_desc desc;
@@ -126,9 +127,9 @@ struct testcard_state2 {
126127
struct audio_frame audio;
127128
struct timeval start_time;
128129
int play_audio_frame;
129-
130-
double audio_remained,
131-
seconds_tone_played;
130+
131+
double audio_remained;
132+
volatile float seconds_tone_played;
132133
struct timeval last_audio_time;
133134
char *audio_tone, *audio_silence;
134135
bool grab_audio;
@@ -313,6 +314,48 @@ get_sdl_render_font()
313314
}
314315
#endif
315316

317+
static void
318+
fill_bg_buffer(struct testcard_state2 *s)
319+
{
320+
unsigned int rect_size = (s->desc.width + COL_NUM - 1) / COL_NUM;
321+
int col_num = 0;
322+
struct testcard_pixmap surface;
323+
surface.data =
324+
malloc(vc_get_datalen(s->desc.width, s->desc.height, RGBA));
325+
surface.w = s->desc.width;
326+
surface.h = s->desc.height;
327+
for (unsigned i = 0; i < s->desc.width; i += rect_size) {
328+
struct testcard_rect r;
329+
r.w = MIN(rect_size, s->desc.width - i);
330+
r.h = s->desc.height;
331+
r.x = i;
332+
r.y = 0;
333+
MSG(VERBOSE, "Fill rect at %d,%d\n", r.x, r.y);
334+
testcard_fillRect(&surface, &r, rect_colors[col_num]);
335+
col_num = (col_num + 1) % COL_NUM;
336+
}
337+
s->bg = malloc(
338+
vc_get_datalen(s->desc.width, s->desc.height, s->desc.color_spec));
339+
testcard_convert_buffer(RGBA, s->desc.color_spec, s->bg, surface.data,
340+
s->desc.width, s->desc.height);
341+
342+
if (s->grab_audio) { // if using audio, rotate RGB to GBR when tone
343+
for (size_t i = 0; i < s->desc.width * s->desc.height; ++i) {
344+
unsigned char r = surface.data[4 * i + 0];
345+
surface.data[4 * i + 0] = surface.data[4 * i + 1];
346+
surface.data[4 * i + 1] = surface.data[4 * i + 2];
347+
surface.data[4 * i + 2] = r;
348+
}
349+
s->bg_inv = malloc(vc_get_datalen(s->desc.width, s->desc.height,
350+
s->desc.color_spec));
351+
testcard_convert_buffer(RGBA, s->desc.color_spec, s->bg_inv,
352+
surface.data, s->desc.width,
353+
s->desc.height);
354+
}
355+
356+
free(surface.data);
357+
}
358+
316359
static int vidcap_testcard2_init(const struct vidcap_params *params, void **state)
317360
{
318361
if (vidcap_params_get_fmt(params) == NULL || strcmp(vidcap_params_get_fmt(params), "help") == 0) {
@@ -362,35 +405,14 @@ static int vidcap_testcard2_init(const struct vidcap_params *params, void **stat
362405
#endif
363406
}
364407

365-
{
366-
unsigned int rect_size = (s->desc.width + COL_NUM - 1) / COL_NUM;
367-
int col_num = 0;
368-
struct testcard_pixmap surface;
369-
surface.data = malloc(vc_get_datalen(s->desc.width, s->desc.height, RGBA));
370-
surface.w = s->desc.width;
371-
surface.h = s->desc.height;
372-
for (unsigned i = 0; i < s->desc.width; i += rect_size) {
373-
struct testcard_rect r;
374-
r.w = MIN(rect_size, s->desc.width - i);
375-
r.h = s->desc.height;
376-
r.x = i;
377-
r.y = 0;
378-
log_msg(LOG_LEVEL_VERBOSE, MOD_NAME "Fill rect at %d,%d\n", r.x, r.y);
379-
testcard_fillRect(&surface, &r,
380-
rect_colors[col_num]);
381-
col_num = (col_num + 1) % COL_NUM;
382-
}
383-
s->bg = malloc(vc_get_datalen(s->desc.width, s->desc.height, s->desc.color_spec));
384-
testcard_convert_buffer(RGBA, s->desc.color_spec, s->bg, surface.data, s->desc.width, s->desc.height);
385-
free(surface.data);
386-
}
387-
388408
s->grab_audio =
389409
vidcap_params_get_flags(params) & VIDCAP_FLAG_AUDIO_EMBEDDED;
390410
if (s->grab_audio) {
391411
configure_audio(s);
392412
}
393413

414+
fill_bg_buffer(s);
415+
394416
s->count = 0;
395417
s->audio_remained = 0.0;
396418
s->seconds_tone_played = 0.0;
@@ -428,6 +450,7 @@ static void vidcap_testcard2_done(void *state)
428450
free(s->audio_tone);
429451
free(s->audio_silence);
430452
free(s->bg);
453+
free(s->bg_inv);
431454
free(s->data);
432455
#ifdef HAVE_LIBSDL_TTF
433456
if (s->sdl_font != NULL) {
@@ -533,7 +556,11 @@ void * vidcap_testcard2_thread(void *arg)
533556
{
534557
size_t data_len = vc_get_datalen(s->desc.width, s->desc.height, s->desc.color_spec);
535558
unsigned char *tmp = malloc(data_len);
536-
memcpy(tmp, s->bg, data_len);
559+
if (!s->grab_audio || s->seconds_tone_played > 1.0) {
560+
memcpy(tmp, s->bg, data_len);
561+
} else {
562+
memcpy(tmp, s->bg_inv, data_len);
563+
}
537564

538565
struct testcard_rect r;
539566
r.w = 300;

src/video_capture/testcard_common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const uint32_t rect_colors[] = {
5959

6060
void testcard_fillRect(struct testcard_pixmap *s, struct testcard_rect *r, uint32_t color)
6161
{
62-
uint32_t *data = s->data;
62+
uint32_t *data = (uint32_t *) s->data;
6363

6464
for (int cur_x = r->x; cur_x < r->x + r->w; ++cur_x) {
6565
for (int cur_y = r->y; cur_y < r->y + r->h; ++cur_y) {

src/video_capture/testcard_common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* @author Martin Pulec <pulec@cesnet.cz>
44
*/
55
/*
6-
* Copyright (c) 2020-2022 CESNET
6+
* Copyright (c) 2020-2026 CESNET, zájmové sdružení právnických osob
77
* All rights reserved.
88
*
99
* Redistribution and use in source and binary forms, with or without
@@ -59,7 +59,7 @@ struct testcard_rect {
5959
};
6060
struct testcard_pixmap {
6161
int w, h;
62-
void *data;
62+
unsigned char *data;
6363
};
6464

6565
void testcard_fillRect(struct testcard_pixmap *s, struct testcard_rect *r, uint32_t color);

0 commit comments

Comments
 (0)