summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/xine-engine/audio_out.c20
-rw-r--r--src/xine-engine/video_out.c8
-rw-r--r--src/xine-engine/xine.c63
3 files changed, 88 insertions, 3 deletions
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index 5bb8242ae..4b2398bef 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -291,6 +291,7 @@ struct audio_fifo_s {
pthread_cond_t empty;
int num_buffers;
+ int num_buffers_max;
};
static int ao_get_property (xine_audio_port_t *this_gen, int property);
@@ -305,9 +306,10 @@ static audio_fifo_t *XINE_MALLOC fifo_new (xine_t *xine) {
if (!fifo)
return NULL;
- fifo->first = NULL;
- fifo->last = NULL;
- fifo->num_buffers = 0;
+ fifo->first = NULL;
+ fifo->last = NULL;
+ fifo->num_buffers = 0;
+ fifo->num_buffers_max = 0;
pthread_mutex_init (&fifo->mutex, NULL);
pthread_cond_init (&fifo->not_empty, NULL);
pthread_cond_init (&fifo->empty, NULL);
@@ -334,6 +336,10 @@ static void fifo_append_int (audio_fifo_t *fifo,
fifo->num_buffers++;
}
+
+ if (fifo->num_buffers_max < fifo->num_buffers)
+ fifo->num_buffers_max = fifo->num_buffers;
+
pthread_cond_signal (&fifo->not_empty);
}
@@ -1779,6 +1785,14 @@ static int ao_get_property (xine_audio_port_t *this_gen, int property) {
ret = this->audio_loop_running ? this->out_fifo->num_buffers : -1;
break;
+ case AO_PROP_BUFS_FREE:
+ ret = this->audio_loop_running ? this->free_fifo->num_buffers : -1;
+ break;
+
+ case AO_PROP_BUFS_TOTAL:
+ ret = this->audio_loop_running ? this->free_fifo->num_buffers_max : -1;
+ break;
+
case AO_PROP_NUM_STREAMS:
pthread_mutex_lock(&this->streams_lock);
ret = xine_list_size(this->streams);
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index 2ffd5ae1d..fc227443c 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -1460,6 +1460,14 @@ static int vo_get_property (xine_video_port_t *this_gen, int property) {
ret = this->video_loop_running ? this->display_img_buf_queue->num_buffers : -1;
break;
+ case VO_PROP_BUFS_FREE:
+ ret = this->video_loop_running ? this->free_img_buf_queue->num_buffers : -1;
+ break;
+
+ case VO_PROP_BUFS_TOTAL:
+ ret = this->video_loop_running ? this->free_img_buf_queue->num_buffers_max : -1;
+ break;
+
case VO_PROP_NUM_STREAMS:
pthread_mutex_lock(&this->streams_lock);
ret = xine_list_size(this->streams);
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index c3896c353..c2e6641ec 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.c
@@ -2399,6 +2399,69 @@ int _x_query_buffer_usage(xine_stream_t *stream, int *num_video_buffers, int *nu
return ticket_acquired != 0;
}
+static void _x_query_buffers_fix_data(xine_query_buffers_data_t *data)
+{
+ if (data->total < 0)
+ data->total = 0;
+
+ if (data->ready < 0)
+ data->ready = 0;
+
+ if (data->avail < 0)
+ data->avail = 0;
+
+ /* fix race condition of not filling data atomically */
+ if (data->ready + data->avail > data->total)
+ data->avail = data->total - data->ready;
+}
+
+int _x_query_buffers(xine_stream_t *stream, xine_query_buffers_t *query)
+{
+ int ticket_acquired = -1;
+
+ memset(query, 0, sizeof (*query));
+
+ if (stream->video_fifo)
+ {
+ query->vi.total = stream->video_fifo->buffer_pool_capacity;
+ query->vi.ready = stream->video_fifo->size(stream->video_fifo);
+ query->vi.avail = stream->video_fifo->num_free(stream->video_fifo);
+ _x_query_buffers_fix_data(&query->vi);
+ }
+
+ if (stream->audio_fifo)
+ {
+ query->ai.total = stream->audio_fifo->buffer_pool_capacity;
+ query->ai.ready = stream->audio_fifo->size(stream->audio_fifo);
+ query->ai.avail = stream->audio_fifo->num_free(stream->audio_fifo);
+ _x_query_buffers_fix_data(&query->ai);
+ }
+
+ if (stream->video_out || stream->audio_out)
+ ticket_acquired = stream->xine->port_ticket->acquire_nonblocking(stream->xine->port_ticket, 1);
+
+ if (ticket_acquired > 0)
+ {
+ if (stream->video_out)
+ {
+ query->vo.total = stream->video_out->get_property(stream->video_out, VO_PROP_BUFS_TOTAL);
+ query->vo.ready = stream->video_out->get_property(stream->video_out, VO_PROP_BUFS_IN_FIFO);
+ query->vo.avail = stream->video_out->get_property(stream->video_out, VO_PROP_BUFS_FREE);
+ }
+
+ if (stream->audio_out)
+ {
+ query->ao.total = stream->audio_out->get_property(stream->audio_out, AO_PROP_BUFS_TOTAL);
+ query->ao.ready = stream->audio_out->get_property(stream->audio_out, AO_PROP_BUFS_IN_FIFO);
+ query->ao.avail = stream->audio_out->get_property(stream->audio_out, AO_PROP_BUFS_FREE);
+ }
+
+ stream->xine->port_ticket->release_nonblocking(stream->xine->port_ticket, 1);
+ }
+
+ return ticket_acquired != 0;
+}
+
int _x_lock_port_rewiring(xine_t *xine, int ms_timeout)
{
return xine->port_ticket->lock_port_rewiring(xine->port_ticket, ms_timeout);