summaryrefslogtreecommitdiffstats
path: root/gst/mpegaudioparse
diff options
context:
space:
mode:
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>2003-10-01 13:14:50 +0000
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>2003-10-01 13:14:50 +0000
commitd9e4457faa360b470a5ae418e3444fccd6c0a5de (patch)
tree2a981bbe80d369449ad5d79e65ae7e766f1635ba /gst/mpegaudioparse
parentb569848e286b7435997a67e17fa0b21db892131d (diff)
downloadgst-plugins-bad-d9e4457faa360b470a5ae418e3444fccd6c0a5de.tar.gz
gst-plugins-bad-d9e4457faa360b470a5ae418e3444fccd6c0a5de.tar.bz2
gst-plugins-bad-d9e4457faa360b470a5ae418e3444fccd6c0a5de.zip
New typefind system: bytestream is now part of the core all plugins have been modified to use this new typefind syste...
Original commit message from CVS: New typefind system: * bytestream is now part of the core * all plugins have been modified to use this new typefind system * asf typefinding added * mpeg video stream typefiding removed because it's broken * duplicate typefind entries removed * extra id3 typefinding added, because we've seen 4 types of files (riff/wav, flac, vorbis, mp3) with id3 headers and each of these needs to work. Instead, I've added an id3 element and let it redo typefiding after the id3 header. this needs a hack because spider only typefinds once. We can remove this hack once spider supports multiple typefinds. * with all this, mp3 typefinding is semi-rewritten * id3 typefinding in flac/vorbis is removed, it's no longer needed * fixed spider and gst-typefind to use this, too. * Other general cleanups
Diffstat (limited to 'gst/mpegaudioparse')
-rw-r--r--gst/mpegaudioparse/Makefile.am10
-rw-r--r--gst/mpegaudioparse/gstmp3types.c251
-rw-r--r--gst/mpegaudioparse/gstmpegaudioparse.c288
3 files changed, 241 insertions, 308 deletions
diff --git a/gst/mpegaudioparse/Makefile.am b/gst/mpegaudioparse/Makefile.am
index ee22c43e..cb06727f 100644
--- a/gst/mpegaudioparse/Makefile.am
+++ b/gst/mpegaudioparse/Makefile.am
@@ -1,17 +1,9 @@
-#FIXME clean me up a bit
-
-plugin_LTLIBRARIES = libgstmpegaudioparse.la libgstmp3types.la
+plugin_LTLIBRARIES = libgstmpegaudioparse.la
libgstmpegaudioparse_la_SOURCES = gstmpegaudioparse.c
libgstmpegaudioparse_la_CFLAGS = $(GST_CFLAGS)
libgstmpegaudioparse_la_LIBADD =
libgstmpegaudioparse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-libgstmp3types_la_SOURCES = gstmp3types.c
-libgstmp3types_la_CFLAGS = $(GST_CFLAGS)
-libgstmp3types_la_LIBADD =
-libgstmp3types_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-
noinst_HEADERS = gstmpegaudioparse.h
EXTRA_DIST = README
-
diff --git a/gst/mpegaudioparse/gstmp3types.c b/gst/mpegaudioparse/gstmp3types.c
deleted file mode 100644
index cf5e860f..00000000
--- a/gst/mpegaudioparse/gstmp3types.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/*#define DEBUG_ENABLED */
-#include <gst/gst.h>
-#include <string.h> /* memcmp */
-
-static GstCaps* mp3_type_find(GstBuffer *buf, gpointer private);
-static GstCaps* mp3_type_find_stream(GstBuffer *buf, gpointer private);
-
-static GstTypeDefinition mp3type_definitions[] = {
- { "mp3types_audio/mpeg", "audio/mpeg", ".mp3 .mp2 .mp1 .mpga", mp3_type_find },
- { "mp3types_stream_audio/mpeg", "audio/mpeg", ".mp3 .mp2 .mp1 .mpga", mp3_type_find_stream },
- { NULL, NULL, NULL, NULL },
-};
-
-static GstCaps*
-mp3_type_find(GstBuffer *buf, gpointer private)
-{
- guint8 *data;
- gint size, layer;
- guint32 head;
- GstCaps *caps;
-
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
-
- GST_DEBUG ("mp3typefind: typefind");
-
- /* gracefully ripped from libid3 */
- if (size >= 3 &&
- data[0] == 'T' && data[1] == 'A' && data[2] == 'G') {
- /* ID V1 tags */
- data += 128;
- size -= 128;
-
- GST_DEBUG ("mp3typefind: detected ID3 Tag V1");
- } else if (size >= 10 &&
- (data[0] == 'I' && data[1] == 'D' && data[2] == '3') &&
- data[3] < 0xff && data[4] < 0xff &&
- data[6] < 0x80 && data[7] < 0x80 && data[8] < 0x80 && data[9] < 0x80)
- {
- guint32 skip = 0;
-
- skip = (skip << 7) | (data[6] & 0x7f);
- skip = (skip << 7) | (data[7] & 0x7f);
- skip = (skip << 7) | (data[8] & 0x7f);
- skip = (skip << 7) | (data[9] & 0x7f);
-
- /* include size of header */
- skip += 10;
- /* footer present? (only available since version 4) */
- if (data[3] > 3 && (data[5] & 0x10))
- skip += 10;
-
- GST_DEBUG ("mp3typefind: detected ID3 Tag V2 with %u bytes", skip);
- size -= skip;
- data += skip;
- }
-
- if (size < 4)
- return NULL;
-
- /* now with the right postion, do typefinding */
- head = GUINT32_FROM_BE(*((guint32 *)data));
- if ((head & 0xffe00000) != 0xffe00000)
- return NULL;
- if (!(layer = ((head >> 17) & 3)))
- return NULL;
- layer = 4 - layer;
- if (((head >> 12) & 0xf) == 0xf)
- return NULL;
- if (!((head >> 12) & 0xf))
- return NULL;
- if (((head >> 10) & 0x3) == 0x3)
- return NULL;
-
- caps = GST_CAPS_NEW ("mp3_type_find", "audio/mpeg", "layer", GST_PROPS_INT (layer));
-
- return caps;
-}
-static guint mp3types_bitrates[2][3][16] =
-{ { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, },
- {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, },
- {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, } },
- { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, },
- {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, },
- {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, } },
-};
-static guint mp3types_freqs[3][3] =
-{ {44100, 48000, 32000},
- {22050, 24000, 16000},
- {11025, 12000, 8000}};
-static inline guint
-mp3_type_frame_length_from_header (guint32 header, guint *put_layer)
-{
- guint length;
- gulong samplerate, bitrate, layer, version;
-
- /* we don't need extension, mode, copyright, original or emphasis for the frame length */
- header >>= 9;
- /* padding */
- length = header & 0x1;
- header >>= 1;
- /* sampling frequency */
- samplerate = header & 0x3;
- if (samplerate == 3)
- return 0;
- header >>= 2;
- /* bitrate index */
- bitrate = header & 0xF;
- if (bitrate == 15 || bitrate == 0)
- return 0;
- /* ignore error correction, too */
- header >>= 5;
- /* layer */
- layer = 4 - (header & 0x3);
- if (layer == 4)
- return 0;
- header >>= 2;
- /* version */
- version = header & 0x3;
- if (version == 1)
- return 0;
- /* lookup */
- bitrate = mp3types_bitrates[version == 3 ? 0 : 1][layer - 1][bitrate];
- samplerate = mp3types_freqs[version > 0 ? version - 1 : 0][samplerate];
- /* calculating */
- if (layer == 1) {
- length = ((12000 * bitrate / samplerate) + length) * 4;
- } else {
- length += ((layer == 3 && version == 0) ? 144000 : 72000) * bitrate / samplerate;
- }
-
- GST_DEBUG ("Calculated mad frame length of %u bytes", length);
- GST_DEBUG ("samplerate = %lu - bitrate = %lu - layer = %lu - version = %lu", samplerate, bitrate, layer, version);
- if (put_layer)
- *put_layer = layer;
- return length;
-}
-/* increase this value when this function finds too many false positives */
-/**
- * The chance that random data is identified as a valid mp3 header is 63 / 2^18
- * (0.024%) per try. This makes the function for calculating false positives
- * 1 - (1 - ((63 / 2 ^18) ^ GST_MP3_TYPEFIND_MIN_HEADERS)) ^ buffersize)
- * This has the following probabilities of false positives:
- * bufsize MIN_HEADERS
- * (bytes) 1 2 3 4
- * 4096 62.6% 0.02% 0% 0%
- * 16384 98% 0.09% 0% 0%
- * 1 MiB 100% 5.88% 0% 0%
- * 1 GiB 100% 100% 1.44% 0%
- * 1 TiB 100% 100% 100% 0.35%
- * This means that the current choice (3 headers by most of the time 4096 byte
- * buffers is pretty safe for now.
- * It is however important to note that in a worst case example a buffer of size
- * 1440 * GST_MP3_TYPEFIND_MIN_HEADERS + 3
- * bytes is needed to reliable find the mp3 stream in a buffer when scanning
- * starts at a random position. This is currently (4323 bytes) slightly above
- * the default buffer size. But you rarely hit the worst case - average mp3
- * frames are in the 500 bytes range.
- */
-#define GST_MP3_TYPEFIND_MIN_HEADERS 3
-static GstCaps*
-mp3_type_find_stream (GstBuffer *buf, gpointer private)
-{
- guint8 *data;
- guint size;
- guint32 head;
- gint layer = 0;
-
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
-
- while (size >= 4) {
- head = GUINT32_FROM_BE(*((guint32 *)data));
- if ((head & 0xffe00000) == 0xffe00000) {
- guint length;
- guint prev_layer = 0;
- guint found = 0; /* number of valid headers found */
- guint pos = 0;
- do {
- if ((length = mp3_type_frame_length_from_header (head, &layer))) {
- if (prev_layer && prev_layer != layer)
- break;
- prev_layer = layer;
- pos += length;
- found++;
- if (pos + 4 >= size) {
- if (found >= GST_MP3_TYPEFIND_MIN_HEADERS)
- goto success;
- }
- head = GUINT32_FROM_BE(*((guint32 *) &(data[pos])));
- if ((head & 0xffe00000) != 0xffe00000)
- break;
- } else {
- break;
- }
- } while (TRUE);
- }
- data++;
- size--;
- }
-
- return NULL;
-
-success:
- g_assert (layer);
- return GST_CAPS_NEW ("mp3_type_find", "audio/mpeg", "layer", GST_PROPS_INT (layer));
-}
-
-static gboolean
-plugin_init (GModule *module, GstPlugin *plugin)
-{
- gint i=0;
-
- while (mp3type_definitions[i].name) {
- GstTypeFactory *type;
-
- type = gst_type_factory_new (&mp3type_definitions[i]);
- gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
- i++;
- }
-
- /* gst_info("gsttypes: loaded %d mp3 types\n",i); */
-
- return TRUE;
-}
-
-GstPluginDesc plugin_desc = {
- GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "mp3types",
- plugin_init
-};
diff --git a/gst/mpegaudioparse/gstmpegaudioparse.c b/gst/mpegaudioparse/gstmpegaudioparse.c
index ba207c0e..920ab22c 100644
--- a/gst/mpegaudioparse/gstmpegaudioparse.c
+++ b/gst/mpegaudioparse/gstmpegaudioparse.c
@@ -35,6 +35,15 @@ static GstElementDetails mp3parse_details = {
"(C) 1999",
};
+static GstCaps * mp3_type_find (GstByteStream *bs, gpointer data);
+
+static GstTypeDefinition mp3type_definition = {
+ "mp3_audio/mpeg",
+ "audio/mpeg",
+ ".mp3 .mp2 .mp1 .mpga",
+ mp3_type_find,
+};
+
static GstPadTemplate*
mp3_src_factory (void)
{
@@ -115,11 +124,221 @@ gst_mp3parse_get_type(void) {
0,
(GInstanceInitFunc)gst_mp3parse_init,
};
- mp3parse_type = g_type_register_static(GST_TYPE_ELEMENT, "GstMPEGAudioParse", &mp3parse_info, 0);
+ mp3parse_type = g_type_register_static (GST_TYPE_ELEMENT,
+ "GstMPEGAudioParse",
+ &mp3parse_info, 0);
}
return mp3parse_type;
}
+static guint mp3types_bitrates[2][3][16] =
+{ { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, },
+ {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, },
+ {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, } },
+ { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, },
+ {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, },
+ {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, } },
+};
+
+static guint mp3types_freqs[3][3] =
+{ {44100, 48000, 32000},
+ {22050, 24000, 16000},
+ {11025, 12000, 8000}};
+
+static inline guint
+mp3_type_frame_length_from_header (guint32 header, guint *put_layer,
+ guint *put_channels, guint *put_bitrate,
+ guint *put_samplerate)
+{
+ guint length;
+ gulong mode, samplerate, bitrate, layer, version, channels;
+
+ /* we don't need extension, copyright, original or
+ * emphasis for the frame length */
+ header >>= 6;
+
+ /* mode */
+ mode = header & 0x3;
+ header >>= 3;
+
+ /* padding */
+ length = header & 0x1;
+ header >>= 1;
+
+ /* sampling frequency */
+ samplerate = header & 0x3;
+ if (samplerate == 3)
+ return 0;
+ header >>= 2;
+
+ /* bitrate index */
+ bitrate = header & 0xF;
+ if (bitrate == 15 || bitrate == 0)
+ return 0;
+
+ /* ignore error correction, too */
+ header >>= 5;
+
+ /* layer */
+ layer = 4 - (header & 0x3);
+ if (layer == 4)
+ return 0;
+ header >>= 2;
+
+ /* version */
+ version = header & 0x3;
+ if (version == 1)
+ return 0;
+
+ /* lookup */
+ channels = (mode == 3) ? 1 : 2;
+ bitrate = mp3types_bitrates[version == 3 ? 0 : 1][layer - 1][bitrate];
+ samplerate = mp3types_freqs[version > 0 ? version - 1 : 0][samplerate];
+
+ /* calculating */
+ if (layer == 1) {
+ length = ((12000 * bitrate / samplerate) + length) * 4;
+ } else {
+ length += ((layer == 3 && version == 0) ? 144000 : 72000) * bitrate / samplerate;
+ }
+
+ GST_DEBUG ("Calculated mp3 frame length of %u bytes", length);
+ GST_DEBUG ("samplerate = %lu - bitrate = %lu - layer = %lu - version = %lu"
+ " - channels = %lu",
+ samplerate, bitrate, layer, version, channels);
+
+ if (put_layer)
+ *put_layer = layer;
+ if (put_channels)
+ *put_channels = channels;
+ if (put_bitrate)
+ *put_bitrate = bitrate;
+ if (put_samplerate)
+ *put_samplerate = samplerate;
+
+ return length;
+}
+
+/**
+ * The chance that random data is identified as a valid mp3 header is 63 / 2^18
+ * (0.024%) per try. This makes the function for calculating false positives
+ * 1 - (1 - ((63 / 2 ^18) ^ GST_MP3_TYPEFIND_MIN_HEADERS)) ^ buffersize)
+ * This has the following probabilities of false positives:
+ * bufsize MIN_HEADERS
+ * (bytes) 1 2 3 4
+ * 4096 62.6% 0.02% 0% 0%
+ * 16384 98% 0.09% 0% 0%
+ * 1 MiB 100% 5.88% 0% 0%
+ * 1 GiB 100% 100% 1.44% 0%
+ * 1 TiB 100% 100% 100% 0.35%
+ * This means that the current choice (3 headers by most of the time 4096 byte
+ * buffers is pretty safe for now.
+ *
+ * The max. size of each frame is 1440 bytes, which means that for N frames
+ * to be detected, we need 1440 * GST_MP3_TYPEFIND_MIN_HEADERS + 3 of data.
+ * Assuming we step into the stream right after the frame header, this
+ * means we need 1440 * (GST_MP3_TYPEFIND_MIN_HEADERS + 1) - 1 + 3 bytes
+ * of data (5762) to always detect any mp3.
+ */
+
+/* increase this value when this function finds too many false positives */
+#define GST_MP3_TYPEFIND_MIN_HEADERS 3
+#define GST_MP3_TYPEFIND_MIN_DATA (1440 * (GST_MP3_TYPEFIND_MIN_HEADERS + 1) - 1 + 3)
+
+static GstCaps *
+mp3_caps_create (guint layer, guint channels,
+ guint bitrate, guint samplerate)
+{
+ GstCaps *new;
+
+ g_assert (layer);
+ g_assert (samplerate);
+ g_assert (bitrate);
+ g_assert (channels);
+
+ new = GST_CAPS_NEW ("mp3_type_find",
+ "audio/mpeg",
+ "mpegversion", GST_PROPS_INT (1),
+ "layer", GST_PROPS_INT (layer),
+ /*"bitrate", GST_PROPS_INT (bitrate),*/
+ "rate", GST_PROPS_INT (samplerate),
+ "channels", GST_PROPS_INT (channels));
+
+ return new;
+}
+
+static GstCaps *
+mp3_type_find (GstByteStream *bs, gpointer private)
+{
+ GstBuffer *buf = NULL;
+ GstCaps *new = NULL;
+ guint8 *data;
+ guint size;
+ guint32 head;
+ guint layer = 0, bitrate = 0, samplerate = 0, channels = 0;
+
+ /* note that even if we don't get the requested size,
+ * it might still be a (very small) mp3 */
+ gst_bytestream_peek (bs, &buf, GST_MP3_TYPEFIND_MIN_DATA);
+ if (!buf) {
+ goto done;
+ }
+
+ data = GST_BUFFER_DATA (buf);
+ size = GST_BUFFER_SIZE (buf);
+
+ while (size >= 4) {
+ head = GUINT32_FROM_BE(*((guint32 *)data));
+ if ((head & 0xffe00000) == 0xffe00000) {
+ guint length;
+ guint prev_layer = 0, prev_bitrate = 0,
+ prev_channels = 0, prev_samplerate = 0;
+ guint found = 0; /* number of valid headers found */
+ guint pos = 0;
+
+ do {
+ if (!(length = mp3_type_frame_length_from_header (head, &layer,
+ &channels, &bitrate,
+ &samplerate))) {
+ break;
+ }
+ if ((prev_layer && prev_layer != layer) || !layer ||
+ (prev_bitrate && prev_bitrate != bitrate) || !bitrate ||
+ (prev_samplerate && prev_samplerate != samplerate) || !samplerate ||
+ (prev_channels && prev_channels != channels) || !channels) {
+ /* this means an invalid property, or a change, which likely
+ * indicates that this is not a mp3 but just a random bytestream */
+ break;
+ }
+ prev_layer = layer;
+ prev_bitrate = bitrate;
+ prev_channels = channels;
+ prev_samplerate = samplerate;
+ pos += length;
+ if (++found >= GST_MP3_TYPEFIND_MIN_HEADERS) {
+ /* we're pretty sure that this is mp3 now */
+ new = mp3_caps_create (layer, channels, bitrate, samplerate);
+ goto done;
+ }
+
+ /* and now, find a new head */
+ head = GUINT32_FROM_BE(*((guint32 *) &(data[pos])));
+ if ((head & 0xffe00000) != 0xffe00000)
+ break;
+ } while (TRUE);
+ }
+ data++;
+ size--;
+ }
+
+done:
+ if (buf != NULL) {
+ gst_buffer_unref (buf);
+ }
+
+ return new;
+}
+
static void
gst_mp3parse_class_init (GstMPEGAudioParseClass *klass)
{
@@ -247,7 +466,10 @@ gst_mp3parse_chain (GstPad *pad, GstBuffer *buf)
header2 = GUINT32_FROM_BE(*((guint32 *)(data+offset+bpf)));
GST_DEBUG ("mp3parse: header=%08X, header2=%08X, bpf=%d", (unsigned int)header, (unsigned int)header2, bpf );
- #define HDRMASK ~( (0xF<<12)/*bitrate*/ | (1<<9)/*padding*/ | (3<<4)/*mode extension*/ ) /* mask the bits which are allowed to differ between frames */
+/* mask the bits which are allowed to differ between frames */
+#define HDRMASK ~((0xF << 12) /* bitrate */ | \
+ (0x1 << 9) /* padding */ | \
+ (0x3 << 4)) /*mode extension*/
if ( (header2&HDRMASK) != (header&HDRMASK) ) { /* require 2 matching headers in a row */
GST_DEBUG ("mp3parse: next header doesn't match (header=%08X, header2=%08X, bpf=%d)", (unsigned int)header, (unsigned int)header2, bpf );
@@ -309,56 +531,23 @@ gst_mp3parse_chain (GstPad *pad, GstBuffer *buf)
}
}
-static int mp3parse_tabsel[2][3][16] =
-{ { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, },
- {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, },
- {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, } },
- { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, },
- {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, },
- {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, } },
-};
-
-static long mp3parse_freqs[9] =
-{44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000};
-
-
static long
bpf_from_header (GstMPEGAudioParse *parse, unsigned long header)
{
- int layer_index,layer,lsf,samplerate_index,padding,mode;
- long bpf;
- gint channels, rate;
-
- /*mpegver = (header >> 19) & 0x3; // don't need this for bpf */
- layer_index = (header >> 17) & 0x3;
- layer = 4 - layer_index;
- lsf = (header & (1 << 20)) ? ((header & (1 << 19)) ? 0 : 1) : 1;
- parse->bit_rate = mp3parse_tabsel[lsf][layer - 1][((header >> 12) & 0xf)];
- samplerate_index = (header >> 10) & 0x3;
- padding = (header >> 9) & 0x1;
- mode = (header >> 6) & 0x3;
+ guint bitrate, layer, rate, channels, length;
- if (layer == 1) {
- bpf = parse->bit_rate * 12000;
- bpf /= mp3parse_freqs[samplerate_index];
- bpf = ((bpf + padding) << 2);
- } else {
- bpf = parse->bit_rate * 144000;
- bpf /= mp3parse_freqs[samplerate_index];
- bpf += padding;
+ if (!(length = mp3_type_frame_length_from_header (header, &layer,
+ &channels,
+ &bitrate, &rate))) {
+ return 0;
}
- channels = (mode == 3) ? 1 : 2;
- rate = mp3parse_freqs[samplerate_index];
if (channels != parse->channels ||
rate != parse->rate ||
- layer != parse->layer) {
- GstCaps *caps = GST_CAPS_NEW ("mp3parse_src",
- "audio/mpeg",
- "mpegversion", GST_PROPS_INT (1),
- "layer", GST_PROPS_INT (layer),
- "channels", GST_PROPS_INT (channels),
- "rate", GST_PROPS_INT (rate));
+ layer != parse->layer ||
+ bitrate != parse->bit_rate) {
+ GstCaps *caps = mp3_caps_create (layer, channels, bitrate, rate);
+
if (gst_pad_try_set_caps(parse->srcpad, caps) <= 0) {
gst_element_error (GST_ELEMENT (parse),
"mp3parse: failed to negotiate format with next element");
@@ -367,12 +556,10 @@ bpf_from_header (GstMPEGAudioParse *parse, unsigned long header)
parse->channels = channels;
parse->layer = layer;
parse->rate = rate;
+ parse->bit_rate = bitrate;
}
- /*g_print("%08x: layer %d lsf %d bitrate %d samplerate_index %d padding %d - bpf %d\n", */
-/*header,layer,lsf,bitrate,samplerate_index,padding,bpf); */
-
- return bpf;
+ return length;
}
static gboolean
@@ -470,6 +657,7 @@ static gboolean
plugin_init (GModule *module, GstPlugin *plugin)
{
GstElementFactory *factory;
+ GstTypeFactory *type;
/* create an elementfactory for the mp3parse element */
factory = gst_element_factory_new ("mp3parse",
@@ -485,6 +673,10 @@ plugin_init (GModule *module, GstPlugin *plugin)
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+ /* type finding */
+ type = gst_type_factory_new (&mp3type_definition);
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
+
return TRUE;
}