~ubuntu-branches/ubuntu/quantal/gst-plugins-bad0.10/quantal-proposed

« back to all changes in this revision

Viewing changes to gst/audioparsers/gstaacparse.c

  • Committer: Bazaar Package Importer
  • Author(s): Ken VanDine
  • Date: 2011-07-19 14:32:43 UTC
  • mfrom: (18.4.21 sid)
  • Revision ID: james.westby@ubuntu.com-20110719143243-p7pnkh45akfp0ihk
Tags: 0.10.22-2ubuntu1
* Rebased on debian unstable, remaining changes:
  - debian/gstreamer-plugins-bad.install
    * don't include dtmf, liveadder, rtpmux, autoconvert and shm, we include 
      them in -good

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* GStreamer AAC parser plugin
2
 
 * Copyright (C) 2008 Nokia Corporation. All rights reserved.
3
 
 *
4
 
 * Contact: Stefan Kost <stefan.kost@nokia.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., 59 Temple Place - Suite 330,
19
 
 * Boston, MA 02111-1307, USA.
20
 
 */
21
 
 
22
 
/**
23
 
 * SECTION:element-aacparse
24
 
 * @short_description: AAC parser
25
 
 * @see_also: #GstAmrParse
26
 
 *
27
 
 * This is an AAC parser which handles both ADIF and ADTS stream formats.
28
 
 *
29
 
 * As ADIF format is not framed, it is not seekable and stream duration cannot
30
 
 * be determined either. However, ADTS format AAC clips can be seeked, and parser
31
 
 * can also estimate playback position and clip duration.
32
 
 *
33
 
 * <refsect2>
34
 
 * <title>Example launch line</title>
35
 
 * |[
36
 
 * gst-launch filesrc location=abc.aac ! aacparse ! faad ! audioresample ! audioconvert ! alsasink
37
 
 * ]|
38
 
 * </refsect2>
39
 
 */
40
 
 
41
 
#ifdef HAVE_CONFIG_H
42
 
#include "config.h"
43
 
#endif
44
 
 
45
 
#include <string.h>
46
 
 
47
 
#include "gstaacparse.h"
48
 
 
49
 
 
50
 
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
51
 
    GST_PAD_SRC,
52
 
    GST_PAD_ALWAYS,
53
 
    GST_STATIC_CAPS ("audio/mpeg, "
54
 
        "framed = (boolean) true, " "mpegversion = (int) { 2, 4 }, "
55
 
        "stream-format = (string) { raw, adts, adif };"));
56
 
 
57
 
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
58
 
    GST_PAD_SINK,
59
 
    GST_PAD_ALWAYS,
60
 
    GST_STATIC_CAPS ("audio/mpeg, "
61
 
        "framed = (boolean) false, " "mpegversion = (int) { 2, 4 };"));
62
 
 
63
 
GST_DEBUG_CATEGORY_STATIC (gst_aacparse_debug);
64
 
#define GST_CAT_DEFAULT gst_aacparse_debug
65
 
 
66
 
 
67
 
#define ADIF_MAX_SIZE 40        /* Should be enough */
68
 
#define ADTS_MAX_SIZE 10        /* Should be enough */
69
 
 
70
 
 
71
 
#define AAC_FRAME_DURATION(parse) (GST_SECOND/parse->frames_per_sec)
72
 
 
73
 
gboolean gst_aacparse_start (GstBaseParse * parse);
74
 
gboolean gst_aacparse_stop (GstBaseParse * parse);
75
 
 
76
 
static gboolean gst_aacparse_sink_setcaps (GstBaseParse * parse,
77
 
    GstCaps * caps);
78
 
 
79
 
gboolean gst_aacparse_check_valid_frame (GstBaseParse * parse,
80
 
    GstBuffer * buffer, guint * size, gint * skipsize);
81
 
 
82
 
GstFlowReturn gst_aacparse_parse_frame (GstBaseParse * parse,
83
 
    GstBuffer * buffer);
84
 
 
85
 
gboolean gst_aacparse_convert (GstBaseParse * parse,
86
 
    GstFormat src_format,
87
 
    gint64 src_value, GstFormat dest_format, gint64 * dest_value);
