audioparsers: use ACCEPT_INTERSECT flag
[platform/upstream/gst-plugins-good.git] / gst / audioparsers / gstsbcparse.c
1 /* GStreamer SBC audio parser
2  * Copyright (C) 2012 Collabora Ltd. <tim.muller@collabora.co.uk>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 /**
25  * SECTION:element-sbcparse
26  * @see_also: sbcdec, sbcenc
27  *
28  * The sbcparse element will parse a bluetooth SBC audio stream into
29  * frames and timestamp them properly.
30  *
31  * Since: 1.2.0
32  */
33
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37
38 #include "gstsbcparse.h"
39
40 #include <string.h>
41 #include <gst/tag/tag.h>
42 #include <gst/audio/audio.h>
43
44 #include <gst/base/gstbitreader.h>
45 #include <gst/base/gstbytereader.h>
46
47 #define SBC_SYNCBYTE 0x9C
48
49 GST_DEBUG_CATEGORY_STATIC (sbcparse_debug);
50 #define GST_CAT_DEFAULT sbcparse_debug
51
52 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
53     GST_PAD_SRC,
54     GST_PAD_ALWAYS,
55     GST_STATIC_CAPS ("audio/x-sbc, parsed = (boolean) true, "
56         "channels = (int) [ 1, 2 ], "
57         "rate = (int) { 16000, 32000, 44100, 48000 }")
58     );
59
60 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
61     GST_PAD_SINK,
62     GST_PAD_ALWAYS,
63     GST_STATIC_CAPS ("audio/x-sbc")
64     );
65
66 static gboolean gst_sbc_parse_start (GstBaseParse * parse);
67 static gboolean gst_sbc_parse_stop (GstBaseParse * parse);
68 static GstFlowReturn gst_sbc_parse_handle_frame (GstBaseParse * parse,
69     GstBaseParseFrame * frame, gint * skipsize);
70 static GstCaps *gst_sbc_parse_get_sink_caps (GstBaseParse * parse,
71     GstCaps * filter);
72
73 static guint8 gst_sbc_calculate_crc8 (const guint8 * data, gint bits_crc);
74 static gsize gst_sbc_calc_framelen (guint subbands, GstSbcChannelMode ch_mode,
75     guint blocks, guint bitpool);
76 static gsize gst_sbc_parse_header (const guint8 * data, guint * rate,
77     guint * n_blocks, GstSbcChannelMode * ch_mode,
78     GstSbcAllocationMethod * alloc_method, guint * n_subbands, guint * bitpool);
79
80 #define parent_class gst_sbc_parse_parent_class
81 G_DEFINE_TYPE (GstSbcParse, gst_sbc_parse, GST_TYPE_BASE_PARSE);
82
83 static void
84 gst_sbc_parse_class_init (GstSbcParseClass * klass)
85 {
86   GstBaseParseClass *baseparse_class = GST_BASE_PARSE_CLASS (klass);
87   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
88
89   GST_DEBUG_CATEGORY_INIT (sbcparse_debug, "sbcparse", 0, "SBC audio parser");
90
91   baseparse_class->start = GST_DEBUG_FUNCPTR (gst_sbc_parse_start);
92   baseparse_class->stop = GST_DEBUG_FUNCPTR (gst_sbc_parse_stop);
93
94   baseparse_class->handle_frame =
95       GST_DEBUG_FUNCPTR (gst_sbc_parse_handle_frame);
96   baseparse_class->get_sink_caps =
97       GST_DEBUG_FUNCPTR (gst_sbc_parse_get_sink_caps);
98
99   gst_element_class_add_pad_template (element_class,
100       gst_static_pad_template_get (&src_factory));
101   gst_element_class_add_pad_template (element_class,
102       gst_static_pad_template_get (&sink_factory));
103
104   gst_element_class_set_static_metadata (element_class, "SBC audio parser",
105       "Codec/Parser/Audio", "Parses an SBC bluetooth audio stream",
106       "Tim-Philipp Müller <tim.muller@collabora.co.uk>");
107 }
108
109 static void
110 gst_sbc_parse_reset (GstSbcParse * sbcparse)
111 {
112   sbcparse->alloc_method = GST_SBC_ALLOCATION_METHOD_INVALID;
113   sbcparse->ch_mode = GST_SBC_CHANNEL_MODE_INVALID;
114   sbcparse->rate = -1;
115   sbcparse->n_blocks = -1;
116   sbcparse->n_subbands = -1;
117   sbcparse->bitpool = -1;
118 }
119
120 static void
121 gst_sbc_parse_init (GstSbcParse * sbcparse)
122 {
123   gst_sbc_parse_reset (sbcparse);
124   GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (sbcparse));
125 }
126
127 static gboolean
128 gst_sbc_parse_start (GstBaseParse * parse)
129 {
130   gst_base_parse_set_min_frame_size (parse,
131       gst_sbc_calc_framelen (4, GST_SBC_CHANNEL_MODE_MONO, 4, 2));
132
133   gst_base_parse_set_has_timing_info (parse, FALSE);
134
135   gst_base_parse_set_syncable (parse, TRUE);
136
137   return TRUE;
138 }
139
140 static gboolean
141 gst_sbc_parse_stop (GstBaseParse * parse)
142 {
143   gst_sbc_parse_reset (GST_SBC_PARSE (parse));
144   return TRUE;
145 }
146
147 static const gchar *
148 gst_sbc_channel_mode_get_name (GstSbcChannelMode ch_mode)
149 {
150   switch (ch_mode) {
151     case GST_SBC_CHANNEL_MODE_MONO:
152       return "mono";
153     case GST_SBC_CHANNEL_MODE_DUAL:
154       return "dual";
155     case GST_SBC_CHANNEL_MODE_STEREO:
156       return "stereo";
157     case GST_SBC_CHANNEL_MODE_JOINT_STEREO:
158       return "joint";
159     default:
160       break;
161   }
162   return "invalid";
163 }
164
165 static const gchar *
166 gst_sbc_allocation_method_get_name (GstSbcAllocationMethod alloc_method)
167 {
168   switch (alloc_method) {
169     case GST_SBC_ALLOCATION_METHOD_SNR:
170       return "snr";
171     case GST_SBC_ALLOCATION_METHOD_LOUDNESS:
172       return "loudness";
173     default:
174       break;
175   }
176   return "invalid";
177 }
178
179 static GstFlowReturn
180 gst_sbc_parse_handle_frame (GstBaseParse * parse, GstBaseParseFrame * frame,
181     gint * skipsize)
182 {
183   GstSbcParse *sbcparse = GST_SBC_PARSE (parse);
184   GstSbcAllocationMethod alloc_method = GST_SBC_ALLOCATION_METHOD_INVALID;
185   GstSbcChannelMode ch_mode = GST_SBC_CHANNEL_MODE_INVALID;
186   GstMapInfo map;
187   guint rate = 0, n_blocks = 0, n_subbands = 0, bitpool = 0;
188   gsize frame_len, next_len;
189   gint i, max_frames;
190
191   gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
192
193   g_assert (map.size >= 6);
194
195   frame_len = gst_sbc_parse_header (map.data, &rate, &n_blocks, &ch_mode,
196       &alloc_method, &n_subbands, &bitpool);
197
198   GST_LOG_OBJECT (parse, "frame_len: %u", (guint) frame_len);
199
200   if (frame_len == 0)
201     goto resync;
202
203   if (sbcparse->alloc_method != alloc_method
204       || sbcparse->ch_mode != ch_mode
205       || sbcparse->rate != rate
206       || sbcparse->n_blocks != n_blocks
207       || sbcparse->n_subbands != n_subbands || sbcparse->bitpool != bitpool) {
208     guint avg_bitrate;
209     GstCaps *caps;
210
211     /* FIXME: do all of these need to be in the caps? */
212     caps = gst_caps_new_simple ("audio/x-sbc", "rate", G_TYPE_INT, rate,
213         "channels", G_TYPE_INT, (ch_mode == GST_SBC_CHANNEL_MODE_MONO) ? 1 : 2,
214         "channel-mode", G_TYPE_STRING, gst_sbc_channel_mode_get_name (ch_mode),
215         "blocks", G_TYPE_INT, n_blocks, "subbands", G_TYPE_INT, n_subbands,
216         "allocation-method", G_TYPE_STRING,
217         gst_sbc_allocation_method_get_name (alloc_method),
218         "bitpool", G_TYPE_INT, bitpool, "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
219
220     GST_INFO_OBJECT (sbcparse, "caps changed to %" GST_PTR_FORMAT, caps);
221
222     gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (sbcparse),
223         gst_event_new_caps (caps));
224
225     avg_bitrate = (8 * frame_len * rate) / (n_subbands * n_blocks);
226     gst_base_parse_set_average_bitrate (parse, avg_bitrate);
227
228     gst_base_parse_set_frame_rate (parse, rate, n_subbands * n_blocks, 0, 0);
229
230     sbcparse->alloc_method = alloc_method;
231     sbcparse->ch_mode = ch_mode;
232     sbcparse->rate = rate;
233     sbcparse->n_blocks = n_blocks;
234     sbcparse->n_subbands = n_subbands;
235     sbcparse->bitpool = bitpool;
236
237     gst_caps_unref (caps);
238   }
239
240   if (frame_len > map.size)
241     goto need_more_data;
242
243   GST_BUFFER_OFFSET (frame->buffer) = GST_BUFFER_OFFSET_NONE;
244   GST_BUFFER_OFFSET_END (frame->buffer) = GST_BUFFER_OFFSET_NONE;
245
246   /* completely arbitrary limit, we only process data we already have,
247    * so we aren't introducing latency here */
248   max_frames = MIN (map.size / frame_len, n_blocks * n_subbands * 5);
249   GST_LOG_OBJECT (sbcparse, "parsing up to %d frames", max_frames);
250
251   for (i = 1; i < max_frames; ++i) {
252     next_len = gst_sbc_parse_header (map.data + (i * frame_len), &rate,
253         &n_blocks, &ch_mode, &alloc_method, &n_subbands, &bitpool);
254
255     if (next_len != frame_len || sbcparse->alloc_method != alloc_method ||
256         sbcparse->ch_mode != ch_mode || sbcparse->rate != rate ||
257         sbcparse->n_blocks != n_blocks || sbcparse->n_subbands != n_subbands ||
258         sbcparse->bitpool != bitpool) {
259       break;
260     }
261   }
262   GST_LOG_OBJECT (sbcparse, "packing %d SBC frames into next output buffer", i);
263
264   /* Note: local n_subbands and n_blocks variables might be tainted if we
265    * bailed out of the loop above because of a header configuration mismatch */
266   gst_base_parse_set_frame_rate (parse, rate,
267       sbcparse->n_subbands * sbcparse->n_blocks * i, 0, 0);
268
269   gst_buffer_unmap (frame->buffer, &map);
270   return gst_base_parse_finish_frame (parse, frame, i * frame_len);
271
272 resync:
273   {
274     const guint8 *possible_sync;
275
276     GST_DEBUG_OBJECT (parse, "no sync, resyncing");
277
278     possible_sync = memchr (map.data, SBC_SYNCBYTE, map.size);
279
280     if (possible_sync != NULL)
281       *skipsize = (gint) (possible_sync - map.data);
282     else
283       *skipsize = map.size;
284
285     gst_buffer_unmap (frame->buffer, &map);
286
287     /* we could optimise things here by looping over the data and checking
288      * whether the sync is good or not instead of handing control back to
289      * the base class just to be called again */
290     return GST_FLOW_OK;
291   }
292 need_more_data:
293   {
294     GST_LOG_OBJECT (parse,
295         "need %" G_GSIZE_FORMAT " bytes, but only have %" G_GSIZE_FORMAT,
296         frame_len, map.size);
297     gst_base_parse_set_min_frame_size (parse, frame_len);
298     gst_buffer_unmap (frame->buffer, &map);
299     return GST_FLOW_OK;
300   }
301 }
302
303 static void
304 remove_fields (GstCaps * caps)
305 {
306   guint i, n;
307
308   n = gst_caps_get_size (caps);
309   for (i = 0; i < n; i++) {
310     GstStructure *s = gst_caps_get_structure (caps, i);
311
312     gst_structure_remove_field (s, "parsed");
313   }
314 }
315
316 static GstCaps *
317 gst_sbc_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
318 {
319   GstCaps *peercaps, *templ;
320   GstCaps *res;
321
322   templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
323   if (filter) {
324     GstCaps *fcopy = gst_caps_copy (filter);
325     /* Remove the fields we convert */
326     remove_fields (fcopy);
327     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
328     gst_caps_unref (fcopy);
329   } else
330     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
331
332   if (peercaps) {
333     /* Remove the parsed field */
334     peercaps = gst_caps_make_writable (peercaps);
335     remove_fields (peercaps);
336
337     res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
338     gst_caps_unref (peercaps);
339   } else {
340     res = templ;
341   }
342
343   if (filter) {
344     GstCaps *intersection;
345
346     intersection =
347         gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
348     gst_caps_unref (res);
349     res = intersection;
350   }
351
352   return res;
353 }
354
355 static const guint8 crc_table[256] = {
356   0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53,
357   0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB,
358   0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E,
359   0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
360   0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4,
361   0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C,
362   0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19,
363   0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
364   0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40,
365   0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
366   0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D,
367   0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
368   0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7,
369   0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F,
370   0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A,
371   0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2,
372   0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75,
373   0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
374   0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8,
375   0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50,
376   0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2,
377   0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A,
378   0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F,
379   0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7,
380   0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66,
381   0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E,
382   0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB,
383   0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
384   0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1,
385   0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
386   0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C,
387   0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4
388 };
389
390 static guint8
391 gst_sbc_calculate_crc8 (const guint8 * data, gint crc_bits)
392 {
393   guint8 crc = 0x0f;
394   guint8 octet;
395
396   while (crc_bits >= 8) {
397     crc = crc_table[crc ^ *data];
398     crc_bits -= 8;
399     ++data;
400   }
401
402   octet = *data;
403   while (crc_bits > 0) {
404     gchar bit = ((octet ^ crc) & 0x80) >> 7;
405
406     crc = ((crc & 0x7f) << 1) ^ (bit ? 0x1d : 0);
407
408     octet = octet << 1;
409     --crc_bits;
410   }
411
412   return crc;
413 }
414
415 static gsize
416 gst_sbc_calc_framelen (guint subbands, GstSbcChannelMode ch_mode,
417     guint blocks, guint bitpool)
418 {
419   switch (ch_mode) {
420     case GST_SBC_CHANNEL_MODE_MONO:
421       return 4 + (subbands * 1) / 2 + (blocks * 1 * bitpool) / 8;
422     case GST_SBC_CHANNEL_MODE_DUAL:
423       return 4 + (subbands * 2) / 2 + (blocks * 2 * bitpool) / 8;
424     case GST_SBC_CHANNEL_MODE_STEREO:
425       return 4 + (subbands * 2) / 2 + (blocks * bitpool) / 8;
426     case GST_SBC_CHANNEL_MODE_JOINT_STEREO:
427       return 4 + (subbands * 2) / 2 + (subbands + blocks * bitpool) / 8;
428     default:
429       break;
430   }
431
432   g_return_val_if_reached (0);
433 }
434
435 static gsize
436 gst_sbc_parse_header (const guint8 * data, guint * rate, guint * n_blocks,
437     GstSbcChannelMode * ch_mode, GstSbcAllocationMethod * alloc_method,
438     guint * n_subbands, guint * bitpool)
439 {
440   static const guint16 sbc_rates[4] = { 16000, 32000, 44100, 48000 };
441   static const guint8 sbc_blocks[4] = { 4, 8, 12, 16 };
442   guint8 crc_data[2 + 1 + 8], crc_bits, i;
443
444   GST_MEMDUMP ("header", data, 8);
445
446   if (data[0] != SBC_SYNCBYTE)
447     return 0;
448
449   *rate = sbc_rates[(data[1] >> 6) & 0x03];
450   *n_blocks = sbc_blocks[(data[1] >> 4) & 0x03];
451   *ch_mode = (GstSbcChannelMode) ((data[1] >> 2) & 0x03);
452   *alloc_method = (data[1] >> 1) & 0x01;
453   *n_subbands = (data[1] & 0x01) ? 8 : 4;
454   *bitpool = data[2];
455
456   GST_TRACE ("rate=%u, n_blocks=%u, ch_mode=%u, alloc_method=%u, "
457       "n_subbands=%u, bitpool=%u", *rate, *n_blocks, *ch_mode, *alloc_method,
458       *n_subbands, *bitpool);
459
460   if (*bitpool < 2)
461     return 0;
462
463   /* check CRC */
464   crc_data[0] = data[1];
465   crc_data[1] = data[2];
466   crc_bits = 16;
467
468   /* joint flags and RFA */
469   if (*ch_mode == GST_SBC_CHANNEL_MODE_JOINT_STEREO)
470     crc_bits += *n_subbands;
471
472   /* scale factors */
473   if (*ch_mode == GST_SBC_CHANNEL_MODE_MONO)
474     crc_bits += *n_subbands * 1 * 4;
475   else
476     crc_bits += *n_subbands * 2 * 4;
477
478   for (i = 16; i < crc_bits; i += 8) {
479     crc_data[i / 8] = data[1 + (i / 8) + 1];
480   }
481
482   if (i > crc_bits) {
483     crc_data[(i / 8) - 1] &= 0xF0;
484   }
485
486   GST_MEMDUMP ("crc bytes", crc_data, GST_ROUND_UP_8 (crc_bits) / 8);
487   if (gst_sbc_calculate_crc8 (crc_data, crc_bits) != data[3]) {
488     GST_LOG ("header CRC check failed, bits=%u, got 0x%02x, expected 0x%02x",
489         crc_bits, gst_sbc_calculate_crc8 (crc_data, crc_bits), data[3]);
490     return 0;
491   }
492
493   return gst_sbc_calc_framelen (*n_subbands, *ch_mode, *n_blocks, *bitpool);
494 }