gst_plugins_good/gst/auparse/gstauparse.c
author hgs
Wed, 24 Mar 2010 18:04:17 -0500
changeset 16 8e837d1bf446
permissions -rw-r--r--
201009
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16
hgs
parents:
diff changeset
     1
/* GStreamer
hgs
parents:
diff changeset
     2
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
hgs
parents:
diff changeset
     3
 * Copyright (C) <2006> Tim-Philipp Müller <tim centricular net>
hgs
parents:
diff changeset
     4
 *
hgs
parents:
diff changeset
     5
 * This library is free software; you can redistribute it and/or
hgs
parents:
diff changeset
     6
 * modify it under the terms of the GNU Library General Public
hgs
parents:
diff changeset
     7
 * License as published by the Free Software Foundation; either
hgs
parents:
diff changeset
     8
 * version 2 of the License, or (at your option) any later version.
hgs
parents:
diff changeset
     9
 *
hgs
parents:
diff changeset
    10
 * This library is distributed in the hope that it will be useful,
hgs
parents:
diff changeset
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
hgs
parents:
diff changeset
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
hgs
parents:
diff changeset
    13
 * Library General Public License for more details.
hgs
parents:
diff changeset
    14
 *
hgs
parents:
diff changeset
    15
 * You should have received a copy of the GNU Library General Public
hgs
parents:
diff changeset
    16
 * License along with this library; if not, write to the
hgs
parents:
diff changeset
    17
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
hgs
parents:
diff changeset
    18
 * Boston, MA 02111-1307, USA.
hgs
parents:
diff changeset
    19
 */
hgs
parents:
diff changeset
    20
hgs
parents:
diff changeset
    21
/**
hgs
parents:
diff changeset
    22
 * SECTION:element-auparse
hgs
parents:
diff changeset
    23
 *
hgs
parents:
diff changeset
    24
 * Parses .au files mostly originating from sun os based computers.
hgs
parents:
diff changeset
    25
 */
hgs
parents:
diff changeset
    26
hgs
parents:
diff changeset
    27
#ifdef HAVE_CONFIG_H
hgs
parents:
diff changeset
    28
#include "config.h"
hgs
parents:
diff changeset
    29
#endif
hgs
parents:
diff changeset
    30
hgs
parents:
diff changeset
    31
#include <stdlib.h>
hgs
parents:
diff changeset
    32
#include <string.h>
hgs
parents:
diff changeset
    33
hgs
parents:
diff changeset
    34
#include "gstauparse.h"
hgs
parents:
diff changeset
    35
#include <gst/audio/audio.h>
hgs
parents:
diff changeset
    36
hgs
parents:
diff changeset
    37
GST_DEBUG_CATEGORY_STATIC (auparse_debug);
hgs
parents:
diff changeset
    38
#define GST_CAT_DEFAULT (auparse_debug)
hgs
parents:
diff changeset
    39
hgs
parents:
diff changeset
    40
static const GstElementDetails gst_au_parse_details =
hgs
parents:
diff changeset
    41
GST_ELEMENT_DETAILS ("AU audio demuxer",
hgs
parents:
diff changeset
    42
    "Codec/Demuxer/Audio",
hgs
parents:
diff changeset
    43
    "Parse an .au file into raw audio",
hgs
parents:
diff changeset
    44
    "Erik Walthinsen <omega@cse.ogi.edu>");
hgs
parents:
diff changeset
    45
hgs
parents:
diff changeset
    46
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
hgs
parents:
diff changeset
    47
    GST_PAD_SINK,
hgs
parents:
diff changeset
    48
    GST_PAD_ALWAYS,
hgs
parents:
diff changeset
    49
    GST_STATIC_CAPS ("audio/x-au")
hgs
parents:
diff changeset
    50
    );
hgs
parents:
diff changeset
    51
hgs
parents:
diff changeset
    52
#define GST_AU_PARSE_ALAW_PAD_TEMPLATE_CAPS \
hgs
parents:
diff changeset
    53
    "audio/x-alaw, "                        \
hgs
parents:
diff changeset
    54
    "rate = (int) [ 8000, 192000 ], "       \
hgs
parents:
diff changeset
    55
    "channels = (int) [ 1, 2 ]"
hgs
parents:
diff changeset
    56
hgs
parents:
diff changeset
    57
#define GST_AU_PARSE_MULAW_PAD_TEMPLATE_CAPS \
hgs
parents:
diff changeset
    58
    "audio/x-mulaw, "                        \
hgs
parents:
diff changeset
    59
    "rate = (int) [ 8000, 192000 ], "        \
hgs
parents:
diff changeset
    60
    "channels = (int) [ 1, 2 ]"
hgs
parents:
diff changeset
    61
hgs
parents:
diff changeset
    62
/* Nothing to decode those ADPCM streams for now */
hgs
parents:
diff changeset
    63
#define GST_AU_PARSE_ADPCM_PAD_TEMPLATE_CAPS \
hgs
parents:
diff changeset
    64
    "audio/x-adpcm, "                        \
hgs
parents:
diff changeset
    65
    "layout = (string) { g721, g722, g723_3, g723_5 }"
hgs
parents:
diff changeset
    66
hgs
parents:
diff changeset
    67
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
hgs
parents:
diff changeset
    68
    GST_PAD_SRC,
hgs
parents:
diff changeset
    69
    GST_PAD_SOMETIMES,
hgs
parents:
diff changeset
    70
    GST_STATIC_CAPS (GST_AUDIO_INT_PAD_TEMPLATE_CAPS "; "
hgs
parents:
diff changeset
    71
        GST_AUDIO_FLOAT_PAD_TEMPLATE_CAPS ";"
hgs
parents:
diff changeset
    72
        GST_AU_PARSE_ALAW_PAD_TEMPLATE_CAPS ";"
hgs
parents:
diff changeset
    73
        GST_AU_PARSE_MULAW_PAD_TEMPLATE_CAPS ";"
hgs
parents:
diff changeset
    74
        GST_AU_PARSE_ADPCM_PAD_TEMPLATE_CAPS));
hgs
parents:
diff changeset
    75
hgs
parents:
diff changeset
    76
hgs
parents:
diff changeset
    77
static void gst_au_parse_dispose (GObject * object);
hgs
parents:
diff changeset
    78
static GstFlowReturn gst_au_parse_chain (GstPad * pad, GstBuffer * buf);
hgs
parents:
diff changeset
    79
static GstStateChangeReturn gst_au_parse_change_state (GstElement * element,
hgs
parents:
diff changeset
    80
    GstStateChange transition);
hgs
parents:
diff changeset
    81
static void gst_au_parse_reset (GstAuParse * auparse);
hgs
parents:
diff changeset
    82
static gboolean gst_au_parse_remove_srcpad (GstAuParse * auparse);
hgs
parents:
diff changeset
    83
static gboolean gst_au_parse_add_srcpad (GstAuParse * auparse, GstCaps * caps);
hgs
parents:
diff changeset
    84
