mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-17 13:56:32 +00:00
vcdsrc: Remove unusable VCD source
The VCD source was ported in 2014 (commit 89eb1e9
), but the necessary
"cdxaparse" plugin, which is used to "Parse a .dat file (VCD) into
raw mpeg1" was never ported.
This means that the probable main user for the feature, totem, hasn't
actually been able to play back VCDs, since 2012, when it switched to
using GStreamer 1.0.
Note that even if cdxaparse was finally ported, a lot of work would
still be necessary before it is considered usable. Notably, it is
missing disc image support [1] and some VCDs just cannot be opened for
reading [2].
[1]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/898
[2]: https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/899
This commit is contained in:
parent
81fd48bcb5
commit
2d5ed45913
12 changed files with 3 additions and 757 deletions
|
@ -888,12 +888,6 @@ AG_GST_CHECK_FEATURE(IPCPIPELINE, [Unix sockets], ipcpipeline, [
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl check for Video CD
|
|
||||||
translit(dnm, m, l) AM_CONDITIONAL(USE_VCD, true)
|
|
||||||
AG_GST_CHECK_FEATURE(VCD, [Video CD], vcdsrc, [
|
|
||||||
AC_CHECK_HEADER(linux/cdrom.h, HAVE_VCD="yes", HAVE_VCD="no")
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl check for OpenSL ES
|
dnl check for OpenSL ES
|
||||||
translit(dnm, m, l) AM_CONDITIONAL(USE_OPENSLES, true)
|
translit(dnm, m, l) AM_CONDITIONAL(USE_OPENSLES, true)
|
||||||
AG_GST_CHECK_FEATURE(OPENSLES, [OpenSL ES], opensl, [
|
AG_GST_CHECK_FEATURE(OPENSLES, [OpenSL ES], opensl, [
|
||||||
|
@ -2611,7 +2605,6 @@ sys/opensles/Makefile
|
||||||
sys/shm/Makefile
|
sys/shm/Makefile
|
||||||
sys/tinyalsa/Makefile
|
sys/tinyalsa/Makefile
|
||||||
sys/uvch264/Makefile
|
sys/uvch264/Makefile
|
||||||
sys/vcd/Makefile
|
|
||||||
sys/vdpau/Makefile
|
sys/vdpau/Makefile
|
||||||
sys/wasapi/Makefile
|
sys/wasapi/Makefile
|
||||||
sys/winks/Makefile
|
sys/winks/Makefile
|
||||||
|
|
|
@ -248,7 +248,6 @@
|
||||||
<xi:include href="xml/element-uvch264mjpgdemux.xml" />
|
<xi:include href="xml/element-uvch264mjpgdemux.xml" />
|
||||||
<xi:include href="xml/element-uvch264src.xml" />
|
<xi:include href="xml/element-uvch264src.xml" />
|
||||||
<xi:include href="xml/element-vc1parse.xml" />
|
<xi:include href="xml/element-vc1parse.xml" />
|
||||||
<xi:include href="xml/element-vcdsrc.xml" />
|
|
||||||
<xi:include href="xml/element-vdpaumpegdec.xml" />
|
<xi:include href="xml/element-vdpaumpegdec.xml" />
|
||||||
<xi:include href="xml/element-videoanalyse.xml" />
|
<xi:include href="xml/element-videoanalyse.xml" />
|
||||||
<xi:include href="xml/element-videodiff.xml" />
|
<xi:include href="xml/element-videodiff.xml" />
|
||||||
|
@ -393,7 +392,6 @@
|
||||||
<xi:include href="xml/plugin-timecode.xml" />
|
<xi:include href="xml/plugin-timecode.xml" />
|
||||||
<xi:include href="xml/plugin-ttmlsubs.xml" />
|
<xi:include href="xml/plugin-ttmlsubs.xml" />
|
||||||
<xi:include href="xml/plugin-uvch264.xml" />
|
<xi:include href="xml/plugin-uvch264.xml" />
|
||||||
<xi:include href="xml/plugin-vcdsrc.xml" />
|
|
||||||
<xi:include href="xml/plugin-vdpau.xml" />
|
<xi:include href="xml/plugin-vdpau.xml" />
|
||||||
<xi:include href="xml/plugin-videofiltersbad.xml" />
|
<xi:include href="xml/plugin-videofiltersbad.xml" />
|
||||||
<xi:include href="xml/plugin-videoframe_audiolevel.xml" />
|
<xi:include href="xml/plugin-videoframe_audiolevel.xml" />
|
||||||
|
|
|
@ -3628,22 +3628,6 @@ GST_TYPE_V_C1_PARSE
|
||||||
gst_v_c1_parse_get_type
|
gst_v_c1_parse_get_type
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
|
||||||
<FILE>element-vcdsrc</FILE>
|
|
||||||
<TITLE>vcdsrc</TITLE>
|
|
||||||
GstVCDSrc
|
|
||||||
<SUBSECTION Standard>
|
|
||||||
GstVCDSrcClass
|
|
||||||
GST_VCD_SRC
|
|
||||||
GST_VCD_SRC_CAST
|
|
||||||
GST_IS_VCD_SRC
|
|
||||||
GST_VCD_SRC_CLASS
|
|
||||||
GST_IS_VCD_SRC_CLASS
|
|
||||||
GST_TYPE_VCD_SRC
|
|
||||||
<SUBSECTION Private>
|
|
||||||
gst_vcd_src_get_type
|
|
||||||
</SECTION>
|
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>element-vmncdec</FILE>
|
<FILE>element-vmncdec</FILE>
|
||||||
<TITLE>vmncdec</TITLE>
|
<TITLE>vmncdec</TITLE>
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
<plugin>
|
|
||||||
<name>vcdsrc</name>
|
|
||||||
<description>Asynchronous read from VCD disk</description>
|
|
||||||
<filename>../../sys/vcd/.libs/libgstvcdsrc.so</filename>
|
|
||||||
<basename>libgstvcdsrc.so</basename>
|
|
||||||
<version>1.15.1</version>
|
|
||||||
<license>LGPL</license>
|
|
||||||
<source>gst-plugins-bad</source>
|
|
||||||
<package>GStreamer Bad Plug-ins source release</package>
|
|
||||||
<origin>Unknown package origin</origin>
|
|
||||||
<elements>
|
|
||||||
<element>
|
|
||||||
<name>vcdsrc</name>
|
|
||||||
<longname>VCD Source</longname>
|
|
||||||
<class>Source/File</class>
|
|
||||||
<description>Asynchronous read from VCD disk</description>
|
|
||||||
<author>Erik Walthinsen <omega@cse.ogi.edu></author>
|
|
||||||
<pads>
|
|
||||||
<caps>
|
|
||||||
<name>src</name>
|
|
||||||
<direction>source</direction>
|
|
||||||
<presence>always</presence>
|
|
||||||
<details>ANY</details>
|
|
||||||
</caps>
|
|
||||||
</pads>
|
|
||||||
</element>
|
|
||||||
</elements>
|
|
||||||
</plugin>
|
|
|
@ -141,7 +141,6 @@ option('teletext', type : 'feature', value : 'auto', description : 'Teletext plu
|
||||||
option('tinyalsa', type : 'feature', value : 'auto', description : 'TinyALSA plugin')
|
option('tinyalsa', type : 'feature', value : 'auto', description : 'TinyALSA plugin')
|
||||||
option('ttml', type : 'feature', value : 'auto', description : 'TTML subtitle parser and renderer plugin')
|
option('ttml', type : 'feature', value : 'auto', description : 'TTML subtitle parser and renderer plugin')
|
||||||
option('uvch264', type : 'feature', value : 'auto', description : 'UVC compliant H.264 camera source plugin')
|
option('uvch264', type : 'feature', value : 'auto', description : 'UVC compliant H.264 camera source plugin')
|
||||||
option('vcd', type : 'feature', value : 'auto', description : 'VCD source plugin')
|
|
||||||
option('vdpau', type : 'feature', value : 'auto', description : 'Nvidia VDPAU plugin')
|
option('vdpau', type : 'feature', value : 'auto', description : 'Nvidia VDPAU plugin')
|
||||||
option('voaacenc', type : 'feature', value : 'auto', description : 'AAC audio encoder plugin')
|
option('voaacenc', type : 'feature', value : 'auto', description : 'AAC audio encoder plugin')
|
||||||
option('voamrwbenc', type : 'feature', value : 'auto', description : 'AMR-WB audio encoder plugin')
|
option('voamrwbenc', type : 'feature', value : 'auto', description : 'AMR-WB audio encoder plugin')
|
||||||
|
|
|
@ -82,12 +82,6 @@ else
|
||||||
OPENSLES_DIR=
|
OPENSLES_DIR=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if USE_VCD
|
|
||||||
VCD_DIR=vcd
|
|
||||||
else
|
|
||||||
VCD_DIR=
|
|
||||||
endif
|
|
||||||
|
|
||||||
if USE_VDPAU
|
if USE_VDPAU
|
||||||
VDPAU_DIR=vdpau
|
VDPAU_DIR=vdpau
|
||||||
else
|
else
|
||||||
|
@ -130,10 +124,10 @@ else
|
||||||
MSDK_DIR=
|
MSDK_DIR=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SUBDIRS = $(ANDROID_MEDIA_DIR) $(APPLE_MEDIA_DIR) $(BLUEZ_DIR) $(D3DVIDEOSINK_DIR) $(DECKLINK_DIR) $(DIRECTSOUND_DIR) $(WINKS_DIR) $(DVB_DIR) $(FBDEV_DIR) $(IPCPIPELINE_DIR) $(KMS_DIR) $(OPENSLES_DIR) $(SHM_DIR) $(UVCH264_DIR) $(VCD_DIR) $(VDPAU_DIR) $(WININET_DIR) $(WINSCREENCAP_DIR) $(WASAPI_DIR) $(NVDEC_DIR) $(NVENC_DIR) $(TINYALSA_DIR) $(MSDK_DIR)
|
SUBDIRS = $(ANDROID_MEDIA_DIR) $(APPLE_MEDIA_DIR) $(BLUEZ_DIR) $(D3DVIDEOSINK_DIR) $(DECKLINK_DIR) $(DIRECTSOUND_DIR) $(WINKS_DIR) $(DVB_DIR) $(FBDEV_DIR) $(IPCPIPELINE_DIR) $(KMS_DIR) $(OPENSLES_DIR) $(SHM_DIR) $(UVCH264_DIR) $(VDPAU_DIR) $(WININET_DIR) $(WINSCREENCAP_DIR) $(WASAPI_DIR) $(NVDEC_DIR) $(NVENC_DIR) $(TINYALSA_DIR) $(MSDK_DIR)
|
||||||
|
|
||||||
DIST_SUBDIRS = androidmedia applemedia bluez d3dvideosink decklink directsound dvb fbdev ipcpipeline kms dshowdecwrapper dshowsrcwrapper dshowvideosink \
|
DIST_SUBDIRS = androidmedia applemedia bluez d3dvideosink decklink directsound dvb fbdev ipcpipeline kms dshowdecwrapper dshowsrcwrapper dshowvideosink \
|
||||||
opensles shm uvch264 vcd vdpau wasapi winks winscreencap \
|
opensles shm uvch264 vdpau wasapi winks winscreencap \
|
||||||
nvdec nvenc tinyalsa msdk
|
nvdec nvenc tinyalsa msdk
|
||||||
|
|
||||||
include $(top_srcdir)/common/parallel-subdirs.mak
|
include $(top_srcdir)/common/parallel-subdirs.mak
|
||||||
|
|
|
@ -16,7 +16,6 @@ subdir('opensles')
|
||||||
subdir('shm')
|
subdir('shm')
|
||||||
subdir('tinyalsa')
|
subdir('tinyalsa')
|
||||||
subdir('uvch264')
|
subdir('uvch264')
|
||||||
subdir('vcd')
|
|
||||||
subdir('vdpau')
|
subdir('vdpau')
|
||||||
subdir('wasapi')
|
subdir('wasapi')
|
||||||
subdir('winks')
|
subdir('winks')
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
|
|
||||||
plugin_LTLIBRARIES = libgstvcdsrc.la
|
|
||||||
|
|
||||||
libgstvcdsrc_la_SOURCES = vcdsrc.c
|
|
||||||
libgstvcdsrc_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
|
|
||||||
libgstvcdsrc_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS)
|
|
||||||
libgstvcdsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
|
||||||
|
|
||||||
noinst_HEADERS = vcdsrc.h
|
|
|
@ -1,16 +0,0 @@
|
||||||
if get_option('vcd').disabled()
|
|
||||||
subdir_done()
|
|
||||||
endif
|
|
||||||
|
|
||||||
if cc.has_header ('linux/cdrom.h')
|
|
||||||
gstvcd = library('gstvcdsrc', 'vcdsrc.c',
|
|
||||||
c_args: gst_plugins_bad_args,
|
|
||||||
include_directories: [configinc],
|
|
||||||
dependencies : [gstbase_dep],
|
|
||||||
install: true,
|
|
||||||
install_dir: plugins_install_dir
|
|
||||||
)
|
|
||||||
pkgconfig.generate(gstvcd, install_dir: plugins_pkgconfig_install_dir)
|
|
||||||
elif get_option('vcd').enabled()
|
|
||||||
error('vcd plugin enabled but linux/cdrom.h not found')
|
|
||||||
endif
|
|
592
sys/vcd/vcdsrc.c
592
sys/vcd/vcdsrc.c
|
@ -1,592 +0,0 @@
|
||||||
/* GStreamer
|
|
||||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
|
||||||
*
|
|
||||||
* 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., 51 Franklin St, Fifth Floor,
|
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "vcdsrc.h"
|
|
||||||
|
|
||||||
#define DEFAULT_DEVICE "/dev/cdrom"
|
|
||||||
|
|
||||||
/* VCDSrc signals and args */
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
/* FILL ME */
|
|
||||||
LAST_SIGNAL
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
PROP_0,
|
|
||||||
PROP_DEVICE,
|
|
||||||
PROP_TRACK,
|
|
||||||
PROP_MAX_ERRORS
|
|
||||||
};
|
|
||||||
|
|
||||||
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
|
|
||||||
GST_PAD_SRC,
|
|
||||||
GST_PAD_ALWAYS,
|
|
||||||
GST_STATIC_CAPS_ANY);
|
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_vcdsrc_debug);
|
|
||||||
#define GST_CAT_DEFAULT gst_vcdsrc_debug
|
|
||||||
|
|
||||||
static void gst_vcdsrc_uri_handler_init (gpointer g_iface, gpointer iface_data);
|
|
||||||
#define gst_vcdsrc_parent_class parent_class
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GstVCDSrc, gst_vcdsrc, GST_TYPE_PUSH_SRC,
|
|
||||||
G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, gst_vcdsrc_uri_handler_init));
|
|
||||||
|
|
||||||
static void gst_vcdsrc_finalize (GObject * object);
|
|
||||||
|
|
||||||
static void gst_vcdsrc_set_property (GObject * object, guint prop_id,
|
|
||||||
const GValue * value, GParamSpec * pspec);
|
|
||||||
static void gst_vcdsrc_get_property (GObject * object, guint prop_id,
|
|
||||||
GValue * value, GParamSpec * pspec);
|
|
||||||
|
|
||||||
static gboolean gst_vcdsrc_start (GstBaseSrc * src);
|
|
||||||
static gboolean gst_vcdsrc_stop (GstBaseSrc * src);
|
|
||||||
static GstFlowReturn gst_vcdsrc_create (GstPushSrc * src, GstBuffer ** out);
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vcdsrc_class_init (GstVCDSrcClass * klass)
|
|
||||||
{
|
|
||||||
GObjectClass *gobject_class;
|
|
||||||
GstElementClass *element_class;
|
|
||||||
GstBaseSrcClass *basesrc_class;
|
|
||||||
GstPushSrcClass *pushsrc_class;
|
|
||||||
|
|
||||||
gobject_class = (GObjectClass *) klass;
|
|
||||||
basesrc_class = (GstBaseSrcClass *) klass;
|
|
||||||
pushsrc_class = (GstPushSrcClass *) klass;
|
|
||||||
element_class = (GstElementClass *) klass;
|
|
||||||
|
|
||||||
gobject_class->set_property = gst_vcdsrc_set_property;
|
|
||||||
gobject_class->get_property = gst_vcdsrc_get_property;
|
|
||||||
gobject_class->finalize = gst_vcdsrc_finalize;
|
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, PROP_DEVICE,
|
|
||||||
g_param_spec_string ("device", "Device",
|
|
||||||
"CD device location", NULL, G_PARAM_READWRITE));
|
|
||||||
g_object_class_install_property (gobject_class, PROP_TRACK,
|
|
||||||
g_param_spec_int ("track", "Track",
|
|
||||||
"Track number to play", G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
|
|
||||||
g_object_class_install_property (gobject_class, PROP_MAX_ERRORS,
|
|
||||||
g_param_spec_int ("max-errors", "Max. errors",
|
|
||||||
"Maximum number of errors before bailing out",
|
|
||||||
0, G_MAXINT, 16, G_PARAM_READWRITE));
|
|
||||||
|
|
||||||
basesrc_class->start = gst_vcdsrc_start;
|
|
||||||
basesrc_class->stop = gst_vcdsrc_stop;
|
|
||||||
|
|
||||||
pushsrc_class->create = gst_vcdsrc_create;
|
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_vcdsrc_debug, "vcdsrc", 0,
|
|
||||||
"VideoCD Source element");
|
|
||||||
|
|
||||||
gst_element_class_set_static_metadata (element_class, "VCD Source",
|
|
||||||
"Source/File",
|
|
||||||
"Asynchronous read from VCD disk", "Erik Walthinsen <omega@cse.ogi.edu>");
|
|
||||||
|
|
||||||
gst_element_class_add_static_pad_template (element_class, &srctemplate);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vcdsrc_init (GstVCDSrc * vcdsrc)
|
|
||||||
{
|
|
||||||
vcdsrc->device = g_strdup (DEFAULT_DEVICE);
|
|
||||||
vcdsrc->track = 1;
|
|
||||||
vcdsrc->fd = 0;
|
|
||||||
vcdsrc->trackoffset = 0;
|
|
||||||
vcdsrc->curoffset = 0;
|
|
||||||
vcdsrc->bytes_per_read = VCD_BYTES_PER_SECTOR;
|
|
||||||
vcdsrc->max_errors = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vcdsrc_finalize (GObject * object)
|
|
||||||
{
|
|
||||||
GstVCDSrc *vcdsrc = GST_VCDSRC (object);
|
|
||||||
|
|
||||||
g_free (vcdsrc->device);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline guint64
|
|
||||||
gst_vcdsrc_msf (GstVCDSrc * vcdsrc, gint track)
|
|
||||||
{
|
|
||||||
return (vcdsrc->tracks[track].cdte_addr.msf.minute * 60 +
|
|
||||||
vcdsrc->tracks[track].cdte_addr.msf.second) * 75 +
|
|
||||||
vcdsrc->tracks[track].cdte_addr.msf.frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vcdsrc_recalculate (GstVCDSrc * vcdsrc)
|
|
||||||
{
|
|
||||||
/* calculate track offset (beginning of track) */
|
|
||||||
vcdsrc->trackoffset = gst_vcdsrc_msf (vcdsrc, vcdsrc->track);
|
|
||||||
GST_DEBUG ("track offset is %ld", vcdsrc->trackoffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vcdsrc_set_property (GObject * object, guint prop_id, const GValue * value,
|
|
||||||
GParamSpec * pspec)
|
|
||||||
{
|
|
||||||
GstVCDSrc *src;
|
|
||||||
|
|
||||||
src = GST_VCDSRC (object);
|
|
||||||
|
|
||||||
switch (prop_id) {
|
|
||||||
case PROP_DEVICE:
|
|
||||||
g_free (src->device);
|
|
||||||
src->device = g_value_dup_string (value);
|
|
||||||
break;
|
|
||||||
case PROP_TRACK:
|
|
||||||
if (g_value_get_int (value) >= 1 &&
|
|
||||||
g_value_get_int (value) < src->numtracks) {
|
|
||||||
src->track = g_value_get_int (value);
|
|
||||||
gst_vcdsrc_recalculate (src);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PROP_MAX_ERRORS:
|
|
||||||
src->max_errors = g_value_get_int (value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vcdsrc_get_property (GObject * object, guint prop_id, GValue * value,
|
|
||||||
GParamSpec * pspec)
|
|
||||||
{
|
|
||||||
GstVCDSrc *src;
|
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_VCDSRC (object));
|
|
||||||
src = GST_VCDSRC (object);
|
|
||||||
|
|
||||||
switch (prop_id) {
|
|
||||||
case PROP_DEVICE:
|
|
||||||
g_value_set_string (value, src->device);
|
|
||||||
break;
|
|
||||||
case PROP_TRACK:
|
|
||||||
g_value_set_int (value, src->track);
|
|
||||||
break;
|
|
||||||
case PROP_MAX_ERRORS:
|
|
||||||
g_value_set_int (value, src->max_errors);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static gboolean
|
|
||||||
gst_vcdsrc_srcpad_event (GstPad * pad, GstEvent * event)
|
|
||||||
{
|
|
||||||
GstVCDSrc *vcdsrc = GST_VCDSRC (gst_pad_get_parent (pad));
|
|
||||||
gboolean res = TRUE;
|
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
|
||||||
case GST_EVENT_SEEK:{
|
|
||||||
gint64 new_off;
|
|
||||||
|
|
||||||
if (GST_EVENT_SEEK_FORMAT (event) != GST_FORMAT_BYTES)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
new_off = GST_EVENT_SEEK_OFFSET (event);
|
|
||||||
switch (GST_EVENT_SEEK_METHOD (event)) {
|
|
||||||
case GST_SEEK_METHOD_SET:
|
|
||||||
/* no-op */
|
|
||||||
break;
|
|
||||||
case GST_SEEK_METHOD_CUR:
|
|
||||||
new_off += vcdsrc->curoffset * vcdsrc->bytes_per_read;
|
|
||||||
break;
|
|
||||||
case GST_SEEK_METHOD_END:
|
|
||||||
new_off = (gst_vcdsrc_msf (vcdsrc, vcdsrc->track + 1) -
|
|
||||||
vcdsrc->trackoffset) * vcdsrc->bytes_per_read - new_off;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_off < 0 ||
|
|
||||||
new_off > (gst_vcdsrc_msf (vcdsrc, vcdsrc->track + 1) -
|
|
||||||
vcdsrc->trackoffset) * vcdsrc->bytes_per_read)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
vcdsrc->curoffset = new_off / vcdsrc->bytes_per_read;
|
|
||||||
vcdsrc->tempoffset = new_off % vcdsrc->bytes_per_read;
|
|
||||||
vcdsrc->discont = TRUE;
|
|
||||||
if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH)
|
|
||||||
vcdsrc->flush = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
res = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_event_unref (event);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static gboolean
|
|
||||||
gst_vcdsrc_srcpad_query (GstPad * pad, GstQueryType type,
|
|
||||||
GstFormat * format, gint64 * value)
|
|
||||||
{
|
|
||||||
GstVCDSrc *vcdsrc = GST_VCDSRC (gst_pad_get_parent (pad));
|
|
||||||
gboolean res = TRUE;
|
|
||||||
|
|
||||||
if (*format != GST_FORMAT_BYTES)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case GST_QUERY_TOTAL:
|
|
||||||
*value = (gst_vcdsrc_msf (vcdsrc, vcdsrc->track + 1) -
|
|
||||||
vcdsrc->trackoffset) * vcdsrc->bytes_per_read;
|
|
||||||
break;
|
|
||||||
case GST_QUERY_POSITION:
|
|
||||||
*value = vcdsrc->curoffset * vcdsrc->bytes_per_read;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
res = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static GstFlowReturn
|
|
||||||
gst_vcdsrc_create (GstPushSrc * src, GstBuffer ** buf)
|
|
||||||
{
|
|
||||||
GstVCDSrc *vcdsrc;
|
|
||||||
GstBuffer *outbuf;
|
|
||||||
GstMapInfo map_info;
|
|
||||||
gulong offset;
|
|
||||||
struct cdrom_msf *msf;
|
|
||||||
gint error_count = 0;
|
|
||||||
|
|
||||||
vcdsrc = GST_VCDSRC (src);
|
|
||||||
|
|
||||||
offset = vcdsrc->trackoffset + vcdsrc->curoffset;
|
|
||||||
if (offset >= gst_vcdsrc_msf (vcdsrc, vcdsrc->track + 1))
|
|
||||||
goto eos;
|
|
||||||
|
|
||||||
/* create the buffer */
|
|
||||||
outbuf = gst_buffer_new_allocate (NULL, vcdsrc->bytes_per_read, NULL);
|
|
||||||
if (!outbuf)
|
|
||||||
goto error_unmapped;
|
|
||||||
|
|
||||||
if (!gst_buffer_map (outbuf, &map_info, GST_MAP_READWRITE))
|
|
||||||
goto error_unmapped;
|
|
||||||
|
|
||||||
msf = (struct cdrom_msf *) map_info.data;
|
|
||||||
|
|
||||||
|
|
||||||
read:
|
|
||||||
/* read it in from the device */
|
|
||||||
msf->cdmsf_frame0 = offset % 75;
|
|
||||||
msf->cdmsf_sec0 = (offset / 75) % 60;
|
|
||||||
msf->cdmsf_min0 = (offset / (75 * 60));
|
|
||||||
|
|
||||||
GST_LOG ("msf is %d:%d:%d", msf->cdmsf_min0, msf->cdmsf_sec0,
|
|
||||||
msf->cdmsf_frame0);
|
|
||||||
|
|
||||||
if (ioctl (vcdsrc->fd, CDROMREADRAW, msf) < 0) {
|
|
||||||
if (++error_count <= vcdsrc->max_errors) {
|
|
||||||
vcdsrc->curoffset++;
|
|
||||||
offset++;
|
|
||||||
goto read;
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_ELEMENT_ERROR (vcdsrc, RESOURCE, READ, (NULL),
|
|
||||||
("Read from cdrom at %d:%d:%d failed: %s",
|
|
||||||
msf->cdmsf_min0, msf->cdmsf_sec0, msf->cdmsf_frame0,
|
|
||||||
strerror (errno)));
|
|
||||||
goto error_mapped;
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_buffer_unmap (outbuf, &map_info);
|
|
||||||
vcdsrc->curoffset += 1;
|
|
||||||
|
|
||||||
*buf = outbuf;
|
|
||||||
return GST_FLOW_OK;
|
|
||||||
|
|
||||||
/* ERRORS */
|
|
||||||
error_mapped:
|
|
||||||
gst_buffer_unmap (outbuf, &map_info);
|
|
||||||
error_unmapped:
|
|
||||||
if (outbuf)
|
|
||||||
gst_buffer_unref (outbuf);
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
eos:
|
|
||||||
{
|
|
||||||
GST_DEBUG_OBJECT (vcdsrc, "got eos");
|
|
||||||
return GST_FLOW_EOS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* open the file, necessary to go to RUNNING state */
|
|
||||||
static gboolean
|
|
||||||
gst_vcdsrc_start (GstBaseSrc * bsrc)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
GstVCDSrc *src = GST_VCDSRC (bsrc);
|
|
||||||
struct stat buf;
|
|
||||||
|
|
||||||
/* open the device */
|
|
||||||
src->fd = open (src->device, O_RDONLY);
|
|
||||||
if (src->fd < 0)
|
|
||||||
goto open_failed;
|
|
||||||
|
|
||||||
if (fstat (src->fd, &buf) < 0)
|
|
||||||
goto toc_failed;
|
|
||||||
/* If it's not a block device, then we need to try and
|
|
||||||
* parse the cue file if there is one
|
|
||||||
* FIXME implement */
|
|
||||||
if (!S_ISBLK (buf.st_mode)) {
|
|
||||||
GST_DEBUG ("Reading CUE files not handled yet, cannot process %s",
|
|
||||||
GST_STR_NULL (src->device));
|
|
||||||
goto toc_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read the table of contents */
|
|
||||||
if (ioctl (src->fd, CDROMREADTOCHDR, &src->tochdr))
|
|
||||||
goto toc_failed;
|
|
||||||
|
|
||||||
/* allocate enough track structs for disk */
|
|
||||||
src->numtracks = (src->tochdr.cdth_trk1 - src->tochdr.cdth_trk0) + 1;
|
|
||||||
src->tracks = g_new (struct cdrom_tocentry, src->numtracks + 1);
|
|
||||||
|
|
||||||
/* read each track entry */
|
|
||||||
for (i = 0; i <= src->numtracks; i++) {
|
|
||||||
src->tracks[i].cdte_track = i == src->numtracks ? CDROM_LEADOUT : i + 1;
|
|
||||||
src->tracks[i].cdte_format = CDROM_MSF;
|
|
||||||
if (ioctl (src->fd, CDROMREADTOCENTRY, &src->tracks[i]))
|
|
||||||
goto toc_entry_failed;
|
|
||||||
|
|
||||||
GST_DEBUG ("track %d begins at %d:%02d.%02d", i,
|
|
||||||
src->tracks[i].cdte_addr.msf.minute,
|
|
||||||
src->tracks[i].cdte_addr.msf.second,
|
|
||||||
src->tracks[i].cdte_addr.msf.frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
src->curoffset = 0;
|
|
||||||
|
|
||||||
gst_vcdsrc_recalculate (src);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* ERRORS */
|
|
||||||
open_failed:
|
|
||||||
{
|
|
||||||
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
toc_failed:
|
|
||||||
{
|
|
||||||
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM);
|
|
||||||
close (src->fd);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
toc_entry_failed:
|
|
||||||
{
|
|
||||||
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM);
|
|
||||||
g_free (src->tracks);
|
|
||||||
close (src->fd);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* close the file */
|
|
||||||
static gboolean
|
|
||||||
gst_vcdsrc_stop (GstBaseSrc * bsrc)
|
|
||||||
{
|
|
||||||
GstVCDSrc *src = GST_VCDSRC (bsrc);
|
|
||||||
|
|
||||||
/* close the file */
|
|
||||||
close (src->fd);
|
|
||||||
|
|
||||||
/* zero out a lot of our state */
|
|
||||||
src->fd = 0;
|
|
||||||
src->curoffset = 0;
|
|
||||||
|
|
||||||
g_free (src->tracks);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* URI interface.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static GstURIType
|
|
||||||
gst_vcdsrc_uri_get_type (GType type)
|
|
||||||
{
|
|
||||||
return GST_URI_SRC;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const gchar *const *
|
|
||||||
gst_vcdsrc_uri_get_protocols (GType type)
|
|
||||||
{
|
|
||||||
static const gchar *protocols[] = { "vcd", NULL };
|
|
||||||
|
|
||||||
return protocols;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gchar *
|
|
||||||
gst_vcdsrc_uri_get_uri (GstURIHandler * handler)
|
|
||||||
{
|
|
||||||
GstVCDSrc *src = GST_VCDSRC (handler);
|
|
||||||
gchar *result;
|
|
||||||
|
|
||||||
GST_OBJECT_LOCK (src);
|
|
||||||
result = g_strdup_printf ("vcd://%d", src->track);
|
|
||||||
GST_OBJECT_UNLOCK (src);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_vcdsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri,
|
|
||||||
GError ** error)
|
|
||||||
{
|
|
||||||
GstVCDSrc *src = GST_VCDSRC (handler);
|
|
||||||
gchar *location = NULL;
|
|
||||||
gint tracknr;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "setting uri '%s'", uri);
|
|
||||||
|
|
||||||
if (!gst_uri_has_protocol (uri, "vcd"))
|
|
||||||
goto wrong_protocol;
|
|
||||||
|
|
||||||
/* parse out the track in the location */
|
|
||||||
if (!(location = gst_uri_get_location (uri)))
|
|
||||||
goto no_location;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "have location '%s'", location);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* URI structure: vcd:///path/to/device,track-num
|
|
||||||
*/
|
|
||||||
if (g_str_has_prefix (uri, "vcd://")) {
|
|
||||||
GST_OBJECT_LOCK (src);
|
|
||||||
g_free (src->device);
|
|
||||||
if (strlen (uri) > 6)
|
|
||||||
src->device = g_strdup (uri + 6);
|
|
||||||
else
|
|
||||||
src->device = g_strdup (DEFAULT_DEVICE);
|
|
||||||
GST_DEBUG_OBJECT (src, "configured device %s", src->device);
|
|
||||||
GST_OBJECT_UNLOCK (src);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse the track number */
|
|
||||||
{
|
|
||||||
char **split;
|
|
||||||
|
|
||||||
split = g_strsplit (location, ",", 2);
|
|
||||||
if (split == NULL || *split == NULL || split[1] == NULL) {
|
|
||||||
tracknr = 1;
|
|
||||||
} else if (sscanf (split[1], "%d", &tracknr) != 1 || tracknr < 1) {
|
|
||||||
g_strfreev (split);
|
|
||||||
goto invalid_location;
|
|
||||||
}
|
|
||||||
g_strfreev (split);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_OBJECT_LOCK (src);
|
|
||||||
src->track = tracknr;
|
|
||||||
GST_DEBUG_OBJECT (src, "configured track %d", src->track);
|
|
||||||
GST_OBJECT_UNLOCK (src);
|
|
||||||
|
|
||||||
g_free (location);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* ERRORS */
|
|
||||||
wrong_protocol:
|
|
||||||
{
|
|
||||||
GST_ERROR_OBJECT (src, "Wrong protocol, uri = %s", uri);
|
|
||||||
g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_UNSUPPORTED_PROTOCOL,
|
|
||||||
"Wrong protocol, uri = %s", uri);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
no_location:
|
|
||||||
{
|
|
||||||
GST_ERROR_OBJECT (src, "No location specified");
|
|
||||||
g_set_error_literal (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
|
|
||||||
"No location specified");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
invalid_location:
|
|
||||||
{
|
|
||||||
GST_ERROR_OBJECT (src, "Invalid location '%s' in URI '%s'", location, uri);
|
|
||||||
g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
|
|
||||||
"Invalid location '%s' in URI '%s'", location, uri);
|
|
||||||
g_free (location);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vcdsrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
|
|
||||||
{
|
|
||||||
GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
|
|
||||||
|
|
||||||
iface->get_type = gst_vcdsrc_uri_get_type;
|
|
||||||
iface->get_protocols = gst_vcdsrc_uri_get_protocols;
|
|
||||||
iface->get_uri = gst_vcdsrc_uri_get_uri;
|
|
||||||
iface->set_uri = gst_vcdsrc_uri_set_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
plugin_init (GstPlugin * plugin)
|
|
||||||
{
|
|
||||||
return gst_element_register (plugin, "vcdsrc", GST_RANK_SECONDARY,
|
|
||||||
GST_TYPE_VCDSRC);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
|
||||||
GST_VERSION_MINOR,
|
|
||||||
vcdsrc,
|
|
||||||
"Asynchronous read from VCD disk",
|
|
||||||
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
|
|
|
@ -1,76 +0,0 @@
|
||||||
/* GStreamer
|
|
||||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
|
||||||
*
|
|
||||||
* 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., 51 Franklin St, Fifth Floor,
|
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __VCDSRC_H__
|
|
||||||
#define __VCDSRC_H__
|
|
||||||
|
|
||||||
#include <linux/cdrom.h>
|
|
||||||
|
|
||||||
#include <gst/gst.h>
|
|
||||||
#include <gst/base/gstpushsrc.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define VCD_BYTES_PER_SECTOR 2352
|
|
||||||
|
|
||||||
#define GST_TYPE_VCDSRC \
|
|
||||||
(gst_vcdsrc_get_type())
|
|
||||||
#define GST_VCDSRC(obj) \
|
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VCDSRC,GstVCDSrc))
|
|
||||||
#define GST_VCDSRC_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VCDSRC,GstVCDSrcClass))
|
|
||||||
#define GST_IS_VCDSRC(obj) \
|
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VCDSRC))
|
|
||||||
#define GST_IS_VCDSRC_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VCDSRC))
|
|
||||||
|
|
||||||
typedef struct _GstVCDSrc GstVCDSrc;
|
|
||||||
typedef struct _GstVCDSrcClass GstVCDSrcClass;
|
|
||||||
|
|
||||||
struct _GstVCDSrc {
|
|
||||||
GstPushSrc parent_object;
|
|
||||||
|
|
||||||
/* device */
|
|
||||||
gchar *device;
|
|
||||||
/* track number */
|
|
||||||
gint track;
|
|
||||||
int max_errors;
|
|
||||||
|
|
||||||
/* fd */
|
|
||||||
gint fd;
|
|
||||||
gint numtracks;
|
|
||||||
struct cdrom_tochdr tochdr;
|
|
||||||
struct cdrom_tocentry *tracks;
|
|
||||||
|
|
||||||
/* current time offset */
|
|
||||||
gulong trackoffset;
|
|
||||||
gulong curoffset; /* current offset in file */
|
|
||||||
gulong bytes_per_read; /* bytes per read */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GstVCDSrcClass {
|
|
||||||
GstPushSrcClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
GType gst_vcdsrc_get_type (void);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __VCDSRC_H__ */
|
|
|
@ -18,7 +18,7 @@ AM_TESTS_ENVIRONMENT += \
|
||||||
decklinksrc \
|
decklinksrc \
|
||||||
decklinksink dtlssrtpdec dtlssrtpenc dvbsrc dvbbasebin dfbvideosink festival fluidsynth \
|
decklinksink dtlssrtpdec dtlssrtpenc dvbsrc dvbbasebin dfbvideosink festival fluidsynth \
|
||||||
kmssink \
|
kmssink \
|
||||||
rsndvdbin vcdsrc rfbsrc vdpauyuvvideo vdpauvideoyuv \
|
rsndvdbin rfbsrc vdpauyuvvideo vdpauvideoyuv \
|
||||||
vdpaumpegdec vdpaumpeg4dec vdpauh264dec vdpauvideopostprocess vdpausink neonhttpsrc waylandsink"
|
vdpaumpegdec vdpaumpeg4dec vdpauh264dec vdpauvideopostprocess vdpausink neonhttpsrc waylandsink"
|
||||||
|
|
||||||
plugindir = $(libdir)/gstreamer-@GST_API_VERSION@
|
plugindir = $(libdir)/gstreamer-@GST_API_VERSION@
|
||||||
|
|
Loading…
Reference in a new issue