summaryrefslogtreecommitdiff
path: root/src/libspudec/xine_decoder.c
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2001-11-28 22:19:10 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2001-11-28 22:19:10 +0000
commitd48b3bf8769a8ac1741d819289ed9ea117764bc5 (patch)
treeb90a868f2118128d8b0bcff135f9b0ac3d46ae73 /src/libspudec/xine_decoder.c
parent157c020ba6d577c45678b7b59f96b3ca646fa525 (diff)
downloadxine-lib-d48b3bf8769a8ac1741d819289ed9ea117764bc5.tar.gz
xine-lib-d48b3bf8769a8ac1741d819289ed9ea117764bc5.tar.bz2
* OSD (On Screen Display) for rendering text and graphics into overlays
* reworked spu and overlay manager (multiple overlays supported) CVS patchset: 1126 CVS date: 2001/11/28 22:19:10
Diffstat (limited to 'src/libspudec/xine_decoder.c')
-rw-r--r--src/libspudec/xine_decoder.c664
1 files changed, 63 insertions, 601 deletions
diff --git a/src/libspudec/xine_decoder.c b/src/libspudec/xine_decoder.c
index 1f05e3ede..0c5811310 100644
--- a/src/libspudec/xine_decoder.c
+++ b/src/libspudec/xine_decoder.c
@@ -19,7 +19,7 @@
* 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.35 2001/11/18 03:53:24 guenter Exp $
+ * $Id: xine_decoder.c,v 1.36 2001/11/28 22:19:12 miguelfreitas Exp $
*
* stuff needed to turn libspu into a xine decoder plugin
*/
@@ -31,15 +31,13 @@
#include <sys/stat.h>
#include <fcntl.h>
-#include "spu.h"
#include "buffer.h"
#include "events.h"
#include "xine_internal.h"
#include "video_out/alphablend.h"
#include "xine-engine/bswap.h"
#include "xineutils.h"
-
-static void spudec_print_overlay( vo_overlay_t *ovl );
+#include "spu.h"
/*
#define LOG_DEBUG 1
@@ -83,90 +81,6 @@ static clut_t __default_clut[] = {
CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef)
};
-#define NUM_SEQ_BUFFERS 50
-#define MAX_OBJECTS 50
-#define MAX_STREAMS 32
-#define MAX_EVENTS 50
-#define MAX_SHOWING 5
-
-#define EVENT_NULL 0
-#define EVENT_SHOW_SPU 1
-#define EVENT_HIDE_SPU 2
-#define EVENT_HIDE_MENU 3
-#define EVENT_MENU_SPU 4
-#define EVENT_MENU_BUTTON 5
-#define EVENT_DELETE_RESOURCE 6 /* Maybe release handle will do this */
-#define EVENT_SHOW_OSD 7 /* Not yet implemented */
-
-typedef struct spu_object_s {
- int32_t handle; /* Used to match Show and Hide events. */
- uint32_t object_type; /* 0=Subtitle, 1=Menu */
- uint32_t pts; /* Needed for Menu button compares */
- vo_overlay_t *overlay; /* The image data. */
- uint32_t palette_type; /* 1 Y'CrCB, 2 R'G'B' */
- uint32_t *palette; /* If NULL, no palette contained in this event. */
-} spu_object_t;
-
-/* This will hold all details of an event item, needed for event queue to function */
-typedef struct spu_overlay_event_s {
- uint32_t event_type; /* Show SPU, Show OSD, Hide etc. */
- uint32_t vpts; /* Time when event will action. 0 means action now */
-/* Once video_out blend_yuv etc. can take rle_elem_t with Colour, blend and length information.
- * we can remove clut and blend from this structure.
- * This will allow for many more colours for OSD.
- */
- spu_object_t object; /* The image data. */
-} spu_overlay_event_t;
-
-typedef struct spu_overlay_events_s {
- spu_overlay_event_t *event;
- uint32_t next_event;
-} spu_overlay_events_t;
-
-typedef struct spu_showing_s {
- int32_t handle; /* -1 means not allocated */
-} spu_showing_t;
-
-
-typedef struct spudec_stream_state_s {
- spu_seq_t ra_seq;
- uint32_t ra_complete;
- uint32_t stream_filter;
- spu_state_t state;
- uint32_t vpts;
- uint32_t pts;
-} spudec_stream_state_t;
-
-typedef struct spudec_decoder_s {
- spu_decoder_t spu_decoder;
- ovl_src_t ovl_src;
-
- xine_t *xine;
-/* spu_seq_t seq_list[NUM_SEQ_BUFFERS]; */
- spu_seq_t *cur_seq;
- spudec_stream_state_t spu_stream_state[MAX_STREAMS];
- pthread_mutex_t spu_events_mutex;
- spu_overlay_events_t spu_events[MAX_EVENTS];
- spu_overlay_event_t event;
- spu_object_t object;
- pthread_mutex_t spu_objects_mutex;
- spu_object_t spu_objects[MAX_OBJECTS];
- pthread_mutex_t spu_showing_mutex; /* Probably not needed */
- spu_showing_t spu_showing[MAX_SHOWING];
- spu_seq_t *ra_seq;
- int ra_complete;
-
- uint32_t ovl_pts;
- uint32_t buf_pts;
- spu_state_t state;
-
- vo_instance_t *vo_out;
- vo_overlay_t overlay;
- int ovl_caps;
- int output_open;
-
-} spudec_decoder_t;
-
static int spudec_can_handle (spu_decoder_t *this_gen, int buf_type) {
int type = buf_type & 0xFFFF0000;
return (type == BUF_SPU_PACKAGE || type == BUF_SPU_CLUT || type == BUF_SPU_SUBP_CONTROL) ;
@@ -175,6 +89,7 @@ static int spudec_can_handle (spu_decoder_t *this_gen, int buf_type) {
/* FIXME: This function needs checking */
static void spudec_reset (spudec_decoder_t *this) {
int i;
+
this->ovl_pts = 0;
this->buf_pts = 0;
@@ -187,50 +102,9 @@ static void spudec_reset (spudec_decoder_t *this) {
for (i=0; i < MAX_STREAMS; i++) {
this->spu_stream_state[i].stream_filter = 1; /* So it works with non-navdvd plugins */
this->spu_stream_state[i].ra_complete = 1;
+ this->spu_stream_state[i].overlay_handle = -1;
}
- for (i=0; i < MAX_EVENTS; i++) {
- if (this->spu_events[i].event == NULL) {
-#ifdef LOG_DEBUG
- printf ("spu: MALLOC1: this->spu_events[%d].event %p, len=%d\n",
- i,
- this->spu_events[i].event,
- sizeof(spu_overlay_event_t));
-#endif
- this->spu_events[i].event = xine_xmalloc (sizeof(spu_overlay_event_t));
-#ifdef LOG_DEBUG
- printf ("spu: MALLOC2: this->spu_events[%d].event %p, len=%d\n",
- i,
- this->spu_events[i].event,
- sizeof(spu_overlay_event_t));
-#endif
- this->spu_events[i].event->event_type = 0; /* Empty slot */
- }
- }
- for (i=0; i < MAX_OBJECTS; i++) {
- this->spu_objects[i].handle = -1;
- }
- /* Initialise the menu object */
- this->spu_objects[1].handle=1;
- this->spu_objects[1].object_type=1;
- this->spu_objects[1].pts=0;
-#ifdef LOG_DEBUG
- printf ("spu: MALLOC1: this->spu_objects[1].overlay %p, len=%d\n",
- this->spu_objects[1].overlay, sizeof(vo_overlay_t));
-#endif
- this->spu_objects[1].overlay = xine_xmalloc (sizeof(vo_overlay_t));
-#ifdef LOG_DEBUG
- printf ("spu: MALLOC2: this->spu_objects[1].overlay %p, len=%d\n",
- this->spu_objects[1].overlay, sizeof(vo_overlay_t));
-#endif
-/* xine_xmalloc does memset */
-/* memset(this->spu_objects[1].overlay,0,sizeof(vo_overlay_t));
- */
-
- pthread_mutex_init (&this->spu_events_mutex,NULL);
- pthread_mutex_init (&this->spu_objects_mutex,NULL);
- pthread_mutex_init (&this->spu_showing_mutex,NULL);
-
/* I don't think I need this.
this->cur_seq = this->ra_seq = this->seq_list;
*/
@@ -249,131 +123,13 @@ static void spudec_init (spu_decoder_t *this_gen, vo_instance_t *vo_out) {
/* FIXME:Do we really need a default clut? */
memcpy(this->state.clut, __default_clut, sizeof(this->state.clut));
this->state.need_clut = 1;
- vo_out->register_ovl_src(vo_out, &this->ovl_src);
-}
-
-/* allocate a handle from the object pool
- */
-static int32_t spu_get_handle(spudec_decoder_t *this) {
- int n;
- n=0;
- do {
- n++;
- } while ( ( n<MAX_OBJECTS ) && ( this->spu_objects[n].handle > -1 ) );
- if (n >= MAX_OBJECTS) return -1;
- this->spu_objects[n].handle=n;
- return n;
-}
-
-/* allocate a menu handle from the object pool
- */
-static int32_t spu_get_menu_handle(spudec_decoder_t *this) {
- return 1; /* This might be dynamic later */
-}
-
-/* free a handle from the object pool
- */
-static void spu_free_handle(spudec_decoder_t *this, int32_t handle) {
- this->spu_objects[handle].handle = -1;
-}
-
-/* add an event to the events queue, sort the queue based on vpts.
- * This can be the API entry point for DVD subtitles.
- * In future this could also be the entry point for OSD as well as other Subtitle formats.
- * One calls this function with an event, the event contains an overlay and a vpts when to action/process it.
- * vpts of 0 means action the event now.
- * One also has a handle, so one can match show and hide events.
- * FIXME: Implement Event queue locking. A different thread calls spu_get_overlay, which removes events from the queue.
- */
-static int32_t spu_add_event(spudec_decoder_t *this, spu_overlay_event_t *event) {
- int found;
- uint32_t last_event,this_event,new_event;
- new_event=0;
- /* We skip the 0 entry because that is used as a pointer to the first event.*/
- /* Find a free event slot */
-#ifdef LOG_DEBUG
- printf ("spu: 284MUTEX1:spu_events lock");
-#endif
- pthread_mutex_lock (&this->spu_events_mutex);
-#ifdef LOG_DEBUG
- printf ("spu:->ok\n");
-#endif
- do {
- new_event++;
- } while ((new_event<MAX_EVENTS) && (this->spu_events[new_event].event->event_type > 0));
- if (new_event >= MAX_EVENTS) {
- pthread_mutex_unlock (&this->spu_events_mutex);
- return -1;
- }
- /* Find position in event queue to be added. */
- this_event=0;
- found=0;
- /* Find where in the current queue to insert the event. I.E. Sort it. */
- do {
- last_event=this_event;
- this_event=this->spu_events[last_event].next_event;
- if (this_event == 0) {
- found=1;
- break;
- }
-#ifdef LOG_DEBUG
- printf ("spu:this_event=%d vpts %d\n",this_event, this->spu_events[this_event].event->vpts);
-#endif
- if (this->spu_events[this_event].event->vpts > event->vpts ) {
- found=2;
- break;
- }
- } while ((this_event != 0) && (found == 0));
- if (last_event >= MAX_EVENTS) {
- pthread_mutex_unlock (&this->spu_events_mutex);
- fprintf(stderr, "No spare subtitle event slots\n");
- return -1;
- }
- /* memcpy everything except the actual image */
- this->spu_events[last_event].next_event=new_event;
- this->spu_events[new_event].next_event=this_event;
- if ( this->spu_events[new_event].event == NULL ) {
- fprintf(stderr,"COMPLAIN BIG TIME!\n");
- }
- this->spu_events[new_event].event->event_type=event->event_type;
- this->spu_events[new_event].event->vpts=event->vpts;
- this->spu_events[new_event].event->object.handle=event->object.handle;
-#ifdef LOG_DEBUG
- printf ("spu: 323MALLOC1: this->spu_events[new_event=%d].event->object.overlay %p, len=%d\n",
- new_event,
- this->spu_events[new_event].event->object.overlay,
- sizeof(vo_overlay_t));
-#endif
- this->spu_events[new_event].event->object.overlay = xine_xmalloc (sizeof(vo_overlay_t));
-#ifdef LOG_DEBUG
- printf ("spu: 328MALLOC2: this->spu_events[new_event=%d].event->object.overlay %p, len=%d\n",
- new_event,
- this->spu_events[new_event].event->object.overlay,
- sizeof(vo_overlay_t));
-#endif
- memcpy(this->spu_events[new_event].event->object.overlay,
- event->object.overlay, sizeof(vo_overlay_t));
- memset(event->object.overlay,0,sizeof(vo_overlay_t));
-// spudec_print_overlay( event->object.overlay );
-// spudec_print_overlay( this->spu_events[new_event].event->object.overlay );
- pthread_mutex_unlock (&this->spu_events_mutex);
-
- return new_event;
}
-/* empty the object queue
- * release all handles currently allocated.
- * IMPLEMENT ME.
- */
-static void spu_free_all_handles(spudec_decoder_t *this) {
-return;
-}
static void spu_process (spudec_decoder_t *this, uint32_t stream_id) {
// spu_overlay_event_t *event;
// spu_object_t *object;
// vo_overlay_t *overlay;
- int handle;
int pending = 1;
this->cur_seq = &this->spu_stream_state[stream_id].ra_seq;
@@ -392,12 +148,7 @@ static void spu_process (spudec_decoder_t *this, uint32_t stream_id) {
this->state.menu = 0; /* 0 - No value, 1 - Forced Display. */
this->state.delay = 0;
this->cur_seq->finished=0;
- handle=spu_get_handle(this);
- if (handle < 0) {
- printf("No SPU Handles left\n");
- return;
- }
-
+
do {
if (!this->spu_stream_state[stream_id].ra_seq.finished) {
@@ -414,7 +165,6 @@ static void spu_process (spudec_decoder_t *this, uint32_t stream_id) {
#ifdef LOG_DEBUG
printf ("spu: Dropping SPU channel %d\n", stream_id);
#endif
- spu_free_handle(this, handle);
return;
}
if ((this->state.modified) ) {
@@ -426,45 +176,56 @@ static void spu_process (spudec_decoder_t *this, uint32_t stream_id) {
if (this->state.menu == 0) {
/* Subtitle */
- this->event.object.handle = handle;
- /* FIXME: memcpy maybe. */
-#ifdef LOG_DEBUG
- printf ("spu: 403MALLOC: this->event.object.overlay=%p\n",
- this->event.object.overlay);
-#endif
- this->event.object.overlay = malloc(sizeof(vo_overlay_t));
+ if( this->spu_stream_state[stream_id].overlay_handle < 0 ) {
+ this->spu_stream_state[stream_id].overlay_handle =
+ this->vo_out->overlay_source->get_handle(this->vo_out->overlay_source, 0);
+ }
+
+ if( this->spu_stream_state[stream_id].overlay_handle < 0 ) {
+ printf("libspudec: No video_overlay handles left for SPU\n");
+ return;
+ }
+
+ this->event.object.handle = this->spu_stream_state[stream_id].overlay_handle;
+
memcpy(this->event.object.overlay,
&this->overlay,
sizeof(vo_overlay_t));
this->overlay.rle=NULL;
-#ifdef LOG_DEBUG
- printf ("spu: 409MALLOC: this->event.object.overlay=%p\n",
- this->event.object.overlay);
-#endif
+
this->event.event_type = this->state.visible;
+
+ /* event hide event must free the handle after use */
+ if( this->event.event_type == EVENT_HIDE_SPU ) {
+ this->spu_stream_state[stream_id].overlay_handle = -1;
+ }
+
this->event.vpts = this->spu_stream_state[stream_id].vpts+(this->state.delay*1000);
+
+ /*
+ printf("spu event %d handle: %d vpts: %d\n", this->event.event_type,
+ this->event.object.handle, this->event.vpts );
+ */
} else {
/* Menu */
- spu_free_handle(this, handle);
- this->event.object.handle = spu_get_menu_handle(this);
- /* FIXME: memcpy maybe. */
-#ifdef LOG_DEBUG
- printf ("spu:418MALLOC: this->event.object.overlay=%p\n",
- this->event.object.overlay);
-#endif
- this->event.object.overlay = malloc(sizeof(vo_overlay_t));
+ if( this->menu_handle < 0 )
+ this->menu_handle = this->vo_out->overlay_source->get_handle(this->vo_out->overlay_source,1);
+
+ if( this->menu_handle < 0 ) {
+ printf("libspudec: No video_overlay handles left for menu\n");
+ return;
+ }
+ this->event.object.handle = this->menu_handle;
+
memcpy(this->event.object.overlay,
&this->overlay,
sizeof(vo_overlay_t));
this->overlay.rle=NULL;
-#ifdef LOG_DEBUG
- printf ("spu: 424MALLOC: this->event.object.overlay=%p\n",
- this->event.object.overlay);
-#endif
+
this->event.event_type = EVENT_MENU_SPU;
this->event.vpts = this->spu_stream_state[stream_id].vpts+(this->state.delay*1000);
}
- spu_add_event(this, &this->event);
+ this->vo_out->overlay_source->add_event(this->vo_out->overlay_source, (void *)&this->event);
} else {
pending = 0;
}
@@ -509,7 +270,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
return;
if (buf->PTS) {
- metronom_t *metronom = this->ovl_src.metronom;
+ metronom_t *metronom = this->xine->metronom;
uint32_t vpts = metronom->got_spu_packet(metronom, buf->PTS, 0, buf->SCR);
if (vpts < this->buf_pts) {
/* FIXME: Don't do this yet,
@@ -546,9 +307,22 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
static void spudec_close (spu_decoder_t *this_gen) {
spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
+ int i;
- this->vo_out->unregister_ovl_src(this->vo_out, &this->ovl_src);
+ if( this->menu_handle >= 0 )
+ this->vo_out->overlay_source->free_handle(this->vo_out->overlay_source,
+ this->menu_handle);
+ this->menu_handle = -1;
+
+
+ for (i=0; i < MAX_STREAMS; i++) {
+ if( this->spu_stream_state[i].overlay_handle >= 0 )
+ this->vo_out->overlay_source->free_handle(this->vo_out->overlay_source,
+ this->spu_stream_state[i].overlay_handle);
+ this->spu_stream_state[i].overlay_handle = -1;
+ }
}
+
/* This function is probably not needed now */
static void spudec_nextseq(spudec_decoder_t* this) {
spu_seq_t *tmp_seq = this->cur_seq + 1;
@@ -582,303 +356,6 @@ static void spudec_print_overlay( vo_overlay_t *ovl ) {
return;
}
-/* FIXME:Some optimization needs to happen here. */
-static void spu_process_event( spudec_decoder_t *this, int vpts ) {
- int32_t handle;
- uint32_t this_event;
-// uint32_t vpts;
-// uint32_t pts;
-// int i;
-// vo_overlay_t overlay;
-#ifdef LOG_DEBUG
- printf ("spu: 557MUTEX1:spu_events lock");
-#endif
- pthread_mutex_lock (&this->spu_events_mutex);
-#ifdef LOG_DEBUG
- printf ("spu: -> ok.\n");
-#endif
- this_event=this->spu_events[0].next_event;
- if ((!this_event) || (vpts < this->spu_events[this_event].event->vpts) ) {
- pthread_mutex_unlock (&this->spu_events_mutex);
- return;
- }
-
- handle=this->spu_events[this_event].event->object.handle;
- switch( this->spu_events[this_event].event->event_type ) {
- case EVENT_SHOW_SPU:
-#ifdef LOG_DEBUG
- printf ("spu: SHOW SPU NOW\n");
-#endif
- if (this->spu_events[this_event].event->object.overlay != NULL) {
- this->spu_objects[handle].handle = handle;
-#ifdef LOG_DEBUG
- printf ("spu: POINTER1: this->spu_objects[handle=%d].overlay=%p\n",
- handle,
- this->spu_objects[handle].overlay);
-#endif
- this->spu_objects[handle].overlay = this->spu_events[this_event].event->object.overlay;
-#ifdef LOG_DEBUG
- printf ("spu: POINTER2: this->spu_objects[handle=%d].overlay=%p\n",
- handle,
- this->spu_objects[handle].overlay);
-#endif
- this->spu_events[this_event].event->object.overlay = NULL;
- }
- this->spu_showing[1].handle = handle;
- break;
-
- case EVENT_HIDE_SPU:
-#ifdef LOG_DEBUG
- printf ("spu: HIDE SPU NOW\n");
-#endif
- this->spu_showing[1].handle = -1;
- if(this->spu_objects[handle].overlay->rle) {
-#ifdef LOG_DEBUG
- printf ("spu: FREE1: this->spu_objects[%d].overlay->rle %p\n",
- handle,
- this->spu_objects[handle].overlay->rle);
-#endif
- free(this->spu_objects[handle].overlay->rle);
- this->spu_objects[handle].overlay->rle = NULL;
-#ifdef LOG_DEBUG
- printf ("spu: FREE2: this->spu_objects[%d].overlay->rle %p\n",
- handle,
- this->spu_objects[handle].overlay->rle);
-#endif
- }
-#ifdef LOG_DEBUG
- printf ("spu: RLE clear=%08X\n",(uint32_t)this->spu_objects[handle].overlay->rle);
-#endif
- if (this->spu_objects[handle].overlay) {
-#ifdef LOG_DEBUG
- printf ("spu: FREE1: this->spu_objects[%d].overlay %p\n",
- handle,
- this->spu_objects[handle].overlay);
-#endif
- free(this->spu_objects[handle].overlay);
- this->spu_objects[handle].overlay = NULL;
-#ifdef LOG_DEBUG
- printf ("spu: FREE2: this->spu_objects[%d].overlay %p\n",
- handle,
- this->spu_objects[handle].overlay);
-#endif
- }
- spu_free_handle( this, handle );
- break;
-
- case EVENT_HIDE_MENU:
-#ifdef LOG_DEBUG
- printf ("spu: HIDE MENU NOW %d\n",handle);
-#endif
- this->spu_showing[1].handle = -1;
- if(this->spu_objects[handle].overlay->rle) {
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "FREE1: this->spu_objects[%d].overlay->rle %p\n",
- handle,
- this->spu_objects[handle].overlay->rle);
-#endif
- free(this->spu_objects[handle].overlay->rle);
- this->spu_objects[handle].overlay->rle = NULL;
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "FREE2: this->spu_objects[%d].overlay->rle %p\n",
- handle,
- this->spu_objects[handle].overlay->rle);
-#endif
- }
-
- /* FIXME: maybe free something here */
- /* spu_free_handle( this, handle ); */
- break;
-
- case EVENT_MENU_SPU:
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "MENU SPU NOW\n");
-#endif
- if (this->spu_events[this_event].event->object.overlay != NULL) {
- vo_overlay_t *overlay = this->spu_objects[handle].overlay;
- vo_overlay_t *event_overlay = this->spu_events[this_event].event->object.overlay;
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "event_overlay\n");
-#endif
- spudec_print_overlay(event_overlay);
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "overlay\n");
-#endif
- spudec_print_overlay(overlay);
-
- this->spu_objects[handle].handle = handle; /* This should not change for menus */
- /* If rle is not empty, free it first */
- if(overlay && overlay->rle) {
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "FREE1: overlay->rle %p\n",
- overlay->rle);
-#endif
- free (overlay->rle);
- overlay->rle = NULL;
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "FREE2: overlay->rle %p\n",
- overlay->rle);
-#endif
- }
- overlay->rle = event_overlay->rle;
- overlay->data_size = event_overlay->data_size;
- overlay->num_rle = event_overlay->num_rle;
- overlay->x = event_overlay->x;
- overlay->y = event_overlay->y;
- overlay->width = event_overlay->width;
- overlay->height = event_overlay->height;
- overlay->rgb_clut = event_overlay->rgb_clut;
- if((event_overlay->color[0] +
- event_overlay->color[1] +
- event_overlay->color[2] +
- event_overlay->color[3]) > 0 ) {
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "mixing clut\n");
-#endif
- overlay->color[0] = event_overlay->color[0];
- overlay->color[1] = event_overlay->color[1];
- overlay->color[2] = event_overlay->color[2];
- overlay->color[3] = event_overlay->color[3];
- }
- if((event_overlay->trans[0] +
- event_overlay->trans[1] +
- event_overlay->trans[2] +
- event_overlay->trans[3]) > 0 ) {
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "mixing trans\n");
-#endif
- overlay->trans[0] = event_overlay->trans[0];
- overlay->trans[1] = event_overlay->trans[1];
- overlay->trans[2] = event_overlay->trans[2];
- overlay->trans[3] = event_overlay->trans[3];
- }
- this->spu_showing[1].handle = handle;
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "overlay after\n");
-#endif
- spudec_print_overlay(overlay);
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "FREE1: event_overlay %p\n",
- this->spu_events[this_event].event->object.overlay = NULL);
-#endif
- /* The null test was done at the start of this case statement */
- free (this->spu_events[this_event].event->object.overlay);
- this->spu_events[this_event].event->object.overlay = NULL;
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "FREE2: event_ovlerlay %p\n",
- this->spu_events[this_event].event->object.overlay);
-#endif
- }
- break;
-
- case EVENT_MENU_BUTTON:
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "MENU BUTTON NOW\n");
-#endif
- if (this->spu_events[this_event].event->object.overlay != NULL) {
- vo_overlay_t *overlay = this->spu_objects[handle].overlay;
- vo_overlay_t *event_overlay = this->spu_events[this_event].event->object.overlay;
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "event_overlay\n");
-#endif
- spudec_print_overlay(event_overlay);
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "overlay\n");
-#endif
- spudec_print_overlay(overlay);
- this->spu_objects[handle].handle = handle; /* This should not change for menus */
- overlay->clip_top = event_overlay->clip_top;
- overlay->clip_bottom = event_overlay->clip_bottom;
- overlay->clip_left = event_overlay->clip_left;
- overlay->clip_right = event_overlay->clip_right;
- //overlay->rgb_clut = event_overlay->rgb_clut; /* May needed later for OSD */
- if((event_overlay->color[0] +
- event_overlay->color[1] +
- event_overlay->color[2] +
- event_overlay->color[3]) > 0 ) {
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "mixing clut\n");
-#endif
- overlay->color[0] = event_overlay->color[0];
- overlay->color[1] = event_overlay->color[1];
- overlay->color[2] = event_overlay->color[2];
- overlay->color[3] = event_overlay->color[3];
- }
- if((event_overlay->trans[0] +
- event_overlay->trans[1] +
- event_overlay->trans[2] +
- event_overlay->trans[3]) > 0 ) {
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "mixing trans\n");
-#endif
- overlay->trans[0] = event_overlay->trans[0];
- overlay->trans[1] = event_overlay->trans[1];
- overlay->trans[2] = event_overlay->trans[2];
- overlay->trans[3] = event_overlay->trans[3];
- }
- this->spu_showing[1].handle = handle;
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "overlay after\n");
-#endif
- spudec_print_overlay(overlay);
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "FREE1: event_overlay %p\n",
- this->spu_events[this_event].event->object.overlay = NULL);
-#endif
- /* The null test was done at the start of this case statement */
- free (this->spu_events[this_event].event->object.overlay);
- this->spu_events[this_event].event->object.overlay = NULL;
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "FREE2: event_ovlerlay %p\n",
- this->spu_events[this_event].event->object.overlay);
-#endif
- }
- break;
-
- default:
-#ifdef LOG_DEBUG
- xprintf (VERBOSE|SPU, "Unhandled event type\n");
-#endif
- break;
-
- }
- this->spu_events[0].next_event = this->spu_events[this_event].next_event;
- this->spu_events[this_event].next_event = 0;
- this->spu_events[this_event].event->event_type = 0;
- pthread_mutex_unlock (&this->spu_events_mutex);
-}
-
-/* This is called from video_out and should return one image.
- * Repeated calls will display the next image.
- * until the last image is reached, when a NULL is returned
- * and the pointer starts from the beginning again.
- * For now, a max of 5 diffent images can be displayed at once.
- * Maybe we should add a callback instead of calling the function all the time.
- * We could rename this then to "Render overlay"
- * This function needs an API change, to add a callback function to do the actual overlay.
- * In this way we can get multiple objects displayed at the same time.
- * i.e. Subtitles and OSD.
- * Currently, only one object can be displayed at the same time.
- * The first checkin of this code should add no more functionality than the current code.
- * It was just be checked in so others can test it.
- */
-
-static vo_overlay_t* spudec_get_overlay(ovl_src_t *ovl_src, int vpts) {
- int32_t handle;
- spudec_decoder_t *this = (spudec_decoder_t*) ovl_src->src_gen;
-
- /* Look at next event, if current video vpts > first event on queue, process the event
- * else just continue
- */
- spu_process_event( this, vpts );
- /* Scan through 5 entries and display any present.
- * Currently, only 1 entry is scanned, until API can change.
- */
- handle=this->spu_showing[1].handle; /* handle is only valid if the object is currently visable. */
- if (handle < 0) return NULL;
- return this->spu_objects[handle].overlay;
-}
-
static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {
spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
xine_spu_event_t *event = (xine_spu_event_t *) event_gen;
@@ -890,7 +367,7 @@ static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {
switch (event->event.type) {
case XINE_EVENT_SPU_BUTTON:
{
- spu_overlay_event_t *overlay_event = NULL;
+ video_overlay_event_t *overlay_event = NULL;
vo_overlay_t *overlay = NULL;
spu_button_t *but = event->data;
#ifdef LOG_DEBUG
@@ -898,7 +375,7 @@ static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {
overlay_event,
sizeof(spu_overlay_event_t));
#endif
- overlay_event = xine_xmalloc (sizeof(spu_overlay_event_t));
+ overlay_event = xine_xmalloc (sizeof(video_overlay_event_t));
#ifdef LOG_DEBUG
xprintf (VERBOSE|SPU, "MALLOC2: overlay_event %p, len=%d\n",
overlay_event,
@@ -928,7 +405,7 @@ static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {
if (!this->state.menu) return;
if (but->show) {
- overlay_event->object.handle = spu_get_menu_handle(this);
+ overlay_event->object.handle = this->menu_handle;
overlay_event->object.overlay=overlay;
overlay_event->event_type = EVENT_MENU_BUTTON;
overlay_event->vpts = 0; /* Activate it NOW */
@@ -944,13 +421,12 @@ static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {
overlay->trans[1] = but->trans[1];
overlay->trans[2] = but->trans[2];
overlay->trans[3] = but->trans[3];
- spu_add_event(this, overlay_event);
} else {
- overlay_event->object.handle = spu_get_menu_handle(this);
+ overlay_event->object.handle = this->menu_handle;
overlay_event->event_type = EVENT_HIDE_MENU;
overlay_event->vpts = 0; /* Activate it NOW */
- spu_add_event(this, overlay_event);
}
+ this->vo_out->overlay_source->add_event(this->vo_out->overlay_source, (void *)overlay_event);
}
break;
case XINE_EVENT_SPU_CLUT:
@@ -963,21 +439,6 @@ static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {
}
}
break;
- /* What is this for?
- * This event is for GUI -> NAVDVD plugin
- * SPUDEC will have to use a different EVENT
- * if it needs this for CLUT auto detect.
- * ->that was a patch to redetect clut on spu channel change.
- * not very important, i will take a look when i have time. [MF]
- */
- /* FIXME
- case XINE_UI_GET_SPU_LANG:
- {
- this->state.need_clut = 1;
- }
- break;
- */
-
}
}
@@ -1008,9 +469,10 @@ spu_decoder_t *init_spu_decoder_plugin (int iface_version, xine_t *xine) {
this->spu_decoder.get_identifier = spudec_get_id;
this->spu_decoder.priority = 1;
- this->ovl_src.src_gen = this;
- this->ovl_src.get_overlay = spudec_get_overlay;
this->xine = xine;
+
+ this->menu_handle = -1;
+ this->event.object.overlay = malloc(sizeof(vo_overlay_t));
xine_register_event_listener(xine, spudec_event_listener, this);