88
 
 
89
 
gint gst_aacparse_get_frame_overhead (GstBaseParse * parse, GstBuffer * buffer);
90
 
 
91
 
gboolean gst_aacparse_event (GstBaseParse * parse, GstEvent * event);
92
 
 
93
 
#define _do_init(bla) \
94
 
    GST_DEBUG_CATEGORY_INIT (gst_aacparse_debug, "aacparse", 0, \
95
 
    "AAC audio stream parser");
96
 
 
97
 
GST_BOILERPLATE_FULL (GstAacParse, gst_aacparse, GstBaseParse,
98
 
    GST_TYPE_BASE_PARSE, _do_init);
99
 
 
100
 
static inline gint
101
 
gst_aacparse_get_sample_rate_from_index (guint sr_idx)
102
 
{
103
 
  static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
104
 
    32000, 24000, 22050, 16000, 12000, 11025, 8000
105
 
  };
106
 
 
107
 
  if (sr_idx < G_N_ELEMENTS (aac_sample_rates))
108
 
    return aac_sample_rates[sr_idx];
109
 
  GST_WARNING ("Invalid sample rate index %u", sr_idx);
110
 
  return 0;
111
 
}
112
 
 
113
 
/**
114
 
 * gst_aacparse_base_init:
115
 
 * @klass: #GstElementClass.
116
 
 *
117
 
 */
118
 
static void
119
 
gst_aacparse_base_init (gpointer klass)
120
 
{
121
 
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
122
 
 
123
 
  gst_element_class_add_pad_template (element_class,
124
 
      gst_static_pad_template_get (&sink_template));
125
 
  gst_element_class_add_pad_template (element_class,
126
 
      gst_static_pad_template_get (&src_template));
127
 
 
128
 
  gst_element_class_set_details_simple (element_class,
129
 
      "AAC audio stream parser", "Codec/Parser/Audio",
130
 
      "Advanced Audio Coding parser", "Stefan Kost <stefan.kost@nokia.com>");
131
 
}
132
 
 
133
 
 
134
 
/**
135
 
 * gst_aacparse_class_init:
136
 
 * @klass: #GstAacParseClass.
137
 
 *
138
 
 */
139
 
static void
140
 
gst_aacparse_class_init (GstAacParseClass * klass)
141
 
{
142
 
  GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
143
 
 
144
 
  parse_class->start = GST_DEBUG_FUNCPTR (gst_aacparse_start);
145
 
  parse_class->stop = GST_DEBUG_FUNCPTR (gst_aacparse_stop);
146
 
  parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_aacparse_sink_setcaps);
147
 
  parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_aacparse_parse_frame);
148
 
  parse_class->check_valid_frame =
149
 
      GST_DEBUG_FUNCPTR (gst_aacparse_check_valid_frame);
150
 
  parse_class->get_frame_overhead =
151
 
      GST_DEBUG_FUNCPTR (gst_aacparse_get_frame_overhead);
152
 
}
153
 
 
154
 
 
155
 
/**
156
 
 * gst_aacparse_init:
157
 
 * @aacparse: #GstAacParse.
158
 
 * @klass: #GstAacParseClass.
159
 
 *
160
 
 */
161
 
static void
162
 
gst_aacparse_init (GstAacParse * aacparse, GstAacParseClass * klass)
163
 
{
164
 
  GST_DEBUG ("initialized");
165
 
}
166
 
 
167
 
 
168
 
/**
169
 
 * gst_aacparse_set_src_caps:
170
 
 * @aacparse: #GstAacParse.
171
 
 * @sink_caps: (proposed) caps of sink pad
172
 
 *
173
 
 * Set source pad caps according to current knowledge about the
174
 
 * audio stream.
175
 
 *
176
 
 * Returns: TRUE if caps were successfully set.
177
 
 */
178
 
static gboolean
179
 
gst_aacparse_set_src_caps (GstAacParse * aacparse, GstCaps * sink_caps)
180
 
