• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) 2009 Pioneers of the Inevitable <songbird@songbirdnest.com>
3  *
4  * Authors: Michael Smith <msmith@songbirdnest.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 /* Based on ADPCM decoders in libsndfile,
23    Copyright (C) 1999-2002 Erik de Castro Lopo <erikd@zip.com.au
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #include <gst/gst.h>
31 #include <gst/audio/gstaudiodecoder.h>
32 
33 #define GST_TYPE_ADPCM_DEC \
34     (adpcmdec_get_type ())
35 
36 #define GST_ADPCM_DEC(obj) \
37     (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_ADPCM_DEC, ADPCMDec))
38 
39 #define GST_CAT_DEFAULT adpcmdec_debug
40 GST_DEBUG_CATEGORY_STATIC (adpcmdec_debug);
41 
42 static GstStaticPadTemplate adpcmdec_sink_template =
43     GST_STATIC_PAD_TEMPLATE ("sink",
44     GST_PAD_SINK,
45     GST_PAD_ALWAYS,
46     GST_STATIC_CAPS ("audio/x-adpcm, "
47         " layout=(string){microsoft, dvi}, "
48         " block_align = (int) [64, 8192], "
49         " rate = (int)[ 1, MAX ], " "channels = (int)[1,2];")
50     );
51 
52 static GstStaticPadTemplate adpcmdec_src_template =
53 GST_STATIC_PAD_TEMPLATE ("src",
54     GST_PAD_SRC,
55     GST_PAD_ALWAYS,
56     GST_STATIC_CAPS ("audio/x-raw, "
57         "format = (string) " GST_AUDIO_NE (S16) ", "
58         "layout = (string) interleaved, "
59         "rate = (int) [1, MAX], channels = (int) [1,2]")
60     );
61 
62 enum adpcm_layout
63 {
64   LAYOUT_ADPCM_MICROSOFT,
65   LAYOUT_ADPCM_DVI
66 };
67 
68 typedef struct _ADPCMDecClass
69 {
70   GstAudioDecoderClass parent_class;
71 } ADPCMDecClass;
72 
73 typedef struct _ADPCMDec
74 {
75   GstAudioDecoder parent;
76 
77   enum adpcm_layout layout;
78   int rate;
79   int channels;
80   int blocksize;
81 } ADPCMDec;
82 
83 GType adpcmdec_get_type (void);
84 GST_ELEMENT_REGISTER_DECLARE (adpcmdec);
85 G_DEFINE_TYPE_WITH_CODE (ADPCMDec, adpcmdec, GST_TYPE_AUDIO_DECODER,
86     GST_DEBUG_CATEGORY_INIT (adpcmdec_debug, "adpcmdec", 0, "ADPCM Decoders");
87     );
88 GST_ELEMENT_REGISTER_DEFINE (adpcmdec, "adpcmdec", GST_RANK_PRIMARY,
89     GST_TYPE_ADPCM_DEC);
90 
91 static gboolean
adpcmdec_set_format(GstAudioDecoder * bdec,GstCaps * in_caps)92 adpcmdec_set_format (GstAudioDecoder * bdec, GstCaps * in_caps)
93 {
94   ADPCMDec *dec = (ADPCMDec *) (bdec);
95   GstStructure *structure = gst_caps_get_structure (in_caps, 0);
96   const gchar *layout;
97   GstAudioInfo info;
98 
99   layout = gst_structure_get_string (structure, "layout");
100   if (!layout)
101     return FALSE;
102 
103   if (g_str_equal (layout, "microsoft"))
104     dec->layout = LAYOUT_ADPCM_MICROSOFT;
105   else if (g_str_equal (layout, "dvi"))
106     dec->layout = LAYOUT_ADPCM_DVI;
107   else
108     return FALSE;
109 
110   if (!gst_structure_get_int (structure, "block_align", &dec->blocksize))
111     dec->blocksize = -1;        /* Not provided */
112 
113   if (!gst_structure_get_int (structure, "rate", &dec->rate))
114     return FALSE;
115   if (!gst_structure_get_int (structure, "channels", &dec->channels))
116     return FALSE;
117 
118   gst_audio_info_init (&info);
119   gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S16, dec->rate,
120       dec->channels, NULL);
121 
122   gst_audio_decoder_set_output_format (bdec, &info);
123   return TRUE;
124 }
125 
126 
127 /*=====================================================================
128  * From libsndfile:
129  *
130  *  MS ADPCM Block Layout.
131  *  ======================
132  *  Block is usually 256, 512 or 1024 bytes depending on sample rate.
133  *  For a mono file, the block is laid out as follows:
134  *      byte    purpose
135  *      0       block predictor [0..6]
136  *      1,2     initial idelta (positive)
137  *      3,4     sample 1
138  *      5,6     sample 0
139  *      7..n    packed bytecodes
140  *
141  *  For a stereo file, the block is laid out as follows:
142  *      byte    purpose
143  *      0       block predictor [0..6] for left channel
144  *      1       block predictor [0..6] for right channel
145  *      2,3     initial idelta (positive) for left channel
146  *      4,5     initial idelta (positive) for right channel
147  *      6,7     sample 1 for left channel
148  *      8,9     sample 1 for right channel
149  *      10,11   sample 0 for left channel
150  *      12,13   sample 0 for right channel
151  *      14..n   packed bytecodes
152  *
153  *=====================================================================
154 */
155 static const int AdaptationTable[] = {
156   230, 230, 230, 230, 307, 409, 512, 614,
157   768, 614, 512, 409, 307, 230, 230, 230
158 };
159 
160 static const int AdaptCoeff1[] = {
161   256, 512, 0, 192, 240, 460, 392
162 };
163 
164 static const int AdaptCoeff2[] = {
165   0, -256, 0, 64, 0, -208, -232
166 };
167 
168 static gint16
read_sample(const guint8 * data)169 read_sample (const guint8 * data)
170 {
171   guint16 val = data[0] | (data[1] << 8);
172   return *((gint16 *) & val);
173 }
174 
175 /* Decode a single block of data from 'data', storing 'n_samples' decoded 16 bit
176    samples in 'samples'.
177 
178    All buffer lengths have been verified by the caller
179  */
180 static gboolean
adpcmdec_decode_ms_block(ADPCMDec * dec,int n_samples,const guint8 * data,gint16 * samples)181 adpcmdec_decode_ms_block (ADPCMDec * dec, int n_samples, const guint8 * data,
182     gint16 * samples)
183 {
184   gint16 pred[2];
185   gint16 idelta[2];
186   int idx;                      /* Current byte offset in 'data' */
187   int i;                        /* Current sample index in 'samples' */
188 
189   /* Read the block header, verify for sanity */
190   if (dec->channels == 1) {
191     pred[0] = data[0];
192     idelta[0] = read_sample (data + 1);
193     samples[1] = read_sample (data + 3);
194     samples[0] = read_sample (data + 5);
195     idx = 7;
196     i = 2;
197     if (pred[0] < 0 || pred[0] > 6) {
198       GST_WARNING_OBJECT (dec, "Invalid block predictor");
199       return FALSE;
200     }
201   }
202 
203   else {
204     pred[0] = data[0];
205     pred[1] = data[1];
206     idelta[0] = read_sample (data + 2);
207     idelta[1] = read_sample (data + 4);
208     samples[2] = read_sample (data + 6);
209     samples[3] = read_sample (data + 8);
210     samples[0] = read_sample (data + 10);
211     samples[1] = read_sample (data + 12);
212     idx = 14;
213     i = 4;
214     if (pred[0] < 0 || pred[0] > 6 || pred[1] < 0 || pred[1] > 6) {
215       GST_WARNING_OBJECT (dec, "Invalid block predictor");
216       return FALSE;
217     }
218   }
219   for (; i < n_samples; i++) {
220     int chan = i % dec->channels;
221     int bytecode;
222     int delta;
223     int current;
224     int predict;
225     if (i % 2 == 0) {
226       bytecode = (data[idx] >> 4) & 0x0F;
227     } else {
228       bytecode = data[idx] & 0x0F;
229       idx++;
230     }
231 
232     delta = idelta[chan];
233     idelta[chan] = (AdaptationTable[bytecode] * delta) >> 8;
234     if (idelta[chan] < 16)
235       idelta[chan] = 16;
236 
237     /* Bytecode is used above as an index into the table. Below, it's used
238        as a signed 4-bit value; convert appropriately */
239     if (bytecode & 0x8)
240       bytecode -= 0x10;
241 
242     predict = ((samples[i - dec->channels] * AdaptCoeff1[pred[chan]]) +
243         (samples[i - 2 * dec->channels] * AdaptCoeff2[pred[chan]])
244         ) >> 8;
245 
246     current = (bytecode * delta) + predict;
247 
248     /* Clamp to 16 bits, store decoded sample */
249     samples[i] = CLAMP (current, G_MININT16, G_MAXINT16);
250   }
251   return TRUE;
252 }
253 
254 static const int ima_indx_adjust[16] = {
255   -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8,
256 };
257 
258 static const int ima_step_size[89] = {
259   7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
260   50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230,
261   253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
262   1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
263   3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
264   11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
265   32767
266 };
267 
268 /* Decode a single block of data from 'data', storing 'n_samples' decoded 16 bit
269    samples in 'samples'.
270 
271    All buffer lengths have been verified by the caller
272  */
273 static gboolean
adpcmdec_decode_ima_block(ADPCMDec * dec,int n_samples,const guint8 * data,gint16 * samples)274 adpcmdec_decode_ima_block (ADPCMDec * dec, int n_samples, const guint8 * data,
275     gint16 * samples)
276 {
277   gint16 stepindex[2];
278   int channel;
279   int idx;
280   int i, j;
281   int sample;
282 
283   if ((n_samples - dec->channels) % 8 != 0) {
284     GST_WARNING_OBJECT (dec, "Input not correct size");
285     return FALSE;
286   }
287 
288   for (channel = 0; channel < dec->channels; channel++) {
289     samples[channel] = read_sample (data + channel * 4);
290     stepindex[channel] = MIN (data[channel * 4 + 2], 88);
291 
292     if (data[channel * 4 + 3] != 0) {
293       GST_WARNING_OBJECT (dec, "Synchronisation error");
294       return FALSE;
295     }
296   }
297 
298   i = dec->channels;
299   idx = 4 * dec->channels;
300 
301   while (i < n_samples) {
302     for (channel = 0; channel < dec->channels; channel++) {
303       sample = i + channel;
304       for (j = 0; j < 8; j++) {
305         int bytecode;
306         int step;
307         int diff;
308 
309         if (j % 2 == 0) {
310           bytecode = data[idx] & 0x0F;
311         } else {
312           bytecode = (data[idx] >> 4) & 0x0F;
313           idx++;
314         }
315         step = ima_step_size[stepindex[channel]];
316         diff = (2 * (bytecode & 0x7) * step + step) / 8;
317         if (bytecode & 8)
318           diff = -diff;
319 
320         samples[sample] =
321             CLAMP (samples[sample - dec->channels] + diff, G_MININT16,
322             G_MAXINT16);
323         stepindex[channel] =
324             CLAMP (stepindex[channel] + ima_indx_adjust[bytecode], 0, 88);
325         sample += dec->channels;
326       }
327     }
328     i += 8 * dec->channels;
329   }
330   return TRUE;
331 }
332 
333 static GstBuffer *
adpcmdec_decode_block(ADPCMDec * dec,const guint8 * data,int blocksize)334 adpcmdec_decode_block (ADPCMDec * dec, const guint8 * data, int blocksize)
335 {
336   gboolean res = FALSE;
337   GstBuffer *outbuf = NULL;
338   int outsize;
339   int samples;
340   GstMapInfo omap;
341 
342   if (dec->layout == LAYOUT_ADPCM_MICROSOFT) {
343     /* Each block has a 3 byte header per channel, plus 4 bytes per channel to
344        give two initial sample values per channel. Then the remainder gives
345        two samples per byte */
346     if (blocksize < 7 * dec->channels)
347       goto exit;
348     samples = (blocksize - 7 * dec->channels) * 2 + 2 * dec->channels;
349     outsize = 2 * samples;
350     outbuf = gst_buffer_new_and_alloc (outsize);
351 
352     gst_buffer_map (outbuf, &omap, GST_MAP_WRITE);
353     res = adpcmdec_decode_ms_block (dec, samples, data, (gint16 *) omap.data);
354     gst_buffer_unmap (outbuf, &omap);
355   } else if (dec->layout == LAYOUT_ADPCM_DVI) {
356     /* Each block has a 4 byte header per channel, include an initial sample.
357        Then the remainder gives two samples per byte */
358     if (blocksize < 4 * dec->channels)
359       goto exit;
360     samples = (blocksize - 4 * dec->channels) * 2 + dec->channels;
361     outsize = 2 * samples;
362     outbuf = gst_buffer_new_and_alloc (outsize);
363 
364     gst_buffer_map (outbuf, &omap, GST_MAP_WRITE);
365     res = adpcmdec_decode_ima_block (dec, samples, data, (gint16 *) omap.data);
366     gst_buffer_unmap (outbuf, &omap);
367   } else {
368     GST_WARNING_OBJECT (dec, "Unknown layout");
369   }
370 
371   if (!res) {
372     if (outbuf)
373       gst_buffer_unref (outbuf);
374     outbuf = NULL;
375     GST_WARNING_OBJECT (dec, "Decode of block failed");
376   }
377 
378 exit:
379   return outbuf;
380 }
381 
382 static GstFlowReturn
adpcmdec_parse(GstAudioDecoder * bdec,GstAdapter * adapter,gint * offset,gint * length)383 adpcmdec_parse (GstAudioDecoder * bdec, GstAdapter * adapter,
384     gint * offset, gint * length)
385 {
386   ADPCMDec *dec = (ADPCMDec *) (bdec);
387   guint size;
388 
389   size = gst_adapter_available (adapter);
390   g_return_val_if_fail (size > 0, GST_FLOW_ERROR);
391 
392   if (dec->blocksize < 0) {
393     /* No explicit blocksize; we just process one input buffer at a time */
394     *offset = 0;
395     *length = size;
396   } else {
397     if (size >= dec->blocksize) {
398       *offset = 0;
399       *length = dec->blocksize;
400     } else {
401       return GST_FLOW_EOS;
402     }
403   }
404 
405   return GST_FLOW_OK;
406 }
407 
408 static GstFlowReturn
adpcmdec_handle_frame(GstAudioDecoder * bdec,GstBuffer * buffer)409 adpcmdec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buffer)
410 {
411   ADPCMDec *dec = (ADPCMDec *) (bdec);
412   GstFlowReturn ret = GST_FLOW_OK;
413   GstMapInfo map;
414   GstBuffer *outbuf = NULL;
415 
416   /* no fancy draining */
417   if (G_UNLIKELY (!buffer))
418     return GST_FLOW_OK;
419 
420   if (!dec->blocksize)
421     return GST_FLOW_NOT_NEGOTIATED;
422 
423   gst_buffer_map (buffer, &map, GST_MAP_READ);
424   outbuf = adpcmdec_decode_block (dec, map.data, dec->blocksize);
425   gst_buffer_unmap (buffer, &map);
426 
427   if (outbuf == NULL) {
428     GST_AUDIO_DECODER_ERROR (bdec, 1, STREAM, DECODE, (NULL),
429         ("frame decode failed"), ret);
430   }
431 
432   if (ret == GST_FLOW_OK)
433     ret = gst_audio_decoder_finish_frame (bdec, outbuf, 1);
434 
435   return ret;
436 }
437 
438 static gboolean
adpcmdec_start(GstAudioDecoder * bdec)439 adpcmdec_start (GstAudioDecoder * bdec)
440 {
441   ADPCMDec *dec = (ADPCMDec *) bdec;
442 
443   GST_DEBUG_OBJECT (dec, "start");
444 
445   dec->blocksize = 0;
446   dec->rate = 0;
447   dec->channels = 0;
448 
449   return TRUE;
450 }
451 
452 static gboolean
adpcmdec_stop(GstAudioDecoder * dec)453 adpcmdec_stop (GstAudioDecoder * dec)
454 {
455   GST_DEBUG_OBJECT (dec, "stop");
456 
457   return TRUE;
458 }
459 
460 static void
adpcmdec_init(ADPCMDec * dec)461 adpcmdec_init (ADPCMDec * dec)
462 {
463   gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (dec), TRUE);
464   gst_audio_decoder_set_use_default_pad_acceptcaps (GST_AUDIO_DECODER_CAST
465       (dec), TRUE);
466   GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (dec));
467 }
468 
469 static void
adpcmdec_class_init(ADPCMDecClass * klass)470 adpcmdec_class_init (ADPCMDecClass * klass)
471 {
472   GstElementClass *element_class = (GstElementClass *) klass;
473   GstAudioDecoderClass *base_class = (GstAudioDecoderClass *) klass;
474 
475   gst_element_class_add_static_pad_template (element_class,
476       &adpcmdec_sink_template);
477   gst_element_class_add_static_pad_template (element_class,
478       &adpcmdec_src_template);
479   gst_element_class_set_static_metadata (element_class, "ADPCM decoder",
480       "Codec/Decoder/Audio", "Decode MS and IMA ADPCM audio",
481       "Pioneers of the Inevitable <songbird@songbirdnest.com>");
482 
483   base_class->start = GST_DEBUG_FUNCPTR (adpcmdec_start);
484   base_class->stop = GST_DEBUG_FUNCPTR (adpcmdec_stop);
485   base_class->set_format = GST_DEBUG_FUNCPTR (adpcmdec_set_format);
486   base_class->parse = GST_DEBUG_FUNCPTR (adpcmdec_parse);
487   base_class->handle_frame = GST_DEBUG_FUNCPTR (adpcmdec_handle_frame);
488 }
489 
490 static gboolean
plugin_init(GstPlugin * plugin)491 plugin_init (GstPlugin * plugin)
492 {
493   return GST_ELEMENT_REGISTER (adpcmdec, plugin);
494 }
495 
496 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, adpcmdec,
497     "ADPCM decoder", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
498     GST_PACKAGE_ORIGIN);
499