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