{
181
 
  GstStructure *s;
182
 
  GstCaps *src_caps = NULL;
183
 
  gboolean res = FALSE;
184
 
  const gchar *stream_format;
185
 
 
186
 
  GST_DEBUG_OBJECT (aacparse, "sink caps: %" GST_PTR_FORMAT, sink_caps);
187
 
  if (sink_caps)
188
 
    src_caps = gst_caps_copy (sink_caps);
189
 
  else
190
 
    src_caps = gst_caps_new_simple ("audio/mpeg", NULL);
191
 
 
192
 
  gst_caps_set_simple (src_caps, "framed", G_TYPE_BOOLEAN, TRUE,
193
 
      "mpegversion", G_TYPE_INT, aacparse->mpegversion, NULL);
194
 
 
195
 
  switch (aacparse->header_type) {
196
 
    case DSPAAC_HEADER_NONE:
197
 
      stream_format = "raw";
198
 
      break;
199
 
    case DSPAAC_HEADER_ADTS:
200
 
      stream_format = "adts";
201
 
      break;
202
 
    case DSPAAC_HEADER_ADIF:
203
 
      stream_format = "adif";
204
 
      break;
205
 
    default:
206
 
      stream_format = NULL;
207
 
  }
208
 
 
209
 
  s = gst_caps_get_structure (src_caps, 0);
210
 
  if (aacparse->sample_rate > 0)
211
 
    gst_structure_set (s, "rate", G_TYPE_INT, aacparse->sample_rate, NULL);
212
 
  if (aacparse->channels > 0)
213
 
    gst_structure_set (s, "channels", G_TYPE_INT, aacparse->channels, NULL);
214
 
  if (stream_format)
215
 
    gst_structure_set (s, "stream-format", G_TYPE_STRING, stream_format, NULL);
216
 
 
217
 
  GST_DEBUG_OBJECT (aacparse, "setting src caps: %" GST_PTR_FORMAT, src_caps);
218
 
 
219
 
  res = gst_pad_set_caps (GST_BASE_PARSE (aacparse)->srcpad, src_caps);
220
 
  gst_caps_unref (src_caps);
221
 
  return res;
222
 
}
223
 
 
224
 
 
225
 
/**
226
 
 * gst_aacparse_sink_setcaps:
227
 
 * @sinkpad: GstPad
228
 
 * @caps: GstCaps
229
 
 *
230
 
 * Implementation of "set_sink_caps" vmethod in #GstBaseParse class.
231
 
 *
232
 
 * Returns: TRUE on success.
233
 
 */
234
 
static gboolean
235
 
gst_aacparse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
236
 
{
237
 
  GstAacParse *aacparse;
238
 
  GstStructure *structure;
239
 
  gchar *caps_str;
240
 
  const GValue *value;
241
 
 
242
 
  aacparse = GST_AACPARSE (parse);
243
 
  structure = gst_caps_get_structure (caps, 0);
244
 
  caps_str = gst_caps_to_string (caps);
245
 
 
246
 
  GST_DEBUG_OBJECT (aacparse, "setcaps: %s", caps_str);
247
 
  g_free (caps_str);
248
 
 
249
 
  /* This is needed at least in case of RTP
250
 
   * Parses the codec_data information to get ObjectType,
251
 
   * number of channels and samplerate */
252
 
  value = gst_structure_get_value (structure, "codec_data");
253
 
  if (value) {
254
 
    GstBuffer *buf = gst_value_get_buffer (value);
255
 
 
256
 
    if (buf) {
257
 
      const guint8 *buffer = GST_BUFFER_DATA (buf);
258
 
      guint sr_idx;
259
 
 
260
 
      sr_idx = ((buffer[0] & 0x07) << 1) | ((buffer[1] & 0x80) >> 7);
261
 
      aacparse->object_type = (buffer[0] & 0xf8) >> 3;
262
 
      aacparse->sample_rate = gst_aacparse_get_sample_rate_from_index (sr_idx);
263
 
      aacparse->channels = (buffer[1] & 0x78) >> 3;
264
 
      aacparse->header_type = DSPAAC_HEADER_NONE;
265
 
      aacparse->mpegversion = 4;
266
 
 
267
 
      GST_DEBUG ("codec_data: object_type=%d, sample_rate=%d, channels=%d",
268
 
          aacparse->object_type, aacparse->sample_rate, aacparse->channels);
269
 
 
270
 
      /* arrange for metadata and get out of the way */
271
 
      gst_aacparse_set_src_caps (aacparse, caps);
272
 
      gst_base_parse_set_passthrough (parse, TRUE);
273
 
    } else
274
 
      return FALSE;
275
 
 
276
 
    /* caps info overrides */
277
 
    gst_structure_get_int (structure, "rate", &aacparse->sample_rate);
278
 
    gst_structure_get_int (structure, "channels", &aacparse->channels);
279
 
  }
280
 
 
281
 
  return TRUE;
282
 
}
283
 
 
284
 
 
285
 
