prepare for ac3plus (need updated hw drivers)
[gst-plugin-dvbmediasink.git] / src / gstdvbaudiosink.c
1 /*
2  * GStreamer DVB Media Sink
3  * Copyright 2006 Felix Domke <tmbinc@elitedvb.net>
4  * based on code by:
5  * Copyright 2005 Thomas Vander Stichele <thomas@apestaart.org>
6  * Copyright 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
7  * 
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24  * DEALINGS IN THE SOFTWARE.
25  *
26  * Alternatively, the contents of this file may be used under the
27  * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
28  * which case the following provisions apply instead of the ones
29  * mentioned above:
30  *
31  * This library is free software; you can redistribute it and/or
32  * modify it under the terms of the GNU Library General Public
33  * License as published by the Free Software Foundation; either
34  * version 2 of the License, or (at your option) any later version.
35  *
36  * This library is distributed in the hope that it will be useful,
37  * but WITHOUT ANY WARRANTY; without even the implied warranty of
38  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
39  * Library General Public License for more details.
40  *
41  * You should have received a copy of the GNU Library General Public
42  * License along with this library; if not, write to the
43  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
44  * Boston, MA 02111-1307, USA.
45  */
46
47 /**
48  * SECTION:element-plugin
49  *
50  * <refsect2>
51  * <title>Example launch line</title>
52  * <para>
53  * <programlisting>
54  * gst-launch -v -m audiotestsrc ! plugin ! fakesink silent=TRUE
55  * </programlisting>
56  * </para>
57  * </refsect2>
58  */
59
60 #ifdef HAVE_CONFIG_H
61 #include <config.h>
62 #endif
63 #include <unistd.h>
64 #include <stdint.h>
65 #include <string.h>
66 #include <sys/ioctl.h>
67 #include <sys/socket.h>
68 #include <linux/dvb/audio.h>
69 #include <linux/dvb/video.h>
70 #include <fcntl.h>
71 #include <poll.h>
72
73 #include <gst/gst.h>
74
75 #include "gstdvbaudiosink.h"
76 #include "gstdvbsink-marshal.h"
77
78 /* We add a control socket as in fdsrc to make it shutdown quickly when it's blocking on the fd.
79  * Poll is used to determine when the fd is ready for use. When the element state is changed,
80  * it happens from another thread while fdsink is poll'ing on the fd. The state-change thread 
81  * sends a control message, so fdsink wakes up and changes state immediately otherwise
82  * it would stay blocked until it receives some data. */
83
84 /* the poll call is also performed on the control sockets, that way
85  * we can send special commands to unblock the poll call */
86 #define CONTROL_STOP            'S'                     /* stop the poll call */
87 #define CONTROL_SOCKETS(sink)   sink->control_sock
88 #define WRITE_SOCKET(sink)      sink->control_sock[1]
89 #define READ_SOCKET(sink)       sink->control_sock[0]
90
91 #define SEND_COMMAND(sink, command)                     \
92 G_STMT_START {                                          \
93         unsigned char c; c = command;                   \
94         write (WRITE_SOCKET(sink), &c, 1);              \
95 } G_STMT_END
96
97 #define READ_COMMAND(sink, command, res)                \
98 G_STMT_START {                                          \
99         res = read(READ_SOCKET(sink), &command, 1);     \
100 } G_STMT_END
101
102 #ifndef AUDIO_GET_PTS
103 #define AUDIO_GET_PTS           _IOR('o', 19, gint64)
104 #endif
105
106 #define PROP_LOCATION 99
107
108 GST_DEBUG_CATEGORY_STATIC (dvbaudiosink_debug);
109 #define GST_CAT_DEFAULT dvbaudiosink_debug
110
111 enum
112 {
113         SIGNAL_GET_DECODER_TIME,
114         LAST_SIGNAL
115 };
116
117 typedef struct bitstream
118 {
119         guint8 *data;
120         guint8 last;
121         int avail;
122         int processed_bits;
123 } bitstream_t;
124
125 static void bitstream_init(bitstream_t *bit, const void *buffer, gboolean wr)
126 {
127         bit->data = (guint8*) buffer;
128         if (wr) {
129                 bit->avail = 0;
130                 bit->last = 0;
131         }
132         else {
133                 bit->processed_bits = 0;
134                 bit->avail = 8;
135                 bit->last = *bit->data++;
136         }
137 }
138
139 static unsigned long bitstream_get(bitstream_t *bit, int bits)
140 {
141         unsigned long res=0;
142         bit->processed_bits += bits;
143         while (bits)
144         {
145                 unsigned int d=bits;
146                 if (!bit->avail) {
147                         bit->last = *bit->data++;
148                         bit->avail = 8;
149                 }
150                 if (d > bit->avail)
151                         d=bit->avail;
152                 res<<=d;
153                 res|=(bit->last>>(bit->avail-d))&~(-1<<d);
154                 bit->avail-=d;
155                 bits-=d;
156         }
157         return res;
158 }
159
160 static guint gst_dvbaudiosink_signals[LAST_SIGNAL] = { 0 };
161
162 static guint AdtsSamplingRates[] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, 0 };
163 #define X_RAW_INT(WIDTH, DEPTH) \
164                 "audio/x-raw-int, " \
165                 "endianess = (int) 1234, " \
166                 "signed = (boolean) { TRUE, FALSE }, " \
167                 "rate = (int) { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }, " \
168                 "channels = (int) [ 1, 2 ], " \
169                 "width = (int) " #WIDTH ", " \
170                 "depth = (int) " #DEPTH "; "
171
172 static GstStaticPadTemplate sink_factory_ati_xilleon =
173 GST_STATIC_PAD_TEMPLATE (
174         "sink",
175         GST_PAD_SINK,
176         GST_PAD_ALWAYS,
177         GST_STATIC_CAPS ("audio/mpeg, "
178                 "mpegversion = (int) 1, "
179                 "layer = (int) [ 1, 2 ]; "
180                 "audio/x-ac3; "
181                 "audio/x-private1-ac3")
182 );
183
184 /* take care when you add or remove caps here!!!
185  * position 11 must be WMA !!!
186  * see gst_dvbaudiosink_get_caps
187  */
188 static GstStaticPadTemplate sink_factory_broadcom_dts =
189 GST_STATIC_PAD_TEMPLATE (
190         "sink",
191         GST_PAD_SINK,
192         GST_PAD_ALWAYS,
193         GST_STATIC_CAPS (
194                 X_RAW_INT(8,8)
195                 X_RAW_INT(16,16)
196                 X_RAW_INT(24,24)
197                 X_RAW_INT(32,24)
198                 X_RAW_INT(32,32)
199                 "audio/mpeg; "
200                 "audio/x-ac3; "
201                 "audio/x-private1-ac3; "
202                 "audio/x-dts; "
203                 "audio/x-private1-dts; "
204                 "audio/x-private1-lpcm; "
205                 "audio/x-wma;"
206                 "audio/x-eac3;"
207                 "audio/x-private-eac3")
208 );
209
210 static GstStaticPadTemplate sink_factory_broadcom =
211 GST_STATIC_PAD_TEMPLATE (
212         "sink",
213         GST_PAD_SINK,
214         GST_PAD_ALWAYS,
215         GST_STATIC_CAPS ("audio/mpeg; "
216                 "audio/x-ac3; "
217                 "audio/x-private1-ac3")
218 );
219
220 #define DEBUG_INIT(bla) \
221         GST_DEBUG_CATEGORY_INIT (dvbaudiosink_debug, "dvbaudiosink", 0, "dvbaudiosink element");
222
223 GST_BOILERPLATE_FULL (GstDVBAudioSink, gst_dvbaudiosink, GstBaseSink, GST_TYPE_BASE_SINK, DEBUG_INIT);
224
225 static void gst_dvbaudiosink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
226 static void gst_dvbaudiosink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
227
228 static gboolean gst_dvbaudiosink_start (GstBaseSink * sink);
229 static gboolean gst_dvbaudiosink_stop (GstBaseSink * sink);
230 static gboolean gst_dvbaudiosink_event (GstBaseSink * sink, GstEvent * event);
231 static GstFlowReturn gst_dvbaudiosink_render (GstBaseSink * sink, GstBuffer * buffer);
232 static gboolean gst_dvbaudiosink_unlock (GstBaseSink * basesink);
233 static gboolean gst_dvbaudiosink_unlock_stop (GstBaseSink * basesink);
234 static gboolean gst_dvbaudiosink_set_caps (GstBaseSink * sink, GstCaps * caps);
235 static void gst_dvbaudiosink_dispose (GObject * object);
236 static GstStateChangeReturn gst_dvbaudiosink_change_state (GstElement * element, GstStateChange transition);
237 static gint64 gst_dvbaudiosink_get_decoder_time (GstDVBAudioSink *self);
238
239 typedef enum { DM7025, DM800, DM8000, DM500HD, DM800SE, DM7020HD } hardware_type_t;
240
241 static hardware_type_t hwtype;
242 static GstStaticPadTemplate *hwtemplate;
243
244 static void
245 gst_dvbaudiosink_base_init (gpointer klass)
246 {
247         static GstElementDetails element_details = {
248                 "A DVB audio sink",
249                 "Generic/DVBAudioSink",
250                 "Outputs a MPEG2 PES / ES into a DVB audio device for hardware playback",
251                 "Felix Domke <tmbinc@elitedvb.net>"
252         };
253         GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
254
255         int fd = open("/proc/stb/info/model", O_RDONLY);
256         if ( fd > 0 )
257         {
258                 gchar string[9] = { 0, };
259                 ssize_t rd = read(fd, string, 8);
260                 if ( rd >= 5 )
261                 {
262                         string[rd] = 0;
263                         if ( !strncasecmp(string, "DM7025", 6) ) {
264                                 hwtype = DM7025;
265                                 hwtemplate = &sink_factory_ati_xilleon;
266                                 GST_INFO ("model is DM7025 set ati xilleon caps");
267                         }
268                         else if ( !strncasecmp(string, "DM8000", 6) ) {
269                                 hwtype = DM8000;
270                                 hwtemplate = &sink_factory_broadcom_dts;
271                                 GST_INFO ("model is DM8000 set broadcom dts caps");
272                         }
273                         else if ( !strncasecmp(string, "DM800SE", 7) ) {
274                                 hwtype = DM800SE;
275                                 hwtemplate = &sink_factory_broadcom_dts;
276                                 GST_INFO ("model is DM800SE set broadcom dts caps", string);
277                         }
278                         else if ( !strncasecmp(string, "DM7020HD", 8) ) {
279                                 hwtype = DM7020HD;
280                                 hwtemplate = &sink_factory_broadcom_dts;
281                                 GST_INFO ("model is DM7020HD set broadcom dts caps", string);
282                         }
283                         else if ( !strncasecmp(string, "DM800", 5) ) {
284                                 hwtype = DM800;
285                                 hwtemplate = &sink_factory_broadcom;
286                                 GST_INFO ("model is DM800 set broadcom caps", string);
287                         }
288                         else if ( !strncasecmp(string, "DM500HD", 7) ) {
289                                 hwtype = DM500HD;
290                                 hwtemplate = &sink_factory_broadcom_dts;
291                                 GST_INFO ("model is DM500HD set broadcom dts caps", string);
292                         }
293                         if (hwtemplate) {
294                                 gst_element_class_add_pad_template (element_class,
295                                         gst_static_pad_template_get (hwtemplate));
296                         }
297                 }
298                 close(fd);
299         }
300
301         gst_element_class_set_details (element_class, &element_details);
302 }
303
304 static GstCaps *
305 gst_dvbaudiosink_get_caps (GstBaseSink *basesink)
306 {
307 //      GstDVBAudioSink *self = GST_DVBAUDIOSINK (basesink);
308 //      gchar *strcaps;
309         GstCaps *caps;
310         static int eac3_support;
311
312         if (!eac3_support) {
313                 int fd = open("/proc/stb/audio/ac3plus", O_RDONLY);
314                 if (fd >= 0) {
315                         eac3_support = 1;
316                         close(fd);
317                 }
318                 else
319                         eac3_support = -1;
320         }
321
322         int eac3_pos = 12;
323
324         if (hwtype == DM8000) {
325                 caps = gst_caps_copy(&hwtemplate->static_caps.caps);
326                 gst_caps_remove_structure(caps, 11); // remove WMA!!
327                 --eac3_pos;
328         }
329         else
330                 caps = gst_static_caps_get(&hwtemplate->static_caps);
331
332         if (eac3_support < 0) {
333                 if (eac3_pos == 12)
334                         caps = gst_caps_copy(&hwtemplate->static_caps.caps);
335                 gst_caps_remove_structure(caps, eac3_pos); // remove x-eac3
336                 gst_caps_remove_structure(caps, eac3_pos); // remove x-private-eac3
337         }
338
339 //      strcaps = gst_caps_to_string(caps);
340 //      GST_INFO_OBJECT (self, "dynamic caps for model %d '%s'", hwtype, gst_caps_to_string(caps));
341 //      g_free(strcaps);
342
343         return caps;
344 }
345
346 static gboolean
347 gst_dvbaudiosink_acceptcaps (GstPad * pad, GstCaps * caps)
348 {
349         GstDVBAudioSink *self = GST_DVBAUDIOSINK (gst_pad_get_parent_element (pad));
350         gboolean ret = FALSE;
351
352         GstCaps *pad_caps = gst_pad_get_caps_reffed (pad);
353         if (pad_caps) {
354                 ret = gst_caps_can_intersect (pad_caps, caps);
355                 gst_caps_unref (pad_caps);
356                 if (!ret)
357                         goto done;
358         }
359
360         /* If we've not got fixed caps, creating a stream might fail, so let's just
361          * return from here with default acceptcaps behaviour */
362         if (!gst_caps_is_fixed (caps))
363                 goto done;
364         else
365         {
366                 GstStructure *st = gst_caps_get_structure (caps, 0);
367                 const char *type = gst_structure_get_name (st);
368
369                 if (!strcmp(type, "audio/mpeg") ||
370                     !strcmp(type, "audio/x-ac3") ||
371                     !strcmp(type, "audio/x-eac3") ||
372 //                  !strcmp(type, "audio/x-private1-ac3") ||
373 //                  !strcmp(type, "audio/x-private1-lpcm") ||
374 //                  !strcmp(type, "audio/x-wma") ||
375 //                  !strcmp(type, "audio/x-raw-int") ||
376 //                  !strcmp(type, "audio/x-private1-dts") ||
377                     !strcmp(type, "audio/x-dts"))
378                 {
379                         gboolean framed = FALSE, parsed = FALSE;
380                         gst_structure_get_boolean (st, "framed", &framed);
381                         gst_structure_get_boolean (st, "parsed", &parsed);
382
383                         GST_INFO_OBJECT(self, "framed %d, parsed %d", framed, parsed);
384
385                         if ((!framed && !parsed)) {
386                                 ret = FALSE;
387                                 goto done;
388                         }
389                 }
390         }
391
392         ret = TRUE;
393
394 done:
395         gst_object_unref (self);
396
397         return ret;
398 }
399
400 static int
401 gst_dvbaudiosink_async_write(GstDVBAudioSink *self, unsigned char *data, unsigned int len);
402
403 /* initialize the plugin's class */
404 static void
405 gst_dvbaudiosink_class_init (GstDVBAudioSinkClass *klass)
406 {
407         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
408         GstBaseSinkClass *gstbasesink_class = GST_BASE_SINK_CLASS (klass);
409         GstElementClass *gelement_class = GST_ELEMENT_CLASS (klass);
410
411         gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_dvbaudiosink_dispose);
412         gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_dvbaudiosink_set_property);
413         gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_dvbaudiosink_get_property);
414         g_object_class_install_property (gobject_class, PROP_LOCATION,
415                 g_param_spec_string ("dump-filename", "Dump File Location",
416                         "Filename that Packetized Elementary Stream will be written to", NULL,
417                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
418
419         gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_dvbaudiosink_start);
420         gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_dvbaudiosink_stop);
421         gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_dvbaudiosink_render);
422         gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_dvbaudiosink_event);
423         gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_dvbaudiosink_unlock);
424         gstbasesink_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_dvbaudiosink_unlock_stop);
425         gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_dvbaudiosink_set_caps);
426         gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_dvbaudiosink_get_caps);
427
428         gelement_class->change_state = GST_DEBUG_FUNCPTR (gst_dvbaudiosink_change_state);
429
430         gst_dvbaudiosink_signals[SIGNAL_GET_DECODER_TIME] =
431                 g_signal_new ("get-decoder-time",
432                 G_TYPE_FROM_CLASS (klass),
433                 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
434                 G_STRUCT_OFFSET (GstDVBAudioSinkClass, get_decoder_time),
435                 NULL, NULL, gst_dvbsink_marshal_INT64__VOID, G_TYPE_INT64, 0);
436
437         klass->get_decoder_time = gst_dvbaudiosink_get_decoder_time;
438         klass->async_write = gst_dvbaudiosink_async_write;
439 }
440
441 /* initialize the new element
442  * instantiate pads and add them to element
443  * set functions
444  * initialize structure
445  */
446 static void
447 gst_dvbaudiosink_init (GstDVBAudioSink *klass, GstDVBAudioSinkClass * gclass)
448 {
449         klass->bypass = -1;
450
451         klass->timestamp = GST_CLOCK_TIME_NONE;
452         klass->aac_adts_header_valid = FALSE;
453         klass->temp_buffer = NULL;
454         klass->temp_bytes = 0;
455
456         klass->no_write = 0;
457         klass->queue = NULL;
458         klass->fd = -1;
459         klass->dump_fd = -1;
460         klass->dump_filename = NULL;
461
462         gst_base_sink_set_sync (GST_BASE_SINK(klass), FALSE);
463         gst_base_sink_set_async_enabled (GST_BASE_SINK(klass), TRUE);
464
465         gst_pad_set_acceptcaps_function (GST_BASE_SINK (klass)->sinkpad,
466                 GST_DEBUG_FUNCPTR (gst_dvbaudiosink_acceptcaps));
467 }
468
469 static void
470 gst_dvbaudiosink_dispose (GObject * object)
471 {
472         GstDVBAudioSink *self = GST_DVBAUDIOSINK (object);
473         GstState state, pending;
474         GST_DEBUG_OBJECT (self, "dispose");
475
476 // hack for gstreamer decodebin2 bug... it tries to dispose .. but doesnt set the state to NULL when it is READY
477         switch(gst_element_get_state(GST_ELEMENT(object), &state, &pending, GST_CLOCK_TIME_NONE))
478         {
479         case GST_STATE_CHANGE_SUCCESS:
480                 GST_DEBUG_OBJECT(self, "success");
481                 if (state != GST_STATE_NULL) {
482                         GST_DEBUG_OBJECT(self, "state %d in dispose.. set it to NULL (decodebin2 bug?)", state);
483                         if (gst_element_set_state(GST_ELEMENT(object), GST_STATE_NULL) == GST_STATE_CHANGE_ASYNC) {
484                                 GST_DEBUG_OBJECT(self, "set state returned async... wait!");
485                                 gst_element_get_state(GST_ELEMENT(object), &state, &pending, GST_CLOCK_TIME_NONE);
486                         }
487                 }
488                 break;
489         case GST_STATE_CHANGE_ASYNC:
490                 GST_DEBUG_OBJECT(self, "async");
491                 break;
492         case GST_STATE_CHANGE_FAILURE:
493                 GST_DEBUG_OBJECT(self, "failure");
494                 break;
495         case GST_STATE_CHANGE_NO_PREROLL:
496                 GST_DEBUG_OBJECT(self, "no preroll");
497                 break;
498         default:
499                 break;
500         }
501 // hack end
502
503         GST_DEBUG_OBJECT(self, "state in dispose %d, pending %d", state, pending);
504
505         if (self->dump_filename)
506         {
507                         g_free (self->dump_filename);
508                         self->dump_filename = NULL;
509         }
510
511         G_OBJECT_CLASS (parent_class)->dispose (object);
512 }
513
514 static gboolean
515 gst_dvbaudiosink_set_location (GstDVBAudioSink * sink, const gchar * location)
516 {
517         if (sink->dump_fd)
518                 goto was_open;
519
520         g_free (sink->dump_filename);
521         if (location != NULL) {
522                 /* we store the filename as we received it from the application. On Windows
523                 * this should be in UTF8 */
524                 sink->dump_filename = g_strdup (location);
525         } else {
526                 sink->dump_filename = NULL;
527         }
528
529         return TRUE;
530
531         /* ERRORS */
532         was_open:
533         {
534                 g_warning ("Changing the `dump-filename' property during operation is not supported.");
535                 return FALSE;
536         }
537 }
538
539 static void
540 gst_dvbaudiosink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
541 {
542         GstDVBAudioSink *sink = GST_DVBAUDIOSINK (object);
543
544         switch (prop_id) {
545                 case PROP_LOCATION:
546                 gst_dvbaudiosink_set_location (sink, g_value_get_string (value));
547                 break;
548                 default:
549                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
550                 break;
551         }
552 }
553
554 static void
555 gst_dvbaudiosink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
556 {
557         GstDVBAudioSink *sink = GST_DVBAUDIOSINK (object);
558
559         switch (prop_id) {
560                 case PROP_LOCATION:
561                 g_value_set_string (value, sink->dump_filename);
562                 break;
563                 default:
564                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
565                 break;
566         }
567 }
568
569 static gint64
570 gst_dvbaudiosink_get_decoder_time (GstDVBAudioSink *self)
571 {
572         if (self->bypass != -1) {
573                 gint64 cur = 0;
574                 static gint64 last_pos = 0;
575
576                 ioctl(self->fd, AUDIO_GET_PTS, &cur);
577
578                 /* workaround until driver fixed */
579                 if (cur)
580                         last_pos = cur;
581                 else
582                         cur = last_pos;
583
584                 cur *= 11111;
585
586                 return cur;
587         }
588         return GST_CLOCK_TIME_NONE;
589 }
590
591 static gboolean
592 gst_dvbaudiosink_unlock (GstBaseSink * basesink)
593 {
594         GstDVBAudioSink *self = GST_DVBAUDIOSINK (basesink);
595         GST_OBJECT_LOCK(self);
596         self->no_write |= 2;
597         GST_OBJECT_UNLOCK(self);
598         SEND_COMMAND (self, CONTROL_STOP);
599         GST_DEBUG_OBJECT (basesink, "unlock");
600         return TRUE;
601 }
602
603 static gboolean
604 gst_dvbaudiosink_unlock_stop (GstBaseSink * basesink)
605 {
606         GstDVBAudioSink *self = GST_DVBAUDIOSINK (basesink);
607         GST_OBJECT_LOCK(self);
608         self->no_write &= ~2;
609         GST_OBJECT_UNLOCK(self);
610         GST_DEBUG_OBJECT (basesink, "unlock_stop");
611         return TRUE;
612 }
613
614 gint get_audio_object_type(bitstream_t *bit)
615 {
616         gint type = bitstream_get(bit, 5);
617         if (type == 31)
618                 type = 32 + bitstream_get(bit, 6);
619         return type;
620 }
621
622 static gboolean
623 gst_dvbaudiosink_set_caps (GstBaseSink * basesink, GstCaps * caps)
624 {
625         GstDVBAudioSink *self = GST_DVBAUDIOSINK (basesink);
626         GstStructure *structure = gst_caps_get_structure (caps, 0);
627         const char *type = gst_structure_get_name (structure);
628         int bypass = -1;
629
630         self->skip = 0;
631         self->block_align = 0;
632         self->aac_adts_header_valid = FALSE;
633         if (self->temp_buffer) {
634                 gst_buffer_unref(self->temp_buffer);
635                 self->temp_buffer = NULL;
636         }
637
638         if (!strcmp(type, "audio/mpeg")) {
639                 gint mpegversion;
640                 gst_structure_get_int (structure, "mpegversion", &mpegversion);
641                 switch (mpegversion) {
642                         case 1:
643                         {
644                                 gint layer;
645                                 gst_structure_get_int (structure, "layer", &layer);
646                                 if ( layer == 3 )
647                                         bypass = 0xA;
648                                 else
649                                         bypass = 1;
650                                 GST_INFO_OBJECT (self, "MIMETYPE %s version %d layer %d",type,mpegversion,layer);
651                                 break;
652                         }
653                         case 2:
654                         case 4:
655                         {
656                                 const gchar *stream_type = gst_structure_get_string (structure, "stream-type");
657                                 if (!stream_type)
658                                         stream_type = gst_structure_get_string (structure, "stream-format");
659                                 if (stream_type && !strcmp(stream_type, "adts"))
660                                         GST_INFO_OBJECT (self, "MIMETYPE %s version %d (AAC-ADTS)", type, mpegversion);
661                                 else {
662                                         const GValue *codec_data = gst_structure_get_value (structure, "codec_data");
663                                         GST_INFO_OBJECT (self, "MIMETYPE %s version %d (AAC-RAW)", type, mpegversion);
664                                         if (codec_data) {
665                                                 gint rate = 0, ext_rate = -1, is_sbr = 0, is_ps = 0;
666                                                 GstBuffer *b = gst_value_get_buffer (codec_data);
667                                                 guint8 *h = GST_BUFFER_DATA(b);
668                                                 guint l = GST_BUFFER_SIZE(b);
669                                                 guint max_bits = l * 8;
670                                                 gint obj_type, rate_idx, channel_config, ext_obj_type=0, ext_rate_idx=0;
671                                                 bitstream_t bs;
672                                                 bitstream_init (&bs, h, 0);
673
674                                                 obj_type = get_audio_object_type(&bs);
675                                                 GST_INFO_OBJECT (self, "(1)obj_type %d", obj_type);
676                                                 rate_idx = bitstream_get(&bs, 4);
677                                                 GST_INFO_OBJECT (self, "(1)rate_idx %d", rate_idx);
678                                                 if (rate_idx == 0x0f) {
679                                                         rate = bitstream_get(&bs, 24);
680                                                         GST_INFO_OBJECT (self, "(1)rate %d", rate);
681                                                 }
682
683                                                 channel_config = bitstream_get(&bs, 4);
684                                                 if (obj_type == 5 || obj_type == 29) {
685                                                         ext_obj_type = 5;
686                                                         ext_rate_idx = bitstream_get(&bs, 4);
687                                                         GST_INFO_OBJECT (self, "(2)ext_rate_idx %d", ext_rate_idx);
688                                                         if (ext_rate_idx == 0xf) {
689                                                                 ext_rate = bitstream_get(&bs, 24);
690                                                                 GST_INFO_OBJECT (self, "(2)rate %d", rate);
691                                                         }
692                                                         obj_type = get_audio_object_type(&bs);
693                                                         GST_INFO_OBJECT (self, "(2)obj_type %d", obj_type);
694                                                 }
695
696                                                 /* GASpecificConfig Skip */
697                                                 switch (obj_type) {
698                                                 case 1 ... 3:
699                                                 case 4:
700                                                 case 6 ... 7:
701                                                 case 17:
702                                                 case 19 ... 23:
703                                                 {
704                                                         gint ext_flag = 0;
705
706                                                         bitstream_get(&bs, 1); // fl flag
707
708                                                         if(bitstream_get(&bs, 1)) { // delay flag
709                                                                 /* Delay is 14 bits */
710                                                                 bitstream_get(&bs, 14);
711                                                         }
712
713                                                         ext_flag = bitstream_get(&bs, 1);
714
715                                                         if (channel_config == 0)
716                                                                 GST_ERROR_OBJECT (self, "GASpecificConfig Parser broken! FIXMEE");
717
718                                                         if (obj_type == 6 || obj_type == 20) {
719                                                                 bitstream_get(&bs, 3);
720                                                         }
721
722                                                         if (ext_flag) {
723                                                                 if (obj_type == 22) {
724                                                                         bitstream_get(&bs, 16);
725                                                                 }
726                                                                 else if (obj_type == 17 || obj_type == 19 || obj_type == 20 || obj_type == 23) {
727                                                                         bitstream_get(&bs, 3);
728                                                                 }
729                                                                 bitstream_get(&bs, 1);
730                                                         }
731                                                         break;
732                                                 }
733                                                 }
734
735                                                 /* ErrorSpecificConfig Skip */
736                                                 switch (obj_type) {
737                                                 case 17:
738                                                 case 19 ... 27:
739                                                         switch (bitstream_get(&bs, 2)) {
740                                                         case 2 ... 3:
741                                                                 bitstream_get(&bs, 1);
742                                                         default:
743                                                                 break;
744                                                         }
745                                                 default:
746                                                         break;
747                                                 }
748
749                                                 if (ext_obj_type != 5 && max_bits - bs.processed_bits >= 16) {
750                                                         if (bitstream_get(&bs, 11) == 0x2b7) {
751                                                                 gint tmp_obj_type = get_audio_object_type(&bs);
752                                                                 GST_INFO_OBJECT (self, "(3)temp_obj_type %d", tmp_obj_type);
753                                                                 if (tmp_obj_type == 5) {
754                                                                         is_sbr = bitstream_get(&bs, 1);
755                                                                         if (is_sbr) { // sbr present flag
756                                                                                 ext_rate_idx = bitstream_get(&bs, 4);
757                                                                                 GST_INFO_OBJECT (self, "(3)ext_rate_idx %d", ext_rate_idx);
758                                                                                 if (ext_rate_idx == 0xf) {
759                                                                                         ext_rate = bitstream_get(&bs, 24);
760                                                                                         GST_INFO_OBJECT (self, "(3)rate %d", rate);
761                                                                                 }
762                                                                                 if (max_bits - bs.processed_bits >= 12) {
763                                                                                         if (bitstream_get(&bs, 11) == 0x548) {
764                                                                                                 is_ps = bitstream_get(&bs, 1);
765                                                                                         }
766                                                                                 }
767                                                                                 GST_INFO_OBJECT (self, "(3)obj_type %d", obj_type);
768                                                                                 obj_type = tmp_obj_type;
769                                                                         }
770                                                                 }
771                                                         }
772                                                 }
773
774                                                 /* Convert rate to rate index */
775                                                 if (rate_idx == 0xf) {
776                                                         rate_idx = 0;
777                                                         do {
778                                                                 if (AdtsSamplingRates[rate_idx] == rate)
779                                                                         break;
780                                                                 ++rate_idx;
781                                                         } while (AdtsSamplingRates[rate_idx]);
782                                                         GST_INFO_OBJECT (self, "calculated rate_idx %d for rate %d", rate_idx, rate);
783                                                 }
784
785                                                 if (obj_type == 5) {
786                                                         obj_type = 1; // AAC LC
787 //                                                      bypass = 0x0b; // always use AAC+ ADTS yet..
788 //                                                      GST_INFO_OBJECT (self, "SBR detected.. use AAC+");
789                                                 }
790                                                 else if (obj_type > 5) {
791 //                                                      bypass = 0x0b; // AAC ADTS
792                                                         GST_WARNING_OBJECT (self, "AAC object type %d not usable with AAC ADTS .. force AAC-LC");
793                                                         obj_type = 1; // AAC LC
794                                                 }
795                                                 else {
796                                                         obj_type -= 1;
797 //                                                      bypass = 0x08; // AAC ADTS
798 //                                                      GST_INFO_OBJECT (self, "AAC object type %d, AAC codec");
799                                                 }
800
801                                                 if (ext_rate != -1)
802                                                         GST_INFO_OBJECT (self, "AAC with codec data ... set ADTS obj_type = %d, ADTS rate_idx = %d(%d), ext rate %d(%d), channel config = %d, mpegversion %d, is_sbr %d, is_ps %d\n",
803                                                                 obj_type, rate_idx, AdtsSamplingRates[rate_idx], ext_rate_idx, AdtsSamplingRates[ext_rate_idx], channel_config, mpegversion, is_sbr, is_ps);
804                                                 else
805                                                         GST_INFO_OBJECT (self, "AAC with codec data ... set ADTS obj_type = %d, ADTS rate_idx = %d(%d), channel config = %d, mpegversion %d, is_sbr %d, is_ps %d\n",
806                                                                 obj_type, rate_idx, AdtsSamplingRates[rate_idx], channel_config, mpegversion, is_sbr, is_ps);
807
808                                                 /* Sync point over a full byte */
809                                                 self->aac_adts_header[0] = 0xFF;
810                                                 /* Sync point continued over first 4 bits + static 4 bits
811                                                  * (ID, layer, protection)*/
812                                                 self->aac_adts_header[1] = 0xF1;
813                                                 if (mpegversion == 2)
814                                                         self->aac_adts_header[1] |= 8;
815                                                 /* Object type over first 2 bits */
816                                                 self->aac_adts_header[2] = ((obj_type & 3) << 6);
817
818                                                 /* rate index over next 4 bits */
819                                                 self->aac_adts_header[2] |= ((rate_idx & 0xF) << 2);
820                                                 /* channels over last bit */
821                                                 self->aac_adts_header[2] |= ((channel_config & 0x4) >> 2);
822                                                 /* channels continued over next 2 bits + 4 bits at zero */
823                                                 self->aac_adts_header[3] = ((channel_config & 0x3) << 6);
824                                                 self->aac_adts_header_valid = TRUE;
825                                         }
826                                         else {
827                                                 gint rate, channels, rate_idx=0, obj_type=1; // hardcoded yet.. hopefully this works every time ;)
828                                                 GST_INFO_OBJECT (self, "no codec data");
829                                                 if (gst_structure_get_int (structure, "rate", &rate) && gst_structure_get_int (structure, "channels", &channels)) {
830                                                         do {
831                                                                 if (AdtsSamplingRates[rate_idx] == rate)
832                                                                         break;
833                                                                 ++rate_idx;
834                                                         } while (AdtsSamplingRates[rate_idx]);
835                                                         if (AdtsSamplingRates[rate_idx]) {
836                                                                 GST_INFO_OBJECT (self, "mpegversion %d, channels %d, rate %d, rate_idx %d\n", mpegversion, channels, rate, rate_idx);
837                                                                 /* Sync point over a full byte */
838                                                                 self->aac_adts_header[0] = 0xFF;
839                                                                 /* Sync point continued over first 4 bits + static 4 bits
840                                                                  * (ID, layer, protection)*/
841                                                                 self->aac_adts_header[1] = 0xF1;
842                                                                 if (mpegversion == 2)
843                                                                         self->aac_adts_header[1] |= 8;
844                                                                 /* Object type over first 2 bits */
845                                                                 self->aac_adts_header[2] = obj_type << 6;
846                                                                 /* rate index over next 4 bits */
847                                                                 self->aac_adts_header[2] |= rate_idx << 2;
848                                                                 /* channels over last 2 bits */
849                                                                 self->aac_adts_header[2] |= (channels & 0x4) >> 2;
850                                                                 /* channels continued over next 2 bits + 4 bits at zero */
851                                                                 self->aac_adts_header[3] = (channels & 0x3) << 6;
852                                                                 self->aac_adts_header_valid = TRUE;
853                                                                 GST_WARNING_OBJECT(self, "FIXMEE no AAC codec data available... use forced AAC-LC profile and AAC+ ADTS codec!");
854                                                         }
855                                                 }
856                                         }
857                                 }
858                                 if (bypass == -1)
859                                         bypass = 0x0b;
860                                 break;
861                         }
862                         default:
863                                 GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL), ("unhandled mpeg version %i", mpegversion));
864                                 break;
865                 }
866         }
867         else if (!strcmp(type, "audio/x-ac3")) {
868                 GST_INFO_OBJECT (self, "MIMETYPE %s",type);
869                 bypass = 0;
870         }
871         else if (!strcmp(type, "audio/x-private1-dts")) {
872                 GST_INFO_OBJECT (self, "MIMETYPE %s (DVD Audio - 2 byte skipping)",type);
873                 bypass = 2;
874                 self->skip = 2;
875         }
876         else if (!strcmp(type, "audio/x-private1-ac3")) {
877                 GST_INFO_OBJECT (self, "MIMETYPE %s (DVD Audio - 2 byte skipping)",type);
878                 bypass = 0;
879                 self->skip = 2;
880         }
881         else if (!strcmp(type, "audio/x-eac3")) {
882                 GST_INFO_OBJECT (self, "MIMETYPE %s",type);
883                 bypass = 7;
884         }
885         else if (!strcmp(type, "audio/x-private1-eac3")) {
886                 GST_INFO_OBJECT (self, "MIMETYPE %s (DVD Audio - 2 byte skipping)",type);
887                 bypass = 7;
888                 self->skip = 2;
889         }
890         else if (!strcmp(type, "audio/x-private1-lpcm")) {
891                 GST_INFO_OBJECT (self, "MIMETYPE %s (DVD Audio)",type);
892                 bypass = 6;
893         }
894         else if (!strcmp(type, "audio/x-wma")) {
895                 const GValue *codec_data = gst_structure_get_value (structure, "codec_data");
896                 if (codec_data) {
897                         GstBuffer *b = gst_value_get_buffer (codec_data);
898                         guint8 *cd = GST_BUFFER_DATA(b);
899                         guint clen = GST_BUFFER_SIZE(b);
900                         gint version;
901                         gst_structure_get_int (structure, "wmaversion", &version);
902                         GST_INFO_OBJECT (self, "MIMETYPE %s",type);
903                         if (version == 2)
904                                 bypass = 0xd;
905                         else if (version == 3)
906                                 bypass = 0xe;
907                         else
908                                 GST_ERROR_OBJECT(self, "unsupported wma version %d!", version);
909                         if (bypass != -1) {
910                                 gint channels, rate, bitrate, depth;
911                                 int codec = version + 0x15f; /*GST_RIFF_WAVE_FORMAT_WMAV1 - 1*/;
912                                 gst_structure_get_int (structure, "block_align", &self->block_align);
913                                 gst_structure_get_int (structure, "channels", &channels);
914                                 gst_structure_get_int (structure, "rate", &rate);
915                                 gst_structure_get_int (structure, "bitrate", &bitrate);
916                                 gst_structure_get_int (structure, "depth", &depth);
917                                 self->temp_offset = 18+8+clen;
918                                 self->temp_buffer = gst_buffer_new_and_alloc(self->temp_offset+self->block_align);
919                                 guint8 *d = GST_BUFFER_DATA(self->temp_buffer);
920                                 memcpy(d, "BCMA", 4);
921                                 d[4] = (self->block_align & 0xFF000000) >> 24;
922                                 d[5] = (self->block_align & 0xFF0000) >> 16;
923                                 d[6] = (self->block_align & 0xFF00) >> 8;
924                                 d[7] = (self->block_align & 0xFF);
925                                 // rebuild WAVFORMATEX
926                                 d[8] = (codec & 0xFF);
927                                 d[9] = (codec & 0xFF00) >> 8;
928                                 d[10] = channels & 0xFF;
929                                 d[11] = (channels >> 8) & 0xFF;
930                                 d[12] = rate & 0xFF; // sample rate
931                                 d[13] = (rate & 0xFF00) >> 8;
932                                 d[14] = (rate & 0xFF0000) >> 16;
933                                 d[15] = (rate & 0xFF000000) >> 24;
934                                 d[16] = (bitrate >> 3) & 0xFF; // byte rate
935                                 d[17] = (bitrate >> 11) & 0xFF;
936                                 d[18] = (bitrate >> 19) & 0xFF;
937                                 d[19] = (bitrate >> 27) & 0xFF;
938                                 d[20] = d[7]; // block align
939                                 d[21] = d[6];
940                                 d[22] = depth & 0xFF; // word size
941                                 d[23] = (depth >> 8) & 0xFF;
942                                 d[24] = clen & 0xFF; // codec data len
943                                 d[25] = (clen >> 8) & 0xFF;
944                                 memcpy(d+18+8, cd, clen);
945                         }
946                 }
947                 else
948                         GST_ERROR_OBJECT(self, "no wma codec data!");
949         }
950         else if (!strcmp(type, "audio/x-raw-int")) {
951                 GST_INFO_OBJECT (self, "MIMETYPE %s",type);
952                 bypass = 0xf;
953                 gint block_align, width, rate, depth, channels, bitrate;
954                 gst_structure_get_int (structure, "channels", &channels);
955                 gst_structure_get_int (structure, "rate", &rate);
956                 gst_structure_get_int (structure, "width", &width);
957                 gst_structure_get_int (structure, "depth", &depth);
958                 // calc size of pcm data for 30ms
959                 self->block_align = rate * 30 / 1000;
960                 self->block_align *= channels * depth / 8;
961                 block_align = channels * width / 8;
962                 bitrate = channels * rate * width;
963                 self->temp_offset = 18+8;
964                 self->temp_buffer = gst_buffer_new_and_alloc(self->temp_offset+self->block_align);
965                 guint8 *d = GST_BUFFER_DATA(self->temp_buffer);
966                 memcpy(d, "BCMA", 4);
967                 d[4] = (self->block_align & 0xFF000000) >> 24;
968                 d[5] = (self->block_align & 0xFF0000) >> 16;
969                 d[6] = (self->block_align & 0xFF00) >> 8;
970                 d[7] = (self->block_align & 0xFF);
971                 // rebuild WAVFORMAT
972                 d[8] = 0x01; // format tag
973                 d[9] = 0x00;
974                 d[10] = channels & 0xFF;
975                 d[11] = (channels >> 8) & 0xFF;
976                 d[12] = rate & 0xFF; // sample rate
977                 d[13] = (rate & 0xFF00) >> 8;
978                 d[14] = (rate & 0xFF0000) >> 16;
979                 d[15] = (rate & 0xFF000000) >> 24;
980                 d[16] = (bitrate >> 3) & 0xFF; // byte rate
981                 d[17] = (bitrate >> 11) & 0xFF;
982                 d[18] = (bitrate >> 19) & 0xFF;
983                 d[19] = (bitrate >> 27) & 0xFF;
984                 d[20] = block_align & 0xFF; // block align
985                 d[21] = (block_align >> 8) & 0xFF;
986                 d[22] = depth & 0xFF; // word size
987                 d[23] = (depth >> 8) & 0xFF;
988                 d[24] = 0; // codec data len
989                 d[25] = 0;
990         }
991         else if (!strcmp(type, "audio/x-dts")) {
992                 GST_INFO_OBJECT (self, "MIMETYPE %s",type);
993                 bypass = 2;
994         }
995         else {
996                 GST_ELEMENT_ERROR (self, STREAM, TYPE_NOT_FOUND, (NULL), ("unimplemented stream type %s", type));
997                 return FALSE;
998         }
999
1000         GST_INFO_OBJECT(self, "setting dvb mode 0x%02x\n", bypass);
1001
1002         if (ioctl(self->fd, AUDIO_SET_BYPASS_MODE, bypass) < 0) {
1003                 if (bypass == 2) {
1004                         GST_ELEMENT_ERROR (self, STREAM, TYPE_NOT_FOUND, (NULL), ("hardware decoder can't be set to bypass mode type %s", type));
1005                         return FALSE;
1006                 }
1007                 GST_ELEMENT_WARNING (self, STREAM, DECODE, (NULL), ("hardware decoder can't be set to bypass mode %i.", bypass));
1008 //              return FALSE;
1009         }
1010         self->bypass = bypass;
1011         return TRUE;
1012 }
1013
1014 static void
1015 queue_push(queue_entry_t **queue_base, guint8 *data, size_t len)
1016 {
1017         queue_entry_t *entry = malloc(sizeof(queue_entry_t)+len);
1018         queue_entry_t *last = *queue_base;
1019         guint8 *d = (guint8*)(entry+1);
1020         memcpy(d, data, len);
1021         entry->bytes = len;
1022         entry->offset = 0;
1023         if (!last)
1024                 *queue_base = entry;
1025         else {
1026                 while(last->next)
1027                         last = last->next;
1028                 last->next = entry;
1029         }
1030         entry->next = NULL;
1031 }
1032
1033 static void
1034 queue_pop(queue_entry_t **queue_base)
1035 {
1036         queue_entry_t *base = *queue_base;
1037         *queue_base = base->next;
1038         free(base);
1039 }
1040
1041 static int
1042 queue_front(queue_entry_t **queue_base, guint8 **data, size_t *bytes)
1043 {
1044         if (!*queue_base) {
1045                 *bytes = 0;
1046                 *data = 0;
1047         }
1048         else {
1049                 queue_entry_t *entry = *queue_base;
1050                 *bytes = entry->bytes - entry->offset;
1051                 *data = ((guint8*)(entry+1))+entry->offset;
1052         }
1053         return *bytes;
1054 }
1055
1056 static gboolean
1057 gst_dvbaudiosink_event (GstBaseSink * sink, GstEvent * event)
1058 {
1059         GstDVBAudioSink *self = GST_DVBAUDIOSINK (sink);
1060         GST_DEBUG_OBJECT (self, "EVENT %s", gst_event_type_get_name(GST_EVENT_TYPE (event)));
1061         int ret=TRUE;
1062
1063         switch (GST_EVENT_TYPE (event)) {
1064         case GST_EVENT_FLUSH_START:
1065                 GST_OBJECT_LOCK(self);
1066                 self->no_write |= 1;
1067                 GST_OBJECT_UNLOCK(self);
1068                 SEND_COMMAND (self, CONTROL_STOP);
1069                 break;
1070         case GST_EVENT_FLUSH_STOP:
1071                 ioctl(self->fd, AUDIO_CLEAR_BUFFER);
1072                 GST_OBJECT_LOCK(self);
1073                 while(self->queue)
1074                         queue_pop(&self->queue);
1075                 self->timestamp = GST_CLOCK_TIME_NONE;
1076                 self->no_write &= ~1;
1077                 GST_OBJECT_UNLOCK(self);
1078                 break;
1079         case GST_EVENT_EOS:
1080         {
1081                 struct pollfd pfd[2];
1082                 int retval;
1083
1084                 pfd[0].fd = READ_SOCKET(self);
1085                 pfd[0].events = POLLIN;
1086                 pfd[1].fd = self->fd;
1087                 pfd[1].events = POLLIN;
1088
1089                 GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
1090                 while (1) {
1091                         retval = poll(pfd, 2, 250);
1092                         if (retval < 0) {
1093                                 perror("poll in EVENT_EOS");
1094                                 ret=FALSE;
1095                                 break;
1096                         }
1097
1098                         if (pfd[0].revents & POLLIN) {
1099                                 GST_DEBUG_OBJECT (self, "wait EOS aborted!!\n");
1100                                 ret=FALSE;
1101                                 break;
1102                         }
1103
1104                         if (pfd[1].revents & POLLIN) {
1105                                 GST_DEBUG_OBJECT (self, "got buffer empty from driver!\n");
1106                                 break;
1107                         }
1108
1109                         if (sink->flushing) {
1110                                 GST_DEBUG_OBJECT (self, "wait EOS flushing!!\n");
1111                                 ret=FALSE;
1112                                 break;
1113                         }
1114                 }
1115                 GST_PAD_PREROLL_LOCK (sink->sinkpad);
1116
1117                 break;
1118         }
1119         case GST_EVENT_NEWSEGMENT:{
1120                 GstFormat fmt;
1121                 gboolean update;
1122                 gdouble rate, applied_rate;
1123                 gint64 cur, stop, time;
1124                 int skip = 0, repeat = 0;
1125                 gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate, &fmt, &cur, &stop, &time);
1126                 GST_DEBUG_OBJECT (self, "GST_EVENT_NEWSEGMENT rate=%f applied_rate=%f\n", rate, applied_rate);
1127
1128                 if (fmt == GST_FORMAT_TIME) {
1129                         int video_fd = open("/dev/dvb/adapter0/video0", O_RDWR);
1130                         if (video_fd >= 0) {
1131                                 if ( rate > 1 )
1132                                         skip = (int) rate;
1133                                 else if ( rate < 1 )
1134                                         repeat = 1.0/rate;
1135                                 ioctl(video_fd, VIDEO_SLOWMOTION, repeat);
1136                                 ioctl(video_fd, VIDEO_FAST_FORWARD, skip);
1137 //                              gst_segment_set_newsegment_full (&dec->segment, update, rate, applied_rate, dformat, cur, stop, time);
1138                                 close(video_fd);
1139                         }
1140                 }
1141                 break;
1142         }
1143
1144         default:
1145                 break;
1146         }
1147
1148         return ret;
1149 }
1150
1151 #define ASYNC_WRITE(data, len) do { \
1152                 switch(gst_dvbaudiosink_async_write(self, data, len)) { \
1153                 case -1: goto poll_error; \
1154                 case -3: goto write_error; \
1155                 default: break; \
1156                 } \
1157         } while(0)
1158
1159 static int
1160 gst_dvbaudiosink_async_write(GstDVBAudioSink *self, unsigned char *data, unsigned int len)
1161 {
1162         unsigned int written=0;
1163         struct pollfd pfd[2];
1164
1165         pfd[0].fd = READ_SOCKET(self);
1166         pfd[0].events = POLLIN;
1167         pfd[1].fd = self->fd;
1168         pfd[1].events = POLLOUT;
1169
1170         do {
1171 loop_start:
1172                 if (self->no_write & 1) {
1173                         GST_DEBUG_OBJECT (self, "skip %d bytes", len - written);
1174                         break;
1175                 }
1176                 else if (self->no_write & 6) {
1177                         // directly push to queue
1178                         GST_OBJECT_LOCK(self);
1179                         queue_push(&self->queue, data + written, len - written);
1180                         GST_OBJECT_UNLOCK(self);
1181                         GST_DEBUG_OBJECT (self, "pushed %d bytes to queue", len - written);
1182                         break;
1183                 }
1184                 else
1185                         GST_LOG_OBJECT (self, "going into poll, have %d bytes to write", len - written);
1186                 if (poll(pfd, 2, -1) == -1) {
1187                         if (errno == EINTR)
1188                                 continue;
1189                         return -1;
1190                 }
1191                 if (pfd[0].revents & POLLIN) {
1192                         /* read all stop commands */
1193                         while (TRUE) {
1194                                 gchar command;
1195                                 int res;
1196                                 READ_COMMAND (self, command, res);
1197                                 if (res < 0) {
1198                                         GST_DEBUG_OBJECT (self, "no more commands");
1199                                         /* no more commands */
1200                                         goto loop_start;
1201                                 }
1202                         }
1203                 }
1204                 if (pfd[1].revents & POLLOUT) {
1205                         size_t queue_entry_size;
1206                         guint8 *queue_data;
1207                         GST_OBJECT_LOCK(self);
1208                         if (queue_front(&self->queue, &queue_data, &queue_entry_size)) {
1209                                 int wr = write(self->fd, queue_data, queue_entry_size);
1210                                 if ( self->dump_fd > 0 )
1211                                                 write(self->dump_fd, queue_data, queue_entry_size);
1212                                 if (wr < 0) {
1213                                         switch (errno) {
1214                                                 case EINTR:
1215                                                 case EAGAIN:
1216                                                         break;
1217                                                 default:
1218                                                         GST_OBJECT_UNLOCK(self);
1219                                                         return -3;
1220                                         }
1221                                 }
1222                                 else if (wr == queue_entry_size) {
1223                                         queue_pop(&self->queue);
1224                                         GST_DEBUG_OBJECT (self, "written %d queue bytes... pop entry", wr);
1225                                 }
1226                                 else {
1227                                         self->queue->offset += wr;
1228                                         GST_DEBUG_OBJECT (self, "written %d queue bytes... update offset", wr);
1229                                 }
1230                                 GST_OBJECT_UNLOCK(self);
1231                                 continue;
1232                         }
1233                         GST_OBJECT_UNLOCK(self);
1234                         int wr = write(self->fd, data+written, len - written);
1235                         if ( self->dump_fd > 0 )
1236                                         write(self->dump_fd, data+written, len - written);
1237                         if (wr < 0) {
1238                                 switch (errno) {
1239                                         case EINTR:
1240                                         case EAGAIN:
1241                                                 continue;
1242                                         default:
1243                                                 return -3;
1244                                 }
1245                         }
1246                         written += wr;
1247                 }
1248         } while (written != len);
1249
1250         return 0;
1251 }
1252
1253 static GstFlowReturn
1254 gst_dvbaudiosink_render (GstBaseSink * sink, GstBuffer * buffer)
1255 {
1256         GstDVBAudioSink *self = GST_DVBAUDIOSINK (sink);
1257         unsigned char pes_header[64];
1258         unsigned int size = GST_BUFFER_SIZE (buffer) - self->skip;
1259         unsigned char *data = GST_BUFFER_DATA (buffer) + self->skip;
1260         GstClockTime timestamp = GST_BUFFER_TIMESTAMP(buffer);
1261         GstClockTime duration = GST_BUFFER_DURATION(buffer);
1262         unsigned int bytes_left = size;
1263         int num_blocks = self->block_align ? size / self->block_align : 1;
1264
1265         size_t pes_header_size;
1266 //      int i=0;
1267
1268         /* LPCM workaround.. we also need the first two byte of the lpcm header.. (substreamid and num of frames) 
1269            i dont know why the mpegpsdemux strips out this two bytes... */
1270         if (self->bypass == 6 && (data[0] < 0xA0 || data[0] > 0xAF)) {
1271                 if (data[-2] >= 0xA0 && data[-2] <= 0xAF) {
1272                         data -= 2;
1273                         size += 2;
1274                 }
1275                 else
1276                         GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL), ("lpcm broken!"));
1277         }
1278
1279         if (duration != GST_CLOCK_TIME_NONE && timestamp != GST_CLOCK_TIME_NONE && self->bypass != 0xd && self->bypass != 0xe) {
1280                 if (self->timestamp == GST_CLOCK_TIME_NONE)
1281                         self->timestamp = timestamp;
1282                 else
1283                         timestamp = self->timestamp;
1284                 if (self->bypass < 0xd)
1285                         self->timestamp += duration;
1286         }
1287         else
1288                 self->timestamp = GST_CLOCK_TIME_NONE;
1289
1290 //      for (;i < (size > 0x1F ? 0x1F : size); ++i)
1291 //              printf("%02x ", data[i]);
1292 //      printf("%d bytes\n", size);
1293 //      printf("timestamp(A): %016lld, buffer timestamp: %016lld, duration %lld, diff %lld, num_blocks %d\n", timestamp, GST_BUFFER_TIMESTAMP(buffer), duration,
1294 //              (timestamp > GST_BUFFER_TIMESTAMP(buffer) ? timestamp - GST_BUFFER_TIMESTAMP(buffer) : GST_BUFFER_TIMESTAMP(buffer) - timestamp) / 1000000, num_blocks);
1295
1296         if ( self->bypass == -1 ) {
1297                 GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL), ("hardware decoder not setup (no caps in pipeline?)"));
1298                 return GST_FLOW_ERROR;
1299         }
1300
1301         if (self->fd < 0)
1302                 return GST_FLOW_OK;
1303
1304         pes_header[0] = 0;
1305         pes_header[1] = 0;
1306         pes_header[2] = 1;
1307         pes_header[3] = 0xC0;
1308
1309         if (self->aac_adts_header_valid)
1310                 size += 7; // ADTS Header length
1311         else if (self->temp_buffer)
1312                 size = self->block_align + self->temp_offset;
1313
1314 next_chunk:
1315                 /* do we have a timestamp? */
1316         if (timestamp != GST_CLOCK_TIME_NONE) {
1317                 unsigned long long pts = timestamp * 9LL / 100000 /* convert ns to 90kHz */;
1318
1319                 pes_header[6] = 0x80;
1320
1321                 pes_header[9]  = 0x21 | ((pts >> 29) & 0xE);
1322                 pes_header[10] = pts >> 22;
1323                 pes_header[11] = 0x01 | ((pts >> 14) & 0xFE);
1324                 pes_header[12] = pts >> 7;
1325                 pes_header[13] = 0x01 | ((pts << 1) & 0xFE);
1326
1327                 if (hwtype == DM7025) {  // DM7025 needs DTS in PES header
1328                         int64_t dts = pts; // what to use as DTS-PTS offset?
1329                         pes_header[4] = (size + 13) >> 8;
1330                         pes_header[5] = (size + 13) & 0xFF;
1331                         pes_header[7] = 0xC0;
1332                         pes_header[8] = 10;
1333                         pes_header[9] |= 0x10;
1334
1335                         pes_header[14] = 0x11 | ((dts >> 29) & 0xE);
1336                         pes_header[15] = dts >> 22;
1337                         pes_header[16] = 0x01 | ((dts >> 14) & 0xFE);
1338                         pes_header[17] = dts >> 7;
1339                         pes_header[18] = 0x01 | ((dts << 1) & 0xFE);
1340                         pes_header_size = 19;
1341                 }
1342                 else {
1343                         pes_header[4] = (size + 8) >> 8;
1344                         pes_header[5] = (size + 8) & 0xFF;
1345                         pes_header[7] = 0x80;
1346                         pes_header[8] = 5;
1347                         pes_header_size = 14;
1348                 }
1349         }
1350         else {
1351                 pes_header[4] = (size + 3) >> 8;
1352                 pes_header[5] = (size + 3) & 0xFF;
1353                 pes_header[6] = 0x80;
1354                 pes_header[7] = 0x00;
1355                 pes_header[8] = 0;
1356                 pes_header_size = 9;
1357         }
1358
1359         if (self->aac_adts_header_valid) {
1360                 self->aac_adts_header[3] &= 0xC0;
1361                 /* frame size over last 2 bits */
1362                 self->aac_adts_header[3] |= (size & 0x1800) >> 11;
1363                 /* frame size continued over full byte */
1364                 self->aac_adts_header[4] = (size & 0x7F8) >> 3;
1365                 /* frame size continued first 3 bits */
1366                 self->aac_adts_header[5] = (size & 7) << 5;
1367                 /* buffer fullness (0x7FF for VBR) over 5 last bits */
1368                 self->aac_adts_header[5] |= 0x1F;
1369                 /* buffer fullness (0x7FF for VBR) continued over 6 first bits + 2 zeros for
1370                  * number of raw data blocks */
1371                 self->aac_adts_header[6] = 0xFC;
1372                 memcpy(pes_header + pes_header_size, self->aac_adts_header, 7);
1373                 pes_header_size += 7;
1374                 size -= 7;
1375         }
1376         else if (self->temp_buffer) {
1377                 guint8 *d = GST_BUFFER_DATA(self->temp_buffer) + self->temp_offset + self->temp_bytes;
1378                 guint cp_size = self->block_align - self->temp_bytes;
1379                 if (bytes_left < cp_size)
1380                         cp_size = bytes_left;
1381                 memcpy(d, data, cp_size);
1382                 data += cp_size;
1383                 bytes_left -= cp_size;
1384                 self->temp_bytes += cp_size;
1385         }
1386
1387         if (!self->temp_buffer || self->temp_bytes == self->block_align) {
1388                 ASYNC_WRITE(pes_header, pes_header_size);
1389                 if (!self->temp_buffer)
1390                         ASYNC_WRITE(data, size);
1391                 else {
1392                         ASYNC_WRITE(GST_BUFFER_DATA(self->temp_buffer), GST_BUFFER_SIZE(self->temp_buffer));
1393                         self->temp_bytes = 0;
1394                         if (self->bypass == 0xf) {
1395                                 self->timestamp += 30*1000000; // always 30ms per chunk
1396                                 timestamp += 30*1000000;
1397                         }
1398                         else if (self->bypass == 0xd || self->bypass == 0xe) {
1399                                 self->timestamp += duration/num_blocks;
1400                                 timestamp += duration/num_blocks;
1401                         }
1402                         else
1403                                 timestamp = GST_CLOCK_TIME_NONE;
1404                         if (bytes_left)
1405                                 goto next_chunk;
1406                 }
1407         }
1408
1409         return GST_FLOW_OK;
1410 poll_error:
1411         {
1412                 GST_ELEMENT_ERROR (self, RESOURCE, READ, (NULL),
1413                                 ("poll on file descriptor: %s.", g_strerror (errno)));
1414                 GST_WARNING_OBJECT (self, "Error during poll");
1415                 return GST_FLOW_ERROR;
1416         }
1417 write_error:
1418         {
1419                 GST_ELEMENT_ERROR (self, RESOURCE, READ, (NULL),
1420                                 ("write on file descriptor: %s.", g_strerror (errno)));
1421                 GST_WARNING_OBJECT (self, "Error during write");
1422                 return GST_FLOW_ERROR;
1423         }
1424 }
1425
1426 static gboolean
1427 gst_dvbaudiosink_start (GstBaseSink * basesink)
1428 {
1429         GstDVBAudioSink *self = GST_DVBAUDIOSINK (basesink);
1430         gint control_sock[2];
1431
1432         GST_DEBUG_OBJECT (self, "start");
1433
1434         if (socketpair(PF_UNIX, SOCK_STREAM, 0, control_sock) < 0) {
1435                 perror("socketpair");
1436                 goto socket_pair;
1437         }
1438
1439         READ_SOCKET (self) = control_sock[0];
1440         WRITE_SOCKET (self) = control_sock[1];
1441
1442         fcntl (READ_SOCKET (self), F_SETFL, O_NONBLOCK);
1443         fcntl (WRITE_SOCKET (self), F_SETFL, O_NONBLOCK);
1444
1445         return TRUE;
1446         /* ERRORS */
1447 socket_pair:
1448         {
1449                 GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ_WRITE, (NULL),
1450                                 GST_ERROR_SYSTEM);
1451                 return FALSE;
1452         }
1453 }
1454
1455 static gboolean
1456 gst_dvbaudiosink_stop (GstBaseSink * basesink)
1457 {
1458         GstDVBAudioSink *self = GST_DVBAUDIOSINK (basesink);
1459
1460         GST_DEBUG_OBJECT (self, "stop");
1461
1462         if (self->fd >= 0) {
1463                 int video_fd = open("/dev/dvb/adapter0/video0", O_RDWR);
1464
1465                 ioctl(self->fd, AUDIO_STOP);
1466                 ioctl(self->fd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX);
1467
1468                 if ( video_fd > 0 ) {
1469                         ioctl(video_fd, VIDEO_SLOWMOTION, 0);
1470                         ioctl(video_fd, VIDEO_FAST_FORWARD, 0);
1471                         close (video_fd);
1472                 }
1473                 close(self->fd);
1474         }
1475
1476         if (self->dump_fd > 0)
1477                 close(self->dump_fd);
1478
1479         while(self->queue)
1480                 queue_pop(&self->queue);
1481
1482         if (self->temp_buffer)
1483                 gst_buffer_unref(self->temp_buffer);
1484
1485         close (READ_SOCKET (self));
1486         close (WRITE_SOCKET (self));
1487         READ_SOCKET (self) = -1;
1488         WRITE_SOCKET (self) = -1;
1489
1490         return TRUE;
1491 }
1492
1493 static GstStateChangeReturn
1494 gst_dvbaudiosink_change_state (GstElement * element, GstStateChange transition)
1495 {
1496         GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
1497         GstDVBAudioSink *self = GST_DVBAUDIOSINK (element);
1498
1499         switch (transition) {
1500         case GST_STATE_CHANGE_NULL_TO_READY:
1501                 GST_DEBUG_OBJECT (self,"GST_STATE_CHANGE_NULL_TO_READY");
1502                 break;
1503         case GST_STATE_CHANGE_READY_TO_PAUSED:
1504                 GST_DEBUG_OBJECT (self,"GST_STATE_CHANGE_READY_TO_PAUSED");
1505                 GST_OBJECT_LOCK(self);
1506                 self->no_write |= 4;
1507                 GST_OBJECT_UNLOCK(self);
1508
1509                 if (self->dump_filename)
1510                                 self->dump_fd = open(self->dump_filename, O_RDWR|O_CREAT, 0555);
1511
1512                 self->fd = open("/dev/dvb/adapter0/audio0", O_RDWR|O_NONBLOCK);
1513
1514                 if (self->fd) {
1515                         ioctl(self->fd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY);
1516                         ioctl(self->fd, AUDIO_PLAY);
1517                         ioctl(self->fd, AUDIO_PAUSE);
1518                 }
1519                 break;
1520         case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1521                 GST_DEBUG_OBJECT (self,"GST_STATE_CHANGE_PAUSED_TO_PLAYING");
1522                 ioctl(self->fd, AUDIO_CONTINUE);
1523                 GST_OBJECT_LOCK(self);
1524                 self->no_write &= ~4;
1525                 GST_OBJECT_UNLOCK(self);
1526                 break;
1527         default:
1528                 break;
1529         }
1530
1531         ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1532
1533         switch (transition) {
1534         case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1535                 GST_DEBUG_OBJECT (self,"GST_STATE_CHANGE_PLAYING_TO_PAUSED");
1536                 GST_OBJECT_LOCK(self);
1537                 self->no_write |= 4;
1538                 GST_OBJECT_UNLOCK(self);
1539                 ioctl(self->fd, AUDIO_PAUSE);
1540                 SEND_COMMAND (self, CONTROL_STOP);
1541                 break;
1542         case GST_STATE_CHANGE_PAUSED_TO_READY:
1543                 GST_DEBUG_OBJECT (self,"GST_STATE_CHANGE_PAUSED_TO_READY");
1544                 break;
1545         case GST_STATE_CHANGE_READY_TO_NULL:
1546                 GST_DEBUG_OBJECT (self,"GST_STATE_CHANGE_READY_TO_NULL");
1547                 break;
1548         default:
1549                 break;
1550         }
1551
1552         return ret;
1553 }
1554
1555 /* entry point to initialize the plug-in
1556  * initialize the plug-in itself
1557  * register the element factories and pad templates
1558  * register the features
1559  *
1560  * exchange the string 'plugin' with your elemnt name
1561  */
1562 static gboolean
1563 plugin_init (GstPlugin *plugin)
1564 {
1565         return gst_element_register (plugin, "dvbaudiosink",
1566                                                  GST_RANK_PRIMARY,
1567                                                  GST_TYPE_DVBAUDIOSINK);
1568 }
1569
1570 /* this is the structure that gstreamer looks for to register plugins
1571  *
1572  * exchange the strings 'plugin' and 'Template plugin' with you plugin name and
1573  * description
1574  */
1575 GST_PLUGIN_DEFINE (
1576         GST_VERSION_MAJOR,
1577         GST_VERSION_MINOR,
1578         "dvb_audio_out",
1579         "DVB Audio Output",
1580         plugin_init,
1581         VERSION,
1582         "LGPL",
1583         "GStreamer",
1584         "http://gstreamer.net/"
1585 )