summaryrefslogtreecommitdiff
path: root/src/xine-engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/xine-engine')
-rw-r--r--src/xine-engine/alphablend.c12
-rw-r--r--src/xine-engine/alphablend.h21
-rw-r--r--src/xine-engine/audio_decoder.c6
-rw-r--r--src/xine-engine/audio_out.c64
-rw-r--r--src/xine-engine/audio_out.h2
-rw-r--r--src/xine-engine/broadcaster.c6
-rw-r--r--src/xine-engine/broadcaster.h6
-rw-r--r--src/xine-engine/buffer.c4
-rw-r--r--src/xine-engine/buffer.h36
-rw-r--r--src/xine-engine/buffer_types.c47
-rw-r--r--src/xine-engine/configfile.c43
-rw-r--r--src/xine-engine/configfile.h2
-rw-r--r--src/xine-engine/demux.c94
-rw-r--r--src/xine-engine/info_helper.c23
-rw-r--r--src/xine-engine/input_cache.c4
-rw-r--r--src/xine-engine/input_rip.c9
-rw-r--r--src/xine-engine/load_plugins.c457
-rw-r--r--src/xine-engine/lrb.c2
-rw-r--r--src/xine-engine/metronom.c9
-rw-r--r--src/xine-engine/metronom.h4
-rw-r--r--src/xine-engine/osd.c67
-rw-r--r--src/xine-engine/osd.h2
-rw-r--r--src/xine-engine/post.c21
-rw-r--r--src/xine-engine/refcounter.c7
-rw-r--r--src/xine-engine/refcounter.h6
-rw-r--r--src/xine-engine/scratch.c15
-rw-r--r--src/xine-engine/scratch.h2
-rw-r--r--src/xine-engine/video_decoder.c2
-rw-r--r--src/xine-engine/video_out.c6
-rw-r--r--src/xine-engine/video_out.h6
-rw-r--r--src/xine-engine/video_overlay.c10
-rw-r--r--src/xine-engine/video_overlay.h2
-rw-r--r--src/xine-engine/vo_scale.c4
-rw-r--r--src/xine-engine/vo_scale.h4
-rw-r--r--src/xine-engine/xine.c309
-rw-r--r--src/xine-engine/xine_interface.c9
-rw-r--r--src/xine-engine/xine_internal.h9
37 files changed, 839 insertions, 493 deletions
diff --git a/src/xine-engine/alphablend.c b/src/xine-engine/alphablend.c
index a7ab33cf8..a9b015209 100644
--- a/src/xine-engine/alphablend.c
+++ b/src/xine-engine/alphablend.c
@@ -23,6 +23,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
/*
#define LOG_BLEND_YUV
#define LOG_BLEND_RGB16
@@ -1110,12 +1114,12 @@ static uint8_t *(*blend_yuv_grow_extra_data(alphablend_t *extra_data, int osd_wi
uint8_t *data[ 3 ][ 2 ];
} *header = (struct header_s *)extra_data->buffer;
- int needed_buffer_size = sizeof (*header) + osd_width * sizeof (uint8_t[ 3 ][ 2 ]);
+ size_t needed_buffer_size = sizeof (*header) + osd_width * sizeof (uint8_t[ 3 ][ 2 ]);
if (extra_data->buffer_size < needed_buffer_size) {
free(extra_data->buffer);
- header = xine_xmalloc(needed_buffer_size);
+ header = calloc(1, needed_buffer_size);
if (!header) {
extra_data->buffer_size = 0;
return 0;
@@ -1552,12 +1556,12 @@ static uint8_t *(*blend_yuy2_grow_extra_data(alphablend_t *extra_data, int osd_w
uint8_t *data[ 3 ];
} *header = (struct header_s *)extra_data->buffer;
- int needed_buffer_size = sizeof (*header) + osd_width * sizeof (uint8_t[ 3 ]);
+ size_t needed_buffer_size = sizeof (*header) + osd_width * sizeof (uint8_t[ 3 ]);
if (extra_data->buffer_size < needed_buffer_size) {
free(extra_data->buffer);
- header = xine_xmalloc(needed_buffer_size);
+ header = calloc(1, needed_buffer_size);
if (!header) {
extra_data->buffer_size = 0;
return 0;
diff --git a/src/xine-engine/alphablend.h b/src/xine-engine/alphablend.h
index 3c9a693d9..7aa63b306 100644
--- a/src/xine-engine/alphablend.h
+++ b/src/xine-engine/alphablend.h
@@ -39,22 +39,7 @@ typedef struct {
void _x_alphablend_init(alphablend_t *extra_data, xine_t *xine) XINE_PROTECTED;
void _x_alphablend_free(alphablend_t *extra_data) XINE_PROTECTED;
-/* _MSC_VER port changes */
-#undef ATTRIBUTE_PACKED
-#undef PRAGMA_PACK_BEGIN
-#undef PRAGMA_PACK_END
-
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) || defined(__ICC)
-#define ATTRIBUTE_PACKED __attribute__ ((packed))
-#define PRAGMA_PACK 0
-#endif
-
-#if !defined(ATTRIBUTE_PACKED)
-#define ATTRIBUTE_PACKED
-#define PRAGMA_PACK 1
-#endif
-
-#if PRAGMA_PACK
+#if !SUPPORT_ATTRIBUTE_PACKED
#pragma pack(8)
#endif
@@ -63,10 +48,10 @@ typedef struct { /* CLUT == Color LookUp Table */
uint8_t cr;
uint8_t y;
uint8_t foo;
-} ATTRIBUTE_PACKED clut_t;
+} XINE_PACKED clut_t;
-#if PRAGMA_PACK
+#if !SUPPORT_ATTRIBUTE_PACKED
#pragma pack()
#endif
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
index 5476262d9..855dee372 100644
--- a/src/xine-engine/audio_decoder.c
+++ b/src/xine-engine/audio_decoder.c
@@ -89,16 +89,18 @@ static void *audio_decoder_loop (void *stream_gen) {
if (stream->audio_decoder_plugin) {
lprintf ("close old decoder\n");
-
+
+ stream->keep_ao_driver_open = !!(buf->decoder_flags & BUF_FLAG_GAPLESS_SW);
_x_free_audio_decoder (stream, stream->audio_decoder_plugin);
stream->audio_decoder_plugin = NULL;
stream->audio_track_map_entries = 0;
stream->audio_type = 0;
+ stream->keep_ao_driver_open = 0;
}
running_ticket->release(running_ticket, 0);
- if( !stream->gapless_switch )
+ if( !(buf->decoder_flags & BUF_FLAG_GAPLESS_SW) )
stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_STREAMSTART, 0);
buftype_unknown = 0;
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index 7fe92d9fe..a6f83dc9d 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -215,6 +215,7 @@ typedef struct {
int num_driver_actions; /* number of threads, that wish to call
* functions needing driver_lock */
pthread_mutex_t driver_action_lock; /* protects num_driver_actions */
+ pthread_cond_t driver_action_cond; /* informs about num_driver_actions-- */
metronom_clock_t *clock;
xine_t *xine;
@@ -243,6 +244,7 @@ typedef struct {
audio_fifo_t *free_fifo;
audio_fifo_t *out_fifo;
int64_t last_audio_vpts;
+ pthread_mutex_t current_speed_lock;
uint32_t current_speed; /* the current playback speed */
/* FIXME: replace all this->clock->speed with this->current_speed. we should make
* sure nobody will change speed without going through xine.c:set_speed_internal */
@@ -287,13 +289,14 @@ struct audio_fifo_s {
int num_buffers;
};
+static int ao_get_property (xine_audio_port_t *this_gen, int property);
static int ao_set_property (xine_audio_port_t *this_gen, int property, int value);
-static audio_fifo_t *fifo_new (xine_t *xine) {
+static audio_fifo_t *XINE_MALLOC fifo_new (xine_t *xine) {
audio_fifo_t *fifo;
- fifo = (audio_fifo_t *) xine_xmalloc (sizeof (audio_fifo_t));
+ fifo = (audio_fifo_t *) calloc(1, sizeof(audio_fifo_t));
if (!fifo)
return NULL;
@@ -1039,6 +1042,7 @@ static void *ao_loop (void *this_gen) {
* we must process/free buffers otherwise the entire engine will stop.
*/
+ pthread_mutex_lock(&this->current_speed_lock);
if ( this->audio_loop_running &&
(this->clock->speed == XINE_SPEED_PAUSE ||
(this->clock->speed != XINE_FINE_SPEED_NORMAL &&
@@ -1054,6 +1058,7 @@ static void *ao_loop (void *this_gen) {
_x_refcounter_dec(in_buf->stream->refcounter);
fifo_append (this->free_fifo, in_buf);
in_buf = NULL;
+ pthread_mutex_unlock(&this->current_speed_lock);
continue;
}
@@ -1064,6 +1069,7 @@ static void *ao_loop (void *this_gen) {
}
lprintf ("loop:pause: I feel sleepy (%d buffers).\n", this->out_fifo->num_buffers);
+ pthread_mutex_unlock(&this->current_speed_lock);
xine_usec_sleep (10000);
lprintf ("loop:pause: I wake up.\n");
continue;
@@ -1273,12 +1279,20 @@ static void *ao_loop (void *this_gen) {
fifo_append (this->free_fifo, in_buf);
in_buf = NULL;
}
+ pthread_mutex_unlock(&this->current_speed_lock);
/* Give other threads a chance to use functions which require this->driver_lock to
* be available. This is needed when using NPTL on Linux (and probably PThreads
* on Solaris as well). */
- if (this->num_driver_actions > 0)
- sched_yield();
+ if (this->num_driver_actions > 0) {
+ /* calling sched_yield() is not sufficient on multicore systems */
+ /* sched_yield(); */
+ /* instead wait for the other thread to acquire this->driver_lock */
+ pthread_mutex_lock(&this->driver_action_lock);
+ if (this->num_driver_actions > 0)
+ pthread_cond_wait(&this->driver_action_cond, &this->driver_action_lock);
+ pthread_mutex_unlock(&this->driver_action_lock);
+ }
}
if (in_buf) {
@@ -1469,6 +1483,8 @@ static inline void dec_num_driver_actions(aos_t *this) {
pthread_mutex_lock(&this->driver_action_lock);
this->num_driver_actions--;
+ /* indicate the change to ao_loop() */
+ pthread_cond_broadcast(&this->driver_action_cond);
pthread_mutex_unlock(&this->driver_action_lock);
}
@@ -1608,17 +1624,21 @@ static void ao_close(xine_audio_port_t *this_gen, xine_stream_t *stream) {
pthread_mutex_unlock(&this->streams_lock);
/* close driver if no streams left */
- if (!ite && !this->grab_only && !stream->gapless_switch) {
+ if (!ite && !this->grab_only && !stream->keep_ao_driver_open) {
xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_out: no streams left, closing driver\n");
if (this->audio_loop_running) {
+ /* make sure there are no more buffers on queue */
if (this->clock->speed == XINE_SPEED_PAUSE ||
(this->clock->speed != XINE_FINE_SPEED_NORMAL && !this->slow_fast_audio)) {
- /* discard buffers, otherwise we'll wait forever */
+ int discard = ao_get_property(this_gen, AO_PROP_DISCARD_BUFFERS);
+ /* discard buffers while waiting, otherwise we'll wait forever */
ao_set_property(this_gen, AO_PROP_DISCARD_BUFFERS, 1);
+ fifo_wait_empty(this->out_fifo);
+ ao_set_property(this_gen, AO_PROP_DISCARD_BUFFERS, discard);
}
- /* make sure there are no more buffers on queue */
- fifo_wait_empty(this->out_fifo);
+ else
+ fifo_wait_empty(this->out_fifo);
}
pthread_mutex_lock( &this->driver_lock );
@@ -1667,6 +1687,7 @@ static void ao_exit(xine_audio_port_t *this_gen) {
}
pthread_mutex_destroy(&this->driver_lock);
+ pthread_cond_destroy(&this->driver_action_cond);
pthread_mutex_destroy(&this->driver_action_lock);
pthread_mutex_destroy(&this->streams_lock);
xine_list_delete(this->streams);
@@ -1679,6 +1700,7 @@ static void ao_exit(xine_audio_port_t *this_gen) {
free (this->frame_buf[1]);
free (this->zero_space);
+ pthread_mutex_destroy(&this->current_speed_lock);
pthread_mutex_destroy(&this->flush_audio_driver_lock);
pthread_cond_destroy(&this->flush_audio_driver_reached);
@@ -1905,8 +1927,15 @@ static int ao_set_property (xine_audio_port_t *this_gen, int property, int value
if (value != XINE_FINE_SPEED_NORMAL && value != XINE_SPEED_PAUSE && !this->slow_fast_audio )
this->ao.control(&this->ao, AO_CTRL_FLUSH_BUFFERS, NULL);
- this->ao.control(&this->ao,
- (value == XINE_SPEED_PAUSE) ? AO_CTRL_PLAY_PAUSE : AO_CTRL_PLAY_RESUME, NULL);
+ if( value == XINE_SPEED_PAUSE ) {
+ /* current_speed_lock is here to make sure the ao_loop will pause in a safe place.
+ * that is, we cannot pause writing to device, filling gaps etc. */
+ pthread_mutex_lock(&this->current_speed_lock);
+ this->ao.control(&this->ao, AO_CTRL_PLAY_PAUSE, NULL);
+ pthread_mutex_unlock(&this->current_speed_lock);
+ } else {
+ this->ao.control(&this->ao, AO_CTRL_PLAY_RESUME, NULL);
+ }
this->current_speed = value;
if( this->slow_fast_audio )
ao_update_resample_factor(this);
@@ -2046,11 +2075,12 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver,
static const char* resample_modes[] = {"auto", "off", "on", NULL};
static const char* av_sync_methods[] = {"metronom feedback", "resample", NULL};
- this = xine_xmalloc (sizeof (aos_t)) ;
+ this = calloc(1, sizeof(aos_t)) ;
this->driver = driver;
this->xine = xine;
this->clock = xine->clock;
+ this->current_speed = xine->clock->speed;
this->streams = xine_list_new();
/* warning: driver_lock is a recursive mutex. it must NOT be
@@ -2062,6 +2092,7 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver,
pthread_mutex_init( &this->streams_lock, NULL );
pthread_mutex_init( &this->driver_lock, &attr );
pthread_mutex_init( &this->driver_action_lock, NULL );
+ pthread_cond_init( &this->driver_action_cond, NULL );
this->ao.open = ao_open;
this->ao.get_buffer = ao_get_buffer;
@@ -2080,8 +2111,9 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver,
this->grab_only = grab_only;
this->flush_audio_driver = 0;
this->discard_buffers = 0;
- this->zero_space = xine_xmalloc (ZERO_BUF_SIZE * 4 * 6); /* MAX as 32bit, 6 channels. */
+ this->zero_space = calloc (1, ZERO_BUF_SIZE * 4 * 6); /* MAX as 32bit, 6 channels. */
+ pthread_mutex_init( &this->current_speed_lock, NULL );
pthread_mutex_init( &this->flush_audio_driver_lock, NULL );
pthread_cond_init( &this->flush_audio_driver_reached, NULL );
@@ -2191,8 +2223,8 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver,
audio_buffer_t *buf;
- buf = (audio_buffer_t *) xine_xmalloc (sizeof (audio_buffer_t));
- buf->mem = xine_xmalloc (AUDIO_BUF_SIZE);
+ buf = (audio_buffer_t *) calloc(1, sizeof(audio_buffer_t));
+ buf->mem = calloc (1, AUDIO_BUF_SIZE);
buf->mem_size = AUDIO_BUF_SIZE;
buf->extra_info = malloc(sizeof(extra_info_t));
@@ -2206,8 +2238,8 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver,
audio_buffer_t *buf;
- buf = (audio_buffer_t *) xine_xmalloc (sizeof (audio_buffer_t));
- buf->mem = xine_xmalloc (4*AUDIO_BUF_SIZE);
+ buf = (audio_buffer_t *) calloc(1, sizeof(audio_buffer_t));
+ buf->mem = calloc(4, AUDIO_BUF_SIZE);
buf->mem_size = 4*AUDIO_BUF_SIZE;
buf->extra_info = malloc(sizeof(extra_info_t));
diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h
index c4581ec24..5f4420363 100644
--- a/src/xine-engine/audio_out.h
+++ b/src/xine-engine/audio_out.h
@@ -259,7 +259,7 @@ struct audio_driver_class_s {
* this initiates the audio_out sync routines
* found in ./src/xine-engine/audio_out.c
*/
-xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, int grab_only) XINE_PROTECTED;
+xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, int grab_only) XINE_MALLOC XINE_PROTECTED;
/*
* audio output modes + capabilities
diff --git a/src/xine-engine/broadcaster.c b/src/xine-engine/broadcaster.c
index 1d2f01366..81711de49 100644
--- a/src/xine-engine/broadcaster.c
+++ b/src/xine-engine/broadcaster.c
@@ -32,6 +32,10 @@
* 'xine -V none -A none'
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -323,7 +327,7 @@ broadcaster_t *_x_init_broadcaster(xine_stream_t *stream, int port)
signal( SIGPIPE, SIG_IGN );
- this = xine_xmalloc(sizeof(broadcaster_t));
+ this = calloc(1, sizeof(broadcaster_t));
this->port = port;
this->stream = stream;
this->msock = msock;
diff --git a/src/xine-engine/broadcaster.h b/src/xine-engine/broadcaster.h
index 093fb4af0..b59d33349 100644
--- a/src/xine-engine/broadcaster.h
+++ b/src/xine-engine/broadcaster.h
@@ -27,13 +27,9 @@
extern "C" {
#endif
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
typedef struct broadcaster_s broadcaster_t;
-broadcaster_t *_x_init_broadcaster(xine_stream_t *stream, int port) XINE_PROTECTED;
+broadcaster_t *_x_init_broadcaster(xine_stream_t *stream, int port) XINE_MALLOC XINE_PROTECTED;
void _x_close_broadcaster(broadcaster_t *this) XINE_PROTECTED;
int _x_get_broadcaster_port(broadcaster_t *this) XINE_PROTECTED;
diff --git a/src/xine-engine/buffer.c b/src/xine-engine/buffer.c
index 93ad75ba0..417fee745 100644
--- a/src/xine-engine/buffer.c
+++ b/src/xine-engine/buffer.c
@@ -500,7 +500,7 @@ fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size) {
int alignment = 2048;
unsigned char *multi_buffer = NULL;
- this = xine_xmalloc (sizeof (fifo_buffer_t));
+ this = calloc(1, sizeof(fifo_buffer_t));
this->first = NULL;
this->last = NULL;
@@ -551,7 +551,7 @@ fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size) {
for (i = 0; i<num_buffers; i++) {
buf_element_t *buf;
- buf = xine_xmalloc (sizeof (buf_element_t));
+ buf = calloc(1, sizeof(buf_element_t));
buf->mem = multi_buffer;
multi_buffer += buf_size;
diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h
index 3a3f06e9b..6928ebd96 100644
--- a/src/xine-engine/buffer.h
+++ b/src/xine-engine/buffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2004 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -35,10 +35,7 @@
extern "C" {
#endif
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
+#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
@@ -191,6 +188,7 @@ extern "C" {
#define BUF_VIDEO_THEORA_RAW 0x02640000
#define BUF_VIDEO_VC1 0x02650000
#define BUF_VIDEO_VMNC 0x02660000
+#define BUF_VIDEO_SNOW 0x02670000
/* audio buffer types: (please keep in sync with buffer_types.c) */
@@ -258,6 +256,9 @@ extern "C" {
#define BUF_AUDIO_SMACKER 0x033B0000
#define BUF_AUDIO_FLVADPCM 0x033C0000
#define BUF_AUDIO_WAVPACK 0x033D0000
+#define BUF_AUDIO_MP3ADU 0x033E0000
+#define BUF_AUDIO_AMR_NB 0x033F0000
+#define BUF_AUDIO_AMR_WB 0x03400000
/* spu buffer types: */
@@ -373,13 +374,16 @@ struct buf_element_s {
* decoder_info[2] carries denominator for display aspect ratio */
#define BUF_FLAG_ASPECT 0x0800
+/* represent the state of gapless_switch at the time buf was enqueued */
+#define BUF_FLAG_GAPLESS_SW 0x1000
+
/* Amount of audio padding added by encoder (mp3, aac). These empty
* audio frames are causing a gap when switching between mp3 files.
* decoder_info[1] carries amount of audio frames padded at the
* beginning of the buffer
* decoder_info[2] carries amount of audio frames padded at the end of
* the buffer */
-#define BUF_FLAG_AUDIO_PADDING 0x1000
+#define BUF_FLAG_AUDIO_PADDING 0x2000
/* Special buffer types:
* Sometimes there is a need to relay special information from a demuxer
@@ -613,8 +617,8 @@ struct fifo_buffer_s
* allocate num_buffers of buf_size bytes each
*/
-fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size) XINE_PROTECTED;
-fifo_buffer_t *_x_dummy_fifo_buffer_new (int num_buffers, uint32_t buf_size) XINE_PROTECTED;
+fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size) XINE_MALLOC XINE_PROTECTED;
+fifo_buffer_t *_x_dummy_fifo_buffer_new (int num_buffers, uint32_t buf_size) XINE_MALLOC XINE_PROTECTED;
/* return BUF_VIDEO_xxx given the fourcc
@@ -624,16 +628,16 @@ fifo_buffer_t *_x_dummy_fifo_buffer_new (int num_buffers, uint32_t buf_size) XIN
uint32_t _x_fourcc_to_buf_video( uint32_t fourcc_int ) XINE_PROTECTED;
/* return codec name given BUF_VIDEO_xxx */
-char * _x_buf_video_name( uint32_t buf_type ) XINE_PROTECTED;
+const char * _x_buf_video_name( uint32_t buf_type ) XINE_PROTECTED;
/* return BUF_AUDIO_xxx given the formattag */
uint32_t _x_formattag_to_buf_audio( uint32_t formattag ) XINE_PROTECTED;
/* return codec name given BUF_AUDIO_xxx */
-char * _x_buf_audio_name( uint32_t buf_type ) XINE_PROTECTED;
+const char * _x_buf_audio_name( uint32_t buf_type ) XINE_PROTECTED;
-#ifndef ATTRIBUTE_PACKED
+#ifndef SUPPORT_ATTRIBUTE_PACKED
/* no attribute packed? let's try with pragma pack as a last resort */
#pragma pack(2)
#endif
@@ -642,7 +646,7 @@ char * _x_buf_audio_name( uint32_t buf_type ) XINE_PROTECTED;
* - will always use machine endian format, so demuxers reading
* stuff from win32 formats must use the function below.
*/
-typedef struct __attribute__((__packed__)) {
+typedef struct XINE_PACKED {
int32_t biSize;
int32_t biWidth;
int32_t biHeight;
@@ -659,7 +663,7 @@ typedef struct __attribute__((__packed__)) {
/* this is xine version of WAVEFORMATEX
* (the same comments from xine_bmiheader)
*/
-typedef struct __attribute__((__packed__)) {
+typedef struct XINE_PACKED {
int16_t wFormatTag;
int16_t nChannels;
int32_t nSamplesPerSec;
@@ -668,7 +672,7 @@ typedef struct __attribute__((__packed__)) {
int16_t wBitsPerSample;
int16_t cbSize;
} xine_waveformatex;
-#ifndef ATTRIBUTE_PACKED
+#ifndef SUPPORT_ATTRIBUTE_PACKED
#pragma pack()
#endif
@@ -678,6 +682,10 @@ void _x_bmiheader_le2me( xine_bmiheader *bih ) XINE_PROTECTED;
/* convert xine_waveformatex struct from little endian */
void _x_waveformatex_le2me( xine_waveformatex *wavex ) XINE_PROTECTED;
+static __inline int _x_is_fourcc(void *ptr, void *tag) {
+ return memcmp(ptr, tag, 4) == 0;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c
index 7242738e1..b7571d1d7 100644
--- a/src/xine-engine/buffer_types.c
+++ b/src/xine-engine/buffer_types.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2005 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -659,6 +659,8 @@ static const video_db_t video_db[] = {
ME_FOURCC('a','v','c','1'),
ME_FOURCC('h','2','6','4'),
ME_FOURCC('H','2','6','4'),
+ ME_FOURCC('x','2','6','4'),
+ ME_FOURCC('X','2','6','4'),
0
},
BUF_VIDEO_H264,
@@ -779,6 +781,14 @@ static const video_db_t video_db[] = {
BUF_VIDEO_VMNC,
"VMware Screen Codec"
},
+{
+ {
+ ME_FOURCC('S','N','O','W'),
+ 0
+ },
+ BUF_VIDEO_SNOW,
+ "Snow"
+},
{ { 0 }, 0, "last entry" }
};
@@ -806,6 +816,14 @@ static const audio_db_t audio_db[] = {
},
{
{
+ ME_FOURCC('a', 'd', 'u', 0x55),
+ 0
+ },
+ BUF_AUDIO_MP3ADU,
+ "MPEG layer-3 adu"
+},
+{
+ {
ME_FOURCC('t','w','o','s'),
ME_FOURCC('i','n','2','4'),
0
@@ -1132,11 +1150,32 @@ static const audio_db_t audio_db[] = {
},
{
{
- 0
+ ME_FOURCC('W', 'V', 'P', 'K'),
},
BUF_AUDIO_WAVPACK,
"Wavpack"
},
+{
+ {
+ ME_FOURCC('s', 'a', 'm', 'r'),
+ },
+ BUF_AUDIO_AMR_NB,
+ "AMR narrow band"
+},
+{
+ {
+ ME_FOURCC('s', 'a', 'w', 'b'),
+ },
+ BUF_AUDIO_AMR_WB,
+ "AMR wide band"
+},
+{
+ {
+ ME_FOURCC('T', 'T', 'A', '1'),
+ },
+ BUF_AUDIO_TTA,
+ "True Audio Lossless"
+},
{ { 0 }, 0, "last entry" }
};
@@ -1161,7 +1200,7 @@ static uint32_t cached_buf_type=0;
return 0;
}
-char * _x_buf_video_name( uint32_t buf_type ) {
+const char * _x_buf_video_name( uint32_t buf_type ) {
int i;
buf_type &= 0xffff0000;
@@ -1195,7 +1234,7 @@ static uint32_t cached_buf_type=0;
return 0;
}
-char * _x_buf_audio_name( uint32_t buf_type ) {
+const char * _x_buf_audio_name( uint32_t buf_type ) {
int i;
buf_type &= 0xffff0000;
diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c
index 2dc89f0af..81acab348 100644
--- a/src/xine-engine/configfile.c
+++ b/src/xine-engine/configfile.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2004 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -319,11 +319,11 @@ static void config_insert(config_values_t *this, cfg_entry_t *new_entry) {
this->first = new_entry;
}
-static cfg_entry_t *config_add (config_values_t *this, const char *key, int exp_level) {
+static cfg_entry_t *XINE_MALLOC config_add (config_values_t *this, const char *key, int exp_level) {
cfg_entry_t *entry;
- entry = (cfg_entry_t *) xine_xmalloc (sizeof (cfg_entry_t));
+ entry = calloc (1, sizeof (cfg_entry_t));
entry->config = this;
entry->key = strdup(key);
entry->type = XINE_CONFIG_TYPE_UNKNOWN;
@@ -356,22 +356,22 @@ static const char *config_xlate_internal (const char *key, const xine_config_ent
return NULL;
}
-static const char *config_translate_key (const char *key) {
+static const char *config_translate_key (const char *key, char **tmp) {
/* Returns translated key or, if no translation found, NULL.
* Translated key may be in a static buffer allocated within this function.
* NOT re-entrant; assumes that config_lock is held.
*/
unsigned trans;
- static char *newkey = NULL;
+ const char *newkey = NULL;
/* first, special-case the decoder entries (so that new ones can be added
* without requiring modification of the translation table)
*/
+ *tmp = NULL;
if (!strncmp (key, "decoder.", 8) &&
!strcmp (key + (trans = strlen (key)) - 9, "_priority")) {
- newkey = realloc (newkey, trans + 27 - 17); /* diff. in string lengths */
- sprintf (newkey, "engine.decoder_priorities.%.*s", trans - 17, key + 8);
- return newkey;
+ asprintf (tmp, "engine.decoder_priorities.%.*s", trans - 17, key + 8);
+ return *tmp;
}
/* search the translation table... */
@@ -386,6 +386,7 @@ static void config_lookup_entry_int (config_values_t *this, const char *key,
cfg_entry_t **entry, cfg_entry_t **prev) {
int trans;
+ char *tmp = NULL;
/* try twice at most (second time with translation from old key name) */
for (trans = 2; trans; --trans) {
@@ -397,14 +398,18 @@ static void config_lookup_entry_int (config_values_t *this, const char *key,
*entry = (*entry)->next;
}
- if (*entry)
+ if (*entry) {
+ free(tmp);
return;
+ }
/* we did not find a match, maybe this is an old config entry name
* trying to translate */
- key = config_translate_key(key);
- if (!key)
+ key = config_translate_key(key, &tmp);
+ if (!key) {
+ free(tmp);
return;
+ }
}
}
@@ -748,7 +753,7 @@ static int config_register_enum (config_values_t *this,
entry->type = XINE_CONFIG_TYPE_ENUM;
if (entry->unknown_value)
- entry->num_value = config_parse_enum (entry->unknown_value, values);
+ entry->num_value = config_parse_enum (entry->unknown_value, (const char **)values);
else
entry->num_value = def_value;
@@ -756,14 +761,14 @@ static int config_register_enum (config_values_t *this,
entry->num_default = def_value;
/* allocate and copy the enum values */
- value_src = values;
+ value_src = (const char **)values;
value_count = 0;
while (*value_src) {
value_src++;
value_count++;
}
entry->enum_values = malloc (sizeof(char*) * (value_count + 1));
- value_src = values;
+ value_src = (const char **)values;
value_dest = entry->enum_values;
while (*value_src) {
*value_dest = strdup(*value_src);
@@ -862,7 +867,7 @@ static void config_update_string (config_values_t *this,
/* if an enum is updated with a string, we convert the string to
* its index and use update number */
if (entry->type == XINE_CONFIG_TYPE_ENUM) {
- config_update_num(this, key, config_parse_enum(value, entry->enum_values));
+ config_update_num(this, key, config_parse_enum(value, (const char **)entry->enum_values));
return;
}
@@ -944,15 +949,17 @@ void xine_config_load (xine_t *xine, const char *filename) {
if (!(entry = config_lookup_entry(this, line))) {
const char *key = line;
+ char *tmp = NULL;
pthread_mutex_lock(&this->config_lock);
if (this->current_version < CONFIG_FILE_VERSION) {
/* old config file -> let's see if we have to rename this one */
- key = config_translate_key(key);
+ key = config_translate_key(key, &tmp);
if (!key)
key = line; /* no translation? fall back on untranslated key */
}
entry = config_add (this, key, 50);
entry->unknown_value = strdup(value);
+ free(tmp);
pthread_mutex_unlock(&this->config_lock);
} else {
switch (entry->type) {
@@ -1005,7 +1012,7 @@ void xine_config_save (xine_t *xine, const char *filename) {
char *buf = NULL;
size_t rlen;
- buf = (char *) xine_xmalloc(config_stat.st_size + 1);
+ buf = (char *) malloc(config_stat.st_size + 1);
if((rlen = fread(buf, 1, config_stat.st_size, f_config)) && ((off_t)rlen == config_stat.st_size)) {
(void) fwrite(buf, 1, rlen, f_backup);
}
@@ -1204,7 +1211,7 @@ config_values_t *_x_config_init (void) {
config_values_t *this;
pthread_mutexattr_t attr;
- if (!(this = xine_xmalloc(sizeof(config_values_t)))) {
+ if (!(this = calloc(1, sizeof(config_values_t)))) {
printf ("configfile: could not allocate config object\n");
_x_abort();
diff --git a/src/xine-engine/configfile.h b/src/xine-engine/configfile.h
index e21b08db0..e1dca7b18 100644
--- a/src/xine-engine/configfile.h
+++ b/src/xine-engine/configfile.h
@@ -200,7 +200,7 @@ struct config_values_s {
/*
* allocate and init a new xine config object
*/
-config_values_t *_x_config_init (void) XINE_PROTECTED;
+config_values_t *_x_config_init (void) XINE_MALLOC XINE_PROTECTED;
/*
* interpret stream_setup part of mrls for config value changes
diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c
index f33397256..698b44988 100644
--- a/src/xine-engine/demux.c
+++ b/src/xine-engine/demux.c
@@ -21,6 +21,9 @@
* hide some xine engine details from demuxers and reduce code duplication
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#include <stdio.h>
#include <string.h>
@@ -47,11 +50,6 @@
#include <winsock.h>
#endif
-#ifdef MIN
-#undef MIN
-#endif
-#define MIN(a,b) ( (a) < (b) ) ? (a) : (b)
-
/*
* Flush audio and video buffers. It is called from demuxers on
* seek/stop, and may be useful when user input changes a stream and
@@ -122,6 +120,16 @@ void _x_demux_flush_engine (xine_stream_t *stream) {
}
+static struct timespec _x_compute_interval(unsigned int millisecs) {
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ uint64_t ttimer = (uint64_t)ts.tv_sec*1000 + ts.tv_nsec/1000000 + millisecs;
+ ts.tv_sec = ttimer/1000;
+ ts.tv_nsec = (ttimer%1000)*1000000;
+ return ts;
+}
+
+
void _x_demux_control_newpts( xine_stream_t *stream, int64_t pts, uint32_t flags ) {
buf_element_t *buf;
@@ -143,6 +151,29 @@ void _x_demux_control_newpts( xine_stream_t *stream, int64_t pts, uint32_t flags
pthread_mutex_unlock(&stream->demux_mutex);
}
+/* avoid ao_loop being stuck in a pthread_cond_wait, waiting for data;
+ * return 1 if the stream is stopped
+ * (better fix wanted!)
+ */
+static int demux_unstick_ao_loop (xine_stream_t *stream)
+{
+/* if (!stream->audio_thread_created)
+ return 0;
+*/
+ int status = xine_get_status (stream);
+ if (status != XINE_STATUS_QUIT && status != XINE_STATUS_STOP && stream->demux_plugin->get_status(stream->demux_plugin) != DEMUX_FINISHED)
+ return 0;
+#if 0
+ /* right, stream is stopped... */
+ audio_buffer_t *buf = stream->audio_out->get_buffer (stream->audio_out);
+ buf->num_frames = 0;
+ buf->stream = NULL;
+ stream->audio_out->put_buffer (stream->audio_out, buf, stream);
+#endif
+ lprintf("stuck\n");
+ return 1;
+}
+
/* sync with decoder fifos, making sure everything gets processed */
void _x_demux_control_headers_done (xine_stream_t *stream) {
@@ -180,24 +211,31 @@ void _x_demux_control_headers_done (xine_stream_t *stream) {
stream->audio_fifo->put (stream->audio_fifo, buf_audio);
pthread_mutex_unlock(&stream->demux_mutex);
+ unsigned int max_iterations = 0;
while ((stream->header_count_audio < header_count_audio) ||
(stream->header_count_video < header_count_video)) {
- struct timeval tv;
- struct timespec ts;
lprintf ("waiting for headers. v:%d %d a:%d %d\n",
stream->header_count_video, header_count_video,
stream->header_count_audio, header_count_audio);
+
+ struct timespec ts = _x_compute_interval(1000);
+ int ret_wait;
- gettimeofday(&tv, NULL);
- ts.tv_sec = tv.tv_sec + 1;
- ts.tv_nsec = tv.tv_usec * 1000;
/* use timedwait to workaround buggy pthread broadcast implementations */
- pthread_cond_timedwait (&stream->counter_changed, &stream->counter_lock, &ts);
+ ret_wait = pthread_cond_timedwait (&stream->counter_changed, &stream->counter_lock, &ts);
+
+ if (ret_wait == ETIMEDOUT && demux_unstick_ao_loop (stream) && ++max_iterations > 4) {
+ xine_log(stream->xine,
+ XINE_LOG_MSG,_("Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n"));
+ stream->emergency_brake = 1;
+ break;
+ }
}
stream->demux_action_pending = 0;
+ pthread_cond_signal(&stream->demux_resume);
lprintf ("headers processed.\n");
@@ -207,15 +245,18 @@ void _x_demux_control_headers_done (xine_stream_t *stream) {
void _x_demux_control_start( xine_stream_t *stream ) {
buf_element_t *buf;
+ uint32_t flags = (stream->gapless_switch) ? BUF_FLAG_GAPLESS_SW : 0;
pthread_mutex_lock(&stream->demux_mutex);
buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
buf->type = BUF_CONTROL_START;
+ buf->decoder_flags = flags;
stream->video_fifo->put (stream->video_fifo, buf);
buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
buf->type = BUF_CONTROL_START;
+ buf->decoder_flags = flags;
stream->audio_fifo->put (stream->audio_fifo, buf);
pthread_mutex_unlock(&stream->demux_mutex);
@@ -284,12 +325,14 @@ static void *demux_loop (void *stream_gen) {
/* someone may want to interrupt us */
if( stream->demux_action_pending ) {
- pthread_mutex_unlock( &stream->demux_lock );
-
- lprintf ("sched_yield\n");
+ struct timeval tv;
+ struct timespec ts;
- sched_yield();
- pthread_mutex_lock( &stream->demux_lock );
+ gettimeofday(&tv, NULL);
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = (tv.tv_usec + 100000) * 1000;
+
+ pthread_cond_timedwait (&stream->demux_resume, &stream->demux_lock, &ts);
}
}
@@ -345,10 +388,21 @@ static void *demux_loop (void *stream_gen) {
pthread_mutex_unlock( &stream->demux_lock );
pthread_mutex_lock (&stream->counter_lock);
+ struct timespec ts;
+ unsigned int max_iterations = 0;
+ int ret_wait;
while ((stream->finished_count_audio < finished_count_audio) ||
(stream->finished_count_video < finished_count_video)) {
lprintf ("waiting for finisheds.\n");
- pthread_cond_wait (&stream->counter_changed, &stream->counter_lock);
+ ts = _x_compute_interval(1000);
+ ret_wait = pthread_cond_timedwait (&stream->counter_changed, &stream->counter_lock, &ts);
+
+ if (ret_wait == ETIMEDOUT && demux_unstick_ao_loop (stream) && ++max_iterations > 4) {
+ xine_log(stream->xine,
+ XINE_LOG_MSG,_("Stuck in demux_loop(). Taking the emergency exit\n"));
+ stream->emergency_brake = 1;
+ break;
+ }
}
pthread_mutex_unlock (&stream->counter_lock);
@@ -365,6 +419,7 @@ int _x_demux_start_thread (xine_stream_t *stream) {
stream->demux_action_pending = 1;
pthread_mutex_lock( &stream->demux_lock );
stream->demux_action_pending = 0;
+ pthread_cond_signal(&stream->demux_resume);
if( !stream->demux_thread_running ) {
@@ -396,6 +451,7 @@ int _x_demux_stop_thread (xine_stream_t *stream) {
pthread_mutex_lock( &stream->demux_lock );
stream->demux_thread_running = 0;
stream->demux_action_pending = 0;
+ pthread_cond_signal(&stream->demux_resume);
/* At that point, the demuxer has sent the last audio/video buffer,
* so it's a safe place to flush the engine.
@@ -435,7 +491,7 @@ int _x_demux_read_header( input_plugin_t *input, unsigned char *buffer, off_t si
read_size = input->read(input, buffer, size);
input->seek(input, 0, SEEK_SET);
} else if (input->get_capabilities(input) & INPUT_CAP_PREVIEW) {
- buf = xine_xmalloc(MAX_PREVIEW_SIZE);
+ buf = malloc(MAX_PREVIEW_SIZE);
read_size = input->get_optional_data(input, buf, INPUT_OPTIONAL_DATA_PREVIEW);
read_size = MIN (read_size, size);
memcpy(buffer, buf, read_size);
@@ -652,7 +708,7 @@ void _x_demux_send_mrl_reference (xine_stream_t *stream, int alternative,
xine_mrl_reference_data_ext_t *e;
xine_mrl_reference_data_t *b;
} data;
- int mrl_len = strlen (mrl);
+ const size_t mrl_len = strlen (mrl);
if (!title)
title = "";
diff --git a/src/xine-engine/info_helper.c b/src/xine-engine/info_helper.c
index 1ac4ed982..6ce9bcd38 100644
--- a/src/xine-engine/info_helper.c
+++ b/src/xine-engine/info_helper.c
@@ -131,7 +131,7 @@ uint32_t _x_stream_info_get_public(xine_stream_t *stream, int info) {
* at the end of the string
*/
static void meta_info_chomp(char *str) {
- int i, len;
+ ssize_t i, len;
len = strlen(str);
if (!len)
@@ -251,7 +251,15 @@ static void meta_info_set_unlocked_encoding(xine_stream_t *stream, int info, con
size_t inbytesleft, outbytesleft;
inbuf = (ICONV_CONST char *)value;
- inbytesleft = strlen(value);
+ if (!strncmp (enc, "UTF-16", 6) || !strncmp (enc, "UCS-2", 5))
+ {
+ /* strlen() won't work with UTF-16* or UCS-2* */
+ inbytesleft = 0;
+ while (value[inbytesleft] || value[inbytesleft + 1])
+ inbytesleft += 2;
+ } /* ... do we need to handle UCS-4? Probably not. */
+ else
+ inbytesleft = strlen(value);
outbytesleft = 4 * inbytesleft; /* estimative (max) */
outbuf = utf8_value = malloc(outbytesleft+1);
@@ -340,11 +348,10 @@ void _x_meta_info_set_utf8(xine_stream_t *stream, int info, const char *str) {
void _x_meta_info_n_set(xine_stream_t *stream, int info, const char *buf, int len) {
pthread_mutex_lock(&stream->meta_mutex);
if(meta_valid(info) && len) {
- char *str = xine_xmalloc(len + 1);
+ char *str = strndup(buf, len);
- snprintf(str, len + 1 , "%s", buf);
- meta_info_set_unlocked(stream, info, (const char *) &str[0]);
- free(str);
+ meta_info_set_unlocked(stream, info, str);
+ free(str);
}
pthread_mutex_unlock(&stream->meta_mutex);
}
@@ -359,7 +366,7 @@ void _x_meta_info_set_multi(xine_stream_t *stream, int info, ...) {
va_list ap;
char *args[1025];
char *buf;
- int n, len;
+ size_t n, len;
len = n = 0;
@@ -376,7 +383,7 @@ void _x_meta_info_set_multi(xine_stream_t *stream, int info, ...) {
if(len) {
char *p, *meta;
- p = meta = (char *) xine_xmalloc(len + 1);
+ p = meta = (char *) malloc(len + 1);
n = 0;
while(args[n]) {
diff --git a/src/xine-engine/input_cache.c b/src/xine-engine/input_cache.c
index 30b1ba4aa..4eb524af6 100644
--- a/src/xine-engine/input_cache.c
+++ b/src/xine-engine/input_cache.c
@@ -356,7 +356,7 @@ input_plugin_t *_x_cache_plugin_get_instance (xine_stream_t *stream, int readahe
lprintf("mrl: %s\n", main_plugin->get_mrl(main_plugin));
- this = (cache_input_plugin_t *)xine_xmalloc(sizeof(cache_input_plugin_t));
+ this = calloc(1, sizeof(cache_input_plugin_t));
if (!this)
return NULL;
@@ -386,7 +386,7 @@ input_plugin_t *_x_cache_plugin_get_instance (xine_stream_t *stream, int readahe
this->buf_size = DEFAULT_BUFFER_SIZE;
}
- this->buf = (char *)xine_xmalloc(this->buf_size);
+ this->buf = calloc(1, this->buf_size);
if (!this->buf) {
free (this);
return NULL;
diff --git a/src/xine-engine/input_rip.c b/src/xine-engine/input_rip.c
index 0c185aa1b..8db7eaaf5 100644
--- a/src/xine-engine/input_rip.c
+++ b/src/xine-engine/input_rip.c
@@ -517,10 +517,9 @@ static void rip_plugin_dispose(input_plugin_t *this_gen) {
* returns non-zero, if there was enough space
*/
static int dir_file_concat(char *target, size_t maxlen, const char *dir, const char *name) {
- size_t len_dir, len_name, pos_name = 0;
-
- len_name = strlen(name);
- len_dir = strlen(dir);
+ size_t len_name = strlen(name);
+ size_t len_dir = strlen(dir);
+ size_t pos_name = 0;
/* remove slashes */
if (dir[len_dir - 1] == '/') len_dir--;
@@ -585,7 +584,7 @@ input_plugin_t *_x_rip_plugin_get_instance (xine_stream_t *stream, const char *f
return NULL;
}
- this = (rip_input_plugin_t *)xine_xmalloc(sizeof(rip_input_plugin_t));
+ this = calloc(1, sizeof(rip_input_plugin_t));
this->main_input_plugin = main_plugin;
this->stream = stream;
this->curpos = 0;
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index 71cb19d3b..5128644da 100644
--- a/src/xine-engine/load_plugins.c
+++ b/src/xine-engine/load_plugins.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2006 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -313,7 +313,6 @@ static void _insert_node (xine_t *this,
const input_info_t *input_old;
uint32_t *types;
char key[80];
- char desc[100];
int i;
_x_assert(list);
@@ -325,8 +324,8 @@ static void _insert_node (xine_t *this,
return;
}
- entry = xine_xmalloc(sizeof(plugin_node_t));
- entry->info = xine_xmalloc(sizeof(plugin_info_t));
+ entry = calloc(1, sizeof(plugin_node_t));
+ entry->info = calloc(1, sizeof(plugin_info_t));
*(entry->info) = *info;
entry->info->id = strdup(info->id);
entry->info->init = info->init;
@@ -339,7 +338,7 @@ static void _insert_node (xine_t *this,
case PLUGIN_VIDEO_OUT:
vo_old = info->special_info;
- vo_new = xine_xmalloc(sizeof(vo_info_t));
+ vo_new = calloc(1, sizeof(vo_info_t));
entry->priority = vo_new->priority = vo_old->priority;
vo_new->visual_type = vo_old->visual_type;
entry->info->special_info = vo_new;
@@ -347,7 +346,7 @@ static void _insert_node (xine_t *this,
case PLUGIN_AUDIO_OUT:
ao_old = info->special_info;
- ao_new = xine_xmalloc(sizeof(ao_info_t));
+ ao_new = calloc(1, sizeof(ao_info_t));
entry->priority = ao_new->priority = ao_old->priority;
entry->info->special_info = ao_new;
break;
@@ -356,7 +355,7 @@ static void _insert_node (xine_t *this,
case PLUGIN_VIDEO_DECODER:
case PLUGIN_SPU_DECODER:
decoder_old = info->special_info;
- decoder_new = xine_xmalloc(sizeof(decoder_info_t));
+ decoder_new = calloc(1, sizeof(decoder_info_t));
if (decoder_old == NULL) {
if (file)
xprintf (this, XINE_VERBOSITY_DEBUG,
@@ -368,22 +367,21 @@ static void _insert_node (xine_t *this,
info->id);
_x_abort();
}
- for (i=0; decoder_old->supported_types[i] != 0; ++i);
- types = xine_xmalloc((i+1)*sizeof(uint32_t));
- for (i=0; decoder_old->supported_types[i] != 0; ++i){
- types[i] = decoder_old->supported_types[i];
+ {
+ size_t supported_types_size;
+ for (supported_types_size=0; decoder_old->supported_types[supported_types_size] != 0; ++supported_types_size);
+ types = calloc((supported_types_size+1), sizeof(uint32_t));
+ memcpy(types, decoder_old->supported_types, supported_types_size*sizeof(uint32_t));
+ decoder_new->supported_types = types;
}
- decoder_new->supported_types = types;
entry->priority = decoder_new->priority = decoder_old->priority;
snprintf(key, sizeof(key), "engine.decoder_priorities.%s", info->id);
- snprintf(desc, sizeof(desc), _("priority for %s decoder"), info->id);
/* write the description on the heap because the config system
* does not strdup() it, so we have to provide a different pointer
* for each decoder */
for (i = 0; catalog->prio_desc[i]; i++);
- catalog->prio_desc[i] = malloc(strlen(desc) + 1);
- strcpy(catalog->prio_desc[i], desc);
+ asprintf(&catalog->prio_desc[i], _("priority for %s decoder"), info->id);
this->config->register_num (this->config,
key,
0,
@@ -402,14 +400,14 @@ static void _insert_node (xine_t *this,
case PLUGIN_POST:
post_old = info->special_info;
- post_new = xine_xmalloc(sizeof(post_info_t));
+ post_new = calloc(1, sizeof(post_info_t));
post_new->type = post_old->type;
entry->info->special_info = post_new;
break;
case PLUGIN_DEMUX:
demux_old = info->special_info;
- demux_new = xine_xmalloc(sizeof(demuxer_info_t));
+ demux_new = calloc(1, sizeof(demuxer_info_t));
if (demux_old) {
entry->priority = demux_new->priority = demux_old->priority;
@@ -426,7 +424,7 @@ static void _insert_node (xine_t *this,
case PLUGIN_INPUT:
input_old = info->special_info;
- input_new = xine_xmalloc(sizeof(input_info_t));
+ input_new = calloc(1, sizeof(input_info_t));
if (input_old) {
entry->priority = input_new->priority = input_old->priority;
@@ -463,12 +461,12 @@ static int _plugin_node_comparator(void *a, void *b) {
}
}
-static plugin_catalog_t *_new_catalog(void){
+static plugin_catalog_t *XINE_MALLOC _new_catalog(void){
plugin_catalog_t *catalog;
int i;
- catalog = xine_xmalloc(sizeof(plugin_catalog_t));
+ catalog = calloc(1, sizeof(plugin_catalog_t));
for (i = 0; i < PLUGIN_TYPE_MAX; i++) {
catalog->plugin_lists[i] = xine_sarray_new(0, _plugin_node_comparator);
@@ -487,7 +485,7 @@ static void _register_plugins_internal(xine_t *this, plugin_file_t *file, plugin
while ( info && info->type != PLUGIN_NONE ) {
- if (file)
+ if (file && file->filename)
xine_log (this, XINE_LOG_PLUGIN,
_("load_plugins: plugin %s found\n"), file->filename);
else
@@ -556,25 +554,20 @@ static void collect_plugins(xine_t *this, char *path){
dir = opendir(path);
if (dir) {
struct dirent *pEntry;
- size_t path_len, str_size;
- char *str = NULL;
- path_len = strlen(path);
- str_size = path_len * 2 + 2; /* +2 for '/' and '\0' */
- str = malloc(str_size);
- xine_fast_memcpy(str, path, path_len);
- str[path_len] = '/';
- str[path_len + 1] = '\0';
+ size_t path_len = strlen(path);
+ size_t str_size = path_len * 2 + 2; /* +2 for '/' and '\0' */
+ char *str = malloc(str_size);
+ sprintf(str, "%s/", path);
while ((pEntry = readdir (dir)) != NULL) {
- size_t new_str_size, d_len;
void *lib = NULL;
plugin_info_t *info = NULL;
struct stat statbuffer;
- d_len = strlen(pEntry->d_name);
- new_str_size = path_len + d_len + 2;
+ size_t d_len = strlen(pEntry->d_name);
+ size_t new_str_size = path_len + d_len + 2;
if (str_size < new_str_size) {
str_size = new_str_size + new_str_size / 2;
str = realloc(str, str_size);
@@ -599,7 +592,7 @@ static void collect_plugins(xine_t *this, char *path){
#if defined(__hpux)
if(!strstr(str, ".sl")
#elif defined(__CYGWIN__) || defined(WIN32)
- if(!strstr(str, ".dll")
+ if(!strstr(str, ".dll") || strstr(str, ".dll.a")
#else
if(!strstr(str, ".so")
#endif
@@ -941,11 +934,11 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
if( node ) {
xine_sarray_add (plugins, node);
}
- node = xine_xmalloc(sizeof(plugin_node_t));
- file = xine_xmalloc(sizeof(plugin_file_t));
+ node = calloc(1, sizeof(plugin_node_t));
+ file = calloc(1, sizeof(plugin_file_t));
node->file = file;
file->filename = strdup(line+1);
- node->info = xine_xmalloc(2*sizeof(plugin_info_t));
+ node->info = calloc(2, sizeof(plugin_info_t));
node->info[1].type = PLUGIN_NONE;
decoder_info = NULL;
vo_info = NULL;
@@ -981,34 +974,34 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
case PLUGIN_VIDEO_OUT:
node->info->special_info = vo_info =
- xine_xmalloc(sizeof(vo_info_t));
+ calloc(1, sizeof(vo_info_t));
break;
case PLUGIN_AUDIO_OUT:
node->info->special_info = ao_info =
- xine_xmalloc(sizeof(ao_info_t));
+ calloc(1, sizeof(ao_info_t));
break;
case PLUGIN_DEMUX:
node->info->special_info = demuxer_info =
- xine_xmalloc(sizeof(demuxer_info_t));
+ calloc(1, sizeof(demuxer_info_t));
break;
case PLUGIN_INPUT:
node->info->special_info = input_info =
- xine_xmalloc(sizeof(input_info_t));
+ calloc(1, sizeof(input_info_t));
break;
case PLUGIN_AUDIO_DECODER:
case PLUGIN_VIDEO_DECODER:
case PLUGIN_SPU_DECODER:
node->info->special_info = decoder_info =
- xine_xmalloc(sizeof(decoder_info_t));
+ calloc(1, sizeof(decoder_info_t));
break;
case PLUGIN_POST:
node->info->special_info = post_info =
- xine_xmalloc(sizeof(post_info_t));
+ calloc(1, sizeof(post_info_t));
break;
}
@@ -1029,7 +1022,7 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
for( s = value, i = 0; s && sscanf(s," %lu",&lu) > 0; i++ ) {
s = strchr(s+1, ' ');
}
- decoder_info->supported_types = xine_xmalloc((i+1)*sizeof(uint32_t));
+ decoder_info->supported_types = calloc((i+1), sizeof(uint32_t));
for( s = value, i = 0; s && sscanf(s," %lu",&lu) > 0; i++ ) {
decoder_info->supported_types[i] = lu;
s = strchr(s+1, ' ');
@@ -1069,22 +1062,21 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
static void save_catalog (xine_t *this) {
FILE *fp;
- char *cachefile, *dirfile;
+ char *cachefile, *cachefile_new, *dirfile;
const char *relname = CACHE_CATALOG_FILE;
const char *dirname = CACHE_CATALOG_DIR;
+
+ const char *const homedir = xine_get_homedir();
- cachefile = (char *) xine_xmalloc(strlen(xine_get_homedir()) +
- strlen(relname) + 2);
- sprintf(cachefile, "%s/%s", xine_get_homedir(), relname);
+ asprintf(&cachefile, "%s/%s", homedir, relname);
+ asprintf(&cachefile_new, "%s.new", cachefile);
/* make sure homedir (~/.xine) exists */
- dirfile = (char *) xine_xmalloc(strlen(xine_get_homedir()) +
- strlen(dirname) + 2);
- sprintf(dirfile, "%s/%s", xine_get_homedir(), dirname);
+ asprintf(&dirfile, "%s/%s", homedir, dirname);
mkdir (dirfile, 0755);
free (dirfile);
- if( (fp = fopen(cachefile,"w")) != NULL ) {
+ if( (fp = fopen(cachefile_new,"w")) != NULL ) {
int i;
fprintf(fp, "# this file is automatically created by xine, do not edit.\n\n");
@@ -1093,9 +1085,29 @@ static void save_catalog (xine_t *this) {
for (i = 0; i < PLUGIN_TYPE_MAX; i++) {
save_plugin_list (fp, this->plugin_catalog->plugin_lists[i]);
}
- fclose(fp);
+ if (fclose(fp))
+ {
+ const char *err = strerror (errno);
+ xine_log (this, XINE_LOG_MSG,
+ _("failed to save catalogue cache: %s\n"), err);
+ goto do_unlink;
+ }
+ else if (rename (cachefile_new, cachefile))
+ {
+ const char *err = strerror (errno);
+ xine_log (this, XINE_LOG_MSG,
+ _("failed to replace catalogue cache: %s\n"), err);
+ do_unlink:
+ if (unlink (cachefile_new) && errno != ENOENT)
+ {
+ err = strerror (errno);
+ xine_log (this, XINE_LOG_MSG,
+ _("failed to remove new catalogue cache: %s\n"), err);
+ }
+ }
}
free(cachefile);
+ free(cachefile_new);
}
/*
@@ -1107,9 +1119,7 @@ static void load_cached_catalog (xine_t *this) {
char *cachefile;
const char *relname = CACHE_CATALOG_FILE;
- cachefile = (char *) xine_xmalloc(strlen(xine_get_homedir()) +
- strlen(relname) + 2);
- sprintf(cachefile, "%s/%s", xine_get_homedir(), relname);
+ asprintf(&cachefile, "%s/%s", xine_get_homedir(), relname);
if( (fp = fopen(cachefile,"r")) != NULL ) {
load_plugin_list (fp, this->plugin_catalog->cache_list);
@@ -1119,14 +1129,24 @@ static void load_cached_catalog (xine_t *this) {
}
+/* helper function for _x_scan_plugins */
+static void push_if_dir (xine_list_t *plugindirs, void *path)
+{
+ struct stat st;
+ if (!stat (path, &st) && S_ISDIR (st.st_mode))
+ xine_list_push_back (plugindirs, path);
+ else
+ free (path);
+}
+
/*
* initialize catalog, load all plugins into new catalog
*/
void _x_scan_plugins (xine_t *this) {
-
- char *homedir, *plugindir, *pluginpath;
- int i,j;
- int lenpluginpath;
+
+ char *homedir, *pluginpath;
+ xine_list_t *plugindirs = xine_list_new ();
+ xine_list_iterator_t iter;
lprintf("_x_scan_plugins()\n");
@@ -1140,41 +1160,45 @@ void _x_scan_plugins (xine_t *this) {
this->plugin_catalog = _new_catalog();
load_cached_catalog (this);
- if ((pluginpath = getenv("XINE_PLUGIN_PATH")) != NULL) {
- pluginpath = strdup(pluginpath);
+ if ((pluginpath = getenv("XINE_PLUGIN_PATH")) != NULL && *pluginpath) {
+ char *p = pluginpath;
+ while (p && p[0])
+ {
+ size_t len;
+ char *dir, *q;
+
+ q = p;
+ p = strchr (p, XINE_PATH_SEPARATOR_CHAR);
+ if (p) {
+ p++;
+ len = p - q;
+ } else
+ len = strlen(q);
+ if (q[0] == '~' && q[1] == '/')
+ asprintf (&dir, "%s%.*s", homedir, (int)(len - 1), q + 1);
+ else
+ dir = strndup (q, len);
+ push_if_dir (plugindirs, dir); /* store or free it */
+ }
} else {
- const char *str1, *str2;
- int len;
-
- str1 = "~/.xine/plugins";
- str2 = XINE_PLUGINDIR;
- len = strlen(str1) + strlen(str2) + 2;
- pluginpath = xine_xmalloc(len);
- snprintf(pluginpath, len, "%s" XINE_PATH_SEPARATOR_STRING "%s", str1, str2);
- }
- plugindir = xine_xmalloc(strlen(pluginpath)+strlen(homedir)+2);
- j=0;
- lenpluginpath = strlen(pluginpath);
- for (i=0; i <= lenpluginpath; ++i){
- switch (pluginpath[i]){
- case XINE_PATH_SEPARATOR_CHAR:
- case '\0':
- plugindir[j] = '\0';
- collect_plugins(this, plugindir);
- j = 0;
- break;
- case '~':
- if (j == 0){
- strcpy(plugindir, homedir);
- j = strlen(plugindir);
- break;
- }
- default:
- plugindir[j++] = pluginpath[i];
+ char *dir;
+ int i;
+ asprintf (&dir, "%s/.xine/plugins", homedir);
+ push_if_dir (plugindirs, dir);
+ for (i = 0; i <= XINE_LT_AGE; ++i)
+ {
+ asprintf (&dir, "%s.%d", XINE_PLUGINROOT, XINE_LT_AGE - i);
+ push_if_dir (plugindirs, dir);
}
}
- free(plugindir);
- free(pluginpath);
+ for (iter = xine_list_front (plugindirs); iter;
+ iter = xine_list_next (plugindirs, iter))
+ {
+ char *dir = xine_list_get_value (plugindirs, iter);
+ collect_plugins(this, dir);
+ free (dir);
+ }
+ xine_list_delete (plugindirs);
free(homedir);
save_catalog (this);
@@ -1229,6 +1253,26 @@ void _x_free_input_plugin (xine_stream_t *stream, input_plugin_t *input) {
}
}
+static int probe_mime_type (xine_t *self, plugin_node_t *node, const char *mime_type)
+{
+ /* catalog->lock is expected to be locked */
+ if (node->plugin_class || _load_plugin_class(self, node, NULL))
+ {
+ const unsigned int mime_type_len = strlen (mime_type);
+ demux_class_t *cls = (demux_class_t *)node->plugin_class;
+ const char *mime = cls->get_mimetypes (cls);
+ while (mime)
+ {
+ while (*mime == ';' || isspace (*mime))
+ ++mime;
+ if (!strncasecmp (mime, mime_type, mime_type_len) &&
+ (!mime[mime_type_len] || mime[mime_type_len] == ':' || mime[mime_type_len] == ';'))
+ return 1;
+ mime = strchr (mime, ';');
+ }
+ }
+ return 0;
+}
static demux_plugin_t *probe_demux (xine_stream_t *stream, int method1, int method2,
input_plugin_t *input) {
@@ -1251,8 +1295,6 @@ static demux_plugin_t *probe_demux (xine_stream_t *stream, int method1, int meth
while (methods[i] != -1 && !plugin) {
int list_id, list_size;
- stream->content_detection_method = methods[i];
-
pthread_mutex_lock (&catalog->lock);
list_size = xine_sarray_size(catalog->plugin_lists[PLUGIN_DEMUX - 1]);
@@ -1264,6 +1306,25 @@ static demux_plugin_t *probe_demux (xine_stream_t *stream, int method1, int meth
xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: probing demux '%s'\n", node->info->id);
if (node->plugin_class || _load_plugin_class(stream->xine, node, NULL)) {
+ const char *mime_type;
+
+ /* If detecting by MRL, try the MIME type first (but not text/plain)... */
+ stream->content_detection_method = METHOD_EXPLICIT;
+ if (methods[i] == METHOD_BY_EXTENSION &&
+ stream->input_plugin->get_optional_data &&
+ stream->input_plugin->get_optional_data (stream->input_plugin, NULL, INPUT_OPTIONAL_DATA_DEMUX_MIME_TYPE) != INPUT_OPTIONAL_UNSUPPORTED &&
+ stream->input_plugin->get_optional_data (stream->input_plugin, &mime_type, INPUT_OPTIONAL_DATA_MIME_TYPE) != INPUT_OPTIONAL_UNSUPPORTED &&
+ mime_type && strcasecmp (mime_type, "text/plain") &&
+ probe_mime_type (stream->xine, node, mime_type) &&
+ (plugin = ((demux_class_t *)node->plugin_class)->open_plugin (node->plugin_class, stream, input)))
+ {
+ inc_node_ref(node);
+ plugin->node = node;
+ break;
+ }
+
+ /* ... then try the extension */
+ stream->content_detection_method = methods[i];
if ((plugin = ((demux_class_t *)node->plugin_class)->open_plugin(node->plugin_class, stream, input))) {
inc_node_ref(node);
plugin->node = node;
@@ -1659,6 +1720,36 @@ const char *const *xine_list_video_output_plugins (xine_t *xine) {
return catalog->ids;
}
+const char *const *xine_list_video_output_plugins_typed(xine_t *xine, uint64_t typemask)
+{
+ plugin_catalog_t *catalog = xine->plugin_catalog;
+ plugin_node_t *node;
+ int list_id, list_size, i;
+
+ pthread_mutex_lock (&catalog->lock);
+
+ list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_VIDEO_OUT - 1]);
+
+ for (list_id = i = 0; list_id < list_size; list_id++)
+ {
+ node = xine_sarray_get (catalog->plugin_lists[PLUGIN_VIDEO_OUT - 1], list_id);
+ if (typemask & (1ULL << ((vo_info_t *)node->info->special_info)->visual_type))
+ {
+ const char *id = node->info->id;
+ int j = i;
+ while (--j >= 0)
+ if (!strcmp (catalog->ids[j], id))
+ goto ignore; /* already listed */
+ catalog->ids[i++] = id;
+ }
+ ignore: ;
+ }
+ catalog->ids[i] = NULL;
+
+ pthread_mutex_unlock (&catalog->lock);
+ return catalog->ids;
+}
+
static ao_driver_t *_load_audio_driver (xine_t *this, plugin_node_t *node,
void *data) {
@@ -2384,6 +2475,31 @@ void xine_post_dispose(xine_t *xine, xine_post_t *post_gen) {
* their disposal if they are still in use => post.c handles the counting for us */
}
+/**
+ * @brief Concantenates an array of strings into a single
+ * string separated with a given string.
+ *
+ * @param strings Array of strings to concatenate.
+ * @param count Number of elements in the @p strings array.
+ * @param joining String to use to join the various strings together.
+ * @param final_length The pre-calculated final length of the string.
+ */
+static char *_x_concatenate_with_string(char const **strings, size_t count, char *joining, size_t final_length) {
+ size_t i;
+ char *const result = malloc(final_length+1); /* Better be safe */
+ char *str = result;
+
+ for(i = 0; i < count; i++, strings++) {
+ if ( *strings ) {
+ int offset = snprintf(str, final_length, "%s%s", *strings, joining);
+ str += offset;
+ final_length -= offset;
+ }
+ }
+
+ return result;
+}
+
/* get a list of file extensions for file types supported by xine
* the list is separated by spaces
*
@@ -2391,66 +2507,35 @@ void xine_post_dispose(xine_t *xine, xine_post_t *post_gen) {
char *xine_get_file_extensions (xine_t *self) {
plugin_catalog_t *catalog = self->plugin_catalog;
- int len, pos;
- plugin_node_t *node;
- char *str;
- int list_id, list_size;
+ int list_id;
pthread_mutex_lock (&catalog->lock);
- /* calc length of output */
-
- len = 0;
- list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
- for (list_id = 0; list_id < list_size; list_id++) {
- demux_class_t *cls;
- const char *exts;
-
- node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
- if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
-
- cls = (demux_class_t *)node->plugin_class;
-
- if((exts = cls->get_extensions(cls)) && *exts)
- len += strlen(exts) + 1;
- }
- }
-
- /* create output */
- str = malloc (len); /* '\0' space is already counted in the previous loop */
- pos = 0;
+ /* calc length of output string and create an array of strings to
+ concatenate */
+ size_t len = 0;
+ const int list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
+ const char **extensions = calloc(list_size, sizeof(char*));
- list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
for (list_id = 0; list_id < list_size; list_id++) {
- demux_class_t *cls;
- const char *e;
- int l;
-
- node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
+ plugin_node_t *const node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
-
- cls = (demux_class_t *)node->plugin_class;
-
- if((e = cls->get_extensions (cls)) && *e) {
- l = strlen(e);
- memcpy (&str[pos], e, l);
-
- pos += l;
-
- /* Don't add ' ' char at the end of str */
- if((pos + 1) < len) {
- str[pos] = ' ';
- pos++;
- }
- }
+ demux_class_t *const cls = (demux_class_t *)node->plugin_class;
+ if( (extensions[list_id] = cls->get_extensions(cls)) != NULL )
+ len += strlen(extensions[list_id]) +1;
}
}
- str[pos] = 0;
+ /* create output string */
+ char *const result = _x_concatenate_with_string(extensions, list_size, " ", len);
+ free(extensions);
+ /* Drop the last whitespace */
+ result[len-1] = '\0';
+
pthread_mutex_unlock (&catalog->lock);
- return str;
+ return result;
}
/* get a list of mime types supported by xine
@@ -2459,65 +2544,34 @@ char *xine_get_file_extensions (xine_t *self) {
char *xine_get_mime_types (xine_t *self) {
plugin_catalog_t *catalog = self->plugin_catalog;
- int len, pos;
- plugin_node_t *node;
- char *str;
- int list_id, list_size;
+ int list_id;
pthread_mutex_lock (&catalog->lock);
/* calc length of output */
- len = 0;
- list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
+ /* calc length of output string and create an array of strings to
+ concatenate */
+ size_t len = 0;
+ const int list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
+ const char **mimetypes = calloc(list_size, sizeof(char*));
for (list_id = 0; list_id < list_size; list_id++) {
- demux_class_t *cls;
- const char *s;
-
- node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
+ plugin_node_t *const node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
-
- cls = (demux_class_t *)node->plugin_class;
-
- s = cls->get_mimetypes (cls);
- if (s)
- len += strlen(s);
+ demux_class_t *const cls = (demux_class_t *)node->plugin_class;
+ if( (mimetypes[list_id] = cls->get_mimetypes(cls)) != NULL )
+ len += strlen(mimetypes[list_id]);
}
}
- /* create output */
-
- str = malloc (len+1);
- pos = 0;
-
- list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
-
- for (list_id = 0; list_id < list_size; list_id++) {
- demux_class_t *cls;
- const char *s;
- int l;
-
- node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
- if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
+ /* create output string */
+ char *const result = _x_concatenate_with_string(mimetypes, list_size, "", len);
+ free(mimetypes);
- cls = (demux_class_t *)node->plugin_class;
-
- s = cls->get_mimetypes (cls);
- if (s) {
- l = strlen(s);
- memcpy (&str[pos], s, l);
-
- pos += l;
- }
- }
- }
-
- str[pos] = 0;
-
pthread_mutex_unlock (&catalog->lock);
- return str;
+ return result;
}
@@ -2530,47 +2584,24 @@ char *xine_get_demux_for_mime_type (xine_t *self, const char *mime_type) {
plugin_catalog_t *catalog = self->plugin_catalog;
plugin_node_t *node;
char *id = NULL;
- char *mime_arg, *mime_demux;
- char *s;
- const char *mt;
int list_id, list_size;
- /* create a copy and convert to lower case */
- mime_arg = strdup(mime_type);
- for(s=mime_arg; *s; s++)
- *s = tolower(*s);
-
pthread_mutex_lock (&catalog->lock);
list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
for (list_id = 0; (list_id < list_size) && !id; list_id++) {
- demux_class_t *cls;
node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
- if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
-
- cls = (demux_class_t *)node->plugin_class;
-
- mt = cls->get_mimetypes (cls);
- if (mt) {
- mime_demux = strdup(mt);
-
- for(s=mime_demux; *s; s++)
- *s = tolower(*s);
-
- if( strstr(mime_demux, mime_arg) )
- id = strdup(node->info->id);
-
- free(mime_demux);
- }
+ if (probe_mime_type (self, node, mime_type))
+ {
+ free (id);
+ id = strdup(node->info->id);
}
}
pthread_mutex_unlock (&catalog->lock);
- free(mime_arg);
-
return id;
}
diff --git a/src/xine-engine/lrb.c b/src/xine-engine/lrb.c
index 6da846a7c..6f8ac8479 100644
--- a/src/xine-engine/lrb.c
+++ b/src/xine-engine/lrb.c
@@ -30,7 +30,7 @@ lrb_t *lrb_new (int max_num_entries,
lrb_t *this;
- this = xine_xmalloc (sizeof (lrb_t));
+ this = calloc(1, sizeof(lrb_t));
this->max_num_entries = max_num_entries;
this->cur_num_entries = 0;
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index 73f36d541..eb9abb84a 100644
--- a/src/xine-engine/metronom.c
+++ b/src/xine-engine/metronom.c
@@ -172,11 +172,10 @@ static void unixscr_exit (scr_plugin_t *scr) {
free(this);
}
-static scr_plugin_t* unixscr_init () {
+static scr_plugin_t *XINE_MALLOC unixscr_init () {
unixscr_t *this;
- this = (unixscr_t *) xine_xmalloc(sizeof(unixscr_t));
- memset(this, 0, sizeof(*this));
+ this = calloc(1, sizeof(unixscr_t));
this->scr.interface_version = 3;
this->scr.get_priority = unixscr_get_priority;
@@ -890,7 +889,7 @@ static void metronom_clock_exit (metronom_clock_t *this) {
metronom_t * _x_metronom_init (int have_video, int have_audio, xine_t *xine) {
- metronom_t *this = xine_xmalloc (sizeof (metronom_t));
+ metronom_t *this = calloc(1, sizeof (metronom_t));
this->set_audio_rate = metronom_set_audio_rate;
this->got_video_frame = metronom_got_video_frame;
@@ -943,7 +942,7 @@ metronom_t * _x_metronom_init (int have_video, int have_audio, xine_t *xine) {
metronom_clock_t *_x_metronom_clock_init(xine_t *xine)
{
- metronom_clock_t *this = (metronom_clock_t *) xine_xmalloc(sizeof(metronom_clock_t));
+ metronom_clock_t *this = calloc(1, sizeof(metronom_clock_t));
int err;
this->set_option = metronom_clock_set_option;
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
index 20e31117c..c7a594d89 100644
--- a/src/xine-engine/metronom.h
+++ b/src/xine-engine/metronom.h
@@ -223,7 +223,7 @@ struct metronom_s {
#define METRONOM_VPTS_OFFSET 6
#define METRONOM_PREBUFFER 7
-metronom_t *_x_metronom_init (int have_video, int have_audio, xine_t *xine) XINE_PROTECTED;
+metronom_t *_x_metronom_init (int have_video, int have_audio, xine_t *xine) XINE_MALLOC XINE_PROTECTED;
/* FIXME: reorder this structure on the next cleanup to remove the dummies */
struct metronom_clock_s {
@@ -319,7 +319,7 @@ struct metronom_clock_s {
#endif
};
-metronom_clock_t *_x_metronom_clock_init(xine_t *xine) XINE_PROTECTED;
+metronom_clock_t *_x_metronom_clock_init(xine_t *xine) XINE_MALLOC XINE_PROTECTED;
/*
* clock options
diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c
index ef888e7a4..af8286831 100644
--- a/src/xine-engine/osd.c
+++ b/src/xine-engine/osd.c
@@ -83,17 +83,6 @@
# define UCS2_ENCODING "UCS-2LE"
#endif
-#ifdef MAX
-#undef MAX
-#endif
-#define MAX(a,b) ( (a) > (b) ) ? (a) : (b)
-
-#ifdef MIN
-#undef MIN
-#endif
-#define MIN(a,b) ( (a) < (b) ) ? (a) : (b)
-
-
#if (FREETYPE_MAJOR > 2) || \
(FREETYPE_MAJOR == 2 && FREETYPE_MINOR > 1) || \
(FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 1 && FREETYPE_PATCH >= 3)
@@ -132,6 +121,20 @@ struct osd_ft2context_s {
FT_Face face;
int size;
};
+
+static void osd_free_ft2 (osd_object_t *osd)
+{
+ if( osd->ft2 ) {
+ if ( osd->ft2->face )
+ FT_Done_Face (osd->ft2->face);
+ if ( osd->ft2->library )
+ FT_Done_FreeType(osd->ft2->library);
+ free( osd->ft2 );
+ osd->ft2 = NULL;
+ }
+}
+#else
+static inline void osd_free_ft2 (osd_object_t *osd __attr_unused) {}
#endif
/*
@@ -143,20 +146,20 @@ struct osd_ft2context_s {
* for the sake of simplicity)
*/
-static osd_object_t *osd_new_object (osd_renderer_t *this, int width, int height) {
+static osd_object_t *XINE_MALLOC osd_new_object (osd_renderer_t *this, int width, int height) {
osd_object_t *osd;
pthread_mutex_lock (&this->osd_mutex);
- osd = xine_xmalloc( sizeof(osd_object_t) );
+ osd = calloc(1, sizeof(osd_object_t));
osd->renderer = this;
osd->next = this->osds;
this->osds = osd;
osd->width = width;
osd->height = height;
- osd->area = xine_xmalloc( width * height );
+ osd->area = calloc(width, height);
osd->x1 = width;
osd->y1 = height;
@@ -670,7 +673,7 @@ static int osd_renderer_load_font(osd_renderer_t *this, char *filename) {
/* fixme: check for all read errors... */
if( (fp = gzopen(filename,"rb")) != NULL ) {
- font = xine_xmalloc( sizeof(osd_font_t) );
+ font = calloc(1, sizeof(osd_font_t));
gzread(fp, font->name, sizeof(font->name) );
font->version = gzread_i16(fp);
@@ -818,7 +821,7 @@ static int osd_renderer_unload_font(osd_renderer_t *this, char *fontname ) {
#ifdef HAVE_FT2
static int osd_set_font_freetype2( osd_object_t *osd, const char *fontname, int size ) {
if (!osd->ft2) {
- osd->ft2 = xine_xmalloc(sizeof(osd_ft2context_t));
+ osd->ft2 = calloc(1, sizeof(osd_ft2context_t));
if(FT_Init_FreeType( &osd->ft2->library )) {
xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG,
_("osd: cannot initialize ft2 library\n"));
@@ -827,6 +830,11 @@ static int osd_set_font_freetype2( osd_object_t *osd, const char *fontname, int
return 0;
}
}
+
+ if (osd->ft2->face) {
+ FT_Done_Face (osd->ft2->face);
+ osd->ft2->face = NULL;
+ }
#ifdef HAVE_FONTCONFIG
do {
@@ -885,16 +893,14 @@ static int osd_set_font_freetype2( osd_object_t *osd, const char *fontname, int
_("osd: error loading font %s with ft2\n"), fontname);
}
- free(osd->ft2);
- osd->ft2 = NULL;
+ osd_free_ft2 (osd);
return 0;
end:
if (FT_Set_Pixel_Sizes(osd->ft2->face, 0, size)) {
xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG,
_("osd: error setting font size (no scalable font?)\n"));
- free(osd->ft2);
- osd->ft2 = NULL;
+ osd_free_ft2 (osd);
return 0;
}
@@ -1410,10 +1416,9 @@ static void osd_preload_fonts (osd_renderer_t *this, char *path) {
if( p ) {
osd_font_t *font;
- char *pathname;
*p++ = '\0';
- font = xine_xmalloc( sizeof(osd_font_t) );
+ font = calloc(1, sizeof(osd_font_t) );
strncpy(font->name, s, sizeof(font->name));
font->size = atoi(p);
@@ -1421,9 +1426,7 @@ static void osd_preload_fonts (osd_renderer_t *this, char *path) {
lprintf("font '%s' size %d is preloaded\n",
font->name, font->size);
- pathname = (char *) xine_xmalloc(strlen(path) + strlen(entry->d_name) + 2);
- sprintf (pathname, "%s/%s", path, entry->d_name);
- font->filename = pathname;
+ asprintf (&font->filename, "%s/%s", path, entry->d_name);
font->next = this->fonts;
this->fonts = font;
@@ -1472,15 +1475,7 @@ static void osd_free_object (osd_object_t *osd_to_close) {
if ( osd == osd_to_close ) {
free( osd->area );
-#ifdef HAVE_FT2
- if( osd->ft2 ) {
- if ( osd->ft2->library )
- FT_Done_FreeType(osd->ft2->library);
-
- free( osd->ft2 );
- }
-#endif
-
+ osd_free_ft2 (osd);
osd_free_encoding(osd);
if( last )
@@ -1579,9 +1574,9 @@ osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ) {
osd_renderer_t *this;
char str[1024];
- this = xine_xmalloc(sizeof(osd_renderer_t));
+ this = calloc(1, sizeof(osd_renderer_t));
this->stream = stream;
- this->event.object.overlay = xine_xmalloc( sizeof(vo_overlay_t) );
+ this->event.object.overlay = calloc(1, sizeof(vo_overlay_t));
pthread_mutex_init (&this->osd_mutex, NULL);
diff --git a/src/xine-engine/osd.h b/src/xine-engine/osd.h
index 38b5d1fdd..70193a2ea 100644
--- a/src/xine-engine/osd.h
+++ b/src/xine-engine/osd.h
@@ -226,7 +226,7 @@ struct osd_renderer_s {
/*
* initialize the osd rendering engine
*/
-osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream );
+osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ) XINE_MALLOC;
/*
diff --git a/src/xine-engine/post.c b/src/xine-engine/post.c
index 5d8d67037..aa182d627 100644
--- a/src/xine-engine/post.c
+++ b/src/xine-engine/post.c
@@ -30,13 +30,10 @@
void _x_post_init(post_plugin_t *post, int num_audio_inputs, int num_video_inputs) {
- int audio_inputs_size = (num_audio_inputs + 1) * sizeof(xine_audio_port_t *);
- int video_inputs_size = (num_video_inputs + 1) * sizeof(xine_video_port_t *);
-
post->input = xine_list_new();
post->output = xine_list_new();
- post->xine_post.audio_input = (xine_audio_port_t **)xine_xmalloc(audio_inputs_size);
- post->xine_post.video_input = (xine_video_port_t **)xine_xmalloc(video_inputs_size);
+ post->xine_post.audio_input = calloc(num_audio_inputs + 1, sizeof(xine_audio_port_t *));
+ post->xine_post.video_input = calloc(num_video_inputs + 1, sizeof(xine_video_port_t *));
}
@@ -207,7 +204,7 @@ static int post_video_rewire(xine_post_out_t *output_gen, void *data) {
post_video_port_t *_x_post_intercept_video_port(post_plugin_t *post, xine_video_port_t *original,
post_in_t **input, post_out_t **output) {
- post_video_port_t *port = (post_video_port_t *)xine_xmalloc(sizeof(post_video_port_t));
+ post_video_port_t *port = calloc(1, sizeof(post_video_port_t));
if (!port)
return NULL;
@@ -235,7 +232,7 @@ post_video_port_t *_x_post_intercept_video_port(post_plugin_t *post, xine_video_
pthread_mutex_init(&port->free_frames_lock, NULL);
if (input) {
- *input = (post_in_t *)xine_xmalloc(sizeof(post_in_t));
+ *input = calloc(1, sizeof(post_in_t));
if (!*input) return port;
(*input)->xine_in.name = "video in";
(*input)->xine_in.type = XINE_POST_DATA_VIDEO;
@@ -245,7 +242,7 @@ post_video_port_t *_x_post_intercept_video_port(post_plugin_t *post, xine_video_
}
if (output) {
- *output = (post_out_t *)xine_xmalloc(sizeof(post_out_t));
+ *output = calloc(1, sizeof(post_out_t));
if (!*output) return port;
(*output)->xine_out.name = "video out";
(*output)->xine_out.type = XINE_POST_DATA_VIDEO;
@@ -353,7 +350,7 @@ vo_frame_t *_x_post_intercept_video_frame(vo_frame_t *frame, post_video_port_t *
new_frame = port->free_frame_slots;
port->free_frame_slots = new_frame->next;
} else {
- new_frame = (vo_frame_t *)xine_xmalloc(sizeof(vo_frame_t));
+ new_frame = calloc(1, sizeof(vo_frame_t));
}
pthread_mutex_unlock(&port->free_frames_lock);
@@ -716,7 +713,7 @@ static int post_audio_rewire(xine_post_out_t *output_gen, void *data) {
post_audio_port_t *_x_post_intercept_audio_port(post_plugin_t *post, xine_audio_port_t *original,
post_in_t **input, post_out_t **output) {
- post_audio_port_t *port = (post_audio_port_t *)xine_xmalloc(sizeof(post_audio_port_t));
+ post_audio_port_t *port = calloc(1, sizeof(post_audio_port_t));
if (!port)
return NULL;
@@ -739,7 +736,7 @@ post_audio_port_t *_x_post_intercept_audio_port(post_plugin_t *post, xine_audio_
pthread_mutex_init(&port->usage_lock, NULL);
if (input) {
- *input = (post_in_t *)xine_xmalloc(sizeof(post_in_t));
+ *input = calloc(1, sizeof(post_in_t));
if (!*input) return port;
(*input)->xine_in.name = "audio in";
(*input)->xine_in.type = XINE_POST_DATA_AUDIO;
@@ -749,7 +746,7 @@ post_audio_port_t *_x_post_intercept_audio_port(post_plugin_t *post, xine_audio_
}
if (output) {
- *output = (post_out_t *)xine_xmalloc(sizeof(post_out_t));
+ *output = calloc(1, sizeof(post_out_t));
if (!*output) return port;
(*output)->xine_out.name = "audio out";
(*output)->xine_out.type = XINE_POST_DATA_AUDIO;
diff --git a/src/xine-engine/refcounter.c b/src/xine-engine/refcounter.c
index 539abf3ed..384bdf5ed 100644
--- a/src/xine-engine/refcounter.c
+++ b/src/xine-engine/refcounter.c
@@ -17,6 +17,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#define LOG_MODULE "refcounter"
#define LOG_VERBOSE
/*
@@ -30,7 +35,7 @@ refcounter_t* _x_new_refcounter(void *object, void (*destructor)(void *))
{
refcounter_t *new_refcounter;
- new_refcounter = (refcounter_t *) xine_xmalloc (sizeof (refcounter_t));
+ new_refcounter = (refcounter_t *) calloc(1, sizeof(refcounter_t));
new_refcounter->count = 1;
new_refcounter->object = object;
new_refcounter->destructor = destructor;
diff --git a/src/xine-engine/refcounter.h b/src/xine-engine/refcounter.h
index 87abd6321..b3ddd71fc 100644
--- a/src/xine-engine/refcounter.h
+++ b/src/xine-engine/refcounter.h
@@ -20,10 +20,6 @@
#ifndef HAVE_REFCOUNTER_H
#define HAVE_REFCOUNTER_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <pthread.h>
typedef struct {
@@ -35,7 +31,7 @@ typedef struct {
typedef void (*refcounter_destructor)(void*);
-refcounter_t* _x_new_refcounter(void *object, refcounter_destructor destructor) XINE_PROTECTED;
+refcounter_t* _x_new_refcounter(void *object, refcounter_destructor destructor) XINE_MALLOC XINE_PROTECTED;
int _x_refcounter_inc(refcounter_t *refcounter) XINE_PROTECTED;
diff --git a/src/xine-engine/scratch.c b/src/xine-engine/scratch.c
index 38b606b84..696e99ffb 100644
--- a/src/xine-engine/scratch.c
+++ b/src/xine-engine/scratch.c
@@ -50,12 +50,11 @@ static void __attribute__((__format__(__printf__, 2, 0)))
localtime_r (&t, &tm);
if ( ! this->lines[this->cur] )
- this->lines[this->cur] = xine_xmalloc(SCRATCH_LINE_LEN_MAX+1);
+ this->lines[this->cur] = malloc(SCRATCH_LINE_LEN_MAX+1);
if ( ! this->lines[this->cur] )
return;
- strftime (this->lines[this->cur], SCRATCH_LINE_LEN_MAX, "%X: ", &tm);
- l = strlen (this->lines[this->cur]);
+ l = strftime (this->lines[this->cur], SCRATCH_LINE_LEN_MAX, "%X: ", &tm);
vsnprintf (this->lines[this->cur] + l, SCRATCH_LINE_LEN_MAX - l, format, argp);
lprintf ("printing format %s to line %d\n", format, this->cur);
@@ -105,15 +104,11 @@ static void scratch_dispose (scratch_buffer_t *this) {
scratch_buffer_t *_x_new_scratch_buffer (int num_lines) {
scratch_buffer_t *this;
- int i;
- this = xine_xmalloc (sizeof (scratch_buffer_t));
+ this = calloc(1, sizeof(scratch_buffer_t));
- this->lines = xine_xmalloc (sizeof (char *) * (num_lines + 1));
- this->ordered = xine_xmalloc (sizeof (char *) * (num_lines + 1));
-
- for (i = 0; i <= num_lines; i++)
- this->lines[i] = this->ordered[i] = NULL;
+ this->lines = calloc ((num_lines + 1), sizeof(char*));
+ this->ordered = calloc ((num_lines + 1), sizeof(char*));
this->scratch_printf = scratch_printf;
this->get_content = scratch_get_content;
diff --git a/src/xine-engine/scratch.h b/src/xine-engine/scratch.h
index c0e591d31..1029276e3 100644
--- a/src/xine-engine/scratch.h
+++ b/src/xine-engine/scratch.h
@@ -51,6 +51,6 @@ struct scratch_buffer_s {
pthread_mutex_t lock;
};
-scratch_buffer_t *_x_new_scratch_buffer (int num_lines) XINE_PROTECTED;
+scratch_buffer_t *_x_new_scratch_buffer (int num_lines) XINE_MALLOC XINE_PROTECTED;
#endif
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index c88e01714..d3c9e0d34 100644
--- a/src/xine-engine/video_decoder.c
+++ b/src/xine-engine/video_decoder.c
@@ -160,7 +160,7 @@ static void *video_decoder_loop (void *stream_gen) {
running_ticket->release(running_ticket, 0);
- if( !stream->gapless_switch )
+ if( !(buf->decoder_flags & BUF_FLAG_GAPLESS_SW) )
stream->metronom->handle_video_discontinuity (stream->metronom,
DISC_STREAMSTART, 0);
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index a8464ac40..be062cc5d 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -139,11 +139,11 @@ typedef struct {
* frame queue (fifo) util functions
*/
-static img_buf_fifo_t *vo_new_img_buf_queue () {
+static img_buf_fifo_t *XINE_MALLOC vo_new_img_buf_queue () {
img_buf_fifo_t *queue;
- queue = (img_buf_fifo_t *) xine_xmalloc (sizeof (img_buf_fifo_t));
+ queue = (img_buf_fifo_t *) calloc(1, sizeof(img_buf_fifo_t));
if( queue ) {
queue->first = NULL;
queue->last = NULL;
@@ -1771,7 +1771,7 @@ xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabon
int num_frame_buffers;
- this = xine_xmalloc (sizeof (vos_t)) ;
+ this = calloc(1, sizeof(vos_t)) ;
this->xine = xine;
this->clock = xine->clock;
diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h
index 4d9c80565..9a2ba06c6 100644
--- a/src/xine-engine/video_out.h
+++ b/src/xine-engine/video_out.h
@@ -36,10 +36,6 @@
extern "C" {
#endif
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <pthread.h>
#ifdef XINE_COMPILE
@@ -448,7 +444,7 @@ struct video_overlay_manager_s {
* build a video_out_port from
* a given video driver
*/
-xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabonly) XINE_PROTECTED;
+xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabonly) XINE_MALLOC XINE_PROTECTED;
#ifdef __cplusplus
}
diff --git a/src/xine-engine/video_overlay.c b/src/xine-engine/video_overlay.c
index c189fa56b..b88f10c11 100644
--- a/src/xine-engine/video_overlay.c
+++ b/src/xine-engine/video_overlay.c
@@ -18,6 +18,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
@@ -199,7 +203,7 @@ static void video_overlay_reset (video_overlay_t *this) {
pthread_mutex_lock (&this->events_mutex);
for (i=0; i < MAX_EVENTS; i++) {
if (this->events[i].event == NULL) {
- this->events[i].event = xine_xmalloc (sizeof(video_overlay_event_t));
+ this->events[i].event = calloc(1, sizeof(video_overlay_event_t));
#ifdef LOG_DEBUG
printf ("video_overlay: MALLOC2: this->events[%d].event %p, len=%d\n",
i,
@@ -293,7 +297,7 @@ static int32_t video_overlay_add_event(video_overlay_manager_t *this_gen, void
event->object.overlay->hili_trans[i] = OVL_MAX_OPACITY;
}
- this->events[new_event].event->object.overlay = xine_xmalloc (sizeof(vo_overlay_t));
+ this->events[new_event].event->object.overlay = calloc(1, sizeof(vo_overlay_t));
xine_fast_memcpy(this->events[new_event].event->object.overlay,
event->object.overlay, sizeof(vo_overlay_t));
@@ -587,7 +591,7 @@ video_overlay_manager_t *_x_video_overlay_new_manager (xine_t *xine) {
video_overlay_t *this;
- this = (video_overlay_t *) xine_xmalloc (sizeof (video_overlay_t));
+ this = (video_overlay_t *) calloc(1, sizeof(video_overlay_t));
this->xine = xine;
this->video_overlay.init = video_overlay_init;
diff --git a/src/xine-engine/video_overlay.h b/src/xine-engine/video_overlay.h
index d580a1e83..01f3a2a3a 100644
--- a/src/xine-engine/video_overlay.h
+++ b/src/xine-engine/video_overlay.h
@@ -98,6 +98,6 @@ typedef struct video_overlay_event_s {
video_overlay_object_t object; /* The image data. */
} video_overlay_event_t;
-video_overlay_manager_t *_x_video_overlay_new_manager(xine_t *) XINE_PROTECTED;
+video_overlay_manager_t *_x_video_overlay_new_manager(xine_t *) XINE_MALLOC XINE_PROTECTED;
#endif
diff --git a/src/xine-engine/vo_scale.c b/src/xine-engine/vo_scale.c
index ff30c47a6..8d84c32da 100644
--- a/src/xine-engine/vo_scale.c
+++ b/src/xine-engine/vo_scale.c
@@ -22,6 +22,10 @@
* Takes into account aspect ratio correction and zooming.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <string.h>
#include <math.h>
diff --git a/src/xine-engine/vo_scale.h b/src/xine-engine/vo_scale.h
index 829405162..eb2607024 100644
--- a/src/xine-engine/vo_scale.h
+++ b/src/xine-engine/vo_scale.h
@@ -29,10 +29,6 @@
extern "C" {
#endif
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#ifdef XINE_COMPILE
# include "configfile.h"
#else
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index eae13bec9..aebbffb39 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.c
@@ -36,6 +36,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
+#include <unistd.h>
#if defined (__linux__) || defined (__GLIBC__)
#include <endian.h>
#elif defined (__FreeBSD__)
@@ -132,7 +133,7 @@ static int acquire_allowed_to_block(xine_ticket_t *this) {
unsigned new_size;
for(entry = 0; entry < this->holder_thread_count; ++entry) {
- if(this->holder_threads[entry].holder == own_id) {
+ if(pthread_equal(this->holder_threads[entry].holder, own_id)) {
/* This thread may already hold this ticket */
this->holder_threads[entry].count++;
return (this->holder_threads[entry].count == 1);
@@ -203,7 +204,7 @@ static int release_allowed_to_block(xine_ticket_t *this) {
unsigned entry;
for(entry = 0; entry < this->holder_thread_count; ++entry) {
- if(this->holder_threads[entry].holder == own_id) {
+ if(pthread_equal(this->holder_threads[entry].holder, own_id)) {
this->holder_threads[entry].count--;
return this->holder_threads[entry].count == 0;
}
@@ -303,10 +304,10 @@ static void ticket_dispose(xine_ticket_t *this) {
free(this);
}
-static xine_ticket_t *ticket_init(void) {
+static xine_ticket_t *XINE_MALLOC ticket_init(void) {
xine_ticket_t *port_ticket;
- port_ticket = (xine_ticket_t *) xine_xmalloc(sizeof(xine_ticket_t));
+ port_ticket = calloc(1, sizeof(xine_ticket_t));
port_ticket->acquire_nonblocking = ticket_acquire_nonblocking;
port_ticket->acquire = ticket_acquire;
@@ -329,17 +330,20 @@ static xine_ticket_t *ticket_init(void) {
static void set_speed_internal (xine_stream_t *stream, int speed) {
xine_t *xine = stream->xine;
+ int old_speed = xine->clock->speed;
- if (xine->clock->speed != XINE_SPEED_PAUSE && speed == XINE_SPEED_PAUSE)
+ if (old_speed != XINE_SPEED_PAUSE && speed == XINE_SPEED_PAUSE)
/* get all decoder and post threads in a state where they agree to be blocked */
xine->port_ticket->revoke(xine->port_ticket, 0);
- if (xine->clock->speed == XINE_SPEED_PAUSE && speed != XINE_SPEED_PAUSE)
+ if (old_speed == XINE_SPEED_PAUSE && speed != XINE_SPEED_PAUSE)
/* all decoder and post threads may continue now */
xine->port_ticket->issue(xine->port_ticket, 0);
- stream->xine->clock->set_fine_speed (stream->xine->clock, speed);
-
+ if (old_speed != XINE_SPEED_PAUSE && speed == XINE_SPEED_PAUSE)
+ /* set master clock so audio_out loop can pause in a safe place */
+ stream->xine->clock->set_fine_speed (stream->xine->clock, speed);
+
/* see coment on audio_out loop about audio_paused */
if( stream->audio_out ) {
xine->port_ticket->acquire(xine->port_ticket, 1);
@@ -349,6 +353,10 @@ static void set_speed_internal (xine_stream_t *stream, int speed) {
xine->port_ticket->release(xine->port_ticket, 1);
}
+
+ if (old_speed == XINE_SPEED_PAUSE || speed != XINE_SPEED_PAUSE)
+ /* master clock is set after resuming the audio device (audio_out loop may continue) */
+ stream->xine->clock->set_fine_speed (stream->xine->clock, speed);
}
@@ -418,6 +426,7 @@ void xine_stop (xine_stream_t *stream) {
static void close_internal (xine_stream_t *stream) {
int i ;
+ int gapless_switch = stream->gapless_switch;
if( stream->slave ) {
xine_close( stream->slave );
@@ -428,7 +437,7 @@ static void close_internal (xine_stream_t *stream) {
}
}
- if( !stream->gapless_switch ) {
+ if( !gapless_switch ) {
/* make sure that other threads cannot change the speed, especially pauseing the stream */
pthread_mutex_lock(&stream->speed_change_lock);
stream->ignore_speed_change = 1;
@@ -444,7 +453,7 @@ static void close_internal (xine_stream_t *stream) {
stop_internal( stream );
- if( !stream->gapless_switch ) {
+ if( !gapless_switch ) {
if (stream->video_out)
stream->video_out->set_property(stream->video_out, VO_PROP_DISCARD_FRAMES, 0);
if (stream->audio_out)
@@ -552,7 +561,7 @@ static int stream_rewire_video(xine_post_out_t *output, void *data)
return 1;
}
-void xine_dispose_internal (xine_stream_t *stream);
+static void xine_dispose_internal (xine_stream_t *stream);
xine_stream_t *xine_stream_new (xine_t *this,
xine_audio_port_t *ao, xine_video_port_t *vo) {
@@ -569,7 +578,7 @@ xine_stream_t *xine_stream_new (xine_t *this,
pthread_mutex_lock (&this->streams_lock);
- stream = (xine_stream_t *) xine_xmalloc (sizeof (xine_stream_t)) ;
+ stream = (xine_stream_t *) calloc (1, sizeof (xine_stream_t)) ;
stream->current_extra_info = malloc( sizeof( extra_info_t ) );
stream->audio_decoder_extra_info = malloc( sizeof( extra_info_t ) );
stream->video_decoder_extra_info = malloc( sizeof( extra_info_t ) );
@@ -595,6 +604,7 @@ xine_stream_t *xine_stream_new (xine_t *this,
stream->early_finish_event = 0;
stream->delay_finish_event = 0;
stream->gapless_switch = 0;
+ stream->keep_ao_driver_open = 0;
stream->video_out = vo;
if (vo)
@@ -628,6 +638,7 @@ xine_stream_t *xine_stream_new (xine_t *this,
pthread_mutex_init (&stream->meta_mutex, NULL);
pthread_mutex_init (&stream->demux_lock, NULL);
pthread_mutex_init (&stream->demux_mutex, NULL);
+ pthread_cond_init (&stream->demux_resume, NULL);
pthread_mutex_init (&stream->event_queues_lock, NULL);
pthread_mutex_init (&stream->counter_lock, NULL);
pthread_cond_init (&stream->counter_changed, NULL);
@@ -733,7 +744,7 @@ xine_stream_t *xine_stream_new (xine_t *this,
}
void _x_mrl_unescape(char *mrl) {
- int i, len = strlen(mrl);
+ size_t i, len = strlen(mrl);
for (i = 0; i < len; i++) {
if ((mrl[i]=='%') && (i<(len-2))) {
@@ -780,9 +791,23 @@ void _x_flush_events_queues (xine_stream_t *stream) {
pthread_mutex_unlock (&stream->event_queues_lock);
}
-/*static*/ int open_internal (xine_stream_t *stream, const char *mrl) {
+static inline int _x_path_looks_like_mrl (const char *path)
+{
+ if ((*path & 0xDF) < 'A' || (*path & 0xDF) > 'Z')
+ return 0;
+
+ for (++path; *path; ++path)
+ if ((*path != '-' && *path < '0') || (*path > '9' && *path < 'A') ||
+ (*path > 'Z' && *path < 'a') || *path > 'z')
+ break;
+
+ return path[0] == ':' && path[1] == '/';
+}
+
+static int open_internal (xine_stream_t *stream, const char *mrl) {
const char *stream_setup = NULL;
+ const char *mrl_proto = NULL;
int no_cache = 0;
if (!mrl) {
@@ -806,16 +831,31 @@ void _x_flush_events_queues (xine_stream_t *stream) {
/*
* look for a stream_setup in MRL and try finding an input plugin
*/
+ stream_setup = strchr (mrl, '#');
if (isalpha (*mrl))
{
- stream_setup = mrl + 1;
- while (isalnum (*stream_setup) || *stream_setup == '+' || *stream_setup == '-' || *stream_setup == '.')
- ++stream_setup;
- if (stream_setup[0] == ':' && stream_setup[1] == '/')
- stream_setup = strchr (mrl, '#');
- else
- stream_setup = NULL;
+ mrl_proto = mrl + 1;
+ while (isalnum (*mrl_proto) || *mrl_proto == '+' || *mrl_proto == '-' || *mrl_proto == '.')
+ ++mrl_proto;
+ if (!mrl_proto[0] || mrl_proto[0] != ':' || mrl_proto[1] != '/')
+ mrl_proto = NULL;
+ }
+
+ /* for raw filenames we must try every '#' checking if it is part of the filename */
+ if( !mrl_proto && stream_setup) {
+ struct stat stat_buf;
+ int res;
+
+ while( stream_setup ) {
+ char *raw_filename = strndup (mrl, stream_setup - mrl);
+
+ res = stat(raw_filename, &stat_buf);
+ free(raw_filename);
+ if( !res )
+ break;
+ stream_setup = strchr(stream_setup + 1, '#');
+ }
}
{
@@ -824,8 +864,10 @@ void _x_flush_events_queues (xine_stream_t *stream) {
/*
* find an input plugin
*/
-
- if ((stream->input_plugin = _x_find_input_plugin (stream, input_source))) {
+ stream->input_plugin = _x_find_input_plugin (stream, input_source);
+ free(input_source);
+
+ if ( stream->input_plugin ) {
int res;
xine_log (stream->xine, XINE_LOG_MSG, _("xine: found input plugin : %s\n"),
@@ -840,7 +882,6 @@ void _x_flush_events_queues (xine_stream_t *stream) {
case 1: /* Open successfull */
break;
case -1: /* Open unsuccessfull, but correct plugin */
- free(input_source);
stream->err = XINE_ERROR_INPUT_FAILED;
_x_flush_events_queues (stream);
return 0;
@@ -851,8 +892,6 @@ void _x_flush_events_queues (xine_stream_t *stream) {
stream->err = XINE_ERROR_INPUT_FAILED;
}
}
-
- free(input_source);
}
if (!stream->input_plugin) {
@@ -917,6 +956,7 @@ void _x_flush_events_queues (xine_stream_t *stream) {
memcpy(filename, tmp, strlen(tmp));
filename[strlen(tmp)] = '\0';
}
+ _x_mrl_unescape(filename);
xine_log(stream->xine, XINE_LOG_MSG, _("xine: join rip input plugin\n"));
input_saver = _x_rip_plugin_get_instance (stream, filename);
@@ -1091,7 +1131,9 @@ void _x_flush_events_queues (xine_stream_t *stream) {
memcpy(subtitle_mrl, tmp, strlen(tmp));
subtitle_mrl[strlen(tmp)] = '\0';
}
- _x_mrl_unescape(subtitle_mrl);
+ /* unescape for xine_open() if the MRL looks like a raw pathname */
+ if (!_x_path_looks_like_mrl(subtitle_mrl))
+ _x_mrl_unescape(subtitle_mrl);
stream->slave = xine_stream_new (stream->xine, NULL, stream->video_out );
stream->slave_affection = XINE_MASTER_SLAVE_PLAY | XINE_MASTER_SLAVE_STOP;
if( xine_open( stream->slave, subtitle_mrl ) ) {
@@ -1152,6 +1194,27 @@ void _x_flush_events_queues (xine_stream_t *stream) {
/* enable buffered input plugin (request optimizer) */
stream->input_plugin = _x_cache_plugin_get_instance(stream, 0);
+ /* Let the plugin request a specific demuxer (if the user hasn't).
+ * This overrides find-by-content & find-by-extension.
+ */
+ if (!stream->demux_plugin)
+ {
+ char *default_demux = NULL;
+ stream->input_plugin->get_optional_data (stream->input_plugin, &default_demux, INPUT_OPTIONAL_DATA_DEMUXER);
+ if (default_demux)
+ {
+ stream->demux_plugin = _x_find_demux_plugin_by_name (stream, default_demux, stream->input_plugin);
+ if (stream->demux_plugin)
+ {
+ lprintf ("demux and input plugin found\n");
+ _x_meta_info_set_utf8 (stream, XINE_META_INFO_SYSTEMLAYER,
+ stream->demux_plugin->demux_class->get_identifier (stream->demux_plugin->demux_class));
+ }
+ else
+ xine_log (stream->xine, XINE_LOG_MSG, _("xine: couldn't load plugin-specified demux %s for >%s<\n"), default_demux, mrl);
+ }
+ }
+
if (!stream->demux_plugin) {
/*
@@ -1290,6 +1353,7 @@ static int play_internal (xine_stream_t *stream, int start_pos, int start_time)
pthread_mutex_lock( &stream->demux_lock );
/* demux_lock taken. now demuxer is suspended */
stream->demux_action_pending = 0;
+ pthread_cond_signal(&stream->demux_resume);
/* set normal speed again (now that demuxer/input pair is suspended)
* some input plugin may have changed speed by itself, we must ensure
@@ -1403,7 +1467,7 @@ int xine_eject (xine_stream_t *stream) {
return status;
}
-void xine_dispose_internal (xine_stream_t *stream) {
+static void xine_dispose_internal (xine_stream_t *stream) {
xine_list_iterator_t *ite;
@@ -1416,6 +1480,7 @@ void xine_dispose_internal (xine_stream_t *stream) {
pthread_mutex_destroy (&stream->current_extra_info_lock);
pthread_cond_destroy (&stream->counter_changed);
pthread_mutex_destroy (&stream->demux_mutex);
+ pthread_cond_destroy (&stream->demux_resume);
pthread_mutex_destroy (&stream->demux_lock);
pthread_mutex_destroy (&stream->first_frame_lock);
pthread_cond_destroy (&stream->first_frame_reached);
@@ -1510,7 +1575,7 @@ xine_t *xine_new (void) {
int i_err;
#endif
- this = xine_xmalloc (sizeof (xine_t));
+ this = calloc(1, sizeof (xine_t));
if (!this)
_x_abort();
@@ -1599,8 +1664,7 @@ static void config_save_cb (void *this_gen, xine_cfg_entry_t *entry) {
xine_t *this = (xine_t *)this_gen;
char *homedir_trail_slash;
- homedir_trail_slash = (char *)malloc(strlen(xine_get_homedir()) + 2);
- sprintf(homedir_trail_slash, "%s/", xine_get_homedir());
+ asprintf(&homedir_trail_slash, "%s/", xine_get_homedir());
if (entry->str_value[0] &&
(entry->str_value[0] != '/' || strstr(entry->str_value, "/.") ||
strcmp(entry->str_value, xine_get_homedir()) == 0 ||
@@ -1627,6 +1691,12 @@ void xine_init (xine_t *this) {
static const char *demux_strategies[] = {"default", "reverse", "content",
"extension", NULL};
+ /*
+ * locks
+ */
+ pthread_mutex_init (&this->streams_lock, NULL);
+ pthread_mutex_init (&this->log_lock, NULL);
+
/* initialize color conversion tables and functions */
init_yuv_conversion();
@@ -1708,12 +1778,6 @@ void xine_init (xine_t *this) {
this->streams = xine_list_new();
/*
- * locks
- */
- pthread_mutex_init (&this->streams_lock, NULL);
- pthread_mutex_init (&this->log_lock, NULL);
-
- /*
* start metronom clock
*/
@@ -1899,50 +1963,98 @@ int xine_get_pos_length (xine_stream_t *stream, int *pos_stream,
return 1;
}
-int xine_get_current_frame (xine_stream_t *stream, int *width, int *height,
- int *ratio_code, int *format,
- uint8_t *img) {
+static int _x_get_current_frame_data (xine_stream_t *stream,
+ xine_current_frame_data_t *data,
+ int flags, int img_size_unknown) {
vo_frame_t *frame;
+ size_t required_size;
stream->xine->port_ticket->acquire(stream->xine->port_ticket, 0);
frame = stream->video_out->get_last_frame (stream->video_out);
stream->xine->port_ticket->release(stream->xine->port_ticket, 0);
- if (!frame)
+ if (!frame) {
+ data->img_size = 0;
return 0;
+ }
- *width = frame->width;
- *height = frame->height;
+ data->width = frame->width;
+ data->height = frame->height;
+ data->crop_left = frame->crop_left;
+ data->crop_right = frame->crop_right;
+ data->crop_top = frame->crop_top;
+ data->crop_bottom = frame->crop_bottom;
- *ratio_code = 10000.0 * frame->ratio;
+ data->ratio_code = 10000.0 * frame->ratio;
/* make ratio_code backward compatible */
#define RATIO_LIKE(a, b) ((b) - 1 <= (a) && (a) <= 1 + (b))
- if (RATIO_LIKE(*ratio_code, 10000))
- *ratio_code = XINE_VO_ASPECT_SQUARE;
- else if (RATIO_LIKE(*ratio_code, 13333))
- *ratio_code = XINE_VO_ASPECT_4_3;
- else if (RATIO_LIKE(*ratio_code, 17778))
- *ratio_code = XINE_VO_ASPECT_ANAMORPHIC;
- else if (RATIO_LIKE(*ratio_code, 21100))
- *ratio_code = XINE_VO_ASPECT_DVB;
-
- *format = frame->format;
-
- if (img){
+ if (RATIO_LIKE(data->ratio_code, 10000))
+ data->ratio_code = XINE_VO_ASPECT_SQUARE;
+ else if (RATIO_LIKE(data->ratio_code, 13333))
+ data->ratio_code = XINE_VO_ASPECT_4_3;
+ else if (RATIO_LIKE(data->ratio_code, 17778))
+ data->ratio_code = XINE_VO_ASPECT_ANAMORPHIC;
+ else if (RATIO_LIKE(data->ratio_code, 21100))
+ data->ratio_code = XINE_VO_ASPECT_DVB;
+
+ data->format = frame->format;
+ data->interlaced = frame->progressive_frame ? 0 : (2 - frame->top_field_first);
+
+ switch (frame->format) {
+
+ case XINE_IMGFMT_YV12:
+ required_size = frame->width * frame->height
+ + ((frame->width + 1) / 2) * ((frame->height + 1) / 2)
+ + ((frame->width + 1) / 2) * ((frame->height + 1) / 2);
+ break;
+
+ case XINE_IMGFMT_YUY2:
+ required_size = frame->width * frame->height
+ + ((frame->width + 1) / 2) * frame->height
+ + ((frame->width + 1) / 2) * frame->height;
+ break;
+
+ default:
+ if (data->img || (flags & XINE_FRAME_DATA_ALLOCATE_IMG)) {
+ xprintf (stream->xine, XINE_VERBOSITY_DEBUG,
+ "xine: error, snapshot function not implemented for format 0x%x\n", frame->format);
+ _x_abort ();
+ }
+
+ required_size = 0;
+ }
+
+ if (flags & XINE_FRAME_DATA_ALLOCATE_IMG) {
+ /* return allocated buffer size */
+ data->img_size = required_size;
+ /* allocate img or fail */
+ if (!(data->img = calloc(1, required_size)))
+ return 0;
+ } else {
+ /* fail if supplied buffer is to small */
+ if (data->img && !img_size_unknown && data->img_size < required_size) {
+ data->img_size = required_size;
+ return 0;
+ }
+ /* return used buffer size */
+ data->img_size = required_size;
+ }
+
+ if (data->img) {
switch (frame->format) {
case XINE_IMGFMT_YV12:
yv12_to_yv12(
/* Y */
frame->base[0], frame->pitches[0],
- img, frame->width,
+ data->img, frame->width,
/* U */
frame->base[1], frame->pitches[1],
- img+frame->width*frame->height, frame->width/2,
+ data->img+frame->width*frame->height, frame->width/2,
/* V */
frame->base[2], frame->pitches[2],
- img+frame->width*frame->height+frame->width*frame->height/4, frame->width/2,
+ data->img+frame->width*frame->height+frame->width*frame->height/4, frame->width/2,
/* width x height */
frame->width, frame->height);
break;
@@ -1952,7 +2064,7 @@ int xine_get_current_frame (xine_stream_t *stream, int *width, int *height,
/* src */
frame->base[0], frame->pitches[0],
/* dst */
- img, frame->width*2,
+ data->img, frame->width*2,
/* width x height */
frame->width, frame->height);
break;
@@ -1966,6 +2078,69 @@ int xine_get_current_frame (xine_stream_t *stream, int *width, int *height,
return 1;
}
+int xine_get_current_frame_data (xine_stream_t *stream,
+ xine_current_frame_data_t *data,
+ int flags) {
+
+ return _x_get_current_frame_data(stream, data, flags, 0);
+}
+
+int xine_get_current_frame_alloc (xine_stream_t *stream, int *width, int *height,
+ int *ratio_code, int *format,
+ uint8_t **img, int *img_size) {
+
+ int result;
+ xine_current_frame_data_t data;
+
+ memset(&data, 0, sizeof (data));
+
+ result = _x_get_current_frame_data(stream, &data, img ? XINE_FRAME_DATA_ALLOCATE_IMG : 0, 0);
+ if (width) *width = data.width;
+ if (height) *height = data.height;
+ if (ratio_code) *ratio_code = data.ratio_code;
+ if (format) *format = data.format;
+ if (img_size) *img_size = data.img_size;
+ if (img) *img = data.img;
+ return result;
+}
+
+int xine_get_current_frame_s (xine_stream_t *stream, int *width, int *height,
+ int *ratio_code, int *format,
+ uint8_t *img, int *img_size) {
+ int result;
+ xine_current_frame_data_t data;
+
+ memset(&data, 0, sizeof (data));
+ data.img = img;
+ if (img_size)
+ data.img_size = *img_size;
+
+ result = _x_get_current_frame_data(stream, &data, 0, 0);
+ if (width) *width = data.width;
+ if (height) *height = data.height;
+ if (ratio_code) *ratio_code = data.ratio_code;
+ if (format) *format = data.format;
+ if (img_size) *img_size = data.img_size;
+ return result;
+}
+
+int xine_get_current_frame (xine_stream_t *stream, int *width, int *height,
+ int *ratio_code, int *format,
+ uint8_t *img) {
+ int result;
+ xine_current_frame_data_t data;
+
+ memset(&data, 0, sizeof (data));
+ data.img = img;
+
+ result = _x_get_current_frame_data(stream, &data, 0, 1);
+ if (width) *width = data.width;
+ if (height) *height = data.height;
+ if (ratio_code) *ratio_code = data.ratio_code;
+ if (format) *format = data.format;
+ return result;
+}
+
int xine_get_video_frame (xine_stream_t *stream,
int timestamp, /* msec */
int *width, int *height,
@@ -2084,7 +2259,10 @@ void xine_log (xine_t *this, int buf, const char *format, ...) {
vsnprintf(buffer, SCRATCH_LINE_LEN_MAX, format, argp);
printf("%s", buffer);
va_end (argp);
- }
+ }
+
+ if (this->log_cb)
+ this->log_cb (this->log_cb_user_data, buf);
}
void xine_vlog(xine_t *this, int buf, const char *format,
@@ -2093,6 +2271,9 @@ void xine_vlog(xine_t *this, int buf, const char *format,
check_log_alloc (this, buf);
this->log_buffers[buf]->scratch_printf(this->log_buffers[buf], format, args);
+
+ if (this->log_cb)
+ this->log_cb (this->log_cb_user_data, buf);
}
char *const *xine_get_log (xine_t *this, int buf) {
@@ -2107,12 +2288,10 @@ char *const *xine_get_log (xine_t *this, int buf) {
}
void xine_register_log_cb (xine_t *this, xine_log_cb_t cb, void *user_data) {
-
- printf ("xine: xine_register_log_cb: not implemented yet.\n");
- _x_abort();
+ this->log_cb = cb;
+ this->log_cb_user_data = user_data;
}
-
int xine_get_error (xine_stream_t *stream) {
return stream->err;
}
diff --git a/src/xine-engine/xine_interface.c b/src/xine-engine/xine_interface.c
index 50d8796e8..0438aedfa 100644
--- a/src/xine-engine/xine_interface.c
+++ b/src/xine-engine/xine_interface.c
@@ -527,6 +527,9 @@ void xine_set_param (xine_stream_t *stream, int param, int value) {
case XINE_PARAM_GAPLESS_SWITCH:
stream->gapless_switch = !!value;
+ if( stream->gapless_switch && !stream->early_finish_event ) {
+ xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "frontend possibly buggy: gapless_switch without early_finish_event\n");
+ }
break;
default:
@@ -739,6 +742,8 @@ uint32_t xine_get_stream_info (xine_stream_t *stream, int info) {
case XINE_STREAM_INFO_IGNORE_AUDIO:
case XINE_STREAM_INFO_IGNORE_SPU:
case XINE_STREAM_INFO_VIDEO_HAS_STILL:
+ case XINE_STREAM_INFO_SKIPPED_FRAMES:
+ case XINE_STREAM_INFO_DISCARDED_FRAMES:
case XINE_STREAM_INFO_VIDEO_AFD:
case XINE_STREAM_INFO_DVD_TITLE_NUMBER:
case XINE_STREAM_INFO_DVD_TITLE_COUNT:
@@ -945,7 +950,7 @@ int _x_message(xine_stream_t *stream, int type, ...) {
xine_ui_message_data_t *data;
xine_event_t event;
const char *explanation;
- int size;
+ size_t size;
int n;
va_list ap;
char *s, *params;
@@ -990,7 +995,7 @@ int _x_message(xine_stream_t *stream, int type, ...) {
args[n] = NULL;
size += sizeof(xine_ui_message_data_t) + 1;
- data = xine_xmalloc( size );
+ data = calloc(1, size );
strcpy(data->compatibility.str, "Upgrade your frontend to see the error messages");
data->type = type;
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
index 9b69f16f1..945157fc2 100644
--- a/src/xine-engine/xine_internal.h
+++ b/src/xine-engine/xine_internal.h
@@ -117,6 +117,9 @@ struct xine_s {
#ifdef XINE_ENGINE_INTERNAL
xine_ticket_t *port_ticket;
pthread_mutex_t log_lock;
+
+ xine_log_cb_t log_cb;
+ void *log_cb_user_data;
#endif
};
@@ -333,6 +336,7 @@ struct xine_stream_s {
int demux_thread_running;
pthread_mutex_t demux_lock;
int demux_action_pending;
+ pthread_cond_t demux_resume;
pthread_mutex_t demux_mutex; /* used in _x_demux_... functions to synchronize order of pairwise A/V buffer operations */
extra_info_t *current_extra_info;
@@ -357,6 +361,7 @@ struct xine_stream_s {
int early_finish_event; /* do not wait fifos get empty before sending event */
int gapless_switch; /* next stream switch will be gapless */
int delay_finish_event; /* delay event in 1/10 sec units. 0=>no delay, -1=>forever */
+ int keep_ao_driver_open;
#endif
};
@@ -388,8 +393,8 @@ input_plugin_t *_x_find_input_plugin (xine_stream_t *stream, const char *mrl) XI
demux_plugin_t *_x_find_demux_plugin (xine_stream_t *stream, input_plugin_t *input) XINE_PROTECTED;
demux_plugin_t *_x_find_demux_plugin_by_name (xine_stream_t *stream, const char *name, input_plugin_t *input) XINE_PROTECTED;
demux_plugin_t *_x_find_demux_plugin_last_probe(xine_stream_t *stream, const char *last_demux_name, input_plugin_t *input) XINE_PROTECTED;
-input_plugin_t *_x_rip_plugin_get_instance (xine_stream_t *stream, const char *filename) XINE_PROTECTED;
-input_plugin_t *_x_cache_plugin_get_instance (xine_stream_t *stream, int readahead_size) XINE_PROTECTED;
+input_plugin_t *_x_rip_plugin_get_instance (xine_stream_t *stream, const char *filename) XINE_MALLOC XINE_PROTECTED;
+input_plugin_t *_x_cache_plugin_get_instance (xine_stream_t *stream, int readahead_size) XINE_MALLOC XINE_PROTECTED;
void _x_free_input_plugin (xine_stream_t *stream, input_plugin_t *input) XINE_PROTECTED;
void _x_free_demux_plugin (xine_stream_t *stream, demux_plugin_t *demux) XINE_PROTECTED;