/**
286
 
 * gst_aacparse_adts_get_frame_len:
287
 
 * @data: block of data containing an ADTS header.
288
 
 *
289
 
 * This function calculates ADTS frame length from the given header.
290
 
 *
291
 
 * Returns: size of the ADTS frame.
292
 
 */
293
 
static inline guint
294
 
gst_aacparse_adts_get_frame_len (const guint8 * data)
295
 
{
296
 
  return ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
297
 
}
298
 
 
299
 
 
300
 
/**
301
 
 * gst_aacparse_check_adts_frame:
302
 
 * @aacparse: #GstAacParse.
303
 
 * @data: Data to be checked.
304
 
 * @avail: Amount of data passed.
305
 
 * @framesize: If valid ADTS frame was found, this will be set to tell the
306
 
 *             found frame size in bytes.
307
 
 * @needed_data: If frame was not found, this may be set to tell how much
308
 
 *               more data is needed in the next round to detect the frame
309
 
 *               reliably. This may happen when a frame header candidate
310
 
 *               is found but it cannot be guaranteed to be the header without
311
 
 *               peeking the following data.
312
 
 *
313
 
 * Check if the given data contains contains ADTS frame. The algorithm
314
 
 * will examine ADTS frame header and calculate the frame size. Also, another
315
 
 * consecutive ADTS frame header need to be present after the found frame.
316
 
 * Otherwise the data is not considered as a valid ADTS frame. However, this
317
 
 * "extra check" is omitted when EOS has been received. In this case it is
318
 
 * enough when data[0] contains a valid ADTS header.
319
 
 *
320
 
 * This function may set the #needed_data to indicate that a possible frame
321
 
 * candidate has been found, but more data (#needed_data bytes) is needed to
322
 
 * be absolutely sure. When this situation occurs, FALSE will be returned.
323
 
 *
324
 
 * When a valid frame is detected, this function will use
325
 
 * gst_base_parse_set_min_frame_size() function from #GstBaseParse class
326
 
 * to set the needed bytes for next frame.This way next data chunk is already
327
 
 * of correct size.
328
 
 *
329
 
 * Returns: TRUE if the given data contains a valid ADTS header.
330
 
 */
331
 
static gboolean
332
 
gst_aacparse_check_adts_frame (GstAacParse * aacparse,
333
 
    const guint8 * data,
334
 
    const guint avail, guint * framesize, guint * needed_data)
335
 
{
336
 
  if (G_UNLIKELY (avail < 2))
337
 
    return FALSE;
338
 
 
339
 
  if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
340
 
    *framesize = gst_aacparse_adts_get_frame_len (data);
341
 
 
342
 
    /* In EOS mode this is enough. No need to examine the data further */
343
 
    if (gst_base_parse_get_drain (GST_BASE_PARSE (aacparse))) {
344
 
      return TRUE;
345
 
    }
346
 
 
347
 
    if (*framesize + ADTS_MAX_SIZE > avail) {
348
 
      /* We have found a possible frame header candidate, but can't be
349
 
         sure since we don't have enough data to check the next frame */
350
 
      GST_DEBUG ("NEED MORE DATA: we need %d, available %d",
351
 
          *framesize + ADTS_MAX_SIZE, avail);
352
 
      *needed_data = *framesize + ADTS_MAX_SIZE;
353
 
      gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
354
 
          *framesize + ADTS_MAX_SIZE);
355
 
      return FALSE;
356
 
    }
