diff options
| author | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2007-07-13 21:47:37 +0100 |
|---|---|---|
| committer | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2007-07-13 21:47:37 +0100 |
| commit | af9e42132f6dcc13866892eb47367940ef04c6f9 (patch) | |
| tree | 8a9e5da2417658c1d7da84ddb9102cc5f8c30492 /src/xine-engine | |
| parent | f158a50df518175dbba6a665a52b2ffa472237ae (diff) | |
| parent | b417806ce02dcc44352610e6898f6287677b13e1 (diff) | |
| download | xine-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.c | 20 | ||||
| -rw-r--r-- | src/xine-engine/video_overlay.c | 8 | ||||
| -rw-r--r-- | src/xine-engine/xine.c | 63 | ||||
| -rw-r--r-- | src/xine-engine/xine_internal.h | 6 |
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 }; |
