1 /*****************************************************************
2 * gmerlin - a general purpose multimedia framework and applications
3 *
4 * Copyright (c) 2001 - 2011 Members of the Gmerlin project
5 * gmerlin-general@lists.sourceforge.net
6 * http://gmerlin.sourceforge.net
7 *
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.
12 *
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.
17 *
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 * *****************************************************************/
21
22 #include <signal.h>
23
24 #include <config.h>
25 #include <gmerlin/recorder.h>
26 #include <gmerlin/pluginregistry.h>
27 #include <gavl/gavl.h>
28 #include <gmerlin/utils.h>
29 #include <gmerlin/cmdline.h>
30 #include <gmerlin/log.h>
31 #include <gmerlin/translation.h>
32
33 static bg_recorder_t * recorder;
34
35 static bg_cfg_section_t * audio_section;
36 static bg_cfg_section_t * video_section;
37 static bg_cfg_section_t * metadata_section;
38 static bg_cfg_section_t * encoder_section;
39 static bg_cfg_section_t * af_section;
40 static bg_cfg_section_t * vf_section;
41 static bg_cfg_section_t * vm_section;
42 static bg_cfg_section_t * output_section;
43
44 const bg_parameter_info_t * audio_parameters;
45 const bg_parameter_info_t * video_parameters;
46 const bg_parameter_info_t * af_parameters;
47 const bg_parameter_info_t * vf_parameters;
48 const bg_parameter_info_t * vm_parameters;
49 const bg_parameter_info_t * output_parameters;
50
51 const bg_parameter_info_t * metadata_parameters;
52 const bg_parameter_info_t * encoder_parameters;
53
54
55 static bg_plugin_registry_t * plugin_reg;
56 static bg_cfg_registry_t * cfg_reg;
57
58 static int do_record = 0;
59
60 static int do_syslog = 0;
61
62 #define DELAY_TIME 50
63 #define PING_INTERVAL 20
64
65 int got_sigint = 0;
66
sigint_handler(int sig)67 static void sigint_handler(int sig)
68 {
69 fprintf(stderr, "\nCTRL+C caught\n");
70 got_sigint = 1;
71 }
72
set_sigint_handler()73 static void set_sigint_handler()
74 {
75 struct sigaction sa;
76 sa.sa_flags = 0;
77 sigemptyset(&sa.sa_mask);
78 sa.sa_handler = sigint_handler;
79 if (sigaction(SIGINT, &sa, NULL) == -1)
80 {
81 fprintf(stderr, "sigaction failed\n");
82 }
83 }
84
opt_aud(void * data,int * argc,char *** _argv,int arg)85 static void opt_aud(void * data, int * argc, char *** _argv, int arg)
86 {
87 if(arg >= *argc)
88 {
89 fprintf(stderr, "Option -aud requires an argument\n");
90 exit(-1);
91 }
92 if(!bg_cmdline_apply_options(audio_section,
93 bg_recorder_set_audio_parameter,
94 recorder,
95 audio_parameters,
96 (*_argv)[arg]))
97 exit(-1);
98 bg_cmdline_remove_arg(argc, _argv, arg);
99 }
100
opt_af(void * data,int * argc,char *** _argv,int arg)101 static void opt_af(void * data, int * argc, char *** _argv, int arg)
102 {
103 if(arg >= *argc)
104 {
105 fprintf(stderr, "Option -af requires an argument\n");
106 exit(-1);
107 }
108 if(!bg_cmdline_apply_options(audio_section,
109 bg_recorder_set_audio_filter_parameter,
110 recorder,
111 af_parameters,
112 (*_argv)[arg]))
113 exit(-1);
114 bg_cmdline_remove_arg(argc, _argv, arg);
115 }
116
opt_vid(void * data,int * argc,char *** _argv,int arg)117 static void opt_vid(void * data, int * argc, char *** _argv, int arg)
118 {
119 if(arg >= *argc)
120 {
121 fprintf(stderr, "Option -vid requires an argument\n");
122 exit(-1);
123 }
124 if(!bg_cmdline_apply_options(video_section,
125 bg_recorder_set_video_parameter,
126 recorder,
127 video_parameters,
128 (*_argv)[arg]))
129 exit(-1);
130 bg_cmdline_remove_arg(argc, _argv, arg);
131 }
132
opt_vf(void * data,int * argc,char *** _argv,int arg)133 static void opt_vf(void * data, int * argc, char *** _argv, int arg)
134 {
135 if(arg >= *argc)
136 {
137 fprintf(stderr, "Option -vf requires an argument\n");
138 exit(-1);
139 }
140 if(!bg_cmdline_apply_options(video_section,
141 bg_recorder_set_video_filter_parameter,
142 recorder,
143 vf_parameters,
144 (*_argv)[arg]))
145 exit(-1);
146 bg_cmdline_remove_arg(argc, _argv, arg);
147 }
148
opt_vm(void * data,int * argc,char *** _argv,int arg)149 static void opt_vm(void * data, int * argc, char *** _argv, int arg)
150 {
151 if(arg >= *argc)
152 {
153 fprintf(stderr, "Option -vm requires an argument\n");
154 exit(-1);
155 }
156 if(!bg_cmdline_apply_options(video_section,
157 bg_recorder_set_video_monitor_parameter,
158 recorder,
159 vm_parameters,
160 (*_argv)[arg]))
161 exit(-1);
162 bg_cmdline_remove_arg(argc, _argv, arg);
163 }
164
opt_m(void * data,int * argc,char *** _argv,int arg)165 static void opt_m(void * data, int * argc, char *** _argv, int arg)
166 {
167 if(arg >= *argc)
168 {
169 fprintf(stderr, "Option -m requires an argument\n");
170 exit(-1);
171 }
172 if(!bg_cmdline_apply_options(metadata_section,
173 bg_recorder_set_metadata_parameter,
174 recorder,
175 metadata_parameters,
176 (*_argv)[arg]))
177 exit(-1);
178 bg_cmdline_remove_arg(argc, _argv, arg);
179 }
180
opt_r(void * data,int * argc,char *** _argv,int arg)181 static void opt_r(void * data, int * argc, char *** _argv, int arg)
182 {
183 do_record = 1;
184 }
185
opt_enc(void * data,int * argc,char *** _argv,int arg)186 static void opt_enc(void * data, int * argc, char *** _argv, int arg)
187 {
188 if(arg >= *argc)
189 {
190 fprintf(stderr, "Option -enc requires an argument\n");
191 exit(-1);
192 }
193 if(!bg_cmdline_apply_options(encoder_section,
194 /* bg_recorder_set_metadata_parameter */ NULL,
195 /* recorder */ NULL,
196 encoder_parameters,
197 (*_argv)[arg]))
198 exit(-1);
199 bg_cmdline_remove_arg(argc, _argv, arg);
200 }
201
opt_o(void * data,int * argc,char *** _argv,int arg)202 static void opt_o(void * data, int * argc, char *** _argv, int arg)
203 {
204 if(arg >= *argc)
205 {
206 fprintf(stderr, "Option -o requires an argument\n");
207 exit(-1);
208 }
209 if(!bg_cmdline_apply_options(encoder_section,
210 bg_recorder_set_output_parameter,
211 recorder,
212 output_parameters,
213 (*_argv)[arg]))
214 exit(-1);
215 bg_cmdline_remove_arg(argc, _argv, arg);
216 }
217
opt_syslog(void * data,int * argc,char *** _argv,int arg)218 static void opt_syslog(void * data, int * argc, char *** _argv, int arg)
219 {
220 if(arg >= *argc)
221 {
222 fprintf(stderr, "Option -syslog requires an argument\n");
223 exit(-1);
224 }
225 bg_log_syslog_init((*_argv)[arg]);
226 do_syslog = 1;
227 bg_cmdline_remove_arg(argc, _argv, arg);
228 }
229
230 static bg_cmdline_arg_t global_options[] =
231 {
232 {
233 .arg = "-aud",
234 .help_arg = "<audio_options>",
235 .help_string = "Set audio recording options",
236 .callback = opt_aud,
237 },
238 {
239 .arg = "-vid",
240 .help_arg = "<video_options>",
241 .help_string = "Set video recording options",
242 .callback = opt_vid,
243 },
244 {
245 .arg = "-af",
246 .help_arg = "<audio filter options>",
247 .help_string = "Set audio filter options",
248 .callback = opt_af,
249 },
250 {
251 .arg = "-vf",
252 .help_arg = "<video filter options>",
253 .help_string = "Set video filter options",
254 .callback = opt_vf,
255 },
256 {
257 .arg = "-vm",
258 .help_arg = "<video monitor options>",
259 .help_string = "Set video monitor options",
260 .callback = opt_vm,
261 },
262 {
263 .arg = "-m",
264 .help_arg = "<metadata_options>",
265 .help_string = "Set metadata options",
266 .callback = opt_m,
267 },
268 {
269 .arg = "-enc",
270 .help_arg = "<encoding_options>",
271 .help_string = "Set encoding options",
272 .callback = opt_enc,
273
274 },
275 {
276 .arg = "-o",
277 .help_arg = "<output_options>",
278 .help_string = "Set output options",
279 .callback = opt_o,
280
281 },
282 {
283 .arg = "-r",
284 .help_string = "Record to file",
285 .callback = opt_r,
286 },
287 {
288 .arg = "-syslog",
289 .help_arg = "<name>",
290 .help_string = "Set log messages to syslog",
291 .callback = opt_syslog,
292 },
293 {
294 /* End */
295 }
296 };
297
update_global_options()298 static void update_global_options()
299 {
300 global_options[0].parameters = audio_parameters;
301 global_options[1].parameters = video_parameters;
302 global_options[2].parameters = af_parameters;
303 global_options[3].parameters = vf_parameters;
304 global_options[4].parameters = vm_parameters;
305 global_options[5].parameters = metadata_parameters;
306 global_options[6].parameters = encoder_parameters;
307 global_options[7].parameters = output_parameters;
308 }
309
310 const bg_cmdline_app_data_t app_data =
311 {
312 .package = PACKAGE,
313 .version = VERSION,
314 .name = "gmerlin-record",
315 .synopsis = TRS("[options]\n"),
316 .help_before = TRS("Commandline recorder\n"),
317 .args = (bg_cmdline_arg_array_t[]) { { TRS("Options"), global_options },
318 { } },
319 .files = (bg_cmdline_ext_doc_t[])
320 { { "~/.gmerlin/plugins.xml",
321 TRS("Cache of the plugin registry (shared by all applicatons)") },
322 { "~/.gmerlin/generic/config.xml",
323 TRS("Default plugin parameters are read from there. Use gmerlin_plugincfg to change them.") },
324 { /* End */ }
325 },
326
327 };
328
329
330
main(int argc,char ** argv)331 int main(int argc, char ** argv)
332 {
333 bg_cfg_section_t * cfg_section;
334 char * tmp_path;
335 int timeout_counter = 0;
336
337 gavl_time_t delay_time = DELAY_TIME * 1000;
338
339 set_sigint_handler();
340
341 /* We must initialize the random number generator if we want the
342 Vorbis encoder to work */
343 srand(time(NULL));
344
345 /* Create plugin regsitry */
346 cfg_reg = bg_cfg_registry_create();
347 tmp_path = bg_search_file_read("generic", "config.xml");
348 bg_cfg_registry_load(cfg_reg, tmp_path);
349 if(tmp_path)
350 free(tmp_path);
351
352 cfg_section = bg_cfg_registry_find_section(cfg_reg, "plugins");
353 plugin_reg = bg_plugin_registry_create(cfg_section);
354
355 recorder = bg_recorder_create(plugin_reg);
356
357 /* Create config sections */
358
359 audio_parameters = bg_recorder_get_audio_parameters(recorder);
360 audio_section =
361 bg_cfg_section_create_from_parameters("audio", audio_parameters);
362
363 video_parameters = bg_recorder_get_video_parameters(recorder);
364 video_section =
365 bg_cfg_section_create_from_parameters("video", video_parameters);
366
367 af_parameters = bg_recorder_get_audio_filter_parameters(recorder);
368 af_section =
369 bg_cfg_section_create_from_parameters("audio_filters", af_parameters);
370
371 vf_parameters = bg_recorder_get_video_filter_parameters(recorder);
372 vf_section =
373 bg_cfg_section_create_from_parameters("video_filters", vf_parameters);
374
375 vm_parameters = bg_recorder_get_video_monitor_parameters(recorder);
376 vm_section =
377 bg_cfg_section_create_from_parameters("video_monitor", vm_parameters);
378
379 metadata_parameters = bg_recorder_get_metadata_parameters(recorder);
380 metadata_section =
381 bg_cfg_section_create_from_parameters("metadata", metadata_parameters);
382
383 encoder_parameters = bg_recorder_get_encoder_parameters(recorder);
384
385 encoder_section =
386 bg_cfg_section_create_from_parameters("encoder", encoder_parameters);
387
388 output_parameters = bg_recorder_get_output_parameters(recorder);
389 output_section =
390 bg_cfg_section_create_from_parameters("output", output_parameters);
391
392 update_global_options();
393
394 /* Apply default options */
395
396 bg_cfg_section_apply(audio_section, audio_parameters,
397 bg_recorder_set_audio_parameter, recorder);
398 bg_cfg_section_apply(video_section, video_parameters,
399 bg_recorder_set_video_parameter, recorder);
400 bg_cfg_section_apply(af_section, af_parameters,
401 bg_recorder_set_audio_filter_parameter, recorder);
402 bg_cfg_section_apply(vf_section, vf_parameters,
403 bg_recorder_set_video_filter_parameter, recorder);
404 bg_cfg_section_apply(vm_section, vm_parameters,
405 bg_recorder_set_video_monitor_parameter, recorder);
406 bg_cfg_section_apply(metadata_section, metadata_parameters,
407 bg_recorder_set_metadata_parameter, recorder);
408 bg_cfg_section_apply(output_section, output_parameters,
409 bg_recorder_set_output_parameter, recorder);
410
411 /* Get commandline options */
412 bg_cmdline_init(&app_data);
413 bg_cmdline_parse(global_options, &argc, &argv, NULL);
414
415 /* Set encoding options */
416 bg_recorder_set_encoder_section(recorder, encoder_section);
417
418 bg_recorder_record(recorder, do_record);
419 bg_recorder_run(recorder);
420
421 while(1)
422 {
423 if(!timeout_counter)
424 {
425 if(!bg_recorder_ping(recorder))
426 break;
427 }
428
429 if(got_sigint)
430 break;
431
432 timeout_counter++;
433 if(timeout_counter >= PING_INTERVAL)
434 timeout_counter = 0;
435
436 if(do_syslog)
437 bg_log_syslog_flush();
438
439 gavl_time_delay(&delay_time);
440 }
441
442 bg_recorder_destroy(recorder);
443 return 0;
444 }
445