357
 
 
358
 
    if ((data[*framesize] == 0xff) && ((data[*framesize + 1] & 0xf6) == 0xf0)) {
359
 
      guint nextlen = gst_aacparse_adts_get_frame_len (data + (*framesize));
360
 
 
361
 
      GST_LOG ("ADTS frame found, len: %d bytes", *framesize);
362
 
      gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
363
 
          nextlen + ADTS_MAX_SIZE);
364
 
      return TRUE;
365
 
    }
366
 
  }
367
 
  return FALSE;
368
 
}
369
 
 
370
 
/* caller ensure sufficient data */
371
 
static inline void
372
 
gst_aacparse_parse_adts_header (GstAacParse * aacparse, const guint8 * data,
373
 
    gint * rate, gint * channels, gint * object, gint * version)
374
 
{
375
 
 
376
 
  if (rate) {
377
 
    gint sr_idx = (data[2] & 0x3c) >> 2;
378
 
 
379
 
    *rate = gst_aacparse_get_sample_rate_from_index (sr_idx);
380
 
  }
381
 
  if (channels)
382
 
    *channels = ((data[2] & 0x01) << 2) | ((data[3] & 0xc0) >> 6);
383
 
 
384
 
  if (version)
385
 
    *version = (data[1] & 0x08) ? 2 : 4;
386
 
  if (object)
387
 
    *object = (data[2] & 0xc0) >> 6;
388
 
}
389
 
 
390
 
/**
391
 
 * gst_aacparse_detect_stream:
392
 
 * @aacparse: #GstAacParse.
393
 
 * @data: A block of data that needs to be examined for stream characteristics.
394
 
 * @avail: Size of the given datablock.
395
 
 * @framesize: If valid stream was found, this will be set to tell the
396
 
 *             first frame size in bytes.
397
 
 * @skipsize: If valid stream was found, this will be set to tell the first
398
 
 *            audio frame position within the given data.
399
 
 *
400
 
 * Examines the given piece of data and try to detect the format of it. It
401
 
 * checks for "ADIF" header (in the beginning of the clip) and ADTS frame
402
 
 * header. If the stream is detected, TRUE will be returned and #framesize
403
 
 * is set to indicate the found frame size. Additionally, #skipsize might
404
 
 * be set to indicate the number of bytes that need to be skipped, a.k.a. the
405
 
 * position of the frame inside given data chunk.
406
 
 *
407
 
 * Returns: TRUE on success.
408
 
 */
409
 
static gboolean
410
 
gst_aacparse_detect_stream (GstAacParse * aacparse,
411
 
    const guint8 * data, const guint avail, guint * framesize, gint * skipsize)
412
 
