1 /*
2 * Copyright (C) 2000-2020 the xine project
3 *
4 * This file is part of xine, a free video player.
5 *
6 * xine is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * xine is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 *
20 * convenience/abstraction layer, functions to implement
21 * libxine's public interface
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <sys/types.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <pthread.h>
32 #include <stdarg.h>
33 #if defined (__linux__) || defined (__GLIBC__)
34 #include <endian.h>
35 #elif defined (__FreeBSD__)
36 #include <machine/endian.h>
37 #endif
38
39 #include <xine/xine_internal.h>
40 #include <xine/audio_out.h>
41 #include <xine/video_out.h>
42 #include <xine/demux.h>
43 #include <xine/post.h>
44
45 #include "xine_private.h"
46
47 /*
48 * version information / checking
49 */
50
xine_get_version_string(void)51 const char *xine_get_version_string(void) {
52 return VERSION
53 #ifndef NDEBUG
54 "[DEBUG]"
55 #endif
56 ;
57 }
58
xine_get_version(int * major,int * minor,int * sub)59 void xine_get_version (int *major, int *minor, int *sub) {
60 *major = XINE_MAJOR;
61 *minor = XINE_MINOR;
62 *sub = XINE_SUB;
63 }
64
xine_check_version(int major,int minor,int sub)65 int xine_check_version(int major, int minor, int sub) {
66
67 if((XINE_MAJOR > major) ||
68 ((XINE_MAJOR == major) && (XINE_MINOR > minor)) ||
69 ((XINE_MAJOR == major) && (XINE_MINOR == minor) && (XINE_SUB >= sub)))
70 return 1;
71
72 return 0;
73 }
74
75 /*
76 * public config object access functions
77 */
78
xine_config_register_string(xine_t * self,const char * key,const char * def_value,const char * description,const char * help,int exp_level,xine_config_cb_t changed_cb,void * cb_data)79 const char* xine_config_register_string (xine_t *self,
80 const char *key,
81 const char *def_value,
82 const char *description,
83 const char *help,
84 int exp_level,
85 xine_config_cb_t changed_cb,
86 void *cb_data) {
87
88 return self->config->register_string (self->config,
89 key,
90 def_value,
91 description,
92 help,
93 exp_level,
94 changed_cb,
95 cb_data);
96
97 }
98
xine_config_register_filename(xine_t * self,const char * key,const char * def_value,int req_type,const char * description,const char * help,int exp_level,xine_config_cb_t changed_cb,void * cb_data)99 const char* xine_config_register_filename (xine_t *self,
100 const char *key,
101 const char *def_value,
102 int req_type,
103 const char *description,
104 const char *help,
105 int exp_level,
106 xine_config_cb_t changed_cb,
107 void *cb_data) {
108
109 return self->config->register_filename (self->config,
110 key, def_value, req_type,
111 description, help, exp_level,
112 changed_cb, cb_data);
113 }
114
xine_config_register_range(xine_t * self,const char * key,int def_value,int min,int max,const char * description,const char * help,int exp_level,xine_config_cb_t changed_cb,void * cb_data)115 int xine_config_register_range (xine_t *self,
116 const char *key,
117 int def_value,
118 int min, int max,
119 const char *description,
120 const char *help,
121 int exp_level,
122 xine_config_cb_t changed_cb,
123 void *cb_data) {
124 return self->config->register_range (self->config,
125 key, def_value, min, max,
126 description, help, exp_level,
127 changed_cb, cb_data);
128 }
129
130
xine_config_register_enum(xine_t * self,const char * key,int def_value,char ** values,const char * description,const char * help,int exp_level,xine_config_cb_t changed_cb,void * cb_data)131 int xine_config_register_enum (xine_t *self,
132 const char *key,
133 int def_value,
134 char **values,
135 const char *description,
136 const char *help,
137 int exp_level,
138 xine_config_cb_t changed_cb,
139 void *cb_data) {
140 return self->config->register_enum (self->config,
141 key, def_value, values,
142 description, help, exp_level,
143 changed_cb, cb_data);
144 }
145
146
xine_config_register_num(xine_t * self,const char * key,int def_value,const char * description,const char * help,int exp_level,xine_config_cb_t changed_cb,void * cb_data)147 int xine_config_register_num (xine_t *self,
148 const char *key,
149 int def_value,
150 const char *description,
151 const char *help,
152 int exp_level,
153 xine_config_cb_t changed_cb,
154 void *cb_data) {
155 return self->config->register_num (self->config,
156 key, def_value,
157 description, help, exp_level,
158 changed_cb, cb_data);
159 }
160
161
xine_config_register_bool(xine_t * self,const char * key,int def_value,const char * description,const char * help,int exp_level,xine_config_cb_t changed_cb,void * cb_data)162 int xine_config_register_bool (xine_t *self,
163 const char *key,
164 int def_value,
165 const char *description,
166 const char *help,
167 int exp_level,
168 xine_config_cb_t changed_cb,
169 void *cb_data) {
170 return self->config->register_bool (self->config,
171 key, def_value,
172 description, help, exp_level,
173 changed_cb, cb_data);
174 }
175
xine_config_unregister_callbacks(xine_t * self,const char * key,xine_config_cb_t changed_cb,void * cb_data,size_t cb_data_size)176 int xine_config_unregister_callbacks (xine_t *self,
177 const char *key, xine_config_cb_t changed_cb, void *cb_data, size_t cb_data_size) {
178 /* avoid misuse */
179 if (!key && !changed_cb && !cb_data)
180 return 0;
181 if (!self)
182 return 0;
183 if (!self->config)
184 return 0;
185 return self->config->unregister_callbacks (self->config, key, changed_cb, cb_data, cb_data_size);
186 }
187
xine_config_lookup_num(xine_t * this,const char * key,int def_value)188 int xine_config_lookup_num(xine_t *this, const char *key, int def_value) {
189 return this->config->lookup_num(this->config, key, def_value);
190 }
191
xine_config_lookup_string(xine_t * this,const char * key)192 char *xine_config_lookup_string(xine_t *this, const char *key) {
193 return this->config->lookup_string(this->config, key);
194 }
195
xine_config_free_string(xine_t * this,char ** value)196 void xine_config_free_string(xine_t *this, char **value) {
197 this->config->free_string(this->config, value);
198 }
199
200 /*
201 * helper function:
202 *
203 * copy current config entry data to user-provided memory
204 * and return status
205 */
206
config_get_current_entry(xine_t * this,xine_cfg_entry_t * entry)207 static int config_get_current_entry (xine_t *this, xine_cfg_entry_t *entry) {
208
209 config_values_t *config = this->config;
210
211 if (!config->cur)
212 return 0;
213
214 entry->key = config->cur->key;
215 entry->type = config->cur->type;
216 entry->str_value = config->cur->str_value;
217 entry->str_default = config->cur->str_default;
218 entry->num_value = config->cur->num_value;
219 entry->num_default = config->cur->num_default;
220 entry->range_min = config->cur->range_min;
221 entry->range_max = config->cur->range_max;
222 entry->enum_values = config->cur->enum_values;
223
224 entry->description = config->cur->description;
225 entry->help = config->cur->help;
226 entry->callback = config->cur->callback;
227 entry->callback_data = config->cur->callback_data;
228 entry->exp_level = config->cur->exp_level;
229
230 return 1;
231 }
232
233 /*
234 * get first config item
235 */
xine_config_get_first_entry(xine_t * this,xine_cfg_entry_t * entry)236 int xine_config_get_first_entry (xine_t *this, xine_cfg_entry_t *entry) {
237 int result;
238 config_values_t *config = this->config;
239
240 pthread_mutex_lock(&config->config_lock);
241 config->cur = config->first;
242
243 /* do not hand out unclaimed entries */
244 while (config->cur && config->cur->type == XINE_CONFIG_TYPE_UNKNOWN)
245 config->cur = config->cur->next;
246 result = config_get_current_entry (this, entry);
247 pthread_mutex_unlock(&config->config_lock);
248
249 return result;
250 }
251
252
253 /*
254 * get next config item (iterate through the items)
255 * this will return NULL when called after returning the last item
256 */
xine_config_get_next_entry(xine_t * this,xine_cfg_entry_t * entry)257 int xine_config_get_next_entry (xine_t *this, xine_cfg_entry_t *entry) {
258 int result;
259 config_values_t *config = this->config;
260
261 pthread_mutex_lock(&config->config_lock);
262
263 if (!config->cur) {
264 pthread_mutex_unlock(&config->config_lock);
265 return (xine_config_get_first_entry(this, entry));
266 }
267
268 /* do not hand out unclaimed entries */
269 do {
270 config->cur = config->cur->next;
271 } while (config->cur && config->cur->type == XINE_CONFIG_TYPE_UNKNOWN);
272 result = config_get_current_entry (this, entry);
273 pthread_mutex_unlock(&config->config_lock);
274
275 return result;
276 }
277
278
279 /*
280 * search for a config entry by key
281 */
282
xine_config_lookup_entry(xine_t * this,const char * key,xine_cfg_entry_t * entry)283 int xine_config_lookup_entry (xine_t *this, const char *key,
284 xine_cfg_entry_t *entry) {
285 int result;
286 config_values_t *config = this->config;
287
288 pthread_mutex_lock(&config->config_lock);
289 /* safe because of the mutex is recursive */
290 config->cur = config->lookup_entry (config, key);
291
292 /* do not hand out unclaimed entries */
293 if (config->cur && config->cur->type == XINE_CONFIG_TYPE_UNKNOWN)
294 config->cur = NULL;
295 result = config_get_current_entry (this, entry);
296 pthread_mutex_unlock(&config->config_lock);
297
298 return result;
299 }
300
301
302 /*
303 * update a config entry (which was returned from lookup_entry() )
304 */
xine_config_update_entry(xine_t * this,const xine_cfg_entry_t * entry)305 void xine_config_update_entry (xine_t *this, const xine_cfg_entry_t *entry) {
306
307 switch (entry->type) {
308 case XINE_CONFIG_TYPE_RANGE:
309 case XINE_CONFIG_TYPE_ENUM:
310 case XINE_CONFIG_TYPE_NUM:
311 case XINE_CONFIG_TYPE_BOOL:
312 this->config->update_num (this->config, entry->key, entry->num_value);
313 break;
314
315 case XINE_CONFIG_TYPE_STRING:
316 this->config->update_string (this->config, entry->key, entry->str_value);
317 break;
318
319 default:
320 xprintf (this, XINE_VERBOSITY_DEBUG,
321 "xine_interface: error, unknown config entry type %d\n", entry->type);
322 break;
323 }
324 }
325
326
xine_config_reset(xine_t * this)327 void xine_config_reset (xine_t *this) {
328
329 config_values_t *config = this->config;
330 cfg_entry_t *entry;
331
332 pthread_mutex_lock(&config->config_lock);
333 config->cur = NULL;
334
335 entry = config->first;
336 while (entry) {
337 cfg_entry_t *next;
338 next = entry->next;
339 free (entry);
340 entry = next;
341 }
342
343 config->first = NULL;
344 config->last = NULL;
345 pthread_mutex_unlock(&config->config_lock);
346 }
347
xine_port_send_gui_data(xine_video_port_t * vo,int type,void * data)348 int xine_port_send_gui_data (xine_video_port_t *vo,
349 int type, void *data) {
350
351 return vo->driver->gui_data_exchange (vo->driver,
352 type, data);
353 }
354
send_audio_amp_event_internal(xine_stream_private_t * stream)355 static void send_audio_amp_event_internal (xine_stream_private_t *stream) {
356 xine_event_t event;
357 xine_audio_level_data_t data;
358
359 data.left
360 = data.right
361 = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_AMP);
362 data.mute
363 = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_AMP_MUTE);
364
365 event.type = XINE_EVENT_AUDIO_AMP_LEVEL;
366 event.data = &data;
367 event.data_length = sizeof (data);
368
369 xine_event_send (&stream->s, &event);
370 }
371
xine_set_param(xine_stream_t * s,int param,int value)372 void xine_set_param (xine_stream_t *s, int param, int value) {
373 xine_stream_private_t *stream = (xine_stream_private_t *)s;
374 xine_private_t *xine;
375 /* Avoid crashing */
376 if ( ! stream ) {
377 lprintf ("xine_interface: xine_set_param called with NULL stream.\n");
378 return;
379 }
380 xine = (xine_private_t *)stream->s.xine;
381
382 switch (param) {
383 case XINE_PARAM_SPEED:
384 pthread_mutex_lock (&stream->frontend_lock);
385 _x_set_speed (&stream->s, value);
386 pthread_mutex_unlock (&stream->frontend_lock);
387 break;
388
389 case XINE_PARAM_FINE_SPEED:
390 pthread_mutex_lock (&stream->frontend_lock);
391 _x_set_fine_speed (&stream->s, value);
392 pthread_mutex_unlock (&stream->frontend_lock);
393 break;
394
395 case XINE_PARAM_AV_OFFSET:
396 stream->s.metronom->set_option (stream->s.metronom, METRONOM_AV_OFFSET, value);
397 break;
398
399 case XINE_PARAM_SPU_OFFSET:
400 stream->s.metronom->set_option (stream->s.metronom, METRONOM_SPU_OFFSET, value);
401 break;
402
403 case XINE_PARAM_AUDIO_CHANNEL_LOGICAL:
404 pthread_mutex_lock (&stream->frontend_lock);
405 if (value < -2)
406 value = -2;
407 stream->audio_channel_user = value;
408 pthread_mutex_unlock (&stream->frontend_lock);
409 break;
410
411 case XINE_PARAM_SPU_CHANNEL:
412 _x_select_spu_channel (&stream->s, value);
413 break;
414
415 case XINE_PARAM_VIDEO_CHANNEL:
416 pthread_mutex_lock (&stream->frontend_lock);
417 if (value<0)
418 value = 0;
419 stream->video_channel = value;
420 pthread_mutex_unlock (&stream->frontend_lock);
421 break;
422
423 case XINE_PARAM_AUDIO_VOLUME:
424 xine->port_ticket->acquire (xine->port_ticket, 1);
425 if (stream->s.audio_out)
426 stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_MIXER_VOL, value);
427 xine->port_ticket->release (xine->port_ticket, 1);
428 break;
429
430 case XINE_PARAM_AUDIO_MUTE:
431 xine->port_ticket->acquire (xine->port_ticket, 1);
432 if (stream->s.audio_out)
433 stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_MUTE_VOL, value);
434 xine->port_ticket->release (xine->port_ticket, 1);
435 break;
436
437 case XINE_PARAM_AUDIO_COMPR_LEVEL:
438 xine->port_ticket->acquire (xine->port_ticket, 1);
439 if (stream->s.audio_out)
440 stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_COMPRESSOR, value);
441 xine->port_ticket->release (xine->port_ticket, 1);
442 break;
443
444 case XINE_PARAM_AUDIO_AMP_LEVEL:
445 xine->port_ticket->acquire (xine->port_ticket, 1);
446 if (stream->s.audio_out) {
447 int old_value = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_AMP);
448 if (old_value != stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_AMP, value))
449 send_audio_amp_event_internal (stream);
450 }
451 xine->port_ticket->release(xine->port_ticket, 1);
452 break;
453
454 case XINE_PARAM_AUDIO_AMP_MUTE:
455 xine->port_ticket->acquire (xine->port_ticket, 1);
456 if (stream->s.audio_out) {
457 int old_value = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_AMP_MUTE);
458 if (old_value != stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_AMP_MUTE, value))
459 send_audio_amp_event_internal(stream);
460 }
461 xine->port_ticket->release (xine->port_ticket, 1);
462 break;
463
464 case XINE_PARAM_AUDIO_CLOSE_DEVICE:
465 xine->port_ticket->acquire (xine->port_ticket, 1);
466 if (stream->s.audio_out)
467 stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_CLOSE_DEVICE, value);
468 xine->port_ticket->release (xine->port_ticket, 1);
469 break;
470
471 case XINE_PARAM_EQ_30HZ:
472 case XINE_PARAM_EQ_60HZ:
473 case XINE_PARAM_EQ_125HZ:
474 case XINE_PARAM_EQ_250HZ:
475 case XINE_PARAM_EQ_500HZ:
476 case XINE_PARAM_EQ_1000HZ:
477 case XINE_PARAM_EQ_2000HZ:
478 case XINE_PARAM_EQ_4000HZ:
479 case XINE_PARAM_EQ_8000HZ:
480 case XINE_PARAM_EQ_16000HZ:
481 xine->port_ticket->acquire (xine->port_ticket, 1);
482 if (stream->s.audio_out)
483 stream->s.audio_out->set_property (stream->s.audio_out,
484 param - XINE_PARAM_EQ_30HZ + AO_PROP_EQ_30HZ,
485 value);
486 xine->port_ticket->release (xine->port_ticket, 1);
487 break;
488
489 case XINE_PARAM_VERBOSITY:
490 stream->s.xine->verbosity = value;
491 break;
492
493 case XINE_PARAM_VO_SHARPNESS:
494 case XINE_PARAM_VO_NOISE_REDUCTION:
495 case XINE_PARAM_VO_HUE:
496 case XINE_PARAM_VO_SATURATION:
497 case XINE_PARAM_VO_CONTRAST:
498 case XINE_PARAM_VO_BRIGHTNESS:
499 case XINE_PARAM_VO_GAMMA:
500 case XINE_PARAM_VO_DEINTERLACE:
501 case XINE_PARAM_VO_ASPECT_RATIO:
502 case XINE_PARAM_VO_ZOOM_X:
503 case XINE_PARAM_VO_ZOOM_Y:
504 case XINE_PARAM_VO_TVMODE:
505 case XINE_PARAM_VO_CROP_LEFT:
506 case XINE_PARAM_VO_CROP_RIGHT:
507 case XINE_PARAM_VO_CROP_TOP:
508 case XINE_PARAM_VO_CROP_BOTTOM:
509 xine->port_ticket->acquire (xine->port_ticket, 1);
510 stream->s.video_out->set_property (stream->s.video_out, param, value);
511 xine->port_ticket->release (xine->port_ticket, 1);
512 break;
513
514 case XINE_PARAM_VO_SINGLE_STEP:
515 pthread_mutex_lock (&stream->frontend_lock);
516 if (_x_get_fine_speed (&stream->s) != XINE_SPEED_PAUSE) {
517 _x_set_fine_speed (&stream->s, XINE_SPEED_PAUSE);
518 } else {
519 /* HACK: temporarily resume decoders. */
520 _x_set_fine_speed (&stream->s, XINE_LIVE_PAUSE_ON);
521 /* rather miss 1 strobe than wait or freeze. */
522 if (xine->port_ticket->ticket_revoked == 0) {
523 xine->port_ticket->acquire (xine->port_ticket, 1);
524 stream->s.video_out->set_property (stream->s.video_out, param, value);
525 stream->s.audio_out->set_property (stream->s.audio_out, param, value);
526 xine->port_ticket->release (xine->port_ticket, 1);
527 }
528 }
529 pthread_mutex_unlock (&stream->frontend_lock);
530 break;
531
532 case XINE_PARAM_IGNORE_VIDEO:
533 _x_stream_info_set (&stream->s, XINE_STREAM_INFO_IGNORE_VIDEO, value);
534 break;
535
536 case XINE_PARAM_IGNORE_AUDIO:
537 _x_stream_info_set (&stream->s, XINE_STREAM_INFO_IGNORE_AUDIO, value);
538 break;
539
540 case XINE_PARAM_IGNORE_SPU:
541 _x_stream_info_set (&stream->s, XINE_STREAM_INFO_IGNORE_SPU, value);
542 break;
543
544 case XINE_PARAM_METRONOM_PREBUFFER:
545 stream->s.metronom->set_option (stream->s.metronom, METRONOM_PREBUFFER, value);
546 break;
547
548 case XINE_PARAM_BROADCASTER_PORT:
549 if( !stream->broadcaster && value ) {
550 stream->broadcaster = _x_init_broadcaster (&stream->s, value);
551 } else if ( stream->broadcaster && !value ) {
552 _x_close_broadcaster(stream->broadcaster);
553 stream->broadcaster = NULL;
554 }
555 break;
556
557 case XINE_PARAM_EARLY_FINISHED_EVENT:
558 stream->early_finish_event = !!value;
559 break;
560
561 case XINE_PARAM_DELAY_FINISHED_EVENT:
562 stream->delay_finish_event = value;
563 break;
564
565 case XINE_PARAM_GAPLESS_SWITCH:
566 stream->gapless_switch = !!value;
567 if( stream->gapless_switch && !stream->early_finish_event ) {
568 xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "frontend possibly buggy: gapless_switch without early_finish_event\n");
569 }
570 break;
571
572 default:
573 xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG,
574 "xine_interface: unknown or deprecated stream param %d set\n", param);
575 }
576 }
577
xine_get_param(xine_stream_t * s,int param)578 int xine_get_param (xine_stream_t *s, int param) {
579 xine_stream_private_t *stream = (xine_stream_private_t *)s;
580 xine_private_t *xine;
581 int ret;
582 /* Avoid crashing */
583 if ( ! stream ) {
584 lprintf ("xine_interface: xine_set_param called with NULL stream.\n");
585 return 0;
586 }
587 xine = (xine_private_t *)stream->s.xine;
588
589 switch (param) {
590 case XINE_PARAM_SPEED:
591 ret = _x_get_speed (&stream->s);
592 break;
593
594 case XINE_PARAM_FINE_SPEED:
595 ret = _x_get_fine_speed (&stream->s);
596 break;
597
598 case XINE_PARAM_AV_OFFSET:
599 ret = stream->s.metronom->get_option (stream->s.metronom, METRONOM_AV_OFFSET);
600 break;
601
602 case XINE_PARAM_SPU_OFFSET:
603 ret = stream->s.metronom->get_option (stream->s.metronom, METRONOM_SPU_OFFSET);
604 break;
605
606 case XINE_PARAM_AUDIO_CHANNEL_LOGICAL:
607 ret = stream->audio_channel_user;
608 break;
609
610 case XINE_PARAM_SPU_CHANNEL:
611 ret = stream->s.spu_channel_user;
612 break;
613
614 case XINE_PARAM_VIDEO_CHANNEL:
615 ret = stream->video_channel;
616 break;
617
618 case XINE_PARAM_AUDIO_VOLUME:
619 xine->port_ticket->acquire (xine->port_ticket, 1);
620 if (!stream->s.audio_out)
621 ret = -1;
622 else
623 ret = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_MIXER_VOL);
624 xine->port_ticket->release (xine->port_ticket, 1);
625 break;
626
627 case XINE_PARAM_AUDIO_MUTE:
628 xine->port_ticket->acquire (xine->port_ticket, 1);
629 if (!stream->s.audio_out)
630 ret = -1;
631 else
632 ret = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_MUTE_VOL);
633 xine->port_ticket->release (xine->port_ticket, 1);
634 break;
635
636 case XINE_PARAM_AUDIO_COMPR_LEVEL:
637 xine->port_ticket->acquire (xine->port_ticket, 1);
638 if (!stream->s.audio_out)
639 ret = -1;
640 else
641 ret = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_COMPRESSOR);
642 xine->port_ticket->release (xine->port_ticket, 1);
643 break;
644
645 case XINE_PARAM_AUDIO_AMP_LEVEL:
646 xine->port_ticket->acquire (xine->port_ticket, 1);
647 if (!stream->s.audio_out)
648 ret = -1;
649 else
650 ret = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_AMP);
651 xine->port_ticket->release (xine->port_ticket, 1);
652 break;
653
654 case XINE_PARAM_AUDIO_AMP_MUTE:
655 xine->port_ticket->acquire (xine->port_ticket, 1);
656 if (!stream->s.audio_out)
657 ret = -1;
658 else
659 ret = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_AMP_MUTE);
660 xine->port_ticket->release (xine->port_ticket, 1);
661 break;
662
663 case XINE_PARAM_EQ_30HZ:
664 case XINE_PARAM_EQ_60HZ:
665 case XINE_PARAM_EQ_125HZ:
666 case XINE_PARAM_EQ_250HZ:
667 case XINE_PARAM_EQ_500HZ:
668 case XINE_PARAM_EQ_1000HZ:
669 case XINE_PARAM_EQ_2000HZ:
670 case XINE_PARAM_EQ_4000HZ:
671 case XINE_PARAM_EQ_8000HZ:
672 case XINE_PARAM_EQ_16000HZ:
673 xine->port_ticket->acquire (xine->port_ticket, 1);
674 if (!stream->s.audio_out)
675 ret = -1;
676 else
677 ret= stream->s.audio_out->get_property (stream->s.audio_out,
678 param - XINE_PARAM_EQ_30HZ + AO_PROP_EQ_30HZ);
679 xine->port_ticket->release (xine->port_ticket, 1);
680 break;
681
682 case XINE_PARAM_VERBOSITY:
683 ret = stream->s.xine->verbosity;
684 break;
685
686 case XINE_PARAM_VO_SHARPNESS:
687 case XINE_PARAM_VO_NOISE_REDUCTION:
688 case XINE_PARAM_VO_HUE:
689 case XINE_PARAM_VO_SATURATION:
690 case XINE_PARAM_VO_CONTRAST:
691 case XINE_PARAM_VO_BRIGHTNESS:
692 case XINE_PARAM_VO_GAMMA:
693 case XINE_PARAM_VO_DEINTERLACE:
694 case XINE_PARAM_VO_ASPECT_RATIO:
695 case XINE_PARAM_VO_ZOOM_X:
696 case XINE_PARAM_VO_ZOOM_Y:
697 case XINE_PARAM_VO_TVMODE:
698 case XINE_PARAM_VO_WINDOW_WIDTH:
699 case XINE_PARAM_VO_WINDOW_HEIGHT:
700 case XINE_PARAM_VO_CROP_LEFT:
701 case XINE_PARAM_VO_CROP_RIGHT:
702 case XINE_PARAM_VO_CROP_TOP:
703 case XINE_PARAM_VO_CROP_BOTTOM:
704 xine->port_ticket->acquire (xine->port_ticket, 1);
705 ret = stream->s.video_out->get_property(stream->s.video_out, param);
706 xine->port_ticket->release (xine->port_ticket, 1);
707 break;
708
709 case XINE_PARAM_IGNORE_VIDEO:
710 ret = _x_stream_info_get_public (&stream->s, XINE_STREAM_INFO_IGNORE_VIDEO);
711 break;
712
713 case XINE_PARAM_IGNORE_AUDIO:
714 ret = _x_stream_info_get_public (&stream->s, XINE_STREAM_INFO_IGNORE_AUDIO);
715 break;
716
717 case XINE_PARAM_IGNORE_SPU:
718 ret = _x_stream_info_get_public (&stream->s, XINE_STREAM_INFO_IGNORE_SPU);
719 break;
720
721 case XINE_PARAM_METRONOM_PREBUFFER:
722 ret = stream->s.metronom->get_option (stream->s.metronom, METRONOM_PREBUFFER);
723 break;
724
725 case XINE_PARAM_BROADCASTER_PORT:
726 if( stream->broadcaster )
727 ret = _x_get_broadcaster_port(stream->broadcaster);
728 else
729 ret = 0;
730 break;
731
732 case XINE_PARAM_EARLY_FINISHED_EVENT:
733 ret = stream->early_finish_event;
734 break;
735
736 case XINE_PARAM_DELAY_FINISHED_EVENT:
737 ret = stream->delay_finish_event;
738 break;
739
740 case XINE_PARAM_GAPLESS_SWITCH:
741 ret = stream->gapless_switch;
742 break;
743
744 default:
745 xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG,
746 "xine_interface: unknown or deprecated stream param %d requested\n", param);
747 ret = 0;
748 }
749
750 return ret;
751 }
752
xine_get_stream_info(xine_stream_t * s,int info)753 uint32_t xine_get_stream_info (xine_stream_t *s, int info) {
754 xine_stream_private_t *stream = (xine_stream_private_t *)s;
755
756 switch (info) {
757
758 case XINE_STREAM_INFO_SEEKABLE:
759 if (stream->s.input_plugin)
760 return stream->s.input_plugin->get_capabilities (stream->s.input_plugin)
761 & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE | INPUT_CAP_TIME_SEEKABLE);
762 return 0;
763
764 case XINE_STREAM_INFO_HAS_CHAPTERS:
765 if (stream->demux.plugin)
766 if (stream->demux.plugin->get_capabilities (stream->demux.plugin) & DEMUX_CAP_CHAPTERS)
767 return 1;
768 if (stream->s.input_plugin)
769 if (stream->s.input_plugin->get_capabilities (stream->s.input_plugin) & INPUT_CAP_CHAPTERS)
770 return 1;
771 return 0;
772
773 case XINE_STREAM_INFO_BITRATE:
774 case XINE_STREAM_INFO_VIDEO_WIDTH:
775 case XINE_STREAM_INFO_VIDEO_HEIGHT:
776 case XINE_STREAM_INFO_VIDEO_RATIO:
777 case XINE_STREAM_INFO_VIDEO_CHANNELS:
778 case XINE_STREAM_INFO_VIDEO_STREAMS:
779 case XINE_STREAM_INFO_VIDEO_BITRATE:
780 case XINE_STREAM_INFO_VIDEO_FOURCC:
781 case XINE_STREAM_INFO_VIDEO_HANDLED:
782 case XINE_STREAM_INFO_FRAME_DURATION:
783 case XINE_STREAM_INFO_AUDIO_CHANNELS:
784 case XINE_STREAM_INFO_AUDIO_BITS:
785 case XINE_STREAM_INFO_AUDIO_SAMPLERATE:
786 case XINE_STREAM_INFO_AUDIO_BITRATE:
787 case XINE_STREAM_INFO_AUDIO_FOURCC:
788 case XINE_STREAM_INFO_AUDIO_HANDLED:
789 case XINE_STREAM_INFO_HAS_AUDIO:
790 case XINE_STREAM_INFO_HAS_VIDEO:
791 case XINE_STREAM_INFO_IGNORE_VIDEO:
792 case XINE_STREAM_INFO_IGNORE_AUDIO:
793 case XINE_STREAM_INFO_IGNORE_SPU:
794 case XINE_STREAM_INFO_VIDEO_HAS_STILL:
795 case XINE_STREAM_INFO_SKIPPED_FRAMES:
796 case XINE_STREAM_INFO_DISCARDED_FRAMES:
797 case XINE_STREAM_INFO_VIDEO_AFD:
798 case XINE_STREAM_INFO_DVD_TITLE_NUMBER:
799 case XINE_STREAM_INFO_DVD_TITLE_COUNT:
800 case XINE_STREAM_INFO_DVD_CHAPTER_NUMBER:
801 case XINE_STREAM_INFO_DVD_CHAPTER_COUNT:
802 case XINE_STREAM_INFO_DVD_ANGLE_NUMBER:
803 case XINE_STREAM_INFO_DVD_ANGLE_COUNT:
804 return _x_stream_info_get_public (&stream->s, info);
805
806 case XINE_STREAM_INFO_MAX_AUDIO_CHANNEL:
807 return stream->audio_track_map_entries;
808
809 case XINE_STREAM_INFO_MAX_SPU_CHANNEL:
810 return stream->spu_track_map_entries;
811
812 default:
813 xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG,
814 "xine_interface: unknown or deprecated stream info %d requested\n", info);
815 }
816 return 0;
817 }
818
xine_get_meta_info(xine_stream_t * stream,int info)819 const char *xine_get_meta_info (xine_stream_t *stream, int info) {
820 return _x_meta_info_get_public(stream, info);
821 }
822
xine_osd_new(xine_stream_t * stream,int x,int y,int width,int height)823 xine_osd_t *xine_osd_new(xine_stream_t *stream, int x, int y, int width, int height) {
824 xine_osd_t *this = (xine_osd_t *)stream->osd_renderer->new_object(stream->osd_renderer, width, height);
825 this->osd.renderer->set_position(&this->osd, x, y);
826 this->osd.renderer->set_encoding(&this->osd, "");
827 return this;
828 }
829
xine_osd_get_capabilities(xine_osd_t * this)830 uint32_t xine_osd_get_capabilities(xine_osd_t *this) {
831 return this->osd.renderer->get_capabilities(&this->osd);
832 }
833
xine_osd_draw_point(xine_osd_t * this,int x,int y,int color)834 void xine_osd_draw_point(xine_osd_t *this, int x, int y, int color) {
835 this->osd.renderer->point(&this->osd, x, y, color);
836 }
837
xine_osd_draw_line(xine_osd_t * this,int x1,int y1,int x2,int y2,int color)838 void xine_osd_draw_line(xine_osd_t *this, int x1, int y1, int x2, int y2, int color) {
839 this->osd.renderer->line(&this->osd, x1, y1, x2, y2, color);
840 }
841
xine_osd_draw_rect(xine_osd_t * this,int x1,int y1,int x2,int y2,int color,int filled)842 void xine_osd_draw_rect(xine_osd_t *this, int x1, int y1, int x2, int y2, int color, int filled) {
843 if (filled) {
844 this->osd.renderer->filled_rect(&this->osd, x1, y1, x2, y2, color);
845 } else {
846 this->osd.renderer->line(&this->osd, x1, y1, x2, y1, color);
847 this->osd.renderer->line(&this->osd, x2, y1, x2, y2, color);
848 this->osd.renderer->line(&this->osd, x2, y2, x1, y2, color);
849 this->osd.renderer->line(&this->osd, x1, y2, x1, y1, color);
850 }
851 }
852
xine_osd_draw_text(xine_osd_t * this,int x1,int y1,const char * text,int color_base)853 void xine_osd_draw_text(xine_osd_t *this, int x1, int y1, const char *text, int color_base) {
854 this->osd.renderer->render_text(&this->osd, x1, y1, text, color_base);
855 }
856
xine_osd_get_text_size(xine_osd_t * this,const char * text,int * width,int * height)857 void xine_osd_get_text_size(xine_osd_t *this, const char *text, int *width, int *height) {
858 this->osd.renderer->get_text_size(&this->osd, text, width, height);
859 }
860
xine_osd_set_font(xine_osd_t * this,const char * fontname,int size)861 int xine_osd_set_font(xine_osd_t *this, const char *fontname, int size) {
862 return this->osd.renderer->set_font(&this->osd, fontname, size);
863 }
864
xine_osd_set_encoding(xine_osd_t * this,const char * encoding)865 void xine_osd_set_encoding(xine_osd_t *this, const char *encoding) {
866 this->osd.renderer->set_encoding(&this->osd, encoding);
867 }
868
xine_osd_set_position(xine_osd_t * this,int x,int y)869 void xine_osd_set_position(xine_osd_t *this, int x, int y) {
870 this->osd.renderer->set_position(&this->osd, x, y);
871 }
872
xine_osd_show(xine_osd_t * this,int64_t vpts)873 void xine_osd_show(xine_osd_t *this, int64_t vpts) {
874 this->osd.renderer->show(&this->osd, vpts);
875 }
876
xine_osd_show_unscaled(xine_osd_t * this,int64_t vpts)877 void xine_osd_show_unscaled(xine_osd_t *this, int64_t vpts) {
878 this->osd.renderer->show_unscaled(&this->osd, vpts);
879 }
880
xine_osd_hide(xine_osd_t * this,int64_t vpts)881 void xine_osd_hide(xine_osd_t *this, int64_t vpts) {
882 this->osd.renderer->hide(&this->osd, vpts);
883 }
884
xine_osd_clear(xine_osd_t * this)885 void xine_osd_clear(xine_osd_t *this) {
886 this->osd.renderer->clear(&this->osd);
887 }
888
xine_osd_free(xine_osd_t * this)889 void xine_osd_free(xine_osd_t *this) {
890 this->osd.renderer->free_object(&this->osd);
891 }
892
xine_osd_set_palette(xine_osd_t * this,const uint32_t * const color,const uint8_t * const trans)893 void xine_osd_set_palette(xine_osd_t *this, const uint32_t *const color, const uint8_t *const trans) {
894 this->osd.renderer->set_palette(&this->osd, color, trans);
895 }
896
xine_osd_set_text_palette(xine_osd_t * this,int palette_number,int color_base)897 void xine_osd_set_text_palette(xine_osd_t *this, int palette_number, int color_base) {
898 this->osd.renderer->set_text_palette(&this->osd, palette_number, color_base);
899 }
900
xine_osd_get_palette(xine_osd_t * this,uint32_t * color,uint8_t * trans)901 void xine_osd_get_palette(xine_osd_t *this, uint32_t *color, uint8_t *trans) {
902 this->osd.renderer->get_palette(&this->osd, color, trans);
903 }
904
xine_osd_draw_bitmap(xine_osd_t * this,uint8_t * bitmap,int x1,int y1,int width,int height,uint8_t * palette_map)905 void xine_osd_draw_bitmap(xine_osd_t *this, uint8_t *bitmap,
906 int x1, int y1, int width, int height,
907 uint8_t *palette_map) {
908 this->osd.renderer->draw_bitmap(&this->osd, bitmap, x1, y1, width, height, palette_map);
909 }
910
xine_osd_set_argb_buffer(xine_osd_t * this,uint32_t * argb_buffer,int dirty_x,int dirty_y,int dirty_width,int dirty_height)911 void xine_osd_set_argb_buffer(xine_osd_t *this, uint32_t *argb_buffer,
912 int dirty_x, int dirty_y, int dirty_width, int dirty_height) {
913 this->osd.renderer->set_argb_buffer(&this->osd, argb_buffer, dirty_x, dirty_y, dirty_width, dirty_height);
914 }
915
xine_osd_set_extent(xine_osd_t * this,int extent_width,int extent_height)916 void xine_osd_set_extent(xine_osd_t *this, int extent_width, int extent_height) {
917 this->osd.renderer->set_extent(&this->osd, extent_width, extent_height);
918 }
919
xine_osd_set_video_window(xine_osd_t * this,int window_x,int window_y,int window_width,int window_height)920 void xine_osd_set_video_window(xine_osd_t *this, int window_x, int window_y, int window_width, int window_height) {
921 this->osd.renderer->set_video_window(&this->osd, window_x, window_y, window_width, window_height);
922 }
923
924
xine_post_list_inputs(xine_post_t * this_gen)925 const char *const *xine_post_list_inputs(xine_post_t *this_gen) {
926 post_plugin_t *this = (post_plugin_t *)this_gen;
927 return this->input_ids;
928 }
929
xine_post_list_outputs(xine_post_t * this_gen)930 const char *const *xine_post_list_outputs(xine_post_t *this_gen) {
931 post_plugin_t *this = (post_plugin_t *)this_gen;
932 return this->output_ids;
933 }
934
xine_post_input(xine_post_t * this_gen,const char * name)935 xine_post_in_t *xine_post_input(xine_post_t *this_gen, const char *name) {
936 post_plugin_t *this = (post_plugin_t *)this_gen;
937 xine_list_iterator_t ite = NULL;
938 xine_post_in_t *input;
939
940 while ((input = xine_list_next_value (this->input, &ite))) {
941 if (strcmp(input->name, name) == 0)
942 return input;
943 }
944 return NULL;
945 }
946
xine_post_output(xine_post_t * this_gen,const char * name)947 xine_post_out_t *xine_post_output(xine_post_t *this_gen, const char *name) {
948 post_plugin_t *this = (post_plugin_t *)this_gen;
949 xine_list_iterator_t ite = NULL;
950 xine_post_out_t *output;
951
952 while ((output = xine_list_next_value (this->output, &ite))) {
953 if (strcmp(output->name, name) == 0)
954 return output;
955 }
956 return NULL;
957 }
958
xine_post_wire(xine_post_out_t * source,xine_post_in_t * target)959 int xine_post_wire(xine_post_out_t *source, xine_post_in_t *target) {
960 if (source && source->rewire) {
961 if (target) {
962 if (source->type == target->type)
963 return source->rewire(source, target->data);
964 else
965 return 0;
966 } else
967 return source->rewire(source, NULL);
968 }
969 return 0;
970 }
971
xine_post_wire_video_port(xine_post_out_t * source,xine_video_port_t * vo)972 int xine_post_wire_video_port(xine_post_out_t *source, xine_video_port_t *vo) {
973 if (source && source->rewire) {
974 if (vo) {
975 if (source->type == XINE_POST_DATA_VIDEO)
976 return source->rewire(source, vo);
977 else
978 return 0;
979 } else
980 return source->rewire(source, NULL);
981 }
982 return 0;
983 }
984
xine_post_wire_audio_port(xine_post_out_t * source,xine_audio_port_t * ao)985 int xine_post_wire_audio_port(xine_post_out_t *source, xine_audio_port_t *ao) {
986 if (source && source->rewire) {
987 if (ao) {
988 if (source->type == XINE_POST_DATA_AUDIO)
989 return source->rewire(source, ao);
990 else
991 return 0;
992 } else
993 return source->rewire(source, NULL);
994 }
995 return 0;
996 }
997
xine_get_video_source(xine_stream_t * s)998 xine_post_out_t * xine_get_video_source (xine_stream_t *s) {
999 xine_stream_private_t *stream = (xine_stream_private_t *)s;
1000 return &stream->video_source;
1001 }
1002
xine_get_audio_source(xine_stream_t * s)1003 xine_post_out_t * xine_get_audio_source (xine_stream_t *s) {
1004 xine_stream_private_t *stream = (xine_stream_private_t *)s;
1005 return &stream->audio_source;
1006 }
1007
1008 /* report error/message to UI. may be provided with several
1009 * string parameters. last parameter must be NULL.
1010 */
_x_message(xine_stream_t * stream,int type,...)1011 int _x_message(xine_stream_t *stream, int type, ...) {
1012 xine_ui_message_data_t *data;
1013 xine_event_t event;
1014 const char *explanation;
1015 size_t size;
1016 int n;
1017 va_list ap;
1018 char *s, *params;
1019 char *args[1025];
1020 static const char *const std_explanation[] = {
1021 "",
1022 N_("Warning:"),
1023 N_("Unknown host:"),
1024 N_("Unknown device:"),
1025 N_("Network unreachable"),
1026 N_("Connection refused:"),
1027 N_("File not found:"),
1028 N_("Read error from:"),
1029 N_("Error loading library:"),
1030 N_("Encrypted media stream detected"),
1031 N_("Security message:"),
1032 N_("Audio device unavailable"),
1033 N_("Permission error"),
1034 N_("File is empty:"),
1035 };
1036
1037 if (!stream) return 0;
1038
1039 if( type >= 0 && (size_t)type < sizeof(std_explanation)/
1040 sizeof(std_explanation[0]) ) {
1041 explanation = _(std_explanation[type]);
1042 size = strlen(explanation)+1;
1043 } else {
1044 explanation = NULL;
1045 size = 0;
1046 }
1047
1048 n = 0;
1049 va_start(ap, type);
1050 while(((s = va_arg(ap, char *)) != NULL) && (n < 1024)) {
1051 size += strlen(s) + 1;
1052 args[n] = s;
1053 n++;
1054 }
1055 va_end(ap);
1056
1057 args[n] = NULL;
1058
1059 size += sizeof(xine_ui_message_data_t) + 1;
1060 data = calloc(1, size );
1061
1062 strcpy(data->compatibility.str, "Upgrade your frontend to see the error messages");
1063 data->type = type;
1064 data->num_parameters = n;
1065
1066 if( explanation ) {
1067 strcpy(data->messages, explanation);
1068 data->explanation = data->messages - (char *)data;
1069 params = data->messages + strlen(explanation) + 1;
1070 } else {
1071 data->explanation = 0;
1072 params = data->messages;
1073 }
1074
1075 data->parameters = params - (char *)data;
1076
1077 n = 0;
1078 *params = '\0';
1079
1080 while(args[n]) {
1081 strcpy(params, args[n]);
1082 params += strlen(args[n]) + 1;
1083 n++;
1084 }
1085
1086 *params = '\0';
1087
1088 event.type = XINE_EVENT_UI_MESSAGE;
1089 event.stream = stream;
1090 event.data_length = size;
1091 event.data = data;
1092 xine_event_send(stream, &event);
1093
1094 free(data);
1095
1096 return 1;
1097 }
1098
xine_get_current_vpts(xine_stream_t * s)1099 int64_t xine_get_current_vpts (xine_stream_t *s) {
1100 xine_stream_private_t *stream = (xine_stream_private_t *)s;
1101 return stream->s.xine->clock->get_current_time (stream->s.xine->clock);
1102 }
1103