d7bd6881d75152f3e71305e52f9761843dbed41d
[platform/upstream/gstreamer.git] / sys / dxr3 / dxr3audiosink.c
1 /* GStreamer
2  * Copyright (C) 2003 Martin Soto <martinsoto@users.sourceforge.net>
3  *
4  * dxr3audiosink.c: Audio sink for em8300 based DVD cards.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 #include <errno.h>
26 #include <string.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <sys/ioctl.h>
30
31 #include <linux/soundcard.h>
32 #include <linux/em8300.h>
33
34 #include <gst/gst-i18n-plugin.h>
35 #include <gst/gst.h>
36
37 #include "dxr3audiosink.h"
38 #include "dxr3marshal.h"
39 #include "dxr3common.h"
40
41 /* Our only supported AC3 byte rate. */
42 #define AC3_BYTE_RATE 48000
43
44 /* Determines the amount of time to play the given number of bytes of
45    the original AC3 stream.  The result is expressed as MPEG2. */
46 #define TIME_FOR_BYTES(bytes) (((bytes) * 90) / 48)
47
48 /* Dxr3AudioSink signals and args */
49 enum
50 {
51   SIGNAL_FLUSHED,
52   LAST_SIGNAL
53 };
54
55 enum
56 {
57   ARG_0,
58   ARG_DIGITAL_PCM
59 };
60
61 static GstStaticPadTemplate dxr3audiosink_pcm_sink_factory =
62 GST_STATIC_PAD_TEMPLATE ("pcm_sink",
63     GST_PAD_SINK,
64     GST_PAD_ALWAYS,
65     GST_STATIC_CAPS ("audio/x-raw-int, "
66         "endianness = (int) BYTE_ORDER, "
67         "signed = (boolean) TRUE, "
68         "width = (int) 16, "
69         "depth = (int) 16, "
70         "rate = (int) { 32000, 44100, 48000, 66000 }, " "channels = (int) 2")
71     );
72
73 static GstStaticPadTemplate dxr3audiosink_ac3_sink_factory =
74 GST_STATIC_PAD_TEMPLATE ("ac3_sink",
75     GST_PAD_SINK,
76     GST_PAD_ALWAYS,
77     GST_STATIC_CAPS ("audio/x-ac3"
78         /* no parameters needed, we don't need a parsed stream */
79     )
80     );
81
82
83 static void dxr3audiosink_class_init (Dxr3AudioSinkClass * klass);
84 static void dxr3audiosink_base_init (Dxr3AudioSinkClass * klass);
85 static void dxr3audiosink_init (Dxr3AudioSink * sink);
86
87 static void dxr3audiosink_set_property (GObject * object,
88     guint prop_id, const GValue * value, GParamSpec * pspec);
89 static void dxr3audiosink_get_property (GObject * object,
90     guint prop_id, GValue * value, GParamSpec * pspec);
91
92 static gboolean dxr3audiosink_open (Dxr3AudioSink * sink);
93 static gboolean dxr3audiosink_set_mode_pcm (Dxr3AudioSink * sink);
94 static gboolean dxr3audiosink_set_mode_ac3 (Dxr3AudioSink * sink);
95 static void dxr3audiosink_close (Dxr3AudioSink * sink);
96 static void dxr3audiosink_set_clock (GstElement * element, GstClock * clock);
97
98 static GstPadLinkReturn dxr3audiosink_pcm_sinklink (GstPad * pad,
99     const GstCaps * caps);
100 static void dxr3audiosink_set_scr (Dxr3AudioSink * sink, guint32 scr);
101
102 static gboolean dxr3audiosink_handle_event (GstPad * pad, GstEvent * event);
103 static void dxr3audiosink_chain_pcm (GstPad * pad, GstData * buf);
104 static void dxr3audiosink_chain_ac3 (GstPad * pad, GstData * buf);
105
106 /* static void  dxr3audiosink_wait              (Dxr3AudioSink *sink, */
107 /*                                                  GstClockTime time); */
108 /* static int   dxr3audiosink_mvcommand         (Dxr3AudioSink *sink, */
109 /*                                                  int command); */
110
111 static GstStateChangeReturn dxr3audiosink_change_state (GstElement * element,
112     GstStateChange transition);
113
114 static void dxr3audiosink_flushed (Dxr3AudioSink * sink);
115
116 static GstElementClass *parent_class = NULL;
117 static guint dxr3audiosink_signals[LAST_SIGNAL] = { 0 };
118
119
120 extern GType
121 dxr3audiosink_get_type (void)
122 {
123   static GType dxr3audiosink_type = 0;
124
125   if (!dxr3audiosink_type) {
126     static const GTypeInfo dxr3audiosink_info = {
127       sizeof (Dxr3AudioSinkClass),
128       (GBaseInitFunc) dxr3audiosink_base_init,
129       NULL,
130       (GClassInitFunc) dxr3audiosink_class_init,
131       NULL,
132       NULL,
133       sizeof (Dxr3AudioSink),
134       0,
135       (GInstanceInitFunc) dxr3audiosink_init,
136     };
137
138     dxr3audiosink_type = g_type_register_static (GST_TYPE_ELEMENT,
139         "Dxr3AudioSink", &dxr3audiosink_info, 0);
140   }
141
142   return dxr3audiosink_type;
143 }
144
145
146 static void
147 dxr3audiosink_base_init (Dxr3AudioSinkClass * klass)
148 {
149   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
150
151   gst_element_class_add_pad_template (element_class,
152       gst_static_pad_template_get (&dxr3audiosink_pcm_sink_factory));
153   gst_element_class_add_pad_template (element_class,
154       gst_static_pad_template_get (&dxr3audiosink_ac3_sink_factory));
155   gst_element_class_set_details_simple (element_class,
156       "dxr3/Hollywood+ mpeg decoder board audio plugin", "Audio/Sink",
157       "Feeds audio to Sigma Designs em8300 based boards",
158       "Martin Soto <martinsoto@users.sourceforge.net>");
159 }
160
161 static void
162 dxr3audiosink_class_init (Dxr3AudioSinkClass * klass)
163 {
164   GObjectClass *gobject_class;
165   GstElementClass *gstelement_class;
166
167   gobject_class = (GObjectClass *) klass;
168   gstelement_class = (GstElementClass *) klass;
169
170   parent_class = g_type_class_peek_parent (klass);
171
172   dxr3audiosink_signals[SIGNAL_FLUSHED] =
173       g_signal_new ("flushed", G_TYPE_FROM_CLASS (klass),
174       G_SIGNAL_RUN_LAST,
175       G_STRUCT_OFFSET (Dxr3AudioSinkClass, flushed),
176       NULL, NULL, dxr3_marshal_VOID__VOID, G_TYPE_NONE, 0);
177
178   klass->flushed = dxr3audiosink_flushed;
179
180   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DIGITAL_PCM,
181       g_param_spec_boolean ("digital-pcm", "Digital PCM",
182           "Use the digital output for PCM sound", FALSE, G_PARAM_READWRITE));
183
184   gobject_class->set_property = dxr3audiosink_set_property;
185   gobject_class->get_property = dxr3audiosink_get_property;
186
187   gstelement_class->change_state = dxr3audiosink_change_state;
188   gstelement_class->set_clock = dxr3audiosink_set_clock;
189 }
190
191
192 static void
193 dxr3audiosink_init (Dxr3AudioSink * sink)
194 {
195   GstPadTemplate *temp;
196
197   /* Create the PCM pad. */
198   temp = gst_static_pad_template_get (&dxr3audiosink_pcm_sink_factory);
199   sink->pcm_sinkpad = gst_pad_new_from_template (temp, "pcm_sink");
200   gst_pad_set_chain_function (sink->pcm_sinkpad, dxr3audiosink_chain_pcm);
201   gst_pad_set_link_function (sink->pcm_sinkpad, dxr3audiosink_pcm_sinklink);
202   gst_element_add_pad (GST_ELEMENT (sink), sink->pcm_sinkpad);
203
204   /* Create the AC3 pad. */
205   temp = gst_static_pad_template_get (&dxr3audiosink_ac3_sink_factory);
206   sink->ac3_sinkpad = gst_pad_new_from_template (temp, "ac3_sink");
207   gst_pad_set_chain_function (sink->ac3_sinkpad, dxr3audiosink_chain_ac3);
208   gst_element_add_pad (GST_ELEMENT (sink), sink->ac3_sinkpad);
209
210   GST_OBJECT_FLAG_SET (GST_ELEMENT (sink), GST_ELEMENT_EVENT_AWARE);
211
212   sink->card_number = 0;
213
214   sink->audio_filename = NULL;
215   sink->audio_fd = -1;
216
217   sink->control_filename = NULL;
218   sink->control_fd = -1;
219
220   /* Since we don't know any better, we set the initial scr to 0. */
221   sink->scr = 0;
222
223   /* Initially don't use digital output. */
224   sink->digital_pcm = FALSE;
225
226   /* Initially there's no padder. */
227   sink->padder = NULL;
228
229   sink->mode = DXR3AUDIOSINK_MODE_NONE;
230 }
231
232
233 static void
234 dxr3audiosink_set_property (GObject * object, guint prop_id,
235     const GValue * value, GParamSpec * pspec)
236 {
237   Dxr3AudioSink *sink;
238
239   sink = DXR3AUDIOSINK (object);
240
241   switch (prop_id) {
242     case ARG_DIGITAL_PCM:
243       sink->digital_pcm = g_value_get_boolean (value);
244       /* Refresh the setup of the device. */
245       if (sink->mode == DXR3AUDIOSINK_MODE_PCM) {
246         dxr3audiosink_set_mode_pcm (sink);
247       }
248       g_object_notify (G_OBJECT (sink), "digital-pcm");
249       break;
250     default:
251       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
252       break;
253   }
254 }
255
256
257 static void
258 dxr3audiosink_get_property (GObject * object, guint prop_id,
259     GValue * value, GParamSpec * pspec)
260 {
261   Dxr3AudioSink *sink;
262
263   g_return_if_fail (GST_IS_DXR3AUDIOSINK (object));
264
265   sink = DXR3AUDIOSINK (object);
266
267   switch (prop_id) {
268     case ARG_DIGITAL_PCM:
269       g_value_set_boolean (value, sink->digital_pcm);
270       break;
271     default:
272       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
273       break;
274   }
275 }
276
277
278 static gboolean
279 dxr3audiosink_open (Dxr3AudioSink * sink)
280 {
281   g_return_val_if_fail (!GST_OBJECT_FLAG_IS_SET (sink, DXR3AUDIOSINK_OPEN),
282       FALSE);
283
284   /* Compute the name of the audio device file. */
285   sink->audio_filename = g_strdup_printf ("/dev/em8300_ma-%d",
286       sink->card_number);
287
288   sink->audio_fd = open (sink->audio_filename, O_WRONLY);
289   if (sink->audio_fd < 0) {
290     GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
291         (_("Could not open audio device \"%s\" for writing."),
292             sink->audio_filename), GST_ERROR_SYSTEM);
293     return FALSE;
294   }
295
296   /* Open the control device. */
297   sink->control_filename = g_strdup_printf ("/dev/em8300-%d",
298       sink->card_number);
299
300   sink->control_fd = open (sink->control_filename, O_WRONLY);
301   if (sink->control_fd < 0) {
302     GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
303         (_("Could not open control device \"%s\" for writing."),
304             sink->control_filename), GST_ERROR_SYSTEM);
305     return FALSE;
306   }
307
308   GST_OBJECT_FLAG_SET (sink, DXR3AUDIOSINK_OPEN);
309
310   dxr3audiosink_set_mode_pcm (sink);
311
312   return TRUE;
313 }
314
315
316 /**
317  * dxr3audiosink_set_mode:
318  * @sink: The sink element to operate on.
319  *
320  * Set the operation mode of the element to PCM.
321  */
322 static gboolean
323 dxr3audiosink_set_mode_pcm (Dxr3AudioSink * sink)
324 {
325   int tmp, oss_mode, audiomode;
326
327   if (sink->audio_fd == -1 || sink->control_fd == -1) {
328     return FALSE;
329   }
330
331   /* Set the audio device mode. */
332   oss_mode = (G_BYTE_ORDER == G_BIG_ENDIAN ? AFMT_S16_BE : AFMT_S16_LE);
333   tmp = oss_mode;
334   if (ioctl (sink->audio_fd, SNDCTL_DSP_SETFMT, &tmp) < 0 || tmp != oss_mode) {
335     GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS,
336         (_("Could not configure audio device \"%s\"."), sink->audio_filename),
337         GST_ERROR_SYSTEM);
338     return FALSE;
339   }
340
341   /* Set the card's general audio output mode. */
342   audiomode = sink->digital_pcm ?
343       EM8300_AUDIOMODE_DIGITALPCM : EM8300_AUDIOMODE_ANALOG;
344   ioctl (sink->control_fd, EM8300_IOCTL_SET_AUDIOMODE, &audiomode);
345
346   /* Set the sampling rate. */
347   tmp = sink->rate;
348   if (ioctl (sink->audio_fd, SNDCTL_DSP_SPEED, &tmp) < 0) {
349     GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS,
350         (_("Could not set audio device \"%s\" to %d Hz."), sink->audio_filename,
351             sink->rate), GST_ERROR_SYSTEM);
352     return FALSE;
353   }
354
355   /* Get rid of the padder, if any. */
356   if (sink->padder != NULL) {
357     g_free (sink->padder);
358     sink->padder = NULL;
359   }
360
361   sink->mode = DXR3AUDIOSINK_MODE_PCM;
362
363   return TRUE;
364 }
365
366
367 /**
368  * dxr3audiosink_set_mode:
369  * @sink: The sink element to operate on
370  *
371  * Set the operation mode of the element to AC3.
372  */
373 static gboolean
374 dxr3audiosink_set_mode_ac3 (Dxr3AudioSink * sink)
375 {
376   int tmp, audiomode;
377
378   if (sink->audio_fd == -1 || sink->control_fd == -1) {
379     return FALSE;
380   }
381
382   /* Set the sampling rate. */
383   tmp = AC3_BYTE_RATE;
384   if (ioctl (sink->audio_fd, SNDCTL_DSP_SPEED, &tmp) < 0 ||
385       tmp != AC3_BYTE_RATE) {
386     GST_ELEMENT_ERROR (sink, RESOURCE, SETTINGS,
387         (_("Could not set audio device \"%s\" to %d Hz."), sink->audio_filename,
388             AC3_BYTE_RATE), GST_ERROR_SYSTEM);
389     return FALSE;
390   }
391
392   /* Set the card's general audio output mode to AC3. */
393   audiomode = EM8300_AUDIOMODE_DIGITALAC3;
394   ioctl (sink->control_fd, EM8300_IOCTL_SET_AUDIOMODE, &audiomode);
395
396   /* Create a padder if necessary, */
397   if (sink->padder == NULL) {
398     sink->padder = g_malloc (sizeof (ac3_padder));
399     ac3p_init (sink->padder);
400   }
401
402   sink->mode = DXR3AUDIOSINK_MODE_AC3;
403
404   return TRUE;
405 }
406
407
408 static void
409 dxr3audiosink_close (Dxr3AudioSink * sink)
410 {
411   g_return_if_fail (GST_OBJECT_FLAG_IS_SET (sink, DXR3AUDIOSINK_OPEN));
412
413   if (close (sink->audio_fd) != 0) {
414     GST_ELEMENT_ERROR (sink, RESOURCE, CLOSE,
415         (_("Could not close audio device \"%s\"."), sink->audio_filename),
416         GST_ERROR_SYSTEM);
417     return;
418   }
419
420   if (close (sink->control_fd) != 0) {
421     GST_ELEMENT_ERROR (sink, RESOURCE, CLOSE,
422         (_("Could not close control device \"%s\"."), sink->audio_filename),
423         GST_ERROR_SYSTEM);
424     return;
425   }
426
427   GST_OBJECT_FLAG_UNSET (sink, DXR3AUDIOSINK_OPEN);
428
429   g_free (sink->audio_filename);
430   sink->audio_filename = NULL;
431
432   g_free (sink->control_filename);
433   sink->control_filename = NULL;
434
435   /* Get rid of the padder, if any. */
436   if (sink->padder != NULL) {
437     g_free (sink->padder);
438     sink->padder = NULL;
439   }
440 }
441
442
443 static void
444 dxr3audiosink_set_clock (GstElement * element, GstClock * clock)
445 {
446   Dxr3AudioSink *src = DXR3AUDIOSINK (element);
447
448   src->clock = clock;
449 }
450
451
452 static GstPadLinkReturn
453 dxr3audiosink_pcm_sinklink (GstPad * pad, const GstCaps * caps)
454 {
455   Dxr3AudioSink *sink = DXR3AUDIOSINK (gst_pad_get_parent (pad));
456   GstStructure *structure = gst_caps_get_structure (caps, 0);
457   gint rate;
458
459   if (!gst_caps_is_fixed (caps)) {
460     return GST_PAD_LINK_DELAYED;
461   }
462
463   gst_structure_get_int (structure, "rate", &rate);
464   sink->rate = rate;
465
466   return GST_PAD_LINK_OK;
467 }
468
469
470 static void
471 dxr3audiosink_set_scr (Dxr3AudioSink * sink, guint32 scr)
472 {
473   guint32 zero = 0;
474
475 /*   fprintf (stderr, "====== Adjusting SCR\n"); */
476   ioctl (sink->control_fd, EM8300_IOCTL_SCR_SET, &zero);
477   ioctl (sink->control_fd, EM8300_IOCTL_SCR_SET, &scr);
478 }
479
480
481 static gboolean
482 dxr3audiosink_handle_event (GstPad * pad, GstEvent * event)
483 {
484   GstEventType type;
485   Dxr3AudioSink *sink = DXR3AUDIOSINK (gst_pad_get_parent (pad));
486
487   type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
488
489   switch (type) {
490     case GST_EVENT_FLUSH:
491       if (sink->control_fd >= 0) {
492         unsigned audiomode;
493
494         if (sink->mode == DXR3AUDIOSINK_MODE_AC3) {
495           audiomode = EM8300_AUDIOMODE_DIGITALPCM;
496           ioctl (sink->control_fd, EM8300_IOCTL_SET_AUDIOMODE, &audiomode);
497           audiomode = EM8300_AUDIOMODE_DIGITALAC3;
498           ioctl (sink->control_fd, EM8300_IOCTL_SET_AUDIOMODE, &audiomode);
499         }
500
501         /* Report the flush operation. */
502         g_signal_emit (G_OBJECT (sink),
503             dxr3audiosink_signals[SIGNAL_FLUSHED], 0);
504       }
505       break;
506     default:
507       gst_pad_event_default (pad, event);
508       break;
509   }
510
511   return TRUE;
512 }
513
514
515 static void
516 dxr3audiosink_chain_pcm (GstPad * pad, GstData * _data)
517 {
518   Dxr3AudioSink *sink;
519   gint bytes_written = 0;
520   GstBuffer *buf;
521
522   g_return_if_fail (pad != NULL);
523   g_return_if_fail (GST_IS_PAD (pad));
524   g_return_if_fail (_data != NULL);
525
526   sink = DXR3AUDIOSINK (gst_pad_get_parent (pad));
527
528   if (GST_IS_EVENT (_data)) {
529     dxr3audiosink_handle_event (pad, GST_EVENT (_data));
530     return;
531   }
532
533   buf = GST_BUFFER (_data);
534
535   if (sink->mode != DXR3AUDIOSINK_MODE_PCM) {
536     /* Switch to PCM mode. */
537     dxr3audiosink_set_mode_pcm (sink);
538   }
539
540   if (GST_OBJECT_FLAG_IS_SET (sink, DXR3AUDIOSINK_OPEN)) {
541     if (GST_BUFFER_TIMESTAMP (buf) != GST_CLOCK_TIME_NONE) {
542       /* We have a new scr value. */
543       sink->scr = GSTTIME_TO_MPEGTIME (GST_BUFFER_TIMESTAMP (buf));
544     }
545
546     /* Update the system reference clock (SCR) in the card. */
547     {
548       unsigned in, out, odelay;
549       unsigned diff;
550
551       ioctl (sink->control_fd, EM8300_IOCTL_SCR_GET, &out);
552
553       ioctl (sink->audio_fd, SNDCTL_DSP_GETODELAY, &odelay);
554
555       in = MPEGTIME_TO_DXRTIME (sink->scr - (odelay * 90) / 192);
556       diff = in > out ? in - out : out - in;
557       if (diff > 1800) {
558         dxr3audiosink_set_scr (sink, in);
559       }
560     }
561
562     /* Update our SCR value. */
563     sink->scr += (unsigned) (GST_BUFFER_SIZE (buf) *
564         (90000.0 / ((float) sink->rate * 4)));
565
566     /* Write the buffer to the sound device. */
567     bytes_written = write (sink->audio_fd, GST_BUFFER_DATA (buf),
568         GST_BUFFER_SIZE (buf));
569     if (bytes_written < GST_BUFFER_SIZE (buf)) {
570       fprintf (stderr, "dxr3audiosink: Warning: %d bytes should be "
571           "written, only %d bytes written\n",
572           GST_BUFFER_SIZE (buf), bytes_written);
573     }
574   }
575
576   gst_buffer_unref (buf);
577 }
578
579
580 static void
581 dxr3audiosink_chain_ac3 (GstPad * pad, GstData * _data)
582 {
583   Dxr3AudioSink *sink;
584   gint bytes_written = 0;
585   GstBuffer *buf;
586
587   g_return_if_fail (pad != NULL);
588   g_return_if_fail (GST_IS_PAD (pad));
589   g_return_if_fail (_data != NULL);
590
591   sink = DXR3AUDIOSINK (gst_pad_get_parent (pad));
592
593   if (GST_IS_EVENT (_data)) {
594     dxr3audiosink_handle_event (pad, GST_EVENT (_data));
595     return;
596   }
597
598   buf = GST_BUFFER (_data);
599
600   if (sink->mode != DXR3AUDIOSINK_MODE_AC3) {
601     /* Switch to AC3 mode. */
602     dxr3audiosink_set_mode_ac3 (sink);
603   }
604
605   if (GST_OBJECT_FLAG_IS_SET (sink, DXR3AUDIOSINK_OPEN)) {
606     int event;
607
608     if (GST_BUFFER_TIMESTAMP (buf) != GST_CLOCK_TIME_NONE) {
609       /* We have a new scr value. */
610
611 /*       fprintf (stderr, "------ Audio Time %.04f\n", */
612 /*                (double) GST_BUFFER_TIMESTAMP (buf) / GST_SECOND); */
613
614       sink->scr = GSTTIME_TO_MPEGTIME (GST_BUFFER_TIMESTAMP (buf));
615     }
616
617     /* Push the new data into the padder. */
618     ac3p_push_data (sink->padder, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
619
620     /* Parse the data. */
621     event = ac3p_parse (sink->padder);
622     while (event != AC3P_EVENT_PUSH) {
623       switch (event) {
624         case AC3P_EVENT_FRAME:
625           /* We have a new frame: */
626
627           /* Update the system reference clock (SCR) in the card. */
628         {
629           unsigned in, out, odelay;
630           unsigned diff;
631
632           ioctl (sink->control_fd, EM8300_IOCTL_SCR_GET, &out);
633
634           ioctl (sink->audio_fd, SNDCTL_DSP_GETODELAY, &odelay);
635           /* 192000 bytes/sec */
636
637           in = MPEGTIME_TO_DXRTIME (sink->scr - (odelay * 90) / 192);
638           diff = in > out ? in - out : out - in;
639           if (diff > 1800) {
640             dxr3audiosink_set_scr (sink, in);
641           }
642         }
643
644           /* Update our SCR value. */
645           sink->scr += TIME_FOR_BYTES (ac3p_frame_size (sink->padder));
646
647           /* Write the frame to the sound device. */
648           bytes_written = write (sink->audio_fd, ac3p_frame (sink->padder),
649               AC3P_IEC_FRAME_SIZE);
650
651           if (bytes_written < AC3P_IEC_FRAME_SIZE) {
652             fprintf (stderr, "dxr3audiosink: Warning: %d bytes should be "
653                 "written, only %d bytes written\n",
654                 AC3P_IEC_FRAME_SIZE, bytes_written);
655           }
656
657           break;
658       }
659
660       event = ac3p_parse (sink->padder);
661     }
662   }
663
664   gst_buffer_unref (buf);
665 }
666
667 #if 0
668 /**
669  * dxr3audiosink_wait:
670  *
671  * Make the sink wait the specified amount of time.
672  */
673 static void
674 dxr3audiosink_wait (Dxr3AudioSink * sink, GstClockTime time)
675 {
676   GstClockID id;
677   GstClockTimeDiff jitter;
678   GstClockReturn ret;
679   GstClockTime current_time = gst_clock_get_time (sink->clock);
680
681   id = gst_clock_new_single_shot_id (sink->clock, current_time + time);
682   ret = gst_clock_id_wait (id, &jitter);
683   gst_clock_id_free (id);
684 }
685
686
687 static int
688 dxr3audiosink_mvcommand (Dxr3AudioSink * sink, int command)
689 {
690   em8300_register_t regs;
691
692   regs.microcode_register = 1;
693   regs.reg = 0;
694   regs.val = command;
695
696   return ioctl (sink->control_fd, EM8300_IOCTL_WRITEREG, &regs);
697 }
698 #endif
699
700 static GstStateChangeReturn
701 dxr3audiosink_change_state (GstElement * element, GstStateChange transition)
702 {
703   g_return_val_if_fail (GST_IS_DXR3AUDIOSINK (element),
704       GST_STATE_CHANGE_FAILURE);
705
706   if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
707     if (GST_OBJECT_FLAG_IS_SET (element, DXR3AUDIOSINK_OPEN)) {
708       dxr3audiosink_close (DXR3AUDIOSINK (element));
709     }
710   } else {
711     if (!GST_OBJECT_FLAG_IS_SET (element, DXR3AUDIOSINK_OPEN)) {
712       if (!dxr3audiosink_open (DXR3AUDIOSINK (element))) {
713         return GST_STATE_CHANGE_FAILURE;
714       }
715     }
716   }
717
718   if (GST_ELEMENT_CLASS (parent_class)->change_state) {
719     return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
720   }
721
722   return GST_STATE_CHANGE_SUCCESS;
723 }
724
725
726 /**
727  * dxr3audiosink_flushed:
728  *
729  * Default do nothing implementation for the "flushed" signal.  The
730  * "flushed" signal will be fired right after flushing the hardware
731  * queues due to a received flush event 
732  */
733 static void
734 dxr3audiosink_flushed (Dxr3AudioSink * sink)
735 {
736   /* Do nothing. */
737 }