1
/*****************************************************************
2
* gmerlin - a general purpose multimedia framework and applications
4
* Copyright (c) 2001 - 2011 Members of the Gmerlin project
5
* gmerlin-general@lists.sourceforge.net
6
* http://gmerlin.sourceforge.net
8
* This program is free software: you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation, either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program. If not, see <http://www.gnu.org/licenses/>.
20
* *****************************************************************/
26
#include <gavl/gavl.h>
29
#include <gmerlin/translation.h>
31
#include <gmerlin/pluginregistry.h>
32
#include <gmerlin/visualize.h>
33
#include <visualize_priv.h>
34
#include <gmerlin/utils.h>
38
#include <gmerlin/log.h>
40
#define LOG_DOMAIN "visualizer_slave"
46
/* Messages from the application to the visualizer */
50
gavl_audio_converter_t * cnv;
51
gavl_audio_frame_t * in_frame_1;
52
gavl_audio_frame_t * in_frame_2;
53
pthread_mutex_t in_mutex;
57
gavl_audio_frame_t * out_frame;
59
gavl_audio_format_t in_format;
60
gavl_audio_format_t out_format;
62
int last_samples_read;
65
gavl_volume_control_t * gain_control;
66
pthread_mutex_t gain_mutex;
70
static audio_buffer_t * audio_buffer_create()
73
ret = calloc(1, sizeof(*ret));
74
ret->cnv = gavl_audio_converter_create();
75
pthread_mutex_init(&ret->in_mutex,(pthread_mutexattr_t *)0);
76
pthread_mutex_init(&ret->gain_mutex,(pthread_mutexattr_t *)0);
78
ret->gain_control = gavl_volume_control_create();
83
static void audio_buffer_cleanup(audio_buffer_t * b)
87
gavl_audio_frame_destroy(b->in_frame_1);
88
b->in_frame_1 = (gavl_audio_frame_t*)0;
92
gavl_audio_frame_destroy(b->in_frame_2);
93
b->in_frame_2 = (gavl_audio_frame_t*)0;
97
gavl_audio_frame_destroy(b->out_frame);
98
b->out_frame = (gavl_audio_frame_t*)0;
100
b->last_samples_read = 0;
105
static void audio_buffer_destroy(audio_buffer_t * b)
107
audio_buffer_cleanup(b);
108
gavl_audio_converter_destroy(b->cnv);
109
gavl_volume_control_destroy(b->gain_control);
110
pthread_mutex_destroy(&b->in_mutex);
111
pthread_mutex_destroy(&b->gain_mutex);
115
static void audio_buffer_init(audio_buffer_t * b,
116
const gavl_audio_format_t * in_format,
117
const gavl_audio_format_t * out_format)
119
gavl_audio_format_t frame_format;
121
audio_buffer_cleanup(b);
122
gavl_audio_format_copy(&b->in_format, in_format);
123
gavl_audio_format_copy(&b->out_format, out_format);
125
/* For visualizations, we ignore the samplerate completely.
126
Perfect synchronization is mathematically impossible anyway. */
128
b->out_format.samplerate = b->in_format.samplerate;
130
b->do_convert = gavl_audio_converter_init(b->cnv,
134
b->in_frame_1 = gavl_audio_frame_create(&b->in_format);
136
gavl_audio_format_copy(&frame_format, out_format);
137
frame_format.samples_per_frame = b->in_format.samples_per_frame;
139
b->in_frame_2 = gavl_audio_frame_create(&frame_format);
141
b->out_frame = gavl_audio_frame_create(&b->out_format);
143
gavl_volume_control_set_format(b->gain_control, &frame_format);
146
static void audio_buffer_put(audio_buffer_t * b,
147
const gavl_audio_frame_t * f)
149
pthread_mutex_lock(&b->in_mutex);
151
b->in_frame_1->valid_samples =
152
gavl_audio_frame_copy(&b->in_format,
157
b->in_format.samples_per_frame, /* dst_size */
158
f->valid_samples /* src_size */ );
159
pthread_mutex_unlock(&b->in_mutex);
162
static void audio_buffer_set_gain(audio_buffer_t * b, float gain)
164
pthread_mutex_lock(&b->gain_mutex);
165
gavl_volume_control_set_volume(b->gain_control, gain);
166
pthread_mutex_unlock(&b->gain_mutex);
169
static gavl_audio_frame_t * audio_buffer_get(audio_buffer_t * b)
172
/* Check if there is new audio */
173
pthread_mutex_lock(&b->in_mutex);
175
if(b->in_frame_1->valid_samples)
179
gavl_audio_convert(b->cnv, b->in_frame_1, b->in_frame_2);
180
samples_copied = b->in_frame_1->valid_samples;
184
gavl_audio_frame_copy(&b->in_format,
189
b->in_format.samples_per_frame, /* dst_size */
190
b->in_frame_1->valid_samples /* src_size */ );
191
b->in_frame_2->valid_samples = samples_copied;
192
b->last_samples_read = samples_copied;
193
b->in_frame_1->valid_samples = 0;
195
pthread_mutex_lock(&b->gain_mutex);
196
gavl_volume_control_apply(b->gain_control, b->in_frame_2);
197
pthread_mutex_unlock(&b->gain_mutex);
199
pthread_mutex_unlock(&b->in_mutex);
201
/* If the frame was output the last time, set valid_samples to 0 */
204
b->out_frame->valid_samples = 0;
208
/* Copy to output frame and check if there are enough samples */
211
gavl_audio_frame_copy(&b->out_format,
214
b->out_frame->valid_samples, /* dst_pos */
215
b->last_samples_read - b->in_frame_2->valid_samples, /* src_pos */
216
b->out_format.samples_per_frame - b->out_frame->valid_samples, /* dst_size */
217
b->in_frame_2->valid_samples /* src_size */ );
219
b->out_frame->valid_samples += samples_copied;
220
b->in_frame_2->valid_samples -= samples_copied;
222
if(b->out_frame->valid_samples == b->out_format.samples_per_frame)
227
return (gavl_audio_frame_t*)0;
232
bg_plugin_handle_t * vis_handle;
233
bg_plugin_handle_t * ov_handle;
234
bg_plugin_api_t vis_api;
236
audio_buffer_t * audio_buffer;
238
gavl_video_converter_t * video_cnv;
240
int do_convert_video;
242
bg_ov_plugin_t * ov_plugin;
243
bg_ov_callbacks_t ov_callbacks;
245
bg_visualization_plugin_t * vis_plugin;
247
gavl_video_format_t video_format_in;
248
gavl_video_format_t video_format_in_real;
249
gavl_video_format_t video_format_out;
251
pthread_t video_thread;
253
pthread_mutex_t running_mutex;
254
pthread_mutex_t stop_mutex;
255
pthread_mutex_t vis_mutex;
256
pthread_mutex_t ov_mutex;
260
gavl_video_frame_t * video_frame_in;
261
gavl_video_frame_t * video_frame_out;
263
gavl_timer_t * timer;
265
gavl_time_t last_frame_time;
267
gavl_audio_format_t audio_format_in;
268
gavl_audio_format_t audio_format_out;
274
gavl_audio_frame_t * read_frame;
276
pthread_mutex_t fps_mutex;
279
bg_msg_queue_t * cb_queue; /* Pass events */
281
bg_ov_callbacks_t cb;
283
} bg_visualizer_slave_t;
285
static int init_plugin(bg_visualizer_slave_t * v);
287
static bg_plugin_handle_t *
288
load_plugin_gmerlin(const char * filename)
290
int (*get_plugin_api_version)();
291
bg_plugin_handle_t * ret;
292
ret = calloc(1, sizeof(*ret));
294
ret->dll_handle = dlopen(filename, RTLD_NOW | RTLD_GLOBAL);
295
if(!(ret->dll_handle))
297
bg_log(BG_LOG_ERROR, LOG_DOMAIN,
298
"Cannot dlopen plugin module %s: %s", filename,
303
get_plugin_api_version = dlsym(ret->dll_handle, "get_plugin_api_version");
304
if(!get_plugin_api_version)
306
bg_log(BG_LOG_ERROR, LOG_DOMAIN,
307
"cannot get API version: %s", dlerror());
310
if(get_plugin_api_version() != BG_PLUGIN_API_VERSION)
312
bg_log(BG_LOG_ERROR, LOG_DOMAIN,
313
"Wrong API version: Got %d expected %d",
314
get_plugin_api_version(), BG_PLUGIN_API_VERSION);
317
ret->plugin = dlsym(ret->dll_handle, "the_plugin");
320
bg_log(BG_LOG_ERROR, LOG_DOMAIN,
321
"No symbol the_plugin: %s",
325
ret->priv = ret->plugin->create();
328
return (bg_plugin_handle_t *)0;
332
static bg_plugin_handle_t *
333
load_plugin_lv(const char * name, int plugin_flags, const char * window_id)
335
bg_plugin_handle_t * ret;
336
ret = calloc(1, sizeof(*ret));
337
if(!bg_lv_load(ret, name, plugin_flags, window_id))
340
return (bg_plugin_handle_t*)0;
346
// #define BG_VIS_MSG_CB_MOTION // x, y, mask
347
// #define // x, y, button, mask
348
// #define BG_VIS_MSG_CB_BUTTON_REL // x, y, button, mask
351
static int ov_button_callback(void * data, int x, int y,
352
int button, int mask)
355
bg_visualizer_slave_t * s = data;
357
msg = bg_msg_queue_lock_write(s->cb_queue);
358
bg_msg_set_id(msg, BG_VIS_MSG_CB_BUTTON);
359
bg_msg_set_arg_int(msg, 0, x);
360
bg_msg_set_arg_int(msg, 1, y);
361
bg_msg_set_arg_int(msg, 2, button);
362
bg_msg_set_arg_int(msg, 3, mask);
363
bg_msg_queue_unlock_write(s->cb_queue);
367
static int ov_button_release_callback(void * data, int x, int y,
368
int button, int mask)
371
bg_visualizer_slave_t * s = data;
373
msg = bg_msg_queue_lock_write(s->cb_queue);
374
bg_msg_set_id(msg, BG_VIS_MSG_CB_BUTTON_REL);
375
bg_msg_set_arg_int(msg, 0, x);
376
bg_msg_set_arg_int(msg, 1, y);
377
bg_msg_set_arg_int(msg, 2, button);
378
bg_msg_set_arg_int(msg, 3, mask);
379
bg_msg_queue_unlock_write(s->cb_queue);
383
static int ov_motion_callback(void * data, int x, int y,
387
bg_visualizer_slave_t * s = data;
389
msg = bg_msg_queue_lock_write(s->cb_queue);
390
bg_msg_set_id(msg, BG_VIS_MSG_CB_MOTION);
391
bg_msg_set_arg_int(msg, 0, x);
392
bg_msg_set_arg_int(msg, 1, y);
393
bg_msg_set_arg_int(msg, 2, mask);
394
bg_msg_queue_unlock_write(s->cb_queue);
398
static bg_visualizer_slave_t *
399
bg_visualizer_slave_create(int argc, char ** argv)
402
bg_visualizer_slave_t * ret;
403
char * window_id = (char*)0;
404
char * plugin_module = (char*)0;
405
char * ov_module = (char*)0;
407
/* Handle arguments and load plugins */
411
if(!strcmp(argv[i], "-w"))
413
window_id = argv[i+1];
416
else if(!strcmp(argv[i], "-p"))
418
plugin_module = argv[i+1];
421
else if(!strcmp(argv[i], "-o"))
423
ov_module = argv[i+1];
431
bg_log(BG_LOG_ERROR, LOG_DOMAIN, "No window ID given");
432
return (bg_visualizer_slave_t *)0;
436
bg_log(BG_LOG_ERROR, LOG_DOMAIN, "No plugin given");
437
return (bg_visualizer_slave_t *)0;
440
ret = calloc(1, sizeof(*ret));
441
ret->audio_buffer = audio_buffer_create();
442
ret->window_id = window_id;
444
/* Create callbacks */
445
ret->cb.button_release_callback = ov_button_release_callback;
446
ret->cb.button_callback = ov_button_callback;
447
ret->cb.motion_callback = ov_motion_callback;
450
ret->cb_queue = bg_msg_queue_create();
452
pthread_mutex_init(&ret->stop_mutex,(pthread_mutexattr_t *)0);
453
pthread_mutex_init(&ret->running_mutex,(pthread_mutexattr_t *)0);
454
pthread_mutex_init(&ret->vis_mutex,(pthread_mutexattr_t *)0);
455
pthread_mutex_init(&ret->ov_mutex,(pthread_mutexattr_t *)0);
456
pthread_mutex_init(&ret->fps_mutex,(pthread_mutexattr_t *)0);
458
ret->timer = gavl_timer_create();
464
ret->video_cnv = gavl_video_converter_create();
466
ret->ov_handle = load_plugin_gmerlin(ov_module);
468
return (bg_visualizer_slave_t*)0;
470
ret->ov_plugin = (bg_ov_plugin_t*)ret->ov_handle->plugin;
472
if(ret->ov_plugin->set_callbacks)
473
ret->ov_plugin->set_callbacks(ret->ov_handle->priv,
476
ret->ov_plugin->set_window(ret->ov_handle->priv, ret->window_id);
479
ret->vis_api = BG_PLUGIN_API_GMERLIN;
482
if(!strncmp(plugin_module, "vis_lv_", 7))
485
ret->vis_handle = load_plugin_lv(plugin_module, BG_PLUGIN_VISUALIZE_FRAME, ret->window_id);
487
ret->vis_handle = load_plugin_lv(plugin_module, BG_PLUGIN_VISUALIZE_GL, ret->window_id);
488
ret->vis_api = BG_PLUGIN_API_LV;
493
load_plugin_gmerlin(plugin_module);
496
return (bg_visualizer_slave_t*)0;
498
ret->vis_plugin = (bg_visualization_plugin_t*)(ret->vis_handle->plugin);
500
if(ret->vis_plugin->set_callbacks)
501
ret->vis_plugin->set_callbacks(ret->vis_handle->priv, &ret->cb);
506
static void uload_plugin(bg_plugin_handle_t * h, bg_plugin_api_t api)
509
if(api == BG_PLUGIN_API_LV)
516
h->plugin->destroy(h->priv);
517
dlclose(h->dll_handle);
521
static void bg_visualizer_slave_destroy(bg_visualizer_slave_t * v)
523
pthread_mutex_destroy(&v->stop_mutex);
526
gavl_video_converter_destroy(v->video_cnv);
528
audio_buffer_destroy(v->audio_buffer);
529
gavl_timer_destroy(v->timer);
531
bg_msg_queue_destroy(v->cb_queue);
533
pthread_mutex_destroy(&v->running_mutex);
534
pthread_mutex_destroy(&v->fps_mutex);
535
pthread_mutex_destroy(&v->stop_mutex);
536
pthread_mutex_destroy(&v->ov_mutex);
537
pthread_mutex_destroy(&v->vis_mutex);
539
/* Close vis plugin */
540
v->vis_plugin->close(v->vis_handle->priv);
541
uload_plugin(v->vis_handle, v->vis_api);
543
/* Close OV Plugin */
546
if(v->video_frame_out)
548
if(v->ov_plugin->destroy_frame)
549
v->ov_plugin->destroy_frame(v->ov_handle->priv,
552
gavl_video_frame_destroy(v->video_frame_out);
553
v->video_frame_out = (gavl_video_frame_t*)0;
555
if(v->video_frame_in)
557
gavl_video_frame_destroy(v->video_frame_in);
558
v->video_frame_in = (gavl_video_frame_t*)0;
560
v->ov_plugin->close(v->ov_handle->priv);
561
uload_plugin(v->ov_handle, BG_PLUGIN_API_GMERLIN);
567
static void * video_thread_func(void * data)
570
bg_visualizer_slave_t * v;
571
gavl_audio_frame_t * audio_frame;
572
gavl_time_t diff_time, current_time;
573
float last_fps = -1.0;
576
v = (bg_visualizer_slave_t*)data;
578
pthread_mutex_lock(&v->running_mutex);
581
/* Check if we should stop */
582
pthread_mutex_lock(&v->stop_mutex);
583
do_stop = v->do_stop;
584
pthread_mutex_unlock(&v->stop_mutex);
589
pthread_mutex_lock(&v->vis_mutex);
591
/* Check if we should update audio */
593
audio_frame = audio_buffer_get(v->audio_buffer);
595
v->vis_plugin->update(v->vis_handle->priv, audio_frame);
600
v->vis_plugin->draw_frame(v->vis_handle->priv,
601
(gavl_video_frame_t*)0);
602
else if(v->do_convert_video)
604
v->vis_plugin->draw_frame(v->vis_handle->priv, v->video_frame_in);
605
gavl_video_convert(v->video_cnv, v->video_frame_in, v->video_frame_out);
608
v->vis_plugin->draw_frame(v->vis_handle->priv, v->video_frame_out);
610
pthread_mutex_unlock(&v->vis_mutex);
612
/* Wait until we can show the frame */
613
current_time = gavl_timer_get(v->timer);
615
diff_time = v->last_frame_time +
616
v->video_format_in.frame_duration - current_time;
618
if(diff_time > GAVL_TIME_SCALE / 1000)
619
gavl_time_delay(&diff_time);
625
pthread_mutex_lock(&v->ov_mutex);
626
v->ov_plugin->put_video(v->ov_handle->priv, v->video_frame_out);
627
frame_time = gavl_timer_get(v->timer);
629
v->ov_plugin->handle_events(v->ov_handle->priv);
630
pthread_mutex_unlock(&v->ov_mutex);
634
pthread_mutex_lock(&v->vis_mutex);
635
v->vis_plugin->show_frame(v->vis_handle->priv);
636
frame_time = gavl_timer_get(v->timer);
637
pthread_mutex_unlock(&v->vis_mutex);
639
if(v->last_frame_time < frame_time)
643
pthread_mutex_lock(&v->fps_mutex);
644
v->fps = (double)(GAVL_TIME_SCALE) /
645
(double)(frame_time - v->last_frame_time);
647
pthread_mutex_unlock(&v->fps_mutex);
651
pthread_mutex_lock(&v->fps_mutex);
652
v->fps = 0.95 * last_fps +
653
0.05 * (double)(GAVL_TIME_SCALE) /
654
(double)(frame_time - v->last_frame_time);
656
pthread_mutex_unlock(&v->fps_mutex);
659
v->last_frame_time = frame_time;
661
pthread_mutex_unlock(&v->running_mutex);
665
static int bg_visualizer_slave_stop(bg_visualizer_slave_t * v)
667
if(!pthread_mutex_trylock(&v->running_mutex))
669
pthread_mutex_unlock(&v->running_mutex);
675
pthread_mutex_lock(&v->stop_mutex);
677
pthread_mutex_unlock(&v->stop_mutex);
679
pthread_join(v->video_thread, (void**)0);
680
bg_log(BG_LOG_INFO, LOG_DOMAIN, "Joined thread");
681
gavl_timer_stop(v->timer);
685
static int bg_visualizer_slave_start(bg_visualizer_slave_t * v)
687
if(pthread_mutex_trylock(&v->running_mutex))
690
pthread_mutex_unlock(&v->running_mutex);
694
v->last_frame_time = 0;
695
gavl_timer_set(v->timer, 0);
696
gavl_timer_start(v->timer);
698
pthread_create(&v->video_thread, (pthread_attr_t*)0, video_thread_func, v);
699
bg_log(BG_LOG_INFO, LOG_DOMAIN, "Started thread");
704
bg_visualizer_slave_set_audio_format(bg_visualizer_slave_t * v,
705
const gavl_audio_format_t * format)
708
was_running = bg_visualizer_slave_stop(v);
709
pthread_mutex_lock(&v->audio_buffer->in_mutex);
711
gavl_audio_format_copy(&v->audio_format_in, format);
714
audio_buffer_init(v->audio_buffer, &v->audio_format_in, &v->audio_format_out);
715
pthread_mutex_unlock(&v->audio_buffer->in_mutex);
717
bg_visualizer_slave_start(v);
720
static void cleanup_plugin(bg_visualizer_slave_t * v)
724
static int init_plugin(bg_visualizer_slave_t * v)
726
gavl_audio_format_copy(&v->audio_format_out, &v->audio_format_in);
728
/* Set members, which might be missing */
729
v->video_format_in.pixel_width = 1;
730
v->video_format_in.pixel_height = 1;
732
/* Set video format */
733
gavl_video_format_copy(&v->video_format_in_real, &v->video_format_in);
735
/* Open visualizer plugin */
739
v->vis_plugin->open_ov(v->vis_handle->priv, &v->audio_format_out,
740
&v->video_format_in_real);
742
gavl_video_format_copy(&v->video_format_out, &v->video_format_in_real);
745
if(!v->ov_plugin->open(v->ov_handle->priv, &v->video_format_out, 0))
748
/* Initialize video converter */
750
v->do_convert_video =
751
gavl_video_converter_init(v->video_cnv, &v->video_format_in_real,
752
&v->video_format_out);
754
if(v->ov_plugin->create_frame)
755
v->video_frame_out = v->ov_plugin->create_frame(v->ov_handle->priv);
757
v->video_frame_out = gavl_video_frame_create(&v->video_format_out);
759
if(v->do_convert_video)
760
v->video_frame_in = gavl_video_frame_create(&v->video_format_in_real);
764
if(!v->vis_plugin->open_win(v->vis_handle->priv, &v->audio_format_out,
767
gavl_video_format_copy(&v->video_format_out, &v->video_format_in);
770
audio_buffer_init(v->audio_buffer, &v->audio_format_in, &v->audio_format_out);
775
static int msg_read_callback(void * priv, uint8_t * data, int len)
777
return read(STDIN_FILENO, data, len);
780
static int msg_write_callback(void * priv, const uint8_t * data, int len)
782
return write(STDOUT_FILENO, data, len);
785
static int write_message(msg)
788
// fprintf(stderr, "Write message slave...\n");
789
result = bg_msg_write(msg, msg_write_callback, NULL);
790
// fprintf(stderr, "Write message slave done %d\n", result);
794
static void flush_queue(bg_msg_queue_t * queue)
797
while((msg = bg_msg_queue_try_lock_read(queue)))
800
bg_msg_queue_unlock_read(queue);
805
int main(int argc, char ** argv)
807
gavl_audio_format_t audio_format;
808
gavl_audio_frame_t * audio_frame = (gavl_audio_frame_t *)0;
812
bg_visualizer_slave_t * s;
815
char * parameter_name = (char*)0;
816
bg_parameter_value_t parameter_value;
817
bg_msg_queue_t * log_queue;
819
bg_parameter_type_t parameter_type;
820
gavl_dsp_context_t * ctx;
824
ctx = gavl_dsp_context_create();
826
memset(¶meter_value, 0, sizeof(parameter_value));
828
if(isatty(fileno(stdin)))
830
printf("This program is not meant to be started from the commandline.\nThe official frontend API for visualizatons is in " PREFIX "/include/gmerlin/visualize.h\n");
834
log_queue = bg_msg_queue_create();
835
bg_log_set_dest(log_queue);
837
s = bg_visualizer_slave_create(argc, argv);
839
msg = bg_msg_create();
845
// fprintf(stderr, "Read message slave...\n");
846
result = bg_msg_read(msg, msg_read_callback, (void*)0);
847
// fprintf(stderr, "Read message slave done %d\n", result);
851
switch(bg_msg_get_id(msg))
853
case BG_VIS_MSG_AUDIO_FORMAT:
854
bg_msg_get_arg_audio_format(msg, 0, &audio_format, &big_endian);
856
bg_visualizer_slave_set_audio_format(s, &audio_format);
858
gavl_audio_frame_destroy(audio_frame);
859
audio_frame = gavl_audio_frame_create(&audio_format);
861
case BG_VIS_MSG_AUDIO_DATA:
862
bg_msg_read_audio_frame(ctx,
867
(void*)0, big_endian);
869
if(!pthread_mutex_trylock(&s->running_mutex))
871
pthread_mutex_unlock(&s->running_mutex);
875
audio_buffer_put(s->audio_buffer,
878
case BG_VIS_MSG_VIS_PARAM:
879
bg_msg_get_parameter(msg,
884
pthread_mutex_lock(&s->vis_mutex);
885
s->vis_plugin->common.set_parameter(s->vis_handle->priv,
888
pthread_mutex_unlock(&s->vis_mutex);
891
free(parameter_name);
892
parameter_name = (char*)0;
893
bg_parameter_value_free(¶meter_value,
898
case BG_VIS_MSG_OV_PARAM:
899
bg_msg_get_parameter(msg,
903
pthread_mutex_lock(&s->ov_mutex);
906
s->ov_plugin->common.set_parameter(s->ov_handle->priv,
909
pthread_mutex_unlock(&s->ov_mutex);
912
free(parameter_name);
913
parameter_name = (char*)0;
914
bg_parameter_value_free(¶meter_value,
918
case BG_VIS_MSG_GAIN:
919
arg_f = bg_msg_get_arg_float(msg, 0);
920
audio_buffer_set_gain(s->audio_buffer, arg_f);
923
s->video_format_in.timescale = GAVL_TIME_SCALE;
924
s->video_format_in.frame_duration =
925
(int)(GAVL_TIME_SCALE / bg_msg_get_arg_float(msg, 0));
927
case BG_VIS_MSG_IMAGE_SIZE:
928
s->video_format_in.image_width =
929
bg_msg_get_arg_int(msg, 0);
930
s->video_format_in.image_height =
931
bg_msg_get_arg_int(msg, 1);
933
s->video_format_in.frame_width =
934
s->video_format_in.image_width;
935
s->video_format_in.frame_height =
936
s->video_format_in.image_height;
938
case BG_VIS_MSG_START:
940
bg_log(BG_LOG_ERROR, LOG_DOMAIN, "Starting visualization failed");
942
bg_visualizer_slave_start(s);
944
case BG_VIS_MSG_QUIT:
947
case BG_VIS_MSG_TELL:
948
flush_queue(log_queue);
949
flush_queue(s->cb_queue);
954
bg_msg_set_id(msg, BG_VIS_SLAVE_MSG_FPS);
955
pthread_mutex_lock(&s->fps_mutex);
956
bg_msg_set_arg_float(msg, 0, s->fps);
957
pthread_mutex_unlock(&s->fps_mutex);
963
bg_msg_set_id(msg, BG_VIS_SLAVE_MSG_END);
969
bg_visualizer_slave_stop(s);
972
bg_visualizer_slave_destroy(s);
975
gavl_dsp_context_destroy(ctx);