diff options
author | Simon Farnsworth <simon.farnsworth@onelan.co.uk> | 2007-07-12 11:28:43 +0100 |
---|---|---|
committer | Simon Farnsworth <simon.farnsworth@onelan.co.uk> | 2007-07-12 11:28:43 +0100 |
commit | 198fa979f89ba74743a301816d38b46a73770856 (patch) | |
tree | 69d6b6c654a4e84ad1af08bc9a1ed343e7313d81 | |
parent | 33d32c6238d0d5d9ae00a2fee6bba2c987ff0f21 (diff) | |
download | xine-lib-198fa979f89ba74743a301816d38b46a73770856.tar.gz xine-lib-198fa979f89ba74743a301816d38b46a73770856.tar.bz2 |
Remove realloc from osd.c to prevent memory leak due to fragmentation
show() in osd.c uses realloc in an effort to minimise the amount of
memory actually used for rle objects. In practice, this caused xine to
fragment memory, and gradually use more and more RAM (measured over a
period of 24 to 72 hours).
Change osd.c to allocate the maximum amount of memory it could need;
because it touches this memory in a linear fashion, lazy page allocation
will ensure that most of the memory used is needed. Further, because
this makes the per-drawing allocations the same size, it avoids virtual
address space fragmentation.
-rw-r--r-- | src/xine-engine/osd.c | 20 |
1 files changed, 5 insertions, 15 deletions
diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c index c4709c8ab..ebc12300b 100644 --- a/src/xine-engine/osd.c +++ b/src/xine-engine/osd.c @@ -197,7 +197,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); @@ -251,11 +251,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) ); @@ -272,14 +272,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 @@ -297,8 +289,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); |