summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libspudec/spu.c101
-rw-r--r--src/libspudec/spu.h5
-rw-r--r--src/libspudec/xine_decoder.c19
3 files changed, 66 insertions, 59 deletions
diff --git a/src/libspudec/spu.c b/src/libspudec/spu.c
index dafdca000..8f7356052 100644
--- a/src/libspudec/spu.c
+++ b/src/libspudec/spu.c
@@ -35,7 +35,7 @@
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: spu.c,v 1.37 2002/04/23 23:46:23 jcdutton Exp $
+ * $Id: spu.c,v 1.38 2002/04/24 13:42:17 jcdutton Exp $
*
*/
@@ -74,7 +74,6 @@ void spudec_copy_nav_to_overlay(pci_t* nav_pci, uint32_t* clut, int32_t button,
static void spudec_do_commands (spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl);
static void spudec_draw_picture (spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl);
static void spudec_discover_clut (spudec_state_t *state, vo_overlay_t *ovl);
-static void spudec_update_menu (spudec_state_t *state, vo_overlay_t *ovl);
static void spudec_print_overlay( vo_overlay_t *overlay );
void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) {
@@ -146,8 +145,10 @@ void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) {
}
}
if (pci.hli.hl_gi.hli_ss == 1) {
+ pthread_mutex_lock(&this->nav_pci_lock);
xine_fast_memcpy(&this->pci, &pci, sizeof(pci_t));
this->button_filter=1;
+ pthread_mutex_unlock(&this->nav_pci_lock);
/*******************************
* We should do something about fosl_btnn, but
* until we can send the info to dvdnav, ignore it.
@@ -158,8 +159,10 @@ void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) {
}
if ( (pci.hli.hl_gi.hli_ss == 0) &&
(this->pci.hli.hl_gi.hli_ss == 1) ) {
+ pthread_mutex_lock(&this->nav_pci_lock);
xine_fast_memcpy(&this->pci, &pci, sizeof(pci_t));
this->button_filter=0;
+ pthread_mutex_unlock(&this->nav_pci_lock);
/* Hide menu spu between menus */
printf("libspudec:nav:SHOULD HIDE SPU here\n");
if( this->menu_handle < 0 ) {
@@ -173,8 +176,18 @@ void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) {
it yet and we cannot provide correct vpts values. use current_time
instead as an aproximation.
*/
- //this->event.vpts = metronom->got_spu_packet(metronom, pci.pci_gi.vobu_s_ptm, 0);
- this->event.vpts = 0;
+ this->event.vpts = metronom->got_spu_packet(metronom, pci.pci_gi.vobu_s_ptm, 0);
+ /* Keep all the events in the correct order. */
+ /* This corrects for errors during estimation around discontinuity */
+ if( this->event.vpts < this->last_event_vpts ) {
+ this->event.vpts = this->last_event_vpts + 1;
+ }
+ this->last_event_vpts = this->event.vpts;
+ fprintf(stderr, "libspudec: add_event type=%d : current time=%lld, spu vpts=%lld\n",
+ this->event.event_type,
+ this->xine->metronom->get_current_time(this->xine->metronom),
+ this->event.vpts);
+ assert(this->event.event_type != 2);
ovl_instance->add_event(ovl_instance, (void *)&this->event);
} else {
printf("libspudec: No video_overlay handles left for menu\n");
@@ -242,7 +255,7 @@ void spudec_process (spudec_decoder_t *this, uint32_t stream_id) {
#endif
this->state.cmd_ptr = cur_seq->buf + cur_seq->cmd_offs;
this->state.modified = 1; /* Only draw picture if = 1 on first event of SPU */
- this->state.visible = 0; /* 0 - No value, 1 - Show, 2 - Hide. */
+ this->state.visible = EVENT_SHOW_MENU; /* 0 - No value, 1 - Show, 2 - Hide. */
this->state.forced_display = 0; /* 0 - No value, 1 - Forced Display. */
this->state.delay = 0;
cur_seq->finished=0;
@@ -275,6 +288,7 @@ void spudec_process (spudec_decoder_t *this, uint32_t stream_id) {
/* spudec_print_overlay( &this->overlay ); */
printf ("spu: forced display:%s\n", this->state.forced_display ? "Yes" : "No" );
#endif
+ pthread_mutex_lock(&this->nav_pci_lock);
if (this->pci.hli.hl_gi.hli_s_ptm == this->spudec_stream_state[stream_id].pts) {
if ( this->pci.hli.hl_gi.fosl_btnn > 0) {
spu_button_t spu_button;
@@ -285,6 +299,7 @@ void spudec_process (spudec_decoder_t *this, uint32_t stream_id) {
spu_button.buttonN = this->buttonN;
xine_send_event(this->xine, &spu_event.event);
}
+ fprintf(stderr, "libspudec:Full Overlay\n");
spudec_copy_nav_to_overlay(&this->pci, this->state.clut, this->buttonN, 0, &this->overlay );
} else {
/* Subtitle and not a menu button */
@@ -294,6 +309,8 @@ void spudec_process (spudec_decoder_t *this, uint32_t stream_id) {
this->overlay.clip_trans[i] = this->overlay.trans[i];
}
}
+ pthread_mutex_unlock(&this->nav_pci_lock);
+
if ((this->state.modified) ) {
spudec_draw_picture(&this->state, cur_seq, &this->overlay);
}
@@ -319,9 +336,9 @@ void spudec_process (spudec_decoder_t *this, uint32_t stream_id) {
sizeof(vo_overlay_t));
this->overlay.rle=NULL;
/* For force display menus */
- if ( !(this->state.visible) ) {
- this->state.visible = EVENT_SHOW_MENU;
- }
+ //if ( !(this->state.visible) ) {
+ // this->state.visible = EVENT_SHOW_MENU;
+ //}
this->event.event_type = this->state.visible;
/*
@@ -340,6 +357,19 @@ void spudec_process (spudec_decoder_t *this, uint32_t stream_id) {
+ (this->state.delay*1000);
printf("libspudec: vpts current time estimation around discontinuity\n");
}
+ /* Keep all the events in the correct order. */
+ /* This corrects for errors during estimation around discontinuity */
+ if( this->event.vpts < this->last_event_vpts ) {
+ this->event.vpts = this->last_event_vpts + 1;
+ }
+ this->last_event_vpts = this->event.vpts;
+
+ fprintf(stderr, "libspudec: add_event type=%d : current time=%lld, spu vpts=%lld\n",
+ this->event.event_type,
+ this->xine->metronom->get_current_time(this->xine->metronom),
+ this->event.vpts);
+ assert(this->event.event_type != 2);
+
ovl_instance->add_event(ovl_instance, (void *)&this->event);
} else {
pending = 0;
@@ -390,7 +420,7 @@ static void spudec_do_commands(spudec_state_t *state, spudec_seq_t* seq, vo_over
#ifdef LOG_DEBUG
printf ("spu: \tshow subpicture\n");
#endif
- state->visible = 1;
+ state->visible = EVENT_SHOW_MENU;
buf++;
break;
@@ -398,7 +428,7 @@ static void spudec_do_commands(spudec_state_t *state, spudec_seq_t* seq, vo_over
#ifdef LOG_DEBUG
printf ("spu: \thide subpicture\n");
#endif
- state->visible = 2;
+ state->visible = EVENT_HIDE_MENU;
buf++;
break;
@@ -739,38 +769,7 @@ static void spudec_discover_clut(spudec_state_t *state, vo_overlay_t *ovl)
}
}
-
-static void spudec_update_menu (spudec_state_t *state, vo_overlay_t *ovl) {
-
- if (!state->forced_display)
- return;
-
- if (state->b_show) {
-
- int left = state->b_left;
- int right = state->b_right;
- int top = state->b_top;
- int bottom = state->b_bottom;
-
- if (left < state->o_left) left = state->o_left;
- if (right > state->o_right) right = state->o_right;
- if (top < state->o_top) top = state->o_top;
- if (bottom > state->o_bottom) bottom = state->o_bottom;
-
- ovl->clip_top = top - state->o_top;
- ovl->clip_bottom = bottom - state->o_top;
- ovl->clip_left = left - state->o_left;
- ovl->clip_right = right - state->o_left;
-
- state->visible = 1;
-
- } else {
- state->visible = 0;
- }
-}
-
static void spudec_print_overlay( vo_overlay_t *ovl ) {
-#ifdef LOG_DEBUG
printf ("spu: OVERLAY to show\n");
printf ("spu: \tx = %d y = %d width = %d height = %d\n",
ovl->x, ovl->y, ovl->width, ovl->height );
@@ -780,7 +779,10 @@ static void spudec_print_overlay( vo_overlay_t *ovl ) {
ovl->trans[0], ovl->trans[1], ovl->trans[2], ovl->trans[3]);
printf ("spu: \tclip top=%d bottom=%d left=%d right=%d\n",
ovl->clip_top, ovl->clip_bottom, ovl->clip_left, ovl->clip_right);
-#endif
+ printf ("spu: \tclip_clut [%x %x %x %x]\n",
+ ovl->clip_color[0], ovl->clip_color[1], ovl->clip_color[2], ovl->clip_color[3]);
+ printf ("spu: \tclip_trans [%d %d %d %d]\n",
+ ovl->clip_trans[0], ovl->clip_trans[1], ovl->clip_trans[2], ovl->clip_trans[3]);
return;
}
void spudec_copy_nav_to_overlay(pci_t* nav_pci, uint32_t* clut, int32_t button, int32_t mode, vo_overlay_t * overlay ) {
@@ -796,7 +798,7 @@ void spudec_copy_nav_to_overlay(pci_t* nav_pci, uint32_t* clut, int32_t button,
* }
*/
if((button <= 0) || (button > nav_pci->hli.hl_gi.btn_ns)) {
- printf("libspudec:xine_decoder.c:Unable to select button number %i as it doesn't exist. Forcing button 1",
+ printf("libspudec:xine_decoder.c:Unable to select button number %i as it doesn't exist. Forcing button 1\n",
button);
button = 1;
}
@@ -807,28 +809,21 @@ void spudec_copy_nav_to_overlay(pci_t* nav_pci, uint32_t* clut, int32_t button,
overlay->clip_right = button_ptr->x_end;
overlay->clip_bottom = button_ptr->y_end;
if(button_ptr->btn_coln != 0) {
+ fprintf(stderr, "libspudec: normal button clut\n");
for (i = 0;i < 4; i++) {
overlay->clip_color[i] = clut[0xf & (nav_pci->hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode] >> (16 + 4*i))];
overlay->clip_trans[i] = 0xf & (nav_pci->hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode] >> (4*i));
}
} else {
+ fprintf(stderr, "libspudec: abnormal button clut\n");
for (i = 0;i < 4; i++) {
printf("libspudec:btn_coln = 0, clip_color = color\n");
overlay->clip_color[i] = overlay->color[i];
overlay->clip_trans[i] = overlay->trans[i];
}
}
-/*************************
- printf("libspudec:xine_decode.c:color3=%08x\n",overlay.color[3]);
- printf("libspudec:xine_decode.c:color2=%08x\n",overlay.color[2]);
- printf("libspudec:xine_decode.c:color1=%08x\n",overlay.color[1]);
- printf("libspudec:xine_decode.c:color0=%08x\n",overlay.color[0]);
- printf("libspudec:xine_decode.c:trans3=%08x\n",overlay.trans[3]);
- printf("libspudec:xine_decode.c:trans2=%08x\n",overlay.trans[2]);
- printf("libspudec:xine_decode.c:trans1=%08x\n",overlay.trans[1]);
- printf("libspudec:xine_decode.c:trans0=%08x\n",overlay.trans[0]);
-*************************/
+ /* spudec_print_overlay( overlay ); */
printf("libspudec:xine_decoder.c:NAV to SPU pts match!\n");
}
diff --git a/src/libspudec/spu.h b/src/libspudec/spu.h
index d4f64ea15..f85c16841 100644
--- a/src/libspudec/spu.h
+++ b/src/libspudec/spu.h
@@ -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: spu.h,v 1.13 2002/04/23 21:48:06 jcdutton Exp $
+ * $Id: spu.h,v 1.14 2002/04/24 13:42:17 jcdutton Exp $
*
* This file was originally part of the OMS program.
*
@@ -78,7 +78,6 @@ typedef struct {
int32_t visible; /* Must the sub-picture be shown? */
int32_t forced_display; /* This overlay is a menu */
int32_t delay; /* Delay in 90Khz / 1000 */
- int32_t b_show; /* is a button shown? */
int32_t need_clut; /* doesn't have the right clut yet */
int32_t cur_colors[4];/* current 4 colors been used */
@@ -113,6 +112,8 @@ typedef struct spudec_decoder_s {
pci_t pci;
uint32_t buttonN; /* Current button number for highlights */
int32_t button_filter; /* Allow highlight changes or not */
+ pthread_mutex_t nav_pci_lock;
+ int64_t last_event_vpts;
} spudec_decoder_t;
void spudec_reassembly (spudec_seq_t *seq, uint8_t *pkt_data, u_int pkt_len);
diff --git a/src/libspudec/xine_decoder.c b/src/libspudec/xine_decoder.c
index 28d18d6c0..86f6c001e 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.64 2002/04/23 21:48:06 jcdutton Exp $
+ * $Id: xine_decoder.c,v 1.65 2002/04/24 13:42:17 jcdutton Exp $
*
* stuff needed to turn libspu into a xine decoder plugin
*/
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <assert.h>
#include "buffer.h"
#include "events.h"
@@ -76,12 +77,12 @@ static void spudec_init (spu_decoder_t *this_gen, vo_instance_t *vo_out) {
spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
int i;
+ pthread_mutex_init(&this->nav_pci_lock, NULL);
+
this->vo_out = vo_out;
this->ovl_caps = vo_out->get_capabilities(vo_out);
this->output_open = 0;
-
- this->state.visible = 0;
-
+ this->last_event_vpts = 0;
for (i=0; i < MAX_STREAMS; i++) {
this->spudec_stream_state[i].stream_filter = 1; /* So it works with non-navdvd plugins */
this->spudec_stream_state[i].ra_seq.complete = 1;
@@ -173,6 +174,7 @@ static void spudec_close (spu_decoder_t *this_gen) {
this->spudec_stream_state[i].overlay_handle);
this->spudec_stream_state[i].overlay_handle = -1;
}
+ pthread_mutex_destroy(&this->nav_pci_lock);
}
static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {
@@ -231,19 +233,28 @@ static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {
if (but->show == 2) {
this->button_filter = 2;
}
+ pthread_mutex_lock(&this->nav_pci_lock);
overlay_event->object.handle = this->menu_handle;
overlay_event->object.pts = this->pci.hli.hl_gi.hli_s_ptm;
overlay_event->object.overlay=overlay;
overlay_event->event_type = EVENT_MENU_BUTTON;
+ fprintf(stderr, "libspudec:Button Overlay\n");
spudec_copy_nav_to_overlay(&this->pci, this->state.clut, this->buttonN, but->show-1, overlay );
+ pthread_mutex_unlock(&this->nav_pci_lock);
} else {
fprintf (stderr,"libspudec:xine_decoder.c:spudec_event_listener:HIDE ????\n");
+ assert(0);
overlay_event->object.handle = this->menu_handle;
overlay_event->event_type = EVENT_HIDE_MENU;
}
overlay_event->vpts = 0;
if (this->vo_out) {
ovl_instance = this->vo_out->get_overlay_instance (this->vo_out);
+ fprintf(stderr, "libspudec: add_event type=%d : current time=%lld, spu vpts=%lld\n",
+ overlay_event->event_type,
+ this->xine->metronom->get_current_time(this->xine->metronom),
+ overlay_event->vpts);
+ assert(overlay_event->event_type != 2);
ovl_instance->add_event (ovl_instance, (void *)overlay_event);
} else {
free(overlay_event);