diff options
author | Petri Hintukainen <phintuka@users.sourceforge.net> | 2009-11-03 22:40:07 +0200 |
---|---|---|
committer | Petri Hintukainen <phintuka@users.sourceforge.net> | 2009-11-03 22:40:07 +0200 |
commit | f7301e347937dfa9fa6879ff9376f1b3a2642e78 (patch) | |
tree | 677a3da21f0f4e5b31a9a87facdb8f070578993b | |
parent | 9b0a520a6e0d09daefd4916a4298f099907f44f3 (diff) | |
download | xine-lib-f7301e347937dfa9fa6879ff9376f1b3a2642e78.tar.gz xine-lib-f7301e347937dfa9fa6879ff9376f1b3a2642e78.tar.bz2 |
Fixed timing of subtitles.
Splitted decode_presentation_segment()
- Store presentation segments in decoder instance data.
- Try to update overlays after every decoded object.
-rw-r--r-- | src/libspuhdmv/xine_hdmv_decoder.c | 87 |
1 files 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) |