From a32ee1f2295ca674287388d60230b9bf11b2cabf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 4 Apr 2007 22:45:40 +0200 Subject: Rename xine_decoder.c to xine_spu_decoder.c. Use xineplug_LTLIBRARIES. --HG-- rename : src/libspudec/xine_decoder.c => src/libspudec/xine_spu_decoder.c --- src/libspudec/Makefile.am | 10 +- src/libspudec/xine_decoder.c | 404 --------------------------------------- src/libspudec/xine_spu_decoder.c | 404 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 408 insertions(+), 410 deletions(-) delete mode 100644 src/libspudec/xine_decoder.c create mode 100644 src/libspudec/xine_spu_decoder.c diff --git a/src/libspudec/Makefile.am b/src/libspudec/Makefile.am index d50c49ca6..208d994f5 100644 --- a/src/libspudec/Makefile.am +++ b/src/libspudec/Makefile.am @@ -1,14 +1,12 @@ include $(top_srcdir)/misc/Makefile.common -libdir = $(XINE_PLUGINDIR) - -lib_LTLIBRARIES = xineplug_decode_spu.la +xineplug_LTLIBRARIES = xineplug_decode_spu.la if HAVE_DVDNAV xineplug_decode_spu_la_SOURCES = \ spu.c \ - xine_decoder.c + xine_spu_decoder.c xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(DVDNAV_LIBS) $(PTHREAD_LIBS) else @@ -16,13 +14,13 @@ else xineplug_decode_spu_la_SOURCES = \ nav_read.c \ spu.c \ - xine_decoder.c + xine_spu_decoder.c AM_CPPFLAGS = -I$(top_srcdir)/src/input/libdvdnav xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) endif xineplug_decode_spu_la_CFLAGS = $(DVDNAV_CFLAGS) $(VISIBILITY_FLAG) -xineplug_decode_spu_la_LDFLAGS = -avoid-version -module +xineplug_decode_spu_la_LDFLAGS = $(xineplug_ldflags) noinst_HEADERS = spu.h diff --git a/src/libspudec/xine_decoder.c b/src/libspudec/xine_decoder.c deleted file mode 100644 index 30c7f18c9..000000000 --- a/src/libspudec/xine_decoder.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Copyright (C) 2000-2004 the xine project - * - * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: xine_decoder.c,v 1.116 2006/07/10 22:08:30 dgp85 Exp $ - * - * stuff needed to turn libspu into a xine decoder plugin - */ - -#include -#include -#include -#include -#include -#include - -#include "xine_internal.h" -#include "buffer.h" -#include "xine-engine/bswap.h" -#include "xineutils.h" -#include "spu.h" -#ifdef HAVE_DVDNAV -# include -# include -#else -# include "nav_read.h" -# include "nav_types.h" -#endif - -/* -#define LOG_DEBUG 1 -#define LOG_BUTTON 1 -*/ - -static clut_t default_clut[] = { - CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x10, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), - CLUT_Y_CR_CB_INIT(0x51, 0xef, 0x5a), - CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x36, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), - CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x51, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x10, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), - CLUT_Y_CR_CB_INIT(0x5c, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x1c, 0x80, 0x80), - CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef) -}; - -static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { - uint32_t stream_id; - spudec_seq_t *cur_seq; - spudec_decoder_t *this = (spudec_decoder_t *) this_gen; - stream_id = buf->type & 0x1f ; - cur_seq = &this->spudec_stream_state[stream_id].ra_seq; - -#ifdef LOG_DEBUG - printf("libspudec:got buffer type = %x\n", buf->type); -#endif - - /* check, if we need to process the next PCI from the list */ - pthread_mutex_lock(&this->nav_pci_lock); - spudec_update_nav(this); - pthread_mutex_unlock(&this->nav_pci_lock); - - if ( (buf->type & 0xffff0000) != BUF_SPU_DVD || - !(buf->decoder_flags & BUF_FLAG_SPECIAL) || - buf->decoder_info[1] != BUF_SPECIAL_SPU_DVD_SUBTYPE ) - return; - - if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_CLUT ) { -#ifdef LOG_DEBUG - printf("libspudec: SPU CLUT\n"); -#endif - if (buf->content[0]) { /* cheap endianess detection */ - xine_fast_memcpy(this->state.clut, buf->content, sizeof(uint32_t)*16); - } else { - int i; - uint32_t *clut = (uint32_t*) buf->content; - for (i = 0; i < 16; i++) - this->state.clut[i] = bswap_32(clut[i]); - } - this->state.need_clut = 0; - return; - } - - if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_NAV ) { -#ifdef LOG_DEBUG - printf("libspudec:got nav packet 1\n"); -#endif - spudec_decode_nav(this,buf); - return; - } - - if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_VOBSUB_PACKAGE ) { - this->state.vobsub = 1; - } - -#ifdef LOG_DEBUG - printf("libspudec:got buffer type = %x\n", buf->type); -#endif - if (buf->decoder_flags & BUF_FLAG_PREVIEW) /* skip preview data */ - return; - - if (buf->pts) { - metronom_t *metronom = this->stream->metronom; - int64_t vpts = metronom->got_spu_packet(metronom, buf->pts); - - this->spudec_stream_state[stream_id].vpts = vpts; /* Show timer */ - this->spudec_stream_state[stream_id].pts = buf->pts; /* Required to match up with NAV packets */ - } - - spudec_reassembly(this->stream->xine, - &this->spudec_stream_state[stream_id].ra_seq, buf->content, buf->size); - if(this->spudec_stream_state[stream_id].ra_seq.complete == 1) { - if(this->spudec_stream_state[stream_id].ra_seq.broken) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libspudec: dropping broken SPU\n"); - this->spudec_stream_state[stream_id].ra_seq.broken = 0; - } else - spudec_process(this,stream_id); - } -} - -static void spudec_reset (spu_decoder_t *this_gen) { - spudec_decoder_t *this = (spudec_decoder_t *) this_gen; - video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); - int i; - - if( this->menu_handle >= 0 ) - ovl_manager->free_handle(ovl_manager, - this->menu_handle); - this->menu_handle = -1; - - for (i=0; i < MAX_STREAMS; i++) { - if( this->spudec_stream_state[i].overlay_handle >= 0 ) - ovl_manager->free_handle(ovl_manager, - this->spudec_stream_state[i].overlay_handle); - this->spudec_stream_state[i].overlay_handle = -1; - this->spudec_stream_state[i].ra_seq.complete = 1; - this->spudec_stream_state[i].ra_seq.broken = 0; - } - - pthread_mutex_lock(&this->nav_pci_lock); - spudec_clear_nav_list(this); - pthread_mutex_unlock(&this->nav_pci_lock); -} - -static void spudec_discontinuity (spu_decoder_t *this_gen) { - spudec_decoder_t *this = (spudec_decoder_t *) this_gen; - - pthread_mutex_lock(&this->nav_pci_lock); - spudec_clear_nav_list(this); - pthread_mutex_unlock(&this->nav_pci_lock); -} - - -static void spudec_dispose (spu_decoder_t *this_gen) { - - spudec_decoder_t *this = (spudec_decoder_t *) this_gen; - int i; - video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); - - if( this->menu_handle >= 0 ) - ovl_manager->free_handle(ovl_manager, - this->menu_handle); - this->menu_handle = -1; - - for (i=0; i < MAX_STREAMS; i++) { - if( this->spudec_stream_state[i].overlay_handle >= 0 ) - ovl_manager->free_handle(ovl_manager, - this->spudec_stream_state[i].overlay_handle); - this->spudec_stream_state[i].overlay_handle = -1; - free (this->spudec_stream_state[i].ra_seq.buf); - } - - spudec_clear_nav_list(this); - pthread_mutex_destroy(&this->nav_pci_lock); - - free (this->event.object.overlay); - free (this); -} - -/* gets the current already correctly processed nav_pci info */ -/* This is not perfectly in sync with the display, but all the same, */ -/* much closer than doing it at the input stage. */ -/* returns a bool for error/success.*/ -static int spudec_get_interact_info (spu_decoder_t *this_gen, void *data) { - spudec_decoder_t *this = (spudec_decoder_t *) this_gen; - /*printf("get_interact_info() called\n");*/ - if (!this || !data) - return 0; - - /*printf("get_interact_info() coping nav_pci\n");*/ - pthread_mutex_lock(&this->nav_pci_lock); - spudec_update_nav(this); - memcpy(data, &this->pci_cur.pci, sizeof(pci_t) ); - pthread_mutex_unlock(&this->nav_pci_lock); - return 1; - -} - -static void spudec_set_button (spu_decoder_t *this_gen, int32_t button, int32_t show) { - spudec_decoder_t *this = (spudec_decoder_t *) this_gen; - /* This function will move to video_overlay - * when video_overlay does menus */ - - video_overlay_manager_t *ovl_manager; - video_overlay_event_t *overlay_event = NULL; - vo_overlay_t *overlay = NULL; - overlay_event = xine_xmalloc (sizeof(video_overlay_event_t)); - - overlay = xine_xmalloc (sizeof(vo_overlay_t)); - /* FIXME: Watch out for threads. We should really put a lock on this - * because events is a different thread than decode_data */ - - if( this->menu_handle < 0 ) { - if (this->stream->video_out) { - ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); - this->menu_handle = ovl_manager->get_handle(ovl_manager,1); - } - } -#ifdef LOG_BUTTON - printf ("libspudec:xine_decoder.c:spudec_event_listener:this=%p\n",this); - printf ("libspudec:xine_decoder.c:spudec_event_listener:this->menu_handle=%d\n",this->menu_handle); -#endif - if(this->menu_handle < 0) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "Menu handle alloc failed. No more overlays objects available. Only %d at once please.", - MAX_OBJECTS); - free(overlay_event); - free(overlay); - return; - } - - if (show > 0) { -#ifdef LOG_NAV - fprintf (stderr,"libspudec:xine_decoder.c:spudec_event_listener:buttonN = %u show=%d\n", - button, - show); -#endif - this->buttonN = button; - if (this->button_filter != 1) { -#ifdef LOG_BUTTON - fprintf (stdout,"libspudec:xine_decoder.c:spudec_event_listener:buttonN updates not allowed\n"); -#endif - /* Only update highlight is the menu will let us */ - free(overlay_event); - free(overlay); - return; - } - if (show == 2) { - this->button_filter = 2; - } - pthread_mutex_lock(&this->nav_pci_lock); - spudec_update_nav(this); - overlay_event->object.handle = this->menu_handle; - overlay_event->object.pts = this->pci_cur.pci.hli.hl_gi.hli_s_ptm; - overlay_event->object.overlay=overlay; - overlay_event->event_type = OVERLAY_EVENT_MENU_BUTTON; -#ifdef LOG_BUTTON - fprintf(stderr, "libspudec:Button Overlay\n"); -#endif - spudec_copy_nav_to_overlay(this->stream->xine, &this->pci_cur.pci, this->state.clut, - this->buttonN, show-1, overlay, &this->overlay ); - pthread_mutex_unlock(&this->nav_pci_lock); - } else { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "libspudec:xine_decoder.c:spudec_event_listener:HIDE ????\n"); - printf("We dropped out here for some reason"); - _x_abort(); - overlay_event->object.handle = this->menu_handle; - overlay_event->event_type = OVERLAY_EVENT_HIDE; - } - overlay_event->vpts = 0; - if (this->stream->video_out) { - ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); -#ifdef LOG_BUTTON - fprintf(stderr, "libspudec: add_event type=%d : current time=%lld, spu vpts=%lli\n", - overlay_event->event_type, - this->stream->xine->clock->get_current_time(this->stream->xine->clock), - overlay_event->vpts); -#endif - ovl_manager->add_event (ovl_manager, (void *)overlay_event); - free(overlay_event); - free(overlay); - } else { - free(overlay_event); - free(overlay); - } - return; -} - -static spu_decoder_t *open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) { - - spudec_decoder_t *this ; - int i; - - this = (spudec_decoder_t *) xine_xmalloc (sizeof (spudec_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 = spudec_get_interact_info; - this->spu_decoder.set_button = spudec_set_button; - this->stream = stream; - this->class = (spudec_class_t *) class_gen; - - this->menu_handle = -1; - this->buttonN = 1; - this->event.object.overlay = xine_xmalloc(sizeof(vo_overlay_t)); - - pthread_mutex_init(&this->nav_pci_lock, NULL); - this->pci_cur.pci.hli.hl_gi.hli_ss = 0; - this->pci_cur.next = NULL; - - this->ovl_caps = stream->video_out->get_capabilities(stream->video_out); - this->output_open = 0; - this->last_event_vpts = 0; - for (i=0; i < MAX_STREAMS; i++) { - this->spudec_stream_state[i].ra_seq.complete = 1; - this->spudec_stream_state[i].overlay_handle = -1; - } - -/* FIXME:Do we really need a default clut? */ - xine_fast_memcpy(this->state.clut, default_clut, sizeof(this->state.clut)); - this->state.need_clut = 1; - this->state.vobsub = 0; - - return &this->spu_decoder; -} - -static char *get_identifier (spu_decoder_class_t *this) { -#ifdef LOG_DEBUG - printf ("libspudec:get_identifier called\n"); -#endif - return "spudec"; -} - -static char *get_description (spu_decoder_class_t *this) { -#ifdef LOG_DEBUG - printf ("libspudec:get_description called\n"); -#endif - return "DVD/VOB SPU decoder plugin"; -} - -static void dispose_class (spu_decoder_class_t *this) { -#ifdef LOG_DEBUG - printf ("libspudec:dispose_class called\n"); -#endif - free (this); -} - - -static void *init_plugin (xine_t *xine, void *data) { - - spudec_class_t *this; - - this = (spudec_class_t *) xine_xmalloc (sizeof (spudec_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; - - lprintf ("libspudec:init_plugin called\n"); - return this; -} - -/* plugin catalog information */ -static uint32_t supported_types[] = { BUF_SPU_DVD, 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, "spudec", XINE_VERSION_CODE, &dec_info_data, &init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libspudec/xine_spu_decoder.c b/src/libspudec/xine_spu_decoder.c new file mode 100644 index 000000000..30c7f18c9 --- /dev/null +++ b/src/libspudec/xine_spu_decoder.c @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2000-2004 the xine project + * + * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: xine_decoder.c,v 1.116 2006/07/10 22:08:30 dgp85 Exp $ + * + * stuff needed to turn libspu into a xine decoder plugin + */ + +#include +#include +#include +#include +#include +#include + +#include "xine_internal.h" +#include "buffer.h" +#include "xine-engine/bswap.h" +#include "xineutils.h" +#include "spu.h" +#ifdef HAVE_DVDNAV +# include +# include +#else +# include "nav_read.h" +# include "nav_types.h" +#endif + +/* +#define LOG_DEBUG 1 +#define LOG_BUTTON 1 +*/ + +static clut_t default_clut[] = { + CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x10, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), + CLUT_Y_CR_CB_INIT(0x51, 0xef, 0x5a), + CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x36, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), + CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x51, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x10, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), + CLUT_Y_CR_CB_INIT(0x5c, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x1c, 0x80, 0x80), + CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef) +}; + +static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { + uint32_t stream_id; + spudec_seq_t *cur_seq; + spudec_decoder_t *this = (spudec_decoder_t *) this_gen; + stream_id = buf->type & 0x1f ; + cur_seq = &this->spudec_stream_state[stream_id].ra_seq; + +#ifdef LOG_DEBUG + printf("libspudec:got buffer type = %x\n", buf->type); +#endif + + /* check, if we need to process the next PCI from the list */ + pthread_mutex_lock(&this->nav_pci_lock); + spudec_update_nav(this); + pthread_mutex_unlock(&this->nav_pci_lock); + + if ( (buf->type & 0xffff0000) != BUF_SPU_DVD || + !(buf->decoder_flags & BUF_FLAG_SPECIAL) || + buf->decoder_info[1] != BUF_SPECIAL_SPU_DVD_SUBTYPE ) + return; + + if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_CLUT ) { +#ifdef LOG_DEBUG + printf("libspudec: SPU CLUT\n"); +#endif + if (buf->content[0]) { /* cheap endianess detection */ + xine_fast_memcpy(this->state.clut, buf->content, sizeof(uint32_t)*16); + } else { + int i; + uint32_t *clut = (uint32_t*) buf->content; + for (i = 0; i < 16; i++) + this->state.clut[i] = bswap_32(clut[i]); + } + this->state.need_clut = 0; + return; + } + + if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_NAV ) { +#ifdef LOG_DEBUG + printf("libspudec:got nav packet 1\n"); +#endif + spudec_decode_nav(this,buf); + return; + } + + if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_VOBSUB_PACKAGE ) { + this->state.vobsub = 1; + } + +#ifdef LOG_DEBUG + printf("libspudec:got buffer type = %x\n", buf->type); +#endif + if (buf->decoder_flags & BUF_FLAG_PREVIEW) /* skip preview data */ + return; + + if (buf->pts) { + metronom_t *metronom = this->stream->metronom; + int64_t vpts = metronom->got_spu_packet(metronom, buf->pts); + + this->spudec_stream_state[stream_id].vpts = vpts; /* Show timer */ + this->spudec_stream_state[stream_id].pts = buf->pts; /* Required to match up with NAV packets */ + } + + spudec_reassembly(this->stream->xine, + &this->spudec_stream_state[stream_id].ra_seq, buf->content, buf->size); + if(this->spudec_stream_state[stream_id].ra_seq.complete == 1) { + if(this->spudec_stream_state[stream_id].ra_seq.broken) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libspudec: dropping broken SPU\n"); + this->spudec_stream_state[stream_id].ra_seq.broken = 0; + } else + spudec_process(this,stream_id); + } +} + +static void spudec_reset (spu_decoder_t *this_gen) { + spudec_decoder_t *this = (spudec_decoder_t *) this_gen; + video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); + int i; + + if( this->menu_handle >= 0 ) + ovl_manager->free_handle(ovl_manager, + this->menu_handle); + this->menu_handle = -1; + + for (i=0; i < MAX_STREAMS; i++) { + if( this->spudec_stream_state[i].overlay_handle >= 0 ) + ovl_manager->free_handle(ovl_manager, + this->spudec_stream_state[i].overlay_handle); + this->spudec_stream_state[i].overlay_handle = -1; + this->spudec_stream_state[i].ra_seq.complete = 1; + this->spudec_stream_state[i].ra_seq.broken = 0; + } + + pthread_mutex_lock(&this->nav_pci_lock); + spudec_clear_nav_list(this); + pthread_mutex_unlock(&this->nav_pci_lock); +} + +static void spudec_discontinuity (spu_decoder_t *this_gen) { + spudec_decoder_t *this = (spudec_decoder_t *) this_gen; + + pthread_mutex_lock(&this->nav_pci_lock); + spudec_clear_nav_list(this); + pthread_mutex_unlock(&this->nav_pci_lock); +} + + +static void spudec_dispose (spu_decoder_t *this_gen) { + + spudec_decoder_t *this = (spudec_decoder_t *) this_gen; + int i; + video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); + + if( this->menu_handle >= 0 ) + ovl_manager->free_handle(ovl_manager, + this->menu_handle); + this->menu_handle = -1; + + for (i=0; i < MAX_STREAMS; i++) { + if( this->spudec_stream_state[i].overlay_handle >= 0 ) + ovl_manager->free_handle(ovl_manager, + this->spudec_stream_state[i].overlay_handle); + this->spudec_stream_state[i].overlay_handle = -1; + free (this->spudec_stream_state[i].ra_seq.buf); + } + + spudec_clear_nav_list(this); + pthread_mutex_destroy(&this->nav_pci_lock); + + free (this->event.object.overlay); + free (this); +} + +/* gets the current already correctly processed nav_pci info */ +/* This is not perfectly in sync with the display, but all the same, */ +/* much closer than doing it at the input stage. */ +/* returns a bool for error/success.*/ +static int spudec_get_interact_info (spu_decoder_t *this_gen, void *data) { + spudec_decoder_t *this = (spudec_decoder_t *) this_gen; + /*printf("get_interact_info() called\n");*/ + if (!this || !data) + return 0; + + /*printf("get_interact_info() coping nav_pci\n");*/ + pthread_mutex_lock(&this->nav_pci_lock); + spudec_update_nav(this); + memcpy(data, &this->pci_cur.pci, sizeof(pci_t) ); + pthread_mutex_unlock(&this->nav_pci_lock); + return 1; + +} + +static void spudec_set_button (spu_decoder_t *this_gen, int32_t button, int32_t show) { + spudec_decoder_t *this = (spudec_decoder_t *) this_gen; + /* This function will move to video_overlay + * when video_overlay does menus */ + + video_overlay_manager_t *ovl_manager; + video_overlay_event_t *overlay_event = NULL; + vo_overlay_t *overlay = NULL; + overlay_event = xine_xmalloc (sizeof(video_overlay_event_t)); + + overlay = xine_xmalloc (sizeof(vo_overlay_t)); + /* FIXME: Watch out for threads. We should really put a lock on this + * because events is a different thread than decode_data */ + + if( this->menu_handle < 0 ) { + if (this->stream->video_out) { + ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); + this->menu_handle = ovl_manager->get_handle(ovl_manager,1); + } + } +#ifdef LOG_BUTTON + printf ("libspudec:xine_decoder.c:spudec_event_listener:this=%p\n",this); + printf ("libspudec:xine_decoder.c:spudec_event_listener:this->menu_handle=%d\n",this->menu_handle); +#endif + if(this->menu_handle < 0) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "Menu handle alloc failed. No more overlays objects available. Only %d at once please.", + MAX_OBJECTS); + free(overlay_event); + free(overlay); + return; + } + + if (show > 0) { +#ifdef LOG_NAV + fprintf (stderr,"libspudec:xine_decoder.c:spudec_event_listener:buttonN = %u show=%d\n", + button, + show); +#endif + this->buttonN = button; + if (this->button_filter != 1) { +#ifdef LOG_BUTTON + fprintf (stdout,"libspudec:xine_decoder.c:spudec_event_listener:buttonN updates not allowed\n"); +#endif + /* Only update highlight is the menu will let us */ + free(overlay_event); + free(overlay); + return; + } + if (show == 2) { + this->button_filter = 2; + } + pthread_mutex_lock(&this->nav_pci_lock); + spudec_update_nav(this); + overlay_event->object.handle = this->menu_handle; + overlay_event->object.pts = this->pci_cur.pci.hli.hl_gi.hli_s_ptm; + overlay_event->object.overlay=overlay; + overlay_event->event_type = OVERLAY_EVENT_MENU_BUTTON; +#ifdef LOG_BUTTON + fprintf(stderr, "libspudec:Button Overlay\n"); +#endif + spudec_copy_nav_to_overlay(this->stream->xine, &this->pci_cur.pci, this->state.clut, + this->buttonN, show-1, overlay, &this->overlay ); + pthread_mutex_unlock(&this->nav_pci_lock); + } else { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "libspudec:xine_decoder.c:spudec_event_listener:HIDE ????\n"); + printf("We dropped out here for some reason"); + _x_abort(); + overlay_event->object.handle = this->menu_handle; + overlay_event->event_type = OVERLAY_EVENT_HIDE; + } + overlay_event->vpts = 0; + if (this->stream->video_out) { + ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); +#ifdef LOG_BUTTON + fprintf(stderr, "libspudec: add_event type=%d : current time=%lld, spu vpts=%lli\n", + overlay_event->event_type, + this->stream->xine->clock->get_current_time(this->stream->xine->clock), + overlay_event->vpts); +#endif + ovl_manager->add_event (ovl_manager, (void *)overlay_event); + free(overlay_event); + free(overlay); + } else { + free(overlay_event); + free(overlay); + } + return; +} + +static spu_decoder_t *open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) { + + spudec_decoder_t *this ; + int i; + + this = (spudec_decoder_t *) xine_xmalloc (sizeof (spudec_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 = spudec_get_interact_info; + this->spu_decoder.set_button = spudec_set_button; + this->stream = stream; + this->class = (spudec_class_t *) class_gen; + + this->menu_handle = -1; + this->buttonN = 1; + this->event.object.overlay = xine_xmalloc(sizeof(vo_overlay_t)); + + pthread_mutex_init(&this->nav_pci_lock, NULL); + this->pci_cur.pci.hli.hl_gi.hli_ss = 0; + this->pci_cur.next = NULL; + + this->ovl_caps = stream->video_out->get_capabilities(stream->video_out); + this->output_open = 0; + this->last_event_vpts = 0; + for (i=0; i < MAX_STREAMS; i++) { + this->spudec_stream_state[i].ra_seq.complete = 1; + this->spudec_stream_state[i].overlay_handle = -1; + } + +/* FIXME:Do we really need a default clut? */ + xine_fast_memcpy(this->state.clut, default_clut, sizeof(this->state.clut)); + this->state.need_clut = 1; + this->state.vobsub = 0; + + return &this->spu_decoder; +} + +static char *get_identifier (spu_decoder_class_t *this) { +#ifdef LOG_DEBUG + printf ("libspudec:get_identifier called\n"); +#endif + return "spudec"; +} + +static char *get_description (spu_decoder_class_t *this) { +#ifdef LOG_DEBUG + printf ("libspudec:get_description called\n"); +#endif + return "DVD/VOB SPU decoder plugin"; +} + +static void dispose_class (spu_decoder_class_t *this) { +#ifdef LOG_DEBUG + printf ("libspudec:dispose_class called\n"); +#endif + free (this); +} + + +static void *init_plugin (xine_t *xine, void *data) { + + spudec_class_t *this; + + this = (spudec_class_t *) xine_xmalloc (sizeof (spudec_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; + + lprintf ("libspudec:init_plugin called\n"); + return this; +} + +/* plugin catalog information */ +static uint32_t supported_types[] = { BUF_SPU_DVD, 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, "spudec", XINE_VERSION_CODE, &dec_info_data, &init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; -- cgit v1.2.3