summaryrefslogtreecommitdiff
path: root/src/xine-engine
diff options
context:
space:
mode:
authorDarren Salt <linux@youmustbejoking.demon.co.uk>2008-04-09 18:28:49 +0100
committerDarren Salt <linux@youmustbejoking.demon.co.uk>2008-04-09 18:28:49 +0100
commit39939c95eff90545285a9a8f761d9fa6e9349358 (patch)
treeb8ea1fa3f2ddf1627eeecbd889f47226b01a45d8 /src/xine-engine
parent19357940a57c565ebe319729bd08d6e4800aff5d (diff)
parent628c4cbd9d023e74a7c6805d7ec0f163f2c172d1 (diff)
downloadxine-lib-39939c95eff90545285a9a8f761d9fa6e9349358.tar.gz
xine-lib-39939c95eff90545285a9a8f761d9fa6e9349358.tar.bz2
Merge from 1.2 main.
Diffstat (limited to 'src/xine-engine')
-rw-r--r--src/xine-engine/buffer_types.c8
-rw-r--r--src/xine-engine/configfile.c2
-rw-r--r--src/xine-engine/demux.c15
-rw-r--r--src/xine-engine/load_plugins.c19
-rw-r--r--src/xine-engine/xine.c141
5 files changed, 142 insertions, 43 deletions
diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c
index b0e01db31..15b5ff952 100644
--- a/src/xine-engine/buffer_types.c
+++ b/src/xine-engine/buffer_types.c
@@ -808,6 +808,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
diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c
index a41abf193..9f67b7503 100644
--- a/src/xine-engine/configfile.c
+++ b/src/xine-engine/configfile.c
@@ -1458,7 +1458,7 @@ static char* config_register_serialized_entry (config_values_t *this, const char
if (!bytes) goto exit;
if ((value_count < 0) || (value_count > 256)) goto exit;
- enum_values = malloc (sizeof(void*) * value_count + 1);
+ enum_values = calloc (value_count + 1, sizeof(void*));
for (i = 0; i < value_count; i++) {
pos += bytes = get_string(output, output_len, pos, &enum_values[i]);
if (!bytes) goto exit;
diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c
index 232e0342e..e641bbf77 100644
--- a/src/xine-engine/demux.c
+++ b/src/xine-engine/demux.c
@@ -198,6 +198,7 @@ void _x_demux_control_headers_done (xine_stream_t *stream) {
}
stream->demux_action_pending = 0;
+ pthread_cond_signal(&stream->demux_resume);
lprintf ("headers processed.\n");
@@ -284,12 +285,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 );
+ struct timeval tv;
+ struct timespec ts;
- lprintf ("sched_yield\n");
-
- 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);
}
}
@@ -365,6 +368,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 +400,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.
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index 8e4a10a60..710e6dfbf 100644
--- a/src/xine-engine/load_plugins.c
+++ b/src/xine-engine/load_plugins.c
@@ -1339,11 +1339,13 @@ input_plugin_t *_x_find_input_plugin (xine_stream_t *stream, const char *mrl) {
void _x_free_input_plugin (xine_stream_t *stream, input_plugin_t *input) {
plugin_catalog_t *catalog = stream->xine->plugin_catalog;
+ plugin_node_t *node = input->node;
input->dispose(input);
- if (input->node) {
+
+ if (node) {
pthread_mutex_lock(&catalog->lock);
- dec_node_ref(input->node);
+ dec_node_ref(node);
pthread_mutex_unlock(&catalog->lock);
}
}
@@ -1560,11 +1562,13 @@ demux_plugin_t *_x_find_demux_plugin_last_probe(xine_stream_t *stream, const cha
void _x_free_demux_plugin (xine_stream_t *stream, demux_plugin_t *demux) {
plugin_catalog_t *catalog = stream->xine->plugin_catalog;
+ plugin_node_t *node = demux->node;
demux->dispose(demux);
- if (demux->node) {
+
+ if (node) {
pthread_mutex_lock(&catalog->lock);
- dec_node_ref(demux->node);
+ dec_node_ref(node);
pthread_mutex_unlock(&catalog->lock);
}
}
@@ -2054,12 +2058,13 @@ video_decoder_t *_x_get_video_decoder (xine_stream_t *stream, uint8_t stream_typ
void _x_free_video_decoder (xine_stream_t *stream, video_decoder_t *vd) {
plugin_catalog_t *catalog = stream->xine->plugin_catalog;
+ plugin_node_t *node = vd->node;
vd->dispose (vd);
- if (vd->node) {
+ if (node) {
pthread_mutex_lock (&catalog->lock);
- dec_node_ref(vd->node);
+ dec_node_ref(node);
pthread_mutex_unlock (&catalog->lock);
}
}
@@ -2403,7 +2408,7 @@ const char *const *xine_list_post_plugins_typed(xine_t *xine, uint32_t type) {
else \
return NULL; \
} \
- return dgettext(ic->textdomain ? : XINE_TEXTDOMAIN, ic->description); \
+ return dgettext(ic->text_domain ? : XINE_TEXTDOMAIN, ic->description); \
} \
} \
return NULL; \
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index c6dc8a2ce..5c8d0be9d 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__)
@@ -138,7 +139,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);
@@ -209,7 +210,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;
}
@@ -670,6 +671,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);
@@ -839,6 +841,7 @@ static inline int _x_path_looks_like_mrl (const char *path)
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) {
@@ -862,16 +865,31 @@ static int open_internal (xine_stream_t *stream, const char *mrl) {
/*
* 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, '#');
+ }
}
{
@@ -880,12 +898,14 @@ static int open_internal (xine_stream_t *stream, const char *mrl) {
/*
* 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"),
- dgettext(stream->input_plugin->input_class->textdomain ? : XINE_TEXTDOMAIN,
+ dgettext(stream->input_plugin->input_class->text_domain ? : XINE_TEXTDOMAIN,
stream->input_plugin->input_class->description));
if (stream->input_plugin->input_class->eject_media)
stream->eject_class = stream->input_plugin->input_class;
@@ -897,7 +917,6 @@ static int open_internal (xine_stream_t *stream, const char *mrl) {
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;
@@ -908,8 +927,6 @@ static int open_internal (xine_stream_t *stream, const char *mrl) {
stream->err = XINE_ERROR_INPUT_FAILED;
}
}
-
- free(input_source);
}
if (!stream->input_plugin) {
@@ -1235,7 +1252,7 @@ static int open_internal (xine_stream_t *stream, const char *mrl) {
}
xine_log (stream->xine, XINE_LOG_MSG, _("xine: found demuxer plugin: %s\n"),
- dgettext(stream->demux_plugin->demux_class->textdomain ? : XINE_TEXTDOMAIN,
+ dgettext(stream->demux_plugin->demux_class->text_domain ? : XINE_TEXTDOMAIN,
stream->demux_plugin->demux_class->description));
_x_extra_info_reset( stream->current_extra_info );
@@ -1351,6 +1368,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
@@ -1477,6 +1495,7 @@ static 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);
@@ -1691,6 +1710,12 @@ void xine_init (xine_t *this) {
/* First of all, initialise libxdg-basedir as it's used by plugins. */
this->basedir_handle = xdgAllocHandle();
+ /*
+ * locks
+ */
+ pthread_mutex_init (&this->streams_lock, NULL);
+ pthread_mutex_init (&this->log_lock, NULL);
+
/* initialize color conversion tables and functions */
init_yuv_conversion();
@@ -1772,12 +1797,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
*/
@@ -1963,11 +1982,12 @@ 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_impl (xine_stream_t *stream, int *width, int *height,
+ int *ratio_code, int *format,
+ uint8_t **img, int *size, int alloc_img) {
vo_frame_t *frame;
+ int required_size;
stream->xine->port_ticket->acquire(stream->xine->port_ticket, 0);
frame = stream->video_out->get_last_frame (stream->video_out);
@@ -1993,20 +2013,62 @@ int xine_get_current_frame (xine_stream_t *stream, int *width, int *height,
*format = frame->format;
- if (img){
+ switch (*format) {
+
+ case XINE_IMGFMT_YV12:
+ required_size = *width * *height
+ + ((*width + 1) / 2) * ((*height + 1) / 2)
+ + ((*width + 1) / 2) * ((*height + 1) / 2);
+ break;
+
+ case XINE_IMGFMT_YUY2:
+ required_size = *width * *height
+ + ((*width + 1) / 2) * *height
+ + ((*width + 1) / 2) * *height;
+ break;
+
+ default:
+ if (*img || alloc_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 (alloc_img) {
+ /* return size if requested */
+ if (size)
+ *size = required_size;
+ /* allocate img or fail */
+ if (!(*img = xine_xmalloc (required_size)))
+ return 0;
+ } else {
+ /* fail if supplied buffer is to small */
+ if (*img && size && *size < required_size) {
+ *size = required_size;
+ return 0;
+ }
+ /* return size if requested */
+ if (size)
+ *size = required_size;
+ }
+
+ if (*img) {
switch (frame->format) {
case XINE_IMGFMT_YV12:
yv12_to_yv12(
/* Y */
frame->base[0], frame->pitches[0],
- img, frame->width,
+ *img, frame->width,
/* U */
frame->base[1], frame->pitches[1],
- img+frame->width*frame->height, frame->width/2,
+ *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,
+ *img+frame->width*frame->height+frame->width*frame->height/4, frame->width/2,
/* width x height */
frame->width, frame->height);
break;
@@ -2016,7 +2078,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,
+ *img, frame->width*2,
/* width x height */
frame->width, frame->height);
break;
@@ -2030,6 +2092,25 @@ int xine_get_current_frame (xine_stream_t *stream, int *width, int *height,
return 1;
}
+int xine_get_current_frame_alloc (xine_stream_t *stream, int *width, int *height,
+ int *ratio_code, int *format,
+ uint8_t **img, int *size) {
+ uint8_t *no_img = NULL;
+ return _x_get_current_frame_impl(stream, width, height, ratio_code, format, img ? img : &no_img, size, img != NULL);
+}
+
+int xine_get_current_frame_s (xine_stream_t *stream, int *width, int *height,
+ int *ratio_code, int *format,
+ uint8_t *img, int *size) {
+ return (!img || size) && _x_get_current_frame_impl(stream, width, height, ratio_code, format, &img, size, 0);
+}
+
+int xine_get_current_frame (xine_stream_t *stream, int *width, int *height,
+ int *ratio_code, int *format,
+ uint8_t *img) {
+ return _x_get_current_frame_impl(stream, width, height, ratio_code, format, &img, NULL, 0);
+}
+
int xine_get_video_frame (xine_stream_t *stream,
int timestamp, /* msec */
int *width, int *height,