summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2002-05-24 22:09:44 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2002-05-24 22:09:44 +0000
commit1c7516dd16d95fdbf862db13153810a92644f330 (patch)
tree6e5c9514c00f534bb4c6ac135b9dc46f8bb59ee7
parent1c13f131692c6c42021a45dcc209f7ec6ef611a7 (diff)
downloadxine-lib-1c7516dd16d95fdbf862db13153810a92644f330.tar.gz
xine-lib-1c7516dd16d95fdbf862db13153810a92644f330.tar.bz2
- dxr3 cleanup from Michael Roitzsch <amalthea@freenet.de>
- audio fifo size adjust CVS patchset: 1937 CVS date: 2002/05/24 22:09:44
-rw-r--r--src/dxr3/Makefile.am8
-rw-r--r--src/dxr3/dxr3.h7
-rw-r--r--src/dxr3/dxr3_decode_spu.c21
-rw-r--r--src/dxr3/dxr3_decode_video.c14
-rw-r--r--src/dxr3/dxr3_mpeg_encoders.c543
-rw-r--r--src/dxr3/dxr3_scr.c9
-rw-r--r--src/dxr3/dxr3_scr.h5
-rw-r--r--src/dxr3/dxr3_video_out.c648
-rw-r--r--src/dxr3/dxr3_video_out.h192
-rw-r--r--src/dxr3/dxr3_vo_core.c801
-rw-r--r--src/dxr3/mpeg_encoders.c453
-rw-r--r--src/dxr3/video_out_dxr3.c1221
-rw-r--r--src/dxr3/video_out_dxr3.h132
-rw-r--r--src/xine-engine/audio_decoder.c11
-rw-r--r--src/xine-engine/video_decoder.c9
15 files changed, 1953 insertions, 2121 deletions
diff --git a/src/dxr3/Makefile.am b/src/dxr3/Makefile.am
index ae9d535c7..d0fc11bc2 100644
--- a/src/dxr3/Makefile.am
+++ b/src/dxr3/Makefile.am
@@ -22,13 +22,11 @@ xineplug_decode_dxr3_video_la_LDFLAGS = -avoid-version -module
xineplug_decode_dxr3_spu_la_SOURCES = dxr3_decode_spu.c nav_read.c
xineplug_decode_dxr3_spu_la_LDFLAGS = -avoid-version -module
-xineplug_vo_out_dxr3_la_SOURCES = dxr3_video_out.c \
- dxr3_vo_core.c mpeg_encoders.c alphablend.c
+xineplug_vo_out_dxr3_la_SOURCES = video_out_dxr3.c dxr3_mpeg_encoders.c alphablend.c
xineplug_vo_out_dxr3_la_LIBADD = $(X_LIBS) -lXext
-xineplug_vo_out_dxr3_la_LDFLAGS = -avoid-version \
- -module $(link_fame) $(link_rte) $(X_LIBS)
+xineplug_vo_out_dxr3_la_LDFLAGS = -avoid-version -module $(link_fame) $(link_rte) $(X_LIBS)
-noinst_HEADERS = dxr3.h dxr3_scr.h dxr3_video_out.h nav_types.h nav_read.h alphablend.h bswap.h
+noinst_HEADERS = dxr3.h dxr3_scr.h video_out_dxr3.h nav_types.h nav_read.h alphablend.h bswap.h
debug:
@$(MAKE) CFLAGS="$(DEBUG_CFLAGS) $(LINUX_INCLUDE)"
diff --git a/src/dxr3/dxr3.h b/src/dxr3/dxr3.h
index f6d3cc2d9..c17708e11 100644
--- a/src/dxr3/dxr3.h
+++ b/src/dxr3/dxr3.h
@@ -17,9 +17,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: dxr3.h,v 1.1 2002/05/06 11:26:37 jcdutton Exp $
+ * $Id: dxr3.h,v 1.2 2002/05/24 22:09:44 miguelfreitas Exp $
*/
+#ifndef HAVE_DXR3_H
+#define HAVE_DXR3_H
+
#include <linux/em8300.h>
/* data for the device name config entry */
@@ -30,3 +33,5 @@
/* image format used by dxr3_decoder to tag undecoded mpeg data */
#define IMGFMT_MPEG (('G'<<24)|('E'<<16)|('P'<<8)|'M')
+
+#endif
diff --git a/src/dxr3/dxr3_decode_spu.c b/src/dxr3/dxr3_decode_spu.c
index 3b9b78f8a..31649cf62 100644
--- a/src/dxr3/dxr3_decode_spu.c
+++ b/src/dxr3/dxr3_decode_spu.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: dxr3_decode_spu.c,v 1.2 2002/05/06 11:26:37 jcdutton Exp $
+ * $Id: dxr3_decode_spu.c,v 1.3 2002/05/24 22:09:44 miguelfreitas Exp $
*/
/* dxr3 spu decoder plugin.
@@ -26,7 +26,6 @@
* Takes precedence over libspudec due to a higher priority.
*/
-
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
@@ -82,10 +81,10 @@ typedef struct dxr3_spudec_s {
char devname[128];
char devnum[3];
- int fd_spu; /* to access the dxr3 spu device */
+ int fd_spu; /* to access the dxr3 spu device */
dxr3_spu_stream_state_t spu_stream_state[MAX_SPU_STREAMS];
- int menu; /* are we in a menu? */
+ int menu; /* are we in a menu? */
pci_t pci;
uint32_t buttonN; /* currently highlighted button */
} dxr3_spudec_t;
@@ -94,7 +93,7 @@ typedef struct dxr3_spudec_s {
spu_decoder_t *init_spu_decoder_plugin(int iface_version, xine_t *xine)
{
dxr3_spudec_t *this;
- char *confstr;
+ const char *confstr;
int dashpos;
if (iface_version != 7) {
@@ -108,6 +107,7 @@ spu_decoder_t *init_spu_decoder_plugin(int iface_version, xine_t *xine)
if (!dxr3_present(xine)) return NULL;
this = (dxr3_spudec_t *)malloc(sizeof(dxr3_spudec_t));
+ if (!this) return NULL;
confstr = xine->config->register_string(xine->config,
CONF_LOOKUP, CONF_DEFAULT, CONF_NAME, CONF_HELP, NULL, NULL);
@@ -195,7 +195,7 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf)
printf("dxr3_decode_spu: failed to set CLUT (%s)\n", strerror(errno));
return;
}
- if(buf->type == BUF_SPU_SUBP_CONTROL) {
+ if(buf->type == BUF_SPU_SUBP_CONTROL) {
/* FIXME: is BUF_SPU_SUBP_CONTROL used anymore? */
int i;
uint32_t *subp_control = (uint32_t *)buf->content;
@@ -230,9 +230,18 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf)
}
if ((pci.hli.hl_gi.hli_ss == 0) && (this->pci.hli.hl_gi.hli_ss == 1)) {
+ /* this is (or: should be, I hope I got this right) a
+ subpicture plane, that hides all menu buttons */
+ uint8_t empty_spu[] = {
+ 0x00, 0x26, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x20, 0x01, 0x03, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x01, 0x06, 0x00, 0x04, 0x00, 0x07, 0xFF,
+ 0x00, 0x01, 0x00, 0x20, 0x02, 0xFF };
/* leaving menu */
this->pci.hli.hl_gi.hli_ss = 0;
ioctl(this->fd_spu, EM8300_IOCTL_SPU_BUTTON, NULL);
+ write(this->fd_spu, empty_spu, sizeof(empty_spu));
}
}
return;
diff --git a/src/dxr3/dxr3_decode_video.c b/src/dxr3/dxr3_decode_video.c
index cb6bbfdb7..10c07700e 100644
--- a/src/dxr3/dxr3_decode_video.c
+++ b/src/dxr3/dxr3_decode_video.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: dxr3_decode_video.c,v 1.2 2002/05/06 11:26:37 jcdutton Exp $
+ * $Id: dxr3_decode_video.c,v 1.3 2002/05/24 22:09:44 miguelfreitas Exp $
*/
/* dxr3 video decoder plugin.
@@ -26,7 +26,6 @@
* due to a higher priority.
*/
-
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdio.h>
@@ -102,6 +101,8 @@ static int dxr3_present(xine_t *xine);
static int dxr3_mvcommand(int fd_control, int command);
static void parse_mpeg_header(dxr3_decoder_t *this, uint8_t *buffer);
static int get_duration(int framecode, int repeat_first_field);
+
+/* config callbacks */
static void dxr3_update_priority(void *this_gen, cfg_entry_t *entry);
static void dxr3_update_sync_mode(void *this_gen, cfg_entry_t *entry);
static void dxr3_update_enhanced_mode(void *this_gen, cfg_entry_t *entry);
@@ -111,7 +112,7 @@ video_decoder_t *init_video_decoder_plugin(int iface_version, xine_t *xine)
{
dxr3_decoder_t *this;
config_values_t *cfg;
- char *tmpstr;
+ const char *confstr;
int dashpos;
if (iface_version != 8) {
@@ -125,10 +126,11 @@ video_decoder_t *init_video_decoder_plugin(int iface_version, xine_t *xine)
if (!dxr3_present(xine)) return NULL;
this = (dxr3_decoder_t *)malloc(sizeof (dxr3_decoder_t));
+ if (!this) return NULL;
cfg = xine->config;
- tmpstr = cfg->register_string(cfg, CONF_LOOKUP, CONF_DEFAULT, CONF_NAME, CONF_HELP, NULL, NULL);
- strncpy(this->devname, tmpstr, 128);
+ confstr = cfg->register_string(cfg, CONF_LOOKUP, CONF_DEFAULT, CONF_NAME, CONF_HELP, NULL, NULL);
+ strncpy(this->devname, confstr, 128);
this->devname[127] = '\0';
dashpos = strlen(this->devname) - 2; /* the dash in the new device naming scheme would be here */
if (this->devname[dashpos] == '-') {
@@ -240,7 +242,7 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf)
*/
buffer = buf->content;
shift = 0xffffff00;
- for (i=0; i<buf->size; i++) {
+ for (i = 0; i < buf->size; i++) {
byte = *buffer++;
if (shift != 0x00000100) {
shift = (shift | byte) << 8;
diff --git a/src/dxr3/dxr3_mpeg_encoders.c b/src/dxr3/dxr3_mpeg_encoders.c
new file mode 100644
index 000000000..4dfc4cccb
--- /dev/null
+++ b/src/dxr3/dxr3_mpeg_encoders.c
@@ -0,0 +1,543 @@
+/*
+ * 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: dxr3_mpeg_encoders.c,v 1.1 2002/05/24 22:09:44 miguelfreitas Exp $
+ */
+
+/* mpeg encoders for the dxr3 video out plugin.
+ * supports the libfame and librte mpeg encoder libraries.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_LIBRTE
+# define _GNU_SOURCE
+# include <unistd.h>
+# include <rte.h>
+#endif
+#ifdef HAVE_LIBFAME
+# include <fame.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+
+#include "xineutils.h"
+#include "video_out_dxr3.h"
+
+#define LOG_ENC 1
+
+/* buffer size for encoded mpeg1 stream; will hold one intra frame
+ * at 640x480 typical sizes are <50 kB. 512 kB should be plenty */
+#define DEFAULT_BUFFER_SIZE 512*1024
+
+
+#ifdef HAVE_LIBRTE
+/* initialization function */
+int dxr3_rte_init(dxr3_driver_t *drv);
+
+/* functions required by encoder api */
+static int rte_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame);
+static int rte_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame);
+static int rte_on_close(dxr3_driver_t *drv);
+
+/* helper function */
+static void mp1e_callback(rte_context *context, void *data, ssize_t size,
+ void *user_data);
+
+/* encoder structure */
+typedef struct rte_data_s {
+ encoder_data_t encoder_data;
+ rte_context *context; /* handle for encoding */
+ int width, height;
+ void *rte_ptr; /* buffer maintened by librte */
+ double rte_bitrate; /* mpeg out bitrate, default 2.3e6 bits/s */
+} rte_data_t;
+#endif
+
+#ifdef HAVE_LIBFAME
+/* initialization function */
+int dxr3_fame_init(dxr3_driver_t *drv);
+
+/* functions required by encoder api */
+static int fame_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame);
+static int fame_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame);
+static int fame_on_close(dxr3_driver_t *drv);
+
+/* encoder structure */
+typedef struct {
+ encoder_data_t encoder_data;
+ fame_context_t *context; /* needed for fame calls */
+ fame_parameters_t fp;
+ fame_yuv_t yuv;
+ char *buffer; /* temporary buffer for mpeg data */
+ /* temporary buffer for YUY2->YV12 conversion */
+ uint8_t *out[3]; /* aligned buffer for YV12 data */
+ uint8_t *buf; /* unaligned YV12 buffer */
+} fame_data_t;
+
+/* helper function */
+static int fame_prepare_frame(fame_data_t *this, dxr3_driver_t *drv,
+ dxr3_frame_t *frame);
+#endif
+
+
+#ifdef HAVE_LIBRTE
+int dxr3_rte_init(dxr3_driver_t *drv)
+{
+ rte_data_t* this;
+
+ if (!rte_init()) {
+ printf("dxr3_mpeg_encoder: failed to init librte\n");
+ return 0;
+ }
+
+ this = malloc(sizeof(rte_data_t));
+ if (!this) return 0;
+ memset(this, 0, sizeof(rte_data_t));
+
+ this->encoder_data.type = ENC_RTE;
+ this->encoder_data.on_update_format = rte_on_update_format;
+ this->encoder_data.on_frame_copy = NULL;
+ this->encoder_data.on_display_frame = rte_on_display_frame;
+ this->encoder_data.on_close = rte_on_close;
+ this->context = 0;
+
+ drv->enc = &this->encoder_data;
+ return 1;
+}
+
+static int rte_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame)
+{
+ rte_data_t *this = (rte_data_t *)drv->enc;
+ rte_context *context;
+ rte_codec *codec;
+ double fps;
+
+ if (this->context) { /* already running */
+#if LOG_ENC
+ printf("dxr3_mpeg_encoder: closing current encoding context.\n");
+#endif
+ rte_stop(this->context);
+ rte_context_destroy(this->context);
+ this->context = 0;
+ }
+
+ this->width = drv->video_width;
+ this->height = drv->video_oheight;
+
+ /* create new rte context */
+ this->context = rte_context_new(this->width, this->height, "mp1e", drv);
+ if (!this->context) {
+ printf("dxr3_mpeg_encoder: failed to get rte context.\n");
+ return 0;
+ }
+ context = this->context; /* shortcut */
+#if LOG_ENC
+ rte_set_verbosity(context, 2);
+#endif
+
+ /* get mpeg codec handle */
+ codec = rte_codec_set(context, RTE_STREAM_VIDEO, 0, "mpeg1_video");
+ if (!codec) {
+ printf("dxr3_mpeg_encoder: could not create codec.\n");
+ rte_context_destroy(context);
+ this->context = 0;
+ return 0;
+ }
+
+ this->rte_bitrate = drv->config->register_range(drv->config,
+ "dxr3.rte_bitrate", 10000, 1000, 20000,
+ "Dxr3enc: rte mpeg output bitrate (kbit/s)",
+ "The bitrate the mpeg encoder library librte should use for dxr3's encoding mode",
+ NULL, NULL);
+ this->rte_bitrate *= 1000; /* config in kbit/s, rte wants bit/s */
+
+ /* FIXME: this needs to be replaced with a codec option call.
+ * However, there seems to be none for the colour format!
+ * So we'll use the deprecated set_video_parameters instead.
+ * Alternative is to manually set context->video_format (RTE_YU... )
+ * and context->video_bytes (= width * height * bytes/pixel)
+ */
+ rte_set_video_parameters(context,
+ (drv->format == IMGFMT_YV12 ? RTE_YUV420 : RTE_YUYV),
+ context->width, context->height,
+ context->video_rate, context->output_video_bits,
+ context->gop_sequence);
+
+ /* Now set a whole bunch of codec options
+ * If I understand correctly, virtual_frame_rate is the frame rate
+ * of the source (can be anything), while coded_frame_rate must be
+ * one of the mpeg1 alloweds
+ */
+ fps = 90000.0 / frame->vo_frame.duration;
+ if (!rte_option_set(codec, "virtual_frame_rate", fps))
+ printf("dxr3_mpeg_encoder: WARNING: rte_option_set failed; virtual_frame_rate = %g.\n", fps);
+ if (!rte_option_set(codec, "coded_frame_rate", fps))
+ printf("dxr3_mpeg_encoder: WARNING: rte_option_set failed; coded_frame_rate = %g.\n", fps);
+ if (!rte_option_set(codec, "bit_rate", (int)this->rte_bitrate))
+ printf("dxr3_mpeg_encoder: WARNING: rte_option_set failed; bit_rate = %d.\n", (int)this->rte_bitrate);
+ if (!rte_option_set(codec, "gop_sequence", "I"))
+ printf("dxr3_mpeg_encoder: WARNING: rte_option_set failed; gop_sequence = \"I\".\n");
+ /* just to be sure, disable motion comp (not needed in I frames) */
+ if (!rte_option_set(codec, "motion_compensation", 0))
+ printf("dxr3_mpeg_encoder: WARNING: rte_option_set failed; motion_compensation = 0.\n");
+
+ rte_set_input(context, RTE_VIDEO, RTE_PUSH, FALSE, NULL, NULL, NULL);
+ rte_set_output(context, mp1e_callback, NULL, NULL);
+
+ if (!rte_init_context(context)) {
+ printf("dxr3_mpeg_encoder: cannot init the context: %s\n", context->error);
+ rte_context_destroy(context);
+ this->context = 0;
+ return 0;
+ }
+ /* do the sync'ing and start encoding */
+ if (!rte_start_encoding(context)) {
+ printf("dxr3_mpeg_encoder: cannot start encoding: %s\n", context->error);
+ rte_context_destroy(context);
+ this->context = 0;
+ return 0;
+ }
+ this->rte_ptr = rte_push_video_data(context, NULL, 0);
+ if (!this->rte_ptr) {
+ printf("dxr3_mpeg_encoder: failed to get encoder buffer pointer.\n");
+ return 0;
+ }
+
+ /* set the dxr3 playmode */
+ if (drv->enhanced_mode) {
+ em8300_register_t regs;
+ regs.microcode_register = 1;
+ regs.reg = 0;
+ regs.val = MVCOMMAND_SYNC;
+ ioctl(drv->fd_control, EM8300_IOCTL_WRITEREG, &regs);
+ }
+
+ return 1;
+}
+
+static int rte_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame)
+{
+ int size;
+ rte_data_t* this = (rte_data_t *)drv->enc;
+
+ if ((this->width != frame->width) || (this->height != frame->oheight))
+ /* maybe we were reinitialized and get an old frame. */
+ return 1;
+
+ size = frame->width * frame->oheight;
+ if (frame->vo_frame.format == IMGFMT_YV12)
+ xine_fast_memcpy(this->rte_ptr, frame->real_base[0], size * 3/2);
+ else
+ xine_fast_memcpy(this->rte_ptr, frame->real_base[0], size * 2);
+ this->rte_ptr = rte_push_video_data(this->context, this->rte_ptr,
+ frame->vo_frame.vpts / 90000.0);
+
+ frame->vo_frame.displayed(&frame->vo_frame);
+ return 1;
+}
+
+static int rte_on_close(dxr3_driver_t *drv)
+{
+ rte_data_t *this = (rte_data_t *)drv->enc;
+
+ if (this->context) {
+ rte_stop(this->context);
+ rte_context_destroy(this->context);
+ }
+ free(this);
+ drv->enc = 0;
+ return 1;
+}
+
+
+static void mp1e_callback(rte_context *context, void *data, ssize_t size, void *user_data)
+{
+ dxr3_driver_t *drv = (dxr3_driver_t *)user_data;
+ char tmpstr[128];
+ ssize_t written;
+
+ if (drv->fd_video == CLOSED_FOR_ENCODER) {
+ snprintf(tmpstr, sizeof(tmpstr), "%s_mv%s", drv->devname, drv->devnum);
+ drv->fd_video = open(tmpstr, O_WRONLY | O_NONBLOCK);
+ }
+ if (drv->fd_video < 0) return;
+ written = write(drv->fd_video, data, size);
+ if (written < 0) {
+ printf("dxr3_mpeg_encoder: video device write failed (%s)\n",
+ strerror(errno));
+ return;
+ }
+ if (written != size)
+ printf("dxr3_mpeg_encoder: Could only write %d of %d mpeg bytes.\n",
+ written, size);
+}
+#endif
+
+
+#ifdef HAVE_LIBFAME
+int dxr3_fame_init(dxr3_driver_t *drv)
+{
+ fame_data_t *this;
+
+ this = malloc(sizeof(fame_data_t));
+ if (!this) return 0;
+ memset(this, 0, sizeof(fame_data_t));
+
+ this->encoder_data.type = ENC_FAME;
+ this->encoder_data.on_update_format = fame_on_update_format;
+ this->encoder_data.on_frame_copy = NULL;
+ this->encoder_data.on_display_frame = fame_on_display_frame;
+ this->encoder_data.on_close = fame_on_close;
+ this->context = 0;
+
+ drv->enc = &this->encoder_data;
+ return 1;
+}
+
+static int fame_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame)
+{
+ fame_data_t *this = (fame_data_t *)drv->enc;
+ fame_parameters_t init_fp = FAME_PARAMETERS_INITIALIZER;
+ double fps;
+
+ if (this->buf) free(this->buf);
+ this->buf = 0;
+ this->out[0] = this->out[1] = this->out[2] = 0;
+
+ /* if YUY2 and dimensions changed, we need to re-allocate the
+ * internal YV12 buffer */
+ if (drv->format == IMGFMT_YUY2) {
+ int image_size = drv->video_width * drv->video_oheight;
+
+ this->out[0] = xine_xmalloc_aligned(16, image_size * 3/2,
+ (void *)&this->buf);
+ this->out[1] = this->out[0] + image_size;
+ this->out[2] = this->out[1] + image_size/4;
+
+ /* fill with black (yuv 16,128,128) */
+ memset(this->out[0], 16, image_size);
+ memset(this->out[1], 128, image_size/4);
+ memset(this->out[2], 128, image_size/4);
+#if LOG_ENC
+ printf("dxr3_mpeg_encoder: Using YUY2->YV12 conversion\n");
+#endif
+ }
+
+ if (this->context) {
+#if LOG_ENC
+ printf("dxr3_mpeg_encoder: closing current encoding context.\n");
+#endif
+ fame_close(this->context);
+ this->context = 0;
+ }
+
+ this->context = fame_open();
+ if (!this->context) {
+ printf("dxr3_mpeg_encoder: Couldn't start the FAME library\n");
+ return 0;
+ }
+
+ if (!this->buffer)
+ this->buffer = (unsigned char *)malloc(DEFAULT_BUFFER_SIZE);
+ if (!this->buffer) {
+ printf("dxr3_mpeg_encoder: Couldn't allocate temp buffer for mpeg data\n");
+ return 0;
+ }
+
+ this->fp = init_fp;
+ this->fp.quality = drv->config->register_range(drv->config,
+ "dxr3.fame_quality", 90, 10, 100,
+ "Dxr3enc: fame mpeg encoding quality",
+ "The encoding quality of the libfame mpeg encoder library.",
+ NULL,NULL);
+#if LOG_ENC
+ /* the really interesting bit is the quantizer scale. The formula
+ * below is copied from libfame's sources (could be changed in the
+ * future) */
+ printf("dxr3_mpeg_encoder: quality %d -> quant scale = %d\n", this->fp.quality,
+ 1 + (30 * (100 - this->fp.quality) + 50) / 100);
+#endif
+ this->fp.width = drv->video_width;
+ this->fp.height = drv->video_oheight;
+ this->fp.profile = "mpeg1";
+ this->fp.coding = "I";
+#if LOG_ENC
+ this->fp.verbose = 1;
+#else
+ this->fp.verbose = 0;
+#endif
+
+ /* start guessing the framerate */
+ fps = 90000.0 / frame->vo_frame.duration;
+ if (fabs(fps - 25) < 0.01) { /* PAL */
+#if LOG_ENC
+ printf("dxr3_mpeg_encoder: setting mpeg output framerate to PAL (25 Hz)\n");
+#endif
+ this->fp.frame_rate_num = 25;
+ this->fp.frame_rate_den = 1;
+ }
+ else if (fabs(fps - 24) < 0.01) { /* FILM */
+#if LOG_ENC
+ printf("dxr3_mpeg_encoder: setting mpeg output framerate to FILM (24 Hz)\n");
+#endif
+ this->fp.frame_rate_num = 24;
+ this->fp.frame_rate_den = 1;
+ }
+ else if (fabs(fps - 23.976) < 0.01) { /* NTSC-FILM */
+#if LOG_ENC
+ printf("dxr3_mpeg_encoder: setting mpeg output framerate to NTSC-FILM (23.976 Hz)\n");
+#endif
+ this->fp.frame_rate_num = 24000;
+ this->fp.frame_rate_den = 1001;
+ }
+ else if (fabs(fps - 29.97) < 0.01) { /* NTSC */
+#if LOG_ENC
+ printf("dxr3_mpeg_encoder: setting mpeg output framerate to NTSC (29.97 Hz)\n");
+#endif
+ this->fp.frame_rate_num = 30000;
+ this->fp.frame_rate_den = 1001;
+ }
+ else { /* try 1/fps, if not legal, libfame will go to PAL */
+ this->fp.frame_rate_num = (int)(fps + 0.5);
+ this->fp.frame_rate_den = 1;
+#if LOG_ENC
+ printf("dxr3_mpeg_encoder: trying to set mpeg output framerate to %d Hz\n",
+ this->fp.frame_rate_num);
+#endif
+ }
+
+ fame_init (this->context, &this->fp, this->buffer, DEFAULT_BUFFER_SIZE);
+
+ /* set the dxr3 playmode */
+ if (drv->enhanced_mode) {
+ em8300_register_t regs;
+ regs.microcode_register = 1;
+ regs.reg = 0;
+ regs.val = MVCOMMAND_SYNC;
+ ioctl(drv->fd_control, EM8300_IOCTL_WRITEREG, &regs);
+ }
+
+ return 1;
+}
+
+static int fame_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame)
+{
+ fame_data_t *this = (fame_data_t *)drv->enc;
+ char tmpstr[128];
+ ssize_t written;
+ int size;
+
+ if ((frame->width != this->fp.width) || (frame->oheight != this->fp.height))
+ /* probably an old frame for a previous context. ignore it */
+ return 1;
+
+ fame_prepare_frame(this, drv, frame);
+ size = fame_encode_frame(this->context, &this->yuv, NULL);
+ frame->vo_frame.displayed(&frame->vo_frame);
+
+ if (drv->fd_video == CLOSED_FOR_ENCODER) {
+ snprintf (tmpstr, sizeof(tmpstr), "%s_mv%s", drv->devname, drv->devnum);
+ drv->fd_video = open(tmpstr, O_WRONLY | O_NONBLOCK);
+ }
+ if (drv->fd_video < 0) return 0;
+ written = write(drv->fd_video, this->buffer, size);
+ if (written < 0) {
+ printf("dxr3_mpeg_encoder: video device write failed (%s)\n",
+ strerror(errno));
+ return 0;
+ }
+ if (written != size)
+ printf("dxr3_mpeg_encoder: Could only write %d of %d mpeg bytes.\n",
+ written, size);
+ return 1;
+}
+
+static int fame_on_close(dxr3_driver_t *drv)
+{
+ fame_data_t *this = (fame_data_t *)drv->enc;
+
+ if (this->context)
+ fame_close(this->context);
+ free(this);
+ drv->enc = 0;
+ return 1;
+}
+
+
+static int fame_prepare_frame(fame_data_t *this, dxr3_driver_t *drv, dxr3_frame_t *frame)
+{
+ int i, j, w2;
+ uint8_t *y, *u, *v, *yuy2;
+
+ if (frame->vo_frame.bad_frame) return 1;
+
+ if (frame->vo_frame.format == IMGFMT_YUY2) {
+ /* need YUY2->YV12 conversion */
+ if (!(this->out[0] && this->out[1] && this->out[2]) ) {
+ printf("dxr3_mpeg_encoder: Internal YV12 buffer not created.\n");
+ return 0;
+ }
+ y = this->out[0] + frame->width * drv->top_bar;
+ u = this->out[1] + frame->width/2 * (drv->top_bar / 2);
+ v = this->out[2] + frame->width/2 * (drv->top_bar / 2);
+ yuy2 = frame->vo_frame.base[0];
+ w2 = frame->width / 2;
+ for (i = 0; i < frame->iheight; i += 2) {
+ for (j = 0; j < w2; j++) {
+ /* packed YUV 422 is: Y[i] U[i] Y[i+1] V[i] */
+ *(y++) = *(yuy2++);
+ *(u++) = *(yuy2++);
+ *(y++) = *(yuy2++);
+ *(v++) = *(yuy2++);
+ }
+ /* down sampling */
+ for (j = 0; j < w2; j++) {
+ /* skip every second line for U and V */
+ *(y++) = *(yuy2++);
+ yuy2++;
+ *(y++) = *(yuy2++);
+ yuy2++;
+ }
+ }
+ /* reset for encoder */
+ y = this->out[0];
+ u = this->out[1];
+ v = this->out[2];
+ }
+ else { /* YV12 */
+ y = frame->real_base[0];
+ u = frame->real_base[1];
+ v = frame->real_base[2];
+ }
+
+ this->yuv.y = y;
+ this->yuv.u = u;
+ this->yuv.v = v;
+ return 1;
+}
+#endif
diff --git a/src/dxr3/dxr3_scr.c b/src/dxr3/dxr3_scr.c
index 2ddfb6844..97cfb9bdf 100644
--- a/src/dxr3/dxr3_scr.c
+++ b/src/dxr3/dxr3_scr.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: dxr3_scr.c,v 1.1 2002/05/06 11:26:37 jcdutton Exp $
+ * $Id: dxr3_scr.c,v 1.2 2002/05/24 22:09:44 miguelfreitas Exp $
*/
/* dxr3 scr plugin.
@@ -25,17 +25,14 @@
* global time reference.
*/
-
#include <sys/ioctl.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
-#include "xine_internal.h"
#include "xineutils.h"
#include "dxr3.h"
-
#include "dxr3_scr.h"
#define LOG_SCR 0
@@ -51,13 +48,15 @@ static void dxr3_scr_exit(scr_plugin_t *scr);
/* helper function */
static int dxr3_mvcommand(int fd_control, int command);
+
+/* config callback */
static void dxr3_scr_update_priority(void *this_gen, cfg_entry_t *entry);
dxr3_scr_t *dxr3_scr_init(xine_t *xine)
{
dxr3_scr_t *this;
- char *confstr;
+ const char *confstr;
this = (dxr3_scr_t *)malloc(sizeof(dxr3_scr_t));
diff --git a/src/dxr3/dxr3_scr.h b/src/dxr3/dxr3_scr.h
index b0814ebd8..8260ce3f0 100644
--- a/src/dxr3/dxr3_scr.h
+++ b/src/dxr3/dxr3_scr.h
@@ -17,9 +17,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: dxr3_scr.h,v 1.1 2002/05/06 11:26:37 jcdutton Exp $
+ * $Id: dxr3_scr.h,v 1.2 2002/05/24 22:09:44 miguelfreitas Exp $
*/
+#include "xine_internal.h"
+
+
/* plugin structure */
typedef struct dxr3_scr_s {
scr_plugin_t scr_plugin;
diff --git a/src/dxr3/dxr3_video_out.c b/src/dxr3/dxr3_video_out.c
deleted file mode 100644
index 29edf5c5e..000000000
--- a/src/dxr3/dxr3_video_out.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- * 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: dxr3_video_out.c,v 1.16 2002/05/06 11:26:37 jcdutton Exp $
- *
- * mpeg1 encoding video out plugin for the dxr3.
- *
- * modifications to the original dxr3 video out plugin by
- * Mike Lampard <mike at web2u.com.au>
- * this first standalone version by
- * Harm van der Heijden <hrm at users.sourceforge.net>
- *
- * Changes are mostly in dxr3_update_frame_format() (init stuff),
- * dxr3_frame_copy() (encoding), and dxr3_display_frame() (send stream
- * to device). The driver and frame structs are changed too.
- *
- * What it does
- * - automatically insert black borders to correct a.r. to 16:9 of 4:3
- * if needed (these are the only ones that dxr3 supports).
- * - detect framerate from frame's duration value and set it as mpeg1's
- * framerate. We are hampered a little by the fact that mpeg1 supports
- * a limited number of frame rates. Most notably 23.976 (NTSC-FILM)
- * is missing
- * - (ab)uses the vo_frame_t->copy() function to encode mpeg1 as soon as
- * the frame is available.
- * - full support for YUY2 output; automatic conversion to YV12
- *
- * TODO:
- * - try ffmpeg encoder instead of libfame
- * - jerkiness issues with mpeg1 output (possibly fixed, see below)
- * - sync issues (possibly fixed, see below)
- * - split off code that is shared with original dxr3 decoder, for
- * maintainability of the whole thing.
- * - init; sometimes (usually first time after boot) there's no output
- * to tv. The second attempt usually works.
- * - test with overlay (haven't figured out yet how to get it working
- * on my system, not even with standard dxr3 driver -- harm)
- *
- ***** Update 28/10/2001 by Harm
- *
- * I've implemented a method for buffering the mpeg data
- * (basically copying it to the frame) for display (read: write to mpeg
- * device) when xine requests it via dxr3_frame_display. It helps sync,
- * but playback is still not smooth.
- *
- * buffering enabled by default, see USE_MPEG_BUFFER define.
- *
- * Moved the mpeg device (/dev/em8300_fd) file descriptor to vo_driver_t;
- * very weird: to be able to use it in frame_display, I must reopen it
- * there! Is that a thread thing or something? Normally you'd open it in
- * the driver's init function.
- *
- ***** Update 29/10/2001 by Harm
- *
- * Mike Lampard figured out a solution to the jerky playback problem that
- * seems to work well; write the value 6 to the MV_COMMAND register!
- * I'm guessing this puts the dxr3 playback in some sort of scan mode
- * where it plays frames as soon as it can. This combines well with our
- * method because we deliver them when they need displaying.
- *
- * This fix is turned on/off by setting USE_MAGIC_REGISTER to 1/0.
- *
- * Note, we write to the register at every frame; possibly overkill, but
- * there seems to be no noticeable overhead and better safe than sorry...
- *
- * If you still get occasional jerky playback, try lowering the
- * mpeg1 encoding qualtiy (.xinerc var dxr3enc_quality) first. On my
- * system, there are occasional scenes with high entropy that libfame
- * can't encode at hi quality and 25 fps. Remember, the time it takes
- * to encode a frame is not fixed but depends on the complexity!
- *
- * You wanna hear a funny thing? With the register fix in place, it no
- * longer seems to matter whether USE_MPEG_BUFFER is on or off; in both
- * cases A/V sync seems fine! Weird... I'm leaving it on for the moment,
- * to be safe. It should give the encoder the option to spend more than
- * 1/fps on occasional frames.
- *
- * Other changes:
- * - .xinerc: renamed dxr3_enc_quality to dxr3enc_quality
- * - .xinerc: added dxr3_file for output of mpeg stream to file, for
- * debugging. set to <none> or delete the entry to send stream to dxr3.
- *
- ***** Update 29/10/2001 (later) by Harm
- *
- * Added support for encoding using libavcodec from ffmpeg. See the defines
- * USE_LIBFAME and USE_FFMPEG (mutually exclusive)
- * These defines are getting quite messy; there's three of them now.
- * Need to make some decisions soon :-)
- *
- * If using ffmpeg, do not link against libavcodec from xine sources!
- * There's something wrong with that one, you'll get rubbish output.
- * Get the ffmpeg cvs, compile, then copy libavcodec.a to /usr/local/lib
- * or something.
- *
- * At the moment libffmpeg's encoder output is pretty crappy, with weird
- * ghost effects left and right of objects. At the moment using a fixed
- * quantizer value. Somewhat more cpu intensive than libfame.
- *
- ***** Update 1/12/2001 by Harm
- * some support for mp1e encoder. Needs the raw-input patch for mp1e to
- * be functional. I'm sending that patch to the mp1e guys at zapping.sf.net,
- * it might be in the next version...
- *
- * (later) A/V sync should now be good; MP1E_DISPLAY_FRAME==1 works.
- * needs major code cleanup, but that's for later.
- *
- * looks like it'll work with mp1e rte API as well, provided it's
- * stable and all threads don't become a tangled mess.
- *
- ****** Update 2/12/2001 by Harm
- *
- * Switched to librte instead of that weird mp1e-fifo concoction.
- * Not terribly impressed by the speed gain, if any, but certainly
- * cleaner. To use it, install librte-0.4 (get it at zapping.sf.net, the
- * API is still under development so don't expect newer versions to work
- * right away), define USE_MP1E 1 in the header below and change -lfame
- * to -lrte in Makefile.am
- *
- ****** Update 11/12/2001 by Harm
- *
- * Much much needed clean up.
- * Dropped ffmpeg support for the moment. Moved almost all libfame and
- * librte stuff in separate sections, defined general encoder API
- * in encoder_data_t.
- *
- ****** Update 16/12/2001 by Harm
- *
- * Merged dxr3 and dxr3enc video out drivers. Now there's only one!
- * dxr3_vo_standard.c and dxr3_vo_encoder.c are no more, everything
- * is in dxr3_video_out.c.
- *
- * renamed most config variables dxr3enc.XXX to dxr3.XXX
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "dxr3_video_out.h"
-
-#ifdef HAVE_LIBRTE
-int dxr3_rte_init(dxr3_driver_t *);
-#endif
-#ifdef HAVE_LIBFAME
-int dxr3_fame_init(dxr3_driver_t *);
-#endif
-
-static uint32_t dxr3_get_capabilities (vo_driver_t *this_gen)
-{
- return VO_CAP_YV12 | VO_CAP_YUY2 |
- VO_CAP_SATURATION | VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST;
-}
-
-static void dummy_frame_field (vo_frame_t *vo_img, int which_field)
-{
- /* dummy function */
-}
-
-static void dxr3_frame_dispose (vo_frame_t *frame_gen)
-{
- dxr3_frame_t *frame = (dxr3_frame_t *) frame_gen;
- if (frame->mem)
- free (frame->mem);
- free(frame);
-}
-
-static void dxr3_frame_copy(vo_frame_t *frame_gen, uint8_t **src);
-
-static vo_frame_t *dxr3_alloc_frame (vo_driver_t *this_gen)
-{
- dxr3_frame_t *frame;
- dxr3_driver_t *this = (dxr3_driver_t *)this_gen;
-
- frame = (dxr3_frame_t *) malloc (sizeof (dxr3_frame_t));
- memset (frame, 0, sizeof(dxr3_frame_t));
-
- if (this->enc && this->enc->on_frame_copy)
- frame->vo_frame.copy = dxr3_frame_copy;
- else
- frame->vo_frame.copy = 0;
- frame->vo_frame.field = dummy_frame_field;
- frame->vo_frame.dispose = dxr3_frame_dispose;
- frame->vo_frame.driver = this_gen;
-
- return (vo_frame_t*) frame;
-}
-
-static void dxr3_update_frame_format (vo_driver_t *this_gen,
- vo_frame_t *frame_gen,
- uint32_t width, uint32_t height,
- int ratio_code, int format, int flags)
-{
- dxr3_driver_t *this = (dxr3_driver_t *) this_gen;
- int aspect,i;
- dxr3_frame_t *frame = (dxr3_frame_t *) frame_gen;
- int image_size, oheight;
-
- /* update the overlay window co-ords if required */
- dxr3_overlay_update(this);
-
- /* reset the copy calls counter (number of calls to dxr3_frame_copy) */
- frame->copy_calls = 0;
- frame->vo_frame.driver = this_gen;
-
- aspect = this->aspectratio;
- oheight = this->oheight;
-
- if (format == IMGFMT_MPEG) { /* talking to dxr3 decoder */
- int aspect;
- /* a bit of a hack. we must release the em8300_mv fd for
- * the dxr3 decoder plugin */
- if (this->fd_video >= 0) {
- close(this->fd_video);
- this->fd_video = CLOSED_FOR_DECODER;
- }
- /* for mpeg source, we don't have to do much. */
- this->video_width = width;
- this->video_height = height;
- this->video_aspect = ratio_code;
- /* remember, there are no buffers malloc'ed for this frame!
- * the dxr3 decoder plugin is cool about this */
- frame->width = width;
- frame->height = height;
- frame->oheight = oheight;
- if (frame->mem) {
- free (frame->mem);
- frame->mem = NULL;
- frame->real_base[0] = frame->real_base[1]
- = frame->real_base[2] = NULL;
- frame_gen->base[0] = frame_gen->base[1]
- = frame_gen->base[2] = NULL;
- }
- if (ratio_code < 3 || ratio_code>4)
- aspect = ASPECT_FULL;
- else
- aspect = ASPECT_ANAMORPHIC;
- if(this->aspectratio!=aspect)
- dxr3_set_property ((vo_driver_t*)this, VO_PROP_ASPECT_RATIO, aspect);
- return;
- }
-
- /* the following is for the mpeg encoding part only */
-
- if (this->fd_video == CLOSED_FOR_DECODER) { /* decoder should have released it */
- this->fd_video = CLOSED_FOR_ENCODER; /* allow encoder to reopen it */
- this->need_redraw = 1;
- }
-
- if (this->add_bars == 0) {
- /* don't add black bars; assume source is in 4:3 */
- ratio_code = XINE_ASPECT_RATIO_4_3;
- }
-
- /* check aspect ratio, see if we need to add black borders */
- if ((this->video_width != width) || (this->video_iheight != height) ||
- (this->video_aspect != ratio_code)) {
- switch (ratio_code) {
- case XINE_ASPECT_RATIO_4_3: /* 4:3 */
- aspect = ASPECT_FULL;
- oheight = height;
- break;
- case XINE_ASPECT_RATIO_ANAMORPHIC:
- aspect = ASPECT_ANAMORPHIC;
- oheight = height;
- break;
- default: /* assume square pixel */
- aspect = ASPECT_ANAMORPHIC;
- oheight = (int)(width * 9./16.);
- if (oheight < height) { /* frame too high, try 4:3 */
- aspect = ASPECT_FULL;
- oheight = (int)(width * 3./4.);
- }
- }
- /* find closest multiple of 16 */
- oheight = 16*(int)(oheight / 16. + 0.5);
- if (oheight < height)
- oheight = height;/* no good, need horizontal bars (not yet) */
-
- this->oheight = oheight;
-
- /* Tell the viewers about the aspect ratio stuff. */
- if (oheight - height > 0)
- printf("dxr3: adding %d black lines to get %s a.r.\n",
- oheight-height, aspect == ASPECT_FULL ? "4:3" : "16:9");
- this->video_width = width;
- this->video_iheight = height;
- this->video_height = oheight;
- this->video_aspect = ratio_code;
- this->fps = 90000.0/frame->vo_frame.duration;
- this->format = format;
- this->need_redraw = 1;
-
- if (! this->enc) {
- /* no encoder plugin! Let's bug the user! */
- printf(
- "dxr3: ********************************************************\n"
- "dxr3: * *\n"
- "dxr3: * need an mpeg encoder to play non-mpeg videos on dxr3 *\n"
- "dxr3: * read the README.dxr3 for details. *\n"
- "dxr3: * (if you get this message while trying to play an *\n"
- "dxr3: * mpeg video, there is something wrong with the dxr3 *\n"
- "dxr3: * decoder plugin. check if it is set up correctly) *\n"
- "dxr3: * *\n"
- "dxr3: ********************************************************\n"
- );
- }
-
- if (this->enc && this->enc->on_update_format)
- this->enc->on_update_format(this);
- }
-
-
- /* if dimensions changed, we need to re-allocate frame memory */
- if ((frame->width != width) || (frame->height != height) ||
- (frame->oheight != oheight)) {
- if (frame->mem) {
- free (frame->mem);
- frame->mem = NULL;
- }
- /* make top black bar multiple of 16,
- * so old and new macroblocks overlap */
- this->top_bar = ((oheight - height) / 32) * 16;
- if (format == IMGFMT_YUY2) {
- image_size = width * oheight; /* includes black bars */
- /* planar format, only base[0] */
- /* add one extra line for field swap stuff */
- frame->real_base[0] = malloc_aligned(16, (image_size+width)*2,
- (void**)&frame->mem);
- /* don't use first line */
- frame->real_base[0] += width * 2;
- frame->real_base[1] = frame->real_base[2] = 0;
-
- /* fix offset, so the decoder does not see the top black bar */
- frame->vo_frame.base[0] = frame->real_base[0] + width * 2 * this->top_bar;
- frame->vo_frame.base[1] = frame->vo_frame.base[2] = 0;
-
- /* fill with black (yuy2 16,128,16,128,...) */
- memset(frame->real_base[0], 128, 2*image_size); /* U and V */
- for (i=0; i<2*image_size; i+=2)
- *(frame->real_base[0]+i) = 16; /* Y */
- }
- else { /* IMGFMT_YV12 */
- image_size = width * oheight; /* includes black bars */
- /* add one extra line for field swap stuff */
- frame->real_base[0] = malloc_aligned(16, (image_size + width) * 3/2,
- (void**) &frame->mem);
- /* don't use first line */
- frame->real_base[0] += width;
- frame->real_base[1] = frame->real_base[0] + image_size;
- frame->real_base[2] = frame->real_base[1] + image_size/4;
-
- /* fill with black (yuv 16,128,128) */
- memset(frame->real_base[0], 16, image_size);
- memset(frame->real_base[1], 128, image_size/4);
- memset(frame->real_base[2], 128, image_size/4);
-
- /* fix offsets, so the decoder does not see the top black bar */
- frame->vo_frame.base[0] = frame->real_base[0] + width * this->top_bar;
- frame->vo_frame.base[1] = frame->real_base[1] + width * this->top_bar/4;
- frame->vo_frame.base[2] = frame->real_base[2] + width * this->top_bar/4;
- }
- }
-
- if (this->swap_fields != frame->swap_fields) {
- if (format == IMGFMT_YUY2) {
- if (this->swap_fields)
- frame->vo_frame.base[0] -= width *2;
- else
- frame->vo_frame.base[0] += width *2;
- }
- else {
- if (this->swap_fields)
- frame->vo_frame.base[0] -= width;
- else
- frame->vo_frame.base[0] += width;
- }
- }
-
- frame->width = width;
- frame->height = height;
- frame->oheight = oheight;
- frame->swap_fields = this->swap_fields;
- if(this->aspectratio!=aspect)
- dxr3_set_property (this_gen,VO_PROP_ASPECT_RATIO, aspect);
-
-}
-
-int dxr3_redraw_needed(vo_driver_t *this_gen)
-{
- dxr3_driver_t *this = (dxr3_driver_t *)this_gen;
-
- dxr3_overlay_update(this);
-
- if (this->need_redraw) {
- this->need_redraw = 0;
- return 1;
- }
-
- return 0;
-}
-
-static void dxr3_frame_copy(vo_frame_t *frame_gen, uint8_t **src)
-{
- dxr3_frame_t *frame = (dxr3_frame_t *) frame_gen;
- dxr3_driver_t *this = (dxr3_driver_t *) frame_gen->driver;
- if (frame_gen->format != IMGFMT_MPEG && this->enc && this->enc->on_frame_copy)
- this->enc->on_frame_copy(this, frame, src);
-}
-
-static void dxr3_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
-{
- dxr3_driver_t *this = (dxr3_driver_t*)this_gen;
- dxr3_frame_t *frame = (dxr3_frame_t*)frame_gen;
-
- if (frame_gen->format != IMGFMT_MPEG && this->enc && this->enc->on_display_frame) {
- this->enc->on_display_frame(this, frame);
- } else {
- frame_gen->displayed(frame_gen);
- }
- /* for non-mpeg, the encoder plugin is responsible for calling
- * frame_gen->displayed(frame_gen) ! */
-}
-
-static void dxr3_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen,
- vo_overlay_t *overlay)
-{
- /* FIXME: We only blend non-mpeg frames here.
- Is there any way to provide overlays for mpeg content? Subpictures? */
- if ( frame_gen->format != IMGFMT_MPEG )
- {
- dxr3_frame_t *frame = (dxr3_frame_t*)frame_gen;
-
- if (overlay->rle) {
- if( frame_gen->format == IMGFMT_YV12 )
- blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height);
- else
- blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height);
- }
- }
-}
-
-void dxr3_exit (vo_driver_t *this_gen)
-{
- dxr3_driver_t *this = (dxr3_driver_t *) this_gen;
-
- if (this->enc && this->enc->on_close)
- this->enc->on_close(this);
- printf("dxr3: vo exit called\n");
-
- if(this->overlay_enabled)
- dxr3_overlay_set_mode(&this->overlay, EM8300_OVERLAY_MODE_OFF);
-}
-
-void dxr3_update_add_bars(void *data, cfg_entry_t* entry)
-{
- dxr3_driver_t* this = (dxr3_driver_t*)data;
- this->add_bars = entry->num_value;
- printf("dxr3: add bars to correct a.r. is %s\n",
- (this->add_bars ? "on" : "off"));
-}
-
-void dxr3_update_swap_fields(void *data, cfg_entry_t* entry)
-{
- dxr3_driver_t* this = (dxr3_driver_t*)data;
- this->swap_fields = entry->num_value;
- printf("dxr3: set swap field to %s\n",
- (this->swap_fields ? "on" : "off"));
-}
-
-static void dxr3_update_enhanced_mode(void *this_gen, cfg_entry_t *entry)
-{
- ((dxr3_driver_t*)this_gen)->enhanced_mode = entry->num_value;
- printf("dxr3: encode: set enhanced mode to %s\n",
- (entry->num_value ? "on" : "off"));
-}
-
-vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen)
-{
- dxr3_driver_t *this;
- char tmpstr[100];
- const char *encoder;
- char *available_encoders,*default_encoder;
- char *confstr;
- int dashpos;
-
- /*
- * allocate plugin struct
- */
-printf("dxr3_video_out:init_plugin\n");
-
- this = malloc (sizeof (dxr3_driver_t));
-
- if (!this) {
- printf ("video_out_dxr3: malloc failed\n");
- return NULL;
- }
-
- memset (this, 0, sizeof(dxr3_driver_t));
-
- this->vo_driver.get_capabilities = dxr3_get_capabilities;
- this->vo_driver.alloc_frame = dxr3_alloc_frame;
- this->vo_driver.update_frame_format = dxr3_update_frame_format;
- this->vo_driver.display_frame = dxr3_display_frame;
- this->vo_driver.overlay_blend = dxr3_overlay_blend;
- this->vo_driver.get_property = dxr3_get_property;
- this->vo_driver.set_property = dxr3_set_property;
- this->vo_driver.get_property_min_max = dxr3_get_property_min_max;
- this->vo_driver.gui_data_exchange = dxr3_gui_data_exchange;
- this->vo_driver.redraw_needed = dxr3_redraw_needed;
- this->vo_driver.exit = dxr3_exit;
- this->config=config;
-
- this->swap_fields = config->register_bool(config, "dxr3.enc_swap_fields", 0, "swap odd and even lines", NULL, dxr3_update_swap_fields, this);
-
- this->add_bars = config->register_bool(config, "dxr3.enc_add_bars", 1, "Add black bars to correct aspect ratio", "If disabled, will assume source has 4:3 a.r.", dxr3_update_add_bars, this);
-
- this->enhanced_mode = config->register_bool(config,"dxr3.enc_alt_play_mode", 1, "dxr3: use alternate play mode for mpeg encoder playback","Enabling this option will utilise a slightly different play mode",dxr3_update_enhanced_mode,this);
- /* open control device */
- confstr = config->register_string (config, LOOKUP_DEV, DEFAULT_DEV,NULL,NULL,NULL,NULL);
- strncpy(this->devname, confstr, 128);
- this->devname[127] = '\0';
- dashpos = strlen(this->devname) - 2; /* the dash in the new device naming scheme would be here */
- if (this->devname[dashpos] == '-') {
- /* use new device naming scheme with trailing number */
- strncpy(this->devnum, &this->devname[dashpos], 3);
- this->devname[dashpos] = '\0';
- } else {
- /* use old device naming scheme without trailing number */
- /* FIXME: remove this when everyone uses em8300 >=0.12.0 */
- this->devnum[0] = '\0';
- }
-
- snprintf (tmpstr, sizeof(tmpstr), "%s%s", this->devname, this->devnum);
- printf("dxr3: Entering video init, devname=%s.\n",tmpstr);
- if ((this->fd_control = open(tmpstr, O_WRONLY)) < 0) {
- printf("dxr3: Failed to open control device %s (%s)\n",
- tmpstr, strerror(errno));
- return 0;
- }
- /* output mpeg to file instead of dxr3? */
- this->file_out = config->register_string(config, "dxr3.outputfile", "<none>", "dxr3: output file of encoded mpeg video for debugging",NULL,NULL,NULL);
-
- if (this->file_out && strcmp(this->file_out, "<none>")) {
- this->fd_video = open(this->file_out, O_WRONLY | O_CREAT);
- if (this->fd_video < 0) {
- perror("dxr3: failed to open output file");
- return 0;
- }
- }
- else {
- /* open video device */
- snprintf (tmpstr, sizeof(tmpstr), "%s_mv%s", this->devname, this->devnum);
- if ((this->fd_video = open (tmpstr, O_WRONLY | O_SYNC )) < 0) {
- printf("dxr3: failed to open video device %s (%s)\n",
- tmpstr, strerror(errno));
- return 0;
- }
- /* close now and and let the encoders reopen if they want */
- close(this->fd_video);
- this->fd_video = CLOSED_FOR_DECODER;
- }
-
- /* which encoder to use? Whadda we got? */
- default_encoder = 0;
- /* memory leak... but config doesn't copy our help string :-( */
- available_encoders = malloc(256);
- strcpy(available_encoders, "Mpeg1 encoder. Options: ");
-#ifdef HAVE_LIBFAME
- default_encoder = "fame";
- strcat(available_encoders, "\"fame\" (very fast, good quality) ");
-#endif
-#ifdef HAVE_LIBRTE
- default_encoder = "rte";
- strcat(available_encoders, "\"rte\" (fast, high quality) ");
-#endif
- printf("dxr3: %s\n", available_encoders);
- this->enc = 0;
- if (default_encoder) {
- encoder = config->register_string(config, "dxr3.encoder",
- default_encoder, available_encoders, NULL, NULL, NULL);
-#ifdef HAVE_LIBRTE
- if (! strcmp(encoder, "rte"))
- if ( dxr3_rte_init(this) )
- return 0;
-#endif
-#ifdef HAVE_LIBFAME
- if (! strcmp(encoder, "fame"))
- if ( dxr3_fame_init(this) )
- return 0;
-#endif
- if (this->enc == 0) {
- printf(
-"dxr3: mpeg encoder \"%s\" not compiled in or not supported.\n"
-"dxr3: valid options are %s\n", encoder, available_encoders);
- }
- }
- else {
- printf(
-"dxr3: no mpeg encoder compiled in.\n"
-"dxr3: that's ok, you don't need if for mpeg video like DVDs, but\n"
-"dxr3: you will not be able to play non-mpeg content using this video out\n"
-"dxr3: driver. See the README.dxr3 for details on configuring an encoder.\n"
- );
- }
-
- /* default values */
- this->overlay_enabled = 0;
- this->aspectratio = ASPECT_FULL;
-
- dxr3_read_config(this, visual_gen);
-
- if (this->overlay_enabled) {
- dxr3_get_keycolor(this);
- dxr3_overlay_buggy_preinit(&this->overlay, this->fd_control);
- }
-
- return &this->vo_driver;
-}
-
-static vo_info_t vo_info_dxr3 = {
- 5, /* api version */
- "dxr3",
- "xine video output plugin for dxr3 cards",
- VISUAL_TYPE_X11,
- 10 /* priority */
-};
-
-vo_info_t *get_video_out_plugin_info()
-{
- return &vo_info_dxr3;
-}
-
-
diff --git a/src/dxr3/dxr3_video_out.h b/src/dxr3/dxr3_video_out.h
deleted file mode 100644
index 31e28971b..000000000
--- a/src/dxr3/dxr3_video_out.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * 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: dxr3_video_out.h,v 1.20 2002/05/06 11:26:37 jcdutton Exp $
- *
- */
-
-/*
- * Globals for dxr3 videoout plugins
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <math.h>
-
-#include <linux/em8300.h>
-#include "video_out.h"
-#include "xine_internal.h"
-#include "alphablend.h"
-
-/* for fast_memcpy: */
-#include "xineutils.h"
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-#ifdef HAVE_XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif
-#include "../video_out/video_out_x11.h"
-
-#define LOOKUP_DEV "dxr3.devicename"
-#define DEFAULT_DEV "/dev/em8300"
-
-/* image format used by dxr3_decoder to tag undecoded mpeg data */
-#define IMGFMT_MPEG (('G'<<24)|('E'<<16)|('P'<<8)|'M')
-
-/* values for fd_video indicating why it is closed */
-#define CLOSED_FOR_DECODER -1
-#define CLOSED_FOR_ENCODER -2
-
-struct coeff {
- float k,m;
-};
-
-typedef struct {
- int fd_control;
-
- int xoffset;
- int yoffset;
- int xcorr;
- int jitter;
- int stability;
- int colorkey;
- float color_interval;
- int screen_xres;
- int screen_yres;
- int screen_depth;
-
- struct coeff colcal_upper[3];
- struct coeff colcal_lower[3];
-} dxr3_overlay_t;
-
-typedef enum { ENC_FAME, ENC_RTE } encoder_type;
-typedef struct encoder_data_s encoder_data_t;
-
-typedef struct dxr3_driver_s {
- vo_driver_t vo_driver;
- config_values_t *config;
- int fd_control;
- int fd_video;
- int aspectratio;
- int tv_mode;
- int enhanced_mode; /* enhanced play mode */
- int need_redraw;
- em8300_bcs_t bcs;
- char devname[128];
- char devnum[3];
-
- /* for encoder plugin */
- encoder_data_t *enc; /* encoder data */
- double fps; /* frames per second */
- int format; /* color format */
- const char *file_out;
- int swap_fields; /* swap fields */
- int add_bars; /* add black bars to correct a.r. */
- /* height after adding black bars to correct a.r. */
- int oheight;
- int top_bar; /* number of lines in top black bar */
- /* input height (before adding black bars) */
- int video_iheight;
- /* output height (after adding bars) */
- int video_height;
-
- /* for overlay */
- dxr3_overlay_t overlay;
- Display *display;
- Drawable win;
- GC gc;
- XColor color;
- int xpos, ypos;
- int width, height;
- int overlay_enabled;
- int tv_switchable; /* can switch from overlay<->tvout */
- int fullscreen_rectangle;
- float desired_ratio;
-
- int zoom_enabled; /* zoomed 16:9 mode */
-
- int video_width;
- int video_aspect;
-
- char *user_data;
-
- void (*frame_output_cb) (void *user_data,
- int video_width, int video_height,
- int *dest_x, int *dest_y,
- int *dest_height, int *dest_width,
- int *win_x, int *win_u);
-
-/* void (*frame_output_cb) (char *userdata, int video_width,
- int video_height, int *dest_x,
- int *dest_y, int *dest_height, int *dest_width);
-*/
-} dxr3_driver_t;
-
-typedef struct dxr3_frame_s {
- vo_frame_t vo_frame;
- int width, height,oheight;
- uint8_t *mem; /* allocated for YV12 or YUY2 buffers */
- uint8_t *real_base[3]; /* yuv/yuy2 buffers in mem aligned on 16 */
- int copy_calls; /* counts calls to dxr3_frame_copy function */
- int swap_fields; /* shifts Y buffer one line to exchange odd/even lines*/
-} dxr3_frame_t;
-
-struct encoder_data_s {
- encoder_type type;
- int (*on_update_format)(dxr3_driver_t *);
- int (*on_frame_copy)(dxr3_driver_t *, dxr3_frame_t *, uint8_t **src);
- int (*on_display_frame)(dxr3_driver_t *, dxr3_frame_t *);
- int (*on_close)(dxr3_driver_t *);
-};
-
-/* func definitions */
-int dxr3_redraw_needed(vo_driver_t *this_gen);
-
-/* Overlay functions */
-int dxr3_overlay_set_mode(dxr3_overlay_t *this, int mode);
-int dxr3_overlay_set_attributes(dxr3_overlay_t *this);
-int dxr3_overlay_set_screen(dxr3_overlay_t *this);
-int dxr3_overlay_set_window(dxr3_overlay_t *this,
- int xpos, int ypos, int width, int height);
-void dxr3_overlay_adapt_area(dxr3_driver_t *this,
- int xpos, int ypos, int width, int height);
-void dxr3_overlay_update(dxr3_driver_t *this);
-void dxr3_overlay_buggy_preinit(dxr3_overlay_t *this, int fd);
-int dxr3_overlay_read_state(dxr3_overlay_t *this);
-void dxr3_get_keycolor(dxr3_driver_t *this);
-void dxr3_read_config(dxr3_driver_t *this, void *visual_gen);
-
-void *malloc_aligned (size_t alignment, size_t size, void **mem);
-void gather_screen_vars(dxr3_driver_t *this, x11_visual_t *vis);
-
-/* xine accessable functions */
-int dxr3_get_property (vo_driver_t *this_gen, int property);
-int dxr3_set_property (vo_driver_t *this_gen, int property, int value);
-void dxr3_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max);
-int dxr3_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data);
-
diff --git a/src/dxr3/dxr3_vo_core.c b/src/dxr3/dxr3_vo_core.c
deleted file mode 100644
index dbcd96316..000000000
--- a/src/dxr3/dxr3_vo_core.c
+++ /dev/null
@@ -1,801 +0,0 @@
-/*
- * 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: dxr3_vo_core.c,v 1.21 2002/05/06 11:26:37 jcdutton Exp $
- *
- *************************************************************************
- * core functions common to both Standard and RT-Encoding vo plugins *
- * *
- * functions in this file (in order of appearance): * *
- * malloc_aligned *
- * dxr3_overlay_adapt_area *
- * dxr3_get_keycolor *
- * dxr3_read_config *
- * is_fullscreen *
- * dxr3_zoomTV *
- * dxr3_get_property *
- * dxr3_set_property *
- * dxr3_get_property_min_max *
- * dxr3_translate_gui2video *
- * dxr3_gui_data_exchange *
- * dxr3_gather_screen_vars *
- * *
- * and overlay specific functions formerly in overlay.c *
- *************************************************************************/
-
-#include "dxr3_video_out.h"
-#include <locale.h>
-
-/*
-#define OVERLAY_LOG 1
-*/
-
-void *malloc_aligned (size_t alignment, size_t size, void **mem) {
- char *aligned;
-
- aligned = malloc (size+alignment);
- *mem = aligned;
-
- while ((int) aligned % alignment)
- aligned++;
-
- return aligned;
-}
-
-/****** update the overlay window ******/
-void dxr3_overlay_update(dxr3_driver_t *this)
-{
- if(this->overlay_enabled) {
- int gui_win_x, gui_win_y, gypos,gxpos,gw,gh;
-
- this->frame_output_cb (this->user_data,
- this->video_width, this->video_height,
- &gxpos, &gypos, &gw, &gh,
- &gui_win_x, &gui_win_y );
-
- if(this->xpos!=gxpos || this->ypos!=gypos ||
- this->width !=gw || this->height!=gh) {
- this->xpos=gxpos+1;
- this->ypos=gypos+1;
- this->width=gw;
- this->height=gh;
- dxr3_overlay_adapt_area(this, this->xpos, this->ypos, this->width, this->height);
- }
- }
-}
-
-
-/****** detect true window position and adapt overlay to it *******/
-void dxr3_overlay_adapt_area(dxr3_driver_t *this,
- int dest_x, int dest_y, int dest_width, int dest_height)
-{
- XWindowAttributes a;
- Window junkwin;
- int rx, ry;
-
- XLockDisplay(this->display);
-
- XSetForeground(this->display, this->gc, this->color.pixel);
- XGetWindowAttributes(this->display, this->win, &a);
- XTranslateCoordinates (this->display, this->win, a.root,
- dest_x, dest_y, &rx, &ry, &junkwin);
-
- XUnlockDisplay(this->display);
-
- this->xpos = rx; this->ypos = ry;
- this->width = dest_width; this->height = dest_height;
-
- dxr3_overlay_set_window(&this->overlay, this->xpos, this->ypos,
- this->width, this->height);
-}
-
-
-/****** Allocate keycolor in the current palette ***********/
-void dxr3_get_keycolor(dxr3_driver_t *this)
-{
- this->color.red = ((this->overlay.colorkey >> 16) & 0xff) * 256;
- this->color.green = ((this->overlay.colorkey >> 8) & 0xff) * 256;
- this->color.blue = ((this->overlay.colorkey ) & 0xff) * 256;
-
- XAllocColor(this->display, DefaultColormap(this->display,0), &this->color);
-}
-
-
-/******* Read dxr3 configuration data from ~/.xinerc **********
- * overlay setup data is read from ~/.overlay/res* in the *
- * overlay section below *
- ***************************************************************/
-void dxr3_read_config(dxr3_driver_t *this, void * visual_gen)
-{
- char* str;
- config_values_t *config=this->config;
-
- if (ioctl(this->fd_control, EM8300_IOCTL_GETBCS, &this->bcs))
- printf("dxr3_vo: cannot read bcs values (%s)\n",
- strerror(errno));
-
- this->bcs.contrast = config->register_range(config, "dxr3.contrast", this->bcs.contrast,100,900,"Dxr3: contrast control",NULL,NULL,NULL);
- this->bcs.saturation = config->register_range(config, "dxr3.saturation", this->bcs.saturation,100,900,"Dxr3: saturation control",NULL,NULL,NULL);
- this->bcs.brightness = config->register_range(config, "dxr3.brightness", this->bcs.brightness,100,900,"Dxr3: brightness control",NULL,NULL,NULL);
-
- this->fullscreen_rectangle = config->register_bool(config, "dxr3.fullscreen_rectangle",0,"Dxr3: Fullscreen Rectangle Mode",NULL,NULL,NULL);
-
- this->vo_driver.set_property(&this->vo_driver,
- VO_PROP_ASPECT_RATIO, ASPECT_FULL);
-
- str = config->register_string(config, "dxr3.videoout_mode", "tv", "Dxr3: videoout mode (tv or overlay)", NULL,NULL,NULL);
- printf("dxr3:overlaymode=%s\n",str);
- if (!strcasecmp(str, "tv")) {
- this->overlay_enabled=0;
- this->tv_switchable=0; /* don't allow on-the-fly switching */
- } else if (!strcasecmp(str, "overlay")) {
- this->tv_mode = EM8300_VIDEOMODE_DEFAULT;
- printf("dxr3_vo: setting up overlay mode\n");
- gather_screen_vars(this, visual_gen);
- if (dxr3_overlay_read_state(&this->overlay) == 0) {
- this->overlay_enabled = 1;
- this->tv_switchable=1;
- str = config->register_string(config, "dxr3.keycolor", "0x80a040", "Dxr3: overlay colourkey value",NULL,NULL,NULL);
-
- sscanf(str, "%x", &this->overlay.colorkey);
-
- str = config->register_string(config, "dxr3.color_interval", "50.0", "Dxr3: overlay colourkey range","A greater value widens the search range for the overlay keycolor",NULL,NULL);
-
- sscanf(str, "%f", &this->overlay.color_interval);
- } else {
- printf("dxr3_vo: please run autocal, overlay disabled\n");
- this->overlay_enabled=0;
- this->tv_switchable=0;
- }
- }
- str = config->register_string(config, "dxr3.preferred_tvmode", "default", "Dxr3 preferred tv mode - PAL, PAL60, NTSC or default",NULL,NULL,NULL);
-
- if (!strcasecmp(str, "ntsc")) {
- this->tv_mode = EM8300_VIDEOMODE_NTSC;
- printf("dxr3_vo: setting tv_mode to NTSC\n");
- } else if (!strcasecmp(str, "pal")) {
- this->tv_mode = EM8300_VIDEOMODE_PAL;
- printf("dxr3_vo: setting tv_mode to PAL 50Hz\n");
- } else if (!strcasecmp(str, "pal60")) {
- this->tv_mode = EM8300_VIDEOMODE_PAL60;
- printf("dxr3_vo: setting tv_mode to PAL 60Hz\n");
- } else {
- this->tv_mode = EM8300_VIDEOMODE_DEFAULT;
- }
-
-
- if (this->tv_mode != EM8300_VIDEOMODE_DEFAULT)
- if (ioctl(this->fd_control, EM8300_IOCTL_SET_VIDEOMODE, &this->tv_mode))
- printf("dxr3_vo: setting video mode failed.");
-}
-
-
-/******** is this window fullscreen? ************/
-int is_fullscreen(dxr3_driver_t *this)
-{
- XWindowAttributes a;
-
- XGetWindowAttributes(this->display, this->win, &a);
- /* this is a good place for gathering the with and height
- * although it is a mis-use for is_fullscreen */
- this->width = a.width;
- this->height = a.height;
-
- return a.x==0 && a.y==0 &&
- a.width == this->overlay.screen_xres &&
- a.height == this->overlay.screen_yres;
-}
-
-
-/******* Experimental zoom function for tvout only *********
- * (mis)uses the dxr3 dicom function *
- ***********************************************************/
-static void dxr3_zoomTV(dxr3_driver_t *this)
-{
- em8300_register_t frame, visible, update;
- frame.microcode_register=1; /* Yes, this is a MC Reg */
- visible.microcode_register=1; /* Yes, this is a MC Reg */
- update.microcode_register=1;
-
- /* change left <- */
- frame.microcode_register=1; /* Yes, this is a MC Reg */
- visible.microcode_register=1; /* Yes, this is a MC Reg */
- frame.reg = 93; // dicom frame left
- visible.reg = 97; //dicom visible left
- update.reg = 65; //dicom_update
- update.val=1;
- frame.val=0x10;
- visible.val=0x10;
-
- ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &frame);
- ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &visible);
- ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &update);
-
- /* change right -> */
- frame.microcode_register=1; /* Yes, this is a MC Reg */
- visible.microcode_register=1; /* Yes, this is a MC Reg */
- update.reg = 94; // dicom frame right
- visible.reg = 98; //dicom visible right
- update.reg = 65; //dicom_update
- update.val=1;
- frame.val=0x10;
- visible.val= 968;
-
- ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &frame);
- ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &visible);
- ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &update);
-
-}
-
-int dxr3_get_property (vo_driver_t *this_gen, int property)
-{
- dxr3_driver_t *this = (dxr3_driver_t *) this_gen;
- int val=0;
-
- switch (property) {
- case VO_PROP_SATURATION:
- val = this->bcs.saturation;
- break;
-
- case VO_PROP_CONTRAST:
- val = this->bcs.contrast;
- break;
-
- case VO_PROP_BRIGHTNESS:
- val = this->bcs.brightness;
- break;
-
- case VO_PROP_ASPECT_RATIO:
- val = this->aspectratio;
- break;
-
- case VO_PROP_COLORKEY:
- val = this->overlay.colorkey;
- break;
- case VO_PROP_ZOOM_FACTOR:
- case VO_PROP_TVMODE:
- break;
-
- case VO_PROP_VO_TYPE:
- val = VO_TYPE_DXR3;
- break;
- default:
- val = 0;
- printf("dxr3_vo: property %d not implemented!\n", property);
- }
-
- return val;
-}
-
-int dxr3_set_property (vo_driver_t *this_gen,
- int property, int value)
-{
- dxr3_driver_t *this = (dxr3_driver_t *) this_gen;
- int val, bcs_changed = 0;
- int fullscreen;
-
- switch (property) {
- case VO_PROP_SATURATION:
- this->bcs.saturation = value;
- bcs_changed = 1;
- break;
- case VO_PROP_CONTRAST:
- this->bcs.contrast = value;
- bcs_changed = 1;
- break;
- case VO_PROP_BRIGHTNESS:
- this->bcs.brightness = value;
- bcs_changed = 1;
- break;
- case VO_PROP_ASPECT_RATIO:
- /* xitk-ui just increments the value, so we make
- * just a two value "loop"
- */
- if (value > ASPECT_FULL)
- value = ASPECT_ANAMORPHIC;
- this->aspectratio = value;
- fullscreen = this->overlay_enabled ? is_fullscreen(this) : 0;
-
- if (value == ASPECT_ANAMORPHIC) {
- printf("dxr3_vo: setting aspect ratio to anamorphic\n");
- if (!this->overlay_enabled || fullscreen)
- val = EM8300_ASPECTRATIO_16_9;
- else /* The overlay window can adapt to the ratio */
- val = EM8300_ASPECTRATIO_4_3;
- this->desired_ratio = 16.0/9.0;
- } else {
- printf("dxr3_vo: setting aspect ratio to full\n");
- val = EM8300_ASPECTRATIO_4_3;
- this->desired_ratio = 4.0/3.0;
- }
-
- if (ioctl(this->fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &val))
- printf("dxr3_vo: failed to set aspect ratio (%s)\n",
- strerror(errno));
-
- if (this->overlay_enabled && !fullscreen){
- int foo;
- this->frame_output_cb(this->user_data, this->width,
- this->width/this->desired_ratio, &foo, &foo, &foo, &foo, &foo, &foo);
- }
- break;
- case VO_PROP_COLORKEY:
- printf("dxr3_vo: VO_PROP_COLORKEY not implemented!");
- this->overlay.colorkey = val;
- break;
- case VO_PROP_ZOOM_FACTOR: /* FIXME: Was ZOOM_X */
- if(!this->overlay_enabled){ /* TV-out only */
- if(value==1){
- printf("dxr3_vo: enabling 16:9 zoom\n");
- val=EM8300_ASPECTRATIO_4_3;
- if (ioctl(this->fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &val))
- printf("dxr3_vo: failed to set aspect ratio (%s)\n",
- strerror(errno));
- dxr3_zoomTV(this);
- }else if (value==-1){
- printf("dxr3_vo: disabling 16:9 zoom\n");
- if (ioctl(this->fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &this->aspectratio))
- printf("dxr3_vo: failed to set aspect ratio (%s)\n",
- strerror(errno));
- }
- }
- break;
-
- case VO_PROP_TVMODE: {
- /* Use meta-v to cycle TV formats */
- static int newmode;
- newmode++;
- if (newmode>EM8300_VIDEOMODE_LAST)
- newmode=EM8300_VIDEOMODE_PAL;
- printf("dxr3_vo: Changing TVMode to ");
- if(newmode==EM8300_VIDEOMODE_PAL)
- printf("PAL\n");
- if(newmode==EM8300_VIDEOMODE_PAL60)
- printf("PAL60\n");
- if(newmode==EM8300_VIDEOMODE_NTSC)
- printf("NTSC\n");
- if (ioctl(this->fd_control, EM8300_IOCTL_SET_VIDEOMODE, &newmode))
- printf("dxr3_vo: setting video mode failed.");
- }
- break;
- default:
- break;
- }
-
- if (bcs_changed){
- if (ioctl(this->fd_control, EM8300_IOCTL_SETBCS, &this->bcs))
- printf("dxr3_vo: bcs set failed (%s)\n",
- strerror(errno));
- this->config->update_num(this->config, "dxr3.contrast", this->bcs.contrast);
- this->config->update_num(this->config, "dxr3.saturation", this->bcs.saturation);
- this->config->update_num(this->config, "dxr3.brightness", this->bcs.brightness);
- }
-
- return value;
-}
-
-void dxr3_get_property_min_max (vo_driver_t *this_gen,
- int property, int *min, int *max)
-{
- /* dxr3_driver_t *this = (dxr3_driver_t *) this_gen; */
-
- switch (property) {
- case VO_PROP_SATURATION:
- case VO_PROP_CONTRAST:
- case VO_PROP_BRIGHTNESS:
- *min = 0;
- *max = 1000;
- break;
-
- default:
- *min = 0;
- *max = 0;
- }
-}
-
-static void dxr3_translate_gui2video(dxr3_driver_t *this,
- int x, int y,
- int *vid_x, int *vid_y)
-{
- x = x * this->video_width / this->width;
- y = y * this->video_height / this->height;
- *vid_x = x;
- *vid_y = y;
-}
-
-int dxr3_gui_data_exchange (vo_driver_t *this_gen,
- int data_type, void *data)
-{
- dxr3_driver_t *this = (dxr3_driver_t*) this_gen;
-
-
- if (!this->overlay_enabled && !this->tv_switchable) return 0;
-
- switch (data_type) {
-/*************************************************************************
- * FIXME: Removed due to changes in XV by Guenter, but don't know what to replace it with
- * Update 2/4/02 - Mike Lampard:
- * This functionality is now incorporated into dxr3_overlay_update until
- * a cleaner way can be found to update window changes.
-
- case GUI_DATA_EX_DEST_POS_SIZE_CHANGED:{
- x11_rectangle_t *area = (x11_rectangle_t*) data;
- dxr3_overlay_adapt_area(this, area->x, area->y, area->w, area->h);
-
- if(is_fullscreen(this) && this->fullscreen_rectangle)
- dxr3_overlay_set_mode(&this->overlay,EM8300_OVERLAY_MODE_RECTANGLE);
- else if (this->fullscreen_rectangle)
- dxr3_overlay_set_mode(&this->overlay,EM8300_OVERLAY_MODE_OVERLAY);
- }
- break;
-*************************************************************************/
- case GUI_DATA_EX_EXPOSE_EVENT:{
- XLockDisplay(this->display);
- XFillRectangle(this->display, this->win,
- this->gc, 0, 0, this->width, this->height);
- XUnlockDisplay(this->display);
- dxr3_overlay_update(this);
- }
- break;
- case GUI_DATA_EX_DRAWABLE_CHANGED:{
- XWindowAttributes a;
- this->win = (Drawable) data;
- this->gc = XCreateGC(this->display, this->win, 0, NULL);
- XGetWindowAttributes(this->display, this->win, &a);
- dxr3_set_property((vo_driver_t*) this,
- VO_PROP_ASPECT_RATIO, this->aspectratio);
- }
- break;
- case GUI_DATA_EX_TRANSLATE_GUI_TO_VIDEO:{
- int x1, y1, x2, y2;
- x11_rectangle_t *rect = data;
-
- dxr3_translate_gui2video(this, rect->x, rect->y,
- &x1, &y1);
- dxr3_translate_gui2video(this, rect->w, rect->h,
- &x2, &y2);
- rect->x = x1;
- rect->y = y1;
- rect->w = x2-x1;
- rect->h = y2-y1;
- }
- break;
- case GUI_DATA_EX_VIDEOWIN_VISIBLE:{
- int window_showing;
- (int *)window_showing = (int *)data;
- if(!window_showing){
- printf("dxr3_vo: Hiding VO window and diverting video to TV\n");
- dxr3_overlay_set_mode(&this->overlay, EM8300_OVERLAY_MODE_OFF );
- this->overlay_enabled=0;
- }else{
- printf("dxr3_vo: Using VO window for overlaying video\n");
- dxr3_overlay_set_mode(&this->overlay, EM8300_OVERLAY_MODE_OVERLAY );
- this->overlay_enabled=1;
- }
- dxr3_set_property((vo_driver_t*) this,
- VO_PROP_ASPECT_RATIO, this->aspectratio);
- break;
- }
-
- default:
- return -1;
- }
- return 0;
-}
-
-/******** detect screen resolution and colour depth **********/
-void gather_screen_vars(dxr3_driver_t *this, x11_visual_t *vis)
-{
- int scrn;
-#ifdef HAVE_XINERAMA
- int screens;
- int dummy_a, dummy_b;
- XineramaScreenInfo *screeninfo = NULL;
-#endif
-
- this->win = vis->d;
- this->display = vis->display;
- this->user_data = vis->user_data;
- this->gc = XCreateGC(this->display, this->win, 0, NULL);
- scrn = DefaultScreen(this->display);
-
- /* Borrowed from xine-ui in order to detect fullscreen */
-#ifdef HAVE_XINERAMA
- if (XineramaQueryExtension(this->display, &dummy_a, &dummy_b) &&
- (screeninfo = XineramaQueryScreens(this->display, &screens)) &&
- XineramaIsActive(this->display))
- {
- this->overlay.screen_xres = screeninfo[0].width;
- this->overlay.screen_yres = screeninfo[0].height;
- } else
-#endif
- {
- this->overlay.screen_xres = DisplayWidth(this->display, scrn);
- this->overlay.screen_yres = DisplayHeight(this->display, scrn);
- }
-
- this->overlay.screen_depth = DisplayPlanes(this->display, scrn);
- this->frame_output_cb = (void *)vis->frame_output_cb;
-/* request_dest_size; */
- printf("xres %d yres %d depth %d\n", this->overlay.screen_xres, this->overlay.screen_yres, this->overlay.screen_depth);
-}
-
-/**************************************************************************
- * Overlay initialisation and other overlay_specific functions *
- **************************************************************************/
-
-#define TYPE_INT 1
-#define TYPE_XINT 2
-#define TYPE_COEFF 3
-#define TYPE_FLOAT 4
-
-struct lut_entry {
- char *name;
- int type;
- void *ptr;
-};
-
-static struct lut_entry *new_lookuptable(dxr3_overlay_t *this)
-{
- struct lut_entry m[] = {
- {"xoffset", TYPE_INT, &this->xoffset},
- {"yoffset", TYPE_INT, &this->yoffset},
- {"xcorr", TYPE_INT, &this->xcorr},
- {"jitter", TYPE_INT, &this->jitter},
- {"stability", TYPE_INT, &this->stability},
- {"keycolor", TYPE_XINT, &this->colorkey},
- {"colcal_upper", TYPE_COEFF, &this->colcal_upper[0]},
- {"colcal_lower", TYPE_COEFF, &this->colcal_lower[0]},
- {"color_interval", TYPE_FLOAT, &this->color_interval},
- {0,0,0}
- },*p;
-
- p = malloc(sizeof(m));
- memcpy(p,m,sizeof(m));
- return p;
-}
-
-static int lookup_parameter(struct lut_entry *lut, char *name,
- void **ptr, int *type)
-{
- int i;
- for(i=0; lut[i].name; i++)
- if(!strcmp(name,lut[i].name)) {
- *ptr = lut[i].ptr;
- *type = lut[i].type;
-#if OVERLAY_LOG
- printf("dxr3: found parameter \"%s\"\n", name);
-#endif
- return 1;
- }
-#if OVERLAY_LOG
- printf("dxr3: WARNING: unknown parameter \"%s\"\n", name);
-#endif
- return 0;
-}
-
-int dxr3_overlay_read_state(dxr3_overlay_t *this)
-{
- char *tok;
- char fname[128],tmp[128],line[256];
- FILE *fp;
- struct lut_entry *lut;
- void *ptr;
- int type;
- int j;
- char *loc;
-
- /* store previous locale */
- loc = setlocale(LC_NUMERIC, NULL);
- /* set american locale for floating point values
- * (used by .overlay/res file) */
- setlocale(LC_NUMERIC, "en_US");
-
- strcpy(fname,getenv("HOME"));
- strcat(fname,"/.overlay");
-
- sprintf(tmp,"/res_%dx%dx%d",
- this->screen_xres,this->screen_yres,this->screen_depth);
- strcat(fname,tmp);
-#if OVERLAY_LOG
- printf("dxr3: attempting to open %s\n", fname);
-#endif
- if(!(fp=fopen(fname,"r"))){
- printf("ERRROR Reading overlay init file!! run autocal !!!\n");
- return -1;
- }
-
- lut = new_lookuptable(this);
-
- while(!feof(fp)) {
- if(!fgets(line,256,fp))
- break;
- tok=strtok(line," ");
- if(lookup_parameter(lut,tok,&ptr,&type)) {
- tok=strtok(NULL," \n");
- switch(type) {
- case TYPE_INT:
- sscanf(tok,"%d",(int *)ptr);
-#if OVERLAY_LOG
- printf("dxr3: value \"%s\" -> %d\n", tok, *(int*)ptr);
-#endif
- break;
- case TYPE_XINT:
- sscanf(tok,"%x",(int *)ptr);
-#if OVERLAY_LOG
- printf("dxr3: value \"%s\" -> %d\n", tok, *(int*)ptr);
-#endif
- break;
- case TYPE_FLOAT:
- sscanf(tok,"%f",(float *)ptr);
-#if OVERLAY_LOG
- printf("dxr3: value \"%s\" -> %f\n", tok, *(float*)ptr);
-#endif
- break;
- case TYPE_COEFF:
- for(j=0;j<3;j++) {
- sscanf(tok,"%f",&((struct coeff *)ptr)[j].k);
-#if OVERLAY_LOG
- printf("dxr3: value (%d,k) \"%s\" -> %f\n", j, tok, ((struct coeff*)ptr)[j].k);
-#endif
- tok=strtok(NULL," \n");
- sscanf(tok,"%f",&((struct coeff *)ptr)[j].m);
-#if OVERLAY_LOG
- printf("dxr3: value (%d,m) \"%s\" -> %f\n", j, tok, ((struct coeff*)ptr)[j].m);
-#endif
- tok=strtok(NULL," \n");
- }
- break;
- }
- }
- }
- free(lut);
- fclose(fp);
- /* restore original locale */
- setlocale(LC_NUMERIC, loc);
- return 0;
-}
-
-static int col_interp(float x, struct coeff c)
-{
- int y;
- y = rint(x*c.k + c.m);
- if (y > 255) y = 255;
- if (y < 0) y = 0;
- return y;
-}
-
-int dxr3_overlay_set_keycolor(dxr3_overlay_t *this)
-{
- float r = (this->colorkey & 0xff0000) >> 16;
- float g = (this->colorkey & 0x00ff00) >> 8;
- float b = (this->colorkey & 0x0000ff);
- float interval = this->color_interval;
- int ret;
- int32_t overlay_limit;
- em8300_attribute_t attr;
-
-#if OVERLAY_LOG
- printf("dxr3: set_keycolor: r=%f g=%f b=%f, interval = %f\n",
- r,g,b,interval);
-#endif
- overlay_limit = /* lower limit */
- col_interp(r - interval, this->colcal_lower[0]) << 16 |
- col_interp(g - interval, this->colcal_lower[1]) << 8 |
- col_interp(b - interval, this->colcal_lower[2]);
-
-#if OVERLAY_LOG
- printf("dxr3: lower overlay_limit = %d\n", overlay_limit);
-#endif
- attr.attribute = EM9010_ATTRIBUTE_KEYCOLOR_LOWER;
- attr.value = overlay_limit;
- ret = ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr);
- if (ret < 0) {
- printf("dxr3: WARNING: error setting overlay upperl limit attribute\n");
- return ret;
- }
-
- overlay_limit = /* upper limit */
- col_interp(r + interval, this->colcal_upper[0]) << 16 |
- col_interp(g + interval, this->colcal_upper[1]) << 8 |
- col_interp(b + interval, this->colcal_upper[2]);
-#if OVERLAY_LOG
- printf("dxr3: upper overlay_limit = %d\n", overlay_limit);
-#endif
- attr.attribute = EM9010_ATTRIBUTE_KEYCOLOR_UPPER;
- attr.value = overlay_limit;
- ret = ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr);
- if (ret < 0) {
- printf("dxr3: WARNING: error setting overlay upperl limit attribute\n");
- }
- return ret;
-}
-
-
-int dxr3_overlay_set_mode(dxr3_overlay_t *this, int mode)
-{
- return ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETMODE, &mode);
-}
-
-int dxr3_overlay_set_attributes(dxr3_overlay_t *this)
-{
- em8300_attribute_t attr;
- attr.attribute = EM9010_ATTRIBUTE_XOFFSET;
- attr.value = this->xoffset;
- if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1)
- return -1;
- attr.attribute = EM9010_ATTRIBUTE_YOFFSET;
- attr.value = this->yoffset;
- if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1)
- return -1;
- attr.attribute = EM9010_ATTRIBUTE_XCORR;
- attr.value = this->xcorr;
- if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1)
- return -1;
- attr.attribute = EM9010_ATTRIBUTE_STABILITY;
- attr.value = this->stability;
- if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1)
- return -1;
- attr.attribute = EM9010_ATTRIBUTE_JITTER;
- attr.value = this->jitter;
- return ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr);
-}
-
-int dxr3_overlay_set_screen(dxr3_overlay_t *this)
-{
- em8300_overlay_screen_t scr;
- scr.xsize = this->screen_xres;
- scr.ysize = this->screen_yres;
- return ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETSCREEN, &scr);
-}
-
-int dxr3_overlay_set_window(dxr3_overlay_t *this,
- int xpos, int ypos, int width, int height)
-{
- em8300_overlay_window_t win;
-
- /* is some part of the picture visible? */
- if (xpos+width < 0) return 0;
- if (ypos+height < 0) return 0;
- if (xpos > this->screen_xres) return 0;
- if (ypos > this->screen_yres) return 0;
-
- win.xpos = xpos;
- win.ypos = ypos;
- win.width = width;
- win.height = height;
- return ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETWINDOW, &win);
-}
-
-int dxr3_overlay_set_signalmode(dxr3_overlay_t *this,int mode)
-{
- return ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SIGNALMODE, &mode);
-}
-
-void dxr3_overlay_buggy_preinit(dxr3_overlay_t *this, int fd)
-{
- /* TODO: catch errors */
-
- this->fd_control = fd;
- dxr3_overlay_set_screen(this);
- dxr3_overlay_set_window(this, 1,1, 2,2);
- dxr3_overlay_set_keycolor(this);
- dxr3_overlay_set_attributes(this);
- dxr3_overlay_set_mode(this, EM8300_OVERLAY_MODE_OVERLAY);
-}
diff --git a/src/dxr3/mpeg_encoders.c b/src/dxr3/mpeg_encoders.c
deleted file mode 100644
index 841a9d8ae..000000000
--- a/src/dxr3/mpeg_encoders.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * 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: mpeg_encoders.c,v 1.7 2002/05/06 11:26:37 jcdutton Exp $
- *
- * mpeg encoders for the dxr3 video out plugin.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#ifdef HAVE_LIBRTE
-# define _GNU_SOURCE
-# include <unistd.h>
-# include <rte.h>
-#endif
-#ifdef HAVE_LIBFAME
-# include <fame.h>
-#endif
-
-#include "dxr3_video_out.h"
-
-#define MV_COMMAND 0
-/* buffer size for encoded mpeg1 stream; will hold one intra frame
- * at 640x480 typical sizes are <50 kB. 512 kB should be plenty */
-#define DEFAULT_BUFFER_SIZE 512*1024
-
-#ifdef HAVE_LIBRTE
-typedef struct {
- encoder_data_t encoder_data;
- int width, height;
- rte_context* context; /* handle for encoding */
- void* rte_ptr; /* buffer maintened by librte */
- double rte_time; /* frame time (s) */
- double rte_time_step; /* time per frame (s) */
- double rte_bitrate; /* mpeg out bitrate, default 2.3e6 bits/s */
-} rte_data_t;
-
-
-static void mp1e_callback(rte_context *context, void *data, ssize_t size,
- void* user_data)
-{
- dxr3_driver_t *this = (dxr3_driver_t*)user_data;
- em8300_register_t regs;
- char tmpstr[128];
-
- if (this->enhanced_mode)
- {
- regs.microcode_register=1; /* Yes, this is a MC Reg */
- regs.reg = MV_COMMAND;
- regs.val=6; /* Mike's mystery number :-) */
- ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &regs);
- }
- if (this->fd_video == CLOSED_FOR_ENCODER) {
- snprintf (tmpstr, sizeof(tmpstr), "%s_mv%s", this->devname, this->devnum);
- this->fd_video = open(tmpstr, O_WRONLY | O_NONBLOCK);
- }
- if (this->fd_video < 0) return;
- /* FIXME: Is a SETPTS necessary here? */
- if (write(this->fd_video, data, size) < 0)
- perror("dxr3: writing to video device");
-}
-
-static int rte_on_update_format(dxr3_driver_t *drv)
-{
- rte_data_t *this = (rte_data_t*)drv->enc;
- rte_context* context;
- rte_codec *codec;
- int width, height;
- char tmpstr[128];
-
- width = drv->video_width;
- height = drv->video_height;
-
- if (this->context != 0) {/* already running */
- printf("dxr3: closing current encoding context.\n");
- rte_stop(this->context);
- rte_context_delete(this->context);
- this->context = 0;
- }
- this->width = width;
- this->height = height;
-
- this->context = rte_context_new (width, height, "mp1e", drv);
- if (! this->context) {
- printf("dxr3: failed to get rte context.\n");
- return 1;
- }
- context = this->context; /* shortcut */
- rte_set_verbosity(context, 2);
- /* get mpeg codec handle */
- codec = rte_codec_set(context, RTE_STREAM_VIDEO, 0, "mpeg1_video");
- if (! codec) {
- printf("dxr3: could not create codec.\n");
- rte_context_destroy(context);
- context = 0;
- return 1;
- }
- this->rte_bitrate=drv->config->register_range(drv->config,"dxr3.rte_bitrate",10000, 1000,20000, "Dxr3enc: rte mpeg output bitrate (kbit/s)",NULL,NULL,NULL);
- this->rte_bitrate *= 1000; /* config in kbit/s, rte wants bit/s */
- /* FIXME: this needs to be replaced with a codec option call.
- * However, there seems to be none for the colour format!
- * So we'll use the deprecated set_video_parameters instead.
- * Alternative is to manually set context->video_format (RTE_YU... )
- * and context->video_bytes (= width * height * bytes/pixel) */
- rte_set_video_parameters(context,
- (drv->format == IMGFMT_YV12 ? RTE_YUV420 : RTE_YUYV),
- context->width, context->height,
- context->video_rate, context->output_video_bits,
- context->gop_sequence);
- /* Now set a whole bunch of codec options */
- /* If I understand correctly, virtual_frame_rate is the frame rate
- * of the source (can be anything), while coded_frame_rate must be
- * one of the mpeg1 alloweds */
- if (!rte_option_set(codec, "virtual_frame_rate", drv->fps))
- printf("dxr3: WARNING: rte_option_set failed; virtual_frame_rate=%g.\n",drv->fps);
- if (!rte_option_set(codec, "coded_frame_rate", drv->fps))
- printf("dxr3: WARNING: rte_option_set failed; coded_frame_rate=%g.\n",drv->fps);
- if (!rte_option_set(codec, "bit_rate", (int)this->rte_bitrate))
- printf("dxr3: WARNING: rte_option_set failed; bit_rate = %d.\n",
- (int)this->rte_bitrate);
- if (!rte_option_set(codec, "gop_sequence", "I"))
- printf("dxr3: WARNING: rte_option_set failed; gop_sequence = \"I\".\n");
- /* just to be sure, disable motion comp (not needed in I frames) */
- if (!rte_option_set(codec, "motion_compensation", 0))
- printf("dxr3: WARNING: rte_option_set failed; motion_compensation = 0.\n");
- rte_set_input(context, RTE_VIDEO, RTE_PUSH, FALSE, NULL, NULL, NULL);
- snprintf (tmpstr, sizeof(tmpstr), "%s_mv", drv->devname);
- rte_set_output(context, mp1e_callback, NULL, NULL);
- if (!rte_init_context(context)) {
- printf("dxr3: cannot init the context: %s\n",
- context->error);
- rte_context_delete(context);
- context = 0;
- return 1;
- }
- /* do the sync'ing and start encoding */
- if (!rte_start_encoding(context)) {
- printf("dxr3: cannot start encoding: %s\n",
- context->error);
- rte_context_delete(context);
- context = 0;
- return 1;
- }
- this->rte_ptr = rte_push_video_data(context, NULL, 0);
- if (! this->rte_ptr) {
- printf("dxr3: failed to get encoder buffer pointer.\n");
- return 1;
- }
- this->rte_time = 0.0;
- this->rte_time_step = 1.0/drv->fps;
-
- return 0;
-}
-
-static int rte_on_display_frame( dxr3_driver_t* drv, dxr3_frame_t* frame )
-{
- int size;
- rte_data_t* this = (rte_data_t*)drv->enc;
-
- if ( (this->width != frame->width) || (this->height != frame->oheight)){
- /* maybe we were reinitialized and get an old frame. */
- return 0;
- }
- size = frame->width * frame->oheight;
- if (frame->vo_frame.format == IMGFMT_YV12)
- xine_fast_memcpy(this->rte_ptr, frame->real_base[0], size*3/2);
- else
- xine_fast_memcpy(this->rte_ptr, frame->real_base[0], size*2);
- this->rte_time += this->rte_time_step;
- this->rte_ptr = rte_push_video_data(this->context, this->rte_ptr,
- this->rte_time);
- frame->vo_frame.displayed(&frame->vo_frame);
- return 0;
-}
-
-static int rte_on_close( dxr3_driver_t *drv )
-{
- rte_data_t *this = (rte_data_t*)drv->enc;
- if (this->context) {
- rte_stop(this->context);
- rte_context_delete(this->context);
- this->context = 0;
- }
- free(this);
- drv->enc = 0;
- return 0;
-}
-
-int dxr3_rte_init( dxr3_driver_t *drv )
-{
- rte_data_t* this;
- if (! rte_init() ) {
- printf("dxr3: failed to init librte\n");
- return 1;
- }
- this = malloc(sizeof(rte_data_t));
- if (!this)
- return 1;
- memset(this, 0, sizeof(rte_data_t));
- this->encoder_data.type = ENC_RTE;
- this->context = 0;
- this->encoder_data.on_update_format = rte_on_update_format;
- this->encoder_data.on_frame_copy = 0;
- this->encoder_data.on_display_frame = rte_on_display_frame;
- this->encoder_data.on_close = rte_on_close;
- drv->enc = (encoder_data_t*)this;
- return 0;
-}
-
-#endif
-
-#ifdef HAVE_LIBFAME
-typedef struct {
- encoder_data_t encoder_data;
- fame_context_t *fc; /* needed for fame calls */
- fame_parameters_t fp;
- fame_yuv_t yuv;
- /* temporary buffer for mpeg data */
- char *buffer;
- /* temporary buffer for YUY2->YV12 conversion */
- uint8_t *out[3]; /* aligned buffer for YV12 data */
- uint8_t *buf; /* unaligned YV12 buffer */
-} fame_data_t;
-
-
-static fame_parameters_t dummy_init_fp = FAME_PARAMETERS_INITIALIZER;
-
-static int fame_on_update_format(dxr3_driver_t *drv)
-{
- fame_data_t *this = (fame_data_t*)drv->enc;
- double fps;
-
- /* if YUY2 and dimensions changed, we need to re-allocate the
- * internal YV12 buffer */
- if (this->buf) free(this->buf);
- this->buf = 0;
- this->out[0] = this->out[1] = this->out[2] = 0;
- if (drv->format == IMGFMT_YUY2) {
- int image_size = drv->video_width * drv->video_height;
-
- this->out[0] = malloc_aligned(16, image_size * 3/2,
- (void*)&this->buf);
- this->out[1] = this->out[0] + image_size;
- this->out[2] = this->out[1] + image_size/4;
-
- /* fill with black (yuv 16,128,128) */
- memset(this->out[0], 16, image_size);
- memset(this->out[1], 128, image_size/4);
- memset(this->out[2], 128, image_size/4);
-
- printf("dxr3: Using YUY2->YV12 conversion\n");
- }
-
- if (this->fc) {
- printf("dxr3: closing current encoding context.\n");
- fame_close(this->fc);
- this->fc = 0;
- }
- if (!this->fc)
- this->fc = fame_open();
- if (!this->fc) {
- printf("Couldn't start the FAME library\n");
- return 1;
- }
-
- if (!this->buffer)
- this->buffer = (unsigned char *) malloc (DEFAULT_BUFFER_SIZE);
- if (!this->buffer) {
- printf("Couldn't allocate temp buffer for mpeg data\n");
- return 1;
- }
-
- this->fp = dummy_init_fp;
- this->fp.quality=drv->config->register_range(drv->config,"dxr3.fame_quality",90, 10,100, "Dxr3enc: fame mpeg encoding quality",NULL,NULL,NULL);
- /* the really interesting bit is the quantizer scale. The formula
- * below is copied from libfame's sources (could be changed in the
- * future) */
- printf("dxr3: quality %d -> quant scale = %d\n", this->fp.quality,
- 1 + (30*(100-this->fp.quality)+50)/100);
- this->fp.width = drv->video_width;
- this->fp.height = drv->video_height;
- this->fp.profile = "mpeg1";
- this->fp.coding = "I";
- this->fp.verbose = 1; /* we don't need any more info.. thanks :) */
-
- /* start guessing the framerate */
- fps = drv->fps;
- if (fabs(fps - 25) < 0.01) { /* PAL */
- printf("dxr3: setting mpeg output framerate to PAL (25 Hz)\n");
- this->fp.frame_rate_num = 25; this->fp.frame_rate_den = 1;
- }
- else if (fabs(fps - 24) < 0.01) { /* FILM */
- printf("dxr3: setting mpeg output framerate to FILM (24 Hz))\n");
- this->fp.frame_rate_num = 24; this->fp.frame_rate_den = 1;
- }
- else if (fabs(fps - 23.976) < 0.01) { /* NTSC-FILM */
- printf("dxr3: setting mpeg output framerate to NTSC-FILM (23.976 Hz))\n");
- this->fp.frame_rate_num = 24000; this->fp.frame_rate_den = 1001;
- }
- else if (fabs(fps - 29.97) < 0.01) { /* NTSC */
- printf("dxr3: setting mpeg output framerate to NTSC (29.97 Hz)\n");
- this->fp.frame_rate_num = 30000; this->fp.frame_rate_den = 1001;
- }
- else { /* try 1/fps, if not legal, libfame will go to PAL */
- this->fp.frame_rate_num = (int)(fps + 0.5); this->fp.frame_rate_den = 1;
- printf("dxr3: trying to set mpeg output framerate to %d Hz\n",
- this->fp.frame_rate_num);
- }
- fame_init (this->fc, &this->fp, this->buffer, DEFAULT_BUFFER_SIZE);
-
- return 0;
-}
-
-static int fame_prepare_frame(fame_data_t* this, dxr3_driver_t *drv,
- dxr3_frame_t *frame)
-{
- int i, j, w2;
- uint8_t *y, *u, *v, *yuy2;
-
- if (frame->vo_frame.bad_frame)
- return 0;
-
- if (frame->vo_frame.format == IMGFMT_YUY2) {
- /* need YUY2->YV12 conversion */
- if (! (this->out[0] && this->out[1] && this->out[2]) ) {
- printf("dxr3: Internal error. Internal YV12 buffer not created.\n");
- return 1;
- }
- /* need conversion */
- y = this->out[0] + frame->width*drv->top_bar;
- u = this->out[1] + frame->width/2*(drv->top_bar/2);
- v = this->out[2] + frame->width/2*(drv->top_bar/2);
- yuy2 = frame->vo_frame.base[0];
- w2 = frame->width/2;
- for (i=0; i<frame->height; i+=2) {
- for (j=0; j<w2; j++) {
- /* packed YUV 422 is: Y[i] U[i] Y[i+1] V[i] */
- *(y++) = *(yuy2++);
- *(u++) = *(yuy2++);
- *(y++) = *(yuy2++);
- *(v++) = *(yuy2++);
- }
- /* down sampling */
- for (j=0; j<w2; j++) {
- /* skip every second line for U and V */
- *(y++) = *(yuy2++);
- yuy2++;
- *(y++) = *(yuy2++);
- yuy2++;
- }
- }
- /* reset for encoder */
- y = this->out[0];
- u = this->out[1];
- v = this->out[2];
- }
- else { /* YV12 */
- y = frame->real_base[0];
- u = frame->real_base[1];
- v = frame->real_base[2];
- }
-
- this->yuv.y=y;
- this->yuv.u=u;
- this->yuv.v=v;
- return 0;
-}
-
-
-static int fame_on_display_frame( dxr3_driver_t* drv, dxr3_frame_t* frame)
-{
- char tmpstr[128];
- em8300_register_t regs;
- int size;
- fame_data_t *this = (fame_data_t*)drv->enc;
-
- if ((frame->width != this->fp.width) || (frame->oheight != this->fp.height)) {
- /* probably an old frame for a previous context. ignore it */
- return 0;
- }
-
- fame_prepare_frame(this, drv, frame);
- size = fame_encode_frame(this->fc, &this->yuv, NULL);
-
- if (drv->enhanced_mode)
- {
- regs.microcode_register=1; /* Yes, this is a MC Reg */
- regs.reg = MV_COMMAND;
- regs.val=6; /* Mike's mystery number :-) */
- ioctl(drv->fd_control, EM8300_IOCTL_WRITEREG, &regs);
- }
-
- if (drv->fd_video == CLOSED_FOR_ENCODER) {
- snprintf (tmpstr, sizeof(tmpstr), "%s_mv%s", drv->devname, drv->devnum);
- drv->fd_video = open(tmpstr, O_WRONLY | O_NONBLOCK);
- }
- if (drv->fd_video >= 0)
- /* FIXME: Is a SETPTS necessary here? */
- if (write(drv->fd_video, this->buffer, size) < 0)
- perror("dxr3: writing to video device");
- frame->vo_frame.displayed(&frame->vo_frame);
- return 0;
-}
-
-static int fame_on_close( dxr3_driver_t *drv )
-{
- fame_data_t *this = (fame_data_t*)drv->enc;
- if (this->fc) {
- fame_close(this->fc);
- }
- free(this);
- drv->enc = 0;
- return 0;
-}
-
-int dxr3_fame_init( dxr3_driver_t *drv )
-{
- fame_data_t* this;
- this = malloc(sizeof(fame_data_t));
- if (! this)
- return 1;
- memset(this, 0, sizeof(fame_data_t));
- this->encoder_data.type = ENC_FAME;
- /* fame context */
- this->fc = 0;
- this->encoder_data.on_update_format = fame_on_update_format;
- this->encoder_data.on_frame_copy = NULL;
- this->encoder_data.on_display_frame = fame_on_display_frame;
- this->encoder_data.on_close = fame_on_close;
- drv->enc = (encoder_data_t*)this;
- return 0;
-}
-
-#endif
-
diff --git a/src/dxr3/video_out_dxr3.c b/src/dxr3/video_out_dxr3.c
new file mode 100644
index 000000000..507632add
--- /dev/null
+++ b/src/dxr3/video_out_dxr3.c
@@ -0,0 +1,1221 @@
+/*
+ * 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: video_out_dxr3.c,v 1.20 2002/05/24 22:09:44 miguelfreitas Exp $
+ */
+
+/* mpeg1 encoding video out plugin for the dxr3.
+ *
+ * modifications to the original dxr3 video out plugin by
+ * Mike Lampard <mike at web2u.com.au>
+ * this first standalone version by
+ * Harm van der Heijden <hrm at users.sourceforge.net>
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+#ifdef HAVE_XINERAMA
+# include <X11/extensions/Xinerama.h>
+#endif
+
+#include "xine_internal.h"
+#include "xineutils.h"
+#include "video_out.h"
+#include "../video_out/video_out_x11.h"
+#include "alphablend.h"
+#include "dxr3.h"
+#include "video_out_dxr3.h"
+
+#define LOG_VID 1
+#define LOG_OVR 0
+
+
+/* plugin initialization functions */
+vo_info_t *get_video_out_plugin_info();
+vo_driver_t *init_video_out_plugin(config_values_t *config, void *visual_gen);
+
+/* functions required by xine api */
+static uint32_t dxr3_get_capabilities(vo_driver_t *this_gen);
+static vo_frame_t *dxr3_alloc_frame(vo_driver_t *this_gen);
+static void dxr3_frame_copy(vo_frame_t *frame_gen, uint8_t **src);
+static void dxr3_frame_field(vo_frame_t *vo_img, int which_field);
+static void dxr3_frame_dispose(vo_frame_t *frame_gen);
+static void dxr3_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_gen,
+ uint32_t width, uint32_t height,
+ int ratio_code, int format, int flags);
+static void dxr3_overlay_blend(vo_driver_t *this_gen, vo_frame_t *frame_gen,
+ vo_overlay_t *overlay);
+static void dxr3_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen);
+static int dxr3_redraw_needed(vo_driver_t *this_gen);
+static int dxr3_get_property(vo_driver_t *this_gen, int property);
+static int dxr3_set_property(vo_driver_t *this_gen, int property, int value);
+static void dxr3_get_property_min_max(vo_driver_t *this_gen, int property,
+ int *min, int *max);
+static int dxr3_gui_data_exchange(vo_driver_t *this_gen,
+ int data_type, void *data);
+static void dxr3_exit(vo_driver_t *this_gen);
+
+/* overlay helper functions only called once during plugin init */
+static void gather_screen_vars(dxr3_driver_t *this, x11_visual_t *vis);
+static int dxr3_overlay_read_state(dxr3_overlay_t *this);
+static int dxr3_overlay_set_keycolor(dxr3_overlay_t *this);
+static int dxr3_overlay_set_attributes(dxr3_overlay_t *this);
+
+/* overlay helper functions */
+static int dxr3_overlay_set_window(dxr3_overlay_t *this, int xpos, int ypos,
+ int width, int height);
+static void dxr3_overlay_update(dxr3_driver_t *this);
+static void dxr3_zoomTV(dxr3_driver_t *this);
+static void dxr3_translate_gui2video(dxr3_driver_t *this, int x, int y,
+ int *vid_x, int *vid_y);
+static int is_fullscreen(dxr3_driver_t *this);
+
+/* config callbacks */
+static void dxr3_update_add_bars(void *data, cfg_entry_t *entry);
+static void dxr3_update_swap_fields(void *data, cfg_entry_t *entry);
+static void dxr3_update_enhanced_mode(void *this_gen, cfg_entry_t *entry);
+
+
+vo_info_t *get_video_out_plugin_info()
+{
+ static vo_info_t vo_info_dxr3 = {
+ 5, /* api version */
+ "dxr3",
+ "xine video output plugin for dxr3 cards",
+ VISUAL_TYPE_X11,
+ 10 /* priority */
+ };
+
+ return &vo_info_dxr3;
+}
+
+vo_driver_t *init_video_out_plugin(config_values_t *config, void *visual_gen)
+{
+ dxr3_driver_t *this;
+ char tmpstr[100];
+ char *available_encoders, *default_encoder;
+ const char *confstr;
+ int dashpos;
+
+ this = (dxr3_driver_t *)malloc(sizeof(dxr3_driver_t));
+ if (!this) return NULL;
+ memset(this, 0, sizeof(dxr3_driver_t));
+
+ this->vo_driver.get_capabilities = dxr3_get_capabilities;
+ this->vo_driver.alloc_frame = dxr3_alloc_frame;
+ this->vo_driver.update_frame_format = dxr3_update_frame_format;
+ this->vo_driver.overlay_blend = dxr3_overlay_blend;
+ this->vo_driver.display_frame = dxr3_display_frame;
+ this->vo_driver.redraw_needed = dxr3_redraw_needed;
+ this->vo_driver.get_property = dxr3_get_property;
+ this->vo_driver.set_property = dxr3_set_property;
+ this->vo_driver.get_property_min_max = dxr3_get_property_min_max;
+ this->vo_driver.gui_data_exchange = dxr3_gui_data_exchange;
+ this->vo_driver.exit = dxr3_exit;
+
+ this->config = config;
+ this->aspect = ASPECT_FULL;
+ this->overlay_enabled = 0;
+ this->swap_fields = config->register_bool(config,
+ "dxr3.enc_swap_fields", 0, "swap odd and even lines", NULL, dxr3_update_swap_fields, this);
+ this->add_bars = config->register_bool(config,
+ "dxr3.enc_add_bars", 1, "Add black bars to correct aspect ratio",
+ "If disabled, will assume source has 4:3 aspect ratio.", dxr3_update_add_bars, this);
+ this->enhanced_mode = config->register_bool(config,
+ "dxr3.enc_alt_play_mode", 1, "dxr3: use alternate play mode for mpeg encoder playback",
+ "Enabling this option will utilise a smoother play mode", dxr3_update_enhanced_mode, this);
+
+ confstr = config->register_string(config, CONF_LOOKUP, CONF_DEFAULT, CONF_NAME, CONF_HELP, NULL, NULL);
+ strncpy(this->devname, confstr, 128);
+ this->devname[127] = '\0';
+ dashpos = strlen(this->devname) - 2; /* the dash in the new device naming scheme would be here */
+ if (this->devname[dashpos] == '-') {
+ /* use new device naming scheme with trailing number */
+ strncpy(this->devnum, &this->devname[dashpos], 3);
+ this->devname[dashpos] = '\0';
+ } else {
+ /* use old device naming scheme without trailing number */
+ /* FIXME: remove this when everyone uses em8300 >=0.12.0 */
+ this->devnum[0] = '\0';
+ }
+
+ snprintf(tmpstr, sizeof(tmpstr), "%s%s", this->devname, this->devnum);
+#if LOG_VID
+ printf("video_out_dxr3: Entering video init, devname = %s.\n", tmpstr);
+#endif
+ if ((this->fd_control = open(tmpstr, O_WRONLY)) < 0) {
+ printf("video_out_dxr3: Failed to open control device %s (%s)\n",
+ tmpstr, strerror(errno));
+ return 0;
+ }
+
+ snprintf (tmpstr, sizeof(tmpstr), "%s_mv%s", this->devname, this->devnum);
+ if ((this->fd_video = open (tmpstr, O_WRONLY | O_SYNC )) < 0) {
+ printf("dxr3:Ffailed to open video device %s (%s)\n",
+ tmpstr, strerror(errno));
+ return 0;
+ }
+ /* close now and and let the decoder/encoder reopen if they want */
+ close(this->fd_video);
+ this->fd_video = CLOSED_FOR_DECODER;
+
+ /* which encoder to use? Whadda we got? */
+ default_encoder = 0;
+ this->enc = 0;
+ /* memory leak... but config doesn't copy our help string :-( */
+ available_encoders = malloc(256);
+ strcpy(available_encoders, "Mpeg1 encoder. Options: ");
+#ifdef HAVE_LIBFAME
+ default_encoder = "fame";
+ strcat(available_encoders, "\"fame\" (very fast, good quality) ");
+#endif
+#ifdef HAVE_LIBRTE
+ default_encoder = "rte";
+ strcat(available_encoders, "\"rte\" (fast, high quality) ");
+#endif
+#if LOG_VID
+ printf("video_out_dxr3: %s\n", available_encoders);
+#endif
+ if (default_encoder) {
+ confstr = config->register_string(config, "dxr3.encoder",
+ default_encoder, available_encoders, NULL, NULL, NULL);
+#ifdef HAVE_LIBRTE
+ if ((strcmp(confstr, "rte") == 0) && !dxr3_rte_init(this))
+ return 0;
+#endif
+#ifdef HAVE_LIBFAME
+ if ((strcmp(confstr, "fame") == 0) && !dxr3_fame_init(this))
+ return 0;
+#endif
+ if (this->enc == 0)
+ printf("video_out_dxr3: mpeg encoder \"%s\" not compiled in or not supported.\n"
+ "video_out_dxr3: valid options are %s\n", confstr, available_encoders);
+ }
+ else
+ printf("video_out_dxr3: no mpeg encoder compiled in.\n"
+ "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n"
+ "video_out_dxr3: you will not be able to play non-mpeg content using this video out\n"
+ "video_out_dxr3: driver. See the README.dxr3 for details on configuring an encoder.\n");
+
+ /* init bcs */
+ if (ioctl(this->fd_control, EM8300_IOCTL_GETBCS, &this->bcs))
+ printf("video_out_dxr3: cannot read bcs values (%s)\n",
+ strerror(errno));
+ this->bcs.contrast = config->register_range(config, "dxr3.contrast",
+ this->bcs.contrast, 100, 900, "Dxr3: contrast control", NULL, NULL, NULL);
+ this->bcs.saturation = config->register_range(config, "dxr3.saturation",
+ this->bcs.saturation, 100, 900, "Dxr3: saturation control", NULL, NULL, NULL);
+ this->bcs.brightness = config->register_range(config, "dxr3.brightness",
+ this->bcs.brightness, 100, 900, "Dxr3: brightness control", NULL, NULL, NULL);
+
+ /* overlay or tvout? */
+ confstr = config->register_string(config, "dxr3.videoout_mode", "tv",
+ "Dxr3: videoout mode (tv or overlay)", NULL, NULL, NULL);
+#if LOG_VID
+ printf("video_out_dxr3: overlaymode = %s\n", confstr);
+#endif
+ if (strcasecmp(confstr, "tv") == 0) {
+ this->overlay_enabled = 0;
+ this->tv_switchable = 0; /* don't allow on-the-fly switching */
+ } else if (strcasecmp(confstr, "overlay") == 0) {
+#if LOG_VID
+ printf("video_out_dxr3: setting up overlay mode\n");
+#endif
+ gather_screen_vars(this, visual_gen);
+ if (dxr3_overlay_read_state(&this->overlay) == 0) {
+ this->overlay_enabled = 1;
+ this->tv_switchable = 1;
+ confstr = config->register_string(config, "dxr3.keycolor", "0x80a040",
+ "Dxr3: overlay colorkey value", NULL, NULL, NULL);
+ sscanf(confstr, "%x", &this->overlay.colorkey);
+ confstr = config->register_string(config, "dxr3.color_interval", "50.0",
+ "Dxr3: overlay colorkey range",
+ "A greater value widens the tolerance for the overlay keycolor", NULL, NULL);
+ sscanf(confstr, "%f", &this->overlay.color_interval);
+ } else {
+ printf("video_out_dxr3: please run autocal, overlay disabled\n");
+ this->overlay_enabled = 0;
+ this->tv_switchable = 0;
+ }
+ }
+
+ /* init tvmode */
+ confstr = config->register_string(config, "dxr3.preferred_tvmode", "default",
+ "Dxr3 preferred tv mode - PAL, PAL60, NTSC or default", NULL, NULL, NULL);
+ if (strcasecmp(confstr, "ntsc") == 0) {
+ this->tv_mode = EM8300_VIDEOMODE_NTSC;
+#if LOG_VID
+ printf("video_out_dxr3: setting tv_mode to NTSC\n");
+#endif
+ } else if (strcasecmp(confstr, "pal") == 0) {
+ this->tv_mode = EM8300_VIDEOMODE_PAL;
+#if LOG_VID
+ printf("video_out_dxr3: setting tv_mode to PAL 50Hz\n");
+#endif
+ } else if (strcasecmp(confstr, "pal60") == 0) {
+ this->tv_mode = EM8300_VIDEOMODE_PAL60;
+#if LOG_VID
+ printf("video_out_dxr3: setting tv_mode to PAL 60Hz\n");
+#endif
+ } else {
+ this->tv_mode = EM8300_VIDEOMODE_DEFAULT;
+ }
+ if (this->tv_mode != EM8300_VIDEOMODE_DEFAULT)
+ if (ioctl(this->fd_control, EM8300_IOCTL_SET_VIDEOMODE, &this->tv_mode))
+ printf("video_out_dxr3: setting video mode failed.\n");
+
+ /* initialize overlay */
+ if (this->overlay_enabled) {
+ em8300_overlay_screen_t scr;
+
+ this->overlay.fd_control = this->fd_control;
+
+ /* allocate keycolor */
+ this->color.red = ((this->overlay.colorkey >> 16) & 0xff) * 256;
+ this->color.green = ((this->overlay.colorkey >> 8) & 0xff) * 256;
+ this->color.blue = ((this->overlay.colorkey ) & 0xff) * 256;
+ XAllocColor(this->display, DefaultColormap(this->display, 0), &this->color);
+
+ /* set the screen */
+ scr.xsize = this->overlay.screen_xres;
+ scr.ysize = this->overlay.screen_yres;
+ if (ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETSCREEN, &scr))
+ printf("video_out_dxr3: setting the overlay screen failed.\n");
+
+ if (dxr3_overlay_set_window(&this->overlay, 1, 1, 2, 2) != 0)
+ printf("video_out_dxr3: setting the overlay window failed.\n");
+ if (dxr3_overlay_set_keycolor(&this->overlay) != 0)
+ printf("video_out_dxr3: setting the overlay keycolor failed.\n");
+ if (dxr3_overlay_set_attributes(&this->overlay) != 0)
+ printf("video_out_dxr3: setting an overlay attribute failed.\n");
+
+ if (ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETMODE, EM8300_OVERLAY_MODE_OVERLAY) != 0)
+ printf("video_out_dxr3: failed to enable overlay.\n");
+ }
+
+ dxr3_set_property(&this->vo_driver, VO_PROP_ASPECT_RATIO, this->aspect);
+ return &this->vo_driver;
+}
+
+static uint32_t dxr3_get_capabilities(vo_driver_t *this_gen)
+{
+ return VO_CAP_YV12 | VO_CAP_YUY2 |
+ VO_CAP_SATURATION | VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST;
+}
+
+static vo_frame_t *dxr3_alloc_frame(vo_driver_t *this_gen)
+{
+ dxr3_frame_t *frame;
+ dxr3_driver_t *this = (dxr3_driver_t *)this_gen;
+
+ frame = (dxr3_frame_t *)malloc(sizeof(dxr3_frame_t));
+ memset(frame, 0, sizeof(dxr3_frame_t));
+
+ pthread_mutex_init(&frame->vo_frame.mutex, NULL);
+
+ if (this->enc && this->enc->on_frame_copy)
+ frame->vo_frame.copy = dxr3_frame_copy;
+ else
+ frame->vo_frame.copy = 0;
+ frame->vo_frame.field = dxr3_frame_field;
+ frame->vo_frame.dispose = dxr3_frame_dispose;
+ frame->vo_frame.driver = this_gen;
+
+ return &frame->vo_frame;
+}
+
+static void dxr3_frame_copy(vo_frame_t *frame_gen, uint8_t **src)
+{
+ dxr3_frame_t *frame = (dxr3_frame_t *)frame_gen;
+ dxr3_driver_t *this = (dxr3_driver_t *)frame_gen->driver;
+
+ if (frame_gen->format != IMGFMT_MPEG && this->enc && this->enc->on_frame_copy)
+ this->enc->on_frame_copy(this, frame, src);
+}
+
+static void dxr3_frame_field(vo_frame_t *vo_img, int which_field)
+{
+ /* dummy function */
+}
+
+static void dxr3_frame_dispose(vo_frame_t *frame_gen)
+{
+ dxr3_frame_t *frame = (dxr3_frame_t *)frame_gen;
+
+ if (frame->mem) free(frame->mem);
+ pthread_mutex_destroy(&frame_gen->mutex);
+ free(frame);
+}
+
+static void dxr3_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_gen,
+ uint32_t width, uint32_t height, int ratio_code, int format, int flags)
+{
+ dxr3_driver_t *this = (dxr3_driver_t *)this_gen;
+ dxr3_frame_t *frame = (dxr3_frame_t *)frame_gen;
+ int i;
+ int aspect, oheight;
+
+ /* update the overlay window co-ords if required */
+ dxr3_overlay_update(this);
+
+ if (format == IMGFMT_MPEG) { /* talking to dxr3 decoder */
+ /* a bit of a hack. we must release the em8300_mv fd for
+ * the dxr3 decoder plugin */
+ if (this->fd_video >= 0) {
+ close(this->fd_video);
+ this->fd_video = CLOSED_FOR_DECODER;
+ }
+
+ /* for mpeg source, we don't have to do much. */
+ this->video_width = width;
+ this->video_iheight = height;
+ this->video_oheight = height;
+ this->top_bar = 0;
+ this->video_aspect = ratio_code;
+
+ frame->width = width;
+ frame->iheight = height;
+ frame->oheight = height;
+
+ if (frame->mem) {
+ free(frame->mem);
+ frame->mem = NULL;
+ frame->real_base[0] = frame->real_base[1] = frame->real_base[2] = NULL;
+ frame_gen->base[0] = frame_gen->base[1] = frame_gen->base[2] = NULL;
+ }
+
+ if (ratio_code < 3 || ratio_code> 4) aspect = ASPECT_FULL;
+ else aspect = ASPECT_ANAMORPHIC;
+
+ if(this->aspect != aspect)
+ dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO, aspect);
+
+ return;
+ }
+
+ /* the following is for the mpeg encoding part only */
+
+ aspect = this->aspect;
+ oheight = this->video_oheight;
+
+ if (this->fd_video == CLOSED_FOR_DECODER) { /* decoder should have released it */
+ this->fd_video = CLOSED_FOR_ENCODER; /* allow encoder to reopen it */
+ this->need_redraw = 1;
+ }
+
+ if (this->add_bars == 0) {
+ /* don't add black bars; assume source is in 4:3 */
+ ratio_code = XINE_ASPECT_RATIO_4_3;
+ }
+
+ if ((this->video_width != width) || (this->video_iheight != height) ||
+ (this->video_aspect != ratio_code)) {
+ /* check aspect ratio, see if we need to add black borders */
+ switch (ratio_code) {
+ case XINE_ASPECT_RATIO_4_3:
+ aspect = ASPECT_FULL;
+ oheight = height;
+ break;
+ case XINE_ASPECT_RATIO_ANAMORPHIC:
+ aspect = ASPECT_ANAMORPHIC;
+ oheight = height;
+ break;
+ default: /* assume square pixel */
+ aspect = ASPECT_ANAMORPHIC;
+ oheight = (int)(width * 9./16.);
+ if (oheight < height) { /* frame too high, try 4:3 */
+ aspect = ASPECT_FULL;
+ oheight = (int)(width * 3./4.);
+ }
+ }
+
+ /* find closest multiple of 16 */
+ oheight = 16*(int)(oheight / 16. + 0.5);
+ if (oheight < height) oheight = height;
+
+ /* Tell the viewers about the aspect ratio stuff. */
+ if (oheight - height > 0)
+ printf("video_out_dxr3: adding %d black lines to get %s aspect ratio.\n",
+ oheight - height, aspect == ASPECT_FULL ? "4:3" : "16:9");
+
+ this->video_width = width;
+ this->video_iheight = height;
+ this->video_oheight = oheight;
+ this->video_aspect = ratio_code;
+ this->format = format;
+ this->need_redraw = 1;
+ this->need_update = 1;
+
+ if (!this->enc) {
+ /* no encoder plugin! Let's bug the user! */
+ printf("video_out_dxr3: ********************************************************\n"
+ "video_out_dxr3: * *\n"
+ "video_out_dxr3: * need an mpeg encoder to play non-mpeg videos on dxr3 *\n"
+ "video_out_dxr3: * read the README.dxr3 for details. *\n"
+ "video_out_dxr3: * (if you get this message while trying to play an *\n"
+ "video_out_dxr3: * mpeg video, there is something wrong with the dxr3 *\n"
+ "video_out_dxr3: * decoder plugin. check if it is set up correctly) *\n"
+ "video_out_dxr3: * *\n"
+ "video_out_dxr3: ********************************************************\n");
+ }
+ }
+
+ /* if dimensions changed, we need to re-allocate frame memory */
+ if ((frame->width != width) || (frame->iheight != height) ||
+ (frame->oheight != oheight)) {
+ if (frame->mem) {
+ free (frame->mem);
+ frame->mem = NULL;
+ }
+
+ /* make top black bar multiple of 16,
+ * so old and new macroblocks overlap */
+ this->top_bar = ((oheight - height) / 32) * 16;
+ if (format == IMGFMT_YUY2) {
+ int image_size = width * oheight; /* includes black bars */
+
+ /* planar format, only base[0] */
+ /* add one extra line for field swap stuff */
+ frame->real_base[0] = xine_xmalloc_aligned(16, (image_size + width) * 2,
+ (void**)&frame->mem);
+
+ /* don't use first line */
+ frame->real_base[0] += width * 2;
+ frame->real_base[1] = frame->real_base[2] = 0;
+
+ /* fix offset, so the decoder does not see the top black bar */
+ frame->vo_frame.base[0] = frame->real_base[0] + width * 2 * this->top_bar;
+ frame->vo_frame.base[1] = frame->vo_frame.base[2] = 0;
+
+ /* fill with black (yuy2 16,128,16,128,...) */
+ memset(frame->real_base[0], 128, 2 * image_size); /* U and V */
+ for (i = 0; i < 2 * image_size; i += 2) /* Y */
+ *(frame->real_base[0] + i) = 16;
+
+ } else { /* IMGFMT_YV12 */
+ int image_size = width * oheight; /* includes black bars */
+
+ /* add one extra line for field swap stuff */
+ frame->real_base[0] = xine_xmalloc_aligned(16, (image_size + width) * 3/2,
+ (void**)&frame->mem);
+
+ /* don't use first line */
+ frame->real_base[0] += width;
+ frame->real_base[1] = frame->real_base[0] + image_size;
+ frame->real_base[2] = frame->real_base[1] + image_size/4;
+
+ /* fix offsets, so the decoder does not see the top black bar */
+ frame->vo_frame.base[0] = frame->real_base[0] + width * this->top_bar;
+ frame->vo_frame.base[1] = frame->real_base[1] + width * this->top_bar/4;
+ frame->vo_frame.base[2] = frame->real_base[2] + width * this->top_bar/4;
+
+ /* fill with black (yuv 16,128,128) */
+ memset(frame->real_base[0], 16, image_size);
+ memset(frame->real_base[1], 128, image_size/4);
+ memset(frame->real_base[2], 128, image_size/4);
+ }
+ }
+
+ if (this->swap_fields != frame->swap_fields) {
+ if (format == IMGFMT_YUY2) {
+ if (this->swap_fields)
+ frame->vo_frame.base[0] -= width *2;
+ else
+ frame->vo_frame.base[0] += width *2;
+ } else {
+ if (this->swap_fields)
+ frame->vo_frame.base[0] -= width;
+ else
+ frame->vo_frame.base[0] += width;
+ }
+ }
+
+ frame->width = width;
+ frame->iheight = height;
+ frame->oheight = oheight;
+ frame->swap_fields = this->swap_fields;
+
+ if(this->aspect != aspect)
+ dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO, aspect);
+}
+
+static void dxr3_overlay_blend(vo_driver_t *this_gen, vo_frame_t *frame_gen,
+ vo_overlay_t *overlay)
+{
+ /* FIXME: We only blend non-mpeg frames here.
+ Is there any way to provide overlays for mpeg content? Subpictures? */
+ if (frame_gen->format != IMGFMT_MPEG) {
+ dxr3_frame_t *frame = (dxr3_frame_t *)frame_gen;
+
+ if (overlay->rle) {
+ if (frame_gen->format == IMGFMT_YV12)
+ blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->iheight);
+ else
+ blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->iheight);
+ }
+ }
+}
+
+static void dxr3_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen)
+{
+ dxr3_driver_t *this = (dxr3_driver_t *)this_gen;
+ dxr3_frame_t *frame = (dxr3_frame_t *)frame_gen;
+
+ if (frame_gen->format != IMGFMT_MPEG && this->enc && this->enc->on_display_frame) {
+ if (this->need_update) {
+ /* we cannot do this earlier, because vo_frame.duration is only valid here */
+ if (this->enc && this->enc->on_update_format)
+ this->enc->on_update_format(this, frame);
+ this->need_update = 0;
+ }
+ /* for non-mpeg, the encoder plugin is responsible for calling
+ * frame_gen->displayed(frame_gen) ! */
+ this->enc->on_display_frame(this, frame);
+ } else {
+ frame_gen->displayed(frame_gen);
+ }
+}
+
+static int dxr3_redraw_needed(vo_driver_t *this_gen)
+{
+ dxr3_driver_t *this = (dxr3_driver_t *)this_gen;
+
+ dxr3_overlay_update(this);
+
+ if (this->need_redraw) {
+ this->need_redraw = 0;
+ return 1;
+ }
+ return 0;
+}
+
+static int dxr3_get_property(vo_driver_t *this_gen, int property)
+{
+ dxr3_driver_t *this = (dxr3_driver_t *)this_gen;
+
+ switch (property) {
+ case VO_PROP_SATURATION:
+ return this->bcs.saturation;
+ case VO_PROP_CONTRAST:
+ return this->bcs.contrast;
+ case VO_PROP_BRIGHTNESS:
+ return this->bcs.brightness;
+ case VO_PROP_ASPECT_RATIO:
+ return this->aspect;
+ case VO_PROP_COLORKEY:
+ return this->overlay.colorkey;
+ case VO_PROP_ZOOM_FACTOR:
+ case VO_PROP_TVMODE:
+ return 0;
+ case VO_PROP_VO_TYPE:
+ return VO_TYPE_DXR3;
+ }
+ printf("video_out_dxr3: property %d not implemented.\n", property);
+ return 0;
+}
+
+static int dxr3_set_property(vo_driver_t *this_gen, int property, int value)
+{
+ dxr3_driver_t *this = (dxr3_driver_t *)this_gen;
+ int val, bcs_changed = 0;
+ int fullscreen;
+ double ratio;
+
+ switch (property) {
+ case VO_PROP_SATURATION:
+ this->bcs.saturation = value;
+ bcs_changed = 1;
+ break;
+ case VO_PROP_CONTRAST:
+ this->bcs.contrast = value;
+ bcs_changed = 1;
+ break;
+ case VO_PROP_BRIGHTNESS:
+ this->bcs.brightness = value;
+ bcs_changed = 1;
+ break;
+ case VO_PROP_ASPECT_RATIO:
+ /* xitk-ui increments the value, so we make
+ * just a two value "loop" */
+ if (value > ASPECT_FULL) value = ASPECT_ANAMORPHIC;
+ this->aspect = value;
+ fullscreen = this->overlay_enabled ? is_fullscreen(this) : 0;
+
+ if (value == ASPECT_ANAMORPHIC) {
+#if LOG_VID
+ printf("video_out_dxr3: setting aspect ratio to anamorphic\n");
+#endif
+ if (!this->overlay_enabled || fullscreen)
+ val = EM8300_ASPECTRATIO_16_9;
+ else /* The overlay window can adapt to the ratio */
+ val = EM8300_ASPECTRATIO_4_3;
+ ratio = 16.0/9.0;
+ } else {
+#if LOG_VID
+ printf("video_out_dxr3: setting aspect ratio to full\n");
+#endif
+ val = EM8300_ASPECTRATIO_4_3;
+ ratio = 4.0/3.0;
+ }
+
+ if (ioctl(this->fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &val))
+ printf("video_out_dxr3: failed to set aspect ratio (%s)\n", strerror(errno));
+
+ if (this->overlay_enabled && !fullscreen) {
+ int dummy;
+ this->frame_output_cb(this->user_data, this->width, this->width / ratio,
+ &dummy, &dummy, &dummy, &dummy, &dummy, &dummy);
+ }
+ break;
+ case VO_PROP_COLORKEY:
+ printf("video_out_dxr3: VO_PROP_COLORKEY not implemented!");
+ this->overlay.colorkey = value;
+ break;
+ case VO_PROP_ZOOM_FACTOR:
+ if(!this->overlay_enabled) { /* TV-out only */
+ if (value == 1) {
+#if LOG_VID
+ printf("video_out_dxr3: enabling 16:9 zoom\n");
+#endif
+ val = EM8300_ASPECTRATIO_4_3;
+ if (ioctl(this->fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &val))
+ printf("video_out_dxr3: failed to set aspect ratio (%s)\n", strerror(errno));
+ dxr3_zoomTV(this);
+ } else if (value == -1) {
+#if LOG_VID
+ printf("video_out_dxr3: disabling 16:9 zoom\n");
+#endif
+ if (ioctl(this->fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &this->aspect))
+ printf("video_out_dxr3: failed to set aspect ratio (%s)\n", strerror(errno));
+ }
+ }
+ break;
+ case VO_PROP_TVMODE:
+ if (++this->tv_mode > EM8300_VIDEOMODE_LAST) this->tv_mode = EM8300_VIDEOMODE_PAL;
+#if LOG_VID
+ printf("video_out_dxr3: Changing TVMode to ");
+#endif
+ if (this->tv_mode == EM8300_VIDEOMODE_PAL) printf("PAL\n");
+ if (this->tv_mode == EM8300_VIDEOMODE_PAL60) printf("PAL60\n");
+ if (this->tv_mode == EM8300_VIDEOMODE_NTSC) printf("NTSC\n");
+ if (ioctl(this->fd_control, EM8300_IOCTL_SET_VIDEOMODE, &this->tv_mode))
+ printf("video_out_dxr3: setting video mode failed (%s)\n", strerror(errno));
+ break;
+ }
+
+ if (bcs_changed) {
+ if (ioctl(this->fd_control, EM8300_IOCTL_SETBCS, &this->bcs))
+ printf("video_out_dxr3: bcs set failed (%s)\n", strerror(errno));
+ this->config->update_num(this->config, "dxr3.contrast", this->bcs.contrast);
+ this->config->update_num(this->config, "dxr3.saturation", this->bcs.saturation);
+ this->config->update_num(this->config, "dxr3.brightness", this->bcs.brightness);
+ }
+
+ return value;
+}
+
+static void dxr3_get_property_min_max(vo_driver_t *this_gen, int property,
+ int *min, int *max)
+{
+ switch (property) {
+ case VO_PROP_SATURATION:
+ case VO_PROP_CONTRAST:
+ case VO_PROP_BRIGHTNESS:
+ *min = 0;
+ *max = 1000;
+ break;
+ default:
+ *min = 0;
+ *max = 0;
+ }
+}
+
+static int dxr3_gui_data_exchange(vo_driver_t *this_gen, int data_type, void *data)
+{
+ dxr3_driver_t *this = (dxr3_driver_t *)this_gen;
+
+ if (!this->overlay_enabled && !this->tv_switchable) return 0;
+
+ switch (data_type) {
+ case GUI_DATA_EX_EXPOSE_EVENT:
+ XLockDisplay(this->display);
+ XFillRectangle(this->display, this->win, this->gc,
+ 0, 0, this->width, this->height);
+ XUnlockDisplay(this->display);
+ dxr3_overlay_update(this);
+ break;
+ case GUI_DATA_EX_DRAWABLE_CHANGED:
+ {
+ XWindowAttributes a;
+ this->win = (Drawable)data;
+ this->gc = XCreateGC(this->display, this->win, 0, NULL);
+ XGetWindowAttributes(this->display, this->win, &a);
+ dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO, this->aspect);
+ }
+ break;
+ case GUI_DATA_EX_TRANSLATE_GUI_TO_VIDEO:
+ {
+ int x1, y1, x2, y2;
+ x11_rectangle_t *rect = data;
+ dxr3_translate_gui2video(this, rect->x, rect->y, &x1, &y1);
+ dxr3_translate_gui2video(this, rect->w, rect->h, &x2, &y2);
+ rect->x = x1;
+ rect->y = y1;
+ rect->w = x2 - x1;
+ rect->h = y2 - y1;
+ }
+ break;
+ case GUI_DATA_EX_VIDEOWIN_VISIBLE:
+ {
+ int window_showing = (int)data;
+ int val;
+ if (!window_showing) {
+#if LOG_VID
+ printf("video_out_dxr3: Hiding video window and diverting video to TV\n");
+#endif
+ val = EM8300_OVERLAY_MODE_OFF;
+ ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETMODE, &val);
+ this->overlay_enabled = 0;
+ } else {
+#if LOG_VID
+ printf("video_out_dxr3: Using video window for overlaying video\n");
+#endif
+ val = EM8300_OVERLAY_MODE_OVERLAY;
+ ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETMODE, &val);
+ this->overlay_enabled = 1;
+ }
+ dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO, this->aspect);
+ }
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static void dxr3_exit(vo_driver_t *this_gen)
+{
+ dxr3_driver_t *this = (dxr3_driver_t *)this_gen;
+ int val = EM8300_OVERLAY_MODE_OFF;
+
+#if LOG_VID
+ printf("video_out_dxr3: vo exit called\n");
+#endif
+ if (this->enc && this->enc->on_close)
+ this->enc->on_close(this);
+ if(this->overlay_enabled)
+ ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETMODE, &val);
+
+ free(this);
+}
+
+
+static void gather_screen_vars(dxr3_driver_t *this, x11_visual_t *vis)
+{
+ int scrn;
+#ifdef HAVE_XINERAMA
+ int screens;
+ int dummy_a, dummy_b;
+ XineramaScreenInfo *screeninfo = NULL;
+#endif
+
+ this->win = vis->d;
+ this->display = vis->display;
+ this->user_data = vis->user_data;
+ this->gc = XCreateGC(this->display, this->win, 0, NULL);
+ scrn = DefaultScreen(this->display);
+
+#ifdef HAVE_XINERAMA
+ if (XineramaQueryExtension(this->display, &dummy_a, &dummy_b) &&
+ (screeninfo = XineramaQueryScreens(this->display, &screens)) &&
+ XineramaIsActive(this->display)) {
+ this->overlay.screen_xres = screeninfo[0].width;
+ this->overlay.screen_yres = screeninfo[0].height;
+ } else
+#endif
+ {
+ this->overlay.screen_xres = DisplayWidth(this->display, scrn);
+ this->overlay.screen_yres = DisplayHeight(this->display, scrn);
+ }
+
+ this->overlay.screen_depth = DisplayPlanes(this->display, scrn);
+ this->frame_output_cb = (void *)vis->frame_output_cb;
+
+#if LOG_OVR
+ printf("video_out_dxr3: xres: %d, yres: %d, depth: %d\n",
+ this->overlay.screen_xres, this->overlay.screen_yres, this->overlay.screen_depth);
+#endif
+}
+
+/* dxr3_overlay_read_state helper structure */
+#define TYPE_INT 1
+#define TYPE_XINT 2
+#define TYPE_COEFF 3
+#define TYPE_FLOAT 4
+
+struct lut_entry {
+ char *name;
+ int type;
+ void *ptr;
+};
+
+/* dxr3_overlay_read_state helper function */
+static int lookup_parameter(struct lut_entry *lut, char *name,
+ void **ptr, int *type)
+{
+ int i;
+
+ for (i = 0; lut[i].name; i++)
+ if (strcmp(name, lut[i].name) == 0) {
+ *ptr = lut[i].ptr;
+ *type = lut[i].type;
+#if LOG_OVR
+ printf("video_out_dxr3: found parameter \"%s\"\n", name);
+#endif
+ return 1;
+ }
+#if LOG_OVR
+ printf("video_out_dxr3: WARNING: unknown parameter \"%s\"\n", name);
+#endif
+ return 0;
+}
+
+static int dxr3_overlay_read_state(dxr3_overlay_t *this)
+{
+ char *loc;
+ char fname[256], tmp[128], line[256];
+ FILE *fp;
+ struct lut_entry lut[] = {
+ {"xoffset", TYPE_INT, &this->xoffset},
+ {"yoffset", TYPE_INT, &this->yoffset},
+ {"xcorr", TYPE_INT, &this->xcorr},
+ {"jitter", TYPE_INT, &this->jitter},
+ {"stability", TYPE_INT, &this->stability},
+ {"keycolor", TYPE_XINT, &this->colorkey},
+ {"colcal_upper", TYPE_COEFF, &this->colcal_upper[0]},
+ {"colcal_lower", TYPE_COEFF, &this->colcal_lower[0]},
+ {"color_interval", TYPE_FLOAT, &this->color_interval},
+ {0,0,0}
+ };
+ char *tok;
+ void *ptr;
+ int type;
+ int j;
+
+ /* store previous locale */
+ loc = setlocale(LC_NUMERIC, NULL);
+ /* set american locale for floating point values
+ * (used by .overlay/res file) */
+ setlocale(LC_NUMERIC, "en_US");
+
+ snprintf(tmp, sizeof(tmp), "/res_%dx%dx%d",
+ this->screen_xres, this->screen_yres, this->screen_depth);
+ strncpy(fname, getenv("HOME"), sizeof(fname) - strlen(tmp) - sizeof("/.overlay"));
+ fname[sizeof(fname) - strlen(tmp) - sizeof("/.overlay")] = '\0';
+ strcat(fname, "/.overlay");
+ strcat(fname, tmp);
+#if LOG_OVR
+ printf("video_out_dxr3: attempting to open %s\n", fname);
+#endif
+ if (!(fp = fopen(fname, "r"))) {
+ printf("video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n");
+ return -1;
+ }
+
+ while (!feof(fp)) {
+ if (!fgets(line, 256, fp))
+ break;
+ tok = strtok(line, " ");
+ if (lookup_parameter(lut, tok, &ptr, &type)) {
+ tok = strtok(NULL, " \n");
+ switch(type) {
+ case TYPE_INT:
+ sscanf(tok, "%d", (int *)ptr);
+#if LOG_OVR
+ printf("video_out_dxr3: value \"%s\" = %d\n", tok, *(int *)ptr);
+#endif
+ break;
+ case TYPE_XINT:
+ sscanf(tok, "%x", (int *)ptr);
+#if LOG_OVR
+ printf("video_out_dxr3: value \"%s\" = %d\n", tok, *(int *)ptr);
+#endif
+ break;
+ case TYPE_FLOAT:
+ sscanf(tok, "%f", (float *)ptr);
+#if LOG_OVR
+ printf("video_out_dxr3: value \"%s\" = %f\n", tok, *(float *)ptr);
+#endif
+ break;
+ case TYPE_COEFF:
+ for(j = 0; j < 3; j++) {
+ sscanf(tok, "%f", &((struct coeff *)ptr)[j].k);
+#if LOG_OVR
+ printf("video_out_dxr3: value (%d,k) \"%s\" = %f\n", j, tok, ((struct coeff *)ptr)[j].k);
+#endif
+ tok = strtok(NULL, " \n");
+ sscanf(tok, "%f", &((struct coeff *)ptr)[j].m);
+#if LOG_OVR
+ printf("video_out_dxr3: value (%d,m) \"%s\" = %f\n", j, tok, ((struct coeff *)ptr)[j].m);
+#endif
+ tok = strtok(NULL, " \n");
+ }
+ break;
+ }
+ }
+ }
+
+ fclose(fp);
+ /* restore original locale */
+ setlocale(LC_NUMERIC, loc);
+
+ return 0;
+}
+
+/* dxr3_overlay_set_keycolor helper function */
+static int col_interp(float x, struct coeff c)
+{
+ int y;
+ y = rint(x * c.k + c.m);
+ if (y > 255) y = 255;
+ if (y < 0) y = 0;
+ return y;
+}
+
+static int dxr3_overlay_set_keycolor(dxr3_overlay_t *this)
+{
+ em8300_attribute_t attr;
+ float r = (this->colorkey & 0xff0000) >> 16;
+ float g = (this->colorkey & 0x00ff00) >> 8;
+ float b = (this->colorkey & 0x0000ff);
+ float interval = this->color_interval;
+ int32_t overlay_limit;
+ int ret;
+
+#if LOG_OVR
+ printf("video_out_dxr3: set_keycolor: r = %f, g = %f, b = %f, interval = %f\n",
+ r, g, b, interval);
+#endif
+
+ overlay_limit = /* lower limit */
+ col_interp(r - interval, this->colcal_lower[0]) << 16 |
+ col_interp(g - interval, this->colcal_lower[1]) << 8 |
+ col_interp(b - interval, this->colcal_lower[2]);
+#if LOG_OVR
+ printf("video_out_dxr3: lower overlay_limit = %d\n", overlay_limit);
+#endif
+ attr.attribute = EM9010_ATTRIBUTE_KEYCOLOR_LOWER;
+ attr.value = overlay_limit;
+ if ((ret = ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr)) < 0) {
+ printf("video_out_dxr3: WARNING: error setting overlay lower limit attribute\n");
+ return ret;
+ }
+
+ overlay_limit = /* upper limit */
+ col_interp(r + interval, this->colcal_upper[0]) << 16 |
+ col_interp(g + interval, this->colcal_upper[1]) << 8 |
+ col_interp(b + interval, this->colcal_upper[2]);
+#if LOG_OVR
+ printf("video_out_dxr3: upper overlay_limit = %d\n", overlay_limit);
+#endif
+ attr.attribute = EM9010_ATTRIBUTE_KEYCOLOR_UPPER;
+ attr.value = overlay_limit;
+ if ((ret = ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr)) < 0)
+ printf("video_out_dxr3: WARNING: error setting overlay upper limit attribute\n");
+ return ret;
+}
+
+static int dxr3_overlay_set_attributes(dxr3_overlay_t *this)
+{
+ em8300_attribute_t attr;
+
+ attr.attribute = EM9010_ATTRIBUTE_XOFFSET;
+ attr.value = this->xoffset;
+ if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1)
+ return -1;
+ attr.attribute = EM9010_ATTRIBUTE_YOFFSET;
+ attr.value = this->yoffset;
+ if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1)
+ return -1;
+ attr.attribute = EM9010_ATTRIBUTE_XCORR;
+ attr.value = this->xcorr;
+ if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1)
+ return -1;
+ attr.attribute = EM9010_ATTRIBUTE_STABILITY;
+ attr.value = this->stability;
+ if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1)
+ return -1;
+ attr.attribute = EM9010_ATTRIBUTE_JITTER;
+ attr.value = this->jitter;
+ return ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr);
+}
+
+
+static int dxr3_overlay_set_window(dxr3_overlay_t *this,
+ int xpos, int ypos, int width, int height)
+{
+ em8300_overlay_window_t win;
+
+ /* is some part of the picture visible? */
+ if (xpos+width < 0) return 0;
+ if (ypos+height < 0) return 0;
+ if (xpos > this->screen_xres) return 0;
+ if (ypos > this->screen_yres) return 0;
+
+ win.xpos = xpos;
+ win.ypos = ypos;
+ win.width = width;
+ win.height = height;
+
+ return ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETWINDOW, &win);
+}
+
+static void dxr3_overlay_update(dxr3_driver_t *this)
+{
+ if (this->overlay_enabled) {
+ int gui_win_x, gui_win_y, gypos, gxpos, gw, gh;
+
+ this->frame_output_cb(this->user_data,
+ this->video_width, this->video_oheight,
+ &gxpos, &gypos, &gw, &gh, &gui_win_x, &gui_win_y);
+
+ if (this->xpos != gxpos || this->ypos != gypos ||
+ this->width != gw || this->height != gh) {
+ XWindowAttributes a;
+ Window junkwin;
+ int rx, ry;
+
+ /* detect true window position and adapt overlay to it */
+ XLockDisplay(this->display);
+ XSetForeground(this->display, this->gc, this->color.pixel);
+ XGetWindowAttributes(this->display, this->win, &a);
+ XTranslateCoordinates (this->display, this->win, a.root,
+ gxpos + 1, gypos + 1, &rx, &ry, &junkwin);
+ XUnlockDisplay(this->display);
+
+ this->xpos = rx;
+ this->ypos = ry;
+ this->width = gw;
+ this->height = gh;
+
+ dxr3_overlay_set_window(&this->overlay, this->xpos, this->ypos,
+ this->width, this->height);
+ }
+ }
+}
+
+static void dxr3_zoomTV(dxr3_driver_t *this)
+{
+ em8300_register_t frame, visible, update;
+
+ /* change left bound */
+ frame.microcode_register = 1;
+ frame.reg = 93; // dicom frame left
+ frame.val = 0x10;
+
+ visible.microcode_register = 1;
+ visible.reg = 97; // dicom visible left
+ visible.val = 0x10;
+
+ update.microcode_register = 1;
+ update.reg = 65; // dicom_update
+ update.val = 1;
+
+ ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &frame);
+ ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &visible);
+ ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &update);
+
+ /* change right bound */
+ frame.microcode_register = 1;
+ frame.reg = 94; // dicom frame right
+ frame.val = 0x10;
+
+ visible.microcode_register = 1;
+ visible.reg = 98; // dicom visible right
+ visible.val = 968;
+
+ update.microcode_register = 1;
+ update.reg = 65; // dicom_update
+ update.val = 1;
+
+ ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &frame);
+ ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &visible);
+ ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &update);
+}
+
+static void dxr3_translate_gui2video(dxr3_driver_t *this, int x, int y,
+ int *vid_x, int *vid_y)
+{
+ *vid_x = x * this->video_width / this->width;
+ *vid_y = y * this->video_oheight / this->height - this->top_bar;
+}
+
+static int is_fullscreen(dxr3_driver_t *this)
+{
+ XWindowAttributes a;
+
+ XGetWindowAttributes(this->display, this->win, &a);
+
+ return
+ a.x == 0 &&
+ a.y == 0 &&
+ a.width == this->overlay.screen_xres &&
+ a.height == this->overlay.screen_yres;
+}
+
+
+static void dxr3_update_add_bars(void *data, cfg_entry_t *entry)
+{
+ dxr3_driver_t *this = (dxr3_driver_t *)data;
+ this->add_bars = entry->num_value;
+ printf("video_out_dxr3: setting add_bars to correct aspect ratio to %s\n",
+ (this->add_bars ? "on" : "off"));
+}
+
+static void dxr3_update_swap_fields(void *data, cfg_entry_t *entry)
+{
+ dxr3_driver_t *this = (dxr3_driver_t *)data;
+ this->swap_fields = entry->num_value;
+ printf("video_out_dxr3: setting swap fields to %s\n",
+ (this->swap_fields ? "on" : "off"));
+}
+
+static void dxr3_update_enhanced_mode(void *data, cfg_entry_t *entry)
+{
+ dxr3_driver_t *this = (dxr3_driver_t *)data;
+ this->enhanced_mode = entry->num_value;
+ printf("video_out_dxr3: setting enhanced encoding playback to %s\n",
+ (this->enhanced_mode ? "on" : "off"));
+}
diff --git a/src/dxr3/video_out_dxr3.h b/src/dxr3/video_out_dxr3.h
new file mode 100644
index 000000000..3f8be66f5
--- /dev/null
+++ b/src/dxr3/video_out_dxr3.h
@@ -0,0 +1,132 @@
+/*
+ * 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: video_out_dxr3.h,v 1.1 2002/05/24 22:09:44 miguelfreitas Exp $
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <X11/Xlib.h>
+
+#include "xine_internal.h"
+#include "dxr3.h"
+
+/* values for fd_video indicating why it is closed */
+#define CLOSED_FOR_DECODER -1
+#define CLOSED_FOR_ENCODER -2
+
+
+/* plugin structures */
+typedef struct encoder_data_s encoder_data_t;
+
+typedef enum { ENC_FAME, ENC_RTE } encoder_type;
+
+
+struct coeff {
+ float k,m;
+};
+
+typedef struct dxr3_overlay_s {
+ int fd_control;
+
+ int xoffset;
+ int yoffset;
+ int xcorr;
+ int jitter;
+ int stability;
+ int colorkey;
+ float color_interval;
+ int screen_xres;
+ int screen_yres;
+ int screen_depth;
+
+ struct coeff colcal_upper[3];
+ struct coeff colcal_lower[3];
+} dxr3_overlay_t;
+
+typedef struct dxr3_driver_s {
+ vo_driver_t vo_driver;
+ config_values_t *config;
+
+ char devname[128];
+ char devnum[3];
+ int fd_control;
+ int fd_video; /* to access the relevant dxr3 devices */
+
+ int enhanced_mode;
+ int swap_fields; /* swap fields */
+ int add_bars; /* add black bars to correct a.r. */
+
+ int aspect;
+ int tv_mode;
+ int overlay_enabled;
+ int tv_switchable; /* can switch from overlay<->tvout */
+ em8300_bcs_t bcs;
+
+ encoder_data_t *enc; /* encoder data */
+ int format; /* color format */
+ int video_iheight; /* input height (before adding black bars) */
+ int video_oheight; /* output height (after adding bars) */
+ int video_width;
+ int video_aspect;
+ int top_bar; /* the height of the upper black bar */
+ int need_redraw; /* the image on screen needs redrawing */
+ int need_update; /* the mpeg encoder needs to be updated */
+
+ dxr3_overlay_t overlay;
+ Display *display;
+ Drawable win;
+ GC gc;
+ XColor color;
+ int xpos, ypos;
+ int width, height;
+
+ char *user_data;
+ void (*frame_output_cb)(void *user_data,
+ int video_width, int video_height,
+ int *dest_x, int *dest_y,
+ int *dest_height, int *dest_width,
+ int *win_x, int *win_y);
+} dxr3_driver_t;
+
+typedef struct dxr3_frame_s {
+ vo_frame_t vo_frame;
+ int width, iheight, oheight;
+ uint8_t *mem; /* allocated for YV12 or YUY2 buffers */
+ uint8_t *real_base[3]; /* yuv/yuy2 buffers in mem aligned on 16 */
+ int swap_fields; /* shifts Y buffer one line to exchange odd/even lines */
+} dxr3_frame_t;
+
+struct encoder_data_s {
+ encoder_type type;
+ int (*on_update_format)(dxr3_driver_t *, dxr3_frame_t *);
+ int (*on_frame_copy)(dxr3_driver_t *, dxr3_frame_t *, uint8_t **src);
+ int (*on_display_frame)(dxr3_driver_t *, dxr3_frame_t *);
+ int (*on_close)(dxr3_driver_t *);
+};
+
+/* encoder plugins initialization functions */
+#ifdef HAVE_LIBRTE
+int dxr3_rte_init(dxr3_driver_t *);
+#endif
+#ifdef HAVE_LIBFAME
+int dxr3_fame_init(dxr3_driver_t *);
+#endif
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
index 4a137b2df..8ad6d46ec 100644
--- a/src/xine-engine/audio_decoder.c
+++ b/src/xine-engine/audio_decoder.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_decoder.c,v 1.72 2002/04/29 23:32:00 jcdutton Exp $
+ * $Id: audio_decoder.c,v 1.73 2002/05/24 22:09:44 miguelfreitas Exp $
*
*
* functions that implement audio decoding
@@ -266,7 +266,14 @@ void audio_decoder_init (xine_t *this) {
return;
}
- this->audio_fifo = fifo_buffer_new (50, 8192);
+ /* The fifo size is based on dvd playback where buffers are filled
+ * with 2k of data. With 230 buffers and a typical audio data rate
+ * of 1.8 Mbit/s (four ac3 streams), the fifo can hold about 2 seconds
+ * of audio, wich should be enough to compensate for drive delays.
+ * We provide buffers of 8k size instead of 2k for demuxers sending
+ * larger chunks.
+ */
+ this->audio_fifo = fifo_buffer_new (230, 8192);
this->audio_channel_user = -1;
this->audio_channel_auto = 0;
this->audio_type = 0;
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index 31cff4704..3915e37bd 100644
--- a/src/xine-engine/video_decoder.c
+++ b/src/xine-engine/video_decoder.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_decoder.c,v 1.84 2002/04/29 23:32:00 jcdutton Exp $
+ * $Id: video_decoder.c,v 1.85 2002/05/24 22:09:45 miguelfreitas Exp $
*
*/
@@ -282,6 +282,13 @@ void video_decoder_init (xine_t *this) {
struct sched_param pth_params;
int err;
+ /* The fifo size is based on dvd playback where buffers are filled
+ * with 2k of data. With 500 buffers and a typical video data rate
+ * of 4 Mbit/s, the fifo can hold about 2 seconds of video, wich
+ * should be enough to compensate for drive delays.
+ * We provide buffers of 8k size instead of 2k for demuxers sending
+ * larger chunks.
+ */
this->video_fifo = fifo_buffer_new (500, 8192);
pthread_attr_init(&pth_attrs);