perl/Module-Build-Tiny: update to 0.051 for Perl 5.36 and 5.38
[oi-userland.git] / components / multimedia / gst-plugins-good / patches / 01-cdda.patch
bloba505dd538d228f89ff9ac52996457327c86ee69c
1 --- gst-plugins-good-0.10.13/configure.ac-orig 2009-01-23 10:02:53.003952000 -0600
2 +++ gst-plugins-good-0.10.13/configure.ac 2009-01-23 10:03:03.048601000 -0600
3 @@ -660,6 +668,24 @@ AG_GST_CHECK_FEATURE(CAIRO_GOBJECT,
4 AG_GST_PKG_CHECK_MODULES(CAIRO_GOBJECT, cairo-gobject >= 1.10.0)
5 ])
7 +dnl *** cdda2wav ***
8 +translit(dnm, m, l) AM_CONDITIONAL(USE_CDDA2WAV, true)
9 +AG_GST_CHECK_FEATURE(CDDA2WAV, [HAL libraries], cdda2wav, [
10 + AG_GST_PKG_CHECK_MODULES(CDDA2WAV, [hal >= 0.5.8, hal-storage >= 0.5.8, dbus-1 >= 0.32])
11 + AC_PATH_PROG(CDDA2WAVBIN, cdda2wav, no)
12 + if test x$CDDA2WAVBIN = xno; then
13 + HAVE_CDDA2WAV="no"
14 + else
15 + CDDA_VERSION=`$CDDA2WAVBIN --version | grep Schilling`
16 + if test -z "$CDDA_VERSION"; then
17 + HAVE_CDDA2WAV="no"
18 + else
19 + HAVE_CDDA2WAV="yes"
20 + fi
21 + fi
22 + AC_SUBST(HAVE_CDDA2WAV)
23 +])
25 dnl **** ESound ****
26 translit(dnm, m, l) AM_CONDITIONAL(USE_ESD, true)
27 AG_GST_CHECK_FEATURE(ESD, [ESounD sound daemon], esdsink, [
28 @@ -928,6 +954,7 @@ AM_CONDITIONAL(USE_DIRECTDRAW, false)
29 AM_CONDITIONAL(USE_DIRECTSOUND, false)
30 AM_CONDITIONAL(USE_DV1394, false)
31 AM_CONDITIONAL(USE_ESD, false)
32 +AM_CONDITIONAL(USE_CDDA2WAV, false)
33 AM_CONDITIONAL(USE_FLAC, false)
34 AM_CONDITIONAL(USE_GCONF, false)
35 AM_CONDITIONAL(USE_GCONFTOOL, false)
36 @@ -1055,6 +1083,7 @@ ext/Makefile
37 ext/aalib/Makefile
38 ext/annodex/Makefile
39 ext/cairo/Makefile
40 +ext/cdda2wav/Makefile
41 ext/dv/Makefile
42 ext/esd/Makefile
43 ext/flac/Makefile
44 --- gst-plugins-good-0.10.10/ext/Makefile.am-orig 2008-08-27 23:56:51.987944000 -0500
45 +++ gst-plugins-good-0.10.10/ext/Makefile.am 2008-08-27 23:57:20.124741000 -0500
46 @@ -16,6 +16,12 @@ else
47 CAIRO_DIR =
48 endif
50 +if USE_CDDA2WAV
51 +CDDA2WAV_DIR = cdda2wav
52 +else
53 +CDDA2WAV_DIR =
54 +endif
56 if USE_ESD
57 ESD_DIR = esd
58 else
59 @@ -131,6 +137,7 @@ SUBDIRS = \
60 $(CAIRO_DIR) \
61 $(DV1394_DIR) \
62 $(ESD_DIR) \
63 + $(CDDA2WAV_DIR) \
64 $(FLAC_DIR) \
65 $(GCONF_DIR) \
66 $(GDK_PIXBUF_DIR) \
67 --- /dev/null 2007-03-19 01:47:57.000000000 +0800
68 +++ gst-plugins-good-0.10.6/ext/cdda2wav/Makefile.am 2007-03-19 01:46:41.639278000 +0800
69 @@ -0,0 +1,20 @@
70 +plugin_LTLIBRARIES = libgstcdda2wav.la
72 +libgstcdda2wav_la_SOURCES = \
73 + gstcdda2wav.c
75 +libgstcdda2wav_la_CFLAGS = \
76 + $(GST_PLUGINS_BASE_CFLAGS) \
77 + $(GST_BASE_CFLAGS) \
78 + $(GST_CFLAGS) \
79 + $(CDDA2WAV_CFLAGS)
81 +libgstcdda2wav_la_LIBADD = \
82 + $(GST_PLUGINS_BASE_LIBS) -lgstcdda-$(GST_MAJORMINOR) \
83 + $(GST_BASE_LIBS) \
84 + $(CDDA2WAV_LIBS)
86 +libgstcdda2wav_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
88 +noinst_HEADERS = \
89 + gstcdda2wav.h
90 --- /dev/null 2008-12-19 17:50:06.000000000 -0600
91 +++ gst-plugins-good-0.10.6/ext/cdda2wav/gstcdda2wav.h 2008-07-17 07:48:57.000000000 -0500
92 @@ -0,0 +1,72 @@
93 +/* GStreamer
94 + * Copyright (C) 2007 Brian Cameron <Brian.Cameron@sun.com> and
95 + * Artem Kachitchkine <Artem.Kachitchkine@sun.com>
96 + * Copyright (C) 2008 J÷rg Schilling <Joerg.Schilling@fokus.fraunhofer.de>
97 + *
98 + * This library is free software; you can redistribute it and/or
99 + * modify it under the terms of the GNU Library General Public
100 + * License as published by the Free Software Foundation; either
101 + * version 2 of the License, or (at your option) any later version.
103 + * This library is distributed in the hope that it will be useful,
104 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
105 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
106 + * Library General Public License for more details.
108 + * You should have received a copy of the GNU Library General Public
109 + * License along with this library; if not, write to the
110 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
111 + * Boston, MA 02111-1307, USA.
112 + */
114 +#ifndef __GST_CDDA2WAV_H__
115 +#define __GST_CDDA2WAV_H__
117 +#include <sys/types.h>
118 +#include "gst/cdda/gstcddabasesrc.h"
120 +#define CDDA2WAV_BSIZE 2352
122 +G_BEGIN_DECLS
124 +#define GST_TYPE_CDDA2WAV (gst_cdda2wav_get_type())
125 +#define GST_CDDA2WAV(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CDDA2WAV,GstCdda2Wav))
126 +#define GST_CDDA2WAV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CDDA2WAV,GstCdda2WavClass))
127 +#define GST_IS_CDDA2WAV(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CDDA2WAV))
128 +#define GST_IS_CDDA2WAV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CDDA2WAV))
129 +#define GST_CDDA2WAV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CDDA2WAV, GstCdda2WavClass))
131 +typedef struct _GstCdda2Wav GstCdda2Wav;
132 +typedef struct _GstCdda2WavClass GstCdda2WavClass;
134 +#define CDDA2WAV_BSIZE 2352
136 +/**
137 + * GstCdda2Wav::
139 + * The cdda2wav object structure.
140 + */
141 +struct _GstCdda2Wav {
142 + GstCddaBaseSrc cddabasesrc;
144 + /*< private >*/
145 + FILE *cdda2wav_in;
146 + FILE *cdda2wav_out;
147 + FILE *cdda2wav_err;
148 + pid_t cdda2wav_pid;
149 + uint_t track_count;
150 + char **devices;
151 + char *current_device;
152 + boolean_t *has_audio;
155 +struct _GstCdda2WavClass {
156 + GstCddaBaseSrcClass parent_class;
159 +GType gst_cdda2wav_get_type (void);
161 +G_END_DECLS
163 +#endif /* __GST_CDDA2WAV_H__ */
165 --- /dev/null 2009-01-08 02:18:21.000000000 -0600
166 +++ gst-plugins-good-0.10.11/ext/cdda2wav/gstcdda2wav.c 2009-01-08 02:17:15.164536000 -0600
167 @@ -0,0 +1,795 @@
168 +/* GStreamer
169 + * Copyright (C) <2007> Brian Cameron <Brian.Cameron@sun.com> and
170 + * Artem Kachitchkine <Artem.Kachitchkine@sun.com>
171 + * Copyright (C) 2008 J÷rg Schilling <Joerg.Schilling@fokus.fraunhofer.de>
173 + * This library is free software; you can redistribute it and/or
174 + * modify it under the terms of the GNU Library General Public
175 + * License as published by the Free Software Foundation; either
176 + * version 2 of the License, or (at your option) any later version.
178 + * This library is distributed in the hope that it will be useful,
179 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
180 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
181 + * Library General Public License for more details.
183 + * You should have received a copy of the GNU Library General Public
184 + * License along with this library; if not, write to the
185 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
186 + * Boston, MA 02111-1307, USA.
187 + */
189 +/**
190 + * SECTION:element-cdda2wav
191 + * @short_description: Reads raw audio from an Audio CD
192 + * @see_also: GstCddaBaseSrc
194 + * <refsect2>
195 + * <para>
196 + * cdda2wav reads and extracts raw audio from Audio CDs using cdda2wav.
197 + * </para>
198 + * <title>Example launch line</title>
199 + * <para>
200 + * <programlisting>
201 + * gst-launch cdda2wav track=5 ! audioconvert ! vorbisenc ! oggmux ! filesink location=track5.ogg
202 + * </programlisting>
203 + * This pipeline extracts track 5 of the audio CD and encodes it into an
204 + * Ogg/Vorbis file.
205 + * </para>
206 + * </refsect2>
207 + */
209 +#ifdef HAVE_CONFIG_H
210 +#include "config.h"
211 +#endif
213 +#include <stdio.h>
214 +#include <stdlib.h>
215 +#include <fcntl.h>
216 +#include <string.h>
217 +#include <libintl.h>
218 +#include <errno.h>
219 +#include <unistd.h>
220 +#include <sys/filio.h>
221 +#include <signal.h>
222 +#define HAVE_POLL /* XXX Need autoconf test */
223 +#ifdef HAVE_POLL
224 +#include <poll.h>
225 +#endif
226 +#include <sys/byteorder.h>
227 +#include <hal/libhal.h>
228 +#include <hal/libhal-storage.h>
230 +#include "gstcdda2wav.h"
231 +#include "gst/gst-i18n-plugin.h"
233 +enum
235 + PROP0 = 0,
238 +GST_DEBUG_CATEGORY_STATIC (gst_cdda2wav_debug);
239 +#define GST_CAT_DEFAULT gst_cdda2wav_debug
241 +GST_BOILERPLATE (GstCdda2Wav, gst_cdda2wav, GstCddaBaseSrc,
242 + GST_TYPE_CDDA_BASE_SRC)
244 +static void gst_cdda2wav_finalize (GObject * obj);
245 +static GstBuffer *gst_cdda2wav_read_sector (GstCddaBaseSrc * src,
246 + gint sector);
247 +static gboolean gst_cdda2wav_open (GstCddaBaseSrc * src,
248 + const gchar * device);
249 +static void gst_cdda2wav_close (GstCddaBaseSrc * src);
250 +static gchar **gst_cdda2wav_probe_devices (GstCddaBaseSrc * cddabasesrc);
251 +static gchar *gst_cdda2wav_get_default_device (GstCddaBaseSrc * cddabasesrc);
252 +static void gst_cdda2wav_set_property (GObject * object, guint prop_id,
253 + const GValue * value, GParamSpec * pspec);
254 +static void gst_cdda2wav_get_property (GObject * object, guint prop_id,
255 + GValue * value, GParamSpec * pspec);
257 +static void gst_cdda2wav_hal_find_cdroms (GstCdda2Wav *);
259 +static pid_t xpopen(FILE **pfpin, FILE **pfpout, FILE **pfperr, const char *cmd);
260 +static int xpclose(FILE *fpin, FILE *fpout, FILE *fperr, pid_t child);
263 +static const GstElementDetails cdda2wav_details =
264 +GST_ELEMENT_DETAILS ("CD Audio (cdda) Source",
265 + "Source/File",
266 + "Read audio from CD",
267 + "Brian Cameron <Brian.Cameron@sun.com>, " "Artem Kachitchkine <Artem.Kachitchkine@sun.com>, "
268 + "Joerg Schilling <Joerg.Schilling@fokus.fraunhofer.de>");
270 +static void
271 +gst_cdda2wav_base_init (gpointer g_class)
273 + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
275 + gst_element_class_set_details (element_class, &cdda2wav_details);
278 +static void
279 +gst_cdda2wav_init (GstCdda2Wav * src, GstCdda2WavClass * klass)
281 + src->devices = NULL;
282 + src->current_device = NULL;
283 + src->cdda2wav_in = NULL;
284 + src->cdda2wav_out = NULL;
285 + src->cdda2wav_err = NULL;
286 + src->cdda2wav_pid = 0;
289 +static void
290 +gst_cdda2wav_class_init (GstCdda2WavClass * klass)
292 + GstCddaBaseSrcClass *cddabasesrc_class = GST_CDDA_BASE_SRC_CLASS (klass);
293 + GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
295 + gobject_class->set_property = gst_cdda2wav_set_property;
296 + gobject_class->get_property = gst_cdda2wav_get_property;
297 + gobject_class->finalize = gst_cdda2wav_finalize;
299 + cddabasesrc_class->open = gst_cdda2wav_open;
300 + cddabasesrc_class->close = gst_cdda2wav_close;
301 + cddabasesrc_class->read_sector = gst_cdda2wav_read_sector;
302 + cddabasesrc_class->get_default_device = gst_cdda2wav_get_default_device;
303 + cddabasesrc_class->probe_devices = gst_cdda2wav_probe_devices;
306 +static gchar **
307 +gst_cdda2wav_probe_devices (GstCddaBaseSrc * cddabasesrc)
309 + GstCdda2Wav *src = GST_CDDA2WAV (cddabasesrc);
311 + if (src->devices != NULL) {
312 + free (src->devices);
313 + free (src->has_audio);
315 + src->devices = NULL;
316 + src->has_audio = NULL;
318 + gst_cdda2wav_hal_find_cdroms (src);
320 + return (src->devices);
323 +static gchar *
324 +gst_cdda2wav_get_default_device (GstCddaBaseSrc * cddabasesrc)
326 + GstCdda2Wav *src;
327 + gchar *ret = NULL;
328 + int i;
330 + src = GST_CDDA2WAV (cddabasesrc);
332 + if (src->devices == NULL) {
333 + gst_cdda2wav_probe_devices (cddabasesrc);
334 + if (src->devices == NULL) {
335 + return (NULL);
339 + /* prefer a drive with an audio disc, otherwise pick first */
340 + for (i = 0; src->devices[i] != NULL; i++) {
341 + if (src->has_audio[i]) {
342 + ret = src->devices[i];
343 + break;
347 + if (ret == NULL)
348 + ret = src->devices[0];
350 + GST_LOG_OBJECT (src, "returning default device: %s", GST_STR_NULL (ret));
352 + return (ret);
355 +static boolean_t
356 +cdda2wav_read_toc (GstCdda2Wav *src)
358 + gchar *command;
359 + char buf[BUFSIZ];
360 + guint leadout;
361 + int track_num;
362 + uint_t i;
363 + GstCddaBaseSrcTrack tracks[100];
364 + FILE *f;
366 + /* Open the connection to cdda2wav */
367 + command = g_strdup_printf (
368 + "/usr/bin/cdda2wav -q dev=%s --info-only -vtoc --no-infofile --gui 2>&1",
369 + src->current_device);
370 + f = popen (command, "r");
371 + g_free (command);
372 + if (f == NULL)
373 + return (FALSE);
375 + track_num = 0;
376 + leadout = 0;
378 + i = 0;
379 + while (fgets (buf, BUFSIZ, f) != NULL) {
380 + char *endptr;
381 + g_strchomp (buf);
383 + if ((strlen (buf) > 12) &&
384 + (buf[0] == 'T') &&
385 + (g_ascii_isdigit(buf[1])) &&
386 + (g_ascii_isdigit(buf[2])) &&
387 + (buf[3] == ':')) {
389 + track_num = buf[2] - '0' + (buf[1] - '0') * 10;
390 + tracks[i].is_audio = strstr((buf + 4), "audio") != 0;
391 + tracks[i].num = buf[2] - '0' + (buf[1] - '0') * 10;
392 + tracks[i].tags = NULL;
393 + tracks[i].start = (guint) (g_ascii_strtod ((buf + 4), &endptr));
394 +#ifdef DEBUG
395 + fprintf(stderr, "Track %2.2d %2.2d audio %d start %u\n",
396 + i, tracks[i].num, tracks[i].is_audio, tracks[i].start);
397 +#endif
398 + i++;
401 + if (strncmp (buf, "Leadout:", 8) == 0) {
402 + leadout = (guint) (g_ascii_strtod ((buf + 8), &endptr));
405 + track_num = i;
407 + for (i=0; i < track_num; i++) {
408 + GstCddaBaseSrcTrack track = { 0, };
410 + track.is_audio = tracks[i].is_audio;
411 + track.num = tracks[i].num;
412 + track.tags = NULL;
413 + track.start = tracks[i].start;
415 + if (i < (track_num - 1))
416 + track.end = tracks[i+1].start - 1;
417 + else
418 + track.end = leadout;
420 + gst_cdda_base_src_add_track (GST_CDDA_BASE_SRC (src), &track);
423 + src->track_count = track_num + 1;
425 + pclose (f);
427 + return (TRUE);
430 +static gboolean
431 +gst_cdda2wav_open (GstCddaBaseSrc * cddabasesrc, const gchar * device)
433 + GstCdda2Wav *src = GST_CDDA2WAV (cddabasesrc);
434 + gchar *command;
435 + gboolean ret;
437 + g_assert (device != NULL);
439 + GST_LOG_OBJECT (src, "Trying to open device %s", device);
440 + src->current_device = g_strdup (device);
442 + ret = cdda2wav_read_toc (src);
444 + return ret;
447 +static int
448 +gst_cdda_close (GstCdda2Wav * src)
450 + int rc = 0;
452 + if (src->cdda2wav_pid != 0) {
453 + rc = xpclose (src->cdda2wav_in, src->cdda2wav_out, src->cdda2wav_err,
454 + src->cdda2wav_pid);
456 + src->cdda2wav_in = NULL;
457 + src->cdda2wav_out = NULL;
458 + src->cdda2wav_err = NULL;
459 + src->cdda2wav_pid = 0;
461 + return rc;
464 +static void
465 +gst_cdda2wav_close (GstCddaBaseSrc * cddabasesrc)
467 + GstCdda2Wav *src = GST_CDDA2WAV (cddabasesrc);
469 + gst_cdda_close (src);
472 +static gboolean
473 +getans(GstCdda2Wav *src)
475 + char buf[1024];
476 + char *p;
477 + int ret;
478 +#ifdef HAVE_POLL
479 + struct pollfd pfd[1];
480 +#endif
482 +#ifdef DEBUG
483 + fprintf(stderr, "getans\n");
484 +#endif
485 + if (src->cdda2wav_err == NULL)
486 + return (FALSE);
487 + do {
488 + buf[0] = '\0';
489 +#ifdef HAVE_POLL
490 + pfd[0].fd = fileno(src->cdda2wav_err);
491 + pfd[0].events = POLLIN;
492 + pfd[0].revents = 0;
493 + if (poll(pfd, 1, 5000) < 1) /* Give up after 5s */
494 + break;
495 +#else
496 + insert select code here
497 +#endif
498 + p = fgets(buf, sizeof (buf), src->cdda2wav_err);
499 +#ifdef DEBUG
500 + fprintf(stderr, "ERR: '%s'\n", buf);
501 +#endif
502 + if (buf[0] >= '0' && buf[0] <= '9' &&
503 + buf[1] >= '0' && buf[1] <= '9' &&
504 + buf[2] >= '0' && buf[2] <= '9' &&
505 + buf[3] == ' ')
506 + break;
507 + } while (p);
508 + ret = atoi(buf);
509 + if (ret != 200) {
510 + fprintf(stderr, "ERR: %s\n", buf);
511 + gst_cdda_close (src);
512 + return (FALSE);
514 + return (TRUE);
517 +static void
518 +flushpipe(FILE *f)
520 + int nread;
521 + char fbuf[5120];
523 + do {
524 + ioctl(fileno(f), FIONREAD, &nread);
525 + if (nread > 0) {
526 + int amt;
528 + amt = nread;
529 + if (amt > sizeof (fbuf))
530 + amt = sizeof (fbuf);
531 + if (fread(fbuf, amt, 1, f) != 1)
532 + break;
534 + } while (nread > 0);
537 +static gboolean
538 +sendcmd(GstCdda2Wav *src, const char *fmt, uint_t addr)
540 + struct sigaction old;
541 + struct sigaction my;
543 + sigemptyset(&my.sa_mask);
544 + my.sa_handler == SIG_IGN;
545 + my.sa_flags = 0;
546 + sigaction(SIGPIPE, &my, &old);
548 + clearerr(src->cdda2wav_in);
549 + fprintf(src->cdda2wav_in, fmt, addr);
550 + fflush(src->cdda2wav_in);
552 + sigaction(SIGPIPE, &old, NULL);
554 + if (ferror(src->cdda2wav_in)) {
555 + gst_cdda_close(src);
556 + return (FALSE);
558 + return (TRUE);
561 +#if G_BYTE_ORDER == G_LITTLE_ENDIAN
562 +#define CDDA2WAV_BYTE_ORDER "little"
563 +#elif G_BYTE_ORDER == G_BIG_ENDIAN
564 +#define CDDA2WAV_BYTE_ORDER "big"
565 +#else
566 +#error "G_BYTE_ORDER should be big or little endian."
567 +#endif
569 +static gboolean
570 +cdda2wav_read (GstCdda2Wav *src, void *buf, uint_t addr, uint_t len)
572 + static int last_addr = -1;
573 + char * command;
574 + int did_retry = -1;
575 + gboolean do_paranoia = FALSE; /* Need to be parameterized from elsewhere */
577 +retry:
578 + if (++did_retry > 1)
579 + return (FALSE);
581 + if (src->cdda2wav_pid == 0) {
582 + command = g_strdup_printf (
583 + "/usr/bin/cdda2wav -q --output-endianess=%s dev=%s -Oraw %s -interactive -",
584 + CDDA2WAV_BYTE_ORDER, src->current_device,
585 + do_paranoia ? "-paranoia -paraopts=minoverlap=2":"");
586 + src->cdda2wav_pid = xpopen (&src->cdda2wav_in, &src->cdda2wav_out,
587 + &src->cdda2wav_err, command);
588 +#ifdef DEBUG
589 + fprintf(stderr, "PID %d\n", src->cdda2wav_pid);
590 +#endif
591 + g_free (command);
592 + if (!sendcmd(src, "read sectors %u\n", addr))
593 + goto retry;
594 + if (!getans(src))
595 + goto retry;
596 + last_addr = addr;
597 + } else if (addr != (last_addr + 1)) { /* Check whether we need to seek */
598 + int nread;
600 + if (!sendcmd(src, "stop\n", 0))
601 + goto retry;
602 + flushpipe(src->cdda2wav_out);
603 + if (!getans(src))
604 + goto retry;
605 + do {
606 + if (!sendcmd(src, "stop\n", 0))
607 + goto retry;
608 + flushpipe(src->cdda2wav_out);
609 + if (!getans(src))
610 + goto retry;
611 + ioctl(fileno(src->cdda2wav_out), FIONREAD, &nread);
612 + } while (nread > 0);
613 + if (!sendcmd(src, "read sectors %u\n", addr))
614 + goto retry;
615 + if (!getans(src))
616 + goto retry;
618 + last_addr = addr;
620 + if (fread (buf, CDDA2WAV_BSIZE, len, src->cdda2wav_out) != len) {
621 + if (feof(src->cdda2wav_out)) {
622 + if (gst_cdda_close (src) == 0)
623 + return (TRUE);
624 + goto retry;
626 + return (FALSE);
629 + return (TRUE);
632 +static GstBuffer *
633 +gst_cdda2wav_read_sector (GstCddaBaseSrc * cddabasesrc, gint sector)
635 + GstCdda2Wav *src = GST_CDDA2WAV (cddabasesrc);
636 + size_t len = CDDA2WAV_BSIZE;
637 + GstBuffer *buf;
639 + buf = gst_buffer_new_and_alloc (CDDA2WAV_BSIZE);
641 + if (!cdda2wav_read (src, GST_BUFFER_DATA (buf), sector, 1)) {
642 + free (buf);
643 + buf = NULL;
644 + return NULL;
647 + return (buf);
650 +static void
651 +gst_cdda2wav_finalize (GObject * obj)
653 + GstCdda2Wav *src = GST_CDDA2WAV (obj);
655 + gst_cdda_close (src);
657 + g_free (src->devices);
658 + g_free (src->current_device);
660 + G_OBJECT_CLASS (parent_class)->finalize (obj);
663 +static gboolean
664 +plugin_init (GstPlugin * plugin)
666 + GST_DEBUG_CATEGORY_INIT (gst_cdda2wav_debug, "cdda2wav", 0,
667 + "CDDA Source");
669 + if (!gst_element_register (plugin, "cdda2wav", GST_RANK_SECONDARY,
670 + GST_TYPE_CDDA2WAV))
671 + return FALSE;
673 +#ifdef ENABLE_NLS
674 + GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
675 + LOCALEDIR);
676 + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
677 +#endif
679 + return TRUE;
682 +static void
683 +gst_cdda2wav_set_property (GObject * object, guint prop_id,
684 + const GValue * value, GParamSpec * pspec)
686 + GstCdda2Wav *src = GST_CDDA2WAV (object);
688 + switch (prop_id) {
689 + default:
690 + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
691 + break;
695 +static void
696 +gst_cdda2wav_get_property (GObject * object, guint prop_id,
697 + GValue * value, GParamSpec * pspec)
699 + GstCdda2Wav *src = GST_CDDA2WAV (object);
701 + switch (prop_id) {
702 + default:
703 + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
704 + break;
708 +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
709 + GST_VERSION_MINOR,
710 + "cdda2wav",
711 + "Read audio from CD",
712 + plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
714 +/* ===== HAL stuff ===== */
716 +static LibHalContext *
717 +gst_cdda2wav_hal_init (GstCdda2Wav *src)
719 + DBusError error;
720 + LibHalContext *hal_ctx = NULL;
722 + dbus_error_init (&error);
723 + if ((hal_ctx = libhal_ctx_new ()) == NULL) {
724 + GST_ELEMENT_ERROR (src, LIBRARY, INIT,
725 + ("failed to initialize HAL"), ("failed to initialize HAL"));
726 + goto out;
728 + if (!libhal_ctx_set_dbus_connection(hal_ctx,
729 + dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
731 + GST_ELEMENT_ERROR (src, LIBRARY, INIT,
732 + ("DBus connection failed"),
733 + ("libhal_ctx_set_dbus_connection: %s %s", error.name, error.message));
734 + libhal_ctx_free (hal_ctx);
735 + goto out;
737 + if (!libhal_ctx_init(hal_ctx, &error)) {
738 + GST_ELEMENT_ERROR (src, LIBRARY, INIT,
739 + ("HAL context init failed"),
740 + ("libhal_ctx_init: %s: %s", error.name, error.message));
741 + libhal_ctx_free (hal_ctx);
742 + goto out;
744 +out:
745 + dbus_error_free (&error);
747 + return (hal_ctx);
750 +static void
751 +gst_cdda2wav_hal_fini (LibHalContext *hal_ctx)
753 + DBusError error;
755 + dbus_error_init (&error);
756 + libhal_ctx_shutdown (hal_ctx, &error);
757 + libhal_ctx_free (hal_ctx);
758 + dbus_error_free (&error);
761 +static void
762 +gst_cdda2wav_hal_find_cdroms (GstCdda2Wav *src)
764 + DBusError error;
765 + LibHalContext *hal_ctx;
766 + int i, j, k;
767 + char **drive_udis, **volume_udis;
768 + int num_drives, num_volumes;
769 + char *raw_device;
770 + LibHalDrive *drive;
771 + dbus_bool_t has_audio;
773 + if ((hal_ctx = gst_cdda2wav_hal_init (src)) == NULL) {
774 + return;
776 + dbus_error_init (&error);
778 + drive_udis = libhal_find_device_by_capability (hal_ctx, "storage.cdrom",
779 + &num_drives, &error);
781 + if (dbus_error_is_set (&error) || drive_udis == NULL) {
782 + goto out;
785 + src->devices = calloc (num_drives + 1, sizeof (char *));
786 + src->has_audio = calloc (num_drives + 1, sizeof (boolean_t));
788 + for (i = j = 0; i < num_drives; i++) {
789 + raw_device = libhal_device_get_property_string (hal_ctx,
790 + drive_udis[i], "block.solaris.raw_device", &error);
791 + dbus_error_free (&error);
793 + if ((raw_device == NULL) || (strlen (raw_device) == 0)) {
794 + libhal_free_string (raw_device);
795 + continue;
798 + src->devices[j] = strdup (raw_device);
799 + libhal_free_string (raw_device);
801 + /* check for audio disc in this drive */
802 + if ((drive = libhal_drive_from_udi (hal_ctx, drive_udis[i])) != NULL) {
803 + if ((volume_udis = libhal_drive_find_all_volumes (hal_ctx,
804 + drive, &num_volumes)) != NULL) {
806 + for (k = 0; k < num_volumes; k++) {
807 + src->has_audio[j] = (boolean_t)
808 + libhal_device_get_property_bool (hal_ctx,
809 + volume_udis[k], "volume.disc.has_audio", &error);
810 + dbus_error_free (&error);
811 + if (src->has_audio[j]) {
812 + break;
815 + libhal_free_string_array (volume_udis);
817 + libhal_drive_free (drive);
820 + j++;
823 +out:
824 + libhal_free_string_array (drive_udis);
825 + dbus_error_free (&error);
827 + gst_cdda2wav_hal_fini (hal_ctx);
830 +#define HAVE_SYS_FORK_H /* XXX Need autoconf test */
831 +#ifdef HAVE_SYS_FORK_H
832 +#include <sys/fork.h>
833 +#endif
834 +#include <wait.h>
836 +static pid_t
837 +xpopen(FILE **pfpin, FILE **pfpout, FILE **pfperr, const char *cmd)
839 + int in[2];
840 + int out[2];
841 + int err[2];
842 + pid_t pid;
844 + in[0] = STDIN_FILENO;
845 + out[1] = STDOUT_FILENO;
846 + err[1] = STDERR_FILENO;
847 + if (pfpin) {
848 + if (pipe(in) < 0)
849 + return ((pid_t)-1);
851 + if (pfpout) {
852 + if (pipe(out) < 0) {
853 + close(in[0]);
854 + close(in[1]);
855 + return ((pid_t)-1);
858 + if (pfperr) {
859 + if (pipe(err) < 0) {
860 + close(in[0]);
861 + close(in[1]);
862 + close(out[0]);
863 + close(out[1]);
864 + return ((pid_t)-1);
868 +#ifdef FORK_NOSIGCHLD
869 + pid = vforkx(FORK_NOSIGCHLD|FORK_WAITPID);
870 +#else
871 + pid = vfork(); /* Need to find a way to deal with SIGCHLD and wait */
872 +#endif
873 + if (pid == (pid_t)-1) {
874 + return ((pid_t)-1);
875 + } else if (pid > 0) {
876 + if (pfpin) {
877 + close(in[0]);
878 + *pfpin = fdopen(in[1], "w");
879 + if (*pfpin == NULL) {
880 + close(in[1]);
881 + close(out[0]);
882 + close(out[1]);
883 + close(err[0]);
884 + close(err[1]);
885 + kill(pid, SIGKILL);
886 + xpclose(NULL, NULL, NULL, pid);
887 + return ((pid_t)-1);
890 + if (pfpout) {
891 + close(out[1]);
892 + *pfpout = fdopen(out[0], "r");
893 + if (*pfpout == NULL) {
894 + close(out[0]);
895 + close(err[0]);
896 + close(err[1]);
897 + kill(pid, SIGKILL);
898 + xpclose(*pfpin, NULL, NULL, pid);
899 + return ((pid_t)-1);
902 + if (pfperr) {
903 + close(err[1]);
904 + *pfperr = fdopen(err[0], "r");
905 + if (*pfperr == NULL) {
906 + close(err[0]);
907 + kill(pid, SIGKILL);
908 + xpclose(*pfpin, *pfpout, NULL, pid);
909 + return ((pid_t)-1);
912 + } else {
913 + if (pfpin)
914 + close(in[1]);
915 + if (pfpout)
916 + close(out[0]);
917 + if (pfperr)
918 + close(err[0]);
919 + if (in[0] != STDIN_FILENO) {
920 + dup2(in[0], STDIN_FILENO);
921 + close(in[0]);
923 + if (out[1] != STDOUT_FILENO) {
924 + dup2(out[1], STDOUT_FILENO);
925 + close(out[1]);
926 + }
927 + if (err[1] != STDERR_FILENO) {
928 + dup2(err[1], STDERR_FILENO);
929 + close(err[1]);
931 + execl("/bin/sh", "sh", "-c", cmd, (char *)0);
932 + _exit(1);
934 + return (pid);
937 +static int
938 +xpclose(FILE *fpin, FILE *fpout, FILE *fperr, pid_t child)
940 + int status = 0;
942 + if (fpin)
943 + fclose(fpin);
944 + if (fpout)
945 + fclose(fpout);
946 + if (fperr)
947 + fclose(fperr);
949 + if (child <= 0) {
950 + errno = ECHILD;
951 + return (-1);
953 + if (waitpid(child, &status, WNOHANG) == child)
954 + return (status);
955 + while (waitpid(child, &status, 0) < 0) {
956 + if (errno != EINTR) {
957 + status = -1;
958 + break;
961 + return (status);