diff options
author | Eduard Hasenleithner <ehasenle@users.sourceforge.net> | 2001-08-13 12:52:33 +0000 |
---|---|---|
committer | Eduard Hasenleithner <ehasenle@users.sourceforge.net> | 2001-08-13 12:52:33 +0000 |
commit | da711d47f121b937d2ec4a15a7e607af9f528ce5 (patch) | |
tree | 5857b0175ab090206ca629bd34a8be6d4f6a50fc /src | |
parent | 9c7fc92c6c391b037393721dbe8742ddd260b1d1 (diff) | |
download | xine-lib-da711d47f121b937d2ec4a15a7e607af9f528ce5.tar.gz xine-lib-da711d47f121b937d2ec4a15a7e607af9f528ce5.tar.bz2 |
major rewrite of the subpicture mechanism in order to support menus.
CVS patchset: 416
CVS date: 2001/08/13 12:52:33
Diffstat (limited to 'src')
-rw-r--r-- | src/libspudec/Makefile.am | 3 | ||||
-rw-r--r-- | src/libspudec/spu.c | 485 | ||||
-rw-r--r-- | src/libspudec/spu.h | 41 | ||||
-rw-r--r-- | src/libspudec/spu_decoder_api.h | 18 | ||||
-rw-r--r-- | src/libspudec/xine_decoder.c | 259 | ||||
-rw-r--r-- | src/video_out/alphablend.c | 47 | ||||
-rw-r--r-- | src/xine-engine/events.h | 10 | ||||
-rw-r--r-- | src/xine-engine/load_plugins.c | 4 | ||||
-rw-r--r-- | src/xine-engine/video_out.c | 137 | ||||
-rw-r--r-- | src/xine-engine/video_out.h | 42 | ||||
-rw-r--r-- | src/xine-engine/xine.c | 30 | ||||
-rw-r--r-- | src/xine-engine/xine_internal.h | 4 |
12 files changed, 543 insertions, 537 deletions
diff --git a/src/libspudec/Makefile.am b/src/libspudec/Makefile.am index 578f038d4..9e5d8ca4b 100644 --- a/src/libspudec/Makefile.am +++ b/src/libspudec/Makefile.am @@ -9,7 +9,8 @@ lib_LTLIBRARIES = xineplug_decode_spu.la xineplug_decode_spu_la_SOURCES = spu.c xine_decoder.c xineplug_decode_spu_la_LDFLAGS = -avoid-version -module -noinst_HEADERS = spu.h spu_decoder_api.h +noinst_HEADERS = spu.h +include_HEADERS = spu_decoder_api.h ## ## Install header files (default=$includedir/xine) diff --git a/src/libspudec/spu.c b/src/libspudec/spu.c index f28e74884..8c572bf54 100644 --- a/src/libspudec/spu.c +++ b/src/libspudec/spu.c @@ -65,26 +65,8 @@ #include <sys/stat.h> #include <fcntl.h> -//#include <oms/plugin/output_video.h> // for clut_t #include "spu.h" -static u_int field; // which field we are currently decoding - -#define DISPLAY_INIT - -#define REASSEMBLY_START 0 -#define REASSEMBLY_MID 1 -#define REASSEMBLY_UNNEEDED 2 - -static u_int reassembly_flag = REASSEMBLY_START; - -struct reassembly_s { - uint8_t *buf; - uint8_t *buf_ptr; // actual pointer to still empty buffer - u_int buf_len; - u_int cmd_offset; -} reassembly; - #define LOG_DEBUG 1 #ifdef DEBUG @@ -93,8 +75,168 @@ struct reassembly_s { #define LOG(lvl, fmt...) #endif +void spuInit (void) +{ +} + +/* Return value: reassembly complete = 1 */ +int spuReassembly (spu_seq_t *seq, int start, uint8_t *pkt_data, u_int pkt_len) +{ + LOG (LOG_DEBUG, "pkt_len: %d", pkt_len); + + 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->buf_len < seq->seq_len) { + if (seq->buf) + free(seq->buf); + + seq->buf_len = seq->seq_len; + seq->buf = malloc(seq->buf_len); + } + seq->ra_offs = 0; + + LOG (LOG_DEBUG, "buf_len: %d", seq->buf_len); + LOG (LOG_DEBUG, "cmd_off: %d", seq->cmd_offs); + } + + if (seq->ra_offs < seq->buf_len) { + if (seq->ra_offs + pkt_len > seq->seq_len) + pkt_len = seq->seq_len - seq->ra_offs; + + memcpy (seq->buf + seq->ra_offs, pkt_data, pkt_len); + seq->ra_offs += pkt_len; + } + + if (seq->ra_offs == seq->seq_len) { + seq->finished = 0; + return 1; /* sequence ready */ + } + + return 0; +} + +int spuNextEvent(spu_state_t *state, spu_seq_t* seq, int pts) +{ + uint8_t *buf = state->cmd_ptr; + + if (state->next_pts == -1) { /* timestamp valid? */ + state->next_pts = seq->PTS + ((buf[0] << 8) + buf[1]) * 1100; + buf += 2; + state->cmd_ptr = buf; + } + + return state->next_pts <= pts; +} + +#define CMD_SPU_MENU 0x00 +#define CMD_SPU_SHOW 0x01 +#define CMD_SPU_HIDE 0x02 +#define CMD_SPU_SET_PALETTE 0x03 +#define CMD_SPU_SET_ALPHA 0x04 +#define CMD_SPU_SET_SIZE 0x05 +#define CMD_SPU_SET_PXD_OFFSET 0x06 +#define CMD_SPU_EOF 0xff + +void spuDoCommands(spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl) +{ + uint8_t *buf = state->cmd_ptr; + uint8_t *next_seq; + + next_seq = seq->buf + (buf[0] << 8) + buf[1]; + buf += 2; + + if (state->cmd_ptr >= next_seq) + next_seq = seq->buf + seq->seq_len; /* allow to run until end */ + + state->cmd_ptr = next_seq; + + while (buf < next_seq && *buf != CMD_SPU_EOF) { + switch (*buf) { + case CMD_SPU_SHOW: /* show subpicture */ + LOG (LOG_DEBUG, "\tshow subpicture"); + state->visible = 1; + buf++; + break; + + case CMD_SPU_HIDE: /* hide subpicture */ + LOG (LOG_DEBUG, "\thide subpicture"); + state->visible = 0; + buf++; + break; + + case CMD_SPU_SET_PALETTE: { /* CLUT */ + spu_clut_t *clut = (spu_clut_t *) (buf+1); + + ovl->color[3] = state->clut[clut->entry0]; + ovl->color[2] = state->clut[clut->entry1]; + ovl->color[1] = state->clut[clut->entry2]; + ovl->color[0] = state->clut[clut->entry3]; + LOG (LOG_DEBUG, "\tclut [%x %x %x %x]", + ovl->color[0], ovl->color[1], ovl->color[2], ovl->color[3]); + state->modified = 1; + buf += 3; + break; + } + case CMD_SPU_SET_ALPHA: { /* transparency palette */ + spu_clut_t *trans = (spu_clut_t *) (buf+1); + + /* TODO: bswap32? */ + ovl->trans[3] = trans->entry0; + ovl->trans[2] = trans->entry1; + ovl->trans[1] = trans->entry2; + ovl->trans[0] = trans->entry3; + LOG (LOG_DEBUG, "\ttrans [%d %d %d %d]\n", + ovl->trans[0], ovl->trans[1], ovl->trans[2], ovl->trans[3]); + state->modified = 1; + buf += 3; + break; + } + + case CMD_SPU_SET_SIZE: /* image coordinates */ + state->o_left = (buf[1] << 4) | (buf[2] >> 4); + state->o_right = (((buf[2] & 0x0f) << 8) | buf[3]); + + state->o_top = (buf[4] << 4) | (buf[5] >> 4); + state->o_bottom = (((buf[5] & 0x0f) << 8) | buf[6]); + + LOG (LOG_DEBUG, "\ttop = %d bottom = %d left = %d right = %d", + state->o_left, state->o_right, state->o_top, state->o_bottom); + state->modified = 1; + buf += 7; + break; + + case CMD_SPU_SET_PXD_OFFSET: /* image 1 / image 2 offsets */ + state->field_offs[0] = (((u_int)buf[1]) << 8) | buf[2]; + state->field_offs[1] = (((u_int)buf[3]) << 8) | buf[4]; + LOG (LOG_DEBUG, "\toffset[0] = %d offset[1] = %d", + state->field_offs[0], state->field_offs[1]); + state->modified = 1; + buf += 5; + break; + + case CMD_SPU_MENU: + state->menu = 1; + buf++; + break; + + default: + fprintf(stderr, "libspudec: unknown seqence command (%02x)\n", buf[0]); + buf++; + break; + } + } + if (next_seq >= seq->buf + seq->seq_len) + seq->finished = 1; /* last sub-sequence */ + state->next_pts = -1; /* invalidate timestamp */ +} + +static uint8_t *bit_ptr[2]; +static int field; // which field we are currently decoding +static int put_x, put_y; -static u_int _get_bits (u_int bits, vo_overlay_t *spu) +static u_int get_bits (u_int bits) { static u_int data; static u_int bits_left; @@ -109,7 +251,7 @@ static u_int _get_bits (u_int bits, vo_overlay_t *spu) ret |= data << (bits - bits_left); bits -= bits_left; - data = reassembly.buf[spu->offset[field]++]; + data = *bit_ptr[field]++; bits_left = 8; } else { bits_left -= bits; @@ -122,236 +264,68 @@ static u_int _get_bits (u_int bits, vo_overlay_t *spu) return ret; } - -void spuInit (void) -{ -} - - -static inline void _spu_put_pixel (vo_overlay_t *spu, u_int len, uint8_t colorid) +static inline void spu_put_pixel (vo_overlay_t *spu, int len, uint8_t colorid) { - uint8_t *spu_data_ptr = &spu->data[spu->_x + spu->_y * spu->width]; - - spu->_x += len; - - memset (spu_data_ptr, spu->trans[colorid]<<4 | colorid, len); + memset (spu->data + put_x + put_y * spu->width, colorid, len); + put_x += len; } - -static int _spu_next_line (vo_overlay_t *spu) +static int spu_next_line (vo_overlay_t *spu) { - _get_bits (0, spu); // byte align rle data - - spu->_x = 0; - spu->_y++; - field = (field+1) & 0x01; // Toggle fields + get_bits (0); // byte align rle data - if (spu->_y >= spu->height) { - LOG (LOG_DEBUG, "."); - return -1; - } - return 0; -} - - -// DENT: we need a mechanism here, when having non-linearities (like jumps, ff) - // like pass NULL pkt_data to reset reassembly - -static struct reassembly_s *_reassembly (uint8_t *pkt_data, u_int pkt_len) -{ - LOG (LOG_DEBUG, "pkt_len: %d", pkt_len); - - if (reassembly_flag == REASSEMBLY_UNNEEDED) - reassembly_flag = REASSEMBLY_START; - - if (reassembly_flag == REASSEMBLY_START) { - reassembly.buf_len = (((u_int)pkt_data[0])<<8) | pkt_data[1]; - reassembly.cmd_offset = (((u_int)pkt_data[2])<<8) | pkt_data[3]; - - LOG (LOG_DEBUG, "buf_len: %d", reassembly.buf_len); - LOG (LOG_DEBUG, "cmd_off: %d", reassembly.cmd_offset); - - // the whole spu fits into the supplied packet - if (pkt_len >= reassembly.buf_len) { - reassembly.buf = pkt_data; - reassembly_flag = REASSEMBLY_UNNEEDED; - return &reassembly; - } else { - if (!(reassembly.buf = malloc (reassembly.buf_len + 1))) { - LOG (LOG_DEBUG, "unable to alloc buffer"); - return NULL; - } - reassembly.buf_ptr = reassembly.buf; - - memcpy (reassembly.buf_ptr, pkt_data, pkt_len); - reassembly.buf_ptr += pkt_len; - reassembly_flag = REASSEMBLY_MID; - } - } else { - if ((reassembly.buf_ptr+pkt_len) > (reassembly.buf+reassembly.buf_len)) - pkt_len = reassembly.buf_len - (reassembly.buf_ptr - reassembly.buf); - - - memcpy (reassembly.buf_ptr, pkt_data, pkt_len); - reassembly.buf_ptr += pkt_len; - - if (reassembly.buf_ptr >= (reassembly.buf+reassembly.buf_len)) { - reassembly_flag = REASSEMBLY_START; - return &reassembly; - } - } + put_x = 0; + put_y++; + field ^= 1; // Toggle fields - return NULL; -} - - -#define CMD_SPU_MENU 0x00 -#define CMD_SPU_SHOW 0x01 -#define CMD_SPU_HIDE 0x02 -#define CMD_SPU_SET_PALETTE 0x03 -#define CMD_SPU_SET_ALPHA 0x04 -#define CMD_SPU_SET_SIZE 0x05 -#define CMD_SPU_SET_PXD_OFFSET 0x06 -#define CMD_SPU_EOF 0xff - -/* The time is given as an offset from the presentation time stamp - and it is measured in number of fields. If we play a NTSC movie - the time for each field is 1/(2*29.97) seconds. */ -#define TIME_UNIT 1000*1.0/(2*29.97) - -int spuParseHdr (vo_overlay_t *spu, uint8_t *pkt_data, u_int pkt_len) -{ - struct reassembly_s *reassembly; - uint8_t *buf; - u_int DCSQ_offset, prev_DCSQ_offset = -1; - - if (!(reassembly = _reassembly (pkt_data, pkt_len))) + if (put_y >= spu->height) { + LOG (LOG_DEBUG, "."); return -1; - - buf = reassembly->buf; - DCSQ_offset = reassembly->cmd_offset; - - while (DCSQ_offset != prev_DCSQ_offset) { /* Display Control Sequences */ - u_int i = DCSQ_offset; - - spu->duration = /* Frames + */ ((buf[i] << 8) + buf[i+1]) /* * TIME_UNIT */ ; - LOG (LOG_DEBUG, "duration = %d frames", spu->duration); - i += 2; - - prev_DCSQ_offset = DCSQ_offset; - DCSQ_offset = (buf[i] << 8) + buf[i+1]; - i += 2; - - while (buf[i] != CMD_SPU_EOF) { /* Command Sequence */ - switch (buf[i]) { - case CMD_SPU_SHOW: /* show subpicture */ - LOG (LOG_DEBUG, "\tshow subpicture"); - i++; - break; - - case CMD_SPU_HIDE: /* hide subpicture */ - LOG (LOG_DEBUG, "\thide subpicture"); - i++; - break; - - case CMD_SPU_SET_PALETTE: { /* CLUT */ - spu_clut_t *clut = (spu_clut_t *) &buf[i+1]; - - spu->clut[3] = clut->entry0; - spu->clut[2] = clut->entry1; - spu->clut[1] = clut->entry2; - spu->clut[0] = clut->entry3; - LOG (LOG_DEBUG, "\tclut [%d %d %d %d]", - spu->clut[0], spu->clut[1], spu->clut[2], spu->clut[3]); - i += 3; - break; - } - case CMD_SPU_SET_ALPHA: { /* transparency palette */ - spu_clut_t *trans = (spu_clut_t *) &buf[i+1]; - - spu->trans[3] = trans->entry0; - spu->trans[2] = trans->entry1; - spu->trans[1] = trans->entry2; - spu->trans[0] = trans->entry3; - LOG (LOG_DEBUG, "\ttrans [%d %d %d %d]\n", - spu->trans[0], spu->trans[1], spu->trans[2], spu->trans[3]); - i += 3; - break; - } - - case CMD_SPU_SET_SIZE: /* image coordinates */ - spu->x = (buf[i+1] << 4) | - (buf[i+2] >> 4); - spu->width = (((buf[i+2] & 0x0f) << 8) | - buf[i+3]) - spu->x + 1; /* 1-720 */ - - spu->y = (buf[i+4] << 4) | - (buf[i+5] >> 4); - spu->height = (((buf[i+5] & 0x0f) << 8) - | buf[i+6]) - spu->y + 1; /* 1-576 */ - - if (spu->data) spu->data = (uint8_t *) realloc (spu->data,spu->width * spu->height * sizeof (uint8_t)); - else spu->data = (uint8_t *) malloc (spu->width * spu->height * sizeof (uint8_t)); - - /* Private stuff */ - spu->_x = spu->_y = 0; - LOG (LOG_DEBUG, "\tx = %d y = %d width = %d height = %d", - spu->x, spu->y, spu->width, spu->height); - i += 7; - break; - - case CMD_SPU_SET_PXD_OFFSET: /* image 1 / image 2 offsets */ - spu->offset[0] = (((u_int)buf[i+1]) << 8) | buf[i+2]; - spu->offset[1] = (((u_int)buf[i+3]) << 8) | buf[i+4]; - LOG (LOG_DEBUG, "\toffset[0] = %d offset[1] = %d", - spu->offset[0], spu->offset[1]); - i += 5; - break; - - case CMD_SPU_MENU: - /* - * hardcoded menu clut, uncomment this and comment CMD_SPU_SET_PALETTE and - * CMD_SPU_SET_ALPHA to see the menu buttons - */ - i++; - break; - - default: - LOG (LOG_DEBUG, "invalid sequence in control header (%.2x)", buf[i]); - i++; - break; - } - } - i++; /* lose the CMD_SPU_EOF code (no need to, really) */ - - /* Until we change the interface we parse all 'Command Sequence's - but just overwrite the data in spu. Should be a list instead. */ } - - /* Here we should have a linked list of display commands ready to - be decoded/executed by later calling some spu???() */ - return 0; } - -void spuParseData (vo_overlay_t *spu) +void spuDrawPicture (spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl) { field = 0; - _get_bits (0, spu); /* Reset/init bit code */ - - while ((spu->offset[1] < reassembly.cmd_offset)) { + bit_ptr[0] = seq->buf + state->field_offs[0]; + bit_ptr[1] = seq->buf + state->field_offs[1]; + put_x = put_y = 0; + get_bits (0); /* Reset/init bit code */ + + ovl->x = state->o_left; + ovl->y = state->o_top; + ovl->width = state->o_right - state->o_left; + ovl->height = state->o_bottom - state->o_top; + + ovl->clip_top = 0; + ovl->clip_bottom = ovl->height; + ovl->clip_left = 0; + ovl->clip_right = ovl->width; + + spuUpdateMenu(state, ovl); + + if (ovl->width * ovl->height > ovl->data_size) { + if (ovl->data) + free(ovl->data); + ovl->data_size = ovl->width * ovl->height; + ovl->data = malloc(ovl->data_size); + } + + state->modified = 0; /* mark as already processed */ + + while (bit_ptr[1] < seq->buf + seq->cmd_offs) { u_int len; u_int color; u_int vlc; - vlc = _get_bits (4, spu); + vlc = get_bits (4); if (vlc < 0x0004) { - vlc = (vlc << 4) | _get_bits (4, spu); + vlc = (vlc << 4) | get_bits (4); if (vlc < 0x0010) { - vlc = (vlc << 4) | _get_bits (4, spu); + vlc = (vlc << 4) | get_bits (4); if (vlc < 0x0040) { - vlc = (vlc << 4) | _get_bits (4, spu); + vlc = (vlc << 4) | get_bits (4); } } } @@ -360,26 +334,47 @@ void spuParseData (vo_overlay_t *spu) len = vlc>>2; /* if len == 0 -> end sequence - fill to end of line */ - len = len ? : spu->width - spu->_x; + if (!len) + len = ovl->width - put_x; - _spu_put_pixel (spu, len, color); + spu_put_pixel (ovl, len, color); - if (spu->_x >= spu->width) - if (_spu_next_line (spu) < 0) - goto clean_up; + if (put_x >= ovl->width) + if (spu_next_line (ovl) < 0) + return; } /* Like the eof-line escape, fill the rest of the sp. with background */ - _spu_put_pixel (spu, spu->width - spu->_x, 0); - while (!_spu_next_line (spu)) { - _spu_put_pixel (spu, spu->width - spu->_x, 0); - } + do { + spu_put_pixel (ovl, ovl->width, 0); + } while (!spu_next_line (ovl)); +} - clean_up: - if (reassembly_flag != REASSEMBLY_UNNEEDED) { - LOG (LOG_DEBUG, "freeing reassembly.buf"); - free (reassembly.buf); - } +void spuUpdateMenu (spu_state_t *state, vo_overlay_t *ovl) { + + if (!state->menu) + 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; - reassembly_flag = REASSEMBLY_START; + } else { + state->visible = 0; + } } diff --git a/src/libspudec/spu.h b/src/libspudec/spu.h index 09cfd32ee..6899c7af8 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.2 2001/07/04 20:32:29 uid32519 Exp $ + * $Id: spu.h,v 1.3 2001/08/13 12:52:33 ehasenle Exp $ * * This file was originally part of the OMS program. * @@ -59,11 +59,40 @@ typedef struct spu_clut_struct { #endif } spu_clut_t; +typedef struct { + uint8_t *buf; + u_int ra_offs; /* reassembly offset */ + u_int seq_len; + u_int buf_len; -void spuInit (void); -void decode_spu (u_char *data_start, u_char *data_end); -u_int buffer_spupack (u_int *length, u_char **start, u_char *end); -int spuParseHdr (vo_overlay_t *spu, u_char *pkt_data, u_int pkt_len); -void spuParseData (vo_overlay_t *spu); + u_int cmd_offs; + + u_int PTS; /* Base PTS of this sequence */ + int finished; /* Has this sequence been finished? */ +} spu_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; + + u_int 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 b_show; /* is a button shown? */ + + uint32_t clut[16]; +} spu_state_t; + +int spuReassembly (spu_seq_t *seq, int start, uint8_t *pkt_data, u_int pkt_len); +int spuNextEvent (spu_state_t *state, spu_seq_t* seq, int pts); +void spuDoCommands (spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl); +void spuDrawPicture (spu_state_t *state, spu_seq_t* seq, vo_overlay_t *ovl); +void spuUpdateMenu (spu_state_t *state, vo_overlay_t *ovl); #endif diff --git a/src/libspudec/spu_decoder_api.h b/src/libspudec/spu_decoder_api.h index e30a4cd11..a7d75511a 100644 --- a/src/libspudec/spu_decoder_api.h +++ b/src/libspudec/spu_decoder_api.h @@ -44,6 +44,8 @@ struct spu_decoder_s { void (*decode_data) (spu_decoder_t *this, buf_element_t *buf); + void (*event) (spu_decoder_t *this, spu_event_t *event); + void (*close) (spu_decoder_t *this); char* (*get_identifier) (void); @@ -70,4 +72,20 @@ struct spudec_s { }; +#define SPU_EVENT_BUTTON 0x100 +typedef struct spu_button_s spu_button_t; +struct spu_button_s { + int show; + uint8_t color[4]; + uint8_t trans[4]; + int left, right; + int top, bottom; +}; + +#define SPU_EVENT_CLUT 0x101 +typedef struct spu_cltbl_s spu_cltbl_t; +struct spu_cltbl_s { + uint32_t clut[16]; +}; + #endif /* HAVE_SPUDEC_H */ diff --git a/src/libspudec/xine_decoder.c b/src/libspudec/xine_decoder.c index 406c0cc9d..0d3a0836d 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.7 2001/08/05 08:24:56 ehasenle Exp $ + * $Id: xine_decoder.c,v 1.8 2001/08/13 12:52:33 ehasenle Exp $ * * stuff needed to turn libspu into a xine decoder plugin */ @@ -38,31 +38,48 @@ #include "spu.h" #include "buffer.h" +#include "events.h" #include "xine_internal.h" -#define FRAME_SIZE 4096 - +static clut_t __default_clut[] = { + {y: 0x00, cr: 0x80, cb:0x80}, + {y: 0xbf, cr: 0x80, cb:0x80}, + {y: 0x10, cr: 0x80, cb:0x80}, + {y: 0x28, cr: 0x6d, cb:0xef}, + {y: 0x51, cr: 0xef, cb:0x5a}, + {y: 0xbf, cr: 0x80, cb:0x80}, + {y: 0x36, cr: 0x80, cb:0x80}, + {y: 0x28, cr: 0x6d, cb:0xef}, + {y: 0xbf, cr: 0x80, cb:0x80}, + {y: 0x51, cr: 0x80, cb:0x80}, + {y: 0xbf, cr: 0x80, cb:0x80}, + {y: 0x10, cr: 0x80, cb:0x80}, + {y: 0x28, cr: 0x6d, cb:0xef}, + {y: 0x5c, cr: 0x80, cb:0x80}, + {y: 0xbf, cr: 0x80, cb:0x80}, + {y: 0x1c, cr: 0x80, cb:0x80}, + {y: 0x28, cr: 0x6d, cb:0xef} +}; + +#define NUM_SEQ_BUFFERS 5 typedef struct spudec_decoder_s { spu_decoder_t spu_decoder; + ovl_src_t ovl_src; - uint32_t pts; + spu_seq_t seq_list[NUM_SEQ_BUFFERS]; + spu_seq_t *cur_seq; + spu_seq_t *ra_seq; + int ra_complete; - uint8_t frame_buffer[FRAME_SIZE]; - uint8_t *frame_ptr; - int sync_todo; - int frame_length, frame_todo; - uint16_t syncword; + uint32_t ovl_pts; + uint32_t buf_pts; + spu_state_t state; vo_instance_t *vo_out; - vo_overlay_t *spu; - uint32_t *clut; - int spu_caps; - int bypass_mode; - int max_num_channels; - int output_sampling_rate; + vo_overlay_t ovl; + int ovl_caps; int output_open; - int output_mode; } spudec_decoder_t; @@ -71,107 +88,155 @@ int spudec_can_handle (spu_decoder_t *this_gen, int buf_type) { return (type == BUF_SPU_PACKAGE || type == BUF_SPU_CLUT) ; } +static 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 < NUM_SEQ_BUFFERS; i++) { + this->seq_list[i].finished = 1; + } + this->ra_complete = 1; + this->cur_seq = this->ra_seq = this->seq_list; +} + void spudec_init (spu_decoder_t *this_gen, vo_instance_t *vo_out) { spudec_decoder_t *this = (spudec_decoder_t *) this_gen; + this->vo_out = vo_out; - this->spu_caps = vo_out->get_capabilities(vo_out); - this->syncword = 0; - this->sync_todo = 6; + this->ovl_caps = vo_out->get_capabilities(vo_out); this->output_open = 0; -} - -/* overlay_txt is just for test purposes */ -u_int *overlay_txt (vo_overlay_t *spu, float o1) -{ - u_int x, y; - u_char tmp; - /* u_char *clr_ptr1 = (u_char *) img1; */ - u_char *clr_ptr2; - u_char *spu_data_ptr = (u_char *) spu->data; - float o; - - /* don't know why this can happen - but it does happen */ - if ((spu->width <= 0) || (spu->height <= 0) || - (spu->width > 1024) || (spu->height > 1024)) { - fprintf (stderr, "width || height out of range.\n"); - return NULL; - } - - for (y = spu->y; y < (spu->height + spu->y); y++) { - // clr_ptr1 = (u_char *) (img1 + y * 720 + spu->x); - for (x = spu->x; x < (spu->width + spu->x); x++) { - o = ((float) (*spu_data_ptr>>4) / 15.0) * o1; - //clr_ptr2 = (u_char *) &spu_clut[*spu_data_ptr&0x0f]; - *clr_ptr2 = *spu_data_ptr&0x0f; - tmp=*spu_data_ptr; - //printf("%X%X",tmp&0x0f,((tmp>>4)&0x0f)); - spu_data_ptr ++; - - // printf("%d ",(*clr_ptr2++)); - // printf("%d ",(*clr_ptr2++)); - // printf("%d ",(*clr_ptr2++)); - // printf("%d \n",(*clr_ptr2++)); - } - printf("\n"); - } - - return 0; + spudec_reset(this); + memcpy(this->state.clut, __default_clut, sizeof(this->state.clut)); + vo_out->register_ovl_src(vo_out, &this->ovl_src); } void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { spudec_decoder_t *this = (spudec_decoder_t *) this_gen; - uint8_t *current = buf->content; - if (buf->type == BUF_SPU_CLUT) { - if (this->clut == NULL) - this->clut = malloc(sizeof(clut_t)*16); - - memcpy(this->clut, buf->content, sizeof(clut_t)*16); + memcpy(this->state.clut, buf->content, sizeof(int32_t)*16); return; } - - if (!this->spu) { - this->spu = this->vo_out->get_overlay (this->vo_out); - } - /* FIXME: shouldn't happen, but get_overlay function isn't implemented yet */ - if (!this->spu) - return; + if (buf->PTS) { + metronom_t *metronom = this->ovl_src.metronom; + uint32_t pts = metronom->got_spu_packet(metronom, buf->PTS, 0); + if (pts < this->buf_pts) + spudec_reset(this); - this->spu->PTS = buf->PTS; - if (this->clut) - this->spu->clut_tbl = this->clut; - - if (!spuParseHdr (this->spu, current, buf->size)) { - spuParseData (this->spu); - /* overlay_txt(this->spu,1.0); Just for test purposes */ - this->vo_out->queue_overlay (this->vo_out, this->spu); - this->spu = NULL; - } else { - this->spu->data=NULL; - this->vo_out->queue_overlay (this->vo_out, this->spu); - this->spu = NULL; + this->buf_pts = pts; + } + + 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) { + this->ra_seq = tmp_seq; + this->ra_seq->PTS = this->buf_pts; + } } + this->ra_complete = + spuReassembly(this->ra_seq, this->ra_complete, buf->content, buf->size); } void spudec_close (spu_decoder_t *this_gen) { spudec_decoder_t *this = (spudec_decoder_t *) this_gen; + + this->vo_out->unregister_ovl_src(this->vo_out, &this->ovl_src); +} - if (this->clut) { - free(this->clut); - this->clut = 0; +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 = 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 vo_overlay_t* spudec_get_overlay(ovl_src_t *ovl_src, int pts) { + spudec_decoder_t *this = (spudec_decoder_t*) ovl_src->src_gen; + int pending = 0; -/* FIXME not implemented */ -// if (this->output_open) -// this->spu_out->close (this->spu_out); + if (this->ovl_pts > pts) + spudec_reset(this); - /* close (spufile); */ + this->ovl_pts = pts; + + do { + if (this->cur_seq->finished) + spudec_nextseq(this); + + if (!this->cur_seq->finished) { + pending = spuNextEvent(&this->state, this->cur_seq, pts); + + if (pending) + spuDoCommands(&this->state, this->cur_seq, &this->ovl); + } else + pending = 0; + + } while (pending); + + if (this->state.visible) { + if (this->state.modified) { + spuDrawPicture(&this->state, this->cur_seq, &this->ovl); + } + + return &this->ovl; + } + + return NULL; +} + +static void spudec_event(spu_decoder_t *this_gen, spu_event_t *event) { + spudec_decoder_t *this = (spudec_decoder_t*) this_gen; + + switch (event->sub_type) { + case SPU_EVENT_BUTTON: + { + spu_button_t *but = event->data; + if (!this->state.menu) return; + + if (but->show) { + int i; + for (i = 0; i < 4; i++) { + this->ovl.color[i] = this->state.clut[but->color[i]]; + this->ovl.trans[i] = but->trans[i]; + } + + this->state.b_left = but->left; + this->state.b_right = but->right; + this->state.b_top = but->top; + this->state.b_bottom = but->bottom; + } + + this->state.b_show = but->show; + spuUpdateMenu(&this->state, &this->ovl); + } + break; + case SPU_EVENT_CLUT: + { + spu_cltbl_t *clut = event->data; + memcpy(this->state.clut, clut->clut, sizeof(int32_t)*16); + } + break; + } } static char *spudec_get_id(void) { @@ -182,18 +247,28 @@ spu_decoder_t *init_spu_decoder_plugin (int iface_version, config_values_t *cfg) spudec_decoder_t *this ; - if (iface_version != 2) + if (iface_version != 3) { + fprintf(stderr, + "libspudec: Doesn't support plugin API version %d.\n" + "libspudec: This means there is a version mismatch between XINE and\n" + "libspudec: this plugin.\n", iface_version); return NULL; + } this = (spudec_decoder_t *) malloc (sizeof (spudec_decoder_t)); + memset (this, 0, sizeof(*this)); - this->spu_decoder.interface_version = 2; + this->spu_decoder.interface_version = 3; this->spu_decoder.can_handle = spudec_can_handle; this->spu_decoder.init = spudec_init; this->spu_decoder.decode_data = spudec_decode_data; + this->spu_decoder.event = spudec_event; this->spu_decoder.close = spudec_close; 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; return (spu_decoder_t *) this; } diff --git a/src/video_out/alphablend.c b/src/video_out/alphablend.c index e0d6c075e..b8a540b2a 100644 --- a/src/video_out/alphablend.c +++ b/src/video_out/alphablend.c @@ -138,10 +138,10 @@ void blend_tux_rgb16 (uint8_t * img, int dst_width, int dst_height) for (y=0; y<img_overl->height; y++) { \ dst += img_overl->x; \ for (x=0; x<img_overl->width; x++) { \ - o = img_overl->trans[*src&0x0f]; \ + o = img_overl->trans[*src]; \ \ - if ((*src) >> 4 & 0xf) /* if alpha is != 0 */ \ - *dst = blendpixel_rgb##bpp (*dst, myclut[img_overl->clut[(*src&0x0f)]], o); \ + if (o) /* if alpha is != 0 */ \ + *dst = blendpixel_rgb##bpp (*dst, myclut[*src], o); \ src++; \ dst++; \ } \ @@ -256,9 +256,10 @@ static clut_t __default_clut[] = { }; void blend_yuv (uint8_t * dst_img, vo_overlay_t * img_overl, - int dst_width, int dst_height) + int dst_width, int dst_height) { clut_t *my_clut; + uint8_t *my_trans; int src_width = img_overl->width; int src_height = img_overl->height; @@ -275,36 +276,36 @@ void blend_yuv (uint8_t * dst_img, vo_overlay_t * img_overl, int x, y; - /* If there is a CLUT palette specified, use it instead. */ - if(img_overl->clut_tbl != NULL) { - my_clut = (clut_t*)img_overl->clut_tbl; - } else { - my_clut = __default_clut; - } + my_clut = (clut_t*) img_overl->color; + my_trans = img_overl->trans; for (y = 0; y < src_height; y++) { for (x = 0; x < src_width; x++) { uint8_t clr; - uint8_t mask; uint16_t o; - mask = (*src_data) >> 4 ; + clr = *src_data & 3; + o = my_trans[clr]; + + /* OK, this looks time consuming. + * But it gets only evaluated if (o != 0) */ + if (o) if (img_overl->clip_left > x || + img_overl->clip_right <= x || + img_overl->clip_top > y || + img_overl->clip_bottom <= y) + o = 0; - clr = img_overl->clut[*src_data & 0x03]; - o = img_overl->trans[*src_data & 0x03]; - if(o) - *dst_y = BLEND_YUV (*dst_y, my_clut[clr].y, o); + if (o) + *dst_y = BLEND_YUV (*dst_y, my_clut[clr].y, o); dst_y++; if (y & x & 1) { - if (mask) { - if(o) { - *dst_cr = BLEND_YUV (*dst_cr, my_clut[clr].cr, o); - *dst_cb = BLEND_YUV (*dst_cb, my_clut[clr].cb, o); - } + if(o) { + *dst_cr = BLEND_YUV (*dst_cr, my_clut[clr].cr, o); + *dst_cb = BLEND_YUV (*dst_cb, my_clut[clr].cb, o); } - dst_cr++; - dst_cb++; + dst_cr++; + dst_cb++; } src_data++; } diff --git a/src/xine-engine/events.h b/src/xine-engine/events.h index 19db8b618..a1ec552f5 100644 --- a/src/xine-engine/events.h +++ b/src/xine-engine/events.h @@ -63,6 +63,16 @@ typedef struct overlay_event_s { vo_overlay_t overlay; } overlay_event_t; +/** + * SPU event - send control events to the spu decoder + */ +#define XINE_SPU_EVENT 0x0003 +typedef struct spu_event_s { + event_t event; + int sub_type; + void *data; +} spu_event_t; + #ifdef __cplusplus } #endif diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c index d15622143..3e18c944b 100644 --- a/src/xine-engine/load_plugins.c +++ b/src/xine-engine/load_plugins.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: load_plugins.c,v 1.35 2001/07/30 17:13:22 guenter Exp $ + * $Id: load_plugins.c,v 1.36 2001/08/13 12:52:33 ehasenle Exp $ * * * Load input/demux/audio_out/video_out/codec plugins @@ -371,7 +371,7 @@ void load_decoder_plugins (xine_t *this, spu_decoder_t *sdp; int streamtype; - sdp = (spu_decoder_t *) initplug(iface_version, config); + sdp = (spu_decoder_t *) initplug(3, config); if (sdp) { sdp->metronom = this->metronom; diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c index 1a01d8cc6..93f6766de 100644 --- a/src/xine-engine/video_out.c +++ b/src/xine-engine/video_out.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_out.c,v 1.38 2001/08/05 08:24:56 ehasenle Exp $ + * $Id: video_out.c,v 1.39 2001/08/13 12:52:33 ehasenle Exp $ * */ @@ -140,8 +140,6 @@ static void *video_out_loop (void *this_gen) { uint32_t cur_pts; int pts_absdiff, diff, absdiff, pts=0; vo_frame_t *img; - vo_overlay_t *overlay; - int count; uint32_t video_step, video_step_new; vo_instance_t *this = (vo_instance_t *) this_gen; sigset_t vo_mask; @@ -276,65 +274,19 @@ static void *video_out_loop (void *this_gen) { xprintf (VERBOSE|VIDEO, "video_out : passing to video driver, image with pts = %d\n", pts); - - overlay=this->first_overlay; - while (overlay) { - if(overlay->state==OVERLAY_SHOWING) { - if (this->driver->overlay_blend) this->driver->overlay_blend (this->driver, img, overlay); - } - overlay=overlay->next; + if (this->overlay_source) { + /* This is the only way for the spu decoder to get pts values + * for flushing it's buffers. So don't remove it! */ + vo_overlay_t *ovl = + this->overlay_source->get_overlay (this->overlay_source, img->PTS); + if (ovl && this->driver->overlay_blend) + this->driver->overlay_blend (this->driver, img, ovl); } this->driver->display_frame (this->driver, img); - /* Control Overlay SHOW/HIDE based on PTS */ - overlay=this->first_overlay; - count=1; - while (overlay) { - switch(overlay->state) { - case OVERLAY_FREE: - break; - case OVERLAY_CREATING: - break; - case OVERLAY_READY_TO_SHOW: - if (cur_pts>overlay->PTS) overlay->state=OVERLAY_SHOWING; - if (abs(cur_pts-overlay->PTS) > pts_absdiff ) overlay->state=OVERLAY_READY_TO_FREE; - break; - case OVERLAY_SHOWING: - /* duration is in frames, Who knows why div 4 ? */ - if ((cur_pts>overlay->PTS+(overlay->duration*video_step/4))) overlay->state=OVERLAY_READY_TO_FREE; - break; - case OVERLAY_READY_TO_FREE: - /* remove overlay from list */ - if (overlay->next) { - if (overlay->priv) - overlay->priv->next=overlay->next; - else - this->first_overlay=overlay->next; - overlay->next->priv=overlay->priv; - } else { - overlay->state=OVERLAY_FREE; - break; - } - /* Set status to free */ - overlay->state=OVERLAY_FREE; - /* Insert at end of list */ - overlay->priv=this->last_overlay; - this->last_overlay->next=overlay; - overlay->next=NULL; - this->last_overlay=overlay; - break; - default: - printf("OVERLAY in UNKNOWN state\n"); - } - overlay=overlay->next; - } - } - - - /* * throw away undisplayed frames */ @@ -365,15 +317,6 @@ static void vo_open (vo_instance_t *this) { if (!this->video_loop_running) { this->video_loop_running = 1; - if(this->first_overlay) { - vo_overlay_t *overlay; - overlay=this->first_overlay; - while (overlay) { - overlay->state=OVERLAY_FREE; - overlay->clut_tbl=NULL; - overlay=overlay->next; - } - } pthread_create (&this->video_thread, NULL, video_out_loop, this) ; printf ("video_out: thread created\n"); @@ -558,57 +501,17 @@ static int vo_frame_draw (vo_frame_t *img) { return frames_to_skip; } -/**************************************************************** - * Current assumption is that only one thread will call vo_get_overlay at a time - * Also mutex locks have not yet been considered or used - * Also, when one is FREEed, it is moved to the end of the queue, so it will be the first one used - * The design is based around a dynamic buffer size. - * The buffer starts at nothing, then increases as needed. - * If a buffer entry is free, it will be reused. - * If all buffers are full, xmalloc is called. - * FIXME: Can someone make this simpler ? It seems a bit long winded to me. - ***************************************************************/ -static vo_overlay_t *vo_get_overlay (vo_instance_t *this) { - vo_overlay_t *next_overlay; - vo_overlay_t *prev_overlay; - int count_overlay=0; - if (this->first_overlay==NULL) { - this->first_overlay = this->last_overlay = xmalloc (sizeof (vo_overlay_t)) ; - this->first_overlay->data=NULL; - this->first_overlay->clut_tbl=NULL; - this->first_overlay->next=NULL; - this->first_overlay->priv=NULL; - this->first_overlay->state=OVERLAY_CREATING; - count_overlay++; - return this->first_overlay; - } - prev_overlay=this->first_overlay; - next_overlay=this->first_overlay->next; - while (next_overlay && (prev_overlay->state!=OVERLAY_FREE)) { - count_overlay++; - prev_overlay=next_overlay; - next_overlay=prev_overlay->next; - } - if (prev_overlay->state==OVERLAY_FREE) { - prev_overlay->state=OVERLAY_CREATING; - return prev_overlay; - } - prev_overlay->next = next_overlay = this->last_overlay = xmalloc (sizeof (vo_overlay_t)) ; - count_overlay++; - next_overlay->data=NULL; - next_overlay->next=NULL; - next_overlay->priv=prev_overlay; - next_overlay->state=OVERLAY_CREATING; - return next_overlay; +static void vo_register_ovl_src (vo_instance_t *this, ovl_src_t *ovl_src) +{ + this->overlay_source = ovl_src; + ovl_src->metronom = this->metronom; } -static void vo_queue_overlay (vo_instance_t *this, vo_overlay_t *overlay) { - overlay->PTS = this->metronom->got_spu_packet (this->metronom, overlay->PTS,overlay->duration); - if (overlay->data==NULL) { - overlay->state=OVERLAY_FREE; - } else { - overlay->state=OVERLAY_READY_TO_SHOW; - } +static void vo_unregister_ovl_src (vo_instance_t *this, ovl_src_t *ovl_src) +{ + /* only remove the source if it is the same as registered */ + if (this->overlay_source == ovl_src) + this->overlay_source = NULL; } vo_instance_t *vo_new_instance (vo_driver_t *driver, metronom_t *metronom) { @@ -617,8 +520,6 @@ vo_instance_t *vo_new_instance (vo_driver_t *driver, metronom_t *metronom) { int i; this = xmalloc (sizeof (vo_instance_t)) ; - this->first_overlay=NULL; - this->last_overlay=NULL; this->driver = driver; this->metronom = metronom; @@ -627,8 +528,8 @@ vo_instance_t *vo_new_instance (vo_driver_t *driver, metronom_t *metronom) { this->close = vo_close; this->exit = vo_exit; this->get_capabilities = vo_get_capabilities; - this->get_overlay = vo_get_overlay; - this->queue_overlay = vo_queue_overlay; + this->register_ovl_src = vo_register_ovl_src; + this->unregister_ovl_src = vo_unregister_ovl_src; this->num_frames_delivered = 0; this->num_frames_skipped = 0; diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h index 0e9c366d8..fbe2b9c60 100644 --- a/src/xine-engine/video_out.h +++ b/src/xine-engine/video_out.h @@ -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_out.h,v 1.15 2001/07/25 23:26:14 richwareham Exp $ + * $Id: video_out.h,v 1.16 2001/08/13 12:52:33 ehasenle Exp $ * * * xine version of video_out.h @@ -95,6 +95,13 @@ struct vo_frame_s { void (*dispose) (vo_frame_t *vo_img); }; +typedef struct ovl_src_s ovl_src_t; + +struct ovl_src_s { + void *src_gen; + vo_overlay_t* (*get_overlay) (ovl_src_t* self, int pts); + metronom_t* metronom; +}; struct vo_instance_s { @@ -119,8 +126,9 @@ struct vo_instance_s { int flags); /* overlay stuff */ - vo_overlay_t* (*get_overlay) (vo_instance_t *this); - void (*queue_overlay) (vo_instance_t *this, vo_overlay_t *overlay); + void (*register_ovl_src) (vo_instance_t *this, ovl_src_t *ovl_src); + void (*unregister_ovl_src) (vo_instance_t *this, ovl_src_t *ovl_src); + ovl_src_t *overlay_source; /* video driver is no longer used by decoder => close */ void (*close) (vo_instance_t *this); @@ -131,8 +139,6 @@ struct vo_instance_s { /* private stuff */ vo_driver_t *driver; - vo_overlay_t *first_overlay; - vo_overlay_t *last_overlay; metronom_t *metronom; img_buf_fifo_t *free_img_buf_queue; @@ -257,34 +263,22 @@ struct vo_driver_s { }; -#define OVERLAY_FREE 0 -#define OVERLAY_CREATING 1 -#define OVERLAY_READY_TO_SHOW 2 -#define OVERLAY_SHOWING 3 -#define OVERLAY_READY_TO_FREE 4 - struct vo_overlay_s { uint8_t *data; /* 7-4: mixer key, 3-0: color index */ + int data_size; /* useful for deciding realloc */ int x; /* x start of subpicture area */ int y; /* y start of subpicture area */ int width; /* width of subpicture area */ int height; /* height of subpicture area */ - uint8_t clut[4]; /* color lookup table */ + uint32_t color[4]; /* color lookup table */ uint8_t trans[4]; /* mixer key table */ - - uint32_t PTS, duration; /* 1/90000 s */ - vo_overlay_t *next; /* optionally more overlays */ - vo_overlay_t *priv; /* optionally more overlays */ - int state; /* State:FREE,SHOWING etc. */ - - uint32_t *clut_tbl; /* Pointer to CLUT palette */ - - /* private stuff */ - int _x; /* current destination x, y */ - int _y; - int offset[2]; /* address in PXD to fetch next rle-code from, one per field */ + int clip_top; + int clip_bottom; + int clip_left; + int clip_right; + }; /* diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 864641e6d..6123aa18d 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.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: xine.c,v 1.39 2001/08/12 15:12:54 guenter Exp $ + * $Id: xine.c,v 1.40 2001/08/13 12:52:33 ehasenle Exp $ * * top-level xine functions * @@ -50,6 +50,7 @@ #include "libw32dll/w32codec.h" #endif #include "libspudec/spu_decoder_api.h" +/* TODO: who uses spu_decoder.h ? */ #include "spu_decoder.h" #include "input/input_plugin.h" #include "metronom.h" @@ -389,29 +390,10 @@ static void event_handler(xine_t *xine, event_t *event, void *data) { } } break; - case XINE_OVERLAY_EVENT: - { - overlay_event_t *oevent = (overlay_event_t*)event; - if(xine->video_out != NULL) { - int i; - vo_overlay_t *overlay = xine->video_out->get_overlay (xine->video_out); - if(overlay != NULL) { - overlay->data = oevent->overlay.data; - overlay->x = oevent->overlay.x; - overlay->y = oevent->overlay.y; - overlay->width = oevent->overlay.width; - overlay->height = oevent->overlay.height; - for(i=0; i<4; i++) { - overlay->clut[i] = oevent->overlay.clut[i]; - overlay->trans[i] = oevent->overlay.trans[i]; - } - overlay->PTS = oevent->overlay.PTS; - overlay->clut_tbl = oevent->overlay.clut_tbl; - overlay->duration = oevent->overlay.duration; - xine->video_out->queue_overlay (xine->video_out, overlay); - } - } - } + case XINE_SPU_EVENT: + if (xine->cur_spu_decoder_plugin) + xine->cur_spu_decoder_plugin->event(xine->cur_spu_decoder_plugin, + (spu_event_t*) event); break; } } diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index 55a4c1ad9..0833438c5 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -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: xine_internal.h,v 1.36 2001/07/30 17:13:22 guenter Exp $ + * $Id: xine_internal.h,v 1.37 2001/08/13 12:52:33 ehasenle Exp $ * */ @@ -36,8 +36,8 @@ extern "C" { #include "audio_out.h" #include "metronom.h" #include "spu_decoder.h" -#include "libspudec/spu_decoder_api.h" #include "events.h" +#include "libspudec/spu_decoder_api.h" #define INPUT_PLUGIN_MAX 50 #define DEMUXER_PLUGIN_MAX 50 |