diff options
| author | James Courtier-Dutton <jcdutton@users.sourceforge.net> | 2002-03-25 13:57:25 +0000 | 
|---|---|---|
| committer | James Courtier-Dutton <jcdutton@users.sourceforge.net> | 2002-03-25 13:57:25 +0000 | 
| commit | 2ce20697979d3765779b59159d44b058d6af9b38 (patch) | |
| tree | 4b0b756f1c8d0a41e628e7e9529f90361eed4a1c | |
| parent | 4b92eb27533df6f0d1aac407dcb03ab46c8b0ccb (diff) | |
| download | xine-lib-2ce20697979d3765779b59159d44b058d6af9b38.tar.gz xine-lib-2ce20697979d3765779b59159d44b058d6af9b38.tar.bz2 | |
Re-organised libspudec to hopefully make it more readable.
CVS patchset: 1632
CVS date: 2002/03/25 13:57:25
| -rw-r--r-- | src/libspudec/spu.c | 347 | ||||
| -rw-r--r-- | src/libspudec/spu.h | 38 | ||||
| -rw-r--r-- | src/libspudec/xine_decoder.c | 414 | ||||
| -rw-r--r-- | src/xine-engine/video_overlay.c | 3 | 
4 files changed, 349 insertions, 453 deletions
| diff --git a/src/libspudec/spu.c b/src/libspudec/spu.c index 382eb7ab9..0c03d30e2 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.30 2002/02/25 23:44:06 jcdutton Exp $ + * $Id: spu.c,v 1.31 2002/03/25 13:57:25 jcdutton Exp $   *   */ @@ -47,17 +47,136 @@  #include <inttypes.h>  #include <malloc.h>  #include <sys/stat.h> +#include <sys/types.h>  #include <fcntl.h>  #include "video_out/alphablend.h"  #include "xineutils.h"  #include "xine_internal.h"  #include "spu.h" +#include "buffer.h" +#include "events.h" +#include "xine-engine/bswap.h" +#include "nav_types.h" +#include "nav_read.h" +#include "nav_print.h"  /*  #define LOG_DEBUG 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_decode_nav(spudec_decoder_t *this, buf_element_t *buf) { +  uint8_t                  *p; +  uint32_t                  packet_len; +  uint32_t                  stream_id; +  uint32_t                  header_len; +  pci_t                     pci; +  dsi_t                     dsi; +  video_overlay_instance_t *ovl_instance = this->vo_out->get_overlay_instance (this->vo_out); + +  p = buf->content; +  if (p[0] || p[1] || (p[2] != 1)) { +    printf("libspudec:spudec_decode_nav:nav demux error! %02x %02x %02x (should be 0x000001) \n",p[0],p[1],p[2]); +    return; +  } + +  packet_len = p[4] << 8 | p[5]; +  stream_id  = p[3]; + +  header_len = 6; +  p += header_len; + +  if (stream_id == 0xbf) { /* Private stream 2 */ +/*   int i; + *   for(i=0;i<80;i++) { + *     printf("%02x ",p[i]); + *   } + *   printf("\n p[0]=0x%02x\n",p[0]); + */ +    if(p[0] == 0x00) { +#ifdef LOG_DEBUG +      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, +       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); +      //navPrint_PCI(&pci);  + +#endif +    } + +    p += packet_len; + +    /* We should now have a DSI packet. */ +    /* We don't need anything from the DSI packet here. */ +    if(p[6] == 0x01) { +      packet_len = p[4] << 8 | p[5]; +      p += 6; +#ifdef LOG_DEBUG +      printf("NAV DSI packet\n");   +#endif +      nav_read_dsi(&dsi, p+1); + +//      self->vobu_start = self->dsi.dsi_gi.nv_pck_lbn; +//      self->vobu_length = self->dsi.dsi_gi.vobu_ea; +    } +  } +  if (pci.hli.hl_gi.hli_ss == 1) { +    xine_fast_memcpy(&this->pci, &pci, sizeof(pci_t)); +  } +  if ( (pci.hli.hl_gi.hli_ss == 0) && +    (this->pci.hli.hl_gi.hli_ss == 1) ) { +    xine_fast_memcpy(&this->pci, &pci, sizeof(pci_t)); +    /* Hide menu spu between menus */ +    printf("libspudec:nav:SHOULD HIDE SPU here\n"); +    if( this->menu_handle < 0 ) { +      this->menu_handle = ovl_instance->get_handle(ovl_instance,1); +    } +    if( this->menu_handle >= 0 ) { +      metronom_t *metronom = this->xine->metronom; +      this->event.object.handle = this->menu_handle; +      this->event.event_type = EVENT_HIDE_SPU; +      /* 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. +      */ +      this->event.vpts = metronom->got_spu_packet(metronom, pci.pci_gi.vobu_s_ptm, 0); +      ovl_instance->add_event(ovl_instance, (void *)&this->event); +    } else { +      printf("libspudec: No video_overlay handles left for menu\n"); +    } +  } +  return; +} +  /* Return value: reassembly complete = 1 */  int spu_reassembly (spu_seq_t *seq, int start, uint8_t *pkt_data, u_int pkt_len)  { @@ -71,21 +190,14 @@ int spu_reassembly (spu_seq_t *seq, int start, uint8_t *pkt_data, u_int pkt_len)      seq->cmd_offs = (((u_int)pkt_data[2])<<8) | pkt_data[3];      if (seq->buf_len < seq->seq_len) { -      if (seq->buf) { +      seq->buf_len = seq->seq_len;  #ifdef LOG_DEBUG -        printf ("spu: FREE1: seq->buf %p\n", seq->buf); +      printf ("spu: MALLOC1: seq->buf %p, len=%d\n", seq->buf,seq->buf_len);  #endif +      if (seq->buf) {          free(seq->buf);          seq->buf = NULL; -#ifdef LOG_DEBUG -        printf ("spu: FREE2: seq->buf %p\n", seq->buf); -#endif        } - -      seq->buf_len = seq->seq_len; -#ifdef LOG_DEBUG -      printf ("spu: MALLOC1: seq->buf %p, len=%d\n", seq->buf,seq->buf_len); -#endif        seq->buf = malloc(seq->buf_len);  #ifdef LOG_DEBUG        printf ("spu: MALLOC2: seq->buf %p, len=%d\n", seq->buf,seq->buf_len); @@ -116,12 +228,12 @@ int spu_reassembly (spu_seq_t *seq, int start, uint8_t *pkt_data, u_int pkt_len)    return 0;	  } -int spu_next_event(spu_state_t *state, spu_seq_t* seq, int pts) +int spu_next_event(spu_state_t *state, spu_seq_t* seq, int64_t pts)  {    uint8_t *buf = state->cmd_ptr;    if (state->next_pts == -1) { /* timestamp valid? */ -    state->next_pts = seq->PTS + ((buf[0] << 8) + buf[1]) * 1024; +    state->next_pts = seq->pts + ((buf[0] << 8) + buf[1]) * 1024;      buf += 2;      state->cmd_ptr = buf;    } @@ -370,22 +482,20 @@ void spu_draw_picture (spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl)   *  ovl->clip_right  = ovl->width - 1;   */ -/*  spu_update_menu(state, ovl); FIXME: What is this for? */ -  /* buffer is believed to be sufficiently large -   * with cmd_offs * 2 * sizeof(rle_elem_t), is that true? */ -//  if (seq->cmd_offs * 2 * sizeof(rle_elem_t) > ovl->data_size) { -//    if (ovl->rle) -//      free(ovl->rle); -    ovl->data_size = seq->cmd_offs * 2 * sizeof(rle_elem_t); +  ovl->data_size = seq->cmd_offs * 2 * sizeof(rle_elem_t);  #ifdef LOG_DEBUG -    printf ("spu: MALLOC1: ovl->rle %p, len=%d\n", ovl->rle,ovl->data_size); +  printf ("spu: MALLOC1: ovl->rle %p, len=%d\n", ovl->rle,ovl->data_size);  #endif -    ovl->rle = malloc(ovl->data_size); +  if (ovl->rle) { +    printf ("libspudec: spu_draw_picture: ovl->rle is not empty!!!! It should be!!! You should never see this message.\n"); +    free(ovl->rle); +    ovl->rle=NULL; +  } +  ovl->rle = malloc(ovl->data_size);  #ifdef LOG_DEBUG -    printf ("spu: MALLOC2: ovl->rle %p, len=%d\n", ovl->rle,ovl->data_size); +  printf ("spu: MALLOC2: ovl->rle %p, len=%d\n", ovl->rle,ovl->data_size);  #endif -//  }    state->modified = 0; /* mark as already processed */    rle = ovl->rle; @@ -551,3 +661,192 @@ void spu_update_menu (spu_state_t *state, vo_overlay_t *ovl) {      state->visible = 0;    }  } + +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 ); +  printf ("spu: \tclut [%x %x %x %x]\n", +	  ovl->color[0], ovl->color[1], ovl->color[2], ovl->color[3]); +  printf ("spu: \ttrans [%d %d %d %d]\n", +	  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 +  return; +}  +void spudec_copy_nav_to_spu(spudec_decoder_t *this) { +  int button; +  btni_t *button_ptr; +  int i; + +  button = this->buttonN; +  /* FIXME: Need to communicate with dvdnav vm to get/set  +    "self->vm->state.HL_BTNN_REG" info.  +    now done via button events from dvdnav. +   */ +  if ( this->pci.hli.hl_gi.fosl_btnn > 0) { +    button = this->pci.hli.hl_gi.fosl_btnn ; +  } +  if((button <= 0) || (button > this->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", +	      button); +    button = 1; +  } +  /* FIXME:Only the first grouping of buttons are used at the moment */ +  button_ptr = &this->pci.hli.btnit[button-1]; +  this->overlay.clip_left = button_ptr->x_start; +  this->overlay.clip_top  = button_ptr->y_start; +  this->overlay.clip_right = button_ptr->x_end; +  this->overlay.clip_bottom = button_ptr->y_end; +  if(button_ptr->btn_coln != 0) { +    for (i = 0;i < 4; i++) { +      this->overlay.clip_color[i] = this->state.clut[0xf & (this->pci.hli.btn_colit.btn_coli[button_ptr->btn_coln-1][0] >> (16 + 4*i))]; +      this->overlay.clip_trans[i] = 0xf & (this->pci.hli.btn_colit.btn_coli[button_ptr->btn_coln-1][0] >> (4*i)); +    } +  } else { +    for (i = 0;i < 4; i++) { +      printf("libspudec:btn_coln = 0, clip_color = color\n"); +      this->overlay.clip_color[i] = this->overlay.color[i]; +      this->overlay.clip_trans[i] = this->overlay.trans[i]; +    } +  } +/************************* +    printf("libspudec:xine_decode.c:color3=%08x\n",this->overlay.color[3]);  +    printf("libspudec:xine_decode.c:color2=%08x\n",this->overlay.color[2]);  +    printf("libspudec:xine_decode.c:color1=%08x\n",this->overlay.color[1]);  +    printf("libspudec:xine_decode.c:color0=%08x\n",this->overlay.color[0]);  +    printf("libspudec:xine_decode.c:trans3=%08x\n",this->overlay.trans[3]);  +    printf("libspudec:xine_decode.c:trans2=%08x\n",this->overlay.trans[2]);  +    printf("libspudec:xine_decode.c:trans1=%08x\n",this->overlay.trans[1]);  +    printf("libspudec:xine_decode.c:trans0=%08x\n",this->overlay.trans[0]);  +*************************/ + +  printf("libspudec:xine_decoder.c:NAV to SPU pts match!\n"); +   +} + +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 8b62301e3..695deb8a1 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.9 2002/01/06 18:27:47 jcdutton Exp $ + * $Id: spu.h,v 1.10 2002/03/25 13:57:25 jcdutton Exp $   *   * This file was originally part of the OMS program.   * @@ -62,7 +62,7 @@ typedef struct {    u_int    cmd_offs; -  u_int PTS;        /* Base PTS of this sequence */ +  int64_t pts;        /* Base PTS of this sequence */    int finished;     /* Has this sequence been finished? */  } spu_seq_t; @@ -75,7 +75,7 @@ typedef struct {    int b_left,   o_left;    int b_right,  o_right; -  u_int next_pts;   /* pts of next sub-sequence */ +  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 */ @@ -87,21 +87,13 @@ typedef struct {    uint32_t clut[16];  } spu_state_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, int 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); - -  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; +  int64_t          vpts; +  int64_t          pts;    int32_t          overlay_handle;  } spudec_stream_state_t; @@ -109,19 +101,14 @@ typedef struct spudec_decoder_s {    spu_decoder_t    spu_decoder;    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];    video_overlay_event_t      event;    video_overlay_object_t     object;      int32_t          menu_handle; -  spu_seq_t       *ra_seq; -  int              ra_complete; - -  uint32_t         ovl_pts; -  uint32_t         buf_pts; +  int64_t          ovl_pts; +  int64_t          buf_pts;    spu_state_t      state;    vo_instance_t   *vo_out; @@ -132,5 +119,16 @@ 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_decode_nav( spudec_decoder_t *this, buf_element_t *buf);  #endif diff --git a/src/libspudec/xine_decoder.c b/src/libspudec/xine_decoder.c index 98f8947b5..64cdff773 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.57 2002/03/11 12:31:26 guenter Exp $ + * $Id: xine_decoder.c,v 1.58 2002/03/25 13:57:25 jcdutton Exp $   *   * stuff needed to turn libspu into a xine decoder plugin   */ @@ -71,31 +71,6 @@ static int spudec_can_handle (spu_decoder_t *this_gen, int buf_type) {    return (type == BUF_SPU_PACKAGE || type == BUF_SPU_CLUT || type == BUF_SPU_NAV || type == BUF_SPU_SUBP_CONTROL) ;  } -/* FIXME: This function needs checking */ -static void spudec_reset (spudec_decoder_t *this) { -  int i; -   -  this->ovl_pts = 0; -  this->buf_pts = 0; - -  this->state.visible = 0; - -//  this->seq_list[0].finished = 1;   /* mark as cur_seq */ -//  for (i = 1; i < NUM_SEQ_BUFFERS; i++) { -//    this->seq_list[i].finished = 2; /* free for reassembly */ -//  } -  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; -  } - -/* I don't think I need this. -  this->cur_seq = this->ra_seq = this->seq_list; - */ -} - -  static void spudec_init (spu_decoder_t *this_gen, vo_instance_t *vo_out) {    spudec_decoder_t *this = (spudec_decoder_t *) this_gen; @@ -110,339 +85,6 @@ static void spudec_init (spu_decoder_t *this_gen, vo_instance_t *vo_out) {    this->state.need_clut = 1;  } -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 ); -  printf ("spu: \tclut [%x %x %x %x]\n", -	  ovl->color[0], ovl->color[1], ovl->color[2], ovl->color[3]); -  printf ("spu: \ttrans [%d %d %d %d]\n", -	  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 -  return; -}  -static void spudec_copy_nav_to_spu(spudec_decoder_t *this) { -  int button; -  btni_t *button_ptr; -  int i; - -  button = this->buttonN; -  /* FIXME: Need to communicate with dvdnav vm to get/set  -    "self->vm->state.HL_BTNN_REG" info.  -    now done via button events from dvdnav. -   */ -  if ( this->pci.hli.hl_gi.fosl_btnn > 0) { -    button = this->pci.hli.hl_gi.fosl_btnn ; -  } -  if((button <= 0) || (button > this->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", -	      button); -    button = 1; -  } -  /* FIXME:Only the first grouping of buttons are used at the moment */ -  button_ptr = &this->pci.hli.btnit[button-1]; -  this->overlay.clip_left = button_ptr->x_start; -  this->overlay.clip_top  = button_ptr->y_start; -  this->overlay.clip_right = button_ptr->x_end; -  this->overlay.clip_bottom = button_ptr->y_end; -  if(button_ptr->btn_coln != 0) { -    for (i = 0;i < 4; i++) { -      this->overlay.clip_color[i] = this->state.clut[0xf & (this->pci.hli.btn_colit.btn_coli[button_ptr->btn_coln-1][0] >> (16 + 4*i))]; -      this->overlay.clip_trans[i] = 0xf & (this->pci.hli.btn_colit.btn_coli[button_ptr->btn_coln-1][0] >> (4*i)); -    } -  } else { -    for (i = 0;i < 4; i++) { -      printf("libspudec:btn_coln = 0, clip_color = color\n"); -      this->overlay.clip_color[i] = this->overlay.color[i]; -      this->overlay.clip_trans[i] = this->overlay.trans[i]; -    } -  } -/************************* -    printf("libspudec:xine_decode.c:color3=%08x\n",this->overlay.color[3]);  -    printf("libspudec:xine_decode.c:color2=%08x\n",this->overlay.color[2]);  -    printf("libspudec:xine_decode.c:color1=%08x\n",this->overlay.color[1]);  -    printf("libspudec:xine_decode.c:color0=%08x\n",this->overlay.color[0]);  -    printf("libspudec:xine_decode.c:trans3=%08x\n",this->overlay.trans[3]);  -    printf("libspudec:xine_decode.c:trans2=%08x\n",this->overlay.trans[2]);  -    printf("libspudec:xine_decode.c:trans1=%08x\n",this->overlay.trans[1]);  -    printf("libspudec:xine_decode.c:trans0=%08x\n",this->overlay.trans[0]);  -*************************/ - -  printf("libspudec:xine_decoder.c:NAV to SPU pts match!\n"); -   -} - -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; -  video_overlay_instance_t *ovl_instance = this->vo_out->get_overlay_instance (this->vo_out); -  int pending = 1; -  this->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 = this->cur_seq->buf + this->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; -  this->cur_seq->finished=0; -   -  do { -    if (!this->spu_stream_state[stream_id].ra_seq.finished) { -       -      //spudec_nextseq(this); -/* Get do commands to build the event. */ -      spu_do_commands(&this->state, this->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, this->cur_seq, &this->overlay); -      } -       -      if (this->state.need_clut) -        spu_discover_clut(&this->state, &this->overlay); -       -      //if (this->state.menu == 0) { -      if (1) { -        /* 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; - -/*******************************  -        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; -*********************************/  -       -        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; -        /* 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; -        } -*******************************/ -        /* -        printf("spu event %d handle: %d vpts: %d\n", this->event.event_type, -           this->event.object.handle, this->event.vpts );  -        */ -      } else { -        /* Menu */ -        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; -         -        xine_fast_memcpy(this->event.object.overlay,  -               &this->overlay, -               sizeof(vo_overlay_t)); -        this->overlay.rle=NULL; -         -        this->event.event_type = EVENT_MENU_SPU; -        //this->event.event_type = EVENT_SHOW_SPU; -      } -         -      /* 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); - -} - -static void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) { -  uint8_t                  *p; -  uint32_t                  packet_len; -  uint32_t                  stream_id; -  uint32_t                  header_len; -  pci_t                    *pci; -  dsi_t                    *dsi; -  video_overlay_instance_t *ovl_instance = this->vo_out->get_overlay_instance (this->vo_out); - -  p = buf->content; -  if (p[0] || p[1] || (p[2] != 1)) { -    printf("libspudec:spudec_decode_nav:nav demux error! %02x %02x %02x (should be 0x000001) \n",p[0],p[1],p[2]); -    return; -  } -  pci=xine_xmalloc(sizeof(pci_t)); -  dsi=xine_xmalloc(sizeof(dsi_t)); - -  packet_len = p[4] << 8 | p[5]; -  stream_id  = p[3]; - -  header_len = 6; -  p += header_len; - -  if (stream_id == 0xbf) { /* Private stream 2 */ -/*   int i; - *   for(i=0;i<80;i++) { - *     printf("%02x ",p[i]); - *   } - *   printf("\n p[0]=0x%02x\n",p[0]); - */ -    if(p[0] == 0x00) { -#ifdef LOG_DEBUG -      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, -       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); -      //navPrint_PCI(pci);  - -#endif -    } - -    p += packet_len; - -    /* We should now have a DSI packet. */ -    /* We don't need anything from the DSI packet here. */ -    if(p[6] == 0x01) { -      packet_len = p[4] << 8 | p[5]; -      p += 6; -#ifdef LOG_DEBUG -      printf("NAV DSI packet\n");   -#endif -      nav_read_dsi(dsi, p+1); - -//      self->vobu_start = self->dsi.dsi_gi.nv_pck_lbn; -//      self->vobu_length = self->dsi.dsi_gi.vobu_ea; -    } -  } -  if (pci->hli.hl_gi.hli_ss == 1) { -    xine_fast_memcpy(&this->pci, pci, sizeof(pci_t)); -  } -  if ( (pci->hli.hl_gi.hli_ss == 0) && -    (this->pci.hli.hl_gi.hli_ss == 1) ) { -    xine_fast_memcpy(&this->pci, pci, sizeof(pci_t)); -    /* Hide menu spu between menus */ -    printf("libspudec:nav:SHOULD HIDE SPU here\n"); -    if( this->menu_handle < 0 ) { -      this->menu_handle = ovl_instance->get_handle(ovl_instance,1); -    } -    if( this->menu_handle >= 0 ) { -      metronom_t *metronom = this->xine->metronom; -      this->event.object.handle = this->menu_handle; -      this->event.event_type = EVENT_HIDE_SPU; -      /* 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. -      */ -      this->event.vpts = metronom->got_spu_packet(metronom, pci->pci_gi.vobu_s_ptm, 0); -      ovl_instance->add_event(ovl_instance, (void *)&this->event); -    } else { -      printf("libspudec: No video_overlay handles left for menu\n"); -    } -  } -  free(pci); -  free(dsi); -  return; -} - - -  static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {    uint32_t stream_id;    spu_seq_t       *cur_seq; @@ -489,44 +131,18 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {    if (buf->pts) {      metronom_t *metronom = this->xine->metronom; -    uint32_t vpts = metronom->got_spu_packet(metronom, buf->pts, 0); +    int64_t vpts = metronom->got_spu_packet(metronom, buf->pts, 0); -    if (vpts < this->buf_pts) { -      /* FIXME: Don't do this yet,  -         because it will cause all sorts of  -         problems with malloc.  -       */ -      /* spudec_reset(this); */ -    } -      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 */    } -/*  if (this->ra_complete) { -    spu_seq_t *tmp_seq = this->ra_seq + 1; -    if (tmp_seq >= this->seq_list + NUM_SEQ_BUFFERS) -      tmp_seq = this->seq_list; -    if (tmp_seq->finished > 1) { -      this->ra_seq = tmp_seq; -      this->ra_seq->PTS = this->buf_pts;  -    } -  } - */ -  stream_id = buf->type & 0x1f ;    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,                       buf->content,                       buf->size);    if(this->spu_stream_state[stream_id].ra_complete == 1) {  -    /* -     * Testing menus   -     * if(stream_id == 0) { -     * spu_process(this,stream_id); -     * } -     * End testing menus -     */       spu_process(this,stream_id);    }  } @@ -550,24 +166,6 @@ static void spudec_close (spu_decoder_t *this_gen) {    }  } -/* This function is probably not needed now */ -static void spudec_nextseq(spudec_decoder_t* this) { -  spu_seq_t *tmp_seq = this->cur_seq + 1; -/*  if (tmp_seq >= this->seq_list + NUM_SEQ_BUFFERS) -    tmp_seq = this->seq_list; - */ -  -  if (!tmp_seq->finished) { /* is the next seq ready for process? */ -    this->cur_seq->finished = 2; /* ready for reassembly */ -    this->cur_seq = tmp_seq; -    this->state.cmd_ptr = this->cur_seq->buf + this->cur_seq->cmd_offs; -    this->state.next_pts = -1; /* invalidate timestamp */ -    this->state.modified = 1; -    this->state.visible = 0; -    this->state.menu = 0; -  } -} -  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; @@ -577,9 +175,6 @@ static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {      return;    } -  if (this->vo_out) -    ovl_instance = this->vo_out->get_overlay_instance (this->vo_out); -    switch (event->event.type) {    case XINE_EVENT_SPU_BUTTON:      { @@ -659,7 +254,10 @@ static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {          overlay_event->event_type = EVENT_HIDE_MENU;        }        overlay_event->vpts = 0; /* Activate it NOW */ -      ovl_instance->add_event (ovl_instance, (void *)overlay_event); +      if (this->vo_out) { +        ovl_instance = this->vo_out->get_overlay_instance (this->vo_out); +        ovl_instance->add_event (ovl_instance, (void *)overlay_event); +      }      }      break;    case XINE_EVENT_SPU_CLUT: diff --git a/src/xine-engine/video_overlay.c b/src/xine-engine/video_overlay.c index 2101cc455..9efc010be 100644 --- a/src/xine-engine/video_overlay.c +++ b/src/xine-engine/video_overlay.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: video_overlay.c,v 1.17 2002/03/21 16:21:03 miguelfreitas Exp $ + * $Id: video_overlay.c,v 1.18 2002/03/25 13:57:25 jcdutton Exp $   *   */ @@ -445,6 +445,7 @@ static int video_overlay_event( video_overlay_t *this, int64_t vpts ) {            /* If rle is not empty, free it first */            if(overlay->rle) {              free (overlay->rle); +            overlay->rle=NULL;            }  #ifdef LOG_DEBUG  	  printf("video_overlay.c:Menu SPU area is (%u,%u)-(%u,%u), display = 1\n", | 