{
413
 
  gboolean found = FALSE;
414
 
  guint need_data = 0;
415
 
  guint i = 0;
416
 
 
417
 
  GST_DEBUG_OBJECT (aacparse, "Parsing header data");
418
 
 
419
 
  /* FIXME: No need to check for ADIF if we are not in the beginning of the
420
 
     stream */
421
 
 
422
 
  /* Can we even parse the header? */
423
 
  if (avail < ADTS_MAX_SIZE)
424
 
    return FALSE;
425
 
 
426
 
  for (i = 0; i < avail - 4; i++) {
427
 
    if (((data[i] == 0xff) && ((data[i + 1] & 0xf6) == 0xf0)) ||
428
 
        strncmp ((char *) data + i, "ADIF", 4) == 0) {
429
 
      found = TRUE;
430
 
 
431
 
      if (i) {
432
 
        /* Trick: tell the parent class that we didn't find the frame yet,
433
 
           but make it skip 'i' amount of bytes. Next time we arrive
434
 
           here we have full frame in the beginning of the data. */
435
 
        *skipsize = i;
436
 
        return FALSE;
437
 
      }
438
 
      break;
439
 
    }
440
 
  }
441
 
  if (!found) {
442
 
    if (i)
443
 
      *skipsize = i;
444
 
    return FALSE;
445
 
  }
446
 
 
447
 
  if (gst_aacparse_check_adts_frame (aacparse, data, avail,
448
 
          framesize, &need_data)) {
449
 
    gint rate, channels;
450
 
 
451
 
    GST_INFO ("ADTS ID: %d, framesize: %d", (data[1] & 0x08) >> 3, *framesize);
452
 
 
453
 
    aacparse->header_type = DSPAAC_HEADER_ADTS;
454
 
    gst_aacparse_parse_adts_header (aacparse, data, &rate, &channels,
455
 
        &aacparse->object_type, &aacparse->mpegversion);
456
 
 
457
 
    gst_base_parse_set_frame_props (GST_BASE_PARSE (aacparse),
458
 
        rate, 1024, 2, 2);
459
 
 
460
 
    GST_DEBUG ("ADTS: samplerate %d, channels %d, objtype %d, version %d",
461
 
        rate, channels, aacparse->object_type, aacparse->mpegversion);
462
 
 
463
 
    return TRUE;
464
 
  } else if (need_data) {
465
 
    /* This tells the parent class not to skip any data */
466
 
    *skipsize = 0;
467
 
    return FALSE;
468
 
  }
469
 
 
470
 
  if (avail < ADIF_MAX_SIZE)
471
 
    return FALSE;
472
 
 
473
 
  if (memcmp (data + i, "ADIF", 4) == 0) {
474
 
    const guint8 *adif;
475
 
    int skip_size = 0;
476
 
    int bitstream_type;
477
 
    int sr_idx;
478
 
 
479
 
    aacparse->header_type = DSPAAC_HEADER_ADIF;
480
 
    aacparse->mpegversion = 4;
481
 
 
482
 
    /* no way to seek this */
483
 
    gst_base_parse_set_seek (GST_BASE_PARSE (aacparse),
484
 
        GST_BASE_PARSE_SEEK_NONE, 0);
485
 
 
486
 
    /* Skip the "ADIF" bytes */
487
 
    adif = data + i + 4;
488
 
 
489
 
    /* copyright string */
490
 
    if (adif[0] & 0x80)
491
 
      skip_size += 9;           /* skip 9 bytes */
492
 
 
493
 
    bitstream_type = adif[0 + skip_size] & 0x10;
494
 
    aacparse->bitrate =
495
 
        ((unsigned int) (adif[0 + skip_size] & 0x0f) << 19) |
496
 
        ((unsigned int) adif[1 + skip_size] << 11) |
497
 
        ((unsigned int) adif[2 + skip_size] << 3) |
498
 
        ((unsigned int) adif[3 + skip_size] & 0xe0);
499
 
 
500
 
    /* CBR */
501
 
    if (bitstream_type == 0) {
502
 
#if 0
503
 
      /* Buffer fullness parsing. Currently not needed... */
504
 
      guint num_elems = 0;
505
 
      guint fullness = 0;
506
 
 
507
 
      num_elems = (adif[3 + skip_size] & 0x1e);
508
 
      GST_INFO ("ADIF num_config_elems: %d", num_elems);
509
 
 
510
 
      fullness = ((unsigned int) (adif[3 + skip_size] & 0x01) << 19) |
511
 
          ((unsigned int) adif[4 + skip_size] << 11) |
512
 
          ((unsigned int) adif[5 + skip_size] << 3) |
513
 
          ((unsigned int) (adif[6 + skip_size] & 0xe0) >> 5);
514
 
 
515
 
      GST_INFO ("ADIF buffer fullness: %d", fullness);
516
 
#endif
517
 
      aacparse->object_type = ((adif[6 + skip_size] & 0x01) << 1) |
518
 
          ((adif[7 + skip_size] & 0x80) >> 7);
519
 
      sr_idx = (adif[7 + skip_size] & 0x78) >> 3;
520
 
    }
521
 
    /* VBR */
522
 
    else {
523
 
      aacparse->object_type = (adif[4 + skip_size] & 0x18) >> 3;
524
 
      sr_idx = ((adif[4 + skip_size] & 0x07) << 1) |
525
 
          ((adif[5 + skip_size] & 0x80) >> 7);
526
 
    }
527
 
 
528
 
    /* FIXME: This gives totally wrong results. Duration calculation cannot
529
 
       be based on this */
530
 
    aacparse->sample_rate = gst_aacparse_get_sample_rate_from_index (sr_idx);
531
 
 
532
 
    /* baseparse is not given any fps,
533
 
     * so it will give up on timestamps, seeking, etc */
534
 
 
535
 
    /* FIXME: Can we assume this? */
536
 
    aacparse->channels = 2;
537
 
 
538
 
    GST_INFO ("ADIF: br=%d, samplerate=%d, objtype=%d",
539
 
        aacparse->bitrate, aacparse->sample_rate, aacparse->object_type);
540
 
 
541
 
    gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 512);
542
 
 
543
 
    /* arrange for metadata and get out of the way */
544
 
    gst_aacparse_set_src_caps (aacparse,
545
 
        GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (aacparse)));
