summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduard Hasenleithner <ehasenle@users.sourceforge.net>2001-07-20 17:28:21 +0000
committerEduard Hasenleithner <ehasenle@users.sourceforge.net>2001-07-20 17:28:21 +0000
commit1a2ca06df30910c52e813df5b99f5c51e6ae567f (patch)
tree5caed141fc466582f611a1bfcc0b283657ab4d11
parentb7ce869892e2191a9045ebaac2b34409a9fcf365 (diff)
downloadxine-lib-1a2ca06df30910c52e813df5b99f5c51e6ae567f.tar.gz
xine-lib-1a2ca06df30910c52e813df5b99f5c51e6ae567f.tar.bz2
Initial commit of the dxr3/hw+ hardware decoder plugin.
CVS patchset: 312 CVS date: 2001/07/20 17:28:21
-rw-r--r--src/dxr3/Makefile.am33
-rw-r--r--src/dxr3/dxr3_decoder.c292
-rw-r--r--src/dxr3/video_out_dxr3.c299
3 files changed, 624 insertions, 0 deletions
diff --git a/src/dxr3/Makefile.am b/src/dxr3/Makefile.am
new file mode 100644
index 000000000..4052eba9a
--- /dev/null
+++ b/src/dxr3/Makefile.am
@@ -0,0 +1,33 @@
+CFLAGS = @GLOBAL_CFLAGS@
+
+EXTRA_DIST = dxr3_decoder.c video_out_dxr3.c
+
+LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic
+
+libdir = $(XINE_PLUGINDIR)
+
+if HAVE_DXR3
+dxr3_modules = xineplug_decode_dxr3.la xineplug_vo_out_dxr3.la
+endif
+
+lib_LTLIBRARIES = $(dxr3_modules)
+
+xineplug_decode_dxr3_la_SOURCES = dxr3_decoder.c
+xineplug_decode_dxr3_la_LDFLAGS = -avoid-version -module
+
+xineplug_vo_out_dxr3_la_SOURCES = video_out_dxr3.c
+xineplug_vo_out_dxr3_la_LDFLAGS = -avoid-version -module
+
+debug:
+ @$(MAKE) CFLAGS="$(DEBUG_CFLAGS)"
+
+install-debug: debug
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
diff --git a/src/dxr3/dxr3_decoder.c b/src/dxr3/dxr3_decoder.c
new file mode 100644
index 000000000..833fa8b4f
--- /dev/null
+++ b/src/dxr3/dxr3_decoder.c
@@ -0,0 +1,292 @@
+/*
+ * 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_decoder.c,v 1.1 2001/07/20 17:28:21 ehasenle Exp $
+ *
+ * dxr3 video and spu decoder plugin. Accepts the video and spu data
+ * from XINE and sends it directly to the corresponding dxr3 devices.
+ * Takes precedence over the libmpeg2 and libspudec due to a higher
+ * priority.
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <buffer.h>
+#include <xine_internal.h>
+#include <linux/soundcard.h>
+#include <linux/em8300.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <inttypes.h>
+
+char devname[]="/dev/em8300";
+
+typedef struct dxr3_decoder_s {
+ video_decoder_t video_decoder;
+ vo_instance_t *video_out;
+
+ int fd_video;
+#if 0
+ int fd_control;
+#endif
+ int last_pts;
+} dxr3_decoder_t;
+
+static int dxr3_tested = 0;
+static int dxr3_ok;
+
+static void dxr3_presence_test()
+{
+ int fd, val;
+ dxr3_tested = 1;
+ dxr3_ok = 0;
+
+ if ((fd = open(devname, O_WRONLY))<0) {
+ fprintf(stderr, "dxr3: not detected. (%s: %s)\n",
+ devname, strerror(errno));
+ return;
+ }
+ if (ioctl(fd, EM8300_IOCTL_GET_AUDIOMODE, &val)<0) {
+ fprintf(stderr, "dxr3: ioctl failed. (%s)\n", strerror(errno));
+ return;
+ }
+ close(fd);
+ dxr3_ok = 1;
+}
+
+static int dxr3_can_handle (video_decoder_t *this_gen, int buf_type)
+{
+ if (!dxr3_tested)
+ dxr3_presence_test();
+ return (dxr3_ok && (buf_type & 0xFFFF0000) == BUF_VIDEO_MPEG) ;
+}
+
+static void dxr3_init (video_decoder_t *this_gen, vo_instance_t *video_out)
+{
+ dxr3_decoder_t *this = (dxr3_decoder_t *) this_gen;
+ char tmpstr[100];
+
+ printf("dxr3: Entering video init, devname=%s.\n",devname);
+
+#if 0
+ /* open control device */
+ if ((this->fd_control = open(devname, O_WRONLY)) < 0) {
+ fprintf(stderr, "dxr3: Failed to open control device %s (%s)\n",
+ devname, strerror(errno));
+ this->fd_video = -1;
+ return;
+ }
+#endif
+
+ /* open video device */
+ snprintf (tmpstr, sizeof(tmpstr), "%s_mv", devname);
+ if ((this->fd_video = open (tmpstr, O_WRONLY)) < 0) {
+ fprintf(stderr, "dxr3: Failed to open video device %s (%s)\n",
+ tmpstr, strerror(errno));
+ return;
+ }
+
+ video_out->open(video_out);
+ this->video_out = video_out;
+
+ this->last_pts = 0;
+}
+
+static void dxr3_decode_data (video_decoder_t *this_gen, buf_element_t *buf)
+{
+ dxr3_decoder_t *this = (dxr3_decoder_t *) this_gen;
+ ssize_t written;
+
+ /* The dxr3 does not need the preview-data */
+ if (buf->decoder_info[0] == 0) return;
+
+ if (buf->PTS) {
+ int vpts,pts;
+ pts = this->video_decoder.metronom->get_current_time
+ (this->video_decoder.metronom);
+ vpts = this->video_decoder.metronom->got_video_frame
+ (this->video_decoder.metronom, buf->PTS);
+
+// fprintf(stderr, "pts %d %d %d\n",vpts,pts,buf->PTS);
+
+ if (vpts > pts && this->last_pts < vpts)
+ {
+ this->last_pts = vpts;
+ if (ioctl(this->fd_video,EM8300_IOCTL_VIDEO_SETSCR,&pts))
+ fprintf(stderr, "dxr3: set master pts failed.\n");
+
+ if (ioctl(this->fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vpts))
+ fprintf(stderr, "dxr3: set video pts failed.\n");
+ }
+ }
+
+ written = write(this->fd_video, buf->content, buf->size);
+ if (written < 0) {
+ fprintf(stderr, "dxr3: video device write failed (%s)\n",
+ strerror(errno));
+ return;
+ }
+ if (written != buf->size)
+ fprintf(stderr, "dxr3: Could only write %d of %d video bytes.\n",
+ written, buf->size);
+}
+
+static void dxr3_close (video_decoder_t *this_gen)
+{
+ dxr3_decoder_t *this = (dxr3_decoder_t *) this_gen;
+
+#if 0
+ ioctl(this->fd_control, EM8300_IOCTL_SET_PLAYMODE, EM8300_PLAYMODE_STOPPED);
+ close(this->fd_control);
+#endif
+ close(this->fd_video);
+
+ this->video_out->close(this->video_out);
+}
+
+static char *dxr3_get_id(void) {
+ return "dxr3-mpeg2";
+}
+
+video_decoder_t *init_video_decoder_plugin (int iface_version,
+ config_values_t *cfg)
+{
+ dxr3_decoder_t *this ;
+
+ if (iface_version != 1)
+ return NULL;
+
+ this = (dxr3_decoder_t *) malloc (sizeof (dxr3_decoder_t));
+
+ this->video_decoder.interface_version = 2;
+ this->video_decoder.can_handle = dxr3_can_handle;
+ this->video_decoder.init = dxr3_init;
+ this->video_decoder.decode_data = dxr3_decode_data;
+ this->video_decoder.close = dxr3_close;
+ this->video_decoder.get_identifier = dxr3_get_id;
+ this->video_decoder.priority = 10;
+
+ return (video_decoder_t *) this;
+}
+
+/*
+ * Second part of the dxr3 plugin: subpicture decoder
+ */
+
+typedef struct spudec_decoder_s {
+ spu_decoder_t spu_decoder;
+
+ vo_instance_t *vo_out;
+ int fd_spu;
+} spudec_decoder_t;
+
+static int spudec_can_handle (spu_decoder_t *this_gen, int buf_type)
+{
+ if (!dxr3_tested)
+ dxr3_presence_test();
+ return (dxr3_ok && (buf_type & 0xFFFF0000) == BUF_SPU_PACKAGE);
+}
+
+static void spudec_init (spu_decoder_t *this_gen, vo_instance_t *vo_out)
+{
+ spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
+ char tmpstr[100];
+
+ this->vo_out = vo_out;
+
+ /* open spu device */
+ snprintf (tmpstr, sizeof(tmpstr), "%s_sp", devname);
+ if ((this->fd_spu = open (tmpstr, O_WRONLY)) < 0) {
+ fprintf(stderr, "dxr3: Failed to open spu device %s (%s)\n",
+ tmpstr, strerror(errno));
+ return;
+ }
+
+}
+
+static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf)
+{
+ spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
+ ssize_t written;
+
+ /* Is this also needed for subpicture? */
+ if (buf->decoder_info[0] == 0) return;
+
+ if (buf->PTS) {
+ int vpts;
+ vpts = this->spu_decoder.metronom->got_spu_packet
+ (this->spu_decoder.metronom, buf->PTS, 0);
+
+// fprintf(stderr, "spu pts %d %d\n",vpts,buf->PTS);
+ if (ioctl(this->fd_spu, EM8300_IOCTL_SPU_SETPTS, &vpts))
+ fprintf(stderr, "spu write failed\n");
+ }
+
+ written = write(this->fd_spu, buf->content, buf->size);
+ if (written < 0) {
+ fprintf(stderr, "dxr3: spu device write failed (%s)\n",
+ strerror(errno));
+ return;
+ }
+ if (written != buf->size)
+ fprintf(stderr, "dxr3: Could only write %d of %d spu bytes.\n",
+ written, buf->size);
+}
+
+static void spudec_close (spu_decoder_t *this_gen)
+{
+ spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
+
+ close(this->fd_spu);
+}
+
+static char *spudec_get_id(void)
+{
+ return "dxr3-spudec";
+}
+
+spu_decoder_t *init_spu_decoder_plugin (int iface_version,
+ config_values_t *cfg)
+{
+ spudec_decoder_t *this;
+
+ if (iface_version != 1)
+ return NULL;
+
+ this = (spudec_decoder_t *) malloc (sizeof (spudec_decoder_t));
+
+ this->spu_decoder.interface_version = 2;
+ this->spu_decoder.can_handle = spudec_can_handle;
+ this->spu_decoder.init = spudec_init;
+ this->spu_decoder.decode_data = spudec_decode_data;
+ this->spu_decoder.close = spudec_close;
+ this->spu_decoder.get_identifier = spudec_get_id;
+ this->spu_decoder.priority = 10;
+
+ return (spu_decoder_t *) this;
+}
+
diff --git a/src/dxr3/video_out_dxr3.c b/src/dxr3/video_out_dxr3.c
new file mode 100644
index 000000000..62999372e
--- /dev/null
+++ b/src/dxr3/video_out_dxr3.c
@@ -0,0 +1,299 @@
+/*
+ * 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.1 2001/07/20 17:28:21 ehasenle Exp $
+ *
+ * Dummy video out plugin for the dxr3. Is responsible for setting
+ * tv_mode, bcs values and the aspectratio.
+ */
+
+#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 <linux/em8300.h>
+#include "video_out.h"
+
+#include <pthread.h>
+
+#include "xine_internal.h"
+#include "utils.h"
+
+char devname[]="/dev/em8300";
+
+typedef struct dxr3_driver_s {
+ vo_driver_t vo_driver;
+ int fd_control;
+ int aspectratio;
+ int tv_mode;
+ em8300_bcs_t bcs;
+} dxr3_driver_t;
+
+static uint32_t dxr3_get_capabilities (vo_driver_t *this_gen)
+{
+ /* Since we have no vo format, we return dummy values here */
+ return VO_CAP_YV12 | IMGFMT_YUY2 | IMGFMT_RGB |
+ VO_CAP_SATURATION | VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST;
+}
+
+/* This are dummy functions to fill in the frame object */
+static void dummy_frame_copy (vo_frame_t *vo_img, uint8_t **src)
+{
+ printf("prevent this: xshm_frame_copy called\n");
+}
+
+static void dummy_frame_field (vo_frame_t *vo_img, int which_field)
+{
+ printf("prevent this: xshm_frame_field called\n");
+}
+
+static void dummy_frame_dispose (vo_frame_t *frame)
+{
+ free(frame);
+}
+
+static vo_frame_t *dxr3_alloc_frame (vo_driver_t *this_gen)
+{
+ vo_frame_t *frame;
+
+ frame = (vo_frame_t *) malloc (sizeof (vo_frame_t));
+ memset (frame, 0, sizeof(vo_frame_t));
+
+ frame->copy = dummy_frame_copy;
+ frame->field = dummy_frame_field;
+ frame->dispose = dummy_frame_dispose;
+
+ return frame;
+}
+
+static void dxr3_update_frame_format (vo_driver_t *this_gen,
+ vo_frame_t *frame,
+ uint32_t width, uint32_t height,
+ int ratio_code, int format)
+{
+ /* dxr3_driver_t *this = (dxr3_driver_t *) this_gen; */
+ printf("dummy function: dxr3_update_frame_format\n");
+}
+
+static void dxr3_display_frame (vo_driver_t *this_gen, vo_frame_t *frame)
+{
+ /* dxr3_driver_t *this = (dxr3_driver_t *) this_gen; */
+ printf("dummy function: dxr3_frame called\n");
+}
+
+static void dxr3_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen,
+ vo_overlay_t *overlay)
+{
+ /* dxr3_driver_t *this = (dxr3_driver_t *) this_gen; */
+ printf("dummy function: dxr3_overlay_blend\n");
+}
+
+static int dxr3_get_property (vo_driver_t *this_gen, int property)
+{
+ dxr3_driver_t *this = (dxr3_driver_t *) this_gen;
+ int val;
+
+ 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;
+ default:
+ val = 0;
+ fprintf(stderr, "dxr3: property %d not implemented!\n", property);
+ }
+
+ return val;
+}
+
+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;
+
+ 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 just increments the value, so we make
+ * just a two value "loop"
+ */
+ if (value > ASPECT_FULL)
+ value = ASPECT_ANAMORPHIC;
+ this->aspectratio = value;
+
+ if (value == ASPECT_ANAMORPHIC) {
+ fprintf(stderr, "dxr3: setting aspect ratio to anamorphic\n");
+ val = EM8300_ASPECTRATIO_16_9;
+ } else {
+ fprintf(stderr, "dxr3: setting aspect ratio to full\n");
+ val = EM8300_ASPECTRATIO_4_3;
+ }
+
+ if (ioctl(this->fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &val))
+ fprintf(stderr, "dxr3: failed to set aspect ratio (%s)\n",
+ strerror(errno));
+
+ break;
+ }
+
+ if (bcs_changed)
+ if (ioctl(this->fd_control, EM8300_IOCTL_SETBCS, &this->bcs))
+ fprintf(stderr, "dxr3: bcs set failed (%s)\n",
+ strerror(errno));
+ return value;
+}
+
+static 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 int dxr3_gui_data_exchange (vo_driver_t *this_gen,
+ int data_type, void *data)
+{
+ /* dxr3_driver_t *this = (dxr3_driver_t *) this_gen; */
+ return 0;
+}
+
+static void dxr3_exit (vo_driver_t *this_gen)
+{
+ dxr3_driver_t *this = (dxr3_driver_t *) this_gen;
+ close(this->fd_control);
+}
+
+
+vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen)
+{
+ dxr3_driver_t *this;
+ char* str;
+
+ /*
+ * allocate plugin struct
+ */
+
+ 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.exit = dxr3_exit;
+
+ /* open control device */
+ if ((this->fd_control = open(devname, O_WRONLY)) < 0) {
+ fprintf(stderr, "dxr3: Failed to open control device %s (%s)\n",
+ devname, strerror(errno));
+ return 0;
+ }
+
+ if (ioctl(this->fd_control, EM8300_IOCTL_GETBCS, &this->bcs))
+ fprintf(stderr, "dxr3: cannot read bcs values (%s)\n",
+ strerror(errno));
+ this->vo_driver.set_property(&this->vo_driver,
+ VO_PROP_ASPECT_RATIO, ASPECT_FULL);
+
+ str = config->lookup_str(config, "dxr3_tvmode", "default");
+ if (!strcmp(str, "ntsc")) {
+ this->tv_mode = EM8300_VIDEOMODE_NTSC;
+ fprintf(stderr, "dxr3: setting tv_mode to NTSC\n");
+ } else if (!strcmp(str, "pal")) {
+ this->tv_mode = EM8300_VIDEOMODE_PAL;
+ fprintf(stderr, "dxr3: setting tv_mode to PAL 50Hz\n");
+ } else if (!strcmp(str, "pal60")) {
+ this->tv_mode = EM8300_VIDEOMODE_PAL60;
+ fprintf(stderr, "dxr3: 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))
+ fprintf(stderr, "dxr3: setting video mode failed.");
+
+ return &this->vo_driver;
+}
+
+/* TODO: VISUAL_TYPE_HARDWARE ? */
+static vo_info_t vo_info_dxr3 = {
+ 2, /* api version */
+ "dxr3",
+ "xine dummy video output plugin for dxr3 cards",
+ VISUAL_TYPE_X11,
+ 20 /* priority */
+};
+
+vo_info_t *get_video_out_plugin_info()
+{
+ return &vo_info_dxr3;
+}
+