diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2007-06-13 11:37:36 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2007-06-13 11:37:36 +0000 |
commit | 2229e288b617ff4a03d613995e62595aa9b205d1 (patch) | |
tree | d1d4b1d41680ca256c1e19349118ea04ea1dd91f | |
parent | e47279f03068de094c4cab0a1f0b0c1b59ac601d (diff) | |
download | gst-plugins-bad-2229e288b617ff4a03d613995e62595aa9b205d1.tar.gz gst-plugins-bad-2229e288b617ff4a03d613995e62595aa9b205d1.tar.bz2 gst-plugins-bad-2229e288b617ff4a03d613995e62595aa9b205d1.zip |
Port VCD element.
Original commit message from CVS:
* configure.ac:
* sys/Makefile.am:
* sys/vcd/Makefile.am:
* sys/vcd/vcdsrc.c: (gst_vcdsrc_setup_interfaces),
(gst_vcdsrc_base_init), (gst_vcdsrc_class_init), (gst_vcdsrc_init),
(gst_vcdsrc_msf), (gst_vcdsrc_recalculate),
(gst_vcdsrc_set_property), (gst_vcdsrc_get_property),
(gst_vcdsrc_create), (gst_vcdsrc_start), (gst_vcdsrc_stop),
(gst_vcdsrc_uri_set_uri):
* sys/vcd/vcdsrc.h:
Port VCD element.
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | configure.ac | 8 | ||||
-rw-r--r-- | sys/Makefile.am | 14 | ||||
-rw-r--r-- | sys/vcd/Makefile.am | 4 | ||||
-rw-r--r-- | sys/vcd/vcdsrc.c | 422 | ||||
-rw-r--r-- | sys/vcd/vcdsrc.h | 33 |
6 files changed, 173 insertions, 322 deletions
@@ -1,3 +1,17 @@ +2007-06-13 Wim Taymans <wim@fluendo.com> + + * configure.ac: + * sys/Makefile.am: + * sys/vcd/Makefile.am: + * sys/vcd/vcdsrc.c: (gst_vcdsrc_setup_interfaces), + (gst_vcdsrc_base_init), (gst_vcdsrc_class_init), (gst_vcdsrc_init), + (gst_vcdsrc_msf), (gst_vcdsrc_recalculate), + (gst_vcdsrc_set_property), (gst_vcdsrc_get_property), + (gst_vcdsrc_create), (gst_vcdsrc_start), (gst_vcdsrc_stop), + (gst_vcdsrc_uri_set_uri): + * sys/vcd/vcdsrc.h: + Port VCD element. + 2007-06-12 Sebastien Moutte <sebastien@moutte.net> * win32/MANIFEST: diff --git a/configure.ac b/configure.ac index 92c84040..bd63e7c3 100644 --- a/configure.ac +++ b/configure.ac @@ -286,6 +286,12 @@ AG_GST_CHECK_FEATURE(OPENGL, [Open GL], glsink, [ CPPFLAGS="$save_CPPFLAGS" LIBS="$save_LIBS" +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 X11 translit(dnm, m, l) AM_CONDITIONAL(USE_X, true) AG_GST_CHECK_FEATURE(X, [X libraries and plugins], @@ -872,6 +878,7 @@ dnl not building plugins with external dependencies, dnl but we still need to set the conditionals AM_CONDITIONAL(USE_OPENGL, false) +AM_CONDITIONAL(USE_VCD, false) AM_CONDITIONAL(USE_X, false) AM_CONDITIONAL(USE_ALSA, false) AM_CONDITIONAL(USE_AMRWB, false) @@ -992,6 +999,7 @@ gst-libs/gst/app/Makefile sys/Makefile sys/glsink/Makefile sys/dvb/Makefile +sys/vcd/Makefile examples/Makefile examples/app/Makefile examples/directfb/Makefile diff --git a/sys/Makefile.am b/sys/Makefile.am index 3866499c..106c729c 100644 --- a/sys/Makefile.am +++ b/sys/Makefile.am @@ -10,11 +10,11 @@ # QCAM_DIR= # endif -# if USE_VCD -# VCD_DIR=vcd -# else -# VCD_DIR= -# endif +if USE_VCD +VCD_DIR=vcd +else +VCD_DIR= +endif # if USE_CDROM # CDROM_DIR=cdrom @@ -34,6 +34,6 @@ else DVB_DIR= endif -SUBDIRS = $(GL_DIR) $(DVB_DIR) +SUBDIRS = $(GL_DIR) $(DVB_DIR) $(VCD_DIR) -DIST_SUBDIRS = glsink dvb +DIST_SUBDIRS = glsink dvb vcd diff --git a/sys/vcd/Makefile.am b/sys/vcd/Makefile.am index 8ad6b847..ed490c51 100644 --- a/sys/vcd/Makefile.am +++ b/sys/vcd/Makefile.am @@ -2,8 +2,8 @@ plugin_LTLIBRARIES = libgstvcdsrc.la libgstvcdsrc_la_SOURCES = vcdsrc.c -libgstvcdsrc_la_CFLAGS = $(GST_CFLAGS) -libgstvcdsrc_la_LIBADD = +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 diff --git a/sys/vcd/vcdsrc.c b/sys/vcd/vcdsrc.c index 61010ec3..b48e307b 100644 --- a/sys/vcd/vcdsrc.c +++ b/sys/vcd/vcdsrc.c @@ -20,6 +20,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -32,9 +33,14 @@ #include <sys/types.h> #include <dirent.h> #include <errno.h> -#include <linux/cdrom.h> -#include <vcdsrc.h> +#include "vcdsrc.h" + +static const GstElementDetails gst_vcdsrc_details = +GST_ELEMENT_DETAILS ("VCD Source", + "Source/File", + "Asynchronous read from VCD disk", + "Erik Walthinsen <omega@cse.ogi.edu>"); /* VCDSrc signals and args */ enum @@ -45,13 +51,10 @@ enum enum { - ARG_0, - ARG_LOCATION, - ARG_DEVICE, - ARG_TRACK, - ARG_BYTESPERREAD, - ARG_OFFSET, - ARG_MAX_ERRORS + PROP_0, + PROP_DEVICE, + PROP_TRACK, + PROP_MAX_ERRORS }; static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", @@ -62,187 +65,134 @@ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", GST_DEBUG_CATEGORY_STATIC (gst_vcdsrc_debug); #define GST_CAT_DEFAULT gst_vcdsrc_debug -static void gst_vcdsrc_base_init (gpointer g_class); -static void gst_vcdsrc_class_init (GstVCDSrcClass * klass); -static void gst_vcdsrc_init (GstVCDSrc * vcdsrc); -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 const GstEventMask *gst_vcdsrc_get_event_mask (GstPad * pad); -static const GstQueryType *gst_vcdsrc_get_query_types (GstPad * pad); -static const GstFormat *gst_vcdsrc_get_formats (GstPad * pad); -static gboolean gst_vcdsrc_srcpad_event (GstPad * pad, GstEvent * event); -static gboolean gst_vcdsrc_srcpad_query (GstPad * pad, GstQueryType type, - GstFormat * format, gint64 * value); +static void gst_vcdsrc_uri_handler_init (gpointer g_iface, gpointer iface_data); -static GstData *gst_vcdsrc_get (GstPad * pad); -static GstStateChangeReturn gst_vcdsrc_change_state (GstElement * element, - GstStateChange transition); -static inline guint64 gst_vcdsrc_msf (GstVCDSrc * vcdsrc, gint track); -static void gst_vcdsrc_recalculate (GstVCDSrc * vcdsrc); +static void +gst_vcdsrc_setup_interfaces (GType type) +{ + static const GInterfaceInfo urihandler_info = { + gst_vcdsrc_uri_handler_init, + NULL, + NULL, + }; -static void gst_vcdsrc_uri_handler_init (gpointer g_iface, gpointer iface_data); + g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info); +} -static GstElementClass *parent_class = NULL; -/*static guint vcdsrc_signals[LAST_SIGNAL] = { 0 }; */ +GST_BOILERPLATE_FULL (GstVCDSrc, gst_vcdsrc, GstPushSrc, GST_TYPE_PUSH_SRC, + gst_vcdsrc_setup_interfaces); -GType -gst_vcdsrc_get_type (void) -{ - static GType gst_vcdsrc_type = 0; - - if (!gst_vcdsrc_type) { - static const GTypeInfo gst_vcdsrc_info = { - sizeof (GstVCDSrcClass), - gst_vcdsrc_base_init, - NULL, - (GClassInitFunc) gst_vcdsrc_class_init, - NULL, - NULL, - sizeof (GstVCDSrc), - 0, - (GInstanceInitFunc) gst_vcdsrc_init, - }; - static const GInterfaceInfo urihandler_info = { - gst_vcdsrc_uri_handler_init, - NULL, - NULL - }; - - gst_vcdsrc_type = - g_type_register_static (GST_TYPE_ELEMENT, - "GstVCDSrc", &gst_vcdsrc_info, 0); - g_type_add_interface_static (gst_vcdsrc_type, - GST_TYPE_URI_HANDLER, &urihandler_info); - } +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); - return gst_vcdsrc_type; -} +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_base_init (gpointer g_class) { GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - static const GstElementDetails gst_vcdsrc_details = - GST_ELEMENT_DETAILS ("VCD Source", - "Source/File", - "Asynchronous read from VCD disk", - "Erik Walthinsen <omega@cse.ogi.edu>"); + + gst_element_class_set_details (element_class, &gst_vcdsrc_details); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&srctemplate)); - gst_element_class_set_details (element_class, &gst_vcdsrc_details); } static void gst_vcdsrc_class_init (GstVCDSrcClass * klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); + GObjectClass *gobject_class; + GstBaseSrcClass *basesrc_class; + GstPushSrcClass *pushsrc_class; + + gobject_class = (GObjectClass *) klass; + basesrc_class = (GstBaseSrcClass *) klass; + pushsrc_class = (GstPushSrcClass *) klass; - parent_class = g_type_class_peek_parent (klass); + gobject_class->set_property = gst_vcdsrc_set_property; + gobject_class->get_property = gst_vcdsrc_get_property; - g_object_class_install_property (gobject_class, ARG_LOCATION, - g_param_spec_string ("location", "Location", - "CD device location (deprecated; use device)", - NULL, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, ARG_DEVICE, + 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, ARG_TRACK, + 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, ARG_BYTESPERREAD, - g_param_spec_int ("bytesperread", "Bytes per read", - "Bytes to read per iteration (VCD sector size)", - G_MININT, G_MAXINT, 0, G_PARAM_READABLE)); - g_object_class_install_property (gobject_class, ARG_OFFSET, - g_param_spec_int ("offset", "Offset", "Offset", - G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, ARG_MAX_ERRORS, + 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)); - gobject_class->set_property = gst_vcdsrc_set_property; - gobject_class->get_property = gst_vcdsrc_get_property; + basesrc_class->start = gst_vcdsrc_start; + basesrc_class->stop = gst_vcdsrc_stop; - gstelement_class->change_state = gst_vcdsrc_change_state; + pushsrc_class->create = gst_vcdsrc_create; GST_DEBUG_CATEGORY_INIT (gst_vcdsrc_debug, "vcdsrc", 0, "VideoCD Source element"); } static void -gst_vcdsrc_init (GstVCDSrc * vcdsrc) +gst_vcdsrc_init (GstVCDSrc * vcdsrc, GstVCDSrcClass * klass) { - vcdsrc->srcpad = - gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate), - "src"); - gst_pad_set_get_function (vcdsrc->srcpad, gst_vcdsrc_get); -#if 0 - gst_pad_set_get_region_function (vcdsrc->srcpad, vcdsrc_getregion); -#endif - gst_pad_set_event_function (vcdsrc->srcpad, gst_vcdsrc_srcpad_event); - gst_pad_set_event_mask_function (vcdsrc->srcpad, gst_vcdsrc_get_event_mask); - gst_pad_set_query_function (vcdsrc->srcpad, gst_vcdsrc_srcpad_query); - gst_pad_set_query_type_function (vcdsrc->srcpad, gst_vcdsrc_get_query_types); - gst_pad_set_formats_function (vcdsrc->srcpad, gst_vcdsrc_get_formats); - gst_element_add_pad (GST_ELEMENT (vcdsrc), vcdsrc->srcpad); - vcdsrc->device = g_strdup ("/dev/cdrom"); vcdsrc->track = 1; vcdsrc->fd = 0; vcdsrc->trackoffset = 0; vcdsrc->curoffset = 0; - vcdsrc->tempoffset = 0; - vcdsrc->discont = vcdsrc->flush = FALSE; vcdsrc->bytes_per_read = VCD_BYTES_PER_SECTOR; - vcdsrc->seq = 0; vcdsrc->max_errors = 16; } +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; - g_return_if_fail (GST_IS_VCDSRC (object)); src = GST_VCDSRC (object); switch (prop_id) { - case ARG_DEVICE: - case ARG_LOCATION: - /* the element must be stopped in order to do this */ -/* g_return_if_fail(!GST_OBJECT_FLAG_IS_SET(src,GST_STATE_RUNNING)); */ - + case PROP_DEVICE: g_free (src->device); - /* clear the filename if we get a NULL (is that possible?) */ - if (g_value_get_string (value) == NULL) - src->device = NULL; - /* otherwise set the new filename */ - else - src->device = g_strdup (g_value_get_string (value)); + src->device = g_value_dup_string (value); break; - case ARG_TRACK: + 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 ARG_MAX_ERRORS: + 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 @@ -255,20 +205,13 @@ gst_vcdsrc_get_property (GObject * object, guint prop_id, GValue * value, src = GST_VCDSRC (object); switch (prop_id) { - case ARG_DEVICE: - case ARG_LOCATION: + case PROP_DEVICE: g_value_set_string (value, src->device); break; - case ARG_TRACK: + case PROP_TRACK: g_value_set_int (value, src->track); break; - case ARG_BYTESPERREAD: - g_value_set_int (value, src->bytes_per_read); - break; - case ARG_OFFSET: - g_value_set_int (value, src->curoffset * VCD_BYTES_PER_SECTOR); - break; - case ARG_MAX_ERRORS: + case PROP_MAX_ERRORS: g_value_set_int (value, src->max_errors); break; default: @@ -277,45 +220,7 @@ gst_vcdsrc_get_property (GObject * object, guint prop_id, GValue * value, } } -/* - * Querying and seeking. - */ - -static const GstEventMask * -gst_vcdsrc_get_event_mask (GstPad * pad) -{ - static const GstEventMask masks[] = { - {GST_EVENT_SEEK, GST_SEEK_METHOD_CUR | - GST_SEEK_METHOD_SET | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH}, - {0, 0} - }; - - return masks; -} - -static const GstQueryType * -gst_vcdsrc_get_query_types (GstPad * pad) -{ - static const GstQueryType types[] = { - GST_QUERY_TOTAL, - GST_QUERY_POSITION, - 0 - }; - - return types; -} - -static const GstFormat * -gst_vcdsrc_get_formats (GstPad * pad) -{ - static const GstFormat formats[] = { - GST_FORMAT_BYTES, - 0, - }; - - return formats; -} - +#if 0 static gboolean gst_vcdsrc_srcpad_event (GstPad * pad, GstEvent * event) { @@ -366,7 +271,9 @@ gst_vcdsrc_srcpad_event (GstPad * pad, GstEvent * event) return res; } +#endif +#if 0 static gboolean gst_vcdsrc_srcpad_query (GstPad * pad, GstQueryType type, GstFormat * format, gint64 * value) @@ -392,48 +299,26 @@ gst_vcdsrc_srcpad_query (GstPad * pad, GstQueryType type, return res; } +#endif -/* - * Data. - */ - -static GstData * -gst_vcdsrc_get (GstPad * pad) +static GstFlowReturn +gst_vcdsrc_create (GstPushSrc * src, GstBuffer ** buf) { GstVCDSrc *vcdsrc; - GstFormat fmt = GST_FORMAT_BYTES; - GstBuffer *buf; + GstBuffer *outbuf; gulong offset; struct cdrom_msf *msf; gint error_count = 0; - g_return_val_if_fail (pad != NULL, NULL); - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - vcdsrc = GST_VCDSRC (GST_OBJECT_PARENT (pad)); - g_return_val_if_fail (GST_OBJECT_FLAG_IS_SET (vcdsrc, VCDSRC_OPEN), NULL); + vcdsrc = GST_VCDSRC (src); offset = vcdsrc->trackoffset + vcdsrc->curoffset; - if (offset >= gst_vcdsrc_msf (vcdsrc, vcdsrc->track + 1)) { - gst_element_set_eos (GST_ELEMENT (vcdsrc)); - return GST_DATA (gst_event_new (GST_EVENT_EOS)); - } - - if (vcdsrc->discont) { - if (vcdsrc->flush) { - vcdsrc->flush = FALSE; - return GST_DATA (gst_event_new (GST_EVENT_FLUSH)); - } - vcdsrc->discont = FALSE; - return GST_DATA (gst_event_new_discontinuous (FALSE, - GST_FORMAT_BYTES, vcdsrc->curoffset * vcdsrc->bytes_per_read, - GST_FORMAT_UNDEFINED)); - } + if (offset >= gst_vcdsrc_msf (vcdsrc, vcdsrc->track + 1)) + goto eos; /* create the buffer */ - /* FIXME: should eventually use a bufferpool for this */ - buf = gst_buffer_new_and_alloc (vcdsrc->bytes_per_read); - msf = (struct cdrom_msf *) GST_BUFFER_DATA (buf); + outbuf = gst_buffer_new_and_alloc (vcdsrc->bytes_per_read); + msf = (struct cdrom_msf *) GST_BUFFER_DATA (outbuf); read: /* read it in from the device */ @@ -455,50 +340,39 @@ read: ("Read from cdrom at %d:%d:%d failed: %s", msf->cdmsf_min0, msf->cdmsf_sec0, msf->cdmsf_frame0, strerror (errno))); - - return GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)); + return GST_FLOW_ERROR; } - - gst_pad_query (pad, GST_QUERY_POSITION, &fmt, - (gint64 *) & GST_BUFFER_OFFSET (buf)); - GST_BUFFER_SIZE (buf) = vcdsrc->bytes_per_read; + GST_BUFFER_SIZE (outbuf) = vcdsrc->bytes_per_read; vcdsrc->curoffset += 1; - if (vcdsrc->tempoffset != 0) { - GstBuffer *sub; + *buf = outbuf; - sub = gst_buffer_create_sub (buf, vcdsrc->tempoffset, - vcdsrc->bytes_per_read - vcdsrc->tempoffset); - vcdsrc->tempoffset = 0; - gst_buffer_unref (buf); - buf = sub; - } + return GST_FLOW_OK; - return GST_DATA (buf); + /* ERRORS */ +eos: + { + GST_DEBUG_OBJECT (vcdsrc, "got eos"); + return GST_FLOW_UNEXPECTED; + } } /* open the file, necessary to go to RUNNING state */ static gboolean -gst_vcdsrc_open_file (GstVCDSrc * src) +gst_vcdsrc_start (GstBaseSrc * bsrc) { int i; - - g_return_val_if_fail (!GST_OBJECT_FLAG_IS_SET (src, VCDSRC_OPEN), FALSE); + GstVCDSrc *src = GST_VCDSRC (bsrc); /* open the device */ src->fd = open (src->device, O_RDONLY); - if (src->fd < 0) { - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM); - return FALSE; - } + if (src->fd < 0) + goto open_failed; /* read the table of contents */ - if (ioctl (src->fd, CDROMREADTOCHDR, &src->tochdr)) { - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM); - close (src->fd); - return FALSE; - } + 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; @@ -508,29 +382,47 @@ gst_vcdsrc_open_file (GstVCDSrc * src) 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])) { - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM); - g_free (src->tracks); - close (src->fd); - return FALSE; - } + 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); } - GST_OBJECT_FLAG_SET (src, VCDSRC_OPEN); + 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 void -gst_vcdsrc_close_file (GstVCDSrc * src) +static gboolean +gst_vcdsrc_stop (GstBaseSrc * bsrc) { - g_return_if_fail (GST_OBJECT_FLAG_IS_SET (src, VCDSRC_OPEN)); + GstVCDSrc *src = GST_VCDSRC (bsrc); /* close the file */ close (src->fd); @@ -538,58 +430,10 @@ gst_vcdsrc_close_file (GstVCDSrc * src) /* zero out a lot of our state */ src->fd = 0; src->curoffset = 0; - src->seq = 0; g_free (src->tracks); - GST_OBJECT_FLAG_UNSET (src, VCDSRC_OPEN); -} - -static GstStateChangeReturn -gst_vcdsrc_change_state (GstElement * element, GstStateChange transition) -{ - GstVCDSrc *vcdsrc = GST_VCDSRC (element); - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_NULL: - if (GST_OBJECT_FLAG_IS_SET (element, VCDSRC_OPEN)) - gst_vcdsrc_close_file (vcdsrc); - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - vcdsrc->curoffset = 0; - vcdsrc->discont = vcdsrc->flush = FALSE; - break; - case GST_STATE_CHANGE_NULL_TO_READY: - if (!GST_OBJECT_FLAG_IS_SET (element, VCDSRC_OPEN)) - if (!gst_vcdsrc_open_file (vcdsrc)) - return GST_STATE_CHANGE_FAILURE; - break; - default: - break; - } - - if (GST_ELEMENT_CLASS (parent_class)->change_state) - return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - return GST_STATE_CHANGE_SUCCESS; -} - -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) -{ - if (GST_OBJECT_FLAG_IS_SET (vcdsrc, VCDSRC_OPEN)) { - /* calculate track offset (beginning of track) */ - vcdsrc->trackoffset = gst_vcdsrc_msf (vcdsrc, vcdsrc->track); - GST_DEBUG ("track offset is %ld", vcdsrc->trackoffset); - } + return TRUE; } /* @@ -620,7 +464,9 @@ static gboolean gst_vcdsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri) { gboolean ret; - gchar *protocol = gst_uri_get_protocol (uri); + gchar *protocol; + + protocol = gst_uri_get_protocol (uri); ret = (protocol && !strcmp (protocol, "vcd")) ? TRUE : FALSE; g_free (protocol); diff --git a/sys/vcd/vcdsrc.h b/sys/vcd/vcdsrc.h index 8d78bb0d..6dd5d91b 100644 --- a/sys/vcd/vcdsrc.h +++ b/sys/vcd/vcdsrc.h @@ -21,9 +21,11 @@ #ifndef __VCDSRC_H__ #define __VCDSRC_H__ -#include <gst/gst.h> #include <linux/cdrom.h> +#include <gst/gst.h> +#include <gst/base/gstpushsrc.h> + G_BEGIN_DECLS #define VCD_BYTES_PER_SECTOR 2352 @@ -39,53 +41,34 @@ G_BEGIN_DECLS #define GST_IS_VCDSRC_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VCDSRC)) -/* NOTE: per-element flags start with 16 for now */ -typedef enum { - VCDSRC_OPEN = (GST_ELEMENT_FLAG_LAST << 0), - - VCDSRC_FLAG_LAST = (GST_ELEMENT_FLAG_LAST << 2), -} GstVCDSrcFlags; - typedef struct _GstVCDSrc GstVCDSrc; typedef struct _GstVCDSrcClass GstVCDSrcClass; struct _GstVCDSrc { - GstElement element; - /* pads */ - GstPad *srcpad; + GstPushSrc parent_object; /* device */ gchar *device; /* track number */ gint track; + int max_errors; + /* fd */ gint fd; - - struct cdrom_tochdr tochdr; gint numtracks; + struct cdrom_tochdr tochdr; struct cdrom_tocentry *tracks; /* current time offset */ gulong trackoffset; - gulong frameoffset; - - /* bytes offset in next buf */ - gulong tempoffset; - gboolean discont, flush; - gulong curoffset; /* current offset in file */ gulong bytes_per_read; /* bytes per read */ - - gulong seq; /* buffer sequence number */ - int max_errors; }; struct _GstVCDSrcClass { - GstElementClass parent_class; + GstPushSrcClass parent_class; }; -GType gst_vcdsrc_get_type(void); - G_END_DECLS #endif /* __VCDSRC_H__ */ |