diff options
author | Petri Hintukainen <phintuka@users.sourceforge.net> | 2009-11-03 21:46:56 +0200 |
---|---|---|
committer | Petri Hintukainen <phintuka@users.sourceforge.net> | 2009-11-03 21:46:56 +0200 |
commit | 145602985c83694699c4984a21ad61165e2c8859 (patch) | |
tree | e0c512269cd97c0ade3c084e0975d1755951470d | |
parent | a9bcaea82059a72fa899f9ed9a69cabfd3ceacc5 (diff) | |
download | xine-lib-145602985c83694699c4984a21ad61165e2c8859.tar.gz xine-lib-145602985c83694699c4984a21ad61165e2c8859.tar.bz2 |
Fixed memory leaks (RLE data)
-rw-r--r-- | src/libspuhdmv/xine_hdmv_decoder.c | 56 |
1 files changed, 37 insertions, 19 deletions
diff --git a/src/libspuhdmv/xine_hdmv_decoder.c b/src/libspuhdmv/xine_hdmv_decoder.c index 13f56b528..04586d750 100644 --- a/src/libspuhdmv/xine_hdmv_decoder.c +++ b/src/libspuhdmv/xine_hdmv_decoder.c @@ -148,7 +148,7 @@ struct presentation_segment_s { * list handling */ -#define LIST_REPLACE(list, obj) \ +#define LIST_REPLACE(list, obj, FREE_FUNC) \ do { \ uint id = obj->id; \ \ @@ -162,17 +162,33 @@ struct presentation_segment_s { if (obj->next) { \ void *tmp = (void*)obj->next; \ obj->next = obj->next->next; \ - free(tmp); \ + FREE_FUNC(tmp); \ } \ } while (0); -#define LIST_DESTROY(list) \ +#define LIST_DESTROY(list, FREE_FUNC) \ while (list) { \ void *tmp = (void*)list; \ list = list->next; \ - free (tmp); \ + FREE_FUNC(tmp); \ } +static void free_subtitle_object(void *ptr) +{ + if (ptr) { + free(((subtitle_object_t*)ptr)->rle); + free(ptr); + } +} +static void free_presentation_segment(void *ptr) +{ + if (ptr) { + presentation_segment_t *seg = (presentation_segment_t*)ptr; + LIST_DESTROY(seg->comp_objs, free); + free(ptr); + } +} + /* * segment_buffer_t @@ -459,14 +475,14 @@ static subtitle_object_t *segbuf_decode_object(segment_buffer_t *buf) segbuf_decode_rle (buf, obj); if (buf->error) { - free(obj); + free_subtitle_object(obj); return NULL; } } else { ERROR(" TODO: APPEND RLE, length %d bytes\n", buf->segment_len - 4); /* TODO */ - free(obj); + free_subtitle_object(obj); return NULL; } @@ -588,7 +604,7 @@ static int decode_palette(spuhdmv_decoder_t *this) if (!clut) return 1; - LIST_REPLACE (this->cluts, clut); + LIST_REPLACE (this->cluts, clut, free); return 0; } @@ -600,7 +616,7 @@ static int decode_object(spuhdmv_decoder_t *this) if (!obj) return 1; - LIST_REPLACE (this->objects, obj); + LIST_REPLACE (this->objects, obj, free_subtitle_object); return 0; } @@ -612,7 +628,7 @@ static int decode_window_definition(spuhdmv_decoder_t *this) if (!wnd) return 1; - LIST_REPLACE (this->windows, wnd); + LIST_REPLACE (this->windows, wnd, free); return 0; } @@ -707,8 +723,6 @@ static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uin ovl_manager->add_event (ovl_manager, (void *)&event); - obj->rle = NULL; - return 0; } @@ -782,12 +796,19 @@ static int decode_presentation_segment(spuhdmv_decoder_t *this) hide_overlays (this, this->pts); } else { show_overlays (this, &p); - LIST_DESTROY (p.comp_objs); + LIST_DESTROY (p.comp_objs, free); } return buf->error; } +static void free_objs(spuhdmv_decoder_t *this) +{ + LIST_DESTROY (this->cluts, free); + LIST_DESTROY (this->objects, free_subtitle_object); + LIST_DESTROY (this->windows, free); +} + static void decode_segment(spuhdmv_decoder_t *this) { TRACE("*** new segment, pts %010ld: 0x%02x (%8d bytes)", @@ -815,7 +836,8 @@ static void decode_segment(spuhdmv_decoder_t *this) break; case 0x80: TRACE(" segment: END OF DISPLAY\n"); - + /* drop all cached objects */ + free_objs(this); break; default: ERROR(" segment type 0x%x unknown, skipping\n", this->buf->segment_type); @@ -873,9 +895,7 @@ static void spudec_reset (spu_decoder_t * this_gen) if (this->buf) segbuf_reset(this->buf); - LIST_DESTROY (this->cluts); - LIST_DESTROY (this->objects); - LIST_DESTROY (this->windows); + free_objs(this); close_osd(this); } @@ -894,9 +914,7 @@ static void spudec_dispose (spu_decoder_t *this_gen) close_osd (this); segbuf_dispose (this->buf); - LIST_DESTROY (this->cluts); - LIST_DESTROY (this->objects); - LIST_DESTROY (this->windows); + free_objs(this); free (this); } |