summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dxr3/dxr3_decoder.c4
-rw-r--r--src/libspudec/spu.c356
-rw-r--r--src/libspudec/spu.h77
-rw-r--r--src/libspudec/spu_decoder_api.h4
-rw-r--r--src/libspudec/xine_decoder.c77
5 files changed, 233 insertions, 285 deletions
diff --git a/src/dxr3/dxr3_decoder.c b/src/dxr3/dxr3_decoder.c
index dea84f78f..0a97b63b4 100644
--- a/src/dxr3/dxr3_decoder.c
+++ b/src/dxr3/dxr3_decoder.c
@@ -17,7 +17,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: dxr3_decoder.c,v 1.69 2002/04/04 00:08:36 miguelfreitas Exp $
+ * $Id: dxr3_decoder.c,v 1.70 2002/04/06 15:40:19 jcdutton Exp $
*
* dxr3 video and spu decoder plugin. Accepts the video and spu data
* from XINE and sends it directly to the corresponding dxr3 devices.
@@ -1107,7 +1107,7 @@ static void spudec_event_listener (void *this_gen, xine_event_t *event_gen) {
case XINE_EVENT_SPU_CLUT:
{
- spu_cltbl_t *clut = event->data;
+ spudec_clut_table_t *clut = event->data;
#if LOG_SPU
printf ("dxr3_spu: SPU_CLUT\n");
#endif
diff --git a/src/libspudec/spu.c b/src/libspudec/spu.c
index 0c03d30e2..611195612 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.31 2002/03/25 13:57:25 jcdutton Exp $
+ * $Id: spu.c,v 1.32 2002/04/06 15:40:19 jcdutton Exp $
*
*/
@@ -63,23 +63,18 @@
/*
#define LOG_DEBUG 1
+#define LOG_NAV 1
*/
-/* FIXME: This function needs checking */
-void spudec_reset (spudec_decoder_t *this) {
- int i;
-
- this->ovl_pts = 0;
- this->buf_pts = 0;
-
- this->state.visible = 0;
-
- 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;
- }
-}
+void spudec_reassembly (spudec_seq_t *seq, uint8_t *pkt_data, u_int pkt_len);
+void spudec_process( spudec_decoder_t *this, uint32_t stream_id);
+void spudec_decode_nav( spudec_decoder_t *this, buf_element_t *buf);
+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 );
+static void spudec_copy_nav_to_spu( spudec_decoder_t *this );
void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) {
uint8_t *p;
@@ -110,24 +105,24 @@ void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) {
* printf("\n p[0]=0x%02x\n",p[0]);
*/
if(p[0] == 0x00) {
-#ifdef LOG_DEBUG
+#ifdef LOG_NAV
printf("libspudec:nav_PCI\n");
#endif
nav_read_pci(&pci, p+1);
-#ifdef LOG_DEBUG
- printf("libspudec:nav:hli_ss=%u, hli_s_ptm=%u, hli_e_ptm=%u, btn_sl_e_ptm=%u pts=%u\n",
- pci->hli.hl_gi.hli_ss,
- pci->hli.hl_gi.hli_s_ptm,
- pci->hli.hl_gi.hli_e_ptm,
- pci->hli.hl_gi.btn_se_e_ptm,
+#ifdef LOG_NAV
+ printf("libspudec:nav:hli_ss=%u, hli_s_ptm=%u, hli_e_ptm=%u, btn_sl_e_ptm=%u pts=%llu\n",
+ pci.hli.hl_gi.hli_ss,
+ pci.hli.hl_gi.hli_s_ptm,
+ pci.hli.hl_gi.hli_e_ptm,
+ pci.hli.hl_gi.btn_se_e_ptm,
buf->pts);
printf("libspudec:nav:btn_sn/ofn=%u, btn_ns=%u, fosl_btnn=%u, foac_btnn=%u\n",
- pci->hli.hl_gi.btn_ofn, pci->hli.hl_gi.btn_ns,
- pci->hli.hl_gi.fosl_btnn, pci->hli.hl_gi.foac_btnn);
- printf("btngr_ns %d\n", pci->hli.hl_gi.btngr_ns);
- printf("btngr%d_dsp_ty 0x%02x\n", 1, pci->hli.hl_gi.btngr1_dsp_ty);
- printf("btngr%d_dsp_ty 0x%02x\n", 2, pci->hli.hl_gi.btngr2_dsp_ty);
- printf("btngr%d_dsp_ty 0x%02x\n", 3, pci->hli.hl_gi.btngr3_dsp_ty);
+ pci.hli.hl_gi.btn_ofn, pci.hli.hl_gi.btn_ns,
+ pci.hli.hl_gi.fosl_btnn, pci.hli.hl_gi.foac_btnn);
+ printf("btngr_ns %d\n", pci.hli.hl_gi.btngr_ns);
+ printf("btngr%d_dsp_ty 0x%02x\n", 1, pci.hli.hl_gi.btngr1_dsp_ty);
+ printf("btngr%d_dsp_ty 0x%02x\n", 2, pci.hli.hl_gi.btngr2_dsp_ty);
+ printf("btngr%d_dsp_ty 0x%02x\n", 3, pci.hli.hl_gi.btngr3_dsp_ty);
//navPrint_PCI(&pci);
#endif
@@ -140,7 +135,7 @@ void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) {
if(p[6] == 0x01) {
packet_len = p[4] << 8 | p[5];
p += 6;
-#ifdef LOG_DEBUG
+#ifdef LOG_NAV
printf("NAV DSI packet\n");
#endif
nav_read_dsi(&dsi, p+1);
@@ -177,17 +172,11 @@ void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) {
return;
}
-/* Return value: reassembly complete = 1 */
-int spu_reassembly (spu_seq_t *seq, int start, uint8_t *pkt_data, u_int pkt_len)
+void spudec_reassembly (spudec_seq_t *seq, uint8_t *pkt_data, u_int pkt_len)
{
-#ifdef LOG_DEBUG
- printf ("spu: pkt_len: %d\n", pkt_len);
- printf ("spu: Reassembly: start=%d seq=%p\n", start,seq);
-#endif
-
- if (start) {
- seq->seq_len = (((u_int)pkt_data[0])<<8) | pkt_data[1];
- seq->cmd_offs = (((u_int)pkt_data[2])<<8) | pkt_data[3];
+ if (seq->complete) {
+ seq->seq_len = (((uint32_t)pkt_data[0])<<8) | pkt_data[1];
+ seq->cmd_offs = (((uint32_t)pkt_data[2])<<8) | pkt_data[3];
if (seq->buf_len < seq->seq_len) {
seq->buf_len = seq->seq_len;
@@ -222,23 +211,129 @@ int spu_reassembly (spu_seq_t *seq, int start, uint8_t *pkt_data, u_int pkt_len)
if (seq->ra_offs == seq->seq_len) {
seq->finished = 0;
- return 1; /* sequence ready */
+ seq->complete = 1;
+ return; /* sequence ready */
}
-
- return 0;
+ seq->complete = 0;
+ return;
}
-int spu_next_event(spu_state_t *state, spu_seq_t* seq, int64_t pts)
-{
- uint8_t *buf = state->cmd_ptr;
+void spudec_process (spudec_decoder_t *this, uint32_t stream_id) {
+ spudec_seq_t *cur_seq;
+ video_overlay_instance_t *ovl_instance = this->vo_out->get_overlay_instance (this->vo_out);
+ int pending = 1;
+ cur_seq = &this->spudec_stream_state[stream_id].ra_seq;
- if (state->next_pts == -1) { /* timestamp valid? */
- state->next_pts = seq->pts + ((buf[0] << 8) + buf[1]) * 1024;
- buf += 2;
- state->cmd_ptr = buf;
- }
+#ifdef LOG_DEBUG
+ printf ("spu: Found SPU from stream %d pts=%lld vpts=%lld\n",stream_id,
+ this->spudec_stream_state[stream_id].pts,
+ this->spudec_stream_state[stream_id].vpts);
+#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.forced_display = 0; /* 0 - No value, 1 - Forced Display. */
+ this->state.delay = 0;
+ cur_seq->finished=0;
+
+ do {
+ if (!(cur_seq->finished) ) {
+
+ /* Get do commands to build the event. */
+ spudec_do_commands(&this->state, cur_seq, &this->overlay);
+ /* FIXME: Check for Forced-display or subtitle stream
+ * For subtitles, open event.
+ * For menus, store it for later.
+ */
+ /* spu_channel is now set based on whether we are in the menu or not. */
+ /* Bit 7 is set if only forced display SPUs should be shown */
+ if ( (this->xine->spu_channel & 0x1f) != stream_id ) {
+#ifdef LOG_DEBUG
+ printf ("spu: Dropping SPU channel %d. Not selected stream_id\n", stream_id);
+#endif
+ return;
+ }
+ if ( (this->state.forced_display == 0) && (this->xine->spu_channel & 0x80) ) {
+#ifdef LOG_DEBUG
+ printf ("spu: Dropping SPU channel %d. Only allow forced display SPUs\n", stream_id);
+#endif
+ return;
+ }
+
+#ifdef LOG_DEBUG
+ /* spudec_print_overlay( &this->overlay ); */
+ printf ("spu: forced display:%s\n", this->state.forced_display ? "Yes" : "No" );
+#endif
+ if (this->pci.hli.hl_gi.hli_s_ptm == this->spudec_stream_state[stream_id].pts) {
+ spudec_copy_nav_to_spu(this);
+ } else {
+ /* Subtitle and not a menu button */
+ int i;
+ for (i = 0;i < 4; i++) {
+ this->overlay.clip_color[i] = this->overlay.color[i];
+ this->overlay.clip_trans[i] = this->overlay.trans[i];
+ }
+ }
+
+ if ( !(this->overlay.trans[0] | this->overlay.trans[1] | this->overlay.trans[2] | this->overlay.trans[3] |
+ this->overlay.clip_trans[0] | this->overlay.clip_trans[1] | this->overlay.clip_trans[2] | this->overlay.clip_trans[3]) ) {
+ /* SPU is transparent so why bother displaying it. */
+ printf ("spu: transparent spu found, discarding it.\n" );
+ return;
+ }
+
+ if ((this->state.modified) ) {
+ spudec_draw_picture(&this->state, cur_seq, &this->overlay);
+ }
+
+ if (this->state.need_clut) {
+ spudec_discover_clut(&this->state, &this->overlay);
+ }
+
+ /* Subtitle */
+ if( this->menu_handle < 0 ) {
+ this->menu_handle = ovl_instance->get_handle(ovl_instance,1);
+ }
+
+ if( this->menu_handle < 0 ) {
+ printf("libspudec: No video_overlay handles left for menu\n");
+ return;
+ }
+ this->event.object.handle = this->menu_handle;
+ this->event.object.pts = this->spudec_stream_state[stream_id].pts;
+
+ xine_fast_memcpy(this->event.object.overlay,
+ &this->overlay,
+ sizeof(vo_overlay_t));
+ this->overlay.rle=NULL;
+ /* For force display menus */
+ if ( !(this->state.visible) ) {
+ this->state.visible = EVENT_SHOW_SPU;
+ }
+
+ this->event.event_type = this->state.visible;
+ /*
+ printf("spu event %d handle: %d vpts: %d\n", this->event.event_type,
+ this->event.object.handle, this->event.vpts );
+ */
+
+ /* if !vpts then we are near a discontinuity but video_out havent detected
+ it yet and we cannot provide correct vpts values. use current_time
+ instead as an aproximation.
+ */
+ if( this->spudec_stream_state[stream_id].vpts ) {
+ this->event.vpts = this->spudec_stream_state[stream_id].vpts+(this->state.delay*1000);
+ } else {
+ this->event.vpts = this->xine->metronom->get_current_time(this->xine->metronom)
+ + (this->state.delay*1000);
+ printf("libspudec: vpts current time estimation around discontinuity\n");
+ }
+ ovl_instance->add_event(ovl_instance, (void *)&this->event);
+ } else {
+ pending = 0;
+ }
+ } while (pending);
- return state->next_pts <= pts;
}
#define CMD_SPU_FORCE_DISPLAY 0x00
@@ -251,13 +346,13 @@ int spu_next_event(spu_state_t *state, spu_seq_t* seq, int64_t pts)
#define CMD_SPU_WIPE 0x07 /* Not currently implemented */
#define CMD_SPU_EOF 0xff
-void spu_do_commands(spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl)
+static void spudec_do_commands(spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl)
{
uint8_t *buf = state->cmd_ptr;
uint8_t *next_seq;
#ifdef LOG_DEBUG
- printf ("spu: SPU EVENT\n");
+ printf ("spu: SPU DO COMMANDS\n");
#endif
state->delay = (buf[0] << 8) + buf[1];
@@ -266,6 +361,9 @@ void spu_do_commands(spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl)
#endif
next_seq = seq->buf + (buf[2] << 8) + buf[3];
buf += 4;
+#ifdef LOG_DEBUG
+ printf ("spu: \tnext_seq=%d\n",next_seq - seq->buf);
+#endif
/* if next equals current, this is the last one
*/
@@ -293,7 +391,7 @@ void spu_do_commands(spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl)
break;
case CMD_SPU_SET_PALETTE: { /* CLUT */
- spu_clut_t *clut = (spu_clut_t *) (buf+1);
+ spudec_clut_t *clut = (spudec_clut_t *) (buf+1);
state->cur_colors[3] = clut->entry0;
state->cur_colors[2] = clut->entry1;
@@ -323,7 +421,7 @@ void spu_do_commands(spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl)
break;
}
case CMD_SPU_SET_ALPHA: { /* transparency palette */
- spu_clut_t *trans = (spu_clut_t *) (buf+1);
+ spudec_clut_t *trans = (spudec_clut_t *) (buf+1);
/* This should go into state for now */
ovl->trans[3] = trans->entry0;
@@ -392,7 +490,7 @@ void spu_do_commands(spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl)
#ifdef LOG_DEBUG
printf ("spu: \tForce Display/Menu\n");
#endif
- state->menu = 1;
+ state->forced_display = 1;
buf++;
break;
@@ -405,14 +503,11 @@ void spu_do_commands(spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl)
if (next_seq >= seq->buf + seq->seq_len)
seq->finished = 1; /* last sub-sequence */
- state->next_pts = -1; /* invalidate timestamp */
-
-
state->cmd_ptr = next_seq;
}
-
+/* FIXME: Get rid of all these static values */
static uint8_t *bit_ptr[2];
static int field; // which field we are currently decoding
static int put_x, put_y;
@@ -445,7 +540,7 @@ static u_int get_bits (u_int bits)
return ret;
}
-static int spu_next_line (vo_overlay_t *spu)
+static int spudec_next_line (vo_overlay_t *spu)
{
get_bits (0); // byte align rle data
@@ -462,7 +557,7 @@ static int spu_next_line (vo_overlay_t *spu)
return 0;
}
-void spu_draw_picture (spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl)
+static void spudec_draw_picture (spudec_state_t *state, spudec_seq_t* seq, vo_overlay_t *ovl)
{
rle_elem_t *rle;
field = 0;
@@ -488,7 +583,7 @@ void spu_draw_picture (spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl)
printf ("spu: MALLOC1: ovl->rle %p, len=%d\n", ovl->rle,ovl->data_size);
#endif
if (ovl->rle) {
- printf ("libspudec: spu_draw_picture: ovl->rle is not empty!!!! It should be!!! You should never see this message.\n");
+ printf ("libspudec: spudec_draw_picture: ovl->rle is not empty!!!! It should be!!! You should never see this message.\n");
free(ovl->rle);
ovl->rle=NULL;
}
@@ -530,7 +625,7 @@ void spu_draw_picture (spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl)
put_x += len;
if (put_x >= ovl->width) {
- if (spu_next_line (ovl) < 0)
+ if (spudec_next_line (ovl) < 0)
break;
}
}
@@ -551,7 +646,7 @@ void spu_draw_picture (spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl)
MINFOUND is the number of ocurrences threshold.
*/
#define MINFOUND 20
-void spu_discover_clut(spu_state_t *state, vo_overlay_t *ovl)
+static void spudec_discover_clut(spudec_state_t *state, vo_overlay_t *ovl)
{
int bg,c;
int seqcolor[10];
@@ -633,9 +728,9 @@ void spu_discover_clut(spu_state_t *state, vo_overlay_t *ovl)
}
-void spu_update_menu (spu_state_t *state, vo_overlay_t *ovl) {
+static void spudec_update_menu (spudec_state_t *state, vo_overlay_t *ovl) {
- if (!state->menu)
+ if (!state->forced_display)
return;
if (state->b_show) {
@@ -662,7 +757,7 @@ void spu_update_menu (spu_state_t *state, vo_overlay_t *ovl) {
}
}
-void spudec_print_overlay( vo_overlay_t *ovl ) {
+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",
@@ -676,7 +771,7 @@ void spudec_print_overlay( vo_overlay_t *ovl ) {
#endif
return;
}
-void spudec_copy_nav_to_spu(spudec_decoder_t *this) {
+static void spudec_copy_nav_to_spu(spudec_decoder_t *this) {
int button;
btni_t *button_ptr;
int i;
@@ -727,126 +822,5 @@ void spudec_copy_nav_to_spu(spudec_decoder_t *this) {
}
-void spu_process (spudec_decoder_t *this, uint32_t stream_id) {
- spu_seq_t *cur_seq;
- video_overlay_instance_t *ovl_instance = this->vo_out->get_overlay_instance (this->vo_out);
- int pending = 1;
- cur_seq = &this->spu_stream_state[stream_id].ra_seq;
-
-/* FIXME:Get Handle after we have found if "Forced display" is set or not.
- */
-
-#ifdef LOG_DEBUG
- printf ("spu: Found SPU from stream %d pts=%d vpts=%d\n",stream_id,
- this->spu_stream_state[stream_id].pts,
- this->spu_stream_state[stream_id].vpts);
-#endif
- this->state.cmd_ptr = cur_seq->buf + cur_seq->cmd_offs;
- this->state.next_pts = -1; /* invalidate timestamp */
- 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.menu = 0; /* 0 - No value, 1 - Forced Display. */
- this->state.delay = 0;
- cur_seq->finished=0;
-
- do {
- if (!(cur_seq->finished) ) {
-
- /* Get do commands to build the event. */
- spu_do_commands(&this->state, cur_seq, &this->overlay);
- /* FIXME: Check for Forced-display or subtitle stream
- * For subtitles, open event.
- * For menus, store it for later.
- */
- /* spu_channel is now set based on whether we are in the menu or not. */
- /* Bit 7 is set if only forced display SPUs should be shown */
- if ( (this->xine->spu_channel & 0x1f) != stream_id ) {
-#ifdef LOG_DEBUG
- printf ("spu: Dropping SPU channel %d. Not selected stream_id\n", stream_id);
-#endif
- return;
- }
- if ( (this->state.menu == 0) && (this->xine->spu_channel & 0x80) ) {
-#ifdef LOG_DEBUG
- printf ("spu: Dropping SPU channel %d. Only allow forced display SPUs\n", stream_id);
-#endif
- return;
- }
-
-#ifdef LOG_DEBUG
- /* spudec_print_overlay( &this->overlay ); */
- printf ("spu: forced display:%s\n", this->state.menu ? "Yes" : "No" );
-#endif
- if (this->pci.hli.hl_gi.hli_s_ptm == this->spu_stream_state[stream_id].pts) {
- spudec_copy_nav_to_spu(this);
- } else {
- /* Subtitle and not a menu button */
- int i;
- for (i = 0;i < 4; i++) {
- this->overlay.clip_color[i] = this->overlay.color[i];
- this->overlay.clip_trans[i] = this->overlay.trans[i];
- }
- }
-
- if ( !(this->overlay.trans[0] | this->overlay.trans[1] | this->overlay.trans[2] | this->overlay.trans[3] |
- this->overlay.clip_trans[0] | this->overlay.clip_trans[1] | this->overlay.clip_trans[2] | this->overlay.clip_trans[3]) ) {
- /* SPU is transparent so why bother displaying it. */
- printf ("spu: transparent spu found, discarding it.\n" );
- return;
- }
-
- if ((this->state.modified) ) {
- spu_draw_picture(&this->state, cur_seq, &this->overlay);
- }
-
- if (this->state.need_clut) {
- spu_discover_clut(&this->state, &this->overlay);
- }
-
- /* Subtitle */
- if( this->menu_handle < 0 ) {
- this->menu_handle = ovl_instance->get_handle(ovl_instance,1);
- }
-
- if( this->menu_handle < 0 ) {
- printf("libspudec: No video_overlay handles left for menu\n");
- return;
- }
- this->event.object.handle = this->menu_handle;
- this->event.object.pts = this->spu_stream_state[stream_id].pts;
-
- xine_fast_memcpy(this->event.object.overlay,
- &this->overlay,
- sizeof(vo_overlay_t));
- this->overlay.rle=NULL;
- /* For force display menus */
- if ( !(this->state.visible) ) {
- this->state.visible = EVENT_SHOW_SPU;
- }
-
- this->event.event_type = this->state.visible;
- /*
- printf("spu event %d handle: %d vpts: %d\n", this->event.event_type,
- this->event.object.handle, this->event.vpts );
- */
-
- /* if !vpts then we are near a discontinuity but video_out havent detected
- it yet and we cannot provide correct vpts values. use current_time
- instead as an aproximation.
- */
- if( this->spu_stream_state[stream_id].vpts ) {
- this->event.vpts = this->spu_stream_state[stream_id].vpts+(this->state.delay*1000);
- } else {
- this->event.vpts = this->xine->metronom->get_current_time(this->xine->metronom)
- + (this->state.delay*1000);
- printf("libspudec: vpts current time estimation around discontinuity\n");
- }
- ovl_instance->add_event(ovl_instance, (void *)&this->event);
- } else {
- pending = 0;
- }
- } while (pending);
-
-}
diff --git a/src/libspudec/spu.h b/src/libspudec/spu.h
index 695deb8a1..f7994ad66 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.10 2002/03/25 13:57:25 jcdutton Exp $
+ * $Id: spu.h,v 1.11 2002/04/06 15:40:19 jcdutton Exp $
*
* This file was originally part of the OMS program.
*
@@ -40,7 +40,7 @@
#define NUM_SEQ_BUFFERS 50
#define MAX_STREAMS 32
-typedef struct spu_clut_struct {
+typedef struct spudec_clut_struct {
#ifdef WORDS_BIGENDIAN
uint8_t entry0 : 4;
uint8_t entry1 : 4;
@@ -52,46 +52,43 @@ typedef struct spu_clut_struct {
uint8_t entry3 : 4;
uint8_t entry2 : 4;
#endif
-} spu_clut_t;
+} spudec_clut_t;
typedef struct {
- uint8_t *buf;
- u_int ra_offs; /* reassembly offset */
- u_int seq_len;
- u_int buf_len;
-
- u_int cmd_offs;
-
- int64_t pts; /* Base PTS of this sequence */
- int finished; /* Has this sequence been finished? */
-} spu_seq_t;
+ uint8_t *buf;
+ uint32_t ra_offs; /* reassembly offset */
+ uint32_t seq_len;
+ uint32_t buf_len;
+ uint32_t cmd_offs;
+ int64_t pts; /* Base PTS of this sequence */
+ int32_t finished; /* Has this control sequence been finished? */
+ uint32_t complete; /* Has this reassembly been finished? */
+} spudec_seq_t;
typedef struct {
uint8_t *cmd_ptr;
- int field_offs[2];
- int b_top, o_top;
- int b_bottom, o_bottom;
- int b_left, o_left;
- int b_right, o_right;
-
- int64_t next_pts; /* pts of next sub-sequence */
- int modified; /* Was the sub-picture modified? */
- int visible; /* Must the sub-picture be shown? */
- int menu; /* This overlay is a menu */
- int delay; /* Delay in 90Khz / 1000 */
- int b_show; /* is a button shown? */
- int need_clut; /* doesn't have the right clut yet */
- int cur_colors[4];/* current 4 colors been used */
+ int32_t field_offs[2];
+ int32_t b_top, o_top;
+ int32_t b_bottom, o_bottom;
+ int32_t b_left, o_left;
+ int32_t b_right, o_right;
+
+ int32_t modified; /* Was the sub-picture modified? */
+ 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 */
uint32_t clut[16];
-} spu_state_t;
+} spudec_state_t;
typedef struct spudec_stream_state_s {
- spu_seq_t ra_seq;
- uint32_t ra_complete;
+ spudec_seq_t ra_seq;
uint32_t stream_filter;
- spu_state_t state;
+ spudec_state_t state;
int64_t vpts;
int64_t pts;
int32_t overlay_handle;
@@ -101,15 +98,13 @@ typedef struct spudec_decoder_s {
spu_decoder_t spu_decoder;
xine_t *xine;
- spudec_stream_state_t spu_stream_state[MAX_STREAMS];
+ spudec_stream_state_t spudec_stream_state[MAX_STREAMS];
video_overlay_event_t event;
video_overlay_object_t object;
int32_t menu_handle;
- int64_t ovl_pts;
- int64_t buf_pts;
- spu_state_t state;
+ spudec_state_t state;
vo_instance_t *vo_out;
vo_overlay_t overlay;
@@ -119,16 +114,8 @@ typedef struct spudec_decoder_s {
uint32_t buttonN; /* Current button number for highlights */
} spudec_decoder_t;
-int spu_reassembly (spu_seq_t *seq, int start, uint8_t *pkt_data, u_int pkt_len);
-int spu_next_event (spu_state_t *state, spu_seq_t* seq, int64_t pts);
-void spu_do_commands (spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl);
-void spu_draw_picture (spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl);
-void spu_discover_clut (spu_state_t *state, vo_overlay_t *ovl);
-void spu_update_menu (spu_state_t *state, vo_overlay_t *ovl);
-void spudec_reset (spudec_decoder_t *this);
-void spudec_print_overlay( vo_overlay_t *overlay );
-void spudec_copy_nav_to_spu( spudec_decoder_t *this );
-void spu_process( spudec_decoder_t *this, uint32_t stream_id);
+void spudec_reassembly (spudec_seq_t *seq, uint8_t *pkt_data, u_int pkt_len);
+void spudec_process( spudec_decoder_t *this, uint32_t stream_id);
void spudec_decode_nav( spudec_decoder_t *this, buf_element_t *buf);
#endif
diff --git a/src/libspudec/spu_decoder_api.h b/src/libspudec/spu_decoder_api.h
index 919457850..fd1c8de9f 100644
--- a/src/libspudec/spu_decoder_api.h
+++ b/src/libspudec/spu_decoder_api.h
@@ -65,8 +65,8 @@ struct spu_button_s {
uint32_t buttonN;
};
-typedef struct spu_cltbl_s spu_cltbl_t;
-struct spu_cltbl_s {
+typedef struct spudec_clut_table_s spudec_clut_table_t;
+struct spudec_clut_table_s {
uint32_t clut[16];
};
diff --git a/src/libspudec/xine_decoder.c b/src/libspudec/xine_decoder.c
index 64cdff773..44e9c1ace 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.58 2002/03/25 13:57:25 jcdutton Exp $
+ * $Id: xine_decoder.c,v 1.59 2002/04/06 15:40:19 jcdutton Exp $
*
* stuff needed to turn libspu into a xine decoder plugin
*/
@@ -34,7 +34,7 @@
#include "buffer.h"
#include "events.h"
#include "xine_internal.h"
-#include "video_out/alphablend.h"
+#include "video_out/alphablend.h" /* For clut_t */
#include "xine-engine/bswap.h"
#include "xineutils.h"
#include "spu.h"
@@ -74,12 +74,20 @@ static int spudec_can_handle (spu_decoder_t *this_gen, int buf_type) {
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;
this->vo_out = vo_out;
this->ovl_caps = vo_out->get_capabilities(vo_out);
this->output_open = 0;
- spudec_reset(this);
+ this->state.visible = 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;
+ 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;
@@ -87,10 +95,10 @@ static void spudec_init (spu_decoder_t *this_gen, vo_instance_t *vo_out) {
static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
uint32_t stream_id;
- spu_seq_t *cur_seq;
+ spudec_seq_t *cur_seq;
spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
stream_id = buf->type & 0x1f ;
- cur_seq = &this->spu_stream_state[stream_id].ra_seq;
+ cur_seq = &this->spudec_stream_state[stream_id].ra_seq;
if (buf->type == BUF_SPU_CLUT) {
printf("libspudec: SPU CLUT\n");
@@ -105,12 +113,13 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
this->state.need_clut = 0;
return;
}
-
+
if (buf->type == BUF_SPU_SUBP_CONTROL) {
+ /* FIXME: I don't think SUBP_CONTROL is used any more */
int i;
uint32_t *subp_control = (uint32_t*) buf->content;
for (i = 0; i < 32; i++) {
- this->spu_stream_state[i].stream_filter = subp_control[i];
+ this->spudec_stream_state[i].stream_filter = subp_control[i];
}
return;
}
@@ -122,28 +131,25 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
return;
}
-
if (buf->decoder_flags & BUF_FLAG_PREVIEW) /* skip preview data */
return;
- if ( this->spu_stream_state[stream_id].stream_filter == 0)
+ if ( this->spudec_stream_state[stream_id].stream_filter == 0)
return;
if (buf->pts) {
metronom_t *metronom = this->xine->metronom;
int64_t vpts = metronom->got_spu_packet(metronom, buf->pts, 0);
- this->spu_stream_state[stream_id].vpts = vpts; /* Show timer */
- this->spu_stream_state[stream_id].pts = buf->pts; /* Required to match up with NAV packets */
+ 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 */
}
- this->spu_stream_state[stream_id].ra_complete =
- spu_reassembly(&this->spu_stream_state[stream_id].ra_seq,
- this->spu_stream_state[stream_id].ra_complete,
+ spudec_reassembly(&this->spudec_stream_state[stream_id].ra_seq,
buf->content,
buf->size);
- if(this->spu_stream_state[stream_id].ra_complete == 1) {
- spu_process(this,stream_id);
+ if(this->spudec_stream_state[stream_id].ra_seq.complete == 1) {
+ spudec_process(this,stream_id);
}
}
@@ -159,10 +165,10 @@ static void spudec_close (spu_decoder_t *this_gen) {
for (i=0; i < MAX_STREAMS; i++) {
- if( this->spu_stream_state[i].overlay_handle >= 0 )
+ if( this->spudec_stream_state[i].overlay_handle >= 0 )
ovl_instance->free_handle(ovl_instance,
- this->spu_stream_state[i].overlay_handle);
- this->spu_stream_state[i].overlay_handle = -1;
+ this->spudec_stream_state[i].overlay_handle);
+ this->spudec_stream_state[i].overlay_handle = -1;
}
}
@@ -178,39 +184,18 @@ static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {
switch (event->event.type) {
case XINE_EVENT_SPU_BUTTON:
{
+ /* This function will move to video_overlay
+ * when video_overlay does menus */
+
video_overlay_event_t *overlay_event = NULL;
vo_overlay_t *overlay = NULL;
spu_button_t *but = event->data;
-#ifdef LOG_DEBUG
- printf ("MALLOC1: overlay_event %p, len=%d\n",
- overlay_event,
- sizeof(video_overlay_event_t));
-#endif
-
overlay_event = xine_xmalloc (sizeof(video_overlay_event_t));
-#ifdef LOG_DEBUG
- printf("MALLOC2: overlay_event %p, len=%d\n",
- overlay_event,
- sizeof(video_overlay_event_t));
-#endif
-
-#ifdef LOG_DEBUG
- printf ("MALLOC1: overlay %p, len=%d\n",
- overlay,
- sizeof(vo_overlay_t));
-#endif
-
overlay = xine_xmalloc (sizeof(vo_overlay_t));
#ifdef LOG_DEBUG
- printf ("MALLOC2: overlay %p, len=%d\n",
- overlay,
- sizeof(vo_overlay_t));
-#endif
-
-#ifdef LOG_DEBUG
printf ("BUTTON\n");
printf ("\tshow=%d\n",but->show);
printf ("\tclut [%x %x %x %x]\n",
@@ -222,7 +207,9 @@ static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {
printf ("\tpts = %u\n",
but->pts );
#endif
- if (!this->state.menu) return;
+ /* FIXME: Watch out for threads. We should really put a lock on this
+ * because events is a different thread than decode_data */
+ if (!this->state.forced_display) return;
#ifdef LOG_DEBUG
printf ("libspudec:xine_decoder.c:spudec_event_listener:this->menu_handle=%u\n",this->menu_handle);
@@ -263,7 +250,7 @@ static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {
case XINE_EVENT_SPU_CLUT:
{
/* FIXME: This function will need checking before it works. */
- spu_cltbl_t *clut = event->data;
+ spudec_clut_table_t *clut = event->data;
if (clut) {
xine_fast_memcpy(this->state.clut, clut->clut, sizeof(uint32_t)*16);
this->state.need_clut = 0;