546
 
    gst_base_parse_set_passthrough (GST_BASE_PARSE (aacparse), TRUE);
547
 
 
548
 
    *framesize = avail;
549
 
    return TRUE;
550
 
  }
551
 
 
552
 
  /* This should never happen */
553
 
  return FALSE;
554
 
}
555
 
 
556
 
 
557
 
/**
558
 
 * gst_aacparse_check_valid_frame:
559
 
 * @parse: #GstBaseParse.
560
 
 * @buffer: #GstBuffer.
561
 
 * @framesize: If the buffer contains a valid frame, its size will be put here
562
 
 * @skipsize: How much data parent class should skip in order to find the
563
 
 *            frame header.
564
 
 *
565
 
 * Implementation of "check_valid_frame" vmethod in #GstBaseParse class.
566
 
 *
567
 
 * Returns: TRUE if buffer contains a valid frame.
568
 
 */
569
 
gboolean
570
 
gst_aacparse_check_valid_frame (GstBaseParse * parse,
571
 
    GstBuffer * buffer, guint * framesize, gint * skipsize)
572
 
{
573
 
  const guint8 *data;
574
 
  GstAacParse *aacparse;
575
 
  gboolean ret = FALSE;
576
 
  gboolean sync;
577
 
 
578
 
  aacparse = GST_AACPARSE (parse);
579
 
  data = GST_BUFFER_DATA (buffer);
580
 
 
581
 
  sync = gst_base_parse_get_sync (parse);
582
 
 
583
 
  if (aacparse->header_type == DSPAAC_HEADER_ADIF ||
584
 
      aacparse->header_type == DSPAAC_HEADER_NONE) {
585
 
    /* There is nothing to parse */
586
 
    *framesize = GST_BUFFER_SIZE (buffer);
587
 
    ret = TRUE;
588
 
 
589
 
  } else if (aacparse->header_type == DSPAAC_HEADER_NOT_PARSED || sync == FALSE) {
590
 
 
591
 
    ret = gst_aacparse_detect_stream (aacparse, data, GST_BUFFER_SIZE (buffer),
592
 
        framesize, skipsize);
593
 
 
594
 
  } else if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
595
 
    guint needed_data = 1024;
596
 
 
597
 
    ret = gst_aacparse_check_adts_frame (aacparse, data,
598
 
        GST_BUFFER_SIZE (buffer), framesize, &needed_data);
599
 
 
600
 
    if (!ret) {
601
 
      GST_DEBUG ("buffer didn't contain valid frame");
602
 
      gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
603
 
          needed_data);
604
 
    }
605
 
 
606
 
  } else {
607
 
    GST_DEBUG ("buffer didn't contain valid frame");
608
 
    gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 1024);
609
 
  }
610
 
 
611
 
  return ret;
612
 
}
613
 
 
614
 
 
615
 
/**
616
 
 * gst_aacparse_parse_frame:
617
 
 * @parse: #GstBaseParse.
618
 
 * @buffer: #GstBuffer.
619
 
 *
620
 
 * Implementation of "parse_frame" vmethod in #GstBaseParse class.
621
 
 *
622
 
 * Returns: GST_FLOW_OK if frame was successfully parsed and can be pushed
623
 
 *          forward. Otherwise appropriate error is returned.
624
 
 */
625
 
GstFlowReturn
626
 
gst_aacparse_parse_frame (GstBaseParse * parse, GstBuffer * buffer)
627
 