static gboolean gst_au_parse_src_query (GstPad * pad, GstQuery * query);
hgs
parents:
diff changeset
    85
static gboolean gst_au_parse_src_event (GstPad * pad, GstEvent * event);
hgs
parents:
diff changeset
    86
static gboolean gst_au_parse_sink_event (GstPad * pad, GstEvent * event);
hgs
parents:
diff changeset
    87
hgs
parents:
diff changeset
    88
GST_BOILERPLATE (GstAuParse, gst_au_parse, GstElement, GST_TYPE_ELEMENT);
hgs
parents:
diff changeset
    89
hgs
parents:
diff changeset
    90
static void
hgs
parents:
diff changeset
    91
gst_au_parse_base_init (gpointer g_class)
hgs
parents:
diff changeset
    92
{
hgs
parents:
diff changeset
    93
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
hgs
parents:
diff changeset
    94
hgs
parents:
diff changeset
    95
  gst_element_class_add_pad_template (element_class,
hgs
parents:
diff changeset
    96
      gst_static_pad_template_get (&sink_template));
hgs
parents:
diff changeset
    97
  gst_element_class_add_pad_template (element_class,
hgs
parents:
diff changeset
    98
      gst_static_pad_template_get (&src_template));
hgs
parents:
diff changeset
    99
  gst_element_class_set_details (element_class, &gst_au_parse_details);
hgs
parents:
diff changeset
   100
hgs
parents:
diff changeset
   101
  GST_DEBUG_CATEGORY_INIT (auparse_debug, "auparse", 0, ".au parser");
hgs
parents:
diff changeset
   102
}
hgs
parents:
diff changeset
   103
hgs
parents:
diff changeset
   104
static void
hgs
parents:
diff changeset
   105
gst_au_parse_class_init (GstAuParseClass * klass)
hgs
parents:
diff changeset
   106
{
hgs
parents:
diff changeset
   107
  GObjectClass *gobject_class;
hgs
parents:
diff changeset
   108
  GstElementClass *gstelement_class;
hgs
parents:
diff changeset
   109
hgs
parents:
diff changeset
   110
  gobject_class = (GObjectClass *) klass;
hgs
parents:
diff changeset
   111
  gstelement_class = (GstElementClass *) klass;
hgs
parents:
diff changeset
   112
hgs
parents:
diff changeset
   113
  gobject_class->dispose = gst_au_parse_dispose;
hgs
parents:
diff changeset
   114
hgs
parents:
diff changeset
   115
  gstelement_class->change_state =
hgs
parents:
diff changeset
   116
      GST_DEBUG_FUNCPTR (gst_au_parse_change_state);
hgs
parents:
diff changeset
   117
}
hgs
parents:
diff changeset
   118
hgs
parents:
diff changeset
   119
static void
hgs
parents:
diff changeset
   120
gst_au_parse_init (GstAuParse * auparse, GstAuParseClass * klass)
hgs
parents:
diff changeset
   121
{
hgs
parents:
diff changeset
   122
  auparse->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
hgs
parents:
diff changeset
   123
  gst_pad_set_chain_function (auparse->sinkpad,
hgs
parents:
diff changeset
   124
      GST_DEBUG_FUNCPTR (gst_au_parse_chain));
hgs
parents:
diff changeset
   125
  gst_pad_set_event_function (auparse->sinkpad,
hgs
parents:
diff changeset
   126
      GST_DEBUG_FUNCPTR (gst_au_parse_sink_event));
hgs
parents:
diff changeset
   127
  gst_element_add_pad (GST_ELEMENT (auparse), auparse->sinkpad);
hgs
parents:
diff changeset
   128
hgs
parents:
diff changeset
   129
  auparse->srcpad = NULL;
hgs
parents:
diff changeset
   130
  auparse->adapter = gst_adapter_new ();
hgs
parents:
diff changeset
   131
  gst_au_parse_reset (auparse);
hgs
parents:
diff changeset
   132
}
hgs
parents:
diff changeset
   133
hgs
parents:
diff changeset
   134
static void
hgs
parents:
diff changeset
   135
gst_au_parse_dispose (GObject * object)
hgs
parents:
diff changeset
   136
{
hgs
parents:
diff changeset
   137
  GstAuParse *au = GST_AU_PARSE (object);
hgs
parents:
diff changeset
   138
hgs
parents:
diff changeset
   139
  if (au->adapter != NULL) {
hgs
parents:
diff changeset
   140
    g_object_unref (au->adapter);
hgs
parents:
diff changeset
   141
    au->adapter = NULL;
hgs
parents:
diff changeset
   142
  }
hgs
parents:
diff changeset
   143
  G_OBJECT_CLASS (parent_class)->dispose (object);
hgs
parents:
diff changeset
   144
}
hgs
parents:
diff changeset
   145
hgs
parents:
diff changeset
   146
static void
hgs
parents:
diff changeset
   147
gst_au_parse_reset (GstAuParse * auparse)
hgs
parents:
diff changeset
   148
{
hgs
parents:
diff changeset
   149
  gst_au_parse_remove_srcpad (auparse);
hgs
parents:
diff changeset
   150
hgs
parents:
diff changeset
   151
  auparse->offset = 0;
hgs
parents:
diff changeset
   152
  auparse->buffer_offset = 0;
hgs
parents:
diff changeset
   153
  auparse->encoding = 0;
hgs
parents:
diff changeset
   154
  auparse->samplerate = 0;
hgs
parents:
diff changeset
   155
  auparse->channels = 0;
hgs
parents:
diff changeset
   156
hgs
parents:
diff changeset
   157
  gst_adapter_clear (auparse->adapter);
hgs
parents:
diff changeset
   158
hgs
parents:
diff changeset
   159
  /* gst_segment_init (&auparse->segment, GST_FORMAT_TIME); */
hgs
parents:
diff changeset
   160
}
hgs
parents:
diff changeset
   161
hgs
parents:
diff changeset
   162
static gboolean
hgs
parents:
diff changeset
   163
