summaryrefslogtreecommitdiff
path: root/xine/BluRay/decode_spuhdmv.c
diff options
context:
space:
mode:
authorcvs2svn <admin@example.com>2009-10-21 00:02:02 +0000
committercvs2svn <admin@example.com>2009-10-21 00:02:02 +0000
commit97a97ca3358eb48de3eb7a222e487e800566569f (patch)
tree97c920d0225a1c9773a3bce2207f261d7d230123 /xine/BluRay/decode_spuhdmv.c
parenta61961358c5a2ec92340b3f8e056bab55438f103 (diff)
downloadxineliboutput-CVS.tar.gz
xineliboutput-CVS.tar.bz2
This commit was manufactured by cvs2svn to create branch 'CVS'.CVS
Diffstat (limited to 'xine/BluRay/decode_spuhdmv.c')
-rw-r--r--xine/BluRay/decode_spuhdmv.c1027
1 files changed, 0 insertions, 1027 deletions
diff --git a/xine/BluRay/decode_spuhdmv.c b/xine/BluRay/decode_spuhdmv.c
deleted file mode 100644
index 81ac6778..00000000
--- a/xine/BluRay/decode_spuhdmv.c
+++ /dev/null
@@ -1,1027 +0,0 @@
-/*
- * Copyright (C) 2000-2009 the xine project
- *
- * Copyright (C) 2009 Petri Hintukainen <phintuka@users.sourceforge.net>
- *
- * This file is part of xine, a unix video player.
- *
- * xine is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * xine is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * Decoder for HDMV/BluRay bitmap subtitles
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#ifdef HAVE_CONFIG_H
-# include "xine_internal.h"
-# include "buffer.h"
-# include "xineutils.h"
-# include "video_out.h"
-# include "video_overlay.h"
-#else
-# include <xine/xine_internal.h>
-# include <xine/buffer.h>
-# include <xine/xineutils.h>
-# include <xine/video_out.h>
-# include <xine/video_overlay.h>
-#endif
-
-#define TRACE(x...) printf(x)
-/*#define TRACE(x...) */
-#define ERROR(x...) fprintf(stderr, "spuhdmv: " x)
-/*#define ERROR(x...) lprintf(x) */
-
-#ifndef EXPORTED
-# define EXPORTED __attribute__((visibility("default")))
-#endif
-
-#ifndef BUF_SPU_HDMV
-# define BUF_SPU_HDMV 0x04180000
-#endif
-
-/*
- * cached palette (xine-lib format)
- */
-typedef struct subtitle_clut_s subtitle_clut_t;
-struct subtitle_clut_s {
- uint8_t id;
- uint32_t color[256];
- uint8_t trans[256];
- subtitle_clut_t *next;
-
- int shown;
-};
-
-/*
- * cached RLE image (xine-lib format)
- */
-typedef struct subtitle_object_s subtitle_object_t;
-struct subtitle_object_s {
- uint16_t id;
- uint16_t xpos, ypos;
- uint16_t width, height;
-
- rle_elem_t *rle;
- 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;
-
- int shown;
-};
-
-/*
- * Window definition
- */
-typedef struct window_def_s window_def_t;
-struct window_def_s {
- uint8_t id;
- uint16_t xpos, ypos;
- uint16_t width, height;
-
- window_def_t *next;
-
- int shown;
-};
-
-
-/*
- * decoded SPU
- */
-typedef struct composition_object_s composition_object_t;
-struct composition_object_s {
- uint8_t window_id_ref;
- uint8_t object_id_ref;
-
- uint16_t xpos, ypos;
-
- uint8_t forced_flag;
- uint8_t cropped_flag;
- uint16_t crop_horiz_pos, crop_vert_pos;
- uint16_t crop_width, crop_height;
-
- composition_object_t *next;
-
- int shown;
-};
-
-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;
- int shown;
-};
-
-/*
- * list handling
- */
-
-#define LIST_REPLACE(list, obj, FREE_FUNC) \
- 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_FUNC(tmp); \
- } \
- } while (0);
-
-#define LIST_DESTROY(list, FREE_FUNC) \
- while (list) { \
- void *tmp = (void*)list; \
- list = list->next; \
- 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
- *
- * assemble and decode segments
- */
-
-typedef struct {
- /* current segment */
- int segment_len; /* length of current segment (without 3-byte header) */
- uint8_t segment_type; /* current segment type */
- uint8_t *segment_data; /* pointer to current segment payload */
- uint8_t *segment_end; /* pointer to last byte + 1 of current segment */
- uint8_t error; /* boolean: buffer overflow etc. */
-
- /* accumulated data */
- uint8_t *buf; /* */
- size_t len; /* count of unprocessed bytes */
- size_t data_size; /* allocated buffer size */
-} segment_buffer_t;
-
-/*
- * mgmt
- */
-
-static segment_buffer_t *segbuf_init(void)
-{
- segment_buffer_t *buf = calloc(1, sizeof(segment_buffer_t));
- return buf;
-}
-
-static void segbuf_dispose(segment_buffer_t *buf)
-{
- if (buf->buf)
- free (buf->buf);
- free (buf);
-}
-
-static void segbuf_reset(segment_buffer_t *buf)
-{
- buf->segment_end = buf->segment_data = buf->buf;
- buf->len = 0;
- buf->segment_len = -1;
- buf->segment_type = 0;
- buf->error = 0;
-}
-
-/*
- * assemble, parse
- */
-
-static void segbuf_parse_segment_header(segment_buffer_t *buf)
-{
- if (buf->len > 2) {
- buf->segment_type = buf->buf[0];
- buf->segment_len = (buf->buf[1] << 8) | buf->buf[2];
- buf->segment_data = buf->buf + 3;
- buf->segment_end = buf->segment_data + buf->segment_len;
- buf->error = 0;
-
- if ( buf->segment_type < 0x14 ||
- ( buf->segment_type > 0x18 &&
- buf->segment_type != 0x80)) {
- ERROR("unknown segment type, resetting\n");
- segbuf_reset(buf);
- }
- } else {
- buf->segment_len = -1;
- buf->error = 1;
- }
-}
-
-static void segbuf_fill(segment_buffer_t *buf, uint8_t *data, size_t len)
-{
- if (buf->len + len > buf->data_size) {
- buf->data_size = buf->len + len;
- if (buf->buf)
- buf->buf = realloc(buf->buf, buf->data_size);
- else
- buf->buf = malloc(buf->data_size);
- }
-
- memcpy(buf->buf + buf->len, data, len);
- buf->len += len;
-
- segbuf_parse_segment_header(buf);
-}
-
-static int segbuf_segment_complete(segment_buffer_t *buf)
-{
- return (buf->segment_len >= 0) && (buf->len >= buf->segment_len + 3);
-}
-
-static void segbuf_skip_segment(segment_buffer_t *buf)
-{
- if (segbuf_segment_complete (buf)) {
- buf->len -= buf->segment_len + 3;
- if (buf->len > 0)
- memmove(buf->buf, buf->buf + buf->segment_len + 3, buf->len);
-
- segbuf_parse_segment_header(buf);
-
- TRACE(" skip_segment: %d bytes left\n", (uint)buf->len);
- } else {
- ERROR(" skip_segment: ERROR - %d bytes queued, %d required\n",
- (uint)buf->len, buf->segment_len);
- segbuf_reset (buf);
- }
-}
-
-/*
- * access segment data
- */
-
-uint8_t segbuf_segment_type(segment_buffer_t *buf)
-{
- return buf->segment_type;
-}
-
-static size_t segbuf_data_length(segment_buffer_t *buf)
-{
- ssize_t val = buf->segment_end - buf->segment_data;
- if (val < 0) val = 0;
- return (size_t)val;
-}
-
-static uint8_t segbuf_get_u8(segment_buffer_t *buf)
-{
- if (!(buf->error = ++buf->segment_data > buf->segment_end))
- return buf->segment_data[-1];
- ERROR("segbuf_get_u8: read failed (end of segment reached) !");
- return 0;
-}
-
-static uint16_t segbuf_get_u16(segment_buffer_t *buf)
-{
- return (segbuf_get_u8(buf) << 8) | segbuf_get_u8(buf);
-}
-
-static uint32_t segbuf_get_u24(segment_buffer_t *buf)
-{
- return (segbuf_get_u8(buf) << 16) | (segbuf_get_u8(buf) << 8) | segbuf_get_u8(buf);
-}
-
-uint8_t *segbuf_get_string(segment_buffer_t *buf, size_t len)
-{
- if (len > 0) {
- uint8_t *val = buf->segment_data;
- buf->segment_data += len;
- if (buf->segment_data <= buf->segment_end)
- return val;
- }
- ERROR("segbuf_get_string(%d): read failed (end of segment reached) !", (int)len);
- buf->error = 1;
- return NULL;
-}
-
-/*
- * decode segments
- */
-
-static subtitle_clut_t *segbuf_decode_palette(segment_buffer_t *buf)
-{
- uint8_t palette_id = segbuf_get_u8 (buf);
- uint8_t palette_version_number = segbuf_get_u8 (buf);
-
- size_t len = segbuf_data_length(buf);
- size_t entries = len / 5;
- int i;
-
- if (buf->error)
- return NULL;
-
- if (len % 5) {
- ERROR(" decode_palette: segment size error (%d ; expected %d for %d entries)\n",
- (uint)len, (uint)(5 * entries), (uint)entries);
- return NULL;
- }
- TRACE("decode_palette: %d items (id %d, version %d)\n",
- (uint)entries, palette_id, palette_version_number);
-
- /* convert to xine-lib clut */
- subtitle_clut_t *clut = calloc(1, sizeof(subtitle_clut_t));
- clut->id = palette_id;
-
- for (i = 0; i < entries; i++) {
- uint8_t index = segbuf_get_u8 (buf);
- uint8_t Y = segbuf_get_u8 (buf);
- uint8_t Cr = segbuf_get_u8 (buf);
- uint8_t Cb = segbuf_get_u8 (buf);
- uint8_t alpha = segbuf_get_u8 (buf);
- clut->color[index] = (Y << 16) | (Cr << 8) | Cb;
- clut->trans[index] = alpha >> 4;
- }
-
- return clut;
-}
-
-static int segbuf_decode_rle(segment_buffer_t *buf, subtitle_object_t *obj)
-{
- int x = 0, y = 0;
- int rle_size = sizeof(rle_elem_t) * obj->width / 16 * obj->height + 1;
- rle_elem_t *rlep = malloc(rle_size);
-
- free (obj->rle);
- obj->rle = rlep;
- obj->data_size = rle_size;
- obj->num_rle = 0;
-
- /* convert to xine-lib rle format */
- while (y < obj->height && !buf->error) {
-
- /* decode RLE element */
- uint8_t byte = segbuf_get_u8 (buf);
- if (byte != 0) {
- rlep->color = byte;
- rlep->len = 1;
- } else {
- byte = segbuf_get_u8 (buf);
- if (!(byte & 0x80)) {
- rlep->color = 0;
- if (!(byte & 0x40))
- rlep->len = byte & 0x3f;
- else
- rlep->len = ((byte & 0x3f) << 8) | segbuf_get_u8 (buf);
- } else {
- if (!(byte & 0x40))
- rlep->len = byte & 0x3f;
- else
- rlep->len = ((byte & 0x3f) << 8) | segbuf_get_u8 (buf);
- rlep->color = segbuf_get_u8 (buf);
- }
- }
-
- /* move to next element */
- if (rlep->len > 0) {
- x += rlep->len;
- rlep++;
- obj->num_rle ++;
- } else {
- /* end of line marker (00 00) */
- if (x < obj->width) {
- rlep->len = obj->width - x;
- rlep->color = 0xff;
- rlep++;
- obj->num_rle ++;
- }
- x = 0;
- y++;
- }
-
- /* grow allocated RLE data size ? */
- if (obj->data_size <= (obj->num_rle + 1) * sizeof(rle_elem_t)) {
- obj->data_size *= 2;
- obj->rle = realloc(obj->rle, obj->data_size);
- rlep = obj->rle + obj->num_rle;
- }
- }
-
- return buf->error;
-}
-
-static subtitle_object_t *segbuf_decode_object(segment_buffer_t *buf)
-{
- uint8_t object_id = segbuf_get_u16(buf);
- uint8_t version = segbuf_get_u8 (buf);
- uint8_t seq_desc = segbuf_get_u8 (buf);
-
- TRACE(" decode_object: object_id %d, version %d, seq 0x%x\n",
- object_id, version, seq_desc);
-
- //LIST_FIND();
- subtitle_object_t *obj = calloc(1, sizeof(subtitle_object_t));
- obj->id = object_id;
-
- if (seq_desc & 0x80) {
-
- uint32_t data_len = segbuf_get_u24(buf);
- obj->width = segbuf_get_u16(buf);
- obj->height = segbuf_get_u16(buf);
-
- TRACE(" object length %d bytes, size %dx%d\n", data_len, obj->width, obj->height);
-
- segbuf_decode_rle (buf, obj);
-
- if (buf->error) {
- free_subtitle_object(obj);
- return NULL;
- }
-
- } else {
- ERROR(" TODO: APPEND RLE, length %d bytes\n", buf->segment_len - 4);
- /* TODO */
- free_subtitle_object(obj);
- return NULL;
- }
-
- return obj;
-}
-
-static window_def_t *segbuf_decode_window_definition(segment_buffer_t *buf)
-{
- window_def_t *wnd = calloc(1, sizeof(window_def_t));
-
- uint8_t a = segbuf_get_u8 (buf);
- wnd->id = segbuf_get_u8 (buf);
- wnd->xpos = segbuf_get_u16 (buf);
- wnd->ypos = segbuf_get_u16 (buf);
- wnd->width = segbuf_get_u16 (buf);
- wnd->height = segbuf_get_u16 (buf);
-
- TRACE(" window: [%02x %d] %d,%d %dx%d\n", a,
- wnd->id, wnd->xpos, wnd->ypos, wnd->width, wnd->height);
-
- if (buf->error) {
- free(wnd);
- return NULL;
- }
-
- return wnd;
-}
-
-static int segbuf_decode_video_descriptor(segment_buffer_t *buf)
-{
- uint16_t width = segbuf_get_u16(buf);
- uint16_t height = segbuf_get_u16(buf);
- uint8_t frame_rate = segbuf_get_u8 (buf);
-
- TRACE(" video_descriptor: %dx%d fps %d\n", width, height, frame_rate);
- return buf->error;
-}
-
-static int segbuf_decode_composition_descriptor(segment_buffer_t *buf, composition_descriptor_t *descr)
-{
- descr->number = segbuf_get_u16(buf);
- descr->state = segbuf_get_u8 (buf);
-
- TRACE(" composition_descriptor: number %d, state %d\n", descr->number, descr->state);
- return buf->error;
-}
-
-static composition_object_t *segbuf_decode_composition_object(segment_buffer_t *buf)
-{
- composition_object_t *cobj = calloc(1, sizeof(composition_object_t));
-
- cobj->object_id_ref = segbuf_get_u16 (buf);
- cobj->window_id_ref = segbuf_get_u8 (buf);
- uint8_t tmp = segbuf_get_u8 (buf);
- cobj->cropped_flag = !!(tmp & 0x80);
- cobj->forced_flag = !!(tmp & 0x40);
- cobj->xpos = segbuf_get_u16 (buf);
- cobj->ypos = segbuf_get_u16 (buf);
- if (cobj->cropped_flag) {
- /* x,y where to take the image from */
- cobj->crop_horiz_pos = segbuf_get_u8 (buf);
- cobj->crop_vert_pos = segbuf_get_u8 (buf);
- /* size of the cropped image */
- cobj->crop_width = segbuf_get_u8 (buf);
- cobj->crop_height = segbuf_get_u8 (buf);
- }
-
- if (buf->error) {
- free(cobj);
- return NULL;
- }
-
- TRACE(" composition_object: id: %d, win: %d, position %d,%d crop %d forced %d\n",
- cobj->object_id_ref, cobj->window_id_ref, cobj->xpos, cobj->ypos,
- cobj->cropped_flag, cobj->forced_flag);
-
- 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) */
-
- rle_elem_t *rle = calloc (obj->num_rle, sizeof(rle_elem_t));
- memcpy (rle, obj->rle, obj->num_rle * sizeof(rle_elem_t));
- return rle;
-}
-
-
-/*
- * xine plugin
- */
-
-typedef struct {
- spu_decoder_class_t decoder_class;
-} spuhdmv_class_t;
-
-typedef struct spuhdmv_decoder_s {
- spu_decoder_t spu_decoder;
-
- spuhdmv_class_t *class;
- xine_stream_t *stream;
-
- segment_buffer_t *buf;
-
- subtitle_clut_t *cluts;
- subtitle_object_t *objects;
- window_def_t *windows;
- presentation_segment_t *segments;
-
- int overlay_handles[MAX_OBJECTS];
-
- int64_t pts;
-
-} spuhdmv_decoder_t;
-
-static int decode_palette(spuhdmv_decoder_t *this)
-{
- /* decode */
- subtitle_clut_t *clut = segbuf_decode_palette(this->buf);
- if (!clut)
- return 1;
-
- LIST_REPLACE (this->cluts, clut, free);
-
- return 0;
-}
-
-static int decode_object(spuhdmv_decoder_t *this)
-{
- /* decode */
- subtitle_object_t *obj = segbuf_decode_object(this->buf);
- if (!obj)
- return 1;
-
- LIST_REPLACE (this->objects, obj, free_subtitle_object);
-
- return 0;
-}
-
-static int decode_window_definition(spuhdmv_decoder_t *this)
-{
- /* decode */
- window_def_t *wnd = segbuf_decode_window_definition (this->buf);
- if (!wnd)
- return 1;
-
- LIST_REPLACE (this->windows, wnd, free);
-
- 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)
-{
- video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager(this->stream->video_out);
- metronom_t *metronom = this->stream->metronom;
- video_overlay_event_t event = {0};
- vo_overlay_t overlay = {0};
-
- /* find palette */
- subtitle_clut_t *clut = this->cluts;
- while (clut && clut->id != palette_id_ref)
- clut = clut->next;
- if (!clut) {
- TRACE(" show_overlay: clut %d not found !\n", palette_id_ref);
- return -1;
- }
-
- /* find RLE image */
- subtitle_object_t *obj = this->objects;
- while (obj && obj->id != cobj->object_id_ref)
- obj = obj->next;
- if (!obj) {
- TRACE(" show_overlay: object %d not found !\n", cobj->object_id_ref);
- return -1;
- }
-
- /* find window */
- window_def_t *wnd = this->windows;
- while (wnd && wnd->id != cobj->window_id_ref)
- wnd = wnd->next;
- if (!wnd) {
- TRACE(" show_overlay: window %d not found !\n", cobj->window_id_ref);
- 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);
- 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;
-
- overlay.rle = copy_crop_rle (obj, cobj);
- overlay.num_rle = obj->num_rle;
- overlay.data_size = obj->num_rle * sizeof(rle_elem_t);
-
- /* */
-
- overlay.x = /*wnd->xpos +*/ cobj->xpos;
- overlay.y = /*wnd->ypos +*/ cobj->ypos;
-
- overlay.unscaled = 0;
- overlay.hili_top = -1;
- overlay.hili_bottom = -1;
- overlay.hili_left = -1;
- overlay.hili_right = -1;
-
- TRACE(" -> overlay: %d,%d %dx%d\n",
- overlay.x, overlay.y, overlay.width, overlay.height);
-
-
- /* set timings */
-
- if (pts > 0)
- event.vpts = metronom->got_spu_packet (metronom, pts);
- else
- event.vpts = 0;
-
-
- /* generate SHOW event */
-
- this->stream->video_out->enable_ovl(this->stream->video_out, 1);
-
- if (this->overlay_handles[overlay_index] < 0)
- this->overlay_handles[overlay_index] = ovl_manager->get_handle(ovl_manager, 0);
-
- event.event_type = OVERLAY_EVENT_SHOW;
- event.object.handle = this->overlay_handles[overlay_index];
- event.object.overlay = &overlay;
- event.object.object_type = 0; /* subtitle */
-
- ovl_manager->add_event (ovl_manager, (void *)&event);
-
- return 0;
-}
-
-static void hide_overlays(spuhdmv_decoder_t *this, int64_t pts)
-{
- video_overlay_event_t event = {0};
- int i = 0;
-
- while (this->overlay_handles[i] >= 0) {
- TRACE(" -> HIDE %d\n", i);
-
- video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager(this->stream->video_out);
- metronom_t *metronom = this->stream->metronom;
-
- event.object.handle = this->overlay_handles[i];
- if (this)
- event.vpts = metronom->got_spu_packet (metronom, pts);
- else
- event.vpts = 0;
- event.event_type = OVERLAY_EVENT_HIDE;
- event.object.overlay = NULL;
- ovl_manager->add_event (ovl_manager, (void *)&event);
-
- //this->overlay_handles[i] = -1;
- i++;
- }
-}
-
-static void update_overlays(spuhdmv_decoder_t *this)
-{
- presentation_segment_t *pseg = this->segments;
-
- while (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;
-
- pseg = pseg->next;
- }
-}
-
-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)
-{
- TRACE("*** new segment, pts %010ld: 0x%02x (%8d bytes)",
- this->pts, (uint)this->buf->segment_type, (uint)this->buf->segment_len);
-
- switch (this->buf->segment_type) {
- case 0x14:
- TRACE(" segment: PALETTE\n");
- decode_palette(this);
- break;
- case 0x15:
- TRACE(" segment: OBJECT\n");
- decode_object(this);
- break;
- case 0x16:
- TRACE(" segment: PRESENTATION SEGMENT\n");
- decode_presentation_segment(this);
- break;
- case 0x17:
- TRACE(" segment: WINDOW DEFINITION\n");
- decode_window_definition(this);
- break;
- case 0x18:
- TRACE(" segment: INTERACTIVE\n");
- 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);
- break;
- }
- if (this->buf->error) {
- ERROR("*** DECODE ERROR ***\n");
- }
-
- update_overlays (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);
-
- int i = 0;
- while (this->overlay_handles[i] >= 0) {
- ovl_manager->free_handle(ovl_manager, this->overlay_handles[i]);
- this->overlay_handles[i] = -1;
- i++;
- }
-}
-
-static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf)
-{
- spuhdmv_decoder_t *this = (spuhdmv_decoder_t *) this_gen;
-
- if ((buf->type & 0xffff0000) != BUF_SPU_HDMV)
- return;
-
- if (buf->size < 1)
- return;
-
- if (buf->pts)
- this->pts = buf->pts;
-
-#ifdef DUMP_SPU_DATA
- int i;
- for(i = 0; i < buf->size; i++)
- printf(" %02x", buf->content[i]);
- printf("\n");
-#endif
-
- segbuf_fill(this->buf, buf->content, buf->size);
-
- while (segbuf_segment_complete(this->buf)) {
- decode_segment(this);
- segbuf_skip_segment(this->buf);
- }
-}
-
-static void spudec_reset (spu_decoder_t * this_gen)
-{
- spuhdmv_decoder_t *this = (spuhdmv_decoder_t *) this_gen;
-
- if (this->buf)
- segbuf_reset(this->buf);
-
- free_objs(this);
-
- close_osd(this);
-}
-
-static void spudec_discontinuity (spu_decoder_t *this_gen)
-{
- spuhdmv_decoder_t *this = (spuhdmv_decoder_t *) this_gen;
-
- close_osd(this);
-}
-
-static void spudec_dispose (spu_decoder_t *this_gen)
-{
- spuhdmv_decoder_t *this = (spuhdmv_decoder_t *) this_gen;
-
- close_osd (this);
- segbuf_dispose (this->buf);
-
- free_objs(this);
-
- free (this);
-}
-
-static spu_decoder_t *open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream)
-{
- spuhdmv_decoder_t *this;
-
- this = (spuhdmv_decoder_t *) calloc(1, sizeof (spuhdmv_decoder_t));
-
- this->spu_decoder.decode_data = spudec_decode_data;
- this->spu_decoder.reset = spudec_reset;
- this->spu_decoder.discontinuity = spudec_discontinuity;
- this->spu_decoder.dispose = spudec_dispose;
- this->spu_decoder.get_interact_info = NULL;
- this->spu_decoder.set_button = NULL;
- this->stream = stream;
- this->class = (spuhdmv_class_t *) class_gen;
-
- this->buf = segbuf_init();
-
- memset(this->overlay_handles, 0xff, sizeof(this->overlay_handles)); /* --> -1 */
-
- return &this->spu_decoder;
-}
-
-static char *get_identifier (spu_decoder_class_t *this)
-{
- return "spuhdmv";
-}
-
-static char *get_description (spu_decoder_class_t *this)
-{
- return "HDMV/BluRay bitmap SPU decoder plugin";
-}
-
-static void dispose_class (spu_decoder_class_t *this)
-{
- free (this);
-}
-
-static void *init_plugin (xine_t *xine, void *data)
-{
- spuhdmv_class_t *this;
-
- this = calloc(1, sizeof (spuhdmv_class_t));
-
- this->decoder_class.open_plugin = open_plugin;
- this->decoder_class.get_identifier = get_identifier;
- this->decoder_class.get_description = get_description;
- this->decoder_class.dispose = dispose_class;
-
- return this;
-}
-
-/* plugin catalog information */
-static uint32_t supported_types[] = { BUF_SPU_HDMV, 0 };
-
-static const decoder_info_t dec_info_data = {
- supported_types, /* supported types */
- 5 /* priority */
-};
-
-const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_SPU_DECODER, 16, "spuhdmv", XINE_VERSION_CODE, &dec_info_data, &init_plugin },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
-};