{
628
 
  GstAacParse *aacparse;
629
 
  GstFlowReturn ret = GST_FLOW_OK;
630
 
  gint rate, channels;
631
 
 
632
 
  aacparse = GST_AACPARSE (parse);
633
 
 
634
 
  if (G_UNLIKELY (aacparse->header_type != DSPAAC_HEADER_ADTS))
635
 
    return ret;
636
 
 
637
 
  gst_aacparse_parse_adts_header (aacparse, GST_BUFFER_DATA (buffer),
638
 
      &rate, &channels, NULL, NULL);
639
 
  GST_LOG_OBJECT (aacparse, "rate: %d, chans: %d", rate, channels);
640
 
 
641
 
  if (G_UNLIKELY (rate != aacparse->sample_rate
642
 
          || channels != aacparse->channels)) {
643
 
    aacparse->sample_rate = rate;
644
 
    aacparse->channels = channels;
645
 
 
646
 
    if (!gst_aacparse_set_src_caps (aacparse,
647
 
            GST_PAD_CAPS (GST_BASE_PARSE (aacparse)->sinkpad))) {
648
 
      /* If linking fails, we need to return appropriate error */
649
 
      ret = GST_FLOW_NOT_LINKED;
650
 
    }
651
 
 
652
 
    gst_base_parse_set_frame_props (GST_BASE_PARSE (aacparse),
653
 
        aacparse->sample_rate, 1024, 2, 2);
654
 
  }
655
 
 
656
 
  return ret;
657
 
}
658
 
 
659
 
 
660
 
/**
661
 
 * gst_aacparse_start:
662
 
 * @parse: #GstBaseParse.
663
 
 *
664
 
 * Implementation of "start" vmethod in #GstBaseParse class.
665
 
 *
666
 
 * Returns: TRUE if startup succeeded.
667
 
 */
668
 
gboolean
669
 
gst_aacparse_start (GstBaseParse * parse)
670
 
{
671
 
  GstAacParse *aacparse;
672
 
 
673
 
  aacparse = GST_AACPARSE (parse);
674
 
  GST_DEBUG ("start");
675
 
  gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 1024);
676
 
  gst_base_parse_set_passthrough (parse, FALSE);
677
 
  return TRUE;
678
 
}
679
 
 
680
 
 
681
 
/**
682
 
 * gst_aacparse_stop:
683
 
 * @parse: #GstBaseParse.
684
 
 *
685
 
 * Implementation of "stop" vmethod in #GstBaseParse class.
686
 
 *
687
 
 * Returns: TRUE is stopping succeeded.
688
 
 */
689
 
gboolean
690
 
gst_aacparse_stop (GstBaseParse * parse)
691
 
{
692
 
  GST_DEBUG ("stop");
693
 
  return TRUE;
694
 
}
695
 
 
696
 
 
697
 
/**
698
 
 * gst_aacparse_get_frame_overhead:
699
 
 * @parse: #GstBaseParse.
700
 
 * @buffer: #GstBuffer.
701
 
 *
702
 
 * Implementation of "get_frame_overhead" vmethod in #GstBaseParse class. ADTS
703
 
 * streams have a 7 byte header in each frame. MP4 and ADIF streams don't have
704
 
 * a per-frame header.
705
 
 *
706
 
 * We're making a couple of simplifying assumptions:
707
 
 *
708
 
 * 1. We count Program Configuration Elements rather than searching for them
709
 
 *    in the streams to discount them - the overhead is negligible.
710
 
 *
711
 
 * 2. We ignore CRC. This has a worst-case impact of (num_raw_blocks + 1)*16
712
 
 *    bits, which should still not be significant enough to warrant the
713
 
 *    additional parsing through the headers
714
 
 */
715
 
gint
716
 
gst_aacparse_get_frame_overhead (GstBaseParse * parse, GstBuffer * buffer)
717
 
{
718
 
  GstAacParse *aacparse = GST_AACPARSE (parse);
719
 
 
720
 
  if (aacparse->header_type == DSPAAC_HEADER_ADTS)
721
 
    return 7;
722
 
  else
723
 
    return 0;
724
 
}