gst_au_parse_add_srcpad (GstAuParse * auparse, GstCaps * new_caps)
hgs
parents:
diff changeset
   164
{
hgs
parents:
diff changeset
   165
  if (auparse->src_caps && gst_caps_is_equal (new_caps, auparse->src_caps)) {
hgs
parents:
diff changeset
   166
    GST_LOG_OBJECT (auparse, "same caps, nothing to do");
hgs
parents:
diff changeset
   167
    return TRUE;
hgs
parents:
diff changeset
   168
  }
hgs
parents:
diff changeset
   169
hgs
parents:
diff changeset
   170
  gst_caps_replace (&auparse->src_caps, new_caps);
hgs
parents:
diff changeset
   171
  if (auparse->srcpad != NULL) {
hgs
parents:
diff changeset
   172
    GST_DEBUG_OBJECT (auparse, "Changing src pad caps to %" GST_PTR_FORMAT,
hgs
parents:
diff changeset
   173
        auparse->src_caps);
hgs
parents:
diff changeset
   174
    gst_pad_set_caps (auparse->srcpad, auparse->src_caps);
hgs
parents:
diff changeset
   175
  }
hgs
parents:
diff changeset
   176
hgs
parents:
diff changeset
   177
  if (auparse->srcpad == NULL) {
hgs
parents:
diff changeset
   178
    auparse->srcpad = gst_pad_new_from_static_template (&src_template, "src");
hgs
parents:
diff changeset
   179
    g_return_val_if_fail (auparse->srcpad != NULL, FALSE);
hgs
parents:
diff changeset
   180
hgs
parents:
diff changeset
   181
#if 0
hgs
parents:
diff changeset
   182
    gst_pad_set_query_type_function (auparse->srcpad,
hgs
parents:
diff changeset
   183
        GST_DEBUG_FUNCPTR (gst_au_parse_src_get_query_types));
hgs
parents:
diff changeset
   184
#endif
hgs
parents:
diff changeset
   185
    gst_pad_set_query_function (auparse->srcpad,
hgs
parents:
diff changeset
   186
        GST_DEBUG_FUNCPTR (gst_au_parse_src_query));
hgs
parents:
diff changeset
   187
    gst_pad_set_event_function (auparse->srcpad,
hgs
parents:
diff changeset
   188
        GST_DEBUG_FUNCPTR (gst_au_parse_src_event));
hgs
parents:
diff changeset
   189
hgs
parents:
diff changeset
   190
    gst_pad_use_fixed_caps (auparse->srcpad);
hgs
parents:
diff changeset
   191
    gst_pad_set_active (auparse->srcpad, TRUE);
hgs
parents:
diff changeset
   192
hgs
parents:
diff changeset
   193
    if (auparse->src_caps)
hgs
parents:
diff changeset
   194
      gst_pad_set_caps (auparse->srcpad, auparse->src_caps);
hgs
parents:
diff changeset
   195
hgs
parents:
diff changeset
   196
    GST_DEBUG_OBJECT (auparse, "Adding src pad with caps %" GST_PTR_FORMAT,
hgs
parents:
diff changeset
   197
        auparse->src_caps);
hgs
parents:
diff changeset
   198
hgs
parents:
diff changeset
   199
    gst_object_ref (auparse->srcpad);
hgs
parents:
diff changeset
   200
    if (!gst_element_add_pad (GST_ELEMENT (auparse), auparse->srcpad))
hgs
parents:
diff changeset
   201
      return FALSE;
hgs
parents:
diff changeset
   202
    gst_element_no_more_pads (GST_ELEMENT (auparse));
hgs
parents:
diff changeset
   203
  }
hgs
parents:
diff changeset
   204
hgs
parents:
diff changeset
   205
  return TRUE;
hgs
parents:
diff changeset
   206
}
hgs
parents:
diff changeset
   207
hgs
parents:
diff changeset
   208
static gboolean
hgs
parents:
diff changeset
   209
gst_au_parse_remove_srcpad (GstAuParse * auparse)
hgs
parents:
diff changeset
   210
{
hgs
parents:
diff changeset
   211
  gboolean res = TRUE;
hgs
parents:
diff changeset
   212
hgs
parents:
diff changeset
   213
  if (auparse->srcpad != NULL) {
hgs
parents:
diff changeset
   214
    GST_DEBUG_OBJECT (auparse, "Removing src pad");
hgs
parents:
diff changeset
   215
    res = gst_element_remove_pad (GST_ELEMENT (auparse), auparse->srcpad);
hgs
parents:
diff changeset
   216
    g_return_val_if_fail (res != FALSE, FALSE);
hgs
parents:
diff changeset
   217
    gst_object_unref (auparse->srcpad);
hgs
parents:
diff changeset
   218
    auparse->srcpad = NULL;
hgs
parents:
diff changeset
   219
  }
hgs
parents:
diff changeset
   220
hgs
parents:
diff changeset
   221
  return res;
hgs
parents:
diff changeset
   222
}
hgs
parents:
diff changeset
   223
hgs
parents:
diff changeset
   224
static GstFlowReturn
hgs
parents:
diff changeset
   225
gst_au_parse_parse_header (GstAuParse * auparse)
hgs
parents:
diff changeset
   226
{
hgs
parents:
diff changeset
   227
  GstCaps *tempcaps;
hgs
parents:
diff changeset
   228
  guint32 size;
hgs
parents:
diff changeset
   229
  guint8 *head;
hgs
parents:
diff changeset
   230
  gchar layout[7] = { 0, };
hgs
parents:
diff changeset
   231
  gint law = 0, depth = 0, ieee = 0;
hgs
parents:
diff changeset
   232
hgs
parents:
diff changeset
   233
  head = (guint8 *) gst_adapter_peek (auparse->adapter, 24);
hgs
parents:
diff changeset
   234
  g_assert (head != NULL);
hgs
parents:
diff changeset
   235
hgs
parents:
diff changeset
   236
  GST_DEBUG_OBJECT (auparse, "[%c%c%c%c]", head[0], head[1], head[2], head[3]);
hgs
parents:
diff changeset
   237
hgs
parents:
diff changeset
   238
  switch (GST_READ_UINT32_BE (head)) {
hgs
parents:
diff changeset
   239
      /* normal format is big endian (au is a Sparc format) */
hgs
parents:
diff changeset
   240
    case 0x2e736e64:{          /* ".snd" */
hgs
parents:
diff changeset
   241
      auparse->endianness = G_BIG_ENDIAN;
hgs
parents:
diff changeset
   242
      break;
hgs
parents:
diff changeset
   243
    }
hgs
parents:
diff changeset
   244
      /* and of course, someone had to invent a little endian
hgs
parents:
diff changeset
   245
       * version.  Used by DEC systems. */
hgs
parents:
diff changeset
   246
    case 0x646e732e:           /* dns.                          */
hgs
parents:
diff changeset
   247
    case 0x0064732e:{          /* other source say it is "dns." */
hgs
parents:
diff changeset
   248
      auparse->endianness = G_LITTLE_ENDIAN;
hgs
parents:
diff changeset
   249
      break;
hgs
parents:
diff changeset
   250
    }
hgs
parents:
diff changeset
   251
    default:{
hgs
parents:
diff changeset
   252
      goto unknown_header;
hgs
parents:
diff changeset
   253
    }
hgs
parents:
diff changeset
   254
  }
hgs
parents:
diff changeset
   255
hgs
parents:
diff changeset
   256
  auparse->offset = GST_READ_UINT32_BE (head + 4);
hgs
parents:
diff changeset
   257
  /* Do not trust size, could be set to -1 : unknown */
hgs
parents:
diff changeset
   258
  size = GST_READ_UINT32_BE (head + 8);
hgs
parents:
diff changeset
   259
  auparse->encoding = GST_READ_UINT32_BE (head + 12);
hgs
parents:
diff changeset
   260
  auparse->samplerate = GST_READ_UINT32_BE (head + 16);
hgs
parents:
diff changeset
   261
  auparse->channels = GST_READ_UINT32_BE (head + 20);
hgs
parents:
diff changeset
   262
hgs
parents:
diff changeset
   263
  if (auparse->samplerate < 8000 || auparse->samplerate > 192000)
hgs
parents:
diff changeset
   264
    goto unsupported_sample_rate;
hgs
parents:
diff changeset
   265
hgs
parents:
diff changeset
   266
  if (auparse->channels < 1 || auparse->channels > 2)
hgs
parents:
diff changeset
   267
    goto unsupported_number_of_channels;
hgs
parents:
diff changeset
   268
hgs
parents:
diff changeset
   269
  GST_DEBUG_OBJECT (auparse, "offset %" G_GINT64_FORMAT ", size %u, "
hgs
parents:
diff changeset
   270
      "encoding %u, frequency %u, channels %u", auparse->offset, size,
hgs
parents:
diff changeset
   271
      auparse->encoding, auparse->samplerate, auparse->channels);
hgs
parents:
diff changeset
   272
hgs
parents:
diff changeset
   273
  /* Docs:
hgs
parents:
diff changeset
   274
   * http://www.opengroup.org/public/pubs/external/auformat.html
hgs
parents:
diff changeset
   275
   * http://astronomy.swin.edu.au/~pbourke/dataformats/au/
hgs
parents:
diff changeset
   276
   * Solaris headers : /usr/include/audio/au.h
hgs
parents:
diff changeset
   277
   * libsndfile : src/au.c
hgs
parents:
diff changeset
   278
   *
hgs
parents:
diff changeset
   279
   * Samples :
hgs
parents:
diff changeset
   280
   * http://www.tsp.ece.mcgill.ca/MMSP/Documents/AudioFormats/AU/Samples.html
hgs
parents:
diff changeset
   281
   */
hgs
parents:
diff changeset
   282
hgs
parents:
diff changeset
   283
  switch (auparse->encoding) {
hgs
parents:
diff changeset
   284
    case 1:                    /* 8-bit ISDN mu-law G.711 */
hgs
parents:
diff changeset
   285
      law = 1;
hgs
parents:
diff changeset
   286
      depth = 8;
hgs
parents:
diff changeset
   287
      break;
hgs
parents:
diff changeset
   288
    case 27:                   /* 8-bit ISDN  A-law G.711 */
hgs
parents:
diff changeset
   289
      law = 2;
hgs
parents:
diff changeset
   290
      depth = 8;
hgs
parents:
diff changeset
   291
      break;
hgs
parents:
diff changeset
   292
hgs
parents:
diff changeset
   293
    case 2:                    /*  8-bit linear PCM */
hgs
parents:
diff changeset
   294
      depth = 8;
hgs
parents:
diff changeset
   295
      break;
hgs
parents:
diff changeset
   296
    case 3:                    /* 16-bit linear PCM */
hgs
parents:
diff changeset
   297
      depth = 16;
hgs
parents:
diff changeset
   298
      break;
hgs
parents:
diff changeset
   299
    case 4:                    /* 24-bit linear PCM */
hgs
parents:
diff changeset
   300
      depth = 24;
hgs
parents:
diff changeset
   301
      break;
hgs
parents:
diff changeset
   302
    case 5:                    /* 32-bit linear PCM */
hgs
parents:
diff changeset
   303
      depth = 32;
hgs
parents:
diff changeset
   304
      break;
hgs
parents:
diff changeset
   305
hgs
parents:
diff changeset
   306
    case 6:                    /* 32-bit IEEE floating point */
hgs
parents:
diff changeset
   307
      ieee = 1;
hgs
parents:
diff changeset
   308
      depth = 32;
hgs
parents:
diff changeset
   309
      break;
hgs
parents:
diff changeset
   310
    case 7:                    /* 64-bit IEEE floating point */
hgs
parents:
diff changeset
   311
      ieee = 1;
hgs
parents:
diff changeset
   312
      depth = 64;
hgs
parents:
diff changeset
   313
      break;
hgs
parents:
diff changeset
   314
hgs
parents:
diff changeset
   315
    case 23:                   /* 4-bit CCITT G.721   ADPCM 32kbps -> modplug/libsndfile (compressed 8-bit mu-law) */
hgs
parents:
diff changeset
   316
      strcpy (layout, "g721");
hgs
parents:
diff changeset
   317
      break;
hgs
parents:
diff changeset
   318
    case 24:                   /* 8-bit CCITT G.722   ADPCM        -> rtp */
hgs
parents:
diff changeset
   319
      strcpy (layout, "g722");
hgs
parents:
diff changeset
   320
      break;
hgs
parents:
diff changeset
   321
    case 25:                   /* 3-bit CCITT G.723.3 ADPCM 24kbps -> rtp/xine/modplug/libsndfile */
hgs
parents:
diff changeset
   322
      strcpy (layout, "g723_3");
hgs
parents:
diff changeset
   323
      break;
hgs
parents:
diff changeset
   324
    case 26:                   /* 5-bit CCITT G.723.5 ADPCM 40kbps -> rtp/xine/modplug/libsndfile */
hgs
parents:
diff changeset
   325
      strcpy (layout, "g723_5");
hgs
parents:
diff changeset
   326
      break;
hgs
parents:
diff changeset
   327
hgs
parents:
diff changeset
   328
    case 8:                    /* Fragmented sample data */
hgs
parents:
diff changeset
   329
    case 9:                    /* AU_ENCODING_NESTED */
hgs
parents:
diff changeset
   330
hgs
parents:
diff changeset
   331
    case 10:                   /* DSP program */
hgs
parents:
diff changeset
   332
    case 11:                   /* DSP  8-bit fixed point */
hgs
parents:
diff changeset
   333
    case 12:                   /* DSP 16-bit fixed point */
hgs
parents:
diff changeset
   334
    case 13:                   /* DSP 24-bit fixed point */
hgs
parents:
diff changeset
   335
    case 14:                   /* DSP 32-bit fixed point */
hgs
parents:
diff changeset
   336
hgs
parents:
diff changeset
   337
    case 16:                   /* AU_ENCODING_DISPLAY : non-audio display data */
hgs
parents:
diff changeset
   338
    case 17:                   /* AU_ENCODING_MULAW_SQUELCH */
hgs
parents:
diff changeset
   339
hgs
parents:
diff changeset
   340
    case 18:                   /* 16-bit linear with emphasis */
hgs
parents:
diff changeset
   341
    case 19:                   /* 16-bit linear compressed (NeXT) */
hgs
parents:
diff changeset
   342
    case 20:                   /* 16-bit linear with emphasis and compression */
hgs
parents:
diff changeset
   343
hgs
parents:
diff changeset
   344
    case 21:                   /* Music kit DSP commands */
hgs
parents:
diff changeset
   345
    case 22:                   /* Music kit DSP commands samples */
hgs
parents:
diff changeset
   346
hgs
parents:
diff changeset
   347
    default:
hgs
parents:
diff changeset
   348
      goto unknown_format;
hgs
parents:
diff changeset
   349
  }
hgs
parents:
diff changeset
   350
hgs
parents:
diff changeset
   351
  if (law) {
hgs
parents:
diff changeset
   352
    tempcaps =
hgs
parents:
diff changeset
   353
        gst_caps_new_simple ((law == 1) ? "audio/x-mulaw" : "audio/x-alaw",
hgs
parents:
diff changeset
   354
        "rate", G_TYPE_INT, auparse->samplerate,
hgs
parents:
diff changeset
   355
        "channels", G_TYPE_INT, auparse->channels, NULL);
hgs
parents:
diff changeset
   356
    auparse->sample_size = auparse->channels;
hgs
parents:
diff changeset
   357
  } else if (ieee) {
hgs
parents:
diff changeset
   358
    tempcaps = gst_caps_new_simple ("audio/x-raw-float",
hgs
parents:
diff changeset
   359
        "rate", G_TYPE_INT, auparse->samplerate,
hgs
parents:
diff changeset
   360
        "channels", G_TYPE_INT, auparse->channels,
hgs
parents:
diff changeset
   361
        "endianness", G_TYPE_INT, auparse->endianness,
hgs
parents:
diff changeset
   362
        "width", G_TYPE_INT, depth, NULL);
hgs
parents:
diff changeset
   363
    auparse->sample_size = auparse->channels * depth / 8;
hgs
parents:
diff changeset
   364
  } else if (layout[0]) {
hgs
parents:
diff changeset
   365
    tempcaps = gst_caps_new_simple ("audio/x-adpcm",
hgs
parents:
diff changeset
   366
        "layout", G_TYPE_STRING, layout, NULL);
hgs
parents:
diff changeset
   367
    auparse->sample_size = 0;
hgs
parents:
diff changeset
   368
  } else {
hgs
parents:
diff changeset
   369
    tempcaps = gst_caps_new_simple ("audio/x-raw-int",
hgs
parents:
diff changeset
   370
        "rate", G_TYPE_INT, auparse->samplerate,
hgs
parents:
diff changeset
   371
        "channels", G_TYPE_INT, auparse->channels,
hgs
parents:
diff changeset
   372
        "endianness", G_TYPE_INT, auparse->endianness,
hgs
parents:
diff changeset
   373
        "depth", G_TYPE_INT, depth, "width", G_TYPE_INT, depth,
hgs
parents:
diff changeset
   374
        /* FIXME: signed TRUE even for 8-bit PCM? */
hgs
parents:
diff changeset
   375
        "signed", G_TYPE_BOOLEAN, TRUE, NULL);
hgs
parents:
diff changeset
   376
    auparse->sample_size = auparse->channels * depth / 8;
hgs
parents:
diff changeset
   377
  }
hgs
parents:
diff changeset
   378
hgs
parents:
diff changeset
   379
  GST_DEBUG_OBJECT (auparse, "sample_size=%d", auparse->sample_size);
hgs
parents:
diff changeset
   380
hgs
parents:
diff changeset
   381
  if (!gst_au_parse_add_srcpad (auparse, tempcaps))
hgs
parents:
diff changeset
   382
    goto add_pad_failed;
hgs
parents:
diff changeset
   383
hgs
parents:
diff changeset
   384
  GST_DEBUG_OBJECT (auparse, "offset=%" G_GINT64_FORMAT, auparse->offset);
hgs
parents:
diff changeset
   385
  gst_adapter_flush (auparse->adapter, auparse->offset);
hgs
parents:
diff changeset
   386
hgs
parents:
diff changeset
   387
  gst_caps_unref (tempcaps);
hgs
parents:
diff changeset
   388
  return GST_FLOW_OK;
hgs
parents:
diff changeset
   389
hgs
parents:
diff changeset
   390
  /* ERRORS */
hgs
parents:
diff changeset
   391
unknown_header:
hgs
parents:
diff changeset
   392
  {
hgs
parents:
diff changeset
   393
    GST_ELEMENT_ERROR (auparse, STREAM, WRONG_TYPE, (NULL), (NULL));
hgs
parents:
diff changeset
   394
    return GST_FLOW_ERROR;
hgs
parents:
diff changeset
   395
  }
hgs
parents:
diff changeset
   396
unsupported_sample_rate:
hgs
parents:
diff changeset
   397
  {
hgs
parents:
diff changeset
   398
    GST_ELEMENT_ERROR (auparse, STREAM, FORMAT, (NULL),
hgs
parents:
diff changeset
   399
        ("Unsupported samplerate: %u", auparse->samplerate));
hgs
parents:
diff changeset
   400
    return GST_FLOW_ERROR;
hgs
parents:
diff changeset
   401
  }
hgs
parents:
diff changeset
   402
unsupported_number_of_channels:
hgs
parents:
diff changeset
   403
  {
hgs
parents:
diff changeset
   404
    GST_ELEMENT_ERROR (auparse, STREAM, FORMAT, (NULL),
hgs
parents:
diff changeset
   405
        ("Unsupported number of channels: %u", auparse->channels));
hgs
parents:
diff changeset
   406
    return GST_FLOW_ERROR;
hgs
parents:
diff changeset
   407
  }
hgs
parents:
diff changeset
   408
unknown_format:
hgs
parents:
diff changeset
   409
  {
hgs
parents:
diff changeset
   410
    GST_ELEMENT_ERROR (auparse, STREAM, FORMAT, (NULL),
hgs
parents:
diff changeset
   411
        ("Unsupported encoding: %u", auparse->encoding));
hgs
parents:
diff changeset
   412
    return GST_FLOW_ERROR;
hgs
parents:
diff changeset
   413
  }
hgs
parents:
diff changeset
   414
add_pad_failed:
hgs
parents:
diff changeset
   415
  {
hgs
parents:
diff changeset
   416
    GST_ELEMENT_ERROR (auparse, STREAM, FAILED, (NULL),
hgs
parents:
diff changeset
   417
        ("Failed to add srcpad"));
hgs
parents:
diff changeset
   418
    gst_caps_unref (tempcaps);
hgs
parents:
diff changeset
   419
    return GST_FLOW_ERROR;
hgs
parents:
diff changeset
   420
  }
hgs
parents:
diff changeset
   421
}
hgs
parents:
diff changeset
   422
hgs
parents:
diff changeset
   423
#define AU_HEADER_SIZE 24
hgs
parents:
diff changeset
   424
hgs
parents:
diff changeset
   425
static GstFlowReturn
hgs
parents:
diff changeset
   426
gst_au_parse_chain (GstPad * pad, GstBuffer * buf)
hgs
parents:
diff changeset
   427
{
hgs
parents:
diff changeset
   428
  GstFlowReturn ret = GST_FLOW_OK;
hgs
parents:
diff changeset
   429
  GstAuParse *auparse;
hgs
parents:
diff changeset
   430
  gint avail, sendnow = 0;
hgs
parents:
diff changeset
   431
hgs
parents:
diff changeset
   432
  auparse = GST_AU_PARSE (gst_pad_get_parent (pad));
hgs
parents:
diff changeset
   433
hgs
parents:
diff changeset
   434
  GST_LOG_OBJECT (auparse, "got buffer of size %u", GST_BUFFER_SIZE (buf));
hgs
parents:
diff changeset
   435
hgs
parents:
diff changeset
   436
  gst_adapter_push (auparse->adapter, buf);
hgs
parents:
diff changeset
   437
  buf = NULL;
hgs
parents:
diff changeset
   438
hgs
parents:
diff changeset
   439
  /* if we haven't seen any data yet... */
hgs
parents:
diff changeset
   440
  if (auparse->srcpad == NULL) {
hgs
parents:
diff changeset
   441
    if (gst_adapter_available (auparse->adapter) < AU_HEADER_SIZE) {
hgs
parents:
diff changeset
   442
      GST_DEBUG_OBJECT (auparse, "need more data to parse header");
hgs
parents:
diff changeset
   443
      ret = GST_FLOW_OK;
hgs
parents:
diff changeset
   444
      goto out;
hgs
parents:
diff changeset
   445
    }
hgs
parents:
diff changeset
   446
hgs
parents:
diff changeset
   447
    ret = gst_au_parse_parse_header (auparse);
hgs
parents:
diff changeset
   448
    if (ret != GST_FLOW_OK)
hgs
parents:
diff changeset
   449
      goto out;
hgs
parents:
diff changeset
   450
hgs
parents:
diff changeset
   451
    gst_pad_push_event (auparse->srcpad,
hgs
parents:
diff changeset
   452
        gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_DEFAULT,
hgs
parents:
diff changeset
   453
            0, GST_CLOCK_TIME_NONE, 0));
hgs
parents:
diff changeset
   454
  }
hgs
parents:
diff changeset
   455
hgs
parents:
diff changeset
   456
  avail = gst_adapter_available (auparse->adapter);
hgs
parents:
diff changeset
   457
hgs
parents:
diff changeset
   458
  if (auparse->sample_size > 0) {
hgs
parents:
diff changeset
   459
    /* Ensure we push a buffer that's a multiple of the frame size downstream */
hgs
parents:
diff changeset
   460
    sendnow = avail - (avail % auparse->sample_size);
hgs
parents:
diff changeset
   461
  } else {
hgs
parents:
diff changeset
   462
    /* It's something non-trivial (such as ADPCM), we don't understand it, so
hgs
parents:
diff changeset
   463
     * just push downstream and assume it will know what to do with it */
hgs
parents:
diff changeset
   464
    sendnow = avail;
hgs
parents:
diff changeset
   465
  }
hgs
parents:
diff changeset
   466
hgs
parents:
diff changeset
   467
  if (sendnow > 0) {
hgs
parents:
diff changeset
   468
    GstBuffer *outbuf;
hgs
parents:
diff changeset
   469
    const guint8 *data;
hgs
parents:
diff changeset
   470
hgs
parents:
diff changeset
   471
    ret = gst_pad_alloc_buffer_and_set_caps (auparse->srcpad,
hgs
parents:
diff changeset
   472
        auparse->buffer_offset, sendnow, GST_PAD_CAPS (auparse->srcpad),
hgs
parents:
diff changeset
   473
        &outbuf);
hgs
parents:
diff changeset
   474
hgs
parents:
diff changeset
   475
    if (ret != GST_FLOW_OK) {
hgs
parents:
diff changeset
   476
      GST_DEBUG_OBJECT (auparse, "pad alloc flow: %s", gst_flow_get_name (ret));
hgs
parents:
diff changeset
   477
      goto out;
hgs
parents:
diff changeset
   478
    }
hgs
parents:
diff changeset
   479
hgs
parents:
diff changeset
   480
    data = gst_adapter_peek (auparse->adapter, sendnow);
hgs
parents:
diff changeset
   481
    memcpy (GST_BUFFER_DATA (outbuf), data, sendnow);
hgs
parents:
diff changeset
   482
    gst_adapter_flush (auparse->adapter, sendnow);
hgs
parents:
diff changeset
   483
hgs
parents:
diff changeset
   484
    auparse->buffer_offset += sendnow;
hgs
parents:
diff changeset
   485
hgs
parents:
diff changeset
   486
    ret = gst_pad_push (auparse->srcpad, outbuf);
hgs
parents:
diff changeset
   487
  }
hgs
parents:
diff changeset
   488
hgs
parents:
diff changeset
   489
out:
hgs
parents:
diff changeset
   490
hgs
parents:
diff changeset
   491
  gst_object_unref (auparse);
hgs
parents:
diff changeset
   492
  return ret;
hgs
parents:
diff changeset
   493
}
hgs
parents:
diff changeset
   494
hgs
parents:
diff changeset
   495
static gboolean
hgs
parents:
diff changeset
   496
gst_au_parse_src_convert (GstAuParse * auparse, GstFormat src_format,
hgs
parents:
diff changeset
   497
    gint64 srcval, GstFormat dest_format, gint64 * destval)
hgs
parents:
diff changeset
   498
{
hgs
parents:
diff changeset
   499
  gboolean ret = TRUE;
hgs
parents:
diff changeset
   500
  guint samplesize, rate;
hgs
parents:
diff changeset
   501
hgs
parents:
diff changeset
   502
  if (dest_format == src_format) {
hgs
parents:
diff changeset
   503
    *destval = srcval;
hgs
parents:
diff changeset
   504
    return TRUE;
hgs
parents:
diff changeset
   505
  }
hgs
parents:
diff changeset
   506
hgs
parents:
diff changeset
   507
  GST_OBJECT_LOCK (auparse);
hgs
parents:
diff changeset
   508
  samplesize = auparse->sample_size;
hgs
parents:
diff changeset
   509
  rate = auparse->samplerate;
hgs
parents:
diff changeset
   510
  GST_OBJECT_UNLOCK (auparse);
hgs
parents:
diff changeset
   511
hgs
parents:
diff changeset
   512
  if (samplesize == 0 || rate == 0) {
hgs
parents:
diff changeset
   513
    GST_LOG_OBJECT (auparse, "cannot convert, sample_size or rate unknown");
hgs
parents:
diff changeset
   514
    return FALSE;
hgs
parents:
diff changeset
   515
  }
hgs
parents:
diff changeset
   516
hgs
parents:
diff changeset
   517
  switch (src_format) {
hgs
parents:
diff changeset
   518
    case GST_FORMAT_BYTES:
hgs
parents:
diff changeset
   519
      srcval /= samplesize;
hgs
parents:
diff changeset
   520
      /* fallthrough */
hgs
parents:
diff changeset
   521
    case GST_FORMAT_DEFAULT:{
hgs
parents:
diff changeset
   522
      switch (dest_format) {
hgs
parents:
diff changeset
   523
        case GST_FORMAT_BYTES:
hgs
parents:
diff changeset
   524
          *destval = srcval * samplesize;
hgs
parents:
diff changeset
   525
          break;
hgs
parents:
diff changeset
   526
        case GST_FORMAT_TIME:
hgs
parents:
diff changeset
   527
          *destval = gst_util_uint64_scale_int (srcval, GST_SECOND, rate);
hgs
parents:
diff changeset
   528
          break;
hgs
parents:
diff changeset
   529
        default:
hgs
parents:
diff changeset
   530
          ret = FALSE;
hgs
parents:
diff changeset
   531
          break;
hgs
parents:
diff changeset
   532
      }
hgs
parents:
diff changeset
   533
      break;
hgs
parents:
diff changeset
   534
    }
hgs
parents:
diff changeset
   535
    case GST_FORMAT_TIME:{
hgs
parents:
diff changeset
   536
      switch (dest_format) {
hgs
parents:
diff changeset
   537
        case GST_FORMAT_BYTES:
hgs
parents:
diff changeset
   538
          *destval =
hgs
parents:
diff changeset
   539
              gst_util_uint64_scale_int (srcval, rate * samplesize, GST_SECOND);
hgs
parents:
diff changeset
   540
          break;
hgs
parents:
diff changeset
   541
        case GST_FORMAT_DEFAULT:
hgs
parents:
diff changeset
   542
          *destval = gst_util_uint64_scale_int (srcval, rate, GST_SECOND);
hgs
parents:
diff changeset
   543
          break;
hgs
parents:
diff changeset
   544
        default:
hgs
parents:
diff changeset
   545
          ret = FALSE;
hgs
parents:
diff changeset
   546
          break;
hgs
parents:
diff changeset
   547
      }
hgs
parents:
diff changeset
   548
      break;
hgs
parents:
diff changeset
   549
    }
hgs
parents:
diff changeset
   550
    default:{
hgs
parents:
diff changeset
   551
      ret = FALSE;
hgs
parents:
diff changeset
   552
      break;
hgs
parents:
diff changeset
   553
    }
hgs
parents:
diff changeset
   554
  }
hgs
parents:
diff changeset
   555
hgs
parents:
diff changeset
   556
  if (!ret) {
hgs
parents:
diff changeset
   557
    GST_DEBUG_OBJECT (auparse, "could not convert from %s to %s format",
hgs
parents:
diff changeset
   558
        gst_format_get_name (src_format), gst_format_get_name (dest_format));
hgs
parents:
diff changeset
   559
  }
hgs
parents:
diff changeset
   560
hgs
parents:
diff changeset
   561
  return ret;
hgs
parents:
diff changeset
   562
}
hgs
parents:
diff changeset
   563
hgs
parents:
diff changeset
   564
static gboolean
hgs
parents:
diff changeset
   565
gst_au_parse_src_query (GstPad * pad, GstQuery * query)
hgs
parents:
diff changeset
   566
{
hgs
parents:
diff changeset
   567
  GstAuParse *auparse;
hgs
parents:
diff changeset
   568
  gboolean ret = FALSE;
hgs
parents:
diff changeset
   569
hgs
parents:
diff changeset
   570
  auparse = GST_AU_PARSE (gst_pad_get_parent (pad));
hgs
parents:
diff changeset
   571
hgs
parents:
diff changeset
   572
  switch (GST_QUERY_TYPE (query)) {
hgs
parents:
diff changeset
   573
    case GST_QUERY_DURATION:{
hgs
parents:
diff changeset
   574
      GstFormat bformat = GST_FORMAT_BYTES;
hgs
parents:
diff changeset
   575
      GstFormat format;
hgs
parents:
diff changeset
   576
      gint64 len, val;
hgs
parents:
diff changeset
   577
hgs
parents:
diff changeset
   578
      gst_query_parse_duration (query, &format, NULL);
hgs
parents:
diff changeset
   579
      if (!gst_pad_query_peer_duration (auparse->sinkpad, &bformat, &len)) {
hgs
parents:
diff changeset
   580
        GST_DEBUG_OBJECT (auparse, "failed to query upstream length");
hgs
parents:
diff changeset
   581
        break;
hgs
parents:
diff changeset
   582
      }
hgs
parents:
diff changeset
   583
      GST_OBJECT_LOCK (auparse);
hgs
parents:
diff changeset
   584
      len -= auparse->offset;
hgs
parents:
diff changeset
   585
      GST_OBJECT_UNLOCK (auparse);
hgs
parents:
diff changeset
   586
hgs
parents:
diff changeset
   587
      ret = gst_au_parse_src_convert (auparse, GST_FORMAT_BYTES, len,
hgs
parents:
diff changeset
   588
          format, &val);
hgs
parents:
diff changeset
   589
hgs
parents:
diff changeset
   590
      if (ret) {
hgs
parents:
diff changeset
   591
        gst_query_set_duration (query, format, val);
hgs
parents:
diff changeset
   592
      }
hgs
parents:
diff changeset
   593
      break;
hgs
parents:
diff changeset
   594
    }
hgs
parents:
diff changeset
   595
    case GST_QUERY_POSITION:{
hgs
parents:
diff changeset
   596
      GstFormat bformat = GST_FORMAT_BYTES;
hgs
parents:
diff changeset
   597
      GstFormat format;
hgs
parents:
diff changeset
   598
      gint64 pos, val;
hgs
parents:
diff changeset
   599
hgs
parents:
diff changeset
   600
      gst_query_parse_position (query, &format, NULL);
hgs
parents:
diff changeset
   601
      if (!gst_pad_query_peer_position (auparse->sinkpad, &bformat, &pos)) {
hgs
parents:
diff changeset
   602
        GST_DEBUG_OBJECT (auparse, "failed to query upstream position");
hgs
parents:
diff changeset
   603
        break;
hgs
parents:
diff changeset
   604
      }
hgs
parents:
diff changeset
   605
      GST_OBJECT_LOCK (auparse);
hgs
parents:
diff changeset
   606
      pos -= auparse->offset;
hgs
parents:
diff changeset
   607
      GST_OBJECT_UNLOCK (auparse);
hgs
parents:
diff changeset
   608
hgs
parents:
diff changeset
   609
      ret = gst_au_parse_src_convert (auparse, GST_FORMAT_BYTES, pos,
hgs
parents:
diff changeset
   610
          format, &val);
hgs
parents:
diff changeset
   611
hgs
parents:
diff changeset
   612
      if (ret) {
hgs
parents:
diff changeset
   613
        gst_query_set_position (query, format, val);
hgs
parents:
diff changeset
   614
      }
hgs
parents:
diff changeset
   615
      break;
hgs
parents:
diff changeset
   616
    }
hgs
parents:
diff changeset
   617
    default:
hgs
parents:
diff changeset
   618
      ret = gst_pad_query_default (pad, query);
hgs
parents:
diff changeset
   619
      break;
hgs
parents:
diff changeset
   620
  }
hgs
parents:
diff changeset
   621
hgs
parents:
diff changeset
   622
  gst_object_unref (auparse);
hgs
parents:
diff changeset
   623
  return ret;
hgs
parents:
diff changeset
   624
}
hgs
parents:
diff changeset
   625
hgs
parents:
diff changeset
   626
static gboolean
hgs
parents:
diff changeset
   627
gst_au_parse_handle_seek (GstAuParse * auparse, GstEvent * event)
hgs
parents:
diff changeset
   628
{
hgs
parents:
diff changeset
   629
  GstSeekType start_type, stop_type;
hgs
parents:
diff changeset
   630
  GstSeekFlags flags;
hgs
parents:
diff changeset
   631
  GstFormat format;
hgs
parents:
diff changeset
   632
  gdouble rate;
hgs
parents:
diff changeset
   633
  gint64 start, stop;
hgs
parents:
diff changeset
   634
hgs
parents:
diff changeset
   635
  gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start,
hgs
parents:
diff changeset
   636
      &stop_type, &stop);
hgs
parents:
diff changeset
   637
hgs
parents:
diff changeset
   638
  if (format != GST_FORMAT_TIME) {
hgs
parents:
diff changeset
   639
    GST_DEBUG_OBJECT (auparse, "only support seeks in TIME format");
hgs
parents:
diff changeset
   640
    return FALSE;
hgs
parents:
diff changeset
   641
  }
hgs
parents:
diff changeset
   642
hgs
parents:
diff changeset
   643
  /* FIXME: implement seeking */
hgs
parents:
diff changeset
   644
  return FALSE;
hgs
parents:
diff changeset
   645
}
hgs
parents:
diff changeset
   646
hgs
parents:
diff changeset
   647
static gboolean
hgs
parents:
diff changeset
   648
gst_au_parse_sink_event (GstPad * pad, GstEvent * event)
hgs
parents:
diff changeset
   649
{
hgs
parents:
diff changeset
   650
  GstAuParse *auparse;
hgs
parents:
diff changeset
   651
  gboolean ret;
hgs
parents:
diff changeset
   652
hgs
parents:
diff changeset
   653
  auparse = GST_AU_PARSE (gst_pad_get_parent (pad));
hgs
parents:
diff changeset
   654
hgs
parents:
diff changeset
   655
  switch (GST_EVENT_TYPE (event)) {
hgs
parents:
diff changeset
   656
    default:
hgs
parents:
diff changeset
   657
      ret = gst_pad_event_default (pad, event);
hgs
parents:
diff changeset
   658
      break;
hgs
parents:
diff changeset
   659
  }
hgs
parents:
diff changeset
   660
hgs
parents:
diff changeset
   661
  gst_object_unref (auparse);
hgs
parents:
diff changeset
   662
  return ret;
hgs
parents:
diff changeset
   663
}
hgs
parents:
diff changeset
   664
hgs
parents:
diff changeset
   665
static gboolean
hgs
parents:
diff changeset
   666
gst_au_parse_src_event (GstPad * pad, GstEvent * event)
hgs
parents:
diff changeset
   667
{
hgs
parents:
diff changeset
   668
  GstAuParse *auparse;
hgs
parents:
diff changeset
   669
  gboolean ret;
hgs
parents:
diff changeset
   670
hgs
parents:
diff changeset
   671
  auparse = GST_AU_PARSE (gst_pad_get_parent (pad));
hgs
parents:
diff changeset
   672
hgs
parents:
diff changeset
   673
  switch (GST_EVENT_TYPE (event)) {
hgs
parents:
diff changeset
   674
    case GST_EVENT_SEEK:
hgs
parents:
diff changeset
   675
      ret = gst_au_parse_handle_seek (auparse, event);
hgs
parents:
diff changeset
   676
      break;
hgs
parents:
diff changeset
   677
    default:
hgs
parents:
diff changeset
   678
      ret = gst_pad_event_default (pad, event);
hgs
parents:
diff changeset
   679
      break;
hgs
parents:
diff changeset
   680
  }
hgs
parents:
diff changeset
   681
hgs
parents:
diff changeset
   682
  gst_object_unref (auparse);
hgs
parents:
diff changeset
   683
  return ret;
hgs
parents:
diff changeset
   684
}
hgs
parents:
diff changeset
   685
hgs
parents:
diff changeset
   686
static GstStateChangeReturn
hgs
parents:
diff changeset
   687
gst_au_parse_change_state (GstElement * element, GstStateChange transition)
hgs
parents:
diff changeset
   688
{
hgs
parents:
diff changeset
   689
  GstAuParse *auparse = GST_AU_PARSE (element);
hgs
parents:
diff changeset
   690
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
hgs
parents:
diff changeset
   691
hgs
parents:
diff changeset
   692
  ret = parent_class->change_state (element, transition);
hgs
parents:
diff changeset
   693
  if (ret == GST_STATE_CHANGE_FAILURE)
hgs
parents:
diff changeset
   694
    return ret;
hgs
parents:
diff changeset
   695
hgs
parents:
diff changeset
   696
  switch (transition) {
hgs
parents:
diff changeset
   697
    case GST_STATE_CHANGE_PAUSED_TO_READY:
hgs
parents:
diff changeset
   698
      gst_au_parse_reset (auparse);
hgs
parents:
diff changeset
   699
    default:
hgs
parents:
diff changeset
   700
      break;
hgs
parents:
diff changeset
   701
  }
hgs
parents:
diff changeset
   702
hgs
parents:
diff changeset
   703
  return ret;
hgs
parents:
diff changeset
   704
}
hgs
parents:
diff changeset
   705
hgs
parents:
diff changeset
   706
static gboolean
hgs
parents:
diff changeset
   707
plugin_init (GstPlugin * plugin)
hgs
parents:
diff changeset
   708
{
hgs
parents:
diff changeset
   709
  if (!gst_element_register (plugin, "auparse", GST_RANK_SECONDARY,
hgs
parents:
diff changeset
   710
          GST_TYPE_AU_PARSE)) {
hgs
parents:
diff changeset
   711
    return FALSE;
hgs
parents:
diff changeset
   712
  }
hgs
parents:
diff changeset
   713
hgs
parents:
diff changeset
   714
  return TRUE;
hgs
parents:
diff changeset
   715
}
hgs
parents:
diff changeset
   716
hgs
parents:
diff changeset
   717
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
hgs
parents:
diff changeset
   718
    GST_VERSION_MINOR,
hgs
parents:
diff changeset
   719
    "auparse",
hgs
parents:
diff changeset
   720
    "parses au streams", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
hgs
parents:
diff changeset
   721
    GST_PACKAGE_ORIGIN)
hgs
parents:
diff changeset
   722
	
hgs
parents:
diff changeset
   723
EXPORT_C GstPluginDesc* _GST_PLUGIN_DESC()
hgs
parents:
diff changeset
   724
{
hgs
parents:
diff changeset
   725
	return &gst_plugin_desc;
hgs
parents:
diff changeset
   726
}