From 1a2ca06df30910c52e813df5b99f5c51e6ae567f Mon Sep 17 00:00:00 2001 From: Eduard Hasenleithner Date: Fri, 20 Jul 2001 17:28:21 +0000 Subject: Initial commit of the dxr3/hw+ hardware decoder plugin. CVS patchset: 312 CVS date: 2001/07/20 17:28:21 --- src/dxr3/Makefile.am | 33 +++++ src/dxr3/dxr3_decoder.c | 292 ++++++++++++++++++++++++++++++++++++++++++++ src/dxr3/video_out_dxr3.c | 299 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 624 insertions(+) create mode 100644 src/dxr3/Makefile.am create mode 100644 src/dxr3/dxr3_decoder.c create mode 100644 src/dxr3/video_out_dxr3.c 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 +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "video_out.h" + +#include + +#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; +} + -- cgit v1.2.3