From f7ceeba7f05e6f511a70c5737740802685c18585 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Tue, 3 Nov 2009 21:34:50 +0200 Subject: Moved struct declarations & list handling to beginning of the file. Cosmetics. --- src/libspuhdmv/xine_hdmv_decoder.c | 132 ++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 75 deletions(-) diff --git a/src/libspuhdmv/xine_hdmv_decoder.c b/src/libspuhdmv/xine_hdmv_decoder.c index 358cb0b72..96acf0c11 100644 --- a/src/libspuhdmv/xine_hdmv_decoder.c +++ b/src/libspuhdmv/xine_hdmv_decoder.c @@ -47,7 +47,7 @@ #define TRACE(x...) printf(x) /*#define TRACE(x...) */ -#define ERROR(x...) fprintf(stderr, x) +#define ERROR(x...) fprintf(stderr, "spuhdmv: " x) /*#define ERROR(x...) lprintf(x) */ /* @@ -112,6 +112,57 @@ struct composition_object_s { composition_object_t *next; }; +typedef struct composition_descriptor_s composition_descriptor_t; +struct composition_descriptor_s { + uint16_t number; + uint8_t state; +}; + +typedef struct presentation_segment_s presentation_segment_t; +struct presentation_segment_s { + composition_descriptor_t comp_descr; + + uint8_t palette_update_flag; + uint8_t palette_id_ref; + uint8_t object_number; + + composition_object_t *comp_objs; + + //presentation_segment_t *next; + + int64_t pts; +}; + +/* + * list handling + */ + +#define LIST_REPLACE(list, obj) \ + do { \ + uint id = obj->id; \ + \ + /* insert to list */ \ + obj->next = list; \ + list = obj; \ + \ + /* remove old */ \ + while (obj->next && obj->next->id != id) \ + obj = obj->next; \ + if (obj->next) { \ + void *tmp = (void*)obj->next; \ + obj->next = obj->next->next; \ + free(tmp); \ + } \ + } while (0); + +#define LIST_DESTROY(list) \ + while (list) { \ + void *tmp = (void*)list; \ + list = list->next; \ + free (tmp); \ + } + + /* * segment_buffer_t * @@ -443,12 +494,6 @@ static int segbuf_decode_video_descriptor(segment_buffer_t *buf) return buf->error; } -typedef struct composition_descriptor_s composition_descriptor_t; -struct composition_descriptor_s { - uint16_t number; - uint8_t state; -}; - static int segbuf_decode_composition_descriptor(segment_buffer_t *buf, composition_descriptor_t *descr) { descr->number = segbuf_get_u16(buf); @@ -492,7 +537,7 @@ static composition_object_t *segbuf_decode_composition_object(segment_buffer_t * static rle_elem_t *copy_crop_rle(subtitle_object_t *obj, composition_object_t *cobj) { - /* TODO: exec cropping here (w,h sized image from pos x,y) */ + /* TODO: cropping (w,h sized image from pos x,y) */ rle_elem_t *rle = calloc (obj->num_rle, sizeof(rle_elem_t)); memcpy (rle, obj->rle, obj->num_rle * sizeof(rle_elem_t)); @@ -516,57 +561,15 @@ typedef struct spuhdmv_decoder_s { segment_buffer_t *buf; - subtitle_clut_t *cluts; - subtitle_object_t *objects; - window_def_t *windows; + subtitle_clut_t *cluts; + subtitle_object_t *objects; + window_def_t *windows; int overlay_handles[MAX_OBJECTS]; int64_t pts; } spuhdmv_decoder_t; -#define LIST_REPLACE_OLD(type, list, obj) \ - do { \ - /* insert to list */ \ - obj->next = list; \ - list = obj; \ -\ - /* remove old */ \ - type *i = list; \ - while (i->next && i->next->id != obj->id) \ - i = i->next; \ - if (i->next) { \ - void *tmp = (void*)i->next; \ - i->next = i->next->next; \ - free(tmp); \ - } \ - } while (0); - -#define LIST_REPLACE(list, obj) \ - do { \ - uint id = obj->id; \ - \ - /* insert to list */ \ - obj->next = list; \ - list = obj; \ - \ - /* remove old */ \ - while (obj->next && obj->next->id != id) \ - obj = obj->next; \ - if (obj->next) { \ - void *tmp = (void*)obj->next; \ - obj->next = obj->next->next; \ - free(tmp); \ - } \ - } while (0); - -#define LIST_DESTROY(list) \ - while (list) { \ - void *tmp = (void*)list; \ - list = list->next; \ - free (tmp); \ - } - static int decode_palette(spuhdmv_decoder_t *this) { /* decode */ @@ -693,21 +696,6 @@ static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uin return 0; } -typedef struct presentation_segment_s presentation_segment_t; -struct presentation_segment_s { - composition_descriptor_t comp_descr; - - uint8_t palette_update_flag; - uint8_t palette_id_ref; - uint8_t object_number; - - composition_object_t *comp_objs; - - presentation_segment_t *next; - - int64_t pts; -}; - static void show_overlays(spuhdmv_decoder_t *this, presentation_segment_t *pseg) { composition_object_t *cobj = pseg->comp_objs; @@ -809,12 +797,6 @@ static void decode_segment(spuhdmv_decoder_t *this) break; case 0x80: TRACE(" segment: END OF DISPLAY\n"); - { - int64_t pts = xine_get_current_vpts(this->stream) - - this->stream->metronom->get_option(this->stream->metronom, - METRONOM_VPTS_OFFSET); - TRACE(" * current pts = %ld\n", pts); - } break; default: @@ -828,7 +810,7 @@ static void decode_segment(spuhdmv_decoder_t *this) static void close_osd(spuhdmv_decoder_t *this) { - video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); + video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); int i = 0; while (this->overlay_handles[i] >= 0) { -- cgit v1.2.3 From 4345dc27aa5bb6b816759f3d7276baad601ff5bd Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Tue, 3 Nov 2009 21:34:50 +0200 Subject: =?UTF-8?q?Copy=20palette=20only=20if=20all=20objects=20have=20bee?= =?UTF-8?q?n=20found;=20ERROR=E2=86=92TRACE=20in=20show=5Foverlay().?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libspuhdmv/xine_hdmv_decoder.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/libspuhdmv/xine_hdmv_decoder.c b/src/libspuhdmv/xine_hdmv_decoder.c index 96acf0c11..1a6b71523 100644 --- a/src/libspuhdmv/xine_hdmv_decoder.c +++ b/src/libspuhdmv/xine_hdmv_decoder.c @@ -74,9 +74,11 @@ struct subtitle_object_s { uint num_rle; size_t data_size; +#if 0 uint8_t *raw_data; /* partial RLE data in HDMV format */ size_t raw_data_len; size_t raw_data_size; +#endif subtitle_object_t *next; }; @@ -619,21 +621,16 @@ static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uin while (clut && clut->id != palette_id_ref) clut = clut->next; if (!clut) { - ERROR(" fill_overlay: clut %d not found !\n", palette_id_ref); + TRACE(" show_overlay: clut %d not found !\n", palette_id_ref); return -1; } - /* copy palette to xine overlay */ - overlay.rgb_clut = 0; - memcpy(overlay.color, clut->color, sizeof(uint32_t) * 256); - memcpy(overlay.trans, clut->trans, sizeof(uint8_t) * 256); - /* find RLE image */ subtitle_object_t *obj = this->objects; while (obj && obj->id != cobj->object_id_ref) obj = obj->next; if (!obj) { - ERROR(" fill_overlay: object %d not found !\n", cobj->object_id_ref); + TRACE(" show_overlay: object %d not found !\n", cobj->object_id_ref); return -1; } @@ -642,10 +639,15 @@ static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uin while (wnd && wnd->id != cobj->window_id_ref) wnd = wnd->next; if (!wnd) { - ERROR(" fill_overlay: window %d not found !\n", cobj->window_id_ref); + TRACE(" show_overlay: window %d not found !\n", cobj->window_id_ref); return -1; } + /* copy palette to xine overlay */ + overlay.rgb_clut = 0; + memcpy(overlay.color, clut->color, sizeof(uint32_t) * 256); + memcpy(overlay.trans, clut->trans, sizeof(uint8_t) * 256); + /* copy and crop RLE image to xine overlay */ overlay.width = obj->width; overlay.height = obj->height; -- cgit v1.2.3 From a9bcaea82059a72fa899f9ed9a69cabfd3ceacc5 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Tue, 3 Nov 2009 21:37:45 +0200 Subject: Do not update overlay if all elements are unchanged --- src/libspuhdmv/xine_hdmv_decoder.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/libspuhdmv/xine_hdmv_decoder.c b/src/libspuhdmv/xine_hdmv_decoder.c index 1a6b71523..13f56b528 100644 --- a/src/libspuhdmv/xine_hdmv_decoder.c +++ b/src/libspuhdmv/xine_hdmv_decoder.c @@ -59,6 +59,8 @@ struct subtitle_clut_s { uint32_t color[256]; uint8_t trans[256]; subtitle_clut_t *next; + + int shown; }; /* @@ -81,6 +83,8 @@ struct subtitle_object_s { #endif subtitle_object_t *next; + + int shown; }; /* @@ -93,6 +97,8 @@ struct window_def_s { uint16_t width, height; window_def_t *next; + + int shown; }; @@ -112,6 +118,8 @@ struct composition_object_s { uint16_t crop_width, crop_height; composition_object_t *next; + + int shown; }; typedef struct composition_descriptor_s composition_descriptor_t; @@ -133,6 +141,7 @@ struct presentation_segment_s { //presentation_segment_t *next; int64_t pts; + int shown; }; /* @@ -609,7 +618,7 @@ static int decode_window_definition(spuhdmv_decoder_t *this) } static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uint palette_id_ref, - int overlay_index, int64_t pts) + int overlay_index, int64_t pts, int force_update) { video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager(this->stream->video_out); metronom_t *metronom = this->stream->metronom; @@ -643,6 +652,11 @@ static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uin return -1; } + /* do not show again if all elements are unchanged */ + if (!force_update && clut->shown && obj->shown && wnd->shown && cobj->shown) + return 0; + clut->shown = obj->shown = wnd->shown = cobj->shown = 1; + /* copy palette to xine overlay */ overlay.rgb_clut = 0; memcpy(overlay.color, clut->color, sizeof(uint32_t) * 256); @@ -707,10 +721,12 @@ static void show_overlays(spuhdmv_decoder_t *this, presentation_segment_t *pseg) if (!cobj) { ERROR("show_overlays: composition object %d missing !\n", i); } else { - show_overlay(this, cobj, pseg->palette_id_ref, i, pseg->pts); + show_overlay(this, cobj, pseg->palette_id_ref, i, pseg->pts, !pseg->shown); cobj = cobj->next; } } + + pseg->shown = 1; } static void hide_overlays(spuhdmv_decoder_t *this, int64_t pts) -- cgit v1.2.3 From 145602985c83694699c4984a21ad61165e2c8859 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Tue, 3 Nov 2009 21:46:56 +0200 Subject: Fixed memory leaks (RLE data) --- src/libspuhdmv/xine_hdmv_decoder.c | 56 +++++++++++++++++++++++++------------- 1 file 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); } -- cgit v1.2.3 From 9b0a520a6e0d09daefd4916a4298f099907f44f3 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Tue, 3 Nov 2009 22:32:05 +0200 Subject: =?UTF-8?q?show=5Foverlays()=20=E2=86=92=20update=5Foverlays()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libspuhdmv/xine_hdmv_decoder.c | 51 +++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/src/libspuhdmv/xine_hdmv_decoder.c b/src/libspuhdmv/xine_hdmv_decoder.c index 04586d750..8ffd4e3aa 100644 --- a/src/libspuhdmv/xine_hdmv_decoder.c +++ b/src/libspuhdmv/xine_hdmv_decoder.c @@ -726,23 +726,6 @@ static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uin return 0; } -static void show_overlays(spuhdmv_decoder_t *this, presentation_segment_t *pseg) -{ - composition_object_t *cobj = pseg->comp_objs; - int i; - - for (i = 0; i < pseg->object_number; i++) { - if (!cobj) { - ERROR("show_overlays: composition object %d missing !\n", i); - } else { - show_overlay(this, cobj, pseg->palette_id_ref, i, pseg->pts, !pseg->shown); - cobj = cobj->next; - } - } - - pseg->shown = 1; -} - static void hide_overlays(spuhdmv_decoder_t *this, int64_t pts) { video_overlay_event_t event = {0}; @@ -768,6 +751,33 @@ static void hide_overlays(spuhdmv_decoder_t *this, int64_t pts) } } +static void update_overlays(spuhdmv_decoder_t *this, presentation_segment_t *pseg) +{ + if (!pseg->comp_descr.state) { + + /* HIDE */ + if (!pseg->shown) + hide_overlays (this, pseg->pts); + + } else { + + /* SHOW */ + composition_object_t *cobj = pseg->comp_objs; + int i; + + for (i = 0; i < pseg->object_number; i++) { + if (!cobj) { + ERROR("show_overlays: composition object %d missing !\n", i); + } else { + show_overlay(this, cobj, pseg->palette_id_ref, i, pseg->pts, !pseg->shown); + cobj = cobj->next; + } + } + } + + pseg->shown = 1; +} + static int decode_presentation_segment(spuhdmv_decoder_t *this) { presentation_segment_t p = {}; @@ -792,12 +802,7 @@ static int decode_presentation_segment(spuhdmv_decoder_t *this) p.comp_objs = cobj; } - if (!p.comp_descr.state) { - hide_overlays (this, this->pts); - } else { - show_overlays (this, &p); - LIST_DESTROY (p.comp_objs, free); - } + update_overlays (this, &p); return buf->error; } -- cgit v1.2.3 From f7301e347937dfa9fa6879ff9376f1b3a2642e78 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Tue, 3 Nov 2009 22:40:07 +0200 Subject: Fixed timing of subtitles. Splitted decode_presentation_segment() - Store presentation segments in decoder instance data. - Try to update overlays after every decoded object. --- src/libspuhdmv/xine_hdmv_decoder.c | 87 +++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/src/libspuhdmv/xine_hdmv_decoder.c b/src/libspuhdmv/xine_hdmv_decoder.c index 8ffd4e3aa..ba4487bf6 100644 --- a/src/libspuhdmv/xine_hdmv_decoder.c +++ b/src/libspuhdmv/xine_hdmv_decoder.c @@ -138,7 +138,7 @@ struct presentation_segment_s { composition_object_t *comp_objs; - //presentation_segment_t *next; + presentation_segment_t *next; int64_t pts; int shown; @@ -562,6 +562,35 @@ static composition_object_t *segbuf_decode_composition_object(segment_buffer_t * return cobj; } +static presentation_segment_t *segbuf_decode_presentation_segment(segment_buffer_t *buf) +{ + presentation_segment_t *seg = calloc(1, sizeof(presentation_segment_t)); + int index; + + segbuf_decode_video_descriptor (buf); + segbuf_decode_composition_descriptor (buf, &seg->comp_descr); + + seg->palette_update_flag = !!((segbuf_get_u8(buf)) & 0x80); + seg->palette_id_ref = segbuf_get_u8 (buf); + seg->object_number = segbuf_get_u8 (buf); + + TRACE(" presentation_segment: object_number %d, palette %d\n", + seg->object_number, seg->palette_id_ref); + + for (index = 0; index < seg->object_number; index++) { + composition_object_t *cobj = segbuf_decode_composition_object (buf); + cobj->next = seg->comp_objs; + seg->comp_objs = cobj; + } + + if (buf->error) { + free_presentation_segment(seg); + return NULL; + } + + return seg; +} + static rle_elem_t *copy_crop_rle(subtitle_object_t *obj, composition_object_t *cobj) { /* TODO: cropping (w,h sized image from pos x,y) */ @@ -591,6 +620,8 @@ typedef struct spuhdmv_decoder_s { subtitle_clut_t *cluts; subtitle_object_t *objects; window_def_t *windows; + presentation_segment_t *segments; + int overlay_handles[MAX_OBJECTS]; int64_t pts; @@ -633,6 +664,23 @@ static int decode_window_definition(spuhdmv_decoder_t *this) return 0; } +static int decode_presentation_segment(spuhdmv_decoder_t *this) +{ + /* decode */ + presentation_segment_t *seg = segbuf_decode_presentation_segment(this->buf); + if (!seg) + return 1; + + seg->pts = this->pts; + + /* replace */ + if (this->segments) + LIST_DESTROY(this->segments, free_presentation_segment); + this->segments = seg; + + return 0; +} + static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uint palette_id_ref, int overlay_index, int64_t pts, int force_update) { @@ -751,8 +799,12 @@ static void hide_overlays(spuhdmv_decoder_t *this, int64_t pts) } } -static void update_overlays(spuhdmv_decoder_t *this, presentation_segment_t *pseg) +static void update_overlays(spuhdmv_decoder_t *this) { + presentation_segment_t *pseg = this->segments; + + while (pseg) { + if (!pseg->comp_descr.state) { /* HIDE */ @@ -776,35 +828,9 @@ static void update_overlays(spuhdmv_decoder_t *this, presentation_segment_t *pse } pseg->shown = 1; -} - -static int decode_presentation_segment(spuhdmv_decoder_t *this) -{ - presentation_segment_t p = {}; - segment_buffer_t *buf = this->buf; - int index; - - segbuf_decode_video_descriptor (this->buf); - segbuf_decode_composition_descriptor (this->buf, &p.comp_descr); - - p.palette_update_flag = !!((segbuf_get_u8(buf)) & 0x80); - p.palette_id_ref = segbuf_get_u8 (buf); - p.object_number = segbuf_get_u8 (buf); - - TRACE(" presentation_segment: object_number %d, palette %d\n", - p.object_number, p.palette_id_ref); - p.pts = this->pts; /* !! todo - use it ? */ - - for (index = 0; index < p.object_number; index++) { - composition_object_t *cobj = segbuf_decode_composition_object (this->buf); - cobj->next = p.comp_objs; - p.comp_objs = cobj; + pseg = pseg->next; } - - update_overlays (this, &p); - - return buf->error; } static void free_objs(spuhdmv_decoder_t *this) @@ -812,6 +838,7 @@ 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); + LIST_DESTROY (this->segments, free_presentation_segment); } static void decode_segment(spuhdmv_decoder_t *this) @@ -851,6 +878,8 @@ static void decode_segment(spuhdmv_decoder_t *this) if (this->buf->error) { ERROR("*** DECODE ERROR ***\n"); } + + update_overlays (this); } static void close_osd(spuhdmv_decoder_t *this) -- cgit v1.2.3