diff options
Diffstat (limited to 'src/xine-engine')
-rw-r--r-- | src/xine-engine/buffer.c | 67 | ||||
-rw-r--r-- | src/xine-engine/buffer.h | 18 | ||||
-rw-r--r-- | src/xine-engine/demux.c | 29 | ||||
-rw-r--r-- | src/xine-engine/xine.c | 58 |
4 files changed, 117 insertions, 55 deletions
diff --git a/src/xine-engine/buffer.c b/src/xine-engine/buffer.c index af2f08242..7c3a94bf5 100644 --- a/src/xine-engine/buffer.c +++ b/src/xine-engine/buffer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2002 the xine project + * Copyright (C) 2000-2003 the xine project * * This file is part of xine, a free video player. * @@ -12,12 +12,12 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: buffer.c,v 1.26 2003/03/03 07:37:23 esnel Exp $ + * $Id: buffer.c,v 1.27 2003/03/30 15:19:46 tmattern Exp $ * * * contents: @@ -65,7 +65,7 @@ static void buffer_pool_free (buf_element_t *element) { */ static buf_element_t *buffer_pool_alloc (fifo_buffer_t *this) { - + buf_element_t *buf; pthread_mutex_lock (&this->buffer_pool_mutex); @@ -109,9 +109,9 @@ static buf_element_t *buffer_pool_try_alloc (fifo_buffer_t *this) { this->buffer_pool_num_free--; } else { - + buf = NULL; - + } pthread_mutex_unlock (&this->buffer_pool_mutex); @@ -132,12 +132,15 @@ static buf_element_t *buffer_pool_try_alloc (fifo_buffer_t *this) { * append buffer element to fifo buffer */ static void fifo_buffer_put (fifo_buffer_t *fifo, buf_element_t *element) { - + pthread_mutex_lock (&fifo->mutex); - if (fifo->last) + if (fifo->put_cb) + fifo->put_cb(fifo, element, fifo->put_cb_data); + + if (fifo->last) fifo->last->next = element; - else + else fifo->first = element; fifo->last = element; @@ -154,15 +157,15 @@ static void fifo_buffer_put (fifo_buffer_t *fifo, buf_element_t *element) { * insert buffer element to fifo buffer (demuxers MUST NOT call this one) */ static void fifo_buffer_insert (fifo_buffer_t *fifo, buf_element_t *element) { - + pthread_mutex_lock (&fifo->mutex); element->next = fifo->first; fifo->first = element; - + if( !fifo->last ) fifo->last = element; - + fifo->fifo_size++; fifo->fifo_data_size += element->size; @@ -194,6 +197,9 @@ static buf_element_t *fifo_buffer_get (fifo_buffer_t *fifo) { fifo->fifo_size--; fifo->fifo_data_size -= buf->size; + if (fifo->get_cb) + fifo->get_cb(fifo, buf, fifo->get_cb_data); + pthread_mutex_unlock (&fifo->mutex); return buf; @@ -227,6 +233,7 @@ static void fifo_buffer_clear (fifo_buffer_t *fifo) { fifo->last = prev; fifo->fifo_size--; + fifo->fifo_data_size -= buf->size; buf->free_buffer(buf); } else @@ -318,6 +325,34 @@ static void fifo_buffer_dispose (fifo_buffer_t *this) { } /* + * Register a "put" callback + */ +static void fifo_register_put_cb (fifo_buffer_t *this, + void (*cb)(fifo_buffer_t *this, + buf_element_t *buf, + void *data_cb), + void *data_cb) { + pthread_mutex_lock(&this->mutex); + this->put_cb = cb; + this->put_cb_data = data_cb; + pthread_mutex_unlock(&this->mutex); +} + +/* + * Register a "get" callback + */ +static void fifo_register_get_cb (fifo_buffer_t *this, + void (*cb)(fifo_buffer_t *this, + buf_element_t *buf, + void *data_cb), + void *data_cb) { + pthread_mutex_lock(&this->mutex); + this->get_cb = cb; + this->get_cb_data = data_cb; + pthread_mutex_unlock(&this->mutex); +} + +/* * allocate and initialize new (empty) fifo buffer */ fifo_buffer_t *fifo_buffer_new (int num_buffers, uint32_t buf_size) { @@ -340,7 +375,8 @@ fifo_buffer_t *fifo_buffer_new (int num_buffers, uint32_t buf_size) { this->num_free = fifo_buffer_num_free; this->data_size = fifo_buffer_data_size; this->dispose = fifo_buffer_dispose; - + this->register_get_cb = fifo_register_get_cb; + this->register_put_cb = fifo_register_put_cb; pthread_mutex_init (&this->mutex, NULL); pthread_cond_init (&this->not_empty, NULL); @@ -384,7 +420,10 @@ fifo_buffer_t *fifo_buffer_new (int num_buffers, uint32_t buf_size) { this->buffer_pool_buf_size = buf_size; this->buffer_pool_alloc = buffer_pool_alloc; this->buffer_pool_try_alloc = buffer_pool_try_alloc; - + this->get_cb = NULL; + this->put_cb = NULL; + this->get_cb_data = NULL; + this->put_cb_data = NULL; return this; } diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h index a1d9073df..98d8bb67a 100644 --- a/src/xine-engine/buffer.h +++ b/src/xine-engine/buffer.h @@ -12,12 +12,12 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: buffer.h,v 1.105 2003/03/23 17:12:30 holstsn Exp $ + * $Id: buffer.h,v 1.106 2003/03/30 15:19:46 tmattern Exp $ * * * contents: @@ -158,7 +158,7 @@ extern "C" { #define BUF_AUDIO_DTS 0x03050000 #define BUF_AUDIO_MSADPCM 0x03060000 #define BUF_AUDIO_MSIMAADPCM 0x03070000 -#define BUF_AUDIO_MSGSM 0x03080000 +#define BUF_AUDIO_MSGSM 0x03080000 #define BUF_AUDIO_VORBIS 0x03090000 #define BUF_AUDIO_IMC 0x030a0000 #define BUF_AUDIO_LH 0x030b0000 @@ -199,7 +199,7 @@ extern "C" { #define BUF_AUDIO_WMAV 0x032E0000 /* spu buffer types: */ - + #define BUF_SPU_BASE 0x04000000 #define BUF_SPU_DVD 0x04000000 #define BUF_SPU_TEXT 0x04010000 @@ -226,7 +226,7 @@ struct buf_element_s { unsigned char *content; /* start of raw content in mem (without header etc) */ int32_t size ; /* size of _content_ */ - int32_t max_size; /* size of pre-allocated memory pointed to by "mem" */ + int32_t max_size; /* size of pre-allocated memory pointed to by "mem" */ uint32_t type; int64_t pts; /* presentation time stamp, used for a/v sync */ int64_t disc_off; /* discontinuity offset */ @@ -443,10 +443,12 @@ struct fifo_buffer_s /* the same as put but insert at the head of the fifo */ void (*insert) (fifo_buffer_t *fifo, buf_element_t *buf); + void (*register_put_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *), void *cb_data); + void (*register_get_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *), void *cb_data); + /* * private variables for buffer pool management */ - buf_element_t *buffer_pool_top; /* a stack actually */ pthread_mutex_t buffer_pool_mutex; pthread_cond_t buffer_pool_cond_not_empty; @@ -454,6 +456,10 @@ struct fifo_buffer_s int buffer_pool_capacity; int buffer_pool_buf_size; void *buffer_pool_base; /*used to free mem chunk */ + void (*put_cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *data_cb); + void (*get_cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *data_cb); + void *put_cb_data; + void *get_cb_data; } ; /* diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c index 1edfac777..88c5515f5 100644 --- a/src/xine-engine/demux.c +++ b/src/xine-engine/demux.c @@ -160,7 +160,7 @@ void xine_demux_control_start( xine_stream_t *stream ) { void xine_demux_control_end( xine_stream_t *stream, uint32_t flags ) { buf_element_t *buf; - + buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo); buf->type = BUF_CONTROL_END; buf->decoder_flags = flags; @@ -174,15 +174,32 @@ void xine_demux_control_end( xine_stream_t *stream, uint32_t flags ) { } } +void xine_demux_control_nop( xine_stream_t *stream, uint32_t flags ) { + + buf_element_t *buf; + + buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo); + buf->type = BUF_CONTROL_NOP; + buf->decoder_flags = flags; + stream->video_fifo->put (stream->video_fifo, buf); + + if (stream->audio_fifo) { + buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo); + buf->type = BUF_CONTROL_NOP; + buf->decoder_flags = flags; + stream->audio_fifo->put (stream->audio_fifo, buf); + } +} + static void *demux_loop (void *stream_gen) { xine_stream_t *stream = (xine_stream_t *)stream_gen; int status; - + #ifdef LOG printf ("demux: loop starting...\n"); #endif - + pthread_mutex_lock( &stream->demux_lock ); /* do-while needed to seek after demux finished */ @@ -208,13 +225,9 @@ static void *demux_loop (void *stream_gen) { #ifdef LOG printf ("demux: main demuxer loop finished (status: %d)\n", status); #endif - /* Avoid deadlock with net_buf_ctrl */ - stream->xine->clock->set_speed (stream->xine->clock, XINE_SPEED_NORMAL); - stream->xine->clock->set_option (stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 1); - if (stream->audio_out) - stream->audio_out->set_property(stream->audio_out,AO_PROP_PAUSED,0); /* wait before sending end buffers: user might want to do a new seek */ + xine_demux_control_nop(stream, BUF_FLAG_END_STREAM); while(stream->demux_thread_running && ((!stream->video_fifo || stream->video_fifo->size(stream->video_fifo)) || (stream->audio_out diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 144789039..c927eb162 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine.c,v 1.239 2003/03/27 18:57:10 miguelfreitas Exp $ + * $Id: xine.c,v 1.240 2003/03/30 15:19:46 tmattern Exp $ * * top-level xine functions * @@ -782,11 +782,11 @@ static int xine_open_internal (xine_stream_t *stream, const char *mrl) { free(config_entry); } } - + } if (!stream->demux_plugin) { - + /* * find a demux plugin */ @@ -796,6 +796,10 @@ static int xine_open_internal (xine_stream_t *stream, const char *mrl) { stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; stream->status = XINE_STATUS_STOP; + + /* force the engine to unregister fifo callbacks */ + xine_demux_control_nop(stream, BUF_FLAG_END_STREAM); + return 0; } @@ -807,7 +811,7 @@ static int xine_open_internal (xine_stream_t *stream, const char *mrl) { = strdup (stream->demux_plugin->demux_class->get_identifier(stream->demux_plugin->demux_class)); } - xine_log (stream->xine, XINE_LOG_MSG, + xine_log (stream->xine, XINE_LOG_MSG, "xine: found demuxer plugin: %s\n", stream->demux_plugin->demux_class->get_description(stream->demux_plugin->demux_class)); @@ -820,7 +824,7 @@ static int xine_open_internal (xine_stream_t *stream, const char *mrl) { */ stream->stream_info[XINE_STREAM_INFO_VIDEO_HANDLED] = 1; stream->stream_info[XINE_STREAM_INFO_AUDIO_HANDLED] = 1; - + /* * send and decode headers */ @@ -834,7 +838,7 @@ static int xine_open_internal (xine_stream_t *stream, const char *mrl) { stream->demux_plugin->dispose (stream->demux_plugin); stream->demux_plugin = NULL; - if (stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) + if (stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) printf ("xine: demux disposed\n"); stream->input_plugin->dispose (stream->input_plugin); @@ -846,15 +850,15 @@ static int xine_open_internal (xine_stream_t *stream, const char *mrl) { /*if (stream->audio_out) stream->audio_out->control (stream->audio_out, AO_CTRL_FLUSH_BUFFERS); */ - + stream->status = XINE_STATUS_STOP; - if (stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) + if (stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) printf ("xine: return from xine_open_internal\n"); return 0; } - + xine_demux_control_headers_done (stream); #ifdef LOG @@ -874,7 +878,7 @@ int xine_open (xine_stream_t *stream, const char *mrl) { #endif ret = xine_open_internal (stream, mrl); - + pthread_mutex_unlock (&stream->frontend_lock); return ret; @@ -887,10 +891,10 @@ static int xine_play_internal (xine_stream_t *stream, int start_pos, int start_t off_t pos, len; int demux_status; - if (stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) + if (stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) printf ("xine: xine_play\n"); - if (stream->xine->clock->speed != XINE_SPEED_NORMAL) + if (stream->xine->clock->speed != XINE_SPEED_NORMAL) xine_set_speed_internal (stream, XINE_SPEED_NORMAL); /* Wait until the first frame produced by the previous @@ -917,21 +921,21 @@ static int xine_play_internal (xine_stream_t *stream, int start_pos, int start_t len = stream->current_extra_info->input_length; pthread_mutex_unlock( &stream->current_extra_info_lock ); /* FIXME: do we need to protect concurrent access to input plugin here? */ - if ((len == 0) && stream->input_plugin) + if ((len == 0) && stream->input_plugin) len = stream->input_plugin->get_length (stream->input_plugin); share = (double) start_pos / 65535; pos = (off_t) (share * len) ; } else pos = 0; - + if (!stream->demux_plugin) { - xine_log (stream->xine, XINE_LOG_MSG, + xine_log (stream->xine, XINE_LOG_MSG, _("xine_play: no demux available\n")); stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; - + return 0; - } - + } + stream->demux_action_pending = 1; pthread_mutex_lock( &stream->demux_lock ); demux_status = stream->demux_plugin->seek (stream->demux_plugin, @@ -940,18 +944,18 @@ static int xine_play_internal (xine_stream_t *stream, int start_pos, int start_t pthread_mutex_unlock( &stream->demux_lock ); if (demux_status != DEMUX_OK) { - xine_log (stream->xine, XINE_LOG_MSG, + xine_log (stream->xine, XINE_LOG_MSG, _("xine_play: demux failed to start\n")); - + stream->err = XINE_ERROR_DEMUX_FAILED; - + return 0; - + } else { xine_demux_start_thread( stream ); stream->status = XINE_STATUS_PLAY; } - + pthread_mutex_lock (&stream->first_frame_lock); stream->first_frame_flag = 1; pthread_mutex_unlock (&stream->first_frame_lock); @@ -959,11 +963,11 @@ static int xine_play_internal (xine_stream_t *stream, int start_pos, int start_t extra_info_reset( stream->current_extra_info ); pthread_mutex_unlock( &stream->current_extra_info_lock ); - if (stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) + if (stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) printf ("xine: xine_play_internal ...done\n"); return 1; -} +} int xine_play (xine_stream_t *stream, int start_pos, int start_time) { @@ -1004,7 +1008,7 @@ int xine_eject (xine_stream_t *stream) { void xine_dispose (xine_stream_t *stream) { - if (stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) + if (stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) printf ("xine: xine_dispose\n"); stream->status = XINE_STATUS_QUIT; @@ -1315,7 +1319,7 @@ static int xine_get_stream_length (xine_stream_t *stream) { return 0; } -int xine_get_pos_length (xine_stream_t *stream, int *pos_stream, +int xine_get_pos_length (xine_stream_t *stream, int *pos_stream, int *pos_time, int *length_time) { int pos = xine_get_current_position (stream); /* force updating extra_info */ |