diff options
Diffstat (limited to 'sys/cdrom')
-rw-r--r-- | sys/cdrom/Makefile.am | 10 | ||||
-rw-r--r-- | sys/cdrom/gstcdplayer.c | 293 | ||||
-rw-r--r-- | sys/cdrom/gstcdplayer.h | 64 | ||||
-rw-r--r-- | sys/cdrom/gstcdplayer_ioctl.c | 165 | ||||
-rw-r--r-- | sys/cdrom/gstcdplayer_ioctl.h | 58 |
5 files changed, 590 insertions, 0 deletions
diff --git a/sys/cdrom/Makefile.am b/sys/cdrom/Makefile.am new file mode 100644 index 00000000..a43c1dcb --- /dev/null +++ b/sys/cdrom/Makefile.am @@ -0,0 +1,10 @@ +plugindir = $(libdir)/gst + +plugin_LTLIBRARIES = libgstcdplayer.la + +libgstcdplayer_la_SOURCES = gstcdplayer.c gstcdplayer_ioctl.c +libgstcdplayer_la_CFLAGS = $(GST_CFLAGS) +libgstcdplayer_la_LIBADD = +libgstcdplayer_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) + +noinst_HEADERS = gstcdplayer.h gstcdplayer_ioctl.h diff --git a/sys/cdrom/gstcdplayer.c b/sys/cdrom/gstcdplayer.c new file mode 100644 index 00000000..ddfc823f --- /dev/null +++ b/sys/cdrom/gstcdplayer.c @@ -0,0 +1,293 @@ +/* gstcdplay + * Copyright (c) 2002 Charles Schmidt <cbschmid@uiuc.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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gstcdplayer.h" +#include "gstcdplayer_ioctl.h" + +/* props */ +enum { + ARG_0, + ARG_DEVICE, + ARG_NUM_TRACKS, + ARG_START_TRACK, +}; + +/* signals */ +enum { + LAST_SIGNAL, +}; + +static void cdplayer_class_init(CDPlayerClass *klass); +static void cdplayer_init(CDPlayer *cdp); +static void cdplayer_set_property(GObject *object,guint prop_id,const GValue *value,GParamSpec *spec); +static void cdplayer_get_property(GObject *object,guint prop_id,GValue *value,GParamSpec *spec); +static void cdplayer_dispose(GObject *object); +static GstElementStateReturn cdplayer_change_state(GstElement *element); + +static gboolean plugin_init(GModule *module,GstPlugin *plugin); + + + +static GstElementClass *parent_class; +/* static guint cdplayer_signals[LAST_SIGNAL] = {0}; */ + + +static GstElementDetails cdplayer_details = { + "CD Player", + "Generic/Bin", + "Play CD audio through the CD Drive", + VERSION, + "Charles Schmidt <cbschmid@uiuc.edu>", + "(C) 2002", +}; + + + +GType cdplayer_get_type(void) +{ + static GType cdplayer_type = 0; + + if (!cdplayer_type) { + static const GTypeInfo cdplayer_info = { + sizeof(CDPlayerClass), + NULL, + NULL, + (GClassInitFunc)cdplayer_class_init, + NULL, + NULL, + sizeof(CDPlayer), + 0, + (GInstanceInitFunc)cdplayer_init, + NULL + }; + + cdplayer_type = g_type_register_static(GST_TYPE_BIN,"CDPlayer",&cdplayer_info,0); + } + + return cdplayer_type; +} + +static void cdplayer_class_init(CDPlayerClass *klass) +{ + GObjectClass *gobject_klass; + GstElementClass *gstelement_klass; + + gobject_klass = (GObjectClass *)klass; + gstelement_klass = (GstElementClass *)klass; + + parent_class = g_type_class_ref(gst_bin_get_type()); + + gobject_klass->dispose = GST_DEBUG_FUNCPTR(cdplayer_dispose); + + gstelement_klass->change_state = GST_DEBUG_FUNCPTR(cdplayer_change_state); + + g_object_class_install_property(gobject_klass,ARG_DEVICE,g_param_spec_string("device","device","CDROM device",NULL,G_PARAM_READWRITE)); + g_object_class_install_property(gobject_klass,ARG_NUM_TRACKS,g_param_spec_int("num_tracks","num_tracks","Number of Tracks",G_MININT,G_MAXINT,0,G_PARAM_READABLE)); + g_object_class_install_property(gobject_klass,ARG_START_TRACK,g_param_spec_int("start_track","start_track","Track to start playback on",1,CDPLAYER_MAX_TRACKS-1,1,G_PARAM_READABLE)); + + gobject_klass->set_property = cdplayer_set_property; + gobject_klass->get_property = cdplayer_get_property; + + return; +} + +static void cdplayer_init(CDPlayer *cdp) +{ + GstScheduler *scheduler; + + cdp->device = g_strdup("/dev/cdrom"); + cdp->num_tracks = -1; + cdp->start_track = 1; + + cdp->paused = FALSE; + + GST_FLAG_SET(cdp,GST_BIN_SELF_SCHEDULABLE); + + scheduler = gst_scheduler_factory_make(NULL,GST_ELEMENT(cdp)); + g_return_if_fail(scheduler != NULL); + + gst_scheduler_setup(scheduler); + + return; +} + +static void cdplayer_set_property(GObject *object,guint prop_id,const GValue *value,GParamSpec *spec) +{ + CDPlayer *cdp; + + g_return_if_fail(GST_IS_CDPLAYER(object)); + + cdp = CDPLAYER(object); + + switch (prop_id) { + case ARG_DEVICE: +// FIXME prolly should uhh.. stop it or something + if (cdp->device) { + g_free(cdp->device); + } + + cdp->device = g_strdup(g_value_get_string(value)); + break; + case ARG_START_TRACK: +// FIXME prolly should uhh.. restart play, i guess... or something whatever + cdp->start_track = g_value_get_int(value); + break; + default: + break; + } + + return; +} + + +static void cdplayer_get_property(GObject *object,guint prop_id,GValue *value,GParamSpec *spec) +{ + CDPlayer *cdp; + + g_return_if_fail(GST_IS_CDPLAYER(object)); + + cdp = CDPLAYER(object); + + switch (prop_id) { + case ARG_DEVICE: + g_value_set_string(value,cdp->device); + break; + case ARG_NUM_TRACKS: + g_value_set_int(value,cdp->num_tracks); + break; + case ARG_START_TRACK: + g_value_set_int(value,cdp->start_track); + break; + default: + break; + } + + return; +} + +static void cdplayer_dispose(GObject *object) +{ + CDPlayer *cdp; + + g_return_if_fail(GST_IS_CDPLAYER(object)); + + cdp = CDPLAYER(object); + + G_OBJECT_CLASS(parent_class)->dispose(object); + + g_free(cdp->device); + + if (GST_ELEMENT_SCHED(cdp)) { + gst_scheduler_reset(GST_ELEMENT_SCHED(cdp)); + gst_object_unref(GST_OBJECT(GST_ELEMENT_SCHED(cdp))); + GST_ELEMENT_SCHED(cdp) = NULL; + } + + return; +} + +static GstElementStateReturn cdplayer_change_state(GstElement *element) +{ + CDPlayer *cdp; + GstElementState state = GST_STATE(element); + GstElementState pending = GST_STATE_PENDING(element); + + g_return_val_if_fail(GST_IS_CDPLAYER(element),GST_STATE_FAILURE); + + cdp = CDPLAYER(element); + + switch (pending) { + case GST_STATE_READY: + if (state != GST_STATE_PAUSED) { + if (cd_init(CDPLAYER_CD(cdp),cdp->device) == FALSE) { + return GST_STATE_FAILURE; + } + cdp->num_tracks = cdp->cd.num_tracks; + } + break; + case GST_STATE_PAUSED: + /* ready->paused is not useful */ + if (state != GST_STATE_READY) { + if (cd_pause(CDPLAYER_CD(cdp)) == FALSE) { + return GST_STATE_FAILURE; + } + + cdp->paused = TRUE; + } + + break; + case GST_STATE_PLAYING: + if (cdp->paused == TRUE) { + if (cd_resume(CDPLAYER_CD(cdp)) == FALSE) { + return GST_STATE_FAILURE; + } + + cdp->paused = FALSE; + } else { + if (cd_start(CDPLAYER_CD(cdp),cdp->start_track) == FALSE) { + return GST_STATE_FAILURE; + } + } + + break; + case GST_STATE_NULL: + /* stop & close fd */ + if (cd_stop(CDPLAYER_CD(cdp)) == FALSE || cd_close(CDPLAYER_CD(cdp)) == FALSE) { + return GST_STATE_FAILURE; + } + + break; + default: + break; + } + + GST_STATE(element) = GST_STATE_PENDING(element); + GST_STATE_PENDING(element) = GST_STATE_VOID_PENDING; + + if (GST_ELEMENT_CLASS(parent_class)->change_state) { + return GST_ELEMENT_CLASS(parent_class)->change_state(element); + } + + return GST_STATE_SUCCESS; +} + + +static gboolean plugin_init(GModule *module,GstPlugin *plugin) +{ + GstElementFactory *factory; + + factory = gst_element_factory_new("cdplayer",GST_TYPE_CDPLAYER,&cdplayer_details); + g_return_val_if_fail(factory != NULL,FALSE); + gst_plugin_add_feature(plugin,GST_PLUGIN_FEATURE(factory)); + + gst_plugin_set_longname(plugin,"CD Player"); + + return TRUE; + +} + +GstPluginDesc plugin_desc = { + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "cdplayer", + plugin_init +}; + + + diff --git a/sys/cdrom/gstcdplayer.h b/sys/cdrom/gstcdplayer.h new file mode 100644 index 00000000..5da5527d --- /dev/null +++ b/sys/cdrom/gstcdplayer.h @@ -0,0 +1,64 @@ +/* gstcdplay + * Copyright (c) 2002 Charles Schmidt <cbschmid@uiuc.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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __CDPLAYER_H__ +#define __CDPLAYER_H__ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> +#include <gst/gst.h> + +#include "gstcdplayer_ioctl.h" + +#define GST_TYPE_CDPLAYER (cdplayer_get_type()) +#define CDPLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CDPLAYER,CDPlayer)) +#define CDPLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CDPLAYER,CDPlayerClass)) +#define GST_IS_CDPLAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CDPLAYER)) +#define GST_IS_CDPLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CDPLAYER)) + + +typedef struct _CDPlayer CDPlayer; +typedef struct _CDPlayerClass CDPlayerClass; + +struct _CDPlayer { + GstBin element; + + /* properties */ + gchar *device; + gint num_tracks; + guint start_track; + + /* private */ + struct cd cd; + gboolean paused; +}; + +struct _CDPlayerClass { + GstBinClass parent_class; + + /* signal callbacks */ +}; + +GType cdplayer_get_type(void); + +#endif + diff --git a/sys/cdrom/gstcdplayer_ioctl.c b/sys/cdrom/gstcdplayer_ioctl.c new file mode 100644 index 00000000..2da746a2 --- /dev/null +++ b/sys/cdrom/gstcdplayer_ioctl.c @@ -0,0 +1,165 @@ +/* gstcdplay + * Copyright (c) 2002 Charles Schmidt <cbschmid@uiuc.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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gstcdplayer_ioctl.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <errno.h> + +#include <linux/cdrom.h> + + +gboolean cd_init(struct cd *cd,const gchar *device) +{ + struct cdrom_tochdr toc_header; + struct cdrom_tocentry toc_entry; + guint i; + + cd->fd = open(device,O_RDONLY | O_NONBLOCK); + + if (cd->fd == -1) { + return FALSE; + } + + /* get the toc header information */ + if (ioctl(cd->fd,CDROMREADTOCHDR,&toc_header) != 0) { + return FALSE; + } + + /* read each entry in the toc header */ + for (i = 1; i < toc_header.cdth_trk1; i++) { + toc_entry.cdte_format = CDROM_MSF; + toc_entry.cdte_track = i; + + if (ioctl(cd->fd,CDROMREADTOCENTRY,&toc_entry) != 0) { + return FALSE; + } + + cd->tracks[i].minute = toc_entry.cdte_addr.msf.minute; + cd->tracks[i].second = toc_entry.cdte_addr.msf.second; + cd->tracks[i].frame = toc_entry.cdte_addr.msf.frame; + cd->tracks[i].data_track = (toc_entry.cdte_ctrl == CDROM_DATA_TRACK); + } + + /* read the leadout */ + toc_entry.cdte_track = CDROM_LEADOUT; + toc_entry.cdte_format = CDROM_MSF; + if (ioctl(cd->fd,CDROMREADTOCENTRY,&toc_entry) != 0) { + return FALSE; + } + cd->tracks[LEADOUT].minute = toc_entry.cdte_addr.msf.minute; + cd->tracks[LEADOUT].second = toc_entry.cdte_addr.msf.second; + cd->tracks[LEADOUT].frame = toc_entry.cdte_addr.msf.frame; + + cd->num_tracks = toc_header.cdth_trk1; + + return TRUE; +} + +gboolean cd_start(struct cd *cd,guint start_track) +{ + struct cdrom_msf msf; + + if (cd->fd == -1) { + return FALSE; + } + + if (start_track <= 0) { + start_track = 1; + } + + if (start_track > cd->num_tracks) { + start_track = cd->num_tracks; + } + + msf.cdmsf_min0 = cd->tracks[start_track].minute; + msf.cdmsf_sec0 = cd->tracks[start_track].second; + msf.cdmsf_frame0 = cd->tracks[start_track].frame; + + msf.cdmsf_min1 = cd->tracks[LEADOUT].minute; + msf.cdmsf_sec1 = cd->tracks[LEADOUT].second; + msf.cdmsf_frame1 = cd->tracks[LEADOUT].frame; + + if (ioctl(cd->fd,CDROMPLAYMSF,&msf) != 0) { + return FALSE; + } + + return TRUE; +} + +gboolean cd_pause(struct cd *cd) +{ + if (cd->fd == -1) { + return FALSE; + } + + if (ioctl(cd->fd,CDROMPAUSE,NULL) != 0) { + return FALSE; + } + + return TRUE; +} + +gboolean cd_resume(struct cd *cd) +{ + if (cd->fd == -1) { + return FALSE; + } + + if (ioctl(cd->fd,CDROMRESUME,NULL) != 0) { + return FALSE; + } + + return TRUE; +} + +gboolean cd_stop(struct cd *cd) +{ + if (cd->fd == -1) { + return FALSE; + } + + if (ioctl(cd->fd,CDROMSTOP,NULL) != 0) { + return FALSE; + } + + return TRUE; +} + + +gboolean cd_close(struct cd *cd) +{ + if (cd->fd == -1) { + return TRUE; + } + + if (close(cd->fd) != 0) { + return FALSE; + } + + return TRUE; +} + diff --git a/sys/cdrom/gstcdplayer_ioctl.h b/sys/cdrom/gstcdplayer_ioctl.h new file mode 100644 index 00000000..7d96925c --- /dev/null +++ b/sys/cdrom/gstcdplayer_ioctl.h @@ -0,0 +1,58 @@ +/* gstcdplay + * Copyright (c) 2002 Charles Schmidt <cbschmid@uiuc.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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __CDPLAYER_IOCTL_H__ +#define __CDPLAYER_IOCTL_H__ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> + +#define LEADOUT 0 + +#define CDPLAYER_CD(cdp) (&(cdp->cd)) + +#define CDPLAYER_MAX_TRACKS 128 + +struct cd_msf { + guint8 minute; + guint8 second; + guint8 frame; + + gboolean data_track; +}; + +struct cd { + gint fd; + gint num_tracks; + struct cd_msf tracks[CDPLAYER_MAX_TRACKS]; +}; + +gboolean cd_init(struct cd *cd,const gchar *device); +gboolean cd_start(struct cd *cd,guint start_track); +gboolean cd_pause(struct cd *cd); +gboolean cd_resume(struct cd *cd); +gboolean cd_stop(struct cd *cd); +gboolean cd_close(struct cd *cd); + +#endif + + |