summaryrefslogtreecommitdiff
path: root/src/xine-engine
diff options
context:
space:
mode:
authorDarren Salt <linux@youmustbejoking.demon.co.uk>2007-07-13 21:47:37 +0100
committerDarren Salt <linux@youmustbejoking.demon.co.uk>2007-07-13 21:47:37 +0100
commitaf9e42132f6dcc13866892eb47367940ef04c6f9 (patch)
tree8a9e5da2417658c1d7da84ddb9102cc5f8c30492 /src/xine-engine
parentf158a50df518175dbba6a665a52b2ffa472237ae (diff)
parentb417806ce02dcc44352610e6898f6287677b13e1 (diff)
downloadxine-lib-af9e42132f6dcc13866892eb47367940ef04c6f9.tar.gz
xine-lib-af9e42132f6dcc13866892eb47367940ef04c6f9.tar.bz2
Merge from 1.1.
Diffstat (limited to 'src/xine-engine')
-rw-r--r--src/xine-engine/osd.c20
-rw-r--r--src/xine-engine/video_overlay.c8
-rw-r--r--src/xine-engine/xine.c63
-rw-r--r--src/xine-engine/xine_internal.h6
4 files changed, 77 insertions, 20 deletions
diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c
index ab34a11e9..ff9cc2176 100644
--- a/src/xine-engine/osd.c
+++ b/src/xine-engine/osd.c
@@ -199,7 +199,7 @@ static int _osd_show (osd_object_t *osd, int64_t vpts, int unscaled ) {
osd_renderer_t *this = osd->renderer;
video_overlay_manager_t *ovl_manager;
rle_elem_t rle, *rle_p=0;
- int x, y, required;
+ int x, y;
uint8_t *c;
lprintf("osd=%p vpts=%"PRId64"\n", osd, vpts);
@@ -253,11 +253,11 @@ static int _osd_show (osd_object_t *osd, int64_t vpts, int unscaled ) {
this->event.object.overlay->hili_right = this->event.object.overlay->width;
/* there will be at least that many rle objects (one for each row) */
- required = osd->y2 - osd->y1;
this->event.object.overlay->num_rle = 0;
- this->event.object.overlay->data_size = 1024;
- while (required > this->event.object.overlay->data_size)
- this->event.object.overlay->data_size += 1024;
+ /* We will never need more rle objects than columns in any row
+ Rely on lazy page allocation to avoid us actually taking up
+ this much RAM */
+ this->event.object.overlay->data_size = osd->width * osd->height;
rle_p = this->event.object.overlay->rle =
malloc(this->event.object.overlay->data_size * sizeof(rle_elem_t) );
@@ -274,14 +274,6 @@ static int _osd_show (osd_object_t *osd, int64_t vpts, int unscaled ) {
/* loop over the remaining pixels in the row */
for( x = osd->x1 + rle.len; x < osd->x2; x++, c++ ) {
if( rle.color != *c ) {
- if( (this->event.object.overlay->num_rle + required) >
- this->event.object.overlay->data_size ) {
- this->event.object.overlay->data_size += 1024;
- rle_p = this->event.object.overlay->rle =
- realloc( this->event.object.overlay->rle,
- this->event.object.overlay->data_size * sizeof(rle_elem_t) );
- rle_p += this->event.object.overlay->num_rle;
- }
#ifdef DEBUG_RLE
lprintf("(%d, %d), ", rle.len, rle.color);
#endif
@@ -299,8 +291,6 @@ static int _osd_show (osd_object_t *osd, int64_t vpts, int unscaled ) {
#endif
*rle_p++ = rle;
this->event.object.overlay->num_rle++;
- /* another row done */
- required--;
}
#ifdef DEBUG_RLE
lprintf("osd_show %p rle ends\n", osd);
diff --git a/src/xine-engine/video_overlay.c b/src/xine-engine/video_overlay.c
index 231aa5a70..574f42ac3 100644
--- a/src/xine-engine/video_overlay.c
+++ b/src/xine-engine/video_overlay.c
@@ -395,6 +395,8 @@ static int video_overlay_event( video_overlay_t *this, int64_t vpts ) {
#endif
/* free any overlay associated with this event */
if (this->events[this_event].event->object.overlay != NULL) {
+ if( this->events[this_event].event->object.overlay->rle != NULL )
+ free( this->events[this_event].event->object.overlay->rle );
free(this->events[this_event].event->object.overlay);
this->events[this_event].event->object.overlay = NULL;
}
@@ -406,9 +408,11 @@ static int video_overlay_event( video_overlay_t *this, int64_t vpts ) {
printf ("video_overlay: FREE SPU NOW\n");
#endif
/* free any overlay associated with this event */
- if (this->events[this_event].event->object.overlay != NULL) {
+ if( this->events[this_event].event->object.overlay != NULL) {
+ if( this->events[this_event].event->object.overlay->rle != NULL )
+ free( this->events[this_event].event->object.overlay->rle );
free(this->events[this_event].event->object.overlay);
- this->events[this_event].event->object.overlay = NULL;
+ this->events[this_event].event->object.overlay = NULL;
}
/* this avoid removing this_event from the queue
* (it will be removed at the end of this loop) */
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index e44419ecf..5399dedbd 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.c
@@ -129,17 +129,54 @@ void _x_extra_info_merge( extra_info_t *dst, extra_info_t *src ) {
}
}
+static int acquire_allowed_to_block(xine_ticket_t *this) {
+ pthread_t own_id = pthread_self();
+ unsigned entry;
+ unsigned new_size;
+
+ for(entry = 0; entry < this->holder_thread_count; ++entry) {
+ if(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);
+ }
+ }
+ /* If we get this far, this thread hasn't claimed this ticket before.
+ We need to give it a new entry in the list, then return true */
+ for(entry = 0; entry < this->holder_thread_count; ++entry) {
+ if(this->holder_threads[entry].count == 0) {
+ this->holder_threads[entry].holder = own_id;
+ this->holder_threads[entry].count = 1;
+ return 1;
+ }
+ }
+ /* List too small. Realloc to larger size */
+ new_size = this->holder_thread_count * 2;
+ lprintf("Reallocing from %d to %d entries\n", this->holder_thread_count, new_size);
+
+ this->holder_threads = realloc(this->holder_threads, sizeof(*this->holder_threads) * new_size);
+ memset(this->holder_threads + this->holder_thread_count, 0, this->holder_thread_count);
+
+ /* Old size is equivalent to index of first newly allocated entry*/
+ this->holder_threads[this->holder_thread_count].count = 1;
+ this->holder_threads[this->holder_thread_count].holder = own_id;
+ this->holder_thread_count = new_size;
+
+ return 1;
+}
+
static int ticket_acquire_internal(xine_ticket_t *this, int irrevocable, int nonblocking) {
int must_wait = 0;
pthread_mutex_lock(&this->lock);
+ int allowed_to_block = acquire_allowed_to_block(this);
if (this->ticket_revoked && !this->irrevocable_tickets)
must_wait = !nonblocking;
else if (this->atomic_revoke && !pthread_equal(this->atomic_revoker_thread, pthread_self()))
must_wait = 1;
- if (must_wait) {
+ if (must_wait && allowed_to_block) {
if (nonblocking) {
pthread_mutex_unlock(&this->lock);
return 0;
@@ -164,9 +201,25 @@ static void ticket_acquire(xine_ticket_t *this, int irrevocable) {
ticket_acquire_internal(this, irrevocable, 0);
}
+static int release_allowed_to_block(xine_ticket_t *this) {
+ pthread_t own_id = pthread_self();
+ unsigned entry;
+
+ for(entry = 0; entry < this->holder_thread_count; ++entry) {
+ if(this->holder_threads[entry].holder == own_id) {
+ this->holder_threads[entry].count--;
+ return this->holder_threads[entry].count == 0;
+ }
+ }
+ lprintf("BUG! Ticket 0x%p released by a thread that never took it! Allowing code to continue\n", this);
+ _x_assert(0);
+ return 1;
+}
+
static void ticket_release_internal(xine_ticket_t *this, int irrevocable, int nonblocking) {
pthread_mutex_lock(&this->lock);
+ int allowed_to_block = release_allowed_to_block(this);
this->tickets_granted--;
if (irrevocable)
@@ -174,8 +227,10 @@ static void ticket_release_internal(xine_ticket_t *this, int irrevocable, int no
if (this->ticket_revoked && !this->tickets_granted)
pthread_cond_broadcast(&this->revoked);
- if (this->ticket_revoked && !this->irrevocable_tickets && !nonblocking)
- pthread_cond_wait(&this->issued, &this->lock);
+ if (allowed_to_block) {
+ if (this->ticket_revoked && !this->irrevocable_tickets && !nonblocking)
+ pthread_cond_wait(&this->issued, &this->lock);
+ }
pthread_mutex_unlock(&this->lock);
}
@@ -295,6 +350,8 @@ static xine_ticket_t *ticket_init(void) {
port_ticket->lock_port_rewiring = ticket_lock_port_rewiring;
port_ticket->unlock_port_rewiring = ticket_unlock_port_rewiring;
port_ticket->dispose = ticket_dispose;
+ port_ticket->holder_thread_count = XINE_MAX_TICKET_HOLDER_THREADS;
+ port_ticket->holder_threads = calloc(XINE_MAX_TICKET_HOLDER_THREADS,sizeof(*port_ticket->holder_threads));
pthread_mutex_init(&port_ticket->lock, NULL);
pthread_mutex_init(&port_ticket->revoke_lock, NULL);
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
index 8f3e6e71f..e4af27b92 100644
--- a/src/xine-engine/xine_internal.h
+++ b/src/xine-engine/xine_internal.h
@@ -74,6 +74,7 @@ extern "C" {
#define XINE_MAX_EVENT_LISTENERS 50
#define XINE_MAX_EVENT_TYPES 100
+#define XINE_MAX_TICKET_HOLDER_THREADS 64
/* used by plugin loader */
#define XINE_VERSION_CODE XINE_MAJOR_VERSION*10000+XINE_MINOR_VERSION*100+XINE_SUB_VERSION
@@ -185,6 +186,11 @@ struct xine_ticket_s {
int atomic_revoke;
pthread_t atomic_revoker_thread;
pthread_mutex_t port_rewiring_lock;
+ struct {
+ int count;
+ pthread_t holder;
+ } *holder_threads;
+ unsigned holder_thread_count;
#endif
};