small fixes
[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 && self->fd > -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                 if (self->fd < 0)
1085                         break;
1086
1087                 pfd[0].fd = READ_SOCKET(self);
1088                 pfd[0].events = POLLIN;
1089                 pfd[1].fd = self->fd;
1090                 pfd[1].events = POLLIN;
1091
1092                 GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
1093                 while (1) {
1094                         retval = poll(pfd, 2, 250);
1095                         if (retval < 0) {
1096                                 perror("poll in EVENT_EOS");
1097                                 ret=FALSE;
1098                                 break;
1099                         }
1100
1101                         if (pfd[0].revents & POLLIN) {
1102                                 GST_DEBUG_OBJECT (self, "wait EOS aborted!!\n");
1103                                 ret=FALSE;
1104                                 break;
1105                         }
1106
1107                         if (pfd[1].revents & POLLIN) {
1108                                 GST_DEBUG_OBJECT (self, "got buffer empty from driver!\n");
1109                                 break;
1110                         }
1111
1112                         if (sink->flushing) {
1113                                 GST_DEBUG_OBJECT (self, "wait EOS flushing!!\n");
1114                                 ret=FALSE;
1115                                 break;
1116                         }
1117                 }
1118                 GST_PAD_PREROLL_LOCK (sink->sinkpad);
1119
1120                 break;
1121         }
1122         case GST_EVENT_NEWSEGMENT:{
1123                 GstFormat fmt;
1124                 gboolean update;
1125                 gdouble rate, applied_rate;
1126                 gint64 cur, stop, time;
1127                 int skip = 0, repeat = 0;
1128                 gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate, &fmt, &cur, &stop, &time);
1129                 GST_DEBUG_OBJECT (self, "GST_EVENT_NEWSEGMENT rate=%f applied_rate=%f\n", rate, applied_rate);
1130
1131                 if (fmt == GST_FORMAT_TIME) {
1132                         int video_fd = open("/dev/dvb/adapter0/video0", O_RDWR);
1133                         if (video_fd >= 0) {
1134                                 if ( rate > 1 )
1135                                         skip = (int) rate;
1136                                 else if ( rate < 1 )
1137                                         repeat = 1.0/rate;
1138                                 ioctl(video_fd, VIDEO_SLOWMOTION, repeat);
1139                                 ioctl(video_fd, VIDEO_FAST_FORWARD, skip);
1140 //                              gst_segment_set_newsegment_full (&dec->segment, update, rate, applied_rate, dformat, cur, stop, time);
1141                                 close(video_fd);
1142                         }
1143                 }
1144                 break;
1145         }
1146
1147         default:
1148                 break;
1149         }
1150
1151         return ret;
1152 }
1153
1154 #define ASYNC_WRITE(data, len) do { \
1155                 switch(gst_dvbaudiosink_async_write(self, data, len)) { \
1156                 case -1: goto poll_error; \
1157                 case -3: goto write_error; \
1158                 default: break; \
1159                 } \
1160         } while(0)
1161
1162 static int
1163 gst_dvbaudiosink_async_write(GstDVBAudioSink *self, unsigned char *data, unsigned int len)
1164 {
1165         unsigned int written=0;
1166         struct pollfd pfd[2];
1167
1168         pfd[0].fd = READ_SOCKET(self);
1169         pfd[0].events = POLLIN;
1170         pfd[1].fd = self->fd;
1171         pfd[1].events = POLLOUT;
1172
1173         do {
1174 loop_start:
1175                 if (self->no_write & 1) {
1176                         GST_DEBUG_OBJECT (self, "skip %d bytes", len - written);
1177                         break;
1178                 }
1179                 else if (self->no_write & 6) {
1180                         // directly push to queue
1181                         GST_OBJECT_LOCK(self);
1182                         queue_push(&self->queue, data + written, len - written);
1183                         GST_OBJECT_UNLOCK(self);
1184                         GST_DEBUG_OBJECT (self, "pushed %d bytes to queue", len - written);
1185                         break;
1186                 }
1187                 else
1188                         GST_LOG_OBJECT (self, "going into poll, have %d bytes to write", len - written);
1189                 if (poll(pfd, 2, -1) == -1) {
1190                         if (errno == EINTR)
1191                                 continue;
1192                         return -1;
1193                 }
1194                 if (pfd[0].revents & POLLIN) {
1195                         /* read all stop commands */
1196                         while (TRUE) {
1197                                 gchar command;
1198                                 int res;
1199                                 READ_COMMAND (self, command, res);
1200                                 if (res < 0) {
1201                                         GST_DEBUG_OBJECT (self, "no more commands");
1202                                         /* no more commands */
1203                                         goto loop_start;
1204                                 }
1205                         }
1206                 }
1207                 if (pfd[1].revents & POLLOUT) {
1208                         size_t queue_entry_size;
1209                         guint8 *queue_data;
1210                         GST_OBJECT_LOCK(self);
1211                         if (queue_front(&self->queue, &queue_data, &queue_entry_size)) {
1212                                 int wr = write(self->fd, queue_data, queue_entry_size);
1213                                 if ( self->dump_fd > 0 )
1214                                                 write(self->dump_fd, queue_data, queue_entry_size);
1215                                 if (wr < 0) {
1216                                         switch (errno) {
1217                                                 case EINTR:
1218                                                 case EAGAIN:
1219                                                         break;
1220                                                 default:
1221                                                         GST_OBJECT_UNLOCK(self);
1222                                                         return -3;
1223                                         }
1224                                 }
1225                                 else if (wr == queue_entry_size) {
1226                                         queue_pop(&self->queue);
1227                                         GST_DEBUG_OBJECT (self, "written %d queue bytes... pop entry", wr);
1228                                 }
1229                                 else {
1230                                         self->queue->offset += wr;
1231                                         GST_DEBUG_OBJECT (self, "written %d queue bytes... update offset", wr);
1232                                 }
1233                                 GST_OBJECT_UNLOCK(self);
1234                                 continue;
1235                         }
1236                         GST_OBJECT_UNLOCK(self);
1237                         int wr = write(self->fd, data+written, len - written);
1238                         if ( self->dump_fd > 0 )
1239                                         write(self->dump_fd, data+written, len - written);
1240                         if (wr < 0) {
1241                                 switch (errno) {
1242                                         case EINTR:
1243                                         case EAGAIN:
1244                                                 continue;
1245                                         default:
1246                                                 return -3;
1247                                 }
1248                         }
1249                         written += wr;
1250                 }
1251         } while (written != len);
1252
1253         return 0;
1254 }
1255
1256 static GstFlowReturn
1257 gst_dvbaudiosink_render (GstBaseSink * sink, GstBuffer * buffer)
1258 {
1259         GstDVBAudioSink *self = GST_DVBAUDIOSINK (sink);
1260         unsigned char pes_header[64];
1261         unsigned int size = GST_BUFFER_SIZE (buffer) - self->skip;
1262         unsigned char *data = GST_BUFFER_DATA (buffer) + self->skip;
1263         GstClockTime timestamp = GST_BUFFER_TIMESTAMP(buffer);
1264         GstClockTime duration = GST_BUFFER_DURATION(buffer);
1265         unsigned int bytes_left = size;
1266         int num_blocks = self->block_align ? size / self->block_align : 1;
1267
1268         size_t pes_header_size;
1269 //      int i=0;
1270
1271         /* LPCM workaround.. we also need the first two byte of the lpcm header.. (substreamid and num of frames) 
1272            i dont know why the mpegpsdemux strips out this two bytes... */
1273         if (self->bypass == 6 && (data[0] < 0xA0 || data[0] > 0xAF)) {
1274                 if (data[-2] >= 0xA0 && data[-2] <= 0xAF) {
1275                         data -= 2;
1276                         size += 2;
1277                 }
1278                 else
1279                         GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL), ("lpcm broken!"));
1280         }
1281
1282         if (duration != GST_CLOCK_TIME_NONE && timestamp != GST_CLOCK_TIME_NONE && self->bypass != 0xd && self->bypass != 0xe) {
1283                 if (self->timestamp == GST_CLOCK_TIME_NONE)
1284                         self->timestamp = timestamp;
1285                 else
1286                         timestamp = self->timestamp;
1287                 if (self->bypass < 0xd)
1288                         self->timestamp += duration;
1289         }
1290         else
1291                 self->timestamp = GST_CLOCK_TIME_NONE;
1292
1293 //      for (;i < (size > 0x1F ? 0x1F : size); ++i)
1294 //              printf("%02x ", data[i]);
1295 //      printf("%d bytes\n", size);
1296 //      printf("timestamp(A): %016lld, buffer timestamp: %016lld, duration %lld, diff %lld, num_blocks %d\n", timestamp, GST_BUFFER_TIMESTAMP(buffer), duration,
1297 //              (timestamp > GST_BUFFER_TIMESTAMP(buffer) ? timestamp - GST_BUFFER_TIMESTAMP(buffer) : GST_BUFFER_TIMESTAMP(buffer) - timestamp) / 1000000, num_blocks);
1298
1299         if ( self->bypass == -1 ) {
1300                 GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL), ("hardware decoder not setup (no caps in pipeline?)"));
1301                 return GST_FLOW_ERROR;
1302         }
1303
1304         if (self->fd < 0)
1305                 return GST_FLOW_OK;
1306
1307         pes_header[0] = 0;
1308         pes_header[1] = 0;
1309         pes_header[2] = 1;
1310         pes_header[3] = 0xC0;
1311
1312         if (self->aac_adts_header_valid)
1313                 size += 7; // ADTS Header length
1314         else if (self->temp_buffer)
1315                 size = self->block_align + self->temp_offset;
1316
1317 next_chunk:
1318                 /* do we have a timestamp? */
1319         if (timestamp != GST_CLOCK_TIME_NONE) {
1320                 unsigned long long pts = timestamp * 9LL / 100000 /* convert ns to 90kHz */;
1321
1322                 pes_header[6] = 0x80;
1323
1324                 pes_header[9]  = 0x21 | ((pts >> 29) & 0xE);
1325                 pes_header[10] = pts >> 22;
1326                 pes_header[11] = 0x01 | ((pts >> 14) & 0xFE);
1327                 pes_header[12] = pts >> 7;
1328                 pes_header[13] = 0x01 | ((pts << 1) & 0xFE);
1329
1330                 if (hwtype == DM7025) {  // DM7025 needs DTS in PES header
1331                         int64_t dts = pts; // what to use as DTS-PTS offset?
1332                         pes_header[4] = (size + 13) >> 8;
1333                         pes_header[5] = (size + 13) & 0xFF;
1334                         pes_header[7] = 0xC0;
1335                         pes_header[8] = 10;
1336                         pes_header[9] |= 0x10;
1337
1338                         pes_header[14] = 0x11 | ((dts >> 29) & 0xE);
1339                         pes_header[15] = dts >> 22;
1340                         pes_header[16] = 0x01 | ((dts >> 14) & 0xFE);
1341                         pes_header[17] = dts >> 7;
1342                         pes_header[18] = 0x01 | ((dts << 1) & 0xFE);
1343                         pes_header_size = 19;
1344                 }
1345                 else {
1346                         pes_header[4] = (size + 8) >> 8;
1347                         pes_header[5] = (size + 8) & 0xFF;
1348                         pes_header[7] = 0x80;
1349                         pes_header[8] = 5;
1350                         pes_header_size = 14;
1351                 }
1352         }
1353         else {
1354                 pes_header[4] = (size + 3) >> 8;
1355                 pes_header[5] = (size + 3) & 0xFF;
1356                 pes_header[6] = 0x80;
1357                 pes_header[7] = 0x00;
1358                 pes_header[8] = 0;
1359                 pes_header_size = 9;
1360         }
1361
1362         if (self->aac_adts_header_valid) {
1363                 self->aac_adts_header[3] &= 0xC0;
1364                 /* frame size over last 2 bits */
1365                 self->aac_adts_header[3] |= (size & 0x1800) >> 11;
1366                 /* frame size continued over full byte */
1367                 self->aac_adts_header[4] = (size & 0x7F8) >> 3;
1368                 /* frame size continued first 3 bits */
1369                 self->aac_adts_header[5] = (size & 7) << 5;
1370                 /* buffer fullness (0x7FF for VBR) over 5 last bits */
1371                 self->aac_adts_header[5] |= 0x1F;
1372                 /* buffer fullness (0x7FF for VBR) continued over 6 first bits + 2 zeros for
1373                  * number of raw data blocks */
1374                 self->aac_adts_header[6] = 0xFC;
1375                 memcpy(pes_header + pes_header_size, self->aac_adts_header, 7);
1376                 pes_header_size += 7;
1377                 size -= 7;
1378         }
1379         else if (self->temp_buffer) {
1380                 guint8 *d = GST_BUFFER_DATA(self->temp_buffer) + self->temp_offset + self->temp_bytes;
1381                 guint cp_size = self->block_align - self->temp_bytes;
1382                 if (bytes_left < cp_size)
1383                         cp_size = bytes_left;
1384                 memcpy(d, data, cp_size);
1385                 data += cp_size;
1386                 bytes_left -= cp_size;
1387                 self->temp_bytes += cp_size;
1388         }
1389
1390         if (!self->temp_buffer || self->temp_bytes == self->block_align) {
1391                 ASYNC_WRITE(pes_header, pes_header_size);
1392                 if (!self->temp_buffer)
1393                         ASYNC_WRITE(data, size);
1394                 else {
1395                         ASYNC_WRITE(GST_BUFFER_DATA(self->temp_buffer), GST_BUFFER_SIZE(self->temp_buffer));
1396                         self->temp_bytes = 0;
1397                         if (self->bypass == 0xf) {
1398                                 self->timestamp += 30*1000000; // always 30ms per chunk
1399                                 timestamp += 30*1000000;
1400                         }
1401                         else if (self->bypass == 0xd || self->bypass == 0xe) {
1402                                 self->timestamp += duration/num_blocks;
1403                                 timestamp += duration/num_blocks;
1404                         }
1405                         else
1406                                 timestamp = GST_CLOCK_TIME_NONE;
1407                         if (bytes_left)
1408                                 goto next_chunk;
1409                 }
1410         }
1411
1412         return GST_FLOW_OK;
1413 poll_error:
1414         {
1415                 GST_ELEMENT_ERROR (self, RESOURCE, READ, (NULL),
1416                                 ("poll on file descriptor: %s.", g_strerror (errno)));
1417                 GST_WARNING_OBJECT (self, "Error during poll");
1418                 return GST_FLOW_ERROR;
1419         }
1420 write_error:
1421         {
1422                 GST_ELEMENT_ERROR (self, RESOURCE, READ, (NULL),
1423                                 ("write on file descriptor: %s.", g_strerror (errno)));
1424                 GST_WARNING_OBJECT (self, "Error during write");
1425                 return GST_FLOW_ERROR;
1426         }
1427 }
1428
1429 static gboolean
1430 gst_dvbaudiosink_start (GstBaseSink * basesink)
1431 {
1432         GstDVBAudioSink *self = GST_DVBAUDIOSINK (basesink);
1433         gint control_sock[2];
1434
1435         GST_DEBUG_OBJECT (self, "start");
1436
1437         if (socketpair(PF_UNIX, SOCK_STREAM, 0, control_sock) < 0) {
1438                 perror("socketpair");
1439                 goto socket_pair;
1440         }
1441
1442         READ_SOCKET (self) = control_sock[0];
1443         WRITE_SOCKET (self) = control_sock[1];
1444
1445         fcntl (READ_SOCKET (self), F_SETFL, O_NONBLOCK);
1446         fcntl (WRITE_SOCKET (self), F_SETFL, O_NONBLOCK);
1447
1448         return TRUE;
1449         /* ERRORS */
1450 socket_pair:
1451         {
1452                 GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ_WRITE, (NULL),
1453                                 GST_ERROR_SYSTEM);
1454                 return FALSE;
1455         }
1456 }
1457
1458 static gboolean
1459 gst_dvbaudiosink_stop (GstBaseSink * basesink)
1460 {
1461         GstDVBAudioSink *self = GST_DVBAUDIOSINK (basesink);
1462
1463         GST_DEBUG_OBJECT (self, "stop");
1464
1465         if (self->fd >= 0) {
1466                 int video_fd = open("/dev/dvb/adapter0/video0", O_RDWR);
1467
1468                 ioctl(self->fd, AUDIO_STOP);
1469                 ioctl(self->fd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX);
1470
1471                 if ( video_fd > 0 ) {
1472                         ioctl(video_fd, VIDEO_SLOWMOTION, 0);
1473                         ioctl(video_fd, VIDEO_FAST_FORWARD, 0);
1474                         close (video_fd);
1475                 }
1476                 close(self->fd);
1477         }
1478
1479         if (self->dump_fd > 0)
1480                 close(self->dump_fd);
1481
1482         while(self->queue)
1483                 queue_pop(&self->queue);
1484
1485         if (self->temp_buffer)
1486                 gst_buffer_unref(self->temp_buffer);
1487
1488         close (READ_SOCKET (self));
1489         close (WRITE_SOCKET (self));
1490         READ_SOCKET (self) = -1;
1491         WRITE_SOCKET (self) = -1;
1492
1493         return TRUE;
1494 }
1495
1496 static GstStateChangeReturn
1497 gst_dvbaudiosink_change_state (GstElement * element, GstStateChange transition)
1498 {
1499         GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
1500         GstDVBAudioSink *self = GST_DVBAUDIOSINK (element);
1501
1502         switch (transition) {
1503         case GST_STATE_CHANGE_NULL_TO_READY:
1504                 GST_DEBUG_OBJECT (self,"GST_STATE_CHANGE_NULL_TO_READY");
1505                 break;
1506         case GST_STATE_CHANGE_READY_TO_PAUSED:
1507                 GST_DEBUG_OBJECT (self,"GST_STATE_CHANGE_READY_TO_PAUSED");
1508                 GST_OBJECT_LOCK(self);
1509                 self->no_write |= 4;
1510                 GST_OBJECT_UNLOCK(self);
1511
1512                 if (self->dump_filename)
1513                                 self->dump_fd = open(self->dump_filename, O_RDWR|O_CREAT, 0555);
1514
1515                 self->fd = open("/dev/dvb/adapter0/audio0", O_RDWR|O_NONBLOCK);
1516
1517                 if (self->fd) {
1518                         ioctl(self->fd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY);
1519                         ioctl(self->fd, AUDIO_PLAY);
1520                         ioctl(self->fd, AUDIO_PAUSE);
1521                 }
1522                 break;
1523         case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1524                 GST_DEBUG_OBJECT (self,"GST_STATE_CHANGE_PAUSED_TO_PLAYING");
1525                 ioctl(self->fd, AUDIO_CONTINUE);
1526                 GST_OBJECT_LOCK(self);
1527                 self->no_write &= ~4;
1528                 GST_OBJECT_UNLOCK(self);
1529                 break;
1530         default:
1531                 break;
1532         }
1533
1534         ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1535
1536         switch (transition) {
1537         case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1538                 GST_DEBUG_OBJECT (self,"GST_STATE_CHANGE_PLAYING_TO_PAUSED");
1539                 GST_OBJECT_LOCK(self);
1540                 self->no_write |= 4;
1541                 GST_OBJECT_UNLOCK(self);
1542                 ioctl(self->fd, AUDIO_PAUSE);
1543                 SEND_COMMAND (self, CONTROL_STOP);
1544                 break;
1545         case GST_STATE_CHANGE_PAUSED_TO_READY:
1546                 GST_DEBUG_OBJECT (self,"GST_STATE_CHANGE_PAUSED_TO_READY");
1547                 break;
1548         case GST_STATE_CHANGE_READY_TO_NULL:
1549                 GST_DEBUG_OBJECT (self,"GST_STATE_CHANGE_READY_TO_NULL");
1550                 break;
1551         default:
1552                 break;
1553         }
1554
1555         return ret;
1556 }
1557
1558 /* entry point to initialize the plug-in
1559  * initialize the plug-in itself
1560  * register the element factories and pad templates
1561  * register the features
1562  *
1563  * exchange the string 'plugin' with your elemnt name
1564  */
1565 static gboolean
1566 plugin_init (GstPlugin *plugin)
1567 {
1568         return gst_element_register (plugin, "dvbaudiosink",
1569                                                  GST_RANK_PRIMARY,
1570                                                  GST_TYPE_DVBAUDIOSINK);
1571 }
1572
1573 /* this is the structure that gstreamer looks for to register plugins
1574  *
1575  * exchange the strings 'plugin' and 'Template plugin' with you plugin name and
1576  * description
1577  */
1578 GST_PLUGIN_DEFINE (
1579         GST_VERSION_MAJOR,
1580         GST_VERSION_MINOR,
1581         "dvb_audio_out",
1582         "DVB Audio Output",
1583         plugin_init,
1584         VERSION,
1585         "LGPL",
1586         "GStreamer",
1587         "http://gstreamer.net/"
1588 )