summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoruid32519 <none@none>2001-07-04 17:10:24 +0000
committeruid32519 <none@none>2001-07-04 17:10:24 +0000
commit507e81ddf0454a0b740a69f69d917ce67075065f (patch)
treed935d772f266ee49a6a73341e1a34afda4b383d8
parentc8d64e87f29e42dc2f6f0068e575dd10188999af (diff)
downloadxine-lib-507e81ddf0454a0b740a69f69d917ce67075065f.tar.gz
xine-lib-507e81ddf0454a0b740a69f69d917ce67075065f.tar.bz2
spu support updated (unfinished) from James
CVS patchset: 250 CVS date: 2001/07/04 17:10:24
-rw-r--r--include/xine.h.tmpl.in6
-rw-r--r--src/demuxers/demux_mpeg.c3
-rw-r--r--src/demuxers/demux_mpeg_block.c17
-rw-r--r--src/libspudec/Makefile.am36
-rw-r--r--src/libspudec/spu.c399
-rw-r--r--src/libspudec/spu.h67
-rw-r--r--src/libspudec/spu_decoder_api.h69
-rw-r--r--src/libspudec/xine_decoder.c184
-rw-r--r--src/video_out/Makefile.am2
-rw-r--r--src/video_out/alphablend.c350
-rw-r--r--src/video_out/alphablend.h39
-rw-r--r--src/video_out/video_out_aa.c8
-rw-r--r--src/video_out/video_out_syncfb.c4
-rw-r--r--src/video_out/video_out_xshm.c14
-rw-r--r--src/video_out/video_out_xv.c55
-rw-r--r--src/xine-engine/Makefile.am8
-rw-r--r--src/xine-engine/load_plugins.c65
-rw-r--r--src/xine-engine/metronom.c3
-rw-r--r--src/xine-engine/metronom.h4
-rw-r--r--src/xine-engine/monitor.h26
-rw-r--r--src/xine-engine/spu_decoder.c99
-rw-r--r--src/xine-engine/spu_decoder.h152
-rw-r--r--src/xine-engine/video_out.c31
-rw-r--r--src/xine-engine/video_out.h38
-rw-r--r--src/xine-engine/xine.c23
-rw-r--r--src/xine-engine/xine_internal.h12
26 files changed, 1562 insertions, 152 deletions
diff --git a/include/xine.h.tmpl.in b/include/xine.h.tmpl.in
index de7f78517..242994d28 100644
--- a/include/xine.h.tmpl.in
+++ b/include/xine.h.tmpl.in
@@ -29,7 +29,7 @@
\endverbatim
*/
/*
- * $Id: xine.h.tmpl.in,v 1.24 2001/06/24 05:30:03 guenter Exp $
+ * $Id: xine.h.tmpl.in,v 1.25 2001/07/04 17:10:24 uid32519 Exp $
*
*/
@@ -128,6 +128,7 @@ struct config_values_s {
typedef struct vo_driver_s vo_driver_t;
typedef void vo_frame_t;
+typedef void vo_overlay_t;
struct vo_driver_s {
@@ -151,6 +152,9 @@ struct vo_driver_s {
/* display a given frame */
void (*display_frame) (vo_driver_t *this, vo_frame_t *vo_img);
+ /* overlay functions */
+ void (*set_overlay) (vo_driver_t *this, vo_overlay_t *overlay);
+
/*
* these can be used by the gui directly:
*/
diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c
index 2061d8843..bc17bb9bc 100644
--- a/src/demuxers/demux_mpeg.c
+++ b/src/demuxers/demux_mpeg.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: demux_mpeg.c,v 1.23 2001/07/03 21:25:03 guenter Exp $
+ * $Id: demux_mpeg.c,v 1.24 2001/07/04 17:10:24 uid32519 Exp $
*
* demultiplexer for mpeg 1/2 program streams
* reads streams of variable blocksizes
@@ -536,6 +536,7 @@ static void *demux_mpeg_loop (void *this_gen) {
this->audio_fifo->put (this->audio_fifo, buf);
}
}
+
xprintf (VERBOSE|DEMUX, "demux loop finished (status: %d, buf:%x)\n",
this->status, w);
printf ("demux loop finished (status: %d, buf:%x)\n",
diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c
index be362d0f0..2aa9e2a48 100644
--- a/src/demuxers/demux_mpeg_block.c
+++ b/src/demuxers/demux_mpeg_block.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: demux_mpeg_block.c,v 1.23 2001/07/03 21:25:04 guenter Exp $
+ * $Id: demux_mpeg_block.c,v 1.24 2001/07/04 17:10:24 uid32519 Exp $
*
* demultiplexer for mpeg 1/2 program streams
*
@@ -371,6 +371,11 @@ static void *demux_mpeg_block_loop (void *this_gen) {
buf->decoder_info[0] = 0; /* stream finished */
this->audio_fifo->put (this->audio_fifo, buf);
}
+
+ buf = this->spu_fifo->buffer_pool_alloc (this->spu_fifo);
+ buf->type = BUF_CONTROL_END;
+ buf->decoder_info[0] = 0; /* stream finished */
+ this->spu_fifo->put (this->spu_fifo, buf);
}
pthread_exit(NULL);
@@ -411,6 +416,12 @@ static void demux_mpeg_block_stop (demux_plugin_t *this_gen) {
this->audio_fifo->put (this->audio_fifo, buf);
}
+ buf = this->spu_fifo->buffer_pool_alloc (this->spu_fifo);
+ buf->type = BUF_CONTROL_END;
+ buf->decoder_info[0] = 1; /* forced */
+
+ this->spu_fifo->put (this->spu_fifo, buf);
+
}
static int demux_mpeg_block_get_status (demux_plugin_t *this_gen) {
@@ -454,6 +465,10 @@ static void demux_mpeg_block_start (demux_plugin_t *this_gen,
this->audio_fifo->put (this->audio_fifo, buf);
}
+ buf = this->spu_fifo->buffer_pool_alloc (this->spu_fifo);
+ buf->type = BUF_CONTROL_START;
+ this->spu_fifo->put (this->spu_fifo, buf);
+
if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) {
int num_buffers = NUM_PREVIEW_BUFFERS;
diff --git a/src/libspudec/Makefile.am b/src/libspudec/Makefile.am
index c96adda1d..11d4cb535 100644
--- a/src/libspudec/Makefile.am
+++ b/src/libspudec/Makefile.am
@@ -1,12 +1,38 @@
-CFLAGS = @BUILD_LIB_STATIC@ @GLOBAL_CFLAGS@
+CFLAGS = @GLOBAL_CFLAGS@
-EXTRA_DIST =
+LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic
-noinst_LTLIBRARIES = libspudec.la
+libdir = $(XINE_PLUGINDIR)
-libspudec_la_SOURCES = spudec.c spudec.h
+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
+
+##
+## Install header files (default=$includedir/xine)
+##
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)/xine
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p; \
+ done
+
+
+##
+## Remove them
+##
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/xine/$$p; \
+ done
-noinst_HEADERS = spudec.h
debug:
$(MAKE) CFLAGS="$(DEBUG_CFLAGS)"
diff --git a/src/libspudec/spu.c b/src/libspudec/spu.c
new file mode 100644
index 000000000..13d9c92c8
--- /dev/null
+++ b/src/libspudec/spu.c
@@ -0,0 +1,399 @@
+/*****
+*
+* This file is part of the OMS program.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2, or (at your option)
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; see the file COPYING. If not, write to
+* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****/
+
+#define DENT_TEST
+
+/*
+ * subpic_decode.c - converts DVD subtitles to an XPM image
+ *
+ * Mostly based on hard work by:
+ *
+ * Copyright (C) 2000 Samuel Hocevar <sam@via.ecp.fr>
+ * and Michel Lespinasse <walken@via.ecp.fr>
+ *
+ * Lots of rearranging by:
+ * Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ * Thomas Mirlacher <dent@cosy.sbg.ac.at>
+ * implemented reassembling
+ * cleaner implementation of SPU are saving
+ * overlaying (proof of concept for now)
+ * ... and yes, it works now with oms
+ * added tranparency (provided by the SPU hdr)
+ * changed structures for easy porting to MGAs DVD mode
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <inttypes.h>
+#include <malloc.h>
+#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
+#define LOG(lvl, fmt...) fprintf (stderr, fmt);
+#else
+#define LOG(lvl, fmt...)
+#endif
+
+
+static u_int _get_bits (u_int bits, vo_overlay_t *spu)
+{
+ static u_int data;
+ static u_int bits_left;
+ u_int ret = 0;
+
+ if (!bits) { /* for realignment to next byte */
+ bits_left = 0;
+ }
+
+ while (bits) {
+ if (bits > bits_left) {
+ ret |= data << (bits - bits_left);
+ bits -= bits_left;
+
+ data = reassembly.buf[spu->offset[field]++];
+ bits_left = 8;
+ } else {
+ bits_left -= bits;
+ ret |= data >> (bits_left);
+ data &= (1 << bits_left) - 1;
+ bits = 0;
+ }
+ }
+
+ return ret;
+}
+
+
+void spuInit (void)
+{
+}
+
+
+static inline void _spu_put_pixel (vo_overlay_t *spu, u_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);
+}
+
+
+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
+
+ 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) {
+ LOG (LOG_DEBUG, "0)");
+ reassembly.buf = pkt_data;
+ reassembly_flag = REASSEMBLY_UNNEEDED;
+ return &reassembly;
+ } else {
+ LOG (LOG_DEBUG, "1)");
+ 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 {
+ LOG (LOG_DEBUG, "2)");
+ 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;
+ }
+ }
+
+ LOG (LOG_DEBUG, "3)");
+ 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)))
+ 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 = /* PTS + */ ((buf[i] << 8) + buf[i+1]) * TIME_UNIT;
+ LOG (LOG_DEBUG, "time = %d ms", 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[0] = clut->entry0;
+ spu->clut[1] = clut->entry1;
+ spu->clut[2] = clut->entry2;
+ spu->clut[3] = 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 */
+#ifndef DENT_TEST
+ 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;
+#else
+ spu->trans[0] = 0;
+ spu->trans[1] = spu->trans[2] = spu->trans[3] = 15;
+#endif
+ 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 */
+
+ 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
+ */
+#ifdef DENT_TEST
+ spu->clut[0] = 0;
+ spu->clut[1] = 9;
+ spu->clut[2] = 8;
+ spu->clut[3] = 12;
+ spu->trans[0] = 0;
+ spu->trans[1] = spu->trans[2] = spu->trans[3] = 15;
+#endif
+ 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)
+{
+ field = 0;
+ _get_bits (0, spu); /* Reset/init bit code */
+
+ while ((spu->offset[1] < reassembly.cmd_offset)) {
+ u_int len;
+ u_int color;
+ u_int vlc;
+
+ vlc = _get_bits (4, spu);
+ if (vlc < 0x0004) {
+ vlc = (vlc << 4) | _get_bits (4, spu);
+ if (vlc < 0x0010) {
+ vlc = (vlc << 4) | _get_bits (4, spu);
+ if (vlc < 0x0040) {
+ vlc = (vlc << 4) | _get_bits (4, spu);
+ }
+ }
+ }
+
+ color = vlc & 0x03;
+ len = vlc>>2;
+
+ /* if len == 0 -> end sequence - fill to end of line */
+ len = len ? : spu->width - spu->_x;
+
+ _spu_put_pixel (spu, len, color);
+
+ if (spu->_x >= spu->width)
+ if (_spu_next_line (spu) < 0)
+ goto clean_up;
+ }
+
+ /* 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);
+ }
+
+ clean_up:
+ if (reassembly_flag != REASSEMBLY_UNNEEDED) {
+ LOG (LOG_DEBUG, "freeing reassembly.buf");
+ free (reassembly.buf);
+ }
+
+ reassembly_flag = REASSEMBLY_START;
+}
diff --git a/src/libspudec/spu.h b/src/libspudec/spu.h
new file mode 100644
index 000000000..844010243
--- /dev/null
+++ b/src/libspudec/spu.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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.1 2001/07/04 17:10:24 uid32519 Exp $
+ *
+ * This file was originally part of the OMS program.
+ *
+ */
+
+#ifndef __SPU_H__
+#define __SPU_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <inttypes.h>
+#include "video_out.h"
+
+#ifndef CLUT_T
+#define CLUT_T
+typedef struct { // CLUT == Color LookUp Table
+ uint8_t:8;
+ uint8_t y:8;
+ uint8_t cr:8;
+ uint8_t cb:8;
+} __attribute__ ((packed)) clut_t;
+#endif
+
+typedef struct spu_clut_struct {
+#ifdef WORDS_BIGENDIAN
+ uint8_t entry0 : 4;
+ uint8_t entry1 : 4;
+ uint8_t entry2 : 4;
+ uint8_t entry3 : 4;
+#else
+ uint8_t entry1 : 4;
+ uint8_t entry0 : 4;
+ uint8_t entry3 : 4;
+ uint8_t entry2 : 4;
+#endif
+} spu_clut_t;
+
+
+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);
+
+#endif
diff --git a/src/libspudec/spu_decoder_api.h b/src/libspudec/spu_decoder_api.h
new file mode 100644
index 000000000..4dfd2739a
--- /dev/null
+++ b/src/libspudec/spu_decoder_api.h
@@ -0,0 +1,69 @@
+/*
+ * spu_decoder_api.h
+ *
+ * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation,
+ *
+ */
+
+#ifndef HAVE_SPU_API_H
+#define HAVE_SPU_API_H
+
+ /*
+ * generic xine spu decoder plugin interface
+ *
+ * for a dynamic plugin make sure you provide this function call:
+ * spu_decoder_t *init_spu_decoder_plugin (int iface_version,
+ * config_values_t *cfg);
+ */
+
+typedef struct spu_decoder_s spu_decoder_t;
+
+struct spu_decoder_s {
+
+ int interface_version;
+
+ int (*can_handle) (spu_decoder_t *this, int buf_type);
+
+ void (*init) (spu_decoder_t *this, vo_instance_t *video_out);
+
+ void (*decode_data) (spu_decoder_t *this, buf_element_t *buf);
+
+ void (*close) (spu_decoder_t *this);
+
+ char* (*get_identifier) (void);
+
+};
+
+
+
+typedef struct spudec_s spudec_t;
+
+struct spudec_s {
+
+ /*
+ * reset spudec for a new stream
+ *
+ * clut : pointer to array of 16 cluts for palette info
+ */
+
+ void (*spudec_start) (spudec_t *this, clut_t *clut);
+
+};
+
+#endif /* HAVE_SPUDEC_H */
diff --git a/src/libspudec/xine_decoder.c b/src/libspudec/xine_decoder.c
new file mode 100644
index 000000000..bcbcbb4ce
--- /dev/null
+++ b/src/libspudec/xine_decoder.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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.1 2001/07/04 17:10:24 uid32519 Exp $
+ *
+ * stuff needed to turn libspu into a xine decoder plugin
+ */
+
+/*
+ * FIXME: libspu uses global variables (that are written to)
+ */
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "spu.h"
+#include "buffer.h"
+#include "xine_internal.h"
+
+#define FRAME_SIZE 4096
+
+
+typedef struct spudec_decoder_s {
+ spu_decoder_t spu_decoder;
+
+ uint32_t pts;
+
+ uint8_t frame_buffer[FRAME_SIZE];
+ uint8_t *frame_ptr;
+ int sync_todo;
+ int frame_length, frame_todo;
+ uint16_t syncword;
+
+ vo_instance_t *vo_out;
+ vo_overlay_t *spu;
+ int spu_caps;
+ int bypass_mode;
+ int max_num_channels;
+ int output_sampling_rate;
+ int output_open;
+ int output_mode;
+
+} spudec_decoder_t;
+
+int spudec_can_handle (spu_decoder_t *this_gen, int buf_type) {
+ return ((buf_type & 0xFFFF0000) == BUF_SPU_PACKAGE) ;
+}
+
+
+void spudec_init (spu_decoder_t *this_gen, vo_instance_t *vo_out) {
+
+ spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
+ printf("spudec_init %p\n",&vo_out);
+ this->vo_out = vo_out;
+ this->spu_caps = vo_out->get_capabilities(vo_out);
+ this->syncword = 0;
+ this->sync_todo = 6;
+ this->output_open = 0;
+
+// spu_init ();
+
+}
+
+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;
+}
+
+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;
+ /* uint8_t *end = buf->content + buf->size; */
+
+ printf ("spudec_decode_data\n");
+
+ 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 (!spuParseHdr (this->spu, current, buf->size)) {
+ spuParseData (this->spu);
+ printf("X=%d Y=%d w=%d h=%d\n",
+ this->spu->x,this->spu->y,
+ this->spu->width,this->spu->height);
+ /* overlay_txt(this->spu,1.0); ??? */
+ this->spu->PTS = buf->PTS;
+ this->vo_out->queue_overlay (this->vo_out, this->spu);
+ this->spu = NULL;
+ }
+
+}
+
+void spudec_close (spu_decoder_t *this_gen) {
+
+ /* spudec_decoder_t *this = (spudec_decoder_t *) this_gen; */
+
+// if (this->output_open)
+// this->spu_out->close (this->spu_out);
+
+ /* close (spufile); */
+}
+
+static char *spudec_get_id(void) {
+ return "spudec";
+}
+
+spu_decoder_t *init_spu_decoder_plugin (int iface_version, config_values_t *cfg) {
+
+ spudec_decoder_t *this ;
+
+ if (iface_version != 1)
+ return NULL;
+
+ this = (spudec_decoder_t *) malloc (sizeof (spudec_decoder_t));
+
+ this->spu_decoder.interface_version = 1;
+ 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.close = spudec_close;
+ this->spu_decoder.get_identifier = spudec_get_id;
+
+ return (spu_decoder_t *) this;
+}
+
diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am
index b946f20e9..5070d63b9 100644
--- a/src/video_out/Makefile.am
+++ b/src/video_out/Makefile.am
@@ -25,7 +25,7 @@ endif
#
lib_LTLIBRARIES = $(xv_module) $(syncfb_module) $(xshm_module) $(aa_module)
-xineplug_vo_out_xv_la_SOURCES = video_out_xv.c
+xineplug_vo_out_xv_la_SOURCES = alphablend.c video_out_xv.c
xineplug_vo_out_xv_la_LIBADD = $(XV_LIB) $(X_LIBS) -lXext
xineplug_vo_out_xv_la_LDFLAGS = -avoid-version -module
diff --git a/src/video_out/alphablend.c b/src/video_out/alphablend.c
new file mode 100644
index 000000000..ac77fbbce
--- /dev/null
+++ b/src/video_out/alphablend.c
@@ -0,0 +1,350 @@
+//TOAST_SPU will define ALL spu entries - no matter the tranparency
+//#define TOAST_SPU
+/* #define PRIV_CLUT */
+
+/*
+ *
+ * Copyright (C) 2000 Thomas Mirlacher
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * The author may be reached as <dent@linuxvideo.org>
+ *
+ *------------------------------------------------------------
+ *
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "video_out.h"
+
+#define BLEND_COLOR(dst, src, mask, o) ((((src&mask)*o + ((dst&mask)*(0x0f-o)))/0xf) & mask)
+
+static inline uint16_t blendpixel_rgb16 (uint16_t dst, uint16_t src,
+ uint8_t o)
+{
+ return BLEND_COLOR (dst, src, 0xf800, o) |
+ BLEND_COLOR (dst, src, 0x07e0, o) |
+ BLEND_COLOR (dst, src, 0x001f, o);
+}
+
+static inline uint32_t blendpixel_rgb24 (uint32_t dst, uint32_t src,
+ uint8_t o)
+{
+ return BLEND_COLOR (dst, src, 0xff0000, o) |
+ BLEND_COLOR (dst, src, 0x00ff00, o) |
+ BLEND_COLOR (dst, src, 0x0000ff, o);
+}
+
+static inline uint32_t blendpixel_rgb32 (uint32_t dst, uint32_t src,
+ uint8_t o)
+{
+ return BLEND_COLOR (dst, src, 0xff0000, o) |
+ BLEND_COLOR (dst, src, 0x00ff00, o) |
+ BLEND_COLOR (dst, src, 0x0000ff, o);
+}
+/*
+void blend_tux_rgb16 (uint8_t * img, int dst_width, int dst_height)
+{
+ int src_width = bg_width;
+ int src_height = bg_height;
+ uint8_t *src = (uint8_t *) bg_img_data;
+ static int x_off;
+ static int y_off;
+ static int x_dir = 1;
+ static int y_dir = 1;
+ static int o = 5;
+ static int o_dir = 1;
+
+// align right bottom
+ x_off += x_dir;
+ if (x_off > (dst_width - src_width))
+ x_dir = -x_dir;
+ if (x_off <= 0)
+ x_dir = -x_dir;
+
+ y_off += y_dir;
+ if (y_off > (dst_height - src_height))
+ y_dir = -y_dir;
+ if (y_off <= 0)
+ y_dir = -y_dir;
+
+// cycle parameters
+ o += o_dir;
+ if (o >= 0xf)
+ o_dir = -o_dir;
+ if (o <= 1)
+ o_dir = -o_dir;
+//
+ {
+ uint16_t *dst = (uint16_t *) img;
+ int x,
+ y;
+
+ dst += y_off * dst_width;
+ for (y = 0; y < src_height; y++) {
+ dst += x_off;
+ for (x = 0; x < src_width; x++) {
+ if ((*src) - bg_start_index)
+ *dst = blendpixel_rgb16 (bg_palette_to_rgb [(*src) - bg_start_index], *dst, o);
+ src++;
+ dst++;
+ }
+ dst += dst_width - x - x_off;
+ }
+ }
+}
+*/
+// convenience
+
+#define uint24_t uint32_t
+
+#define BLEND(bpp, img, img_overl, dst_width, dst_height)\
+{ \
+ static int o=5; \
+ uint8_t *src = (uint8_t *) img_overl->data; \
+ uint##bpp##_t *dst = (uint##bpp##_t *) img; \
+ int x, y; \
+ \
+ dst += img_overl->y*dst_width; \
+ 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]; \
+ \
+/* if ((*src&0x0f) != 0) if alpha is != 0 */ \
+ if (o) /* if alpha is != 0 */ \
+ *dst = blendpixel_rgb##bpp (*dst, img_overl->clut[(*src&0x0f)]/*.y*/, o); \
+/* *dst = blendpixel_rgb##bpp (*dst, myclut[img_overl->clut[(*src&0x0f)]], o);*/\
+ src++; \
+ dst++; \
+ } \
+ dst += dst_width - x - img_overl->x; \
+ } \
+}
+
+//void blend_rgb16 (uint8_t *img, overlay_buf_t *img_overl, int dst_width, int dst_height)
+void blend_rgb (uint8_t * img, vo_overlay_t * img_overl, int dst_width,
+ int dst_height)
+{
+#ifdef PRIV_CLUT
+ u_int myclut[] = {
+ 0x0000,
+ 0x20e2,
+ 0x83ac,
+ 0x4227,
+ 0xa381,
+ 0xad13,
+ 0xbdf8,
+ 0xd657,
+ 0xee67,
+ 0x6a40,
+ 0xd4c1,
+ 0xf602,
+ 0xf664,
+ 0xe561,
+ 0xad13,
+ 0xffdf,
+ };
+#endif
+
+ BLEND (16, img, img_overl, dst_width, dst_height);
+ //blend_tux_rgb16 (img, dst_width, dst_height);
+}
+
+void blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl, int dst_width,
+ int dst_height)
+{
+//FIXME CLUT
+#ifdef PRIV_CLUT
+ u_int myclut[] = {
+ 0x0000,
+ 0x20e2,
+ 0x83ac,
+ 0x4227,
+ 0xa381,
+ 0xad13,
+ 0xbdf8,
+ 0xd657,
+ 0xee67,
+ 0x6a40,
+ 0xd4c1,
+ 0xf602,
+ 0xf664,
+ 0xe561,
+ 0xad13,
+ 0xffdf,
+ };
+#endif
+ BLEND (24, img, img_overl, dst_width, dst_height);
+}
+
+void blend_rgb32 (uint8_t * img, vo_overlay_t * img_overl, int dst_width,
+ int dst_height)
+{
+//FIXME CLUT
+#ifdef PRIV_CLUT
+ u_int myclut[] = {
+ 0x0000,
+ 0x20e2,
+ 0x83ac,
+ 0x4227,
+ 0xa381,
+ 0xad13,
+ 0xbdf8,
+ 0xd657,
+ 0xee67,
+ 0x6a40,
+ 0xd4c1,
+ 0xf602,
+ 0xf664,
+ 0xe561,
+ 0xad13,
+ 0xffdf,
+ };
+#endif
+ BLEND (32, img, img_overl, dst_width, dst_height);
+}
+
+#define BLEND_YUV(dst, src, o) (((src)*o + ((dst)*(0xf-o)))/0xf)
+
+void blend_yuv (uint8_t * dst_img, vo_overlay_t * img_overl,
+ int dst_width, int dst_height)
+{
+#ifdef PRIV_CLUT
+ clut_t my_clut[] = {
+ {y: 0x51, cr: 0xef, cb:0x5a},
+ {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: 0x5c, 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}
+ };
+#endif
+
+ int src_width = img_overl->width;
+ int src_height = img_overl->height;
+ uint8_t *src_data = img_overl->data;
+
+ int x_off = img_overl->x;
+ int y_off = img_overl->y;
+
+ uint8_t *dst_y = dst_img + dst_width * y_off + x_off;
+ uint8_t *dst_cr = dst_img + dst_width * dst_height +
+ (y_off / 2) * (dst_width / 2) + (x_off / 2);
+ uint8_t *dst_cb = dst_img + (dst_width * dst_height * 5) / 4 +
+ (y_off / 2) * (dst_width / 2) + (x_off / 2);
+
+ int x,
+ y;
+
+ for (y = 0; y < src_height; y++) {
+ for (x = 0; x < src_width; x++) {
+ uint8_t clr;
+ uint8_t o;
+
+ clr = img_overl->clut[*src_data & 0x0f];
+ o = img_overl->trans[*src_data & 0x0f];
+
+ if (clr)
+// *INDENT-OFF*
+#ifdef PRIV_CLUT
+ *dst_y = BLEND_YUV (*dst_y, my_clut[clr].y, o);
+#else
+ *dst_y = BLEND_YUV (*dst_y, img_overl->clut[clr]/*.y*/, o);
+#endif
+// *INDENT-ON*
+ dst_y++;
+
+ if (y & x & 1) {
+ if (clr) {
+// *INDENT-OFF*
+#ifdef PRIV_CLUT
+ *dst_cr = BLEND_YUV (*dst_cr, my_clut[clr].cr, o);
+ *dst_cb = BLEND_YUV (*dst_cb, my_clut[clr].cb, o);
+#else
+ *dst_cr = BLEND_YUV (*dst_cr, img_overl->clut [clr]/*.cr*/, o);
+ *dst_cb = BLEND_YUV (*dst_cb, img_overl->clut [clr]/*.cb*/, o);
+#endif
+// *INDENT-ON*
+ }
+ dst_cr++;
+ dst_cb++;
+ }
+ src_data++;
+ }
+
+ dst_y += dst_width - src_width;
+
+ if (y & 1) {
+ dst_cr += (dst_width - src_width) / 2;
+ dst_cb += (dst_width - src_width) / 2;
+ }
+ }
+}
+
+inline int is_blank (uint8_t * ptr, int width)
+{
+ int x;
+
+ for (x = 0; x < width; x++) {
+ if ((*ptr & 0x0f) && (*ptr >> 4))
+ return 0; // color != 0 && alpha != 0
+ ptr++;
+ }
+
+ return 1; // blank line
+}
+
+void crop_overlay (vo_overlay_t * overlay)
+{
+ uint8_t *data = overlay->data;
+ int height = overlay->height;
+ int width = overlay->width;
+ int y;
+
+ /*
+ * Shrink from bottom
+ */
+
+ for (y=height - 1;y >= 0 && is_blank (&data[y * width], width); y--);
+ height = y + 1;
+
+ /*
+ * Shrink from top
+ */
+ for (y=0; y < height && is_blank (&data[y * width], width); y++);
+ height -= y;
+
+ /*
+ * Shift data
+ */
+ overlay->y -= y;
+ overlay->height = height;
+
+ memcpy (data, &data[y * width], height * width);
+}
diff --git a/src/video_out/alphablend.h b/src/video_out/alphablend.h
new file mode 100644
index 000000000..7afa470f7
--- /dev/null
+++ b/src/video_out/alphablend.h
@@ -0,0 +1,39 @@
+
+/*
+ *
+ * Copyright (C) 2000 Thomas Mirlacher
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * The author may be reached as <dent@linuxvideo.org>
+ *
+ *------------------------------------------------------------
+ *
+ */
+
+#ifndef __ALPHABLEND_H__
+#define __ALPHABLEND_H__
+
+#include "video_out.h"
+
+void blend_rgb (uint8_t * img, vo_overlay_t * overlay, int width,
+
+ int height);
+void blend_yuv (uint8_t * img, vo_overlay_t * overlay, int width,
+
+ int height);
+void crop_overlay (vo_overlay_t * overlay);
+
+#endif
diff --git a/src/video_out/video_out_aa.c b/src/video_out/video_out_aa.c
index 179157e7c..1ab490ee2 100644
--- a/src/video_out/video_out_aa.c
+++ b/src/video_out/video_out_aa.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_aa.c,v 1.7 2001/06/14 18:32:57 guenter Exp $
+ * $Id: video_out_aa.c,v 1.8 2001/07/04 17:10:24 uid32519 Exp $
*
* video_out_aa.c, ascii-art output plugin for xine
*
@@ -261,6 +261,9 @@ static void aa_get_property_min_max (vo_driver_t *this_gen,
*max = 0;
}
+static void aa_set_overlay (vo_driver_t *this, vo_overlay_t *overlay) {
+}
+
static void aa_exit (vo_driver_t *this_gen) {
}
@@ -283,12 +286,13 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
this->vo_driver.get_property_min_max = aa_get_property_min_max;
this->vo_driver.gui_data_exchange = NULL;
this->vo_driver.exit = aa_exit;
+ this->vo_driver.set_overlay = aa_set_overlay;
return (vo_driver_t*) this;
}
static vo_info_t vo_info_aa = {
- VIDEO_OUT_IFACE_VERSION,
+ 2,
"aa",
"xine video output plugin using the ascii-art library",
VISUAL_TYPE_AA,
diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c
index a7ec000a1..f3a4d52c8 100644
--- a/src/video_out/video_out_syncfb.c
+++ b/src/video_out/video_out_syncfb.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_syncfb.c,v 1.7 2001/07/04 14:01:50 uid56437 Exp $
+ * $Id: video_out_syncfb.c,v 1.8 2001/07/04 17:10:24 uid32519 Exp $
*
* video_out_syncfb.c, Matrox G400 video extension interface for xine
*
@@ -866,7 +866,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual) {
static vo_info_t vo_info_mga = {
- VIDEO_OUT_IFACE_VERSION,
+ 1,
"Syncfb",
"xine video output plugin using MGA Teletux (syncfb) video extension",
VISUAL_TYPE_X11,
diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c
index b4f9d5e65..63168b852 100644
--- a/src/video_out/video_out_xshm.c
+++ b/src/video_out/video_out_xshm.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_xshm.c,v 1.13 2001/07/04 14:01:50 uid56437 Exp $
+ * $Id: video_out_xshm.c,v 1.14 2001/07/04 17:10:24 uid32519 Exp $
*
* video_out_xshm.c, X11 shared memory extension interface for xine
*
@@ -94,6 +94,7 @@ typedef struct xshm_driver_s {
yuv2rgb_t *yuv2rgb;
xshm_frame_t *cur_frame;
+ vo_overlay_t *overlay;
/* size / aspect ratio calculations */
int delivered_width; /* everything is set up for these frame dimensions */
@@ -652,6 +653,13 @@ static void xshm_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
}
}
+/* Stores an overlay in the Video Out driver */
+static void xshm_set_overlay (vo_driver_t *this_gen, vo_overlay_t *overlay) {
+ xshm_driver_t *this = (xshm_driver_t *) this_gen;
+
+ this->overlay = overlay;
+}
+
static int xshm_get_property (vo_driver_t *this_gen, int property) {
xshm_driver_t *this = (xshm_driver_t *) this_gen;
@@ -823,12 +831,14 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
this->vo_driver.alloc_frame = xshm_alloc_frame;
this->vo_driver.update_frame_format = xshm_update_frame_format;
this->vo_driver.display_frame = xshm_display_frame;
+ this->vo_driver.set_overlay = xshm_set_overlay;
this->vo_driver.get_property = xshm_get_property;
this->vo_driver.set_property = xshm_set_property;
this->vo_driver.get_property_min_max = xshm_get_property_min_max;
this->vo_driver.gui_data_exchange = xshm_gui_data_exchange;
this->vo_driver.exit = xshm_exit;
+
/*
*
* depth in X11 terminology land is the number of bits used to
@@ -924,7 +934,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
}
static vo_info_t vo_info_shm = {
- VIDEO_OUT_IFACE_VERSION,
+ 2,
"XShm",
"xine video output plugin using the MIT X shared memory extension",
VISUAL_TYPE_X11,
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c
index 741bfdd20..ed49b6324 100644
--- a/src/video_out/video_out_xv.c
+++ b/src/video_out/video_out_xv.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_xv.c,v 1.47 2001/06/25 09:51:47 guenter Exp $
+ * $Id: video_out_xv.c,v 1.48 2001/07/04 17:10:24 uid32519 Exp $
*
* video_out_xv.c, X11 video extension interface for xine
*
@@ -54,6 +54,8 @@
#include "video_out.h"
#include "video_out_x11.h"
#include "xine_internal.h"
+/* #include "overlay.h" */
+#include "alphablend.h"
uint32_t xine_debug;
@@ -102,6 +104,7 @@ typedef struct {
uint32_t capabilities;
xv_frame_t *cur_frame;
+ vo_overlay_t *overlay;
/* size / aspect ratio calculations */
int delivered_width; /* everything is set up for
@@ -135,8 +138,6 @@ static uint32_t xv_get_capabilities (vo_driver_t *this_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
- printf ("video_out_xv: get capabilities\n");
-
return this->capabilities;
}
@@ -396,9 +397,6 @@ static void xv_update_frame_format (vo_driver_t *this_gen,
frame->ratio_code = ratio_code;
}
-/*
- *
- */
static void xv_adapt_to_output_area (xv_driver_t *this,
int dest_x, int dest_y,
int dest_width, int dest_height) {
@@ -447,9 +445,6 @@ static void xv_adapt_to_output_area (xv_driver_t *this,
XUnlockDisplay (this->display);
}
-/*
- *
- */
static void xv_calc_format (xv_driver_t *this,
int width, int height, int ratio_code) {
@@ -567,6 +562,10 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
xv_calc_format (this, frame->width, frame->height, frame->ratio_code);
}
+// Alpha Blend here
+ if (this->overlay) {
+ blend_yuv( frame->image->data, this->overlay, frame->width, frame->height);
+ }
XLockDisplay (this->display);
@@ -595,9 +594,13 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
}
}
-/*
- *
- */
+/* Stores an overlay in the Video Out driver */
+static void xv_set_overlay (vo_driver_t *this_gen, vo_overlay_t *overlay) {
+ xv_driver_t *this = (xv_driver_t *) this_gen;
+
+ this->overlay = overlay;
+}
+
static int xv_get_property (vo_driver_t *this_gen, int property) {
xv_driver_t *this = (xv_driver_t *) this_gen;
@@ -605,9 +608,6 @@ static int xv_get_property (vo_driver_t *this_gen, int property) {
return this->props[property].value;
}
-/*
- *
- */
static int xv_set_property (vo_driver_t *this_gen,
int property, int value) {
@@ -649,9 +649,6 @@ static int xv_set_property (vo_driver_t *this_gen,
return value;
}
-/*
- *
- */
static void xv_get_property_min_max (vo_driver_t *this_gen,
int property, int *min, int *max) {
@@ -661,9 +658,6 @@ static void xv_get_property_min_max (vo_driver_t *this_gen,
*max = this->props[property].max;
}
-/*
- *
- */
static int xv_gui_data_exchange (vo_driver_t *this_gen,
int data_type, void *data) {
@@ -730,9 +724,6 @@ static int xv_gui_data_exchange (vo_driver_t *this_gen,
return 0;
}
-/*
- *
- */
static void xv_exit (vo_driver_t *this_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
@@ -744,9 +735,6 @@ static void xv_exit (vo_driver_t *this_gen) {
XUnlockDisplay (this->display);
}
-/*
- *
- */
static int xv_check_yv12 (Display *display, XvPortID port) {
XvImageFormatValues * formatValues;
int formats;
@@ -763,9 +751,6 @@ static int xv_check_yv12 (Display *display, XvPortID port) {
return 1;
}
-/*
- *
- */
static void xv_check_capability (xv_driver_t *this,
uint32_t capability,
int property, XvAttribute attr,
@@ -786,9 +771,6 @@ static void xv_check_capability (xv_driver_t *this,
this->config->lookup_int (this->config, str_prop, nDefault));
}
-/*
- *
- */
vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
xv_driver_t *this;
@@ -875,6 +857,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
this->config = config;
this->display = visual->display;
+ this->overlay = NULL;
this->screen = visual->screen;
this->display_ratio = visual->display_ratio;
this->request_dest_size = visual->request_dest_size;
@@ -897,6 +880,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
this->vo_driver.alloc_frame = xv_alloc_frame;
this->vo_driver.update_frame_format = xv_update_frame_format;
this->vo_driver.display_frame = xv_display_frame;
+ this->vo_driver.set_overlay = xv_set_overlay;
this->vo_driver.get_property = xv_get_property;
this->vo_driver.set_property = xv_set_property;
this->vo_driver.get_property_min_max = xv_get_property_min_max;
@@ -1010,11 +994,8 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
return &this->vo_driver;
}
-/*
- *
- */
static vo_info_t vo_info_xv = {
- VIDEO_OUT_IFACE_VERSION,
+ 2,
"Xv",
"xine video output plugin using the MIT X video extension",
VISUAL_TYPE_X11,
diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am
index 17558fdd2..4726c331d 100644
--- a/src/xine-engine/Makefile.am
+++ b/src/xine-engine/Makefile.am
@@ -8,14 +8,14 @@ EXTRA_DIST = cpu_accel.c
lib_LTLIBRARIES = libxine.la
-libxine_la_SOURCES = xine.c metronom.c configfile.c buffer.c monitor.c \
- utils.c load_plugins.c video_decoder.c spu_decoder.c \
+libxine_la_SOURCES = xine.c metronom.c configfile.c spu_decoder.c buffer.c monitor.c \
+ utils.c load_plugins.c video_decoder.c \
audio_decoder.c video_out.c
libxine_la_LIBADD = cpu_accel.lo \
- $(top_srcdir)/src/libspudec/libspudec.la \
$(THREAD_LIBS) \
- $(DYNAMIC_LD_LIBS)
+ $(DYNAMIC_LD_LIBS) \
-lm
+
libxine_la_LDFLAGS = -version-info 5:0:5
include_HEADERS = buffer.h metronom.h configfile.h \
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index 1a7d97424..a7b1aa924 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.27 2001/07/01 23:37:05 guenter Exp $
+ * $Id: load_plugins.c,v 1.28 2001/07/04 17:10:24 uid32519 Exp $
*
*
* Load input/demux/audio_out/video_out/codec plugins
@@ -268,6 +268,9 @@ void load_decoder_plugins (xine_t *this,
/*
* clean up first
*/
+ this->cur_spu_decoder_plugin = NULL;
+ for (i=0; i<DECODER_PLUGIN_MAX; i++)
+ this->spu_decoder_plugins[i] = NULL;
this->cur_video_decoder_plugin = NULL;
for (i=0; i<DECODER_PLUGIN_MAX; i++)
@@ -312,6 +315,29 @@ void load_decoder_plugins (xine_t *this,
} else {
void *(*initplug) (int, config_values_t *);
+
+ /*
+ * does this plugin provide an spu decoder plugin?
+ */
+
+ if((initplug = dlsym(plugin, "init_spu_decoder_plugin")) != NULL) {
+
+ spu_decoder_t *sdp;
+ int streamtype;
+
+ sdp = (spu_decoder_t *) initplug(iface_version, config);
+ printf("SPU Can Handle ?\n");
+ for (streamtype = 0; streamtype<256; streamtype++) {
+ if (sdp->can_handle (sdp, (streamtype<<16) | BUF_SPU_BASE))
+ printf("SPU Can Handle yes %x\n",streamtype);
+ this->spu_decoder_plugins[streamtype] = sdp;
+ }
+
+ printf("spu decoder plugin found : %s\n",
+ sdp->get_identifier());
+ }
+
+
/*
* does this plugin provide an video decoder plugin?
@@ -360,6 +386,7 @@ void load_decoder_plugins (xine_t *this,
}
}
+ this->cur_spu_decoder_plugin = NULL;
this->cur_video_decoder_plugin = NULL;
this->cur_audio_decoder_plugin = NULL;
}
@@ -498,22 +525,30 @@ vo_driver_t *xine_load_video_output_plugin(config_values_t *config,
if ((getinfo = dlsym(plugin, "get_video_out_plugin_info")) != NULL) {
vo_info = getinfo();
-
- if (!strcmp(id, vo_info->id)) {
- void *(*initplug) (config_values_t *, void *);
+
+ if (!strcmp(id, vo_info->id) ) {
+
+ if (vo_info->interface_version == VIDEO_OUT_IFACE_VERSION) {
+
+ void *(*initplug) (config_values_t *, void *);
- if((initplug = dlsym(plugin, "init_video_out_plugin")) != NULL) {
-
- vod = (vo_driver_t *) initplug(config, visual);
-
- if (vod)
- printf("load_plugins: video output plugin %s successfully"
- " loaded.\n", id);
- else
- printf("load_plugins: video output plugin %s: "
- "init_video_out_plugin failed.\n", str);
+ if((initplug = dlsym(plugin, "init_video_out_plugin")) != NULL) {
+
+ vod = (vo_driver_t *) initplug(config, visual);
+
+ if (vod)
+ printf("load_plugins: video output plugin %s successfully"
+ " loaded.\n", id);
+ else
+ printf("load_plugins: video output plugin %s: "
+ "init_video_out_plugin failed.\n", str);
+
+ return vod;
+ }
+ } else {
- return vod;
+ printf("load_plugins: video output plugin %s: "
+ "wrong interface version %d.\n", str, vo_info->interface_version);
}
}
}
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index de24dad76..ef6706ebf 100644
--- a/src/xine-engine/metronom.c
+++ b/src/xine-engine/metronom.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: metronom.c,v 1.13 2001/07/03 21:25:04 guenter Exp $
+ * $Id: metronom.c,v 1.14 2001/07/04 17:10:24 uid32519 Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -390,7 +390,6 @@ static uint32_t metronom_got_audio_samples (metronom_t *this, uint32_t pts, uint
pthread_mutex_lock (&this->lock);
if (pts) {
- int32_t diff;
/*
* first audio pts ?
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
index 6422d4f62..e7080b57d 100644
--- a/src/xine-engine/metronom.h
+++ b/src/xine-engine/metronom.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: metronom.h,v 1.5 2001/06/24 02:19:29 guenter Exp $
+ * $Id: metronom.h,v 1.6 2001/07/04 17:10:24 uid32519 Exp $
*
* metronom: general pts => virtual calculation/assoc
*
@@ -125,7 +125,7 @@ struct metronom_s {
/*
* start metronom clock (no clock reset)
*/
- void (*start_clock) (metronom_t *this, int32_t pts);
+ void (*start_clock) (metronom_t *this, uint32_t pts);
/*
diff --git a/src/xine-engine/monitor.h b/src/xine-engine/monitor.h
index e338be535..f4033a1d5 100644
--- a/src/xine-engine/monitor.h
+++ b/src/xine-engine/monitor.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: monitor.h,v 1.1 2001/04/18 22:36:07 f1rmb Exp $
+ * $Id: monitor.h,v 1.2 2001/07/04 17:10:24 uid32519 Exp $
*
* debug print and profiling functions
*
@@ -30,18 +30,18 @@
extern uint32_t xine_debug;
-#define VERBOSE (xine_debug & 0x8000>>1)
-#define METRONOM (xine_debug & 0x8000>>2)
-#define AUDIO (xine_debug & 0x8000>>3)
-#define DEMUX (xine_debug & 0x8000>>4)
-#define INPUT (xine_debug & 0x8000>>5)
-#define VIDEO (xine_debug & 0x8000>>6)
-#define VPTS (xine_debug & 0x8000>>7)
-#define MPEG (xine_debug & 0x8000>>8)
-#define VAVI (xine_debug & 0x8000>>9)
-#define AC3 (xine_debug & 0x8000>>10)
-#define LOOP (xine_debug & 0x8000>>11)
-#define GUI (xine_debug & 0x8000>>12)
+#define VERBOSE (xine_debug & 0x8000>>1) // 16384
+#define METRONOM (xine_debug & 0x8000>>2) // 8192
+#define AUDIO (xine_debug & 0x8000>>3) // 4096
+#define DEMUX (xine_debug & 0x8000>>4) // 2048
+#define INPUT (xine_debug & 0x8000>>5) // 1024
+#define VIDEO (xine_debug & 0x8000>>6) // 512
+#define VPTS (xine_debug & 0x8000>>7) // 256
+#define MPEG (xine_debug & 0x8000>>8) // 128
+#define VAVI (xine_debug & 0x8000>>9) // 64
+#define AC3 (xine_debug & 0x8000>>10) // 32
+#define LOOP (xine_debug & 0x8000>>11) // 16
+#define GUI (xine_debug & 0x8000>>12) // 8
#define perr(FMT,ARGS...) {fprintf(stderr, FMT, ##ARGS);fflush(stderr);}
diff --git a/src/xine-engine/spu_decoder.c b/src/xine-engine/spu_decoder.c
index 03f008367..0878bf06a 100644
--- a/src/xine-engine/spu_decoder.c
+++ b/src/xine-engine/spu_decoder.c
@@ -17,8 +17,10 @@
* 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_decoder.c,v 1.2 2001/06/18 15:43:01 richwareham Exp $
+ * $Id: spu_decoder.c,v 1.3 2001/07/04 17:10:24 uid32519 Exp $
*
+
+ * functions that implement spu decoding
*/
#ifdef HAVE_CONFIG_H
@@ -27,52 +29,95 @@
#include "xine_internal.h"
-#include "libspudec/spudec.h"
-
void *spu_decoder_loop (void *this_gen) {
buf_element_t *buf;
xine_t *this = (xine_t *) this_gen;
int running = 1;
- int streamtype;
- spudec_t *decoder;
+ int i;
+ spu_decoder_t *decoder;
- decoder = this->spu_decoder;
while (running) {
- /* printf ("video_decoder: getting buffer...\n"); */
-
buf = this->spu_fifo->get (this->spu_fifo);
- if (buf->input_pos)
- this->cur_input_pos = buf->input_pos;
- /* printf ("spu_decoder: got buffer %d\n", buf->type); */
+ this->cur_input_pos = buf->input_pos;
switch (buf->type) {
+
case BUF_CONTROL_START:
+ if (this->cur_spu_decoder_plugin) {
+ this->cur_spu_decoder_plugin->close (this->cur_spu_decoder_plugin);
+ this->cur_spu_decoder_plugin = NULL;
+ }
+
+ pthread_mutex_lock (&this->xine_lock);
+ this->spu_finished = 0;
+ pthread_mutex_unlock (&this->xine_lock);
+
+ for (i=0 ; i<50; i++)
+ this->spu_track_map[0] = 0;
+
+ this->spu_track_map_entries = 0;
+
break;
case BUF_CONTROL_END:
+ if (this->cur_spu_decoder_plugin) {
+ this->cur_spu_decoder_plugin->close (this->cur_spu_decoder_plugin);
+ this->cur_spu_decoder_plugin = NULL;
+ }
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ this->spu_finished = 1;
+
+ if (this->video_finished) {
+ pthread_mutex_unlock (&this->xine_lock);
+ xine_notify_stream_finished (this);
+ } else
+ pthread_mutex_unlock (&this->xine_lock);
+
break;
case BUF_CONTROL_QUIT:
+ if (this->cur_spu_decoder_plugin) {
+ this->cur_spu_decoder_plugin->close (this->cur_spu_decoder_plugin);
+ this->cur_spu_decoder_plugin = NULL;
+ }
running = 0;
break;
default:
if ( (buf->type & 0xFF000000) == BUF_SPU_BASE ) {
- int stream_id;
-
- printf ("spu_decoder: got an SPU buffer, type %08x\n", buf->type);
-
- stream_id = buf->type & 0xFF;
- if(decoder) {
- decoder->push_packet(decoder, buf);
+
+ /* now, decode this buffer if it's the right track */
+
+ if ( (buf->type & 0xFFFF)== this->spu_channel) {
+
+ int streamtype = (buf->type>>16) & 0xFF;
+ decoder = this->spu_decoder_plugins [streamtype];
+ printf("SPU DECODER: %p\n",decoder);
+ if (decoder) {
+ if (this->cur_spu_decoder_plugin != decoder) {
+
+ if (this->cur_spu_decoder_plugin)
+ this->cur_spu_decoder_plugin->close (this->cur_spu_decoder_plugin);
+
+ this->cur_spu_decoder_plugin = decoder;
+
+ this->cur_spu_decoder_plugin->init (this->cur_spu_decoder_plugin, this->video_out);
+ }
+
+ printf ("spu_decoder: decoder data sent\n");
+ decoder->decode_data (decoder, buf);
+ }
}
- }
+ } else
+ fprintf (stderr,"spu_decoder: unknown buffer type: %08x\n", buf->type);
}
-
+
buf->free_buffer (buf);
}
@@ -80,15 +125,9 @@ void *spu_decoder_loop (void *this_gen) {
}
void spu_decoder_init (xine_t *this) {
- buf_element_t *buf;
-
- this->spu_decoder = spudec_init(this);
this->spu_fifo = fifo_buffer_new (1500, 4096);
-
- buf = this->spu_fifo->buffer_pool_alloc (this->spu_fifo);
- buf->type = BUF_CONTROL_START;
- this->spu_fifo->put (this->spu_fifo, buf);
+ printf ("spu_decoder_init: thread starting %p\n",this->video_out);
pthread_create (&this->spu_thread, NULL, spu_decoder_loop, this) ;
}
@@ -98,15 +137,13 @@ void spu_decoder_shutdown (xine_t *this) {
buf_element_t *buf;
void *p;
- this->spu_fifo->clear(this->spu_fifo);
+ /* this->spu_fifo->clear(this->spu_fifo); */
buf = this->spu_fifo->buffer_pool_alloc (this->spu_fifo);
buf->type = BUF_CONTROL_QUIT;
this->spu_fifo->put (this->spu_fifo, buf);
- spudec_close(this->spu_decoder);
- this->spu_decoder = NULL;
-
pthread_join (this->spu_thread, &p);
}
+
diff --git a/src/xine-engine/spu_decoder.h b/src/xine-engine/spu_decoder.h
new file mode 100644
index 000000000..7ece22335
--- /dev/null
+++ b/src/xine-engine/spu_decoder.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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_decoder.h,v 1.1 2001/07/04 17:10:24 uid32519 Exp $
+ */
+#ifndef HAVE_SPU_OUT_H
+#define HAVE_SPU_OUT_H
+
+#include <inttypes.h>
+
+#if defined(XINE_COMPILE)
+#include "metronom.h"
+#include "configfile.h"
+#endif
+
+
+#define SPU_OUT_IFACE_VERSION 1
+
+/*
+ * spu_functions_s contains the functions every spu output
+ * driver plugin has to implement.
+ */
+
+typedef struct spu_functions_s spu_functions_t;
+
+struct spu_functions_s {
+
+ /*
+ *
+ * find out what output modes + capatilities are supported by
+ * this plugin (constants for the bit vector to return see above)
+ *
+ * See SPU_CAP_* bellow.
+ */
+ uint32_t (*get_capabilities) (spu_functions_t *this);
+
+ /*
+ * connect this driver to the xine engine
+ */
+ void (*connect) (spu_functions_t *this, metronom_t *metronom);
+
+ /*
+ * open the driver and make it ready to receive spu data
+ * buffers may be flushed(!)
+ *
+ * return value: <=0 : failure, 1 : ok
+ */
+
+ int (*open)(spu_functions_t *this, uint32_t bits, uint32_t rate, int mode);
+
+ /*
+ * write spu data to output buffer - may block
+ * spu driver must sync sample playback with metronom
+ */
+
+ void (*write_spu_data)(spu_functions_t *this,
+ int16_t* spu_data, uint32_t num_samples,
+ uint32_t pts);
+
+ /*
+ * this is called when the decoder no longer uses the spu
+ * output driver - the driver should get ready to get opened() again
+ */
+
+ void (*close)(spu_functions_t *this);
+
+ /*
+ * shut down this spu output driver plugin and
+ * free all resources allocated
+ */
+
+ void (*exit) (spu_functions_t *this);
+
+ /*
+ * Get, Set a property of spu driver.
+ *
+ * get_property() return 1 in success, 0 on failure.
+ * set_property() return value on success, ~value on failure.
+ *
+ * See AC_PROP_* bellow for available properties.
+ */
+ int (*get_property) (spu_functions_t *this, int property);
+
+ int (*set_property) (spu_functions_t *this, int property, int value);
+
+};
+
+
+/*
+ * to build a dynamic spu output plugin,
+ * you have to implement these functions:
+ *
+ *
+ * spu_functions_t *init_spu_out_plugin (config_values_t *config)
+ *
+ * init this plugin, check if device is available
+ *
+ * spu_info_t *get_spu_out_plugin_info ()
+ *
+ * peek at some (static) information about the plugin without initializing it
+ *
+ */
+
+/*
+ * spu output modes + capabilities
+ */
+
+#define SPU_CAP_NOCAP 0x00000000 /* Driver have no capabilities */
+#define SPU_CAP_MODE_AC3 0x00000001 /* Driver support AC3 output */
+#define SPU_CAP_MODE_AC5 0x00000002 /* Driver support AC5 output */
+/* 1 sample == 2 bytes */
+#define SPU_CAP_MODE_MONO 0x00000004 /* Driver support mono output */
+ /* 1 sample == 4 bytes */
+#define SPU_CAP_MODE_STEREO 0x00000008 /* Driver support stereo output */
+ /* 1 sample == 8 bytes */
+#define SPU_CAP_MODE_4CHANNEL 0x00000010 /* Driver support 4 channels */
+/* 1 sample == 10 bytes */
+#define SPU_CAP_MODE_5CHANNEL 0x00000020 /* Driver support 5 channels */
+#define SPU_CAP_MIXER_VOL 0x00000040 /* Driver support mixer control */
+#define SPU_CAP_PCM_VOL 0x00000080 /* Driver support pcm control */
+#define SPU_CAP_MUTE_VOL 0x00000100 /* Driver can mute volume */
+
+/* properties supported by get/set_property() */
+#define SPU_PROP_MIXER_VOL 0
+#define SPU_PROP_PCM_VOL 1
+#define SPU_PROP_MUTE_VOL 2
+
+typedef struct spu_info_s {
+
+ int interface_version;
+ char *id;
+ char *description;
+ int priority;
+} spu_info_t ;
+
+#endif
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index 3fb974022..b6a98e8d1 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000 the xine project
+ * Copyright (C) 2000, 2001 the xine project
*
* This file is part of xine, a unix video player.
*
@@ -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.27 2001/07/04 14:14:39 uid56437 Exp $
+ * $Id: video_out.c,v 1.28 2001/07/04 17:10:24 uid32519 Exp $
*
*/
@@ -29,15 +29,13 @@
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <unistd.h>
+#include <string.h>
#include "video_out.h"
#include "utils.h"
#include "monitor.h"
-#include "libspudec/spudec.h"
-
#define NUM_FRAME_BUFFERS 20
struct img_buf_fifo_s {
@@ -148,7 +146,7 @@ static void *video_out_loop (void *this_gen) {
/*
int dummysignum;
*/
- struct timespec ts;
+ /* struct timespec ts; */
/* printf ("%d video_out start\n", getpid()); */
/*
@@ -278,11 +276,6 @@ static void *video_out_loop (void *this_gen) {
img->bDisplayLock = 0;
pthread_mutex_unlock (&img->mutex);
- /* Overlay SPU FIXME: Check image format */
-
- this->spu_decoder->overlay_yuv (this->spu_decoder, pts,
- img->base[0], img->base[1], img->base[2]);
-
xprintf (VERBOSE|VIDEO, "video_out : passing to video driver, image with pts = %d\n", pts);
this->driver->display_frame (this->driver, img);
}
@@ -496,7 +489,18 @@ static int vo_frame_draw (vo_frame_t *img) {
return frames_to_skip;
}
-vo_instance_t *vo_new_instance (vo_driver_t *driver, metronom_t *metronom, spudec_t *spu_decoder) {
+static vo_overlay_t *vo_get_overlay (vo_instance_t *this,
+ int width, int height) {
+ /* FIXME: implement */
+ return NULL;
+}
+
+static void vo_queue_overlay (vo_instance_t *this, vo_overlay_t *overlay) {
+
+ /* FIXME: implement */
+}
+
+vo_instance_t *vo_new_instance (vo_driver_t *driver, metronom_t *metronom) {
vo_instance_t *this;
int i;
@@ -505,13 +509,14 @@ vo_instance_t *vo_new_instance (vo_driver_t *driver, metronom_t *metronom, spude
this->driver = driver;
this->metronom = metronom;
- this->spu_decoder = spu_decoder;
this->open = vo_open;
this->get_frame = vo_get_frame;
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->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 becfba058..a4826c61f 100644
--- a/src/xine-engine/video_out.h
+++ b/src/xine-engine/video_out.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2000-2001 the xine project
*
- * This file is part of xine, a unix video player.
+ * This file is part of xine, a free video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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.8 2001/06/18 15:43:01 richwareham Exp $
+ * $Id: video_out.h,v 1.9 2001/07/04 17:10:24 uid32519 Exp $
*
*
* xine version of video_out.h
@@ -48,8 +48,8 @@ typedef struct vo_frame_s vo_frame_t;
typedef struct vo_driver_s vo_driver_t ;
typedef struct vo_instance_s vo_instance_t;
typedef struct img_buf_fifo_s img_buf_fifo_t;
+typedef struct vo_overlay_s vo_overlay_t;
-typedef struct spudec_s spudec_t;
/* public part, video drivers may add private fields */
struct vo_frame_s {
@@ -111,6 +111,10 @@ struct vo_instance_s {
vo_frame_t* (*get_frame) (vo_instance_t *this, uint32_t width,
uint32_t height, int ratio_code,
int format, uint32_t duration);
+
+ /* overlay stuff */
+ vo_overlay_t* (*get_overlay) (vo_instance_t *this);
+ void (*queue_overlay) (vo_instance_t *this, vo_overlay_t *overlay);
/* video driver is no longer used by decoder => close */
void (*close) (vo_instance_t *this);
@@ -122,7 +126,6 @@ struct vo_instance_s {
vo_driver_t *driver;
metronom_t *metronom;
- spudec_t *spu_decoder;
img_buf_fifo_t *free_img_buf_queue;
img_buf_fifo_t *display_img_buf_queue;
@@ -188,7 +191,7 @@ struct vo_instance_s {
* from generic vo functions.
*/
-#define VIDEO_OUT_IFACE_VERSION 1
+#define VIDEO_OUT_IFACE_VERSION 2
struct vo_driver_s {
@@ -212,6 +215,10 @@ struct vo_driver_s {
/* display a given frame */
void (*display_frame) (vo_driver_t *this, vo_frame_t *vo_img);
+ /* overlay functions */
+ void (*set_overlay) (vo_driver_t *this, vo_overlay_t *overlay);
+
+
/*
* these can be used by the gui directly:
*/
@@ -236,13 +243,32 @@ struct vo_driver_s {
};
+struct vo_overlay_s {
+ uint8_t *data; /* 7-4: mixer key, 3-0: color index */
+ 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 */
+ uint8_t trans[4]; /* mixer key table */
+
+ uint32_t PTS, duration; /* 1/90000 s */
+
+ struct overlay_s *next; /* optionally more overlays */
+
+ /* 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 */
+};
/*
* build a video_out_instance from
* a given video driver
*/
-vo_instance_t *vo_new_instance (vo_driver_t *driver, metronom_t *metronom, spudec_t *spu_decoder) ;
+vo_instance_t *vo_new_instance (vo_driver_t *driver, metronom_t *metronom) ;
/*
* to build a dynamic video output plugin
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index 000401caa..c8fd4dc2a 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.31 2001/07/03 21:25:04 guenter Exp $
+ * $Id: xine.c,v 1.32 2001/07/04 17:10:24 uid32519 Exp $
*
* top-level xine functions
*
@@ -49,7 +49,8 @@
#ifdef ARCH_X86
#include "libw32dll/w32codec.h"
#endif
-#include "libspudec/spudec.h"
+#include "libspudec/spu_decoder_api.h"
+#include "spu_decoder.h"
#include "input/input_plugin.h"
#include "metronom.h"
#include "configfile.h"
@@ -95,8 +96,6 @@ void xine_stop (xine_t *this) {
this->cur_input_plugin = NULL;
}
- this->spu_fifo->clear(this->spu_fifo);
-
printf ("xine_stop: done\n");
pthread_mutex_unlock (&this->xine_lock);
@@ -364,6 +363,7 @@ xine_t *xine_init (vo_driver_t *vo,
gui_branched_cb_t branched_cb) {
xine_t *this = xmalloc (sizeof (xine_t));
+ printf("xine_init entered\n");
this->stream_end_cb = stream_end_cb;
this->get_next_mrl_cb = get_next_mrl_cb;
@@ -398,26 +398,25 @@ xine_t *xine_init (vo_driver_t *vo,
this->cur_input_pos = 0;
/*
- * init SPU decoder (must be done before video decoder
- * so that this->spu_decoder is valid).
- */
- spu_decoder_init (this);
-
- /*
* init and start decoder threads
*/
load_decoder_plugins (this, config, DECODER_PLUGIN_IFACE_VERSION);
- this->video_out = vo_new_instance (vo, this->metronom, this->spu_decoder);
+ this->video_out = vo_new_instance (vo, this->metronom);
video_decoder_init (this);
+ /*
+ * init SPU decoder (must be done before video decoder
+ * so that this->spu_decoder is valid).
+ */
+ spu_decoder_init (this);
if(ao) {
this->audio_out = ao;
this->audio_out->connect (this->audio_out, this->metronom);
}
audio_decoder_init (this);
-
+ printf("xine_init returning\n");
return this;
}
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
index 9712196cf..2269c2117 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.26 2001/06/23 14:05:47 f1rmb Exp $
+ * $Id: xine_internal.h,v 1.27 2001/07/04 17:10:24 uid32519 Exp $
*
*/
@@ -30,6 +30,8 @@
#include "video_out.h"
#include "audio_out.h"
#include "metronom.h"
+#include "spu_decoder.h"
+#include "libspudec/spu_decoder_api.h"
#define INPUT_PLUGIN_MAX 50
#define DEMUXER_PLUGIN_MAX 50
@@ -128,9 +130,15 @@ typedef struct xine_s {
off_t cur_input_pos;
char cur_mrl[1024];
+ spu_functions_t *spu_out;
fifo_buffer_t *spu_fifo;
pthread_t spu_thread;
- spudec_t *spu_decoder;
+ spu_decoder_t *spu_decoder_plugins[DECODER_PLUGIN_MAX];
+ int num_spu_decoder_plugins;
+ spu_decoder_t *cur_spu_decoder_plugin;
+ uint32_t spu_track_map[50];
+ int spu_track_map_entries;
+ int spu_finished;
int audio_channel;
int spu_channel;