From e319b82842668c1d9b96a891394c6dc58bea76d2 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Thu, 17 Mar 2011 17:38:58 -0700 Subject: [PATCH] linsys: Add plugin for Linear Systems SDI boards --- configure.ac | 9 + sys/Makefile.am | 11 +- sys/linsys/Makefile.am | 21 ++ sys/linsys/gstlinsys.c | 48 +++ sys/linsys/gstlinsyssdisink.c | 491 ++++++++++++++++++++++++++++++ sys/linsys/gstlinsyssdisink.h | 59 ++++ sys/linsys/gstlinsyssdisrc.c | 554 ++++++++++++++++++++++++++++++++++ sys/linsys/gstlinsyssdisrc.h | 62 ++++ sys/linsys/include/asi.h | 255 ++++++++++++++++ sys/linsys/include/master.h | 69 +++++ sys/linsys/include/sdi.h | 115 +++++++ sys/linsys/include/sdiaudio.h | 149 +++++++++ sys/linsys/include/sdivideo.h | 155 ++++++++++ 13 files changed, 1996 insertions(+), 2 deletions(-) create mode 100644 sys/linsys/Makefile.am create mode 100644 sys/linsys/gstlinsys.c create mode 100644 sys/linsys/gstlinsyssdisink.c create mode 100644 sys/linsys/gstlinsyssdisink.h create mode 100644 sys/linsys/gstlinsyssdisrc.c create mode 100644 sys/linsys/gstlinsyssdisrc.h create mode 100644 sys/linsys/include/asi.h create mode 100644 sys/linsys/include/master.h create mode 100644 sys/linsys/include/sdi.h create mode 100644 sys/linsys/include/sdiaudio.h create mode 100644 sys/linsys/include/sdivideo.h diff --git a/configure.ac b/configure.ac index 0dac795abc..76c66d4add 100644 --- a/configure.ac +++ b/configure.ac @@ -967,6 +967,14 @@ AG_GST_CHECK_FEATURE(LIBMMS, [mms protocol library], libmms, [ ]) AC_SUBST(LIBMMS_LIBS) +dnl *** linsys *** +translit(dnm, m, l) AM_CONDITIONAL(USE_LINSYS, true) +AG_GST_CHECK_FEATURE(LINSYS, [Linear Systems SDI plugin], linsys, [ + if test "x$host" = "xlinux" ; then + HAVE_LINSYS="yes" + fi +]) + dnl *** modplug *** translit(dnm, m, l) AM_CONDITIONAL(USE_MODPLUG, true) AG_GST_CHECK_FEATURE(MODPLUG, modplug, modplug, [ @@ -1797,6 +1805,7 @@ sys/dshowsrcwrapper/Makefile sys/dshowvideosink/Makefile sys/dvb/Makefile sys/fbdev/Makefile +sys/linsys/Makefile sys/osxvideo/Makefile sys/qtwrapper/Makefile sys/shm/Makefile diff --git a/sys/Makefile.am b/sys/Makefile.am index 766264252a..e2e29d835b 100644 --- a/sys/Makefile.am +++ b/sys/Makefile.am @@ -46,6 +46,13 @@ else DVB_DIR= endif +if USE_LINSYS +LINSYS_DIR=linsys +else +LINSYS_DIR= +endif + + if USE_APPLE_MEDIA APPLE_MEDIA_DIR=applemedia else @@ -88,9 +95,9 @@ else SHM_DIR= endif -SUBDIRS = $(ACM_DIR) $(APPLE_MEDIA_DIR) $(DIRECTDRAW_DIR) $(DIRECTSOUND_DIR) $(DVB_DIR) $(FBDEV_DIR) $(OSX_VIDEO_DIR) $(QT_DIR) $(SHM_DIR) $(VCD_DIR) $(VDPAU_DIR) $(WININET_DIR) +SUBDIRS = $(ACM_DIR) $(APPLE_MEDIA_DIR) $(DIRECTDRAW_DIR) $(DIRECTSOUND_DIR) $(DVB_DIR) $(FBDEV_DIR) $(LINSYS_DIR) $(OSX_VIDEO_DIR) $(QT_DIR) $(SHM_DIR) $(VCD_DIR) $(VDPAU_DIR) $(WININET_DIR) -DIST_SUBDIRS = acmenc acmmp3dec applemedia directdraw directsound dvb fbdev dshowdecwrapper dshowsrcwrapper dshowvideosink \ +DIST_SUBDIRS = acmenc acmmp3dec applemedia directdraw directsound dvb linsys fbdev dshowdecwrapper dshowsrcwrapper dshowvideosink \ osxvideo qtwrapper shm vcd vdpau wasapi wininet winks winscreencap include $(top_srcdir)/common/parallel-subdirs.mak diff --git a/sys/linsys/Makefile.am b/sys/linsys/Makefile.am new file mode 100644 index 0000000000..94e3bbd5b1 --- /dev/null +++ b/sys/linsys/Makefile.am @@ -0,0 +1,21 @@ + + +plugin_LTLIBRARIES = libgstlinsys.la + +libgstlinsys_la_SOURCES = \ + gstlinsyssdisink.c \ + gstlinsyssdisink.h \ + gstlinsyssdisrc.c \ + gstlinsyssdisrc.h \ + gstlinsys.c + +libgstlinsys_la_CFLAGS = \ + -I$(srcdir)/include \ + $(EWGST_CFLAGS) \ + $(GST_BASE_PLUGINS_CFLAGS) \ + $(GST_CFLAGS) +libgstlinsys_la_LDFLAGS = \ + $(GST_PLUGIN_LDFLAGS) \ + $(GST_LDFLAGS) +libgstlinsys_la_LIBADD = $(GST_VIDEO_LIBS) $(GST_LIBS) + diff --git a/sys/linsys/gstlinsys.c b/sys/linsys/gstlinsys.c new file mode 100644 index 0000000000..208c573b34 --- /dev/null +++ b/sys/linsys/gstlinsys.c @@ -0,0 +1,48 @@ +/* GStreamer + * Copyright (C) 2010 FIXME + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "gstlinsyssdisink.h" +#include "gstlinsyssdisrc.h" + +static gboolean +plugin_init (GstPlugin * plugin) +{ + + gst_element_register (plugin, "linsyssdisrc", GST_RANK_NONE, + gst_linsys_sdi_src_get_type ()); + gst_element_register (plugin, "linsyssdisink", GST_RANK_NONE, + gst_linsys_sdi_sink_get_type ()); + + return TRUE; +} + +#define PACKAGE_ORIGIN "http://FIXME.org/" + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "linsys", + "FIXME", plugin_init, VERSION, "LGPL", PACKAGE_NAME, PACKAGE_ORIGIN) diff --git a/sys/linsys/gstlinsyssdisink.c b/sys/linsys/gstlinsyssdisink.c new file mode 100644 index 0000000000..872c3d60e7 --- /dev/null +++ b/sys/linsys/gstlinsyssdisink.c @@ -0,0 +1,491 @@ +/* GStreamer + * Copyright (C) 2010 David Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include "gstlinsyssdisink.h" + +#include +#include +#include +#include +#include + +#include "sdivideo.h" + +/* prototypes */ + + +static void gst_linsys_sdi_sink_set_property (GObject * object, + guint property_id, const GValue * value, GParamSpec * pspec); +static void gst_linsys_sdi_sink_get_property (GObject * object, + guint property_id, GValue * value, GParamSpec * pspec); +static void gst_linsys_sdi_sink_dispose (GObject * object); +static void gst_linsys_sdi_sink_finalize (GObject * object); + +static GstCaps *gst_linsys_sdi_sink_get_caps (GstBaseSink * sink); +static gboolean gst_linsys_sdi_sink_set_caps (GstBaseSink * sink, + GstCaps * caps); +static GstFlowReturn gst_linsys_sdi_sink_buffer_alloc (GstBaseSink * sink, + guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf); +static void gst_linsys_sdi_sink_get_times (GstBaseSink * sink, + GstBuffer * buffer, GstClockTime * start, GstClockTime * end); +static gboolean gst_linsys_sdi_sink_start (GstBaseSink * sink); +static gboolean gst_linsys_sdi_sink_stop (GstBaseSink * sink); +static gboolean gst_linsys_sdi_sink_unlock (GstBaseSink * sink); +static gboolean gst_linsys_sdi_sink_event (GstBaseSink * sink, + GstEvent * event); +static GstFlowReturn gst_linsys_sdi_sink_preroll (GstBaseSink * sink, + GstBuffer * buffer); +static GstFlowReturn gst_linsys_sdi_sink_render (GstBaseSink * sink, + GstBuffer * buffer); +static GstStateChangeReturn gst_linsys_sdi_sink_async_play (GstBaseSink * sink); +static gboolean gst_linsys_sdi_sink_activate_pull (GstBaseSink * sink, + gboolean active); +static void gst_linsys_sdi_sink_fixate (GstBaseSink * sink, GstCaps * caps); +static gboolean gst_linsys_sdi_sink_unlock_stop (GstBaseSink * sink); +static GstFlowReturn +gst_linsys_sdi_sink_render_list (GstBaseSink * sink, + GstBufferList * buffer_list); + +enum +{ + PROP_0, + PROP_DEVICE +}; + +#define DEFAULT_DEVICE "/dev/sditx0" + +/* pad templates */ + +static GstStaticPadTemplate gst_linsys_sdi_sink_sink_template = +GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-raw-yuv,format=(fourcc)UYVY," + "width=720,height=480,pixel-aspect-ratio=10/11," + "framerate=30000/1001,interlaced=true," + "colorspec=sdtv,chroma-site=mpeg2") + ); + +/* class initialization */ + +GST_BOILERPLATE (GstLinsysSdiSink, gst_linsys_sdi_sink, GstBaseSink, + GST_TYPE_BASE_SINK); + +static void +gst_linsys_sdi_sink_base_init (gpointer g_class) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_linsys_sdi_sink_sink_template)); + + gst_element_class_set_details_simple (element_class, "SDI video sink", + "Sink/Video", "Writes video from SDI transmit device", + "David Schleef "); +} + +static void +gst_linsys_sdi_sink_class_init (GstLinsysSdiSinkClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstBaseSinkClass *base_sink_class = GST_BASE_SINK_CLASS (klass); + + gobject_class->set_property = gst_linsys_sdi_sink_set_property; + gobject_class->get_property = gst_linsys_sdi_sink_get_property; + gobject_class->dispose = gst_linsys_sdi_sink_dispose; + gobject_class->finalize = gst_linsys_sdi_sink_finalize; + base_sink_class->get_caps = GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_get_caps); + base_sink_class->set_caps = GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_set_caps); + if (0) + base_sink_class->buffer_alloc = + GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_buffer_alloc); + base_sink_class->get_times = + GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_get_times); + base_sink_class->start = GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_start); + base_sink_class->stop = GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_stop); + base_sink_class->unlock = GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_unlock); + base_sink_class->event = GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_event); + base_sink_class->preroll = GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_preroll); + base_sink_class->render = GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_render); + if (0) + base_sink_class->async_play = + GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_async_play); + if (0) + base_sink_class->activate_pull = + GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_activate_pull); + base_sink_class->fixate = GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_fixate); + base_sink_class->unlock_stop = + GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_unlock_stop); + base_sink_class->render_list = + GST_DEBUG_FUNCPTR (gst_linsys_sdi_sink_render_list); + + g_object_class_install_property (gobject_class, PROP_DEVICE, + g_param_spec_string ("device", "Device", "device to transmit data on", + DEFAULT_DEVICE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +static void +gst_linsys_sdi_sink_init (GstLinsysSdiSink * linsyssdisink, + GstLinsysSdiSinkClass * linsyssdisink_class) +{ + linsyssdisink->device = g_strdup (DEFAULT_DEVICE); +} + +void +gst_linsys_sdi_sink_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + GstLinsysSdiSink *linsyssdisink; + + g_return_if_fail (GST_IS_LINSYS_SDI_SINK (object)); + linsyssdisink = GST_LINSYS_SDI_SINK (object); + + switch (property_id) { + case PROP_DEVICE: + g_free (linsyssdisink->device); + linsyssdisink->device = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +void +gst_linsys_sdi_sink_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + GstLinsysSdiSink *linsyssdisink; + + g_return_if_fail (GST_IS_LINSYS_SDI_SINK (object)); + linsyssdisink = GST_LINSYS_SDI_SINK (object); + + switch (property_id) { + case PROP_DEVICE: + g_value_set_string (value, linsyssdisink->device); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +void +gst_linsys_sdi_sink_dispose (GObject * object) +{ + GstLinsysSdiSink *linsyssdisink; + + g_return_if_fail (GST_IS_LINSYS_SDI_SINK (object)); + linsyssdisink = GST_LINSYS_SDI_SINK (object); + + /* clean up as possible. may be called multiple times */ + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +void +gst_linsys_sdi_sink_finalize (GObject * object) +{ + GstLinsysSdiSink *linsyssdisink; + + g_return_if_fail (GST_IS_LINSYS_SDI_SINK (object)); + linsyssdisink = GST_LINSYS_SDI_SINK (object); + + /* clean up object here */ + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + + + +static GstCaps * +gst_linsys_sdi_sink_get_caps (GstBaseSink * sink) +{ + GST_ERROR_OBJECT (sink, "get_caps"); + + return NULL; +} + +static gboolean +gst_linsys_sdi_sink_set_caps (GstBaseSink * sink, GstCaps * caps) +{ + GST_ERROR_OBJECT (sink, "set_caps"); + + return TRUE; +} + +static GstFlowReturn +gst_linsys_sdi_sink_buffer_alloc (GstBaseSink * sink, guint64 offset, + guint size, GstCaps * caps, GstBuffer ** buf) +{ + GST_ERROR_OBJECT (sink, "buffer_alloc"); + + return GST_FLOW_ERROR; +} + +static void +gst_linsys_sdi_sink_get_times (GstBaseSink * sink, GstBuffer * buffer, + GstClockTime * start, GstClockTime * end) +{ + +} + +static gboolean +gst_linsys_sdi_sink_start (GstBaseSink * sink) +{ + GstLinsysSdiSink *linsyssdisink = GST_LINSYS_SDI_SINK (sink); + int fd; + + GST_ERROR_OBJECT (sink, "start"); + + fd = open (linsyssdisink->device, O_WRONLY, 0); + if (fd < 0) { + GST_ERROR_OBJECT (sink, "failed to open device"); + return FALSE; + } + + linsyssdisink->fd = fd; + linsyssdisink->tmpdata = g_malloc (858 * 525 * 2); + + return TRUE; +} + +static gboolean +gst_linsys_sdi_sink_stop (GstBaseSink * sink) +{ + GstLinsysSdiSink *linsyssdisink = GST_LINSYS_SDI_SINK (sink); + + GST_ERROR_OBJECT (sink, "stop"); + + if (linsyssdisink->fd > 0) { + close (linsyssdisink->fd); + } + g_free (linsyssdisink->tmpdata); + linsyssdisink->tmpdata = NULL; + + return TRUE; +} + +static gboolean +gst_linsys_sdi_sink_unlock (GstBaseSink * sink) +{ + GST_ERROR_OBJECT (sink, "unlock"); + + return TRUE; +} + +static gboolean +gst_linsys_sdi_sink_event (GstBaseSink * sink, GstEvent * event) +{ + GST_ERROR_OBJECT (sink, "event"); + + return TRUE; +} + +static GstFlowReturn +gst_linsys_sdi_sink_preroll (GstBaseSink * sink, GstBuffer * buffer) +{ + GST_ERROR_OBJECT (sink, "preroll"); + + return GST_FLOW_OK; +} + +#define EAV 0x74 +#define SAV 0x80 + +static int +get_av (int f, int v, int h) +{ + static int table[] = { + 0x80, 0x9d, 0xab, 0xb6, 0xc7, 0xda, 0xec, 0xf1 + }; + + return table[(f << 2) | (v << 1) | h]; +} + +static void +sdi_mux (guint8 * data, GstBuffer * buffer) +{ + int j; + int i; + guint8 *dest; + int f, v, h; + int line; + + for (j = 0; j < 525; j++) { + dest = data + 858 * 2 * j; + + line = (j + 4) % 525; + + if (line < 10 || (line >= 264 && line < 273)) { + v = 1; + } else { + v = 0; + } + + if (line >= 266 || line < 4) { + f = 1; + } else { + f = 0; + } + + h = 0; + + dest[0] = 0xff; + dest[1] = 0; + dest[2] = 0; + dest[3] = get_av (f, v, 1); + + for (i = 1; i < (858 - 720) / 2 - 1; i++) { + dest[i * 4 + 0] = 0x200 >> 2; + dest[i * 4 + 1] = 0x040 >> 2; + dest[i * 4 + 2] = 0x200 >> 2; + dest[i * 4 + 3] = 0x040 >> 2; + } + + i = (858 - 720) / 2 - 1; + dest[i * 4 + 0] = 0xff; + dest[i * 4 + 1] = 0x00; + dest[i * 4 + 2] = 0x00; + dest[3] = get_av (f, v, 0); + + i = (858 - 720) / 2; + if (line >= 23 && line <= 262) { + int src_line = (line - 23) * 2 + 1; + memcpy (dest + i * 4, GST_BUFFER_DATA (buffer) + 720 * 2 * src_line, + 720 * 2); + } else if (line >= 285 && line <= 525) { + int src_line = (line - 285) * 2 + 0; + memcpy (dest + i * 4, GST_BUFFER_DATA (buffer) + 720 * 2 * src_line, + 720 * 2); + } else { + for (i = (858 - 720) / 2; i < 858 / 2; i++) { + dest[i * 4 + 0] = 0x200 >> 2; + dest[i * 4 + 1] = 0x040 >> 2; + dest[i * 4 + 2] = 0x200 >> 2; + dest[i * 4 + 3] = 0x040 >> 2; + } + } + } + +} + +static GstFlowReturn +gst_linsys_sdi_sink_render (GstBaseSink * sink, GstBuffer * buffer) +{ + GstLinsysSdiSink *linsyssdisink = GST_LINSYS_SDI_SINK (sink); + int ret; + struct pollfd pfd; + int offset; + guint8 *data = linsyssdisink->tmpdata; + + GST_ERROR_OBJECT (sink, "render"); + + sdi_mux (data, buffer); + + offset = 0; +#define SIZE (858*525*2) + while (offset < SIZE) { + pfd.fd = linsyssdisink->fd; + pfd.events = POLLOUT | POLLPRI; + ret = poll (&pfd, 1, -1); + if (ret < 0) { + GST_ERROR_OBJECT (sink, "poll failed %d", ret); + return GST_FLOW_ERROR; + } + + if (pfd.revents & POLLOUT) { + ret = write (linsyssdisink->fd, data + offset, SIZE - offset); + if (ret < 0) { + GST_ERROR_OBJECT (sink, "write failed %d", ret); + return GST_FLOW_ERROR; + } + offset += ret; + } + if (pfd.revents & POLLPRI) { + long val; + + ret = ioctl (linsyssdisink->fd, SDIVIDEO_IOC_TXGETEVENTS, &val); + if (ret < 0) { + GST_ERROR_OBJECT (sink, "ioctl failed %d", ret); + return GST_FLOW_ERROR; + } + if (val & SDIVIDEO_EVENT_TX_BUFFER) { + GST_ERROR_OBJECT (sink, "transmit buffer underrun"); + return GST_FLOW_ERROR; + } + if (val & SDIVIDEO_EVENT_TX_FIFO) { + GST_ERROR_OBJECT (sink, "transmit FIFO underrun"); + return GST_FLOW_ERROR; + } + if (val & SDIVIDEO_EVENT_TX_DATA) { + GST_ERROR_OBJECT (sink, "transmit status change"); + } + } + } + + return GST_FLOW_OK; +} + +static GstStateChangeReturn +gst_linsys_sdi_sink_async_play (GstBaseSink * sink) +{ + GST_ERROR_OBJECT (sink, "render"); + + return GST_STATE_CHANGE_SUCCESS; +} + +static gboolean +gst_linsys_sdi_sink_activate_pull (GstBaseSink * sink, gboolean active) +{ + GST_ERROR_OBJECT (sink, "activate_pull"); + + return TRUE; +} + +static void +gst_linsys_sdi_sink_fixate (GstBaseSink * sink, GstCaps * caps) +{ + GST_ERROR_OBJECT (sink, "fixate"); + +} + +static gboolean +gst_linsys_sdi_sink_unlock_stop (GstBaseSink * sink) +{ + GST_ERROR_OBJECT (sink, "unlock_stop"); + + return TRUE; +} + +static GstFlowReturn +gst_linsys_sdi_sink_render_list (GstBaseSink * sink, + GstBufferList * buffer_list) +{ + GST_ERROR_OBJECT (sink, "render_list"); + + return GST_FLOW_OK; +} diff --git a/sys/linsys/gstlinsyssdisink.h b/sys/linsys/gstlinsyssdisink.h new file mode 100644 index 0000000000..2f4105f3b0 --- /dev/null +++ b/sys/linsys/gstlinsyssdisink.h @@ -0,0 +1,59 @@ +/* GStreamer + * Copyright (C) 2010 FIXME + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_LINSYS_SDI_SINK_H_ +#define _GST_LINSYS_SDI_SINK_H_ + +#include +#include + + +G_BEGIN_DECLS + +#define GST_TYPE_LINSYS_SDI_SINK (gst_linsys_sdi_sink_get_type()) +#define GST_LINSYS_SDI_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_LINSYS_SDI_SINK,GstLinsysSdiSink)) +#define GST_LINSYS_SDI_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_LINSYS_SDI_SINK,GstLinsysSdiSinkClass)) +#define GST_IS_LINSYS_SDI_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_LINSYS_SDI_SINK)) +#define GST_IS_LINSYS_SDI_SINK_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_LINSYS_SDI_SINK)) + +typedef struct _GstLinsysSdiSink GstLinsysSdiSink; +typedef struct _GstLinsysSdiSinkClass GstLinsysSdiSinkClass; + +struct _GstLinsysSdiSink +{ + GstBaseSink base_linsyssdisink; + + /* properties */ + gchar *device; + + /* state */ + int fd; + guint8 *tmpdata; +}; + +struct _GstLinsysSdiSinkClass +{ + GstBaseSinkClass base_linsyssdisink_class; +}; + +GType gst_linsys_sdi_sink_get_type (void); + +G_END_DECLS + +#endif diff --git a/sys/linsys/gstlinsyssdisrc.c b/sys/linsys/gstlinsyssdisrc.c new file mode 100644 index 0000000000..075b0c7134 --- /dev/null +++ b/sys/linsys/gstlinsyssdisrc.c @@ -0,0 +1,554 @@ +/* GStreamer + * Copyright (C) 2010 David Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include "gstlinsyssdisrc.h" + +#include +#include +#include +#include +#include + +#include "sdivideo.h" + +/* prototypes */ + + +static void gst_linsys_sdi_src_set_property (GObject * object, + guint property_id, const GValue * value, GParamSpec * pspec); +static void gst_linsys_sdi_src_get_property (GObject * object, + guint property_id, GValue * value, GParamSpec * pspec); +static void gst_linsys_sdi_src_dispose (GObject * object); +static void gst_linsys_sdi_src_finalize (GObject * object); + +static GstCaps *gst_linsys_sdi_src_get_caps (GstBaseSrc * src); +static gboolean gst_linsys_sdi_src_set_caps (GstBaseSrc * src, GstCaps * caps); +static gboolean gst_linsys_sdi_src_negotiate (GstBaseSrc * src); +static gboolean gst_linsys_sdi_src_newsegment (GstBaseSrc * src); +static gboolean gst_linsys_sdi_src_start (GstBaseSrc * src); +static gboolean gst_linsys_sdi_src_stop (GstBaseSrc * src); +static void +gst_linsys_sdi_src_get_times (GstBaseSrc * src, GstBuffer * buffer, + GstClockTime * start, GstClockTime * end); +static gboolean gst_linsys_sdi_src_get_size (GstBaseSrc * src, guint64 * size); +static gboolean gst_linsys_sdi_src_is_seekable (GstBaseSrc * src); +static gboolean gst_linsys_sdi_src_unlock (GstBaseSrc * src); +static gboolean gst_linsys_sdi_src_event (GstBaseSrc * src, GstEvent * event); +static GstFlowReturn +gst_linsys_sdi_src_create (GstBaseSrc * src, guint64 offset, guint size, + GstBuffer ** buf); +static gboolean gst_linsys_sdi_src_do_seek (GstBaseSrc * src, + GstSegment * segment); +static gboolean gst_linsys_sdi_src_query (GstBaseSrc * src, GstQuery * query); +static gboolean gst_linsys_sdi_src_check_get_range (GstBaseSrc * src); +static void gst_linsys_sdi_src_fixate (GstBaseSrc * src, GstCaps * caps); +static gboolean gst_linsys_sdi_src_unlock_stop (GstBaseSrc * src); +static gboolean +gst_linsys_sdi_src_prepare_seek_segment (GstBaseSrc * src, GstEvent * seek, + GstSegment * segment); + +enum +{ + PROP_0, + PROP_DEVICE +}; + +#define DEFAULT_DEVICE "/dev/sdirx0" + +GST_DEBUG_CATEGORY (gst_linsys_sdi_src_debug); +#define GST_CAT_DEFAULT gst_linsys_sdi_src_debug + +/* pad templates */ + +static GstStaticPadTemplate gst_linsys_sdi_src_src_template = +GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-raw-yuv,format=(fourcc)UYVY," + "width=720,height=480,pixel-aspect-ratio=10/11," + "framerate=30000/1001,interlaced=true," + "colorspec=sdtv,chroma-site=mpeg2") + ); + +/* class initialization */ + +GST_BOILERPLATE (GstLinsysSdiSrc, gst_linsys_sdi_src, GstBaseSrc, + GST_TYPE_BASE_SRC); + +static void +gst_linsys_sdi_src_base_init (gpointer g_class) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&gst_linsys_sdi_src_src_template)); + + gst_element_class_set_details_simple (element_class, "SDI video source", + "Source/Video", "Reads video from SDI capture device", + "David Schleef "); +} + +static void +gst_linsys_sdi_src_class_init (GstLinsysSdiSrcClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstBaseSrcClass *base_src_class = GST_BASE_SRC_CLASS (klass); + + GST_DEBUG_CATEGORY_INIT (gst_linsys_sdi_src_debug, "linsyssdisrc", 0, + "FIXME"); + + gobject_class->set_property = gst_linsys_sdi_src_set_property; + gobject_class->get_property = gst_linsys_sdi_src_get_property; + gobject_class->dispose = gst_linsys_sdi_src_dispose; + gobject_class->finalize = gst_linsys_sdi_src_finalize; + base_src_class->get_caps = GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_get_caps); + base_src_class->set_caps = GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_set_caps); + if (0) + base_src_class->negotiate = + GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_negotiate); + base_src_class->newsegment = + GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_newsegment); + base_src_class->start = GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_start); + base_src_class->stop = GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_stop); + base_src_class->get_times = GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_get_times); + base_src_class->get_size = GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_get_size); + base_src_class->is_seekable = + GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_is_seekable); + base_src_class->unlock = GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_unlock); + base_src_class->event = GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_event); + base_src_class->create = GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_create); + if (0) + base_src_class->do_seek = GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_do_seek); + base_src_class->query = GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_query); + base_src_class->check_get_range = + GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_check_get_range); + base_src_class->fixate = GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_fixate); + base_src_class->unlock_stop = + GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_unlock_stop); + base_src_class->prepare_seek_segment = + GST_DEBUG_FUNCPTR (gst_linsys_sdi_src_prepare_seek_segment); + + g_object_class_install_property (gobject_class, PROP_DEVICE, + g_param_spec_string ("device", "Device", "device to transmit data on", + DEFAULT_DEVICE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +static void +gst_linsys_sdi_src_init (GstLinsysSdiSrc * linsyssdisrc, + GstLinsysSdiSrcClass * linsyssdisrc_class) +{ + + gst_base_src_set_live (GST_BASE_SRC (linsyssdisrc), TRUE); + gst_base_src_set_blocksize (GST_BASE_SRC (linsyssdisrc), 720 * 480 * 2); + + linsyssdisrc->device = g_strdup (DEFAULT_DEVICE); + + linsyssdisrc->is_625 = FALSE; + linsyssdisrc->fd = -1; +} + +void +gst_linsys_sdi_src_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + GstLinsysSdiSrc *linsyssdisrc; + + g_return_if_fail (GST_IS_LINSYS_SDI_SRC (object)); + linsyssdisrc = GST_LINSYS_SDI_SRC (object); + + switch (property_id) { + case PROP_DEVICE: + g_free (linsyssdisrc->device); + linsyssdisrc->device = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +void +gst_linsys_sdi_src_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + GstLinsysSdiSrc *linsyssdisrc; + + g_return_if_fail (GST_IS_LINSYS_SDI_SRC (object)); + linsyssdisrc = GST_LINSYS_SDI_SRC (object); + + switch (property_id) { + case PROP_DEVICE: + g_value_set_string (value, linsyssdisrc->device); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +void +gst_linsys_sdi_src_dispose (GObject * object) +{ + GstLinsysSdiSrc *linsyssdisrc; + + g_return_if_fail (GST_IS_LINSYS_SDI_SRC (object)); + linsyssdisrc = GST_LINSYS_SDI_SRC (object); + + /* clean up as possible. may be called multiple times */ + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +void +gst_linsys_sdi_src_finalize (GObject * object) +{ + GstLinsysSdiSrc *linsyssdisrc; + + g_return_if_fail (GST_IS_LINSYS_SDI_SRC (object)); + linsyssdisrc = GST_LINSYS_SDI_SRC (object); + + /* clean up object here */ + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + + +static GstCaps * +gst_linsys_sdi_src_get_caps (GstBaseSrc * src) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "get_caps"); + + return NULL; +} + +static gboolean +gst_linsys_sdi_src_set_caps (GstBaseSrc * src, GstCaps * caps) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "set_caps"); + + return TRUE; +} + +static gboolean +gst_linsys_sdi_src_negotiate (GstBaseSrc * src) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "negotiate"); + + return TRUE; +} + +static gboolean +gst_linsys_sdi_src_newsegment (GstBaseSrc * src) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "newsegment"); + + return TRUE; +} + +static gboolean +gst_linsys_sdi_src_start (GstBaseSrc * src) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + int fd; + + GST_DEBUG_OBJECT (linsyssdisrc, "start"); + + fd = open (linsyssdisrc->device, O_RDONLY); + if (fd < 0) { + GST_ERROR_OBJECT (src, "failed to open device"); + return FALSE; + } + + linsyssdisrc->fd = fd; + + if (linsyssdisrc->is_625) { + linsyssdisrc->tmpdata = g_malloc (864 * 625 * 2); + } else { + linsyssdisrc->tmpdata = g_malloc (858 * 525 * 2); + } + linsyssdisrc->have_sync = FALSE; + + return TRUE; +} + +static gboolean +gst_linsys_sdi_src_stop (GstBaseSrc * src) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "stop"); + +#if 0 + if (linsyssdisrc->fd > 0) { + close (linsyssdisrc->fd); + linsyssdisrc->fd = -1; + } + g_free (linsyssdisrc->tmpdata); + linsyssdisrc->tmpdata = NULL; +#endif + + return TRUE; +} + +static void +gst_linsys_sdi_src_get_times (GstBaseSrc * src, GstBuffer * buffer, + GstClockTime * start, GstClockTime * end) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "get_times"); +} + +static gboolean +gst_linsys_sdi_src_get_size (GstBaseSrc * src, guint64 * size) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "get_size"); + + return FALSE; +} + +static gboolean +gst_linsys_sdi_src_is_seekable (GstBaseSrc * src) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "is_seekable"); + + return FALSE; +} + +static gboolean +gst_linsys_sdi_src_unlock (GstBaseSrc * src) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "unlock"); + + return TRUE; +} + +static gboolean +gst_linsys_sdi_src_event (GstBaseSrc * src, GstEvent * event) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "event"); + + return TRUE; +} + +static void +sdi_demux (guint8 * data, GstBuffer * buf, gboolean is_625) +{ + int j; + int line; + int offset; + + if (is_625) { + offset = (864 - 720) / 2; + + for (j = 0; j < 480; j++) { + if (j & 1) { + line = 23 + (j - 1) / 2; + } else { + line = 335 + j / 2; + } + memcpy (GST_BUFFER_DATA (buf) + j * 720 * 2, + data + (line - 1) * 864 * 2 + offset * 4, 720 * 2); + } + } else { + offset = (858 - 720) / 2; + + for (j = 0; j < 480; j++) { + if (j & 1) { + line = 23 + (j - 1) / 2; + } else { + line = 285 + j / 2; + } + memcpy (GST_BUFFER_DATA (buf) + j * 720 * 2, + data + (line - 1) * 858 * 2 + offset * 4, 720 * 2); + } + } + +} + +static GstFlowReturn +gst_linsys_sdi_src_create (GstBaseSrc * src, guint64 _offset, guint size, + GstBuffer ** buf) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + int offset; + int ret; + struct pollfd pfd; + int sdi_size; + int sdi_width; + guint8 *data = linsyssdisrc->tmpdata; + + if (linsyssdisrc->fd < 0) + return GST_FLOW_WRONG_STATE; + + if (linsyssdisrc->is_625) { + sdi_width = 864; + sdi_size = 864 * 625 * 2; + } else { + sdi_width = 858; + sdi_size = 858 * 525 * 2; + } + + GST_DEBUG_OBJECT (linsyssdisrc, "create size=%d fd=%d", size, + linsyssdisrc->fd); + + offset = 0; + while (offset < sdi_size) { + pfd.fd = linsyssdisrc->fd; + pfd.events = POLLIN | POLLPRI; + ret = poll (&pfd, 1, 1000); + if (ret < 0) { + GST_ERROR_OBJECT (src, "poll failed %d", ret); + return GST_FLOW_ERROR; + } + + if (pfd.revents & POLLIN) { + if (linsyssdisrc->have_sync) { + ret = read (linsyssdisrc->fd, data + offset, sdi_size - offset); + } else { + ret = read (linsyssdisrc->fd, data + offset, sdi_width * 2); + } + if (ret < 0) { + GST_ERROR_OBJECT (src, "read failed %d", ret); + return GST_FLOW_ERROR; + } + + if (!linsyssdisrc->have_sync) { + int v = (data[3] >> 5) & 1; + int f = (data[3] >> 6) & 1; + if (!linsyssdisrc->have_vblank && (f == 0) && (v == 1)) { + linsyssdisrc->have_vblank = TRUE; + } else if (linsyssdisrc->have_vblank && (f == 0) && (v == 0)) { + offset += sdi_width * 2 * 9; + linsyssdisrc->have_sync = TRUE; + offset += ret; + } + } else { + offset += ret; + } + } + if (pfd.revents & POLLPRI) { + long val; + + ret = ioctl (linsyssdisrc->fd, SDIVIDEO_IOC_RXGETEVENTS, &val); + if (ret < 0) { + GST_ERROR_OBJECT (src, "ioctl failed %d", ret); + return GST_FLOW_ERROR; + } + if (val & SDIVIDEO_EVENT_RX_BUFFER) { + GST_ERROR_OBJECT (src, "receive buffer overrun"); + return GST_FLOW_ERROR; + } + if (val & SDIVIDEO_EVENT_RX_FIFO) { + GST_ERROR_OBJECT (src, "receive FIFO overrun"); + return GST_FLOW_ERROR; + } + if (val & SDIVIDEO_EVENT_RX_CARRIER) { + GST_ERROR_OBJECT (src, "carrier status change"); + } + } + } + + *buf = gst_buffer_new_and_alloc (size); + sdi_demux (data, *buf, linsyssdisrc->is_625); + + return GST_FLOW_OK; +} + +static gboolean +gst_linsys_sdi_src_do_seek (GstBaseSrc * src, GstSegment * segment) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "do_seek"); + + return FALSE; +} + +static gboolean +gst_linsys_sdi_src_query (GstBaseSrc * src, GstQuery * query) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "query"); + + return TRUE; +} + +static gboolean +gst_linsys_sdi_src_check_get_range (GstBaseSrc * src) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "get_range"); + + return FALSE; +} + +static void +gst_linsys_sdi_src_fixate (GstBaseSrc * src, GstCaps * caps) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "fixate"); +} + +static gboolean +gst_linsys_sdi_src_unlock_stop (GstBaseSrc * src) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "stop"); + + return TRUE; +} + +static gboolean +gst_linsys_sdi_src_prepare_seek_segment (GstBaseSrc * src, GstEvent * seek, + GstSegment * segment) +{ + GstLinsysSdiSrc *linsyssdisrc = GST_LINSYS_SDI_SRC (src); + + GST_DEBUG_OBJECT (linsyssdisrc, "seek_segment"); + + return FALSE; +} diff --git a/sys/linsys/gstlinsyssdisrc.h b/sys/linsys/gstlinsyssdisrc.h new file mode 100644 index 0000000000..e43c9cb671 --- /dev/null +++ b/sys/linsys/gstlinsyssdisrc.h @@ -0,0 +1,62 @@ +/* GStreamer + * Copyright (C) 2010 FIXME + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GST_LINSYS_SDI_SRC_H_ +#define _GST_LINSYS_SDI_SRC_H_ + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_LINSYS_SDI_SRC (gst_linsys_sdi_src_get_type()) +#define GST_LINSYS_SDI_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_LINSYS_SDI_SRC,GstLinsysSdiSrc)) +#define GST_LINSYS_SDI_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_LINSYS_SDI_SRC,GstLinsysSdiSrcClass)) +#define GST_IS_LINSYS_SDI_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_LINSYS_SDI_SRC)) +#define GST_IS_LINSYS_SDI_SRC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_LINSYS_SDI_SRC)) + +typedef struct _GstLinsysSdiSrc GstLinsysSdiSrc; +typedef struct _GstLinsysSdiSrcClass GstLinsysSdiSrcClass; + +struct _GstLinsysSdiSrc +{ + GstBaseSrc base_linsyssdisrc; + + /* properties */ + gchar *device; + gboolean is_625; + + /* state */ + int fd; + guint8 *tmpdata; + gboolean have_sync; + gboolean have_vblank; + +}; + +struct _GstLinsysSdiSrcClass +{ + GstBaseSrcClass base_linsyssdisrc_class; +}; + +GType gst_linsys_sdi_src_get_type (void); + +G_END_DECLS + +#endif diff --git a/sys/linsys/include/asi.h b/sys/linsys/include/asi.h new file mode 100644 index 0000000000..89635886dd --- /dev/null +++ b/sys/linsys/include/asi.h @@ -0,0 +1,255 @@ +/* asi.h + * + * Shared header file for the Linux user-space API for + * Linear Systems Ltd. DVB Master ASI interface boards. + * + * Copyright (C) 1999 Tony Bolger + * Copyright (C) 2000-2009 Linear Systems Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of Linear Systems Ltd. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY LINEAR SYSTEMS LTD. "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL LINEAR SYSTEMS LTD. OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Linear Systems can be contacted at . + * + */ + +#ifndef _ASI_H +#define _ASI_H + +/* Driver info */ +#define ASI_DRIVER_NAME "asi" + +#define ASI_MAJOR 61 /* Set to 0 for dynamic allocation. + * Otherwise, 61 is available. + * See /usr/src/linux/Documentation/devices.txt */ + +#define ASI_TX_BUFFERS_MIN 2 /* This must be at least 2 */ +/* The minimum transmit buffer size must be positive, divisible by 8, + * and large enough that the buffers aren't transferred to the onboard FIFOs + * too quickly for the machine to handle the interrupts. + * This is especially a problem at startup, when the FIFOs are empty. + * Relevant factors include onboard FIFO size, PCI bus throughput, + * processor speed, and interrupt latency. */ +#define ASI_TX_BUFSIZE_MIN 1024 +#define ASI_RX_BUFFERS_MIN 2 /* This must be at least 2 */ +#define ASI_RX_BUFSIZE_MIN 8 /* This must be positive and divisible by 8 */ + +#define ASI_TX_BUFFERS 54 /* This must be at least 2 */ +#define ASI_TX_BUFSIZE 38352 /* This must be positive and divisible by 8 */ +#define ASI_RX_BUFFERS 54 /* This must be at least 2 */ +#define ASI_RX_BUFSIZE 38352 /* This must be positive and divisible by 8 */ + +/* Ioctl () definitions */ +#define ASI_IOC_MAGIC '?' /* This ioctl magic number is currently free. See + * /usr/src/linux/Documentation/ioctl-number.txt */ + +#define ASI_IOC_TXGETCAP _IOR(ASI_IOC_MAGIC, 1, unsigned int) +#define ASI_IOC_TXGETEVENTS _IOR(ASI_IOC_MAGIC, 2, unsigned int) +#define ASI_IOC_TXGETBUFLEVEL _IOR(ASI_IOC_MAGIC, 3, unsigned int) +#define ASI_IOC_TXSETSTUFFING _IOW(ASI_IOC_MAGIC, 4, struct asi_txstuffing) +#define ASI_IOC_TXGETBYTECOUNT _IOR(ASI_IOC_MAGIC, 5, unsigned int) +/* #define ASI_IOC_TXGETFIFO _IOR(ASI_IOC_MAGIC, 6, int) */ +#define ASI_IOC_TXGETTXD _IOR(ASI_IOC_MAGIC, 7, int) +#define ASI_IOC_TXGET27COUNT _IOR(ASI_IOC_MAGIC, 8, unsigned int) +/* Provide compatibility with applications compiled for older API */ +#define ASI_IOC_TXSETPID_DEPRECATED _IOR(ASI_IOC_MAGIC, 9, unsigned int) +#define ASI_IOC_TXSETPID _IOW(ASI_IOC_MAGIC, 9, unsigned int) +#define ASI_IOC_TXGETPCRSTAMP _IOR(ASI_IOC_MAGIC, 10, struct asi_pcrstamp) +/* Provide compatibility with applications compiled for older API */ +#define ASI_IOC_TXCHANGENEXTIP_DEPRECATED _IOR(ASI_IOC_MAGIC, 11, int) +#define ASI_IOC_TXCHANGENEXTIP _IOW(ASI_IOC_MAGIC, 11, int) + +#define ASI_IOC_RXGETCAP _IOR(ASI_IOC_MAGIC, 65, unsigned int) +#define ASI_IOC_RXGETEVENTS _IOR(ASI_IOC_MAGIC, 66, unsigned int) +#define ASI_IOC_RXGETBUFLEVEL _IOR(ASI_IOC_MAGIC, 67, unsigned int) +/* #define ASI_IOC_RXSETREFRAME _IOW(ASI_IOC_MAGIC, 68, int) */ +#define ASI_IOC_RXGETSTATUS _IOR(ASI_IOC_MAGIC, 69, int) +#define ASI_IOC_RXGETBYTECOUNT _IOR(ASI_IOC_MAGIC, 70, unsigned int) +/* #define ASI_IOC_RXGETFIFO _IOR(ASI_IOC_MAGIC, 71, int) */ +#define ASI_IOC_RXSETINVSYNC _IOW(ASI_IOC_MAGIC, 72, int) +#define ASI_IOC_RXGETCARRIER _IOR(ASI_IOC_MAGIC, 73, int) +#define ASI_IOC_RXSETDSYNC _IOW(ASI_IOC_MAGIC, 74, int) +#define ASI_IOC_RXGETRXD _IOR(ASI_IOC_MAGIC, 75, int) +#define ASI_IOC_RXSETPF _IOW(ASI_IOC_MAGIC, 76, unsigned int [256]) +/* #define ASI_IOC_RXSETPFE _IOW(ASI_IOC_MAGIC, 77, int) */ +#define ASI_IOC_RXSETPID0 _IOW(ASI_IOC_MAGIC, 78, int) +#define ASI_IOC_RXGETPID0COUNT _IOR(ASI_IOC_MAGIC, 79, unsigned int) +#define ASI_IOC_RXSETPID1 _IOW(ASI_IOC_MAGIC, 80, int) +#define ASI_IOC_RXGETPID1COUNT _IOR(ASI_IOC_MAGIC, 81, unsigned int) +#define ASI_IOC_RXSETPID2 _IOW(ASI_IOC_MAGIC, 82, int) +#define ASI_IOC_RXGETPID2COUNT _IOR(ASI_IOC_MAGIC, 83, unsigned int) +#define ASI_IOC_RXSETPID3 _IOW(ASI_IOC_MAGIC, 84, int) +#define ASI_IOC_RXGETPID3COUNT _IOR(ASI_IOC_MAGIC, 85, unsigned int) +/* #define ASI_IOC_RXGETSTAMP _IOR(ASI_IOC_MAGIC, 86, unsigned int) */ +#define ASI_IOC_RXGET27COUNT _IOR(ASI_IOC_MAGIC, 87, unsigned int) +#define ASI_IOC_RXGETSTATUS2 _IOR(ASI_IOC_MAGIC, 88, int) +/* Provide compatibility with applications compiled for older API */ +#define ASI_IOC_RXSETINPUT_DEPRECATED _IOR(ASI_IOC_MAGIC, 89, int) +#define ASI_IOC_RXSETINPUT _IOW(ASI_IOC_MAGIC, 89, int) +#define ASI_IOC_RXGETRXD2 _IOR(ASI_IOC_MAGIC, 90, int) + +#define ASI_IOC_GETID _IOR(ASI_IOC_MAGIC, 129, unsigned int) +#define ASI_IOC_GETVERSION _IOR(ASI_IOC_MAGIC, 130, unsigned int) + +/* Transmitter event flag bit locations */ +#define ASI_EVENT_TX_BUFFER_ORDER 0 +#define ASI_EVENT_TX_BUFFER (1 << ASI_EVENT_TX_BUFFER_ORDER) +#define ASI_EVENT_TX_FIFO_ORDER 1 +#define ASI_EVENT_TX_FIFO (1 << ASI_EVENT_TX_FIFO_ORDER) +#define ASI_EVENT_TX_DATA_ORDER 2 +#define ASI_EVENT_TX_DATA (1 << ASI_EVENT_TX_DATA_ORDER) + +/* Receiver event flag bit locations */ +#define ASI_EVENT_RX_BUFFER_ORDER 0 +#define ASI_EVENT_RX_BUFFER (1 << ASI_EVENT_RX_BUFFER_ORDER) +#define ASI_EVENT_RX_FIFO_ORDER 1 +#define ASI_EVENT_RX_FIFO (1 << ASI_EVENT_RX_FIFO_ORDER) +#define ASI_EVENT_RX_CARRIER_ORDER 2 +#define ASI_EVENT_RX_CARRIER (1 << ASI_EVENT_RX_CARRIER_ORDER) +#define ASI_EVENT_RX_AOS_ORDER 3 +#define ASI_EVENT_RX_AOS (1 << ASI_EVENT_RX_AOS_ORDER) +#define ASI_EVENT_RX_LOS_ORDER 4 +#define ASI_EVENT_RX_LOS (1 << ASI_EVENT_RX_LOS_ORDER) +#define ASI_EVENT_RX_DATA_ORDER 5 +#define ASI_EVENT_RX_DATA (1 << ASI_EVENT_RX_DATA_ORDER) + +/** + * asi_txstuffing - Transmitter stuffing parameters + * @ib: interbyte stuffing + * @ip: interpacket stuffing + * @normal_ip: FT0 + * @big_ip: FT1 + * @il_normal: IL0 + * @il_big: IL1 + **/ +struct asi_txstuffing { + /* Number of K28.5 characters to insert between packet bytes */ + unsigned int ib; + + /* Base number of K28.5 characters to insert between packets, + * not including the two required by ASI */ + unsigned int ip; + + /* Number of packets with (ip) bytes of interpacket stuffing + * per finetuning cycle */ + unsigned int normal_ip; + + /* Number of packets with (ip + 1) bytes of interpacket stuffing + * per finetuning cycle */ + unsigned int big_ip; + + /* Number of packets with (ip) bytes of interpacket stuffing + * per interleaved finetuning cycle */ + unsigned int il_normal; + + /* Number of packets with (ip + 1) bytes of interpacket stuffing + * per interleaved finetuning cycle */ + unsigned int il_big; +}; + +/** + * asi_pcrstamp - PCR - departure time pair + * @adaptation_field_length: adaptation field length + * @adaptation_field_flags: adaptation field flags + * @PCR: a program clock reference + * @count: departure time of this PCR, in 1 / 27 MHz + **/ +struct asi_pcrstamp { + unsigned char adaptation_field_length; + unsigned char adaptation_field_flags; + unsigned char PCR[6]; + long long int count; +}; + +/* Interface capabilities */ +#define ASI_CAP_TX_MAKE204 0x00000004 +#define ASI_CAP_TX_FINETUNING 0x00000008 +#define ASI_CAP_TX_BYTECOUNTER 0x00000010 +#define ASI_CAP_TX_SETCLKSRC 0x00000020 +#define ASI_CAP_TX_FIFOUNDERRUN 0x00000040 +#define ASI_CAP_TX_LARGEIB 0x00000080 +#define ASI_CAP_TX_INTERLEAVING 0x00000100 +#define ASI_CAP_TX_DATA 0x00000200 +#define ASI_CAP_TX_RXCLKSRC 0x00000400 +/* #define ASI_CAP_TX_COMPOSITEREF 0x00000800 */ +#define ASI_CAP_TX_PCRSTAMP 0x00001000 +#define ASI_CAP_TX_CHANGENEXTIP 0x00002000 +#define ASI_CAP_TX_27COUNTER 0x00004000 +#define ASI_CAP_TX_BYTESOR27 0x00008000 +#define ASI_CAP_TX_TIMESTAMPS 0x00010000 +#define ASI_CAP_TX_PTIMESTAMPS 0x00020000 +#define ASI_CAP_TX_NULLPACKETS 0x00040000 + +#define ASI_CAP_RX_SYNC 0x00000004 +#define ASI_CAP_RX_MAKE188 0x00000008 +#define ASI_CAP_RX_BYTECOUNTER 0x00000010 +/* #define ASI_CAP_RX_FIFOSTATUS 0x00000020 */ +#define ASI_CAP_RX_INVSYNC 0x00000040 +#define ASI_CAP_RX_CD 0x00000080 +#define ASI_CAP_RX_DSYNC 0x00000100 +#define ASI_CAP_RX_DATA 0x00000200 +#define ASI_CAP_RX_PIDFILTER 0x00000400 +#define ASI_CAP_RX_PIDCOUNTER 0x00000800 +#define ASI_CAP_RX_4PIDCOUNTER 0x00001000 +#define ASI_CAP_RX_FORCEDMA 0x00002000 +#define ASI_CAP_RX_27COUNTER 0x00004000 +#define ASI_CAP_RX_BYTESOR27 0x00008000 +#define ASI_CAP_RX_TIMESTAMPS 0x00010000 +#define ASI_CAP_RX_PTIMESTAMPS 0x00020000 +#define ASI_CAP_RX_NULLPACKETS 0x00040000 +#define ASI_CAP_RX_REDUNDANT 0x00080000 +#define ASI_CAP_RX_DATA2 0x00100000 + +/* Transmitter clock source settings */ +#define ASI_CTL_TX_CLKSRC_ONBOARD 0 +#define ASI_CTL_TX_CLKSRC_EXT 1 +#define ASI_CTL_TX_CLKSRC_RX 2 +/* #define ASI_CTL_TX_CLKSRC_EXT_PAL 3 */ + +/* Transmitter mode settings */ +#define ASI_CTL_TX_MODE_188 0 +#define ASI_CTL_TX_MODE_204 1 +#define ASI_CTL_TX_MODE_MAKE204 2 + +/* Receiver mode settings */ +#define ASI_CTL_RX_MODE_RAW 0 +#define ASI_CTL_RX_MODE_188 1 +#define ASI_CTL_RX_MODE_204 2 +#define ASI_CTL_RX_MODE_AUTO 3 +#define ASI_CTL_RX_MODE_AUTOMAKE188 4 +#define ASI_CTL_RX_MODE_204MAKE188 5 + +/* Timestamping settings */ +#define ASI_CTL_TSTAMP_NONE 0 +#define ASI_CTL_TSTAMP_APPEND 1 +#define ASI_CTL_TSTAMP_PREPEND 2 + +/* Transport settings */ +#define ASI_CTL_TRANSPORT_DVB_ASI 0 +#define ASI_CTL_TRANSPORT_SMPTE_310M 1 + +#endif + diff --git a/sys/linsys/include/master.h b/sys/linsys/include/master.h new file mode 100644 index 0000000000..1d005c668a --- /dev/null +++ b/sys/linsys/include/master.h @@ -0,0 +1,69 @@ +/* master.h + * + * Global definitions for Linear Systems Ltd. + * digital television-related boards. + * + * Copyright (C) 2004-2009 Linear Systems Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of Linear Systems Ltd. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY LINEAR SYSTEMS LTD. "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL LINEAR SYSTEMS LTD. OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Linear Systems can be contacted at . + * + */ + +#ifndef _MASTER_H +#define _MASTER_H + +#define MASTER_DRIVER_VERSION "2.7.0" +#define MASTER_DRIVER_VERSION_CODE 0x020700 +#define MASTER_DRIVER_DATE "2010-01-11" + +#define MASTER_PCI_VENDOR_ID_LINSYS 0x1254 + +/* Device capabilities */ +#define MASTER_CAP_BYPASS 0x00000001 +#define MASTER_CAP_WATCHDOG 0x00000002 +#define MASTER_CAP_GPI 0x00000004 +#define MASTER_CAP_GPO 0x00000008 +#define MASTER_CAP_UID 0x00000010 +#define MASTER_CAP_BLACKBURST 0x00000020 + +/* Bypass mode settings */ +#define MASTER_CTL_BYPASS_ENABLE 0 +#define MASTER_CTL_BYPASS_DISABLE 1 +#define MASTER_CTL_BYPASS_WATCHDOG 2 + +/* Black burst type settings */ +#define MASTER_CTL_BLACKBURST_NTSC 0 +#define MASTER_CTL_BLACKBURST_PAL 1 + +/* Maximum watchdog timeout in milliseconds. + * Limited to 32 bits at 40 MHz or 27 MHz */ +#define MASTER_WATCHDOG_MAX 100000 + +#endif + diff --git a/sys/linsys/include/sdi.h b/sys/linsys/include/sdi.h new file mode 100644 index 0000000000..659c41847c --- /dev/null +++ b/sys/linsys/include/sdi.h @@ -0,0 +1,115 @@ +/* sdi.h + * + * Shared header file for the Linux user-space API for + * Linear Systems Ltd. SMPTE 259M-C interface boards. + * + * Copyright (C) 2004-2009 Linear Systems Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of Linear Systems Ltd. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY LINEAR SYSTEMS LTD. "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL LINEAR SYSTEMS LTD. OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Linear Systems can be contacted at . + * + */ + +#ifndef _SDI_H +#define _SDI_H + +/* Driver info */ +#define SDI_DRIVER_NAME "sdi" + +#define SDI_MAJOR 121 /* Set to 0 for dynamic allocation. + * Otherwise, 121 is available. + * See /usr/src/linux/Documentation/devices.txt */ + +#define SDI_TX_BUFFERS_MIN 2 /* This must be at least 2 */ +/* The minimum transmit buffer size must be positive, divisible by 4, + * and large enough that the buffers aren't transferred to the onboard FIFOs + * too quickly for the machine to handle the interrupts. + * This is especially a problem at startup, when the FIFOs are empty. + * Relevant factors include onboard FIFO size, PCI bus throughput, + * processor speed, and interrupt latency. */ +#define SDI_TX_BUFSIZE_MIN 1024 +#define SDI_RX_BUFFERS_MIN 2 /* This must be at least 2 */ +#define SDI_RX_BUFSIZE_MIN 8 /* This must be positive and divisible by 4 */ + +#define SDI_TX_BUFFERS 25 /* This must be at least 2 */ +#define SDI_TX_BUFSIZE 1235520 /* This must be positive and divisible by 4 */ +#define SDI_RX_BUFFERS 25 /* This must be at least 2 */ +#define SDI_RX_BUFSIZE 1235520 /* This must be positive and divisible by 4 */ + +/* Ioctl () definitions */ +#define SDI_IOC_MAGIC '=' /* This ioctl magic number is currently free. See + * /usr/src/linux/Documentation/ioctl-number.txt */ + +#define SDI_IOC_TXGETCAP _IOR(SDI_IOC_MAGIC, 1, unsigned int) +#define SDI_IOC_TXGETEVENTS _IOR(SDI_IOC_MAGIC, 2, unsigned int) +#define SDI_IOC_TXGETBUFLEVEL _IOR(SDI_IOC_MAGIC, 3, unsigned int) +#define SDI_IOC_TXGETTXD _IOR(SDI_IOC_MAGIC, 4, int) + +#define SDI_IOC_RXGETCAP _IOR(SDI_IOC_MAGIC, 65, unsigned int) +#define SDI_IOC_RXGETEVENTS _IOR(SDI_IOC_MAGIC, 66, unsigned int) +#define SDI_IOC_RXGETBUFLEVEL _IOR(SDI_IOC_MAGIC, 67, unsigned int) +#define SDI_IOC_RXGETCARRIER _IOR(SDI_IOC_MAGIC, 68, int) +#define SDI_IOC_RXGETSTATUS _IOR(SDI_IOC_MAGIC, 69, int) + +#define SDI_IOC_GETID _IOR(SDI_IOC_MAGIC, 129, unsigned int) +#define SDI_IOC_GETVERSION _IOR(SDI_IOC_MAGIC, 130, unsigned int) +#define SDI_IOC_QBUF_DEPRECATED _IOR(SDI_IOC_MAGIC, 131, unsigned int) +#define SDI_IOC_QBUF _IOW(SDI_IOC_MAGIC, 131, unsigned int) +#define SDI_IOC_DQBUF_DEPRECATED _IOR(SDI_IOC_MAGIC, 132, unsigned int) +#define SDI_IOC_DQBUF _IOW(SDI_IOC_MAGIC, 132, unsigned int) + +/* Transmitter event flag bit locations */ +#define SDI_EVENT_TX_BUFFER_ORDER 0 +#define SDI_EVENT_TX_BUFFER (1 << SDI_EVENT_TX_BUFFER_ORDER) +#define SDI_EVENT_TX_FIFO_ORDER 1 +#define SDI_EVENT_TX_FIFO (1 << SDI_EVENT_TX_FIFO_ORDER) +#define SDI_EVENT_TX_DATA_ORDER 2 +#define SDI_EVENT_TX_DATA (1 << SDI_EVENT_TX_DATA_ORDER) + +/* Receiver event flag bit locations */ +#define SDI_EVENT_RX_BUFFER_ORDER 0 +#define SDI_EVENT_RX_BUFFER (1 << SDI_EVENT_RX_BUFFER_ORDER) +#define SDI_EVENT_RX_FIFO_ORDER 1 +#define SDI_EVENT_RX_FIFO (1 << SDI_EVENT_RX_FIFO_ORDER) +#define SDI_EVENT_RX_CARRIER_ORDER 2 +#define SDI_EVENT_RX_CARRIER (1 << SDI_EVENT_RX_CARRIER_ORDER) + +/* Interface capabilities */ +#define SDI_CAP_TX_RXCLKSRC 0x00000001 + +/* Transmitter clock source settings */ +#define SDI_CTL_TX_CLKSRC_ONBOARD 0 +#define SDI_CTL_TX_CLKSRC_EXT 1 +#define SDI_CTL_TX_CLKSRC_RX 2 + +/* Mode settings */ +#define SDI_CTL_MODE_8BIT 0 +#define SDI_CTL_MODE_10BIT 1 + +#endif + diff --git a/sys/linsys/include/sdiaudio.h b/sys/linsys/include/sdiaudio.h new file mode 100644 index 0000000000..1df6f86eb1 --- /dev/null +++ b/sys/linsys/include/sdiaudio.h @@ -0,0 +1,149 @@ +/* sdiaudio.h + * + * Shared header file for the Linux user-space API for + * Linear Systems Ltd. SMPTE 292M and SMPTE 259M-C Audio interface boards. + * + * Copyright (C) 2009 Linear Systems Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of Linear Systems Ltd. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY LINEAR SYSTEMS LTD. "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL LINEAR SYSTEMS LTD. OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Linear Systems can be contacted at . + * + */ + +#ifndef _SDIAUDIO_H +#define _SDIAUDIO_H + +/* Driver info */ +#define SDIAUDIO_DRIVER_NAME "sdiaudio" + +#define SDIAUDIO_MAJOR 0 /* Set to 0 for dynamic allocation. + * See /usr/src/linux/Documentation/devices.txt */ + +#define SDIAUDIO_TX_BUFFERS_MIN 2 /* This must be at least 2 */ +/* The minimum transmit buffer size must be positive, divisible by 4, + * and large enough that the buffers aren't transferred to the onboard FIFOs + * too quickly for the machine to handle the interrupts. + * This is especially a problem at startup, when the FIFOs are empty. + * Relevant factors include onboard FIFO size, PCI bus throughput, + * processor speed, and interrupt latency. */ +#define SDIAUDIO_TX_BUFSIZE_MIN 1024 +#define SDIAUDIO_RX_BUFFERS_MIN 2 /* This must be at least 2 */ +#define SDIAUDIO_RX_BUFSIZE_MIN 8 /* This must be positive and divisible by 4 */ + +#define SDIAUDIO_TX_BUFFERS 30 /* This must be at least 2 */ +#define SDIAUDIO_TX_BUFSIZE 6400 /* This must be positive and divisible by 4 */ +#define SDIAUDIO_RX_BUFFERS 30 /* This must be at least 2 */ +#define SDIAUDIO_RX_BUFSIZE 6400 /* This must be positive and divisible by 4 */ + +/* Ioctl () definitions */ +#define SDIAUDIO_IOC_MAGIC '~' /* This ioctl magic number is currently free. See + * /usr/src/linux/Documentation/ioctl-number.txt */ + +#define SDIAUDIO_IOC_TXGETCAP _IOR(SDIAUDIO_IOC_MAGIC, 1, unsigned int) +#define SDIAUDIO_IOC_TXGETEVENTS _IOR(SDIAUDIO_IOC_MAGIC, 2, unsigned int) +#define SDIAUDIO_IOC_TXGETBUFLEVEL _IOR(SDIAUDIO_IOC_MAGIC, 3, unsigned int) +#define SDIAUDIO_IOC_TXGETTXD _IOR(SDIAUDIO_IOC_MAGIC, 4, int) + +#define SDIAUDIO_IOC_RXGETCAP _IOR(SDIAUDIO_IOC_MAGIC, 65, unsigned int) +#define SDIAUDIO_IOC_RXGETEVENTS _IOR(SDIAUDIO_IOC_MAGIC, 66, unsigned int) +#define SDIAUDIO_IOC_RXGETBUFLEVEL _IOR(SDIAUDIO_IOC_MAGIC, 67, unsigned int) +#define SDIAUDIO_IOC_RXGETCARRIER _IOR(SDIAUDIO_IOC_MAGIC, 68, int) +#define SDIAUDIO_IOC_RXGETSTATUS _IOR(SDIAUDIO_IOC_MAGIC, 69, int) +#define SDIAUDIO_IOC_RXGETAUDIOGR0ERROR _IOR(SDIAUDIO_IOC_MAGIC, 70, unsigned int) +#define SDIAUDIO_IOC_RXGETAUDIOGR0DELAYA _IOR(SDIAUDIO_IOC_MAGIC, 71, unsigned int) +#define SDIAUDIO_IOC_RXGETAUDIOGR0DELAYB _IOR(SDIAUDIO_IOC_MAGIC, 72, unsigned int) +#define SDIAUDIO_IOC_RXGETNONAUDIO _IOR(SDIAUDIO_IOC_MAGIC, 73, unsigned int) +#define SDIAUDIO_IOC_RXGETAUDSTAT _IOR(SDIAUDIO_IOC_MAGIC, 74, unsigned int) +#define SDIAUDIO_IOC_RXGETAUDRATE _IOR(SDIAUDIO_IOC_MAGIC, 75, unsigned int) + +#define SDIAUDIO_IOC_GETID _IOR(SDIAUDIO_IOC_MAGIC, 129, unsigned int) +#define SDIAUDIO_IOC_GETVERSION _IOR(SDIAUDIO_IOC_MAGIC, 130, unsigned int) +#define SDIAUDIO_IOC_QBUF _IOW(SDIAUDIO_IOC_MAGIC, 131, unsigned int) +#define SDIAUDIO_IOC_DQBUF _IOW(SDIAUDIO_IOC_MAGIC, 132, unsigned int) + +/* Transmitter event flag bit locations */ +#define SDIAUDIO_EVENT_TX_BUFFER_ORDER 0 +#define SDIAUDIO_EVENT_TX_BUFFER (1 << SDIAUDIO_EVENT_TX_BUFFER_ORDER) +#define SDIAUDIO_EVENT_TX_FIFO_ORDER 1 +#define SDIAUDIO_EVENT_TX_FIFO (1 << SDIAUDIO_EVENT_TX_FIFO_ORDER) +#define SDIAUDIO_EVENT_TX_DATA_ORDER 2 +#define SDIAUDIO_EVENT_TX_DATA (1 << SDIAUDIO_EVENT_TX_DATA_ORDER) + +/* Receiver event flag bit locations */ +#define SDIAUDIO_EVENT_RX_BUFFER_ORDER 0 +#define SDIAUDIO_EVENT_RX_BUFFER (1 << SDIAUDIO_EVENT_RX_BUFFER_ORDER) +#define SDIAUDIO_EVENT_RX_FIFO_ORDER 1 +#define SDIAUDIO_EVENT_RX_FIFO (1 << SDIAUDIO_EVENT_RX_FIFO_ORDER) +#define SDIAUDIO_EVENT_RX_CARRIER_ORDER 2 +#define SDIAUDIO_EVENT_RX_CARRIER (1 << SDIAUDIO_EVENT_RX_CARRIER_ORDER) +#define SDIAUDIO_EVENT_RX_DATA_ORDER 3 +#define SDIAUDIO_EVENT_RX_DATA (1 << SDIAUDIO_EVENT_RX_DATA_ORDER) + +/* Interface capabilities */ +#define SDIAUDIO_CAP_RX_CD 0x00000001 +#define SDIAUDIO_CAP_RX_DATA 0x00000002 +#define SDIAUDIO_CAP_RX_STATS 0x00000004 +#define SDIAUDIO_CAP_RX_NONAUDIO 0x00000008 +#define SDIAUDIO_CAP_RX_24BIT 0x00000010 + +/* Audio sample size */ +#define SDIAUDIO_CTL_AUDSAMP_SZ_16 16 /* 16 bit */ +#define SDIAUDIO_CTL_AUDSAMP_SZ_24 24 /* 24 bit */ +#define SDIAUDIO_CTL_AUDSAMP_SZ_32 32 /* 32 bit */ + +/* Audio channel enable */ +#define SDIAUDIO_CTL_AUDCH_EN_0 0 /* 0 channel/disable audio */ +#define SDIAUDIO_CTL_AUDCH_EN_2 2 /* 2 channel */ +#define SDIAUDIO_CTL_AUDCH_EN_4 4 /* 4 channel */ +#define SDIAUDIO_CTL_AUDCH_EN_6 6 /* 6 channel */ +#define SDIAUDIO_CTL_AUDCH_EN_8 8 /* 8 channel */ + +#define SDIAUDIO_CTL_PCM_ALLCHANNEL 0x00000000 /* PCM for channel 1 - 8 */ +#define SDIAUDIO_CTL_NONAUDIO_ALLCHANNEL 0x000000ff /* No audio for channel 1 - 8 */ + +/* Active audio channels status */ +#define SDIAUDIO_CTL_ACT_CHAN_0 0x00 /* no audio control packets */ +#define SDIAUDIO_CTL_ACT_CHAN_2 0x03 /* 2 channels */ +#define SDIAUDIO_CTL_ACT_CHAN_4 0x0f /* 4 channels */ +#define SDIAUDIO_CTL_ACT_CHAN_6 0x3f /* 6 channels */ +#define SDIAUDIO_CTL_ACT_CHAN_8 0xff /* 8 channels */ + +/* Audio rate */ +#define SDIAUDIO_CTL_SYNC_48_KHZ 0 /* Synchronous, 48 kHz */ +#define SDIAUDIO_CTL_SYNC_44_1_KHZ 2 /* Synchronous, 44.1 kHz */ +#define SDIAUDIO_CTL_SYNC_32_KHZ 4 /* Synchronous, 32 kHz */ +#define SDIAUDIO_CTL_SYNC_96_KHZ 8 /* Synchronous, 96 kHz */ +#define SDIAUDIO_CTL_SYNC_FREE_RUNNING 14 /* Synchronous, free running */ +#define SDIAUDIO_CTL_ASYNC_48_KHZ 1 /* Asynchronous, 48 kHz */ +#define SDIAUDIO_CTL_ASYNC_44_1_KHZ 3 /* Asynchronous, 44.1 kHz */ +#define SDIAUDIO_CTL_ASYNC_32_KHZ 5 /* Asynchronous, 32 kHz */ +#define SDIAUDIO_CTL_ASYNC_96_KHZ 9 /* Asynchronous, 96 kHz */ +#define SDIAUDIO_CTL_ASYNC_FREE_RUNNING 15 /* Asynchronous, free running */ + +#endif + diff --git a/sys/linsys/include/sdivideo.h b/sys/linsys/include/sdivideo.h new file mode 100644 index 0000000000..e894f6b999 --- /dev/null +++ b/sys/linsys/include/sdivideo.h @@ -0,0 +1,155 @@ +/* sdivideo.h + * + * Shared header file for the Linux user-space API for + * Linear Systems Ltd. SMPTE 292M and SMPTE 259M-C interface boards. + * + * Copyright (C) 2009-2010 Linear Systems Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of Linear Systems Ltd. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY LINEAR SYSTEMS LTD. "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL LINEAR SYSTEMS LTD. OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Linear Systems can be contacted at . + * + */ + +#ifndef _SDIVIDEO_H +#define _SDIVIDEO_H + +/* Driver info */ +#define SDIVIDEO_DRIVER_NAME "sdivideo" + +#define SDIVIDEO_MAJOR 0 /* Set to 0 for dynamic allocation. + * See /usr/src/linux/Documentation/devices.txt */ + +#define SDIVIDEO_TX_BUFFERS_MIN 2 /* This must be at least 2 */ +/* The minimum transmit buffer size must be positive, divisible by 4, + * and large enough that the buffers aren't transferred to the onboard FIFOs + * too quickly for the machine to handle the interrupts. + * This is especially a problem at startup, when the FIFOs are empty. + * Relevant factors include onboard FIFO size, PCI bus throughput, + * processor speed, and interrupt latency. */ +#define SDIVIDEO_TX_BUFSIZE_MIN 1024 +#define SDIVIDEO_RX_BUFFERS_MIN 2 /* This must be at least 2 */ +#define SDIVIDEO_RX_BUFSIZE_MIN 8 /* This must be positive and divisible by 4 */ + +#define SDIVIDEO_TX_BUFFERS 30 /* This must be at least 2 */ +#define SDIVIDEO_TX_BUFSIZE 1843200 /* This must be positive and divisible by 4 */ +#define SDIVIDEO_RX_BUFFERS 30 /* This must be at least 2 */ +#define SDIVIDEO_RX_BUFSIZE 1843200 /* This must be positive and divisible by 4 */ + +/* Ioctl () definitions */ +#define SDIVIDEO_IOC_MAGIC '=' /* This ioctl magic number is currently free. See + * /usr/src/linux/Documentation/ioctl-number.txt */ + +#define SDIVIDEO_IOC_TXGETCAP _IOR(SDIVIDEO_IOC_MAGIC, 1, unsigned int) +#define SDIVIDEO_IOC_TXGETEVENTS _IOR(SDIVIDEO_IOC_MAGIC, 2, unsigned int) +#define SDIVIDEO_IOC_TXGETBUFLEVEL _IOR(SDIVIDEO_IOC_MAGIC, 3, unsigned int) +#define SDIVIDEO_IOC_TXGETTXD _IOR(SDIVIDEO_IOC_MAGIC, 4, int) + +#define SDIVIDEO_IOC_RXGETCAP _IOR(SDIVIDEO_IOC_MAGIC, 65, unsigned int) +#define SDIVIDEO_IOC_RXGETEVENTS _IOR(SDIVIDEO_IOC_MAGIC, 66, unsigned int) +#define SDIVIDEO_IOC_RXGETBUFLEVEL _IOR(SDIVIDEO_IOC_MAGIC, 67, unsigned int) +#define SDIVIDEO_IOC_RXGETCARRIER _IOR(SDIVIDEO_IOC_MAGIC, 68, int) +#define SDIVIDEO_IOC_RXGETSTATUS _IOR(SDIVIDEO_IOC_MAGIC, 69, int) +#define SDIVIDEO_IOC_RXGETYCRCERROR _IOR(SDIVIDEO_IOC_MAGIC, 70, unsigned int) +#define SDIVIDEO_IOC_RXGETCCRCERROR _IOR(SDIVIDEO_IOC_MAGIC, 71, unsigned int) +#define SDIVIDEO_IOC_RXGETVIDSTATUS _IOR(SDIVIDEO_IOC_MAGIC, 72, unsigned int) + +#define SDIVIDEO_IOC_GETID _IOR(SDIVIDEO_IOC_MAGIC, 129, unsigned int) +#define SDIVIDEO_IOC_GETVERSION _IOR(SDIVIDEO_IOC_MAGIC, 130, unsigned int) +#define SDIVIDEO_IOC_QBUF _IOW(SDIVIDEO_IOC_MAGIC, 131, unsigned int) +#define SDIVIDEO_IOC_DQBUF _IOW(SDIVIDEO_IOC_MAGIC, 132, unsigned int) + +/* Transmitter event flag bit locations */ +#define SDIVIDEO_EVENT_TX_BUFFER_ORDER 0 +#define SDIVIDEO_EVENT_TX_BUFFER (1 << SDIVIDEO_EVENT_TX_BUFFER_ORDER) +#define SDIVIDEO_EVENT_TX_FIFO_ORDER 1 +#define SDIVIDEO_EVENT_TX_FIFO (1 << SDIVIDEO_EVENT_TX_FIFO_ORDER) +#define SDIVIDEO_EVENT_TX_DATA_ORDER 2 +#define SDIVIDEO_EVENT_TX_DATA (1 << SDIVIDEO_EVENT_TX_DATA_ORDER) + +/* Receiver event flag bit locations */ +#define SDIVIDEO_EVENT_RX_BUFFER_ORDER 0 +#define SDIVIDEO_EVENT_RX_BUFFER (1 << SDIVIDEO_EVENT_RX_BUFFER_ORDER) +#define SDIVIDEO_EVENT_RX_FIFO_ORDER 1 +#define SDIVIDEO_EVENT_RX_FIFO (1 << SDIVIDEO_EVENT_RX_FIFO_ORDER) +#define SDIVIDEO_EVENT_RX_CARRIER_ORDER 2 +#define SDIVIDEO_EVENT_RX_CARRIER (1 << SDIVIDEO_EVENT_RX_CARRIER_ORDER) +#define SDIVIDEO_EVENT_RX_DATA_ORDER 3 +#define SDIVIDEO_EVENT_RX_DATA (1 << SDIVIDEO_EVENT_RX_DATA_ORDER) + +/* Interface capabilities */ +#define SDIVIDEO_CAP_RX_CD 0x00000001 +#define SDIVIDEO_CAP_RX_DATA 0x00000002 +#define SDIVIDEO_CAP_RX_ERR_COUNT 0x00000004 +#define SDIVIDEO_CAP_RX_VBI 0x00000008 +#define SDIVIDEO_CAP_RX_RAWMODE 0x00000010 +#define SDIVIDEO_CAP_RX_DEINTERLACING 0x00000020 + +/* Transmitter clock source settings */ +#define SDIVIDEO_CTL_TX_CLKSRC_ONBOARD 0 +#define SDIVIDEO_CTL_TX_CLKSRC_NTSC 1 +#define SDIVIDEO_CTL_TX_CLKSRC_PAL 2 + +/* Mode settings */ +#define SDIVIDEO_CTL_MODE_UYVY 0 +#define SDIVIDEO_CTL_MODE_V210 1 +#define SDIVIDEO_CTL_MODE_V210_DEINTERLACE 2 +#define SDIVIDEO_CTL_MODE_RAW 3 + +/* Frame mode settings */ +#define SDIVIDEO_CTL_UNLOCKED 0 +#define SDIVIDEO_CTL_SMPTE_125M_486I_29_97HZ 1 +#define SDIVIDEO_CTL_BT_601_576I_25HZ 2 +#define SDIVIDEO_CTL_SMPTE_267M_486I_29_97HZ 3 + +#define SDIVIDEO_CTL_SMPTE_260M_1035I_30HZ 5 +#define SDIVIDEO_CTL_SMPTE_260M_1035I_29_97HZ 6 +#define SDIVIDEO_CTL_SMPTE_295M_1080I_25HZ 7 +#define SDIVIDEO_CTL_SMPTE_274M_1080I_30HZ 8 +#define SDIVIDEO_CTL_SMPTE_274M_1080PSF_30HZ 9 +#define SDIVIDEO_CTL_SMPTE_274M_1080I_29_97HZ 10 +#define SDIVIDEO_CTL_SMPTE_274M_1080PSF_29_97HZ 11 +#define SDIVIDEO_CTL_SMPTE_274M_1080I_25HZ 12 +#define SDIVIDEO_CTL_SMPTE_274M_1080PSF_25HZ 13 +#define SDIVIDEO_CTL_SMPTE_274M_1080PSF_24HZ 14 +#define SDIVIDEO_CTL_SMPTE_274M_1080PSF_23_98HZ 15 +#define SDIVIDEO_CTL_SMPTE_274M_1080P_30HZ 16 +#define SDIVIDEO_CTL_SMPTE_274M_1080P_29_97HZ 17 +#define SDIVIDEO_CTL_SMPTE_274M_1080P_25HZ 18 +#define SDIVIDEO_CTL_SMPTE_274M_1080P_24HZ 19 +#define SDIVIDEO_CTL_SMPTE_274M_1080P_23_98HZ 20 +#define SDIVIDEO_CTL_SMPTE_296M_720P_60HZ 21 +#define SDIVIDEO_CTL_SMPTE_296M_720P_59_94HZ 22 +#define SDIVIDEO_CTL_SMPTE_296M_720P_50HZ 23 +#define SDIVIDEO_CTL_SMPTE_296M_720P_30HZ 24 +#define SDIVIDEO_CTL_SMPTE_296M_720P_29_97HZ 25 +#define SDIVIDEO_CTL_SMPTE_296M_720P_25HZ 26 +#define SDIVIDEO_CTL_SMPTE_296M_720P_24HZ 27 +#define SDIVIDEO_CTL_SMPTE_296M_720P_23_98HZ 28 + +#endif +