diff --git a/ext/cdparanoia/gstcdparanoia.c b/ext/cdparanoia/gstcdparanoia.c index c1a7bc68a7..2ea371c470 100644 --- a/ext/cdparanoia/gstcdparanoia.c +++ b/ext/cdparanoia/gstcdparanoia.c @@ -34,9 +34,9 @@ #include /* taken from linux/cdrom.h */ -#define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */ -#define CD_SECS 60 /* seconds per minute */ -#define CD_FRAMES 75 /* frames per second */ +#define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */ +#define CD_SECS 60 /* seconds per minute */ +#define CD_FRAMES 75 /* frames per second */ #include "gstcdparanoia.h" @@ -58,15 +58,15 @@ GST_PAD_TEMPLATE_FACTORY (cdparanoia_src_factory, GST_CAPS_NEW ( "cdparanoia_src", "audio/raw", - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), - "endianness", GST_PROPS_INT (G_BYTE_ORDER), - "signed", GST_PROPS_BOOLEAN (TRUE), - "width", GST_PROPS_INT (16), - "depth", GST_PROPS_INT (16), - "rate", GST_PROPS_INT (44100), - "channels", GST_PROPS_INT (2), - "chunksize", GST_PROPS_INT (CD_FRAMESIZE_RAW) + "format", GST_PROPS_STRING ("int"), + "law", GST_PROPS_INT (0), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), + "signed", GST_PROPS_BOOLEAN (TRUE), + "width", GST_PROPS_INT (16), + "depth", GST_PROPS_INT (16), + "rate", GST_PROPS_INT (44100), + "channels", GST_PROPS_INT (2), + "chunksize", GST_PROPS_INT (CD_FRAMESIZE_RAW) ) ); @@ -78,42 +78,50 @@ gst_paranoia_mode_get_type (void) { static GType paranoia_mode_type = 0; static GEnumValue paranoia_modes[] = { - { 0, "0", "Disable paranoid checking" }, - { 1, "1", "cdda2wav-style overlap checking" }, - { 2, "2", "Full paranoia" }, - { 0, NULL, NULL }, + {0, "0", "Disable paranoid checking"}, + {1, "1", "cdda2wav-style overlap checking"}, + {2, "2", "Full paranoia"}, + {0, NULL, NULL}, }; + if (!paranoia_mode_type) { paranoia_mode_type = g_enum_register_static ("GstParanoiaMode", paranoia_modes); } return paranoia_mode_type; } +#define GST_TYPE_PARANOIA_ENDIAN (gst_paranoia_endian_get_type()) +static GType +gst_paranoia_endian_get_type (void) +{ + static GType paranoia_endian_type = 0; + static GEnumValue paranoia_endians[] = { + {0, "0", "treat drive as little endian"}, + {1, "1", "treat drive as big endian"}, + {0, NULL, NULL}, + }; + + if (!paranoia_endian_type) { + paranoia_endian_type = g_enum_register_static ("GstParanoiaEndian", paranoia_endians); + } + return paranoia_endian_type; +} /********** Standard stuff for signals and arguments **********/ /* CDParanoia signals and args */ -enum { +enum +{ SMILIE_CHANGE, TRANSPORT_ERROR, UNCORRECTED_ERROR, LAST_SIGNAL }; -enum { +enum +{ ARG_0, ARG_LOCATION, ARG_GENERIC_DEVICE, -/* - ARG_START_TRACK, - ARG_END_TRACK, -*/ - ARG_LAST_TRACK, - ARG_CUR_TRACK, -/* - ARG_START_SECTOR, - ARG_END_SECTOR, -*/ - ARG_CUR_SECTOR, ARG_DEFAULT_SECTORS, ARG_SEARCH_OVERLAP, ARG_ENDIAN, @@ -124,37 +132,40 @@ enum { ARG_ABORT_ON_SKIP, ARG_PARANOIA_MODE, ARG_SMILIE, - ARG_NO_TRACKS, - ARG_DISCID, - ARG_OFFSETS, - ARG_TOTAL_TIME, + ARG_DISCID }; -static void cdparanoia_class_init (CDParanoiaClass *klass); -static void cdparanoia_init (CDParanoia *cdparanoia); +static void cdparanoia_class_init (CDParanoiaClass *klass); +static void cdparanoia_init (CDParanoia *cdparanoia); -static void cdparanoia_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void cdparanoia_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void cdparanoia_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void cdparanoia_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); -static GstBuffer* cdparanoia_get (GstPad *pad); -static gboolean cdparanoia_event (GstPad *pad, GstEvent *event); -static const GstEventMask *cdparanoia_get_event_mask (GstPad *pad); -static const GstFormat *cdparanoia_get_formats (GstPad *pad); -static gboolean cdparanoia_convert (GstPad *pad, - GstFormat src_format, - gint64 src_value, - GstFormat *dest_format, - gint64 *dest_value); +static GstBuffer* cdparanoia_get (GstPad *pad); +static gboolean cdparanoia_event (GstPad *pad, GstEvent *event); +static const GstEventMask* + cdparanoia_get_event_mask (GstPad *pad); +static const GstFormat* + cdparanoia_get_formats (GstPad *pad); +static gboolean cdparanoia_convert (GstPad *pad, + GstFormat src_format, + gint64 src_value, + GstFormat *dest_format, + gint64 *dest_value); +static gboolean cdparanoia_query (GstPad *pad, GstPadQueryType type, + GstFormat *format, gint64 *value); - -static GstElementStateReturn cdparanoia_change_state (GstElement *element); +static GstElementStateReturn cdparanoia_change_state (GstElement *element); static GstElementClass *parent_class = NULL; static guint cdparanoia_signals[LAST_SIGNAL] = { 0 }; static GstFormat track_format; +static GstFormat sector_format; GType cdparanoia_get_type (void) @@ -163,15 +174,16 @@ cdparanoia_get_type (void) if (!cdparanoia_type) { static const GTypeInfo cdparanoia_info = { - sizeof(CDParanoiaClass), NULL, + sizeof (CDParanoiaClass), NULL, NULL, - (GClassInitFunc)cdparanoia_class_init, + (GClassInitFunc) cdparanoia_class_init, NULL, NULL, - sizeof(CDParanoia), + sizeof (CDParanoia), 0, - (GInstanceInitFunc)cdparanoia_init, + (GInstanceInitFunc) cdparanoia_init, }; + cdparanoia_type = g_type_register_static (GST_TYPE_ELEMENT, "CDParanoia", &cdparanoia_info, 0); } return cdparanoia_type; @@ -183,98 +195,70 @@ cdparanoia_class_init (CDParanoiaClass *klass) GObjectClass *gobject_class; GstElementClass *gstelement_class; char *success = strerror_tr[0]; + success = NULL; - gobject_class = (GObjectClass*)klass; - gstelement_class = (GstElementClass*)klass; + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; parent_class = g_type_class_ref (GST_TYPE_ELEMENT); cdparanoia_signals[SMILIE_CHANGE] = - g_signal_new ("smilie_change", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CDParanoiaClass, smilie_change), NULL, NULL, - g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); + g_signal_new ("smilie_change", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CDParanoiaClass, smilie_change), NULL, NULL, + g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); cdparanoia_signals[TRANSPORT_ERROR] = - g_signal_new ("transport_error", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CDParanoiaClass, transport_error), NULL, NULL, - g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + g_signal_new ("transport_error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CDParanoiaClass, transport_error), NULL, NULL, + g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); cdparanoia_signals[UNCORRECTED_ERROR] = - g_signal_new ("uncorrected_error", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CDParanoiaClass, uncorrected_error), NULL, NULL, - g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + g_signal_new ("uncorrected_error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CDParanoiaClass, uncorrected_error), NULL, NULL, + g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_LOCATION, - g_param_spec_string("location","location","location", - NULL, G_PARAM_READWRITE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_GENERIC_DEVICE, - g_param_spec_string("generic_device","generic_device","generic_device", - NULL, G_PARAM_READWRITE)); /* CHECKME */ -#if 0 - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_START_TRACK, - g_param_spec_int("start_track","start_track","start_track", - G_MININT,G_MAXINT,1,G_PARAM_READWRITE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_END_TRACK, - g_param_spec_int("end_track","end_track","end_track", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */ -#endif - - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_LAST_TRACK, - g_param_spec_int("last_track","last_track","last_track", - G_MININT,G_MAXINT,0,G_PARAM_READABLE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CUR_TRACK, - g_param_spec_int("cur_track","cur_track","cur_track", - G_MININT,G_MAXINT,0,G_PARAM_READABLE)); /* CHECKME */ -#if 0 - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_START_SECTOR, - g_param_spec_int("start_sector","start_sector","start_sector", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_END_SECTOR, - g_param_spec_int("end_sector","end_sector","end_sector", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */ -#endif - - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CUR_SECTOR, - g_param_spec_int("cur_sector","cur_sector","cur_sector", - G_MININT,G_MAXINT,0,G_PARAM_READABLE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEFAULT_SECTORS, - g_param_spec_int("default_sectors","default_sectors","default_sectors", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SEARCH_OVERLAP, - g_param_spec_int("search_overlap","search_overlap","search_overlap", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_ENDIAN, - g_param_spec_int("endian","endian","endian", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_READ_SPEED, - g_param_spec_int("read_speed","read_speed","read_speed", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */ + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOCATION, + g_param_spec_string ("location", "location", "location", + NULL, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_GENERIC_DEVICE, + g_param_spec_string ("generic_device", "Generic device", "Use specified generic scsi device", + NULL, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DEFAULT_SECTORS, + g_param_spec_int ("default_sectors", "Default sectors", + "Force default number of sectors in read to n sectors", + 0, G_MAXINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SEARCH_OVERLAP, + g_param_spec_int ("search_overlap", "Search overlap", + "Force minimum overlap search during verification to n sectors", + 0, G_MAXINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ENDIAN, + g_param_spec_enum ("endian", "Endian", "Force endian on drive", + GST_TYPE_PARANOIA_ENDIAN, 0, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_READ_SPEED, + g_param_spec_int ("read_speed", "Read speed", "Read from device at specified speed", + G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)); g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_TOC_OFFSET, - g_param_spec_int("toc_offset","toc_offset","toc_offset", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */ + g_param_spec_int("toc_offset", "TOC offset", "Add sectors to the values reported", + G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_TOC_BIAS, - g_param_spec_boolean("toc_bias","toc_bias","toc_bias", - TRUE,G_PARAM_READWRITE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NEVER_SKIP, - g_param_spec_boolean("never_skip","never_skip","never_skip", - TRUE,G_PARAM_READWRITE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_ABORT_ON_SKIP, - g_param_spec_boolean("abort_on_skip","abort_on_skip","abort_on_skip", - TRUE,G_PARAM_READWRITE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_PARANOIA_MODE, - g_param_spec_enum("paranoia_mode","paranoia_mode","paranoia_mode", - GST_TYPE_PARANOIA_MODE,0,G_PARAM_READWRITE)); /* CHECKME! */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NO_TRACKS, - g_param_spec_int("no_tracks","no_tracks","no_tracks", - 0,G_MAXINT,0,G_PARAM_READABLE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DISCID, - g_param_spec_string("discid","discid","discid", - NULL, G_PARAM_READABLE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_OFFSETS, - g_param_spec_string("offsets","offsets","offsets", - NULL, G_PARAM_READABLE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_TOTAL_TIME, - g_param_spec_string("total_time","total_time","total_time", - NULL, G_PARAM_READABLE)); + g_param_spec_boolean("toc_bias", "TOC bias", + "Assume that the beginning offset of track 1 as reported in the TOC " + "will be addressed as LBA 0. Necessary for some Toshiba drives to " + "get track boundaries", + TRUE,G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NEVER_SKIP, + g_param_spec_int ("never_skip", "Never skip", + "never accept any less than perfect data reconstruction (don't allow " + "'V's) but if [n] is given, skip after [n] retries without progress.", + 0, G_MAXINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ABORT_ON_SKIP, + g_param_spec_boolean ("abort_on_skip", "Abort on skip", "Abort on imperfect reads/skips", + TRUE, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PARANOIA_MODE, + g_param_spec_enum ("paranoia_mode", "Paranoia mode", "Type of checking to perform", + GST_TYPE_PARANOIA_MODE, 0, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DISCID, + g_param_spec_string ("discid", "discid", "The dics id", + NULL, G_PARAM_READABLE)); gobject_class->set_property = cdparanoia_set_property; gobject_class->get_property = cdparanoia_get_property; @@ -285,14 +269,15 @@ cdparanoia_class_init (CDParanoiaClass *klass) static void cdparanoia_init (CDParanoia *cdparanoia) { - cdparanoia->srcpad = gst_pad_new_from_template ( - GST_PAD_TEMPLATE_GET (cdparanoia_src_factory), "src"); + cdparanoia->srcpad = + gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (cdparanoia_src_factory), "src"); gst_pad_set_get_function (cdparanoia->srcpad, cdparanoia_get); - gst_pad_set_event_function (cdparanoia->srcpad, cdparanoia_event); - gst_pad_set_event_mask_function (cdparanoia->srcpad, cdparanoia_get_event_mask); - gst_pad_set_convert_function (cdparanoia->srcpad, cdparanoia_convert); - gst_pad_set_formats_function (cdparanoia->srcpad, cdparanoia_get_formats); - + gst_pad_set_event_function (cdparanoia->srcpad, cdparanoia_event); + gst_pad_set_event_mask_function (cdparanoia->srcpad, cdparanoia_get_event_mask); + gst_pad_set_convert_function (cdparanoia->srcpad, cdparanoia_convert); + gst_pad_set_query_function (cdparanoia->srcpad, cdparanoia_query); + gst_pad_set_formats_function (cdparanoia->srcpad, cdparanoia_get_formats); + gst_element_add_pad (GST_ELEMENT (cdparanoia), cdparanoia->srcpad); cdparanoia->device = g_strdup ("/dev/cdrom"); @@ -301,12 +286,11 @@ cdparanoia_init (CDParanoia *cdparanoia) cdparanoia->end_sector = -1; cdparanoia->cur_sector = -1; cdparanoia->start_track = -1; - cdparanoia->cur_track = -1; cdparanoia->end_track = -1; cdparanoia->last_track = -1; cdparanoia->default_sectors = -1; cdparanoia->search_overlap = -1; - cdparanoia->endian = -1; + cdparanoia->endian = 0; cdparanoia->read_speed = -1; cdparanoia->toc_offset = 0; cdparanoia->toc_bias = FALSE; @@ -317,10 +301,8 @@ cdparanoia_init (CDParanoia *cdparanoia) cdparanoia->cur_sector = 0; cdparanoia->seq = 0; - cdparanoia->no_tracks=0; - cdparanoia->discid=NULL; - cdparanoia->offsets=NULL; - cdparanoia->total_seconds=0; + cdparanoia->no_tracks = 0; + cdparanoia->total_seconds = 0; } @@ -336,48 +318,26 @@ cdparanoia_set_property (GObject *object, guint prop_id, const GValue *value, GP switch (prop_id) { case ARG_LOCATION: - if (src->device) g_free (src->device); + if (src->device) + g_free (src->device); /* clear the filename if we get a NULL (is that possible?) */ - if (!g_ascii_strcasecmp( g_value_get_string (value),"")) - src->device = NULL; + if (!g_ascii_strcasecmp (g_value_get_string (value), "")) + src->device = NULL; /* otherwise set the new filename */ else - src->device = g_strdup (g_value_get_string (value)); + src->device = g_strdup (g_value_get_string (value)); break; case ARG_GENERIC_DEVICE: - if (src->generic_device) g_free (src->generic_device); + if (src->generic_device) + g_free (src->generic_device); /* reset the device if we get a NULL (is that possible?) */ - if (!g_ascii_strcasecmp( g_value_get_string (value),"")) - src->generic_device = NULL; + if (!g_ascii_strcasecmp (g_value_get_string (value), "")) + src->generic_device = NULL; /* otherwise set the new filename */ else - src->generic_device = g_strdup (g_value_get_string (value)); + src->generic_device = g_strdup (g_value_get_string (value)); break; - -#if 0 - case ARG_START_SECTOR: - src->start_sector = g_value_get_int (value); - src->cur_sector = src->start_sector; - paranoia_seek (src->p, src->start_sector, SEEK_SET); - break; - case ARG_END_SECTOR: - src->end_sector = g_value_get_int (value); - break; - case ARG_START_TRACK: - src->start_track = g_value_get_int (value); - /* Override the start_sector */ - src->start_sector = cdda_track_firstsector (src->d, src->start_track); - src->cur_sector = src->start_sector; - paranoia_seek (src->p, src->start_sector, SEEK_SET); - break; - case ARG_END_TRACK: - src->end_track = g_value_get_int (value); - /* Override the end_sector */ - src->end_sector = cdda_track_lastsector (src->d, src->end_track); - break; -#endif - case ARG_DEFAULT_SECTORS: src->default_sectors = g_value_get_int (value); break; @@ -385,11 +345,11 @@ cdparanoia_set_property (GObject *object, guint prop_id, const GValue *value, GP src->search_overlap = g_value_get_int (value); break; case ARG_ENDIAN: - src->endian = g_value_get_int (value); + src->endian = g_value_get_enum (value); break; case ARG_READ_SPEED: src->read_speed = g_value_get_int (value); - cdda_speed_set (src->d, src->read_speed); + cdda_speed_set (src->d, src->read_speed); break; case ARG_TOC_OFFSET: src->toc_offset = g_value_get_int (value); @@ -398,7 +358,7 @@ cdparanoia_set_property (GObject *object, guint prop_id, const GValue *value, GP src->toc_bias = g_value_get_boolean (value); break; case ARG_NEVER_SKIP: - src->never_skip = g_value_get_boolean (value); + src->never_skip = g_value_get_int (value); break; case ARG_ABORT_ON_SKIP: src->abort_on_skip = g_value_get_boolean (value); @@ -428,31 +388,6 @@ cdparanoia_get_property (GObject *object, guint prop_id, GValue *value, GParamSp case ARG_GENERIC_DEVICE: g_value_set_string (value, src->generic_device); break; -#if 0 - case ARG_START_SECTOR: - g_value_set_int (value, src->start_sector); - break; - case ARG_END_SECTOR: - g_value_set_int (value, src->end_sector); - break; -#endif - case ARG_CUR_SECTOR: - g_value_set_int (value, src->cur_sector); - break; -#if 0 - case ARG_START_TRACK: - g_value_set_int (value, src->start_track); - break; - case ARG_END_TRACK: - g_value_set_int (value, src->end_track); - break; -#endif - case ARG_CUR_TRACK: - g_value_set_int (value, src->cur_track); - break; - case ARG_LAST_TRACK: - g_value_set_int (value, src->last_track); - break; case ARG_DEFAULT_SECTORS: g_value_set_int (value, src->default_sectors); break; @@ -460,7 +395,7 @@ cdparanoia_get_property (GObject *object, guint prop_id, GValue *value, GParamSp g_value_set_int (value, src->search_overlap); break; case ARG_ENDIAN: - g_value_set_int (value, src->endian); + g_value_set_enum (value, src->endian); break; case ARG_READ_SPEED: g_value_set_int (value, src->read_speed); @@ -472,7 +407,7 @@ cdparanoia_get_property (GObject *object, guint prop_id, GValue *value, GParamSp g_value_set_boolean (value, src->toc_bias); break; case ARG_NEVER_SKIP: - g_value_set_boolean (value, src->never_skip); + g_value_set_int (value, src->never_skip); break; case ARG_ABORT_ON_SKIP: g_value_set_boolean (value, src->abort_on_skip); @@ -480,17 +415,8 @@ cdparanoia_get_property (GObject *object, guint prop_id, GValue *value, GParamSp case ARG_PARANOIA_MODE: g_value_set_enum (value, src->paranoia_mode); break; - case ARG_NO_TRACKS: - g_value_set_int (value, src->no_tracks); - break; case ARG_DISCID: - g_value_set_string(value, src->discid); - break; - case ARG_OFFSETS: - g_value_set_string(value, src->offsets); - break; - case ARG_TOTAL_TIME: - g_value_set_string(value, src->total_seconds); + g_value_set_string (value, src->discid); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -498,10 +424,12 @@ cdparanoia_get_property (GObject *object, guint prop_id, GValue *value, GParamSp } } -static void cdparanoia_callback(long inpos, int function) { +static void +cdparanoia_callback (long inpos, int function) +{ } -static GstBuffer* +static GstBuffer * cdparanoia_get (GstPad *pad) { CDParanoia *src; @@ -513,31 +441,23 @@ cdparanoia_get (GstPad *pad) g_return_val_if_fail (GST_FLAG_IS_SET (src, CDPARANOIA_OPEN), NULL); /* read a sector */ -/* NOTE: if you have a patched cdparanoia, set this to 1 to save cycles */ -#if 0 - cdda_buf = paranoia_read (src->p, NULL); -#else cdda_buf = paranoia_read (src->p, cdparanoia_callback); -#endif /* update current sector and stop things if appropriate */ src->cur_sector++; if (src->cur_sector == src->end_sector) { - GST_DEBUG (0,"setting EOS"); - gst_element_set_eos(GST_ELEMENT(src)); + GST_DEBUG (0, "setting EOS"); + gst_element_set_eos (GST_ELEMENT (src)); buf = GST_BUFFER (gst_event_new (GST_EVENT_EOS)); - } - else { - src->cur_track = cdda_sector_gettrack( src->d, src->cur_sector ); - + } else { /* have to copy the buffer for now since we don't own it... */ /* FIXME must ask monty about allowing ownership transfer */ buf = gst_buffer_new_and_alloc (CD_FRAMESIZE_RAW); memcpy (GST_BUFFER_DATA (buf), cdda_buf, CD_FRAMESIZE_RAW); - GST_BUFFER_TIMESTAMP (buf) = ((CD_FRAMESIZE_RAW >> 2 ) * src->seq * GST_SECOND) / 44100; + GST_BUFFER_TIMESTAMP (buf) = ((CD_FRAMESIZE_RAW >> 2) * src->seq * GST_SECOND) / 44100; src->seq++; } @@ -551,82 +471,83 @@ typedef int byte; typedef struct { - byte m; - byte s; - byte f; -}toc_msf; + byte m; + byte s; + byte f; +} +toc_msf; /* cdparanoia provides the toc in lba format dang we need it in msf so * we have to convert it */ -static inline void lba_to_msf (const gint lba, byte *m, byte *s, byte *f) +static inline void +lba_to_msf (const gint lba, byte *m, byte *s, byte *f) { - gint lba2 = lba; - lba2 += CD_MSF_OFFSET; - lba2 &= 0xffffff; - *m = lba2 / (CD_SECS * CD_FRAMES); - lba2 %= (CD_SECS * CD_FRAMES); - *s = lba2 / CD_FRAMES; - *f = lba2 % CD_FRAMES; - *f += (*m)*60*75; - *f += (*s)*75; + gint lba2 = lba; + + lba2 += CD_MSF_OFFSET; + lba2 &= 0xffffff; + *m = lba2 / (CD_SECS * CD_FRAMES); + lba2 %= (CD_SECS * CD_FRAMES); + *s = lba2 / CD_FRAMES; + *f = lba2 % CD_FRAMES; + *f += (*m) * 60 * 75; + *f += (*s) * 75; } -static void +static void lba_toc_to_msf_toc (TOC *lba_toc, toc_msf *msf_toc, gint tracks) { - gint i; - for (i =0; i <= tracks; i++) - lba_to_msf(lba_toc[i].dwStartSector,&msf_toc[i].m, - &msf_toc[i].s, &msf_toc[i].f); + gint i; + + for (i = 0; i <= tracks; i++) + lba_to_msf (lba_toc[i].dwStartSector, &msf_toc[i].m, &msf_toc[i].s, &msf_toc[i].f); } /* the cddb hash function */ static guint -cddb_sum(gint n) +cddb_sum (gint n) { - guint ret; - ret = 0; - while (n > 0) - { - ret += (n % 10); - n /= 10; - } - return ret; + guint ret; + + ret = 0; + while (n > 0) { + ret += (n % 10); + n /= 10; + } + return ret; } -static void -cddb_discid(gchar *discid,toc_msf *toc, gint tracks) +static void +cddb_discid (gchar *discid, toc_msf *toc, gint tracks) { - guint i = 0, t = 0, n = 0; + guint i = 0, t = 0, n = 0; - while (i < tracks) - { - n = n + cddb_sum((toc[i].m * 60) + toc[i].s); - i++; - } - t = ((toc[tracks].m * 60) + toc[tracks].s) - ((toc[0].m * 60) - + toc[0].s); - - sprintf (discid,"%08x",(( n % 0xff) << 24 | t << 8 | tracks)); + while (i < tracks) { + n = n + cddb_sum ((toc[i].m * 60) + toc[i].s); + i++; + } + t = ((toc[tracks].m * 60) + toc[tracks].s) - ((toc[0].m * 60) + + toc[0].s); + sprintf (discid, "%08x", ((n % 0xff) << 24 | t << 8 | tracks)); } /* get all the cddb info at once */ -static void -get_cddb_info(TOC *toc, gint tracks,gchar *discid, gchar *offsets, - gchar *total_seconds) +static void +get_cddb_info (TOC *toc, gint tracks, gchar *discid, gint64 *offsets, gint64 *total_seconds) { - toc_msf msf_toc[MAXTRK]; - gint i; - gchar *p = offsets; + toc_msf msf_toc[MAXTRK]; + gint i; + gint64 *p = offsets; - lba_toc_to_msf_toc(toc, &msf_toc[0],tracks); - cddb_discid ( discid, &msf_toc[0], tracks); + lba_toc_to_msf_toc (toc, &msf_toc[0], tracks); + cddb_discid (discid, &msf_toc[0], tracks); - for (i = 0; i < tracks; i++) - p = (p + sprintf (p, " %d", msf_toc[i].f)) ; + for (i = 0; i < tracks; i++) { + *p++ = msf_toc[i].f; + } + + *total_seconds = msf_toc[tracks].f / 75; - sprintf (total_seconds, "%d", msf_toc[tracks].f/75); - } /* open the file, necessary to go to RUNNING state */ @@ -638,7 +559,7 @@ cdparanoia_open (CDParanoia *src) g_return_val_if_fail (!GST_FLAG_IS_SET (src, CDPARANOIA_OPEN), FALSE); - GST_DEBUG_ENTER("(\"%s\",...)", gst_element_get_name (GST_ELEMENT (src))); + GST_DEBUG_ENTER ("(\"%s\",...)", gst_element_get_name (GST_ELEMENT (src))); /* find the device */ if (src->generic_device != NULL) { @@ -653,7 +574,7 @@ cdparanoia_open (CDParanoia *src) /* fail if the device couldn't be found */ if (src->d == NULL) { - GST_DEBUG (0,"couldn't open device"); + GST_DEBUG (0, "couldn't open device"); return FALSE; } @@ -663,7 +584,7 @@ cdparanoia_open (CDParanoia *src) /* set various other parameters */ if (src->default_sectors != -1) { if ((src->default_sectors < 0) || (src->default_sectors > 100)) { - GST_DEBUG (0,"default sector read size must be 1 <= n <= 100"); + GST_DEBUG (0, "default sector read size must be 1 <= n <= 100"); cdda_close (src->d); src->d = NULL; return FALSE; @@ -674,7 +595,7 @@ cdparanoia_open (CDParanoia *src) } if (src->search_overlap != -1) { if ((src->search_overlap < 0) || (src->search_overlap > 75)) { - GST_DEBUG (0,"search overlap must be 0 <= n <= 75"); + GST_DEBUG (0, "search overlap must be 0 <= n <= 75"); cdda_close (src->d); src->d = NULL; return FALSE; @@ -683,7 +604,7 @@ cdparanoia_open (CDParanoia *src) /* open the disc */ if (cdda_open (src->d)) { - GST_DEBUG (0,"couldn't open disc"); + GST_DEBUG (0, "couldn't open disc"); cdda_close (src->d); src->d = NULL; return FALSE; @@ -692,32 +613,21 @@ cdparanoia_open (CDParanoia *src) /* set up some more stuff */ src->no_tracks = src->d->tracks; - g_assert(src->discid == NULL); - g_assert(src->offsets == NULL); - g_assert(src->total_seconds == NULL); - /* I don't like this here i would prefer it under get_cddb_info but for somereason * when leaving the function it clobbers the allocated mem and all is lost bugger - */ - - src->discid = g_new0(gchar,20) ; - /* FIXME convert to pad_query/convert */ - src->offsets = g_new0(gchar,4096); - src->total_seconds = g_new0(gchar, 4); + */ - get_cddb_info(&src->d->disc_toc[0], src->no_tracks,src->discid, - src->offsets,src->total_seconds); + get_cddb_info (&src->d->disc_toc[0], src->no_tracks, src->discid, + src->offsets, &src->total_seconds); g_object_freeze_notify (G_OBJECT (src)); g_object_notify (G_OBJECT (src), "discid"); - g_object_notify (G_OBJECT (src), "offsets"); - g_object_notify (G_OBJECT (src), "total-time"); g_object_thaw_notify (G_OBJECT (src)); - + if (src->toc_bias) { src->toc_offset -= cdda_track_firstsector (src->d, 1); } - for (i=0;id->tracks + 1;i++) { + for (i = 0; i < src->d->tracks + 1; i++) { src->d->disc_toc[i].dwStartSector += src->toc_offset; } @@ -728,14 +638,14 @@ cdparanoia_open (CDParanoia *src) /* if the start_track is set, override the start_sector */ if (src->start_track != -1) { src->start_sector = cdda_track_firstsector (src->d, src->start_track); - /* if neither start_track nor start_sector is set, */ + /* if neither start_track nor start_sector is set, */ } else if (src->start_sector == -1) { src->start_sector = cdda_disc_firstsector (src->d); } /* if the end_track is set, override the end_sector */ if (src->end_track != -1) { src->end_sector = cdda_track_lastsector (src->d, src->end_track); - /* if neither end_track nor end_sector is set, */ + /* if neither end_track nor end_sector is set, */ } else if (src->end_sector == -1) { src->end_sector = cdda_disc_lastsector (src->d); } @@ -746,14 +656,18 @@ cdparanoia_open (CDParanoia *src) /* create the paranoia struct and set it up */ src->p = paranoia_init (src->d); if (src->p == NULL) { - GST_DEBUG (0,"couldn't create paranoia struct"); + GST_DEBUG (0, "couldn't create paranoia struct"); return FALSE; } - if (src->paranoia_mode == 0) paranoia_mode = PARANOIA_MODE_DISABLE; - else if (src->paranoia_mode == 1) paranoia_mode = PARANOIA_MODE_OVERLAP; - else paranoia_mode = PARANOIA_MODE_FULL; - if (src->never_skip) paranoia_mode |= PARANOIA_MODE_NEVERSKIP; + if (src->paranoia_mode == 0) + paranoia_mode = PARANOIA_MODE_DISABLE; + else if (src->paranoia_mode == 1) + paranoia_mode = PARANOIA_MODE_OVERLAP; + else + paranoia_mode = PARANOIA_MODE_FULL; + if (src->never_skip) + paranoia_mode |= PARANOIA_MODE_NEVERSKIP; paranoia_modeset (src->p, paranoia_mode); if (src->search_overlap != -1) { @@ -762,11 +676,11 @@ cdparanoia_open (CDParanoia *src) src->cur_sector = src->start_sector; paranoia_seek (src->p, src->cur_sector, SEEK_SET); - GST_DEBUG (0,"successfully seek'd to beginning of disk"); + GST_DEBUG (0, "successfully seek'd to beginning of disk"); GST_FLAG_SET (src, CDPARANOIA_OPEN); - GST_DEBUG_LEAVE(""); + GST_DEBUG_LEAVE (""); return TRUE; } @@ -780,15 +694,8 @@ cdparanoia_close (CDParanoia *src) /* kill the paranoia state */ paranoia_free (src->p); src->p = NULL; - - g_free(src->discid); - src->discid = NULL; - - g_free(src->offsets); - src->offsets = NULL; - - g_free(src->total_seconds); - src->total_seconds = NULL; + + src->total_seconds = 0LL; /* close the disc */ cdda_close (src->d); src->d = NULL; @@ -810,8 +717,8 @@ cdparanoia_change_state (GstElement *element) break; case GST_STATE_READY_TO_PAUSED: if (!cdparanoia_open (CDPARANOIA (element))) { - g_warning ("cdparanoia: failed opening cd"); - return GST_STATE_FAILURE; + g_warning ("cdparanoia: failed opening cd"); + return GST_STATE_FAILURE; } cdparanoia->seq = 0; break; @@ -839,147 +746,216 @@ cdparanoia_change_state (GstElement *element) static const GstEventMask * cdparanoia_get_event_mask (GstPad *pad) { - static const GstEventMask masks[] = { - { GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_METHOD_CUR }, - { 0, } - }; + static const GstEventMask masks[] = { + {GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_METHOD_CUR}, + {0,} + }; - return masks; + return masks; } static gboolean -cdparanoia_event (GstPad *pad, - GstEvent *event) +cdparanoia_event (GstPad *pad, GstEvent *event) { - CDParanoia *src; - gint64 offset, endoffset; - int format, start_sector, end_sector; - - src = CDPARANOIA (gst_pad_get_parent (pad)); + CDParanoia *src; + gint64 offset, endoffset; + int format, start_sector, end_sector; - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - format = GST_EVENT_SEEK_FORMAT (event); - offset = GST_EVENT_SEEK_OFFSET (event); + src = CDPARANOIA (gst_pad_get_parent (pad)); - if (format == GST_FORMAT_UNITS) { - start_sector = (int) offset; - } else if (format == track_format) { - start_sector = cdda_track_firstsector (src->d, (int) offset); - } else { - goto error; - } + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_SEEK: + format = GST_EVENT_SEEK_FORMAT (event); + offset = GST_EVENT_SEEK_OFFSET (event); - switch (GST_EVENT_SEEK_METHOD (event)) { - case GST_SEEK_METHOD_SET: - src->start_sector = start_sector;; - src->cur_sector = src->start_sector; + if (format == sector_format) { + start_sector = (int) offset; + } + else if (format == track_format) { + start_sector = cdda_track_firstsector (src->d, (int) offset); + } + else { + goto error; + } - paranoia_seek (src->p, src->start_sector, SEEK_SET); - GST_DEBUG (0, "seeked to %d", src->start_sector); - break; + switch (GST_EVENT_SEEK_METHOD (event)) { + case GST_SEEK_METHOD_SET: + src->start_sector = start_sector;; + src->cur_sector = src->start_sector; - case GST_SEEK_METHOD_CUR: - src->start_sector += start_sector; - src->cur_sector = src->start_sector; - - paranoia_seek (src->p, src->start_sector, SEEK_SET); - GST_DEBUG (0, "seeked to %d", src->start_sector); - break; + paranoia_seek (src->p, src->start_sector, SEEK_SET); + GST_DEBUG (0, "seeked to %d", src->start_sector); + break; + case GST_SEEK_METHOD_CUR: + src->start_sector += start_sector; + src->cur_sector = src->start_sector; - default: - break; - } - - break; - - case GST_EVENT_SEEK_SEGMENT: - format = GST_EVENT_SEEK_FORMAT (event); - offset = GST_EVENT_SEEK_OFFSET (event); - endoffset = GST_EVENT_SEEK_ENDOFFSET (event); - - if (format == GST_FORMAT_UNITS) { - start_sector = (int) offset; - end_sector = (int) endoffset; - } else if (format == track_format) { - start_sector = cdda_track_firstsector (src->d, (int) offset); - end_sector = cdda_track_lastsector (src->d, (int) endoffset); - } else { - goto error; - } - - /* Pretend these are tracks for testing */ - src->start_sector = start_sector; - src->end_sector = end_sector; - src->cur_sector = src->start_sector; - - paranoia_seek (src->p, src->start_sector, SEEK_SET); - GST_DEBUG (0, "seeked from %d to %d", src->start_sector, src->end_sector); - break; - + paranoia_seek (src->p, src->start_sector, SEEK_SET); + GST_DEBUG (0, "seeked to %d", src->start_sector); + break; default: - goto error; - break; - } - - return TRUE; + break; + } + break; + case GST_EVENT_SEEK_SEGMENT: + format = GST_EVENT_SEEK_FORMAT (event); + offset = GST_EVENT_SEEK_OFFSET (event); + endoffset = GST_EVENT_SEEK_ENDOFFSET (event); - error: - g_print ("Event error\n"); - return FALSE; + if (format == sector_format) { + start_sector = (int) offset; + end_sector = (int) endoffset; + } + else if (format == track_format) { + start_sector = cdda_track_firstsector (src->d, (int) offset); + end_sector = cdda_track_lastsector (src->d, (int) endoffset); + } + else { + goto error; + } + + /* Pretend these are tracks for testing */ + src->start_sector = start_sector; + src->end_sector = end_sector; + src->cur_sector = src->start_sector; + + paranoia_seek (src->p, src->start_sector, SEEK_SET); + GST_DEBUG (0, "seeked from %d to %d", src->start_sector, src->end_sector); + break; + default: + goto error; + break; + } + + gst_event_unref (event); + return TRUE; + +error: + g_print ("Event error\n"); + gst_event_unref (event); + return FALSE; } static const GstFormat * cdparanoia_get_formats (GstPad *pad) { - static const GstFormat formats[] = { - GST_FORMAT_TIME, - GST_FORMAT_UNITS, - 0 - }; + static GstFormat formats[] = { + GST_FORMAT_TIME, + GST_FORMAT_UNITS, + 0, + 0, + 0 + }; - return formats; + formats[2] = track_format; + formats[3] = sector_format; + + return formats; } static gboolean cdparanoia_convert (GstPad *pad, - GstFormat src_format, - gint64 src_value, - GstFormat *dest_format, - gint64 *dest_value) + GstFormat src_format, gint64 src_value, + GstFormat *dest_format, gint64 *dest_value) { - gboolean res = TRUE; - CDParanoia *src; + gboolean res = TRUE; + CDParanoia *src; - src = CDPARANOIA (gst_pad_get_parent (pad)); + src = CDPARANOIA (gst_pad_get_parent (pad)); - switch (src_format) { - case GST_FORMAT_TIME: - break; - - default: - break; + switch (src_format) { + case GST_FORMAT_TIME: + break; + case GST_FORMAT_UNITS: + break; + default: + if (src_format == track_format) { + switch (*dest_format) { + case GST_FORMAT_TIME: + *dest_value = src->offsets[src_value] / 75; + break; + case GST_FORMAT_UNITS: + break; + default: + break; } + } + else if (src_format == sector_format) { + } + else + res = FALSE; + break; + } - return res; + return res; } +static gboolean +cdparanoia_query (GstPad *pad, GstPadQueryType type, + GstFormat *format, gint64 *value) +{ + gboolean res = TRUE; + CDParanoia *src; + + src = CDPARANOIA (gst_pad_get_parent (pad)); + + if (!GST_FLAG_IS_SET (src, CDPARANOIA_OPEN)) + return FALSE; + + switch (type) { + case GST_PAD_QUERY_TOTAL: + switch (*format) { + case GST_FORMAT_TIME: + *value = src->total_seconds; + break; + case GST_FORMAT_UNITS: + res = FALSE; + break; + default: + if (*format == track_format) { + *value = src->no_tracks; + } + else if (*format == sector_format) { + *value = cdda_disc_lastsector (src->d); + } + else + res = FALSE; + break; + } + break; + case GST_PAD_QUERY_POSITION: + switch (*format) { + default: + break; + } + break; + default: + res = FALSE; + break; + } + return res; +} + + static gboolean plugin_init (GModule *module, GstPlugin *plugin) { GstElementFactory *factory; /* create an elementfactory for the cdparanoia element */ - factory = gst_element_factory_new ("cdparanoia", GST_TYPE_CDPARANOIA, - &cdparanoia_details); + factory = gst_element_factory_new ("cdparanoia", + GST_TYPE_CDPARANOIA, + &cdparanoia_details); g_return_val_if_fail (factory != NULL, FALSE); /* register the source's caps */ - gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (cdparanoia_src_factory)); + gst_element_factory_add_pad_template (factory, + GST_PAD_TEMPLATE_GET (cdparanoia_src_factory)); + + /* Register the track format */ + track_format = gst_format_register ("track", "CD track"); + sector_format = gst_format_register ("sector", "CD sector"); - /* Register the track format */ - track_format = gst_format_register ("track", "The CD track to select"); - /* and add the cdparanoia element factory to the plugin */ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); diff --git a/ext/cdparanoia/gstcdparanoia.h b/ext/cdparanoia/gstcdparanoia.h index ed2e43bbad..c6c86a5c3b 100644 --- a/ext/cdparanoia/gstcdparanoia.h +++ b/ext/cdparanoia/gstcdparanoia.h @@ -74,7 +74,7 @@ struct _CDParanoia { gchar *device; gchar *generic_device; - gint start_track, end_track, cur_track; + gint start_track, end_track; gint start_sector, end_sector; gint last_track; gint default_sectors; @@ -83,7 +83,7 @@ struct _CDParanoia { gint read_speed; gint toc_offset; gboolean toc_bias; - gboolean never_skip; + gint never_skip; gboolean abort_on_skip; gint paranoia_mode; @@ -95,9 +95,9 @@ struct _CDParanoia { /* hacks by Gordon Irving */ gint no_tracks; - gchar *discid; - gchar *offsets; - gchar *total_seconds; + gchar discid[20]; + gint64 offsets[MAXTRK]; + gint64 total_seconds; }; struct _CDParanoiaClass {