Remove audioparsers plugin, it has been moved to -good

This commit is contained in:
Tim-Philipp Müller 2011-04-08 19:32:31 +01:00
parent a7cbd201b1
commit 9bfac61f97
29 changed files with 3 additions and 6841 deletions

View file

@ -49,6 +49,7 @@ CRUFT_FILES = \
$(top_builddir)/ext/jack/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/aacparse/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/amrparse/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/audioparsers/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/flacparse/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/imagefreeze/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/selector/.libs/*.{so,dll,DLL,dylib} \
@ -56,6 +57,7 @@ CRUFT_FILES = \
$(top_builddir)/gst/valve/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/gst/videoparsers/.libs/libgsth263parse* \
$(top_builddir)/sys/oss4/.libs/*.{so,dll,DLL,dylib} \
$(top_builddir)/tests/check/elements/{aac,ac3,amr,flac,mpegaudio,dca}parse \
$(top_builddir)/tests/check/elements/autocolorspace \
$(top_builddir)/tests/check/elements/capssetter \
$(top_builddir)/tests/check/elements/imagefreeze \

View file

@ -1,48 +0,0 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
aacparse_LOCAL_SRC_FILES:= \
gst/aacparse/gstaacparse.c \
gst/aacparse/gstbaseparse.c
LOCAL_SRC_FILES:= $(addprefix ../,$(aacparse_LOCAL_SRC_FILES))
LOCAL_SHARED_LIBRARIES := \
libgstreamer-0.10 \
libgstbase-0.10 \
libglib-2.0 \
libgthread-2.0 \
libgmodule-2.0 \
libgobject-2.0 \
libgstinterfaces-0.10
LOCAL_MODULE:= libgstaacparse
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/.. \
$(LOCAL_PATH)/../gst-libs \
$(LOCAL_PATH) \
$(TARGET_OUT_HEADERS)/gstreamer-0.10 \
$(TARGET_OUT_HEADERS)/glib-2.0 \
$(TARGET_OUT_HEADERS)/glib-2.0/glib \
external/libxml2/include
ifeq ($(STECONF_ANDROID_VERSION),"FROYO")
LOCAL_SHARED_LIBRARIES += libicuuc
LOCAL_C_INCLUDES += external/icu4c/common
endif
LOCAL_CFLAGS := -DHAVE_CONFIG_H
#
# define LOCAL_PRELINK_MODULE to false to not use pre-link map
#
LOCAL_PRELINK_MODULE := false
#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.10
LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.10
include $(BUILD_SHARED_LIBRARY)

View file

@ -1,48 +0,0 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
amrparse_LOCAL_SRC_FILES:= \
gst/amrparse/gstamrparse.c \
gst/amrparse/gstbaseparse.c
LOCAL_SRC_FILES:= $(addprefix ../,$(amrparse_LOCAL_SRC_FILES))
LOCAL_SHARED_LIBRARIES := \
libgstreamer-0.10 \
libgstbase-0.10 \
libglib-2.0 \
libgthread-2.0 \
libgmodule-2.0 \
libgobject-2.0
LOCAL_MODULE:= libgstamrparse
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../ext/amrwbenc \
$(LOCAL_PATH)/.. \
$(LOCAL_PATH)/../gst-libs \
$(LOCAL_PATH) \
$(TARGET_OUT_HEADERS)/gstreamer-0.10 \
$(TARGET_OUT_HEADERS)/glib-2.0 \
$(TARGET_OUT_HEADERS)/glib-2.0/glib \
external/libxml2/include
ifeq ($(STECONF_ANDROID_VERSION),"FROYO")
LOCAL_SHARED_LIBRARIES += libicuuc
LOCAL_C_INCLUDES += external/icu4c/common
endif
LOCAL_CFLAGS := -DHAVE_CONFIG_H
#
# define LOCAL_PRELINK_MODULE to false to not use pre-link map
#
LOCAL_PRELINK_MODULE := false
#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.10
LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.10
include $(BUILD_SHARED_LIBRARY)

View file

@ -291,7 +291,6 @@ AG_GST_CHECK_PLUGIN(adpcmdec)
AG_GST_CHECK_PLUGIN(adpcmenc)
AG_GST_CHECK_PLUGIN(aiff)
AG_GST_CHECK_PLUGIN(asfmux)
AG_GST_CHECK_PLUGIN(audioparsers)
AG_GST_CHECK_PLUGIN(autoconvert)
AG_GST_CHECK_PLUGIN(bayer)
AG_GST_CHECK_PLUGIN(camerabin)
@ -1742,7 +1741,6 @@ gst/adpcmdec/Makefile
gst/adpcmenc/Makefile
gst/aiff/Makefile
gst/asfmux/Makefile
gst/audioparsers/Makefile
gst/autoconvert/Makefile
gst/bayer/Makefile
gst/camerabin/Makefile

View file

@ -136,12 +136,6 @@ EXTRA_HFILES = \
$(top_srcdir)/ext/zbar/gstzbar.h \
$(top_srcdir)/gst/aiff/aiffparse.h \
$(top_srcdir)/gst/aiff/aiffmux.h \
$(top_srcdir)/gst/audioparsers/gstaacparse.h \
$(top_srcdir)/gst/audioparsers/gstac3parse.h \
$(top_srcdir)/gst/audioparsers/gstamrparse.h \
$(top_srcdir)/gst/audioparsers/gstflacparse.h \
$(top_srcdir)/gst/audioparsers/gstdcaparse.h \
$(top_srcdir)/gst/audioparsers/gstmpegaudioparse.h \
$(top_srcdir)/gst/autoconvert/gstautoconvert.h \
$(top_srcdir)/gst/camerabin/gstcamerabin.h \
$(top_srcdir)/gst/coloreffects/gstcoloreffects.h \

View file

@ -17,11 +17,8 @@
<chapter>
<title>gst-plugins-bad Elements</title>
<xi:include href="xml/element-aacparse.xml" />
<xi:include href="xml/element-ac3parse.xml" />
<xi:include href="xml/element-aiffparse.xml" />
<xi:include href="xml/element-aiffmux.xml" />
<xi:include href="xml/element-amrparse.xml" />
<xi:include href="xml/element-amrwbenc.xml" />
<xi:include href="xml/element-assrender.xml" />
<xi:include href="xml/element-autoconvert.xml" />
@ -42,7 +39,6 @@
<xi:include href="xml/element-cvsobel.xml" />
<xi:include href="xml/element-dataurisrc.xml" />
<!--xi:include href="xml/element-dc1394.xml" /-->
<xi:include href="xml/element-dcaparse.xml" />
<xi:include href="xml/element-dccpclientsink.xml" />
<xi:include href="xml/element-dccpclientsrc.xml" />
<xi:include href="xml/element-dccpserversink.xml" />
@ -65,7 +61,6 @@
<xi:include href="xml/element-facedetect.xml" />
<xi:include href="xml/element-festival.xml" />
<xi:include href="xml/element-fisheye.xml" />
<xi:include href="xml/element-flacparse.xml" />
<xi:include href="xml/element-fpsdisplaysink.xml" />
<xi:include href="xml/element-freeze.xml" />
<xi:include href="xml/element-gaussianblur.xml" />
@ -84,7 +79,6 @@
<xi:include href="xml/element-mimdec.xml" />
<xi:include href="xml/element-mirror.xml" />
<xi:include href="xml/element-modplug.xml" />
<xi:include href="xml/element-mpegaudioparse.xml" />
<xi:include href="xml/element-mpeg2enc.xml" />
<xi:include href="xml/element-mplex.xml" />
<xi:include href="xml/element-mythtvsrc.xml" />
@ -135,7 +129,6 @@
<chapter>
<title>gst-plugins-bad Plugins</title>
<xi:include href="xml/plugin-aiff.xml" />
<xi:include href="xml/plugin-audioparsersbad.xml" />
<xi:include href="xml/plugin-autoconvert.xml" />
<xi:include href="xml/plugin-legacyresample.xml" />
<xi:include href="xml/plugin-amrwbenc.xml" />

View file

@ -1,31 +1,3 @@
<SECTION>
<FILE>element-aacparse</FILE>
<TITLE>aacparse</TITLE>
GstAacParse
<SUBSECTION Standard>
GstAacParseClass
GST_AACPARSE
GST_AACPARSE_CLASS
GST_IS_AACPARSE
GST_IS_AACPARSE_CLASS
GST_TYPE_AACPARSE
gst_aacparse_get_type
</SECTION>
<SECTION>
<FILE>element-ac3parse</FILE>
<TITLE>ac3parse</TITLE>
GstAc3Parse
<SUBSECTION Standard>
GstAc3ParseClass
GST_AC3_PARSE
GST_AC3_PARSE_CLASS
GST_IS_AC3_PARSE
GST_IS_AC3_PARSE_CLASS
GST_TYPE_AC3_PARSE
gst_ac3_parse_get_type
</SECTION>
<SECTION>
<FILE>element-aiffmux</FILE>
<TITLE>aiffmux</TITLE>
@ -55,20 +27,6 @@ GstAiffParseState
gst_aiff_parse_get_type
</SECTION>
<SECTION>
<FILE>element-amrparse</FILE>
<TITLE>amrparse</TITLE>
GstAmrParse
<SUBSECTION Standard>
GstAmrParseClass
GST_AMRPARSE
GST_AMRPARSE_CLASS
GST_IS_AMRPARSE
GST_IS_AMRPARSE_CLASS
GST_TYPE_AMRPARSE
gst_amrparse_get_type
</SECTION>
<SECTION>
<FILE>element-amrwbenc</FILE>
<TITLE>amrwbenc</TITLE>
@ -377,20 +335,6 @@ GST_TYPE_DC1394
gst_dc1394_get_type
</SECTION>
<SECTION>
<FILE>element-dcaparse</FILE>
<TITLE>dcaparse</TITLE>
GstDCAParse
<SUBSECTION Standard>
GstDCAParseClass
GST_DCA_PARSE
GST_DCA_PARSE_CLASS
GST_IS_DCA_PARSE
GST_IS_DCA_PARSE_CLASS
GST_TYPE_DCA_PARSE
gst_dca_parse_get_type
</SECTION>
<SECTION>
<FILE>element-dccpclientsink</FILE>
<TITLE>dccpclientsink</TITLE>
@ -751,20 +695,6 @@ gst_fisheye_get_type
gst_fisheye_plugin_init
</SECTION>
<SECTION>
<FILE>element-flacparse</FILE>
<TITLE>flacparse</TITLE>
GstFlacParse
<SUBSECTION Standard>
GstFlacParseClass
GST_FLAC_PARSE
GST_FLAC_PARSE_CLASS
GST_IS_FLAC_PARSE
GST_IS_FLAC_PARSE_CLASS
GST_TYPE_FLAC_PARSE
gst_flac_parse_get_type
</SECTION>
<SECTION>
<FILE>element-fpsdisplaysink</FILE>
<TITLE>fpsdisplaysink</TITLE>
@ -1034,20 +964,6 @@ GST_TYPE_MODPLUG
gst_modplug_get_type
</SECTION>
<SECTION>
<FILE>element-mpegaudioparse</FILE>
<TITLE>mpegaudioparse</TITLE>
GstMpegAudioParse
<SUBSECTION Standard>
GstMpegAudioParseClass
GST_MPEG_AUDIO_PARSE
GST_MPEG_AUDIO_PARSE_CLASS
GST_IS_MPEG_AUDIO_PARSE
GST_IS_MPEG_AUDIO_PARSE_CLASS
GST_TYPE_MPEG_AUDIO_PARSE
gst_mpeg_audio_parse_get_type
</SECTION>
<SECTION>
<FILE>element-mpeg2enc</FILE>
<TITLE>mpeg2enc</TITLE>

View file

@ -1,139 +0,0 @@
<plugin>
<name>audioparsersbad</name>
<description>audioparsers</description>
<filename>../../gst/audioparsers/.libs/libgstaudioparsersbad.so</filename>
<basename>libgstaudioparsersbad.so</basename>
<version>0.10.21.1</version>
<license>LGPL</license>
<source>gst-plugins-bad</source>
<package>GStreamer Bad Plug-ins git</package>
<origin>Unknown package origin</origin>
<elements>
<element>
<name>aacparse</name>
<longname>AAC audio stream parser</longname>
<class>Codec/Parser/Audio</class>
<description>Advanced Audio Coding parser</description>
<author>Stefan Kost &lt;stefan.kost@nokia.com&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/mpeg, framed=(boolean)false, mpegversion=(int){ 2, 4 }</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>audio/mpeg, framed=(boolean)true, mpegversion=(int){ 2, 4 }, stream-format=(string){ raw, adts, adif }</details>
</caps>
</pads>
</element>
<element>
<name>ac3parse</name>
<longname>AC3 audio stream parser</longname>
<class>Codec/Parser/Audio</class>
<description>AC3 parser</description>
<author>Tim-Philipp Müller &lt;tim centricular net&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/x-ac3, framed=(boolean)false; audio/x-eac3, framed=(boolean)false; audio/ac3, framed=(boolean)false</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>audio/x-ac3, framed=(boolean)true, channels=(int)[ 1, 6 ], rate=(int)[ 32000, 48000 ]; audio/x-eac3, framed=(boolean)true, channels=(int)[ 1, 6 ], rate=(int)[ 32000, 48000 ]</details>
</caps>
</pads>
</element>
<element>
<name>amrparse</name>
<longname>AMR audio stream parser</longname>
<class>Codec/Parser/Audio</class>
<description>Adaptive Multi-Rate audio parser</description>
<author>Ronald Bultje &lt;rbultje@ronald.bitfreak.net&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/x-amr-nb-sh; audio/x-amr-wb-sh</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>audio/AMR, rate=(int)8000, channels=(int)1; audio/AMR-WB, rate=(int)16000, channels=(int)1</details>
</caps>
</pads>
</element>
<element>
<name>dcaparse</name>
<longname>DTS Coherent Acoustics audio stream parser</longname>
<class>Codec/Parser/Audio</class>
<description>DCA parser</description>
<author>Tim-Philipp Müller &lt;tim centricular net&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/x-dts, framed=(boolean)false</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>audio/x-dts, framed=(boolean)true, channels=(int)[ 1, 8 ], rate=(int)[ 8000, 192000 ]</details>
</caps>
</pads>
</element>
<element>
<name>flacparse</name>
<longname>FLAC audio parser</longname>
<class>Codec/Parser/Audio</class>
<description>Parses audio with the FLAC lossless audio codec</description>
<author>Sebastian Dröge &lt;sebastian.droege@collabora.co.uk&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/x-flac, framed=(boolean)false</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>audio/x-flac, framed=(boolean)true, channels=(int)[ 1, 8 ], rate=(int)[ 1, 655350 ]</details>
</caps>
</pads>
</element>
<element>
<name>mpegaudioparse</name>
<longname>MPEG1 Audio Parser</longname>
<class>Codec/Parser/Audio</class>
<description>Parses and frames mpeg1 audio streams (levels 1-3), provides seek</description>
<author>Jan Schmidt &lt;thaytan@mad.scientist.com&gt;,Mark Nauwelaerts &lt;mark.nauwelaerts@collabora.co.uk&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/mpeg, mpegversion=(int)1, parsed=(boolean)false</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>audio/mpeg, mpegversion=(int)1, layer=(int)[ 1, 3 ], rate=(int)[ 8000, 48000 ], channels=(int)[ 1, 2 ], parsed=(boolean)true</details>
</caps>
</pads>
</element>
</elements>
</plugin>

View file

@ -1,20 +0,0 @@
plugin_LTLIBRARIES = libgstaudioparsersbad.la
libgstaudioparsersbad_la_SOURCES = \
gstaacparse.c gstamrparse.c gstac3parse.c \
gstdcaparse.c gstflacparse.c gstmpegaudioparse.c \
plugin.c
libgstaudioparsersbad_la_CFLAGS = \
-I$(top_srcdir)/gst-libs \
$(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
libgstaudioparsersbad_la_LIBADD = \
$(top_builddir)/gst-libs/gst/baseparse/libgstbaseparse-$(GST_MAJORMINOR).la \
$(GST_PLUGINS_BASE_LIBS) -lgsttag-$(GST_MAJORMINOR) \
-lgstaudio-$(GST_MAJORMINOR) \
$(GST_BASE_LIBS) $(GST_LIBS)
libgstaudioparsersbad_la_LDFLAGS = $(PACKAGE_LIBS) $(GST_PLUGIN_LDFLAGS)
libgstaudioparsersbad_la_LIBTOOLFLAGS = --tag=disable-static
noinst_HEADERS = gstaacparse.h gstamrparse.h gstac3parse.h \
gstdcaparse.h gstflacparse.h gstmpegaudioparse.h

View file

@ -1,715 +0,0 @@
/* GStreamer AAC parser plugin
* Copyright (C) 2008 Nokia Corporation. All rights reserved.
*
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* 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.
*/
/**
* SECTION:element-aacparse
* @short_description: AAC parser
* @see_also: #GstAmrParse
*
* This is an AAC parser which handles both ADIF and ADTS stream formats.
*
* As ADIF format is not framed, it is not seekable and stream duration cannot
* be determined either. However, ADTS format AAC clips can be seeked, and parser
* can also estimate playback position and clip duration.
*
* <refsect2>
* <title>Example launch line</title>
* |[
* gst-launch filesrc location=abc.aac ! aacparse ! faad ! audioresample ! audioconvert ! alsasink
* ]|
* </refsect2>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include "gstaacparse.h"
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/mpeg, "
"framed = (boolean) true, " "mpegversion = (int) { 2, 4 }, "
"stream-format = (string) { raw, adts, adif };"));
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/mpeg, "
"framed = (boolean) false, " "mpegversion = (int) { 2, 4 };"));
GST_DEBUG_CATEGORY_STATIC (gst_aacparse_debug);
#define GST_CAT_DEFAULT gst_aacparse_debug
#define ADIF_MAX_SIZE 40 /* Should be enough */
#define ADTS_MAX_SIZE 10 /* Should be enough */
#define AAC_FRAME_DURATION(parse) (GST_SECOND/parse->frames_per_sec)
gboolean gst_aacparse_start (GstBaseParse * parse);
gboolean gst_aacparse_stop (GstBaseParse * parse);
static gboolean gst_aacparse_sink_setcaps (GstBaseParse * parse,
GstCaps * caps);
gboolean gst_aacparse_check_valid_frame (GstBaseParse * parse,
GstBaseParseFrame * frame, guint * size, gint * skipsize);
GstFlowReturn gst_aacparse_parse_frame (GstBaseParse * parse,
GstBaseParseFrame * frame);
gboolean gst_aacparse_convert (GstBaseParse * parse,
GstFormat src_format,
gint64 src_value, GstFormat dest_format, gint64 * dest_value);
gint gst_aacparse_get_frame_overhead (GstBaseParse * parse, GstBuffer * buffer);
gboolean gst_aacparse_event (GstBaseParse * parse, GstEvent * event);
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_aacparse_debug, "aacparse", 0, \
"AAC audio stream parser");
GST_BOILERPLATE_FULL (GstAacParse, gst_aacparse, GstBaseParse,
GST_TYPE_BASE_PARSE, _do_init);
static inline gint
gst_aacparse_get_sample_rate_from_index (guint sr_idx)
{
static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
32000, 24000, 22050, 16000, 12000, 11025, 8000
};
if (sr_idx < G_N_ELEMENTS (aac_sample_rates))
return aac_sample_rates[sr_idx];
GST_WARNING ("Invalid sample rate index %u", sr_idx);
return 0;
}
/**
* gst_aacparse_base_init:
* @klass: #GstElementClass.
*
*/
static void
gst_aacparse_base_init (gpointer klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_template));
gst_element_class_set_details_simple (element_class,
"AAC audio stream parser", "Codec/Parser/Audio",
"Advanced Audio Coding parser", "Stefan Kost <stefan.kost@nokia.com>");
}
/**
* gst_aacparse_class_init:
* @klass: #GstAacParseClass.
*
*/
static void
gst_aacparse_class_init (GstAacParseClass * klass)
{
GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
parse_class->start = GST_DEBUG_FUNCPTR (gst_aacparse_start);
parse_class->stop = GST_DEBUG_FUNCPTR (gst_aacparse_stop);
parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_aacparse_sink_setcaps);
parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_aacparse_parse_frame);
parse_class->check_valid_frame =
GST_DEBUG_FUNCPTR (gst_aacparse_check_valid_frame);
}
/**
* gst_aacparse_init:
* @aacparse: #GstAacParse.
* @klass: #GstAacParseClass.
*
*/
static void
gst_aacparse_init (GstAacParse * aacparse, GstAacParseClass * klass)
{
GST_DEBUG ("initialized");
}
/**
* gst_aacparse_set_src_caps:
* @aacparse: #GstAacParse.
* @sink_caps: (proposed) caps of sink pad
*
* Set source pad caps according to current knowledge about the
* audio stream.
*
* Returns: TRUE if caps were successfully set.
*/
static gboolean
gst_aacparse_set_src_caps (GstAacParse * aacparse, GstCaps * sink_caps)
{
GstStructure *s;
GstCaps *src_caps = NULL;
gboolean res = FALSE;
const gchar *stream_format;
GST_DEBUG_OBJECT (aacparse, "sink caps: %" GST_PTR_FORMAT, sink_caps);
if (sink_caps)
src_caps = gst_caps_copy (sink_caps);
else
src_caps = gst_caps_new_simple ("audio/mpeg", NULL);
gst_caps_set_simple (src_caps, "framed", G_TYPE_BOOLEAN, TRUE,
"mpegversion", G_TYPE_INT, aacparse->mpegversion, NULL);
switch (aacparse->header_type) {
case DSPAAC_HEADER_NONE:
stream_format = "raw";
break;
case DSPAAC_HEADER_ADTS:
stream_format = "adts";
break;
case DSPAAC_HEADER_ADIF:
stream_format = "adif";
break;
default:
stream_format = NULL;
}
s = gst_caps_get_structure (src_caps, 0);
if (aacparse->sample_rate > 0)
gst_structure_set (s, "rate", G_TYPE_INT, aacparse->sample_rate, NULL);
if (aacparse->channels > 0)
gst_structure_set (s, "channels", G_TYPE_INT, aacparse->channels, NULL);
if (stream_format)
gst_structure_set (s, "stream-format", G_TYPE_STRING, stream_format, NULL);
GST_DEBUG_OBJECT (aacparse, "setting src caps: %" GST_PTR_FORMAT, src_caps);
res = gst_pad_set_caps (GST_BASE_PARSE (aacparse)->srcpad, src_caps);
gst_caps_unref (src_caps);
return res;
}
/**
* gst_aacparse_sink_setcaps:
* @sinkpad: GstPad
* @caps: GstCaps
*
* Implementation of "set_sink_caps" vmethod in #GstBaseParse class.
*
* Returns: TRUE on success.
*/
static gboolean
gst_aacparse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
{
GstAacParse *aacparse;
GstStructure *structure;
gchar *caps_str;
const GValue *value;
aacparse = GST_AACPARSE (parse);
structure = gst_caps_get_structure (caps, 0);
caps_str = gst_caps_to_string (caps);
GST_DEBUG_OBJECT (aacparse, "setcaps: %s", caps_str);
g_free (caps_str);
/* This is needed at least in case of RTP
* Parses the codec_data information to get ObjectType,
* number of channels and samplerate */
value = gst_structure_get_value (structure, "codec_data");
if (value) {
GstBuffer *buf = gst_value_get_buffer (value);
if (buf) {
const guint8 *buffer = GST_BUFFER_DATA (buf);
guint sr_idx;
sr_idx = ((buffer[0] & 0x07) << 1) | ((buffer[1] & 0x80) >> 7);
aacparse->object_type = (buffer[0] & 0xf8) >> 3;
aacparse->sample_rate = gst_aacparse_get_sample_rate_from_index (sr_idx);
aacparse->channels = (buffer[1] & 0x78) >> 3;
aacparse->header_type = DSPAAC_HEADER_NONE;
aacparse->mpegversion = 4;
GST_DEBUG ("codec_data: object_type=%d, sample_rate=%d, channels=%d",
aacparse->object_type, aacparse->sample_rate, aacparse->channels);
/* arrange for metadata and get out of the way */
gst_aacparse_set_src_caps (aacparse, caps);
gst_base_parse_set_format (parse,
GST_BASE_PARSE_FORMAT_PASSTHROUGH, TRUE);
} else
return FALSE;
/* caps info overrides */
gst_structure_get_int (structure, "rate", &aacparse->sample_rate);
gst_structure_get_int (structure, "channels", &aacparse->channels);
}
return TRUE;
}
/**
* gst_aacparse_adts_get_frame_len:
* @data: block of data containing an ADTS header.
*
* This function calculates ADTS frame length from the given header.
*
* Returns: size of the ADTS frame.
*/
static inline guint
gst_aacparse_adts_get_frame_len (const guint8 * data)
{
return ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
}
/**
* gst_aacparse_check_adts_frame:
* @aacparse: #GstAacParse.
* @data: Data to be checked.
* @avail: Amount of data passed.
* @framesize: If valid ADTS frame was found, this will be set to tell the
* found frame size in bytes.
* @needed_data: If frame was not found, this may be set to tell how much
* more data is needed in the next round to detect the frame
* reliably. This may happen when a frame header candidate
* is found but it cannot be guaranteed to be the header without
* peeking the following data.
*
* Check if the given data contains contains ADTS frame. The algorithm
* will examine ADTS frame header and calculate the frame size. Also, another
* consecutive ADTS frame header need to be present after the found frame.
* Otherwise the data is not considered as a valid ADTS frame. However, this
* "extra check" is omitted when EOS has been received. In this case it is
* enough when data[0] contains a valid ADTS header.
*
* This function may set the #needed_data to indicate that a possible frame
* candidate has been found, but more data (#needed_data bytes) is needed to
* be absolutely sure. When this situation occurs, FALSE will be returned.
*
* When a valid frame is detected, this function will use
* gst_base_parse_set_min_frame_size() function from #GstBaseParse class
* to set the needed bytes for next frame.This way next data chunk is already
* of correct size.
*
* Returns: TRUE if the given data contains a valid ADTS header.
*/
static gboolean
gst_aacparse_check_adts_frame (GstAacParse * aacparse,
const guint8 * data, const guint avail, gboolean drain,
guint * framesize, guint * needed_data)
{
if (G_UNLIKELY (avail < 2))
return FALSE;
if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
*framesize = gst_aacparse_adts_get_frame_len (data);
/* In EOS mode this is enough. No need to examine the data further */
if (drain) {
return TRUE;
}
if (*framesize + ADTS_MAX_SIZE > avail) {
/* We have found a possible frame header candidate, but can't be
sure since we don't have enough data to check the next frame */
GST_DEBUG ("NEED MORE DATA: we need %d, available %d",
*framesize + ADTS_MAX_SIZE, avail);
*needed_data = *framesize + ADTS_MAX_SIZE;
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
*framesize + ADTS_MAX_SIZE);
return FALSE;
}
if ((data[*framesize] == 0xff) && ((data[*framesize + 1] & 0xf6) == 0xf0)) {
guint nextlen = gst_aacparse_adts_get_frame_len (data + (*framesize));
GST_LOG ("ADTS frame found, len: %d bytes", *framesize);
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
nextlen + ADTS_MAX_SIZE);
return TRUE;
}
}
return FALSE;
}
/* caller ensure sufficient data */
static inline void
gst_aacparse_parse_adts_header (GstAacParse * aacparse, const guint8 * data,
gint * rate, gint * channels, gint * object, gint * version)
{
if (rate) {
gint sr_idx = (data[2] & 0x3c) >> 2;
*rate = gst_aacparse_get_sample_rate_from_index (sr_idx);
}
if (channels)
*channels = ((data[2] & 0x01) << 2) | ((data[3] & 0xc0) >> 6);
if (version)
*version = (data[1] & 0x08) ? 2 : 4;
if (object)
*object = (data[2] & 0xc0) >> 6;
}
/**
* gst_aacparse_detect_stream:
* @aacparse: #GstAacParse.
* @data: A block of data that needs to be examined for stream characteristics.
* @avail: Size of the given datablock.
* @framesize: If valid stream was found, this will be set to tell the
* first frame size in bytes.
* @skipsize: If valid stream was found, this will be set to tell the first
* audio frame position within the given data.
*
* Examines the given piece of data and try to detect the format of it. It
* checks for "ADIF" header (in the beginning of the clip) and ADTS frame
* header. If the stream is detected, TRUE will be returned and #framesize
* is set to indicate the found frame size. Additionally, #skipsize might
* be set to indicate the number of bytes that need to be skipped, a.k.a. the
* position of the frame inside given data chunk.
*
* Returns: TRUE on success.
*/
static gboolean
gst_aacparse_detect_stream (GstAacParse * aacparse,
const guint8 * data, const guint avail, gboolean drain,
guint * framesize, gint * skipsize)
{
gboolean found = FALSE;
guint need_data = 0;
guint i = 0;
GST_DEBUG_OBJECT (aacparse, "Parsing header data");
/* FIXME: No need to check for ADIF if we are not in the beginning of the
stream */
/* Can we even parse the header? */
if (avail < ADTS_MAX_SIZE)
return FALSE;
for (i = 0; i < avail - 4; i++) {
if (((data[i] == 0xff) && ((data[i + 1] & 0xf6) == 0xf0)) ||
strncmp ((char *) data + i, "ADIF", 4) == 0) {
found = TRUE;
if (i) {
/* Trick: tell the parent class that we didn't find the frame yet,
but make it skip 'i' amount of bytes. Next time we arrive
here we have full frame in the beginning of the data. */
*skipsize = i;
return FALSE;
}
break;
}
}
if (!found) {
if (i)
*skipsize = i;
return FALSE;
}
if (gst_aacparse_check_adts_frame (aacparse, data, avail, drain,
framesize, &need_data)) {
gint rate, channels;
GST_INFO ("ADTS ID: %d, framesize: %d", (data[1] & 0x08) >> 3, *framesize);
aacparse->header_type = DSPAAC_HEADER_ADTS;
gst_aacparse_parse_adts_header (aacparse, data, &rate, &channels,
&aacparse->object_type, &aacparse->mpegversion);
gst_base_parse_set_frame_props (GST_BASE_PARSE (aacparse),
rate, 1024, 2, 2);
GST_DEBUG ("ADTS: samplerate %d, channels %d, objtype %d, version %d",
rate, channels, aacparse->object_type, aacparse->mpegversion);
return TRUE;
} else if (need_data) {
/* This tells the parent class not to skip any data */
*skipsize = 0;
return FALSE;
}
if (avail < ADIF_MAX_SIZE)
return FALSE;
if (memcmp (data + i, "ADIF", 4) == 0) {
const guint8 *adif;
int skip_size = 0;
int bitstream_type;
int sr_idx;
aacparse->header_type = DSPAAC_HEADER_ADIF;
aacparse->mpegversion = 4;
/* no way to seek this */
gst_base_parse_set_seek (GST_BASE_PARSE (aacparse),
GST_BASE_PARSE_SEEK_NONE, 0);
/* Skip the "ADIF" bytes */
adif = data + i + 4;
/* copyright string */
if (adif[0] & 0x80)
skip_size += 9; /* skip 9 bytes */
bitstream_type = adif[0 + skip_size] & 0x10;
aacparse->bitrate =
((unsigned int) (adif[0 + skip_size] & 0x0f) << 19) |
((unsigned int) adif[1 + skip_size] << 11) |
((unsigned int) adif[2 + skip_size] << 3) |
((unsigned int) adif[3 + skip_size] & 0xe0);
/* CBR */
if (bitstream_type == 0) {
#if 0
/* Buffer fullness parsing. Currently not needed... */
guint num_elems = 0;
guint fullness = 0;
num_elems = (adif[3 + skip_size] & 0x1e);
GST_INFO ("ADIF num_config_elems: %d", num_elems);
fullness = ((unsigned int) (adif[3 + skip_size] & 0x01) << 19) |
((unsigned int) adif[4 + skip_size] << 11) |
((unsigned int) adif[5 + skip_size] << 3) |
((unsigned int) (adif[6 + skip_size] & 0xe0) >> 5);
GST_INFO ("ADIF buffer fullness: %d", fullness);
#endif
aacparse->object_type = ((adif[6 + skip_size] & 0x01) << 1) |
((adif[7 + skip_size] & 0x80) >> 7);
sr_idx = (adif[7 + skip_size] & 0x78) >> 3;
}
/* VBR */
else {
aacparse->object_type = (adif[4 + skip_size] & 0x18) >> 3;
sr_idx = ((adif[4 + skip_size] & 0x07) << 1) |
((adif[5 + skip_size] & 0x80) >> 7);
}
/* FIXME: This gives totally wrong results. Duration calculation cannot
be based on this */
aacparse->sample_rate = gst_aacparse_get_sample_rate_from_index (sr_idx);
/* baseparse is not given any fps,
* so it will give up on timestamps, seeking, etc */
/* FIXME: Can we assume this? */
aacparse->channels = 2;
GST_INFO ("ADIF: br=%d, samplerate=%d, objtype=%d",
aacparse->bitrate, aacparse->sample_rate, aacparse->object_type);
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 512);
/* arrange for metadata and get out of the way */
gst_aacparse_set_src_caps (aacparse,
GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (aacparse)));
gst_base_parse_set_format (GST_BASE_PARSE (aacparse),
GST_BASE_PARSE_FORMAT_PASSTHROUGH, TRUE);
*framesize = avail;
return TRUE;
}
/* This should never happen */
return FALSE;
}
/**
* gst_aacparse_check_valid_frame:
* @parse: #GstBaseParse.
* @buffer: #GstBuffer.
* @framesize: If the buffer contains a valid frame, its size will be put here
* @skipsize: How much data parent class should skip in order to find the
* frame header.
*
* Implementation of "check_valid_frame" vmethod in #GstBaseParse class.
*
* Returns: TRUE if buffer contains a valid frame.
*/
gboolean
gst_aacparse_check_valid_frame (GstBaseParse * parse,
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
{
const guint8 *data;
GstAacParse *aacparse;
gboolean ret = FALSE;
gboolean sync;
GstBuffer *buffer;
aacparse = GST_AACPARSE (parse);
buffer = frame->buffer;
data = GST_BUFFER_DATA (buffer);
sync = GST_BASE_PARSE_FRAME_SYNC (frame);
if (aacparse->header_type == DSPAAC_HEADER_ADIF ||
aacparse->header_type == DSPAAC_HEADER_NONE) {
/* There is nothing to parse */
*framesize = GST_BUFFER_SIZE (buffer);
ret = TRUE;
} else if (aacparse->header_type == DSPAAC_HEADER_NOT_PARSED || sync == FALSE) {
ret = gst_aacparse_detect_stream (aacparse, data, GST_BUFFER_SIZE (buffer),
GST_BASE_PARSE_FRAME_DRAIN (frame), framesize, skipsize);
} else if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
guint needed_data = 1024;
ret = gst_aacparse_check_adts_frame (aacparse, data,
GST_BUFFER_SIZE (buffer), GST_BASE_PARSE_FRAME_DRAIN (frame),
framesize, &needed_data);
if (!ret) {
GST_DEBUG ("buffer didn't contain valid frame");
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
needed_data);
}
} else {
GST_DEBUG ("buffer didn't contain valid frame");
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 1024);
}
return ret;
}
/**
* gst_aacparse_parse_frame:
* @parse: #GstBaseParse.
* @buffer: #GstBuffer.
*
* Implementation of "parse_frame" vmethod in #GstBaseParse class.
*
* Also determines frame overhead.
* ADTS streams have a 7 byte header in each frame. MP4 and ADIF streams don't have
* a per-frame header.
*
* We're making a couple of simplifying assumptions:
*
* 1. We count Program Configuration Elements rather than searching for them
* in the streams to discount them - the overhead is negligible.
*
* 2. We ignore CRC. This has a worst-case impact of (num_raw_blocks + 1)*16
* bits, which should still not be significant enough to warrant the
* additional parsing through the headers
*
* Returns: GST_FLOW_OK if frame was successfully parsed and can be pushed
* forward. Otherwise appropriate error is returned.
*/
GstFlowReturn
gst_aacparse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
{
GstAacParse *aacparse;
GstBuffer *buffer;
GstFlowReturn ret = GST_FLOW_OK;
gint rate, channels;
aacparse = GST_AACPARSE (parse);
buffer = frame->buffer;
if (G_UNLIKELY (aacparse->header_type != DSPAAC_HEADER_ADTS))
return ret;
/* see above */
frame->overhead = 7;
gst_aacparse_parse_adts_header (aacparse, GST_BUFFER_DATA (buffer),
&rate, &channels, NULL, NULL);
GST_LOG_OBJECT (aacparse, "rate: %d, chans: %d", rate, channels);
if (G_UNLIKELY (rate != aacparse->sample_rate
|| channels != aacparse->channels)) {
aacparse->sample_rate = rate;
aacparse->channels = channels;
if (!gst_aacparse_set_src_caps (aacparse,
GST_PAD_CAPS (GST_BASE_PARSE (aacparse)->sinkpad))) {
/* If linking fails, we need to return appropriate error */
ret = GST_FLOW_NOT_LINKED;
}
gst_base_parse_set_frame_props (GST_BASE_PARSE (aacparse),
aacparse->sample_rate, 1024, 2, 2);
}
return ret;
}
/**
* gst_aacparse_start:
* @parse: #GstBaseParse.
*
* Implementation of "start" vmethod in #GstBaseParse class.
*
* Returns: TRUE if startup succeeded.
*/
gboolean
gst_aacparse_start (GstBaseParse * parse)
{
GstAacParse *aacparse;
aacparse = GST_AACPARSE (parse);
GST_DEBUG ("start");
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 1024);
return TRUE;
}
/**
* gst_aacparse_stop:
* @parse: #GstBaseParse.
*
* Implementation of "stop" vmethod in #GstBaseParse class.
*
* Returns: TRUE is stopping succeeded.
*/
gboolean
gst_aacparse_stop (GstBaseParse * parse)
{
GST_DEBUG ("stop");
return TRUE;
}

View file

@ -1,109 +0,0 @@
/* GStreamer AAC parser
* Copyright (C) 2008 Nokia Corporation. All rights reserved.
*
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* 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.
*/
#ifndef __GST_AACPARSE_H__
#define __GST_AACPARSE_H__
#include <gst/gst.h>
#include <gst/baseparse/gstbaseparse.h>
G_BEGIN_DECLS
#define GST_TYPE_AACPARSE \
(gst_aacparse_get_type())
#define GST_AACPARSE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_AACPARSE, GstAacParse))
#define GST_AACPARSE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_AACPARSE, GstAacParseClass))
#define GST_IS_AACPARSE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_AACPARSE))
#define GST_IS_AACPARSE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_AACPARSE))
/**
* GstAacHeaderType:
* @DSPAAC_HEADER_NOT_PARSED: Header not parsed yet.
* @DSPAAC_HEADER_UNKNOWN: Unknown (not recognized) header.
* @DSPAAC_HEADER_ADIF: ADIF header found.
* @DSPAAC_HEADER_ADTS: ADTS header found.
* @DSPAAC_HEADER_NONE: Raw stream, no header.
*
* Type header enumeration set in #header_type.
*/
typedef enum {
DSPAAC_HEADER_NOT_PARSED,
DSPAAC_HEADER_UNKNOWN,
DSPAAC_HEADER_ADIF,
DSPAAC_HEADER_ADTS,
DSPAAC_HEADER_NONE
} GstAacHeaderType;
typedef struct _GstAacParse GstAacParse;
typedef struct _GstAacParseClass GstAacParseClass;
/**
* GstAacParse:
* @element: the parent element.
* @object_type: AAC object type of the stream.
* @bitrate: Current media bitrate.
* @sample_rate: Current media samplerate.
* @channels: Current media channel count.
* @frames_per_sec: FPS value of the current stream.
* @header_type: #GstAacHeaderType indicating the current stream type.
* @framecount: The amount of frames that has been processed this far.
* @bytecount: The amount of bytes that has been processed this far.
* @sync: Tells whether the parser is in sync (a.k.a. not searching for header)
* @eos: End-of-Stream indicator. Set when EOS event arrives.
* @duration: Duration of the current stream.
* @ts: Current stream timestamp.
*
* The opaque GstAacParse data structure.
*/
struct _GstAacParse {
GstBaseParse element;
/* Stream type -related info */
gint object_type;
gint bitrate;
gint sample_rate;
gint channels;
gint mpegversion;
GstAacHeaderType header_type;
};
/**
* GstAacParseClass:
* @parent_class: Element parent class.
*
* The opaque GstAacParseClass data structure.
*/
struct _GstAacParseClass {
GstBaseParseClass parent_class;
};
GType gst_aacparse_get_type (void);
G_END_DECLS
#endif /* __GST_AACPARSE_H__ */

View file

@ -1,507 +0,0 @@
/* GStreamer AC3 parser
* Copyright (C) 2009 Tim-Philipp Müller <tim centricular net>
* Copyright (C) 2009 Mark Nauwelaerts <mnauw users sf net>
* Copyright (C) 2009 Nokia Corporation. All rights reserved.
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* 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.
*/
/**
* SECTION:element-ac3parse
* @short_description: AC3 parser
* @see_also: #GstAmrParse, #GstAACParse
*
* This is an AC3 parser.
*
* <refsect2>
* <title>Example launch line</title>
* |[
* gst-launch filesrc location=abc.ac3 ! ac3parse ! a52dec ! audioresample ! audioconvert ! autoaudiosink
* ]|
* </refsect2>
*/
/* TODO:
* - add support for audio/x-private1-ac3 as well
* - should accept framed and unframed input (needs decodebin fixes first)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include "gstac3parse.h"
#include <gst/base/gstbytereader.h>
#include <gst/base/gstbitreader.h>
GST_DEBUG_CATEGORY_STATIC (ac3_parse_debug);
#define GST_CAT_DEFAULT ac3_parse_debug
static const struct
{
const guint bit_rate; /* nominal bit rate */
const guint frame_size[3]; /* frame size for 32kHz, 44kHz, and 48kHz */
} frmsizcod_table[38] = {
{
32, {
64, 69, 96}}, {
32, {
64, 70, 96}}, {
40, {
80, 87, 120}}, {
40, {
80, 88, 120}}, {
48, {
96, 104, 144}}, {
48, {
96, 105, 144}}, {
56, {
112, 121, 168}}, {
56, {
112, 122, 168}}, {
64, {
128, 139, 192}}, {
64, {
128, 140, 192}}, {
80, {
160, 174, 240}}, {
80, {
160, 175, 240}}, {
96, {
192, 208, 288}}, {
96, {
192, 209, 288}}, {
112, {
224, 243, 336}}, {
112, {
224, 244, 336}}, {
128, {
256, 278, 384}}, {
128, {
256, 279, 384}}, {
160, {
320, 348, 480}}, {
160, {
320, 349, 480}}, {
192, {
384, 417, 576}}, {
192, {
384, 418, 576}}, {
224, {
448, 487, 672}}, {
224, {
448, 488, 672}}, {
256, {
512, 557, 768}}, {
256, {
512, 558, 768}}, {
320, {
640, 696, 960}}, {
320, {
640, 697, 960}}, {
384, {
768, 835, 1152}}, {
384, {
768, 836, 1152}}, {
448, {
896, 975, 1344}}, {
448, {
896, 976, 1344}}, {
512, {
1024, 1114, 1536}}, {
512, {
1024, 1115, 1536}}, {
576, {
1152, 1253, 1728}}, {
576, {
1152, 1254, 1728}}, {
640, {
1280, 1393, 1920}}, {
640, {
1280, 1394, 1920}}
};
static const guint fscod_rates[4] = { 48000, 44100, 32000, 0 };
static const guint acmod_chans[8] = { 2, 1, 2, 3, 3, 4, 4, 5 };
static const guint numblks[4] = { 1, 2, 3, 6 };
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-ac3, framed = (boolean) true, "
" channels = (int) [ 1, 6 ], rate = (int) [ 32000, 48000 ]; "
"audio/x-eac3, framed = (boolean) true, "
" channels = (int) [ 1, 6 ], rate = (int) [ 32000, 48000 ] "));
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-ac3, framed = (boolean) false; "
"audio/x-eac3, framed = (boolean) false; "
"audio/ac3, framed = (boolean) false "));
static void gst_ac3_parse_finalize (GObject * object);
static gboolean gst_ac3_parse_start (GstBaseParse * parse);
static gboolean gst_ac3_parse_stop (GstBaseParse * parse);
static gboolean gst_ac3_parse_check_valid_frame (GstBaseParse * parse,
GstBaseParseFrame * frame, guint * size, gint * skipsize);
static GstFlowReturn gst_ac3_parse_parse_frame (GstBaseParse * parse,
GstBaseParseFrame * frame);
GST_BOILERPLATE (GstAc3Parse, gst_ac3_parse, GstBaseParse, GST_TYPE_BASE_PARSE);
static void
gst_ac3_parse_base_init (gpointer klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_template));
gst_element_class_set_details_simple (element_class,
"AC3 audio stream parser", "Codec/Parser/Audio",
"AC3 parser", "Tim-Philipp Müller <tim centricular net>");
}
static void
gst_ac3_parse_class_init (GstAc3ParseClass * klass)
{
GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GST_DEBUG_CATEGORY_INIT (ac3_parse_debug, "ac3parse", 0,
"AC3 audio stream parser");
object_class->finalize = gst_ac3_parse_finalize;
parse_class->start = GST_DEBUG_FUNCPTR (gst_ac3_parse_start);
parse_class->stop = GST_DEBUG_FUNCPTR (gst_ac3_parse_stop);
parse_class->check_valid_frame =
GST_DEBUG_FUNCPTR (gst_ac3_parse_check_valid_frame);
parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_ac3_parse_parse_frame);
}
static void
gst_ac3_parse_reset (GstAc3Parse * ac3parse)
{
ac3parse->channels = -1;
ac3parse->sample_rate = -1;
ac3parse->eac = FALSE;
}
static void
gst_ac3_parse_init (GstAc3Parse * ac3parse, GstAc3ParseClass * klass)
{
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (ac3parse), 64 * 2);
gst_ac3_parse_reset (ac3parse);
}
static void
gst_ac3_parse_finalize (GObject * object)
{
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static gboolean
gst_ac3_parse_start (GstBaseParse * parse)
{
GstAc3Parse *ac3parse = GST_AC3_PARSE (parse);
GST_DEBUG_OBJECT (parse, "starting");
gst_ac3_parse_reset (ac3parse);
return TRUE;
}
static gboolean
gst_ac3_parse_stop (GstBaseParse * parse)
{
GST_DEBUG_OBJECT (parse, "stopping");
return TRUE;
}
static gboolean
gst_ac3_parse_frame_header_ac3 (GstAc3Parse * ac3parse, GstBuffer * buf,
guint * frame_size, guint * rate, guint * chans, guint * blks, guint * sid)
{
GstBitReader bits = GST_BIT_READER_INIT_FROM_BUFFER (buf);
guint8 fscod, frmsizcod, bsid, bsmod, acmod, lfe_on;
GST_LOG_OBJECT (ac3parse, "parsing ac3");
gst_bit_reader_skip_unchecked (&bits, 16 + 16);
fscod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2);
frmsizcod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 6);
if (G_UNLIKELY (fscod == 3 || frmsizcod >= G_N_ELEMENTS (frmsizcod_table))) {
GST_DEBUG_OBJECT (ac3parse, "bad fscod=%d frmsizcod=%d", fscod, frmsizcod);
return FALSE;
}
bsid = gst_bit_reader_get_bits_uint8_unchecked (&bits, 5);
bsmod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 3);
acmod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 3);
/* spec not quite clear here: decoder should decode if less than 8,
* but seemingly only defines 6 and 8 cases */
if (bsid > 8) {
GST_DEBUG_OBJECT (ac3parse, "unexpected bsid=%d", bsid);
return FALSE;
} else if (bsid != 8 && bsid != 6) {
GST_DEBUG_OBJECT (ac3parse, "undefined bsid=%d", bsid);
}
if ((acmod & 0x1) && (acmod != 0x1)) /* 3 front channels */
gst_bit_reader_skip_unchecked (&bits, 2);
if ((acmod & 0x4)) /* if a surround channel exists */
gst_bit_reader_skip_unchecked (&bits, 2);
if (acmod == 0x2) /* if in 2/0 mode */
gst_bit_reader_skip_unchecked (&bits, 2);
lfe_on = gst_bit_reader_get_bits_uint8_unchecked (&bits, 1);
if (frame_size)
*frame_size = frmsizcod_table[frmsizcod].frame_size[fscod] * 2;
if (rate)
*rate = fscod_rates[fscod];
if (chans)
*chans = acmod_chans[acmod] + lfe_on;
if (blks)
*blks = 6;
if (sid)
*sid = 0;
return TRUE;
}
static gboolean
gst_ac3_parse_frame_header_eac3 (GstAc3Parse * ac3parse, GstBuffer * buf,
guint * frame_size, guint * rate, guint * chans, guint * blks, guint * sid)
{
GstBitReader bits = GST_BIT_READER_INIT_FROM_BUFFER (buf);
guint16 frmsiz, sample_rate, blocks;
guint8 strmtyp, fscod, fscod2, acmod, lfe_on, strmid, numblkscod;
GST_LOG_OBJECT (ac3parse, "parsing e-ac3");
gst_bit_reader_skip_unchecked (&bits, 16);
strmtyp = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2); /* strmtyp */
if (G_UNLIKELY (strmtyp == 3)) {
GST_DEBUG_OBJECT (ac3parse, "bad strmtyp %d", strmtyp);
return FALSE;
}
strmid = gst_bit_reader_get_bits_uint8_unchecked (&bits, 3); /* substreamid */
frmsiz = gst_bit_reader_get_bits_uint16_unchecked (&bits, 11); /* frmsiz */
fscod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2); /* fscod */
if (fscod == 3) {
fscod2 = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2); /* fscod2 */
if (G_UNLIKELY (fscod2 == 3)) {
GST_DEBUG_OBJECT (ac3parse, "invalid fscod2");
return FALSE;
}
sample_rate = fscod_rates[fscod2] / 2;
blocks = 6;
} else {
numblkscod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2); /* numblkscod */
sample_rate = fscod_rates[fscod];
blocks = numblks[numblkscod];
}
acmod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 3); /* acmod */
lfe_on = gst_bit_reader_get_bits_uint8_unchecked (&bits, 1); /* lfeon */
gst_bit_reader_skip_unchecked (&bits, 5); /* bsid */
if (frame_size)
*frame_size = (frmsiz + 1) * 2;
if (rate)
*rate = sample_rate;
if (chans)
*chans = acmod_chans[acmod] + lfe_on;
if (blks)
*blks = blocks;
if (sid)
*sid = (strmtyp & 0x1) << 3 | strmid;
return TRUE;
}
static gboolean
gst_ac3_parse_frame_header (GstAc3Parse * parse, GstBuffer * buf,
guint * framesize, guint * rate, guint * chans, guint * blocks,
guint * sid, gboolean * eac)
{
GstBitReader bits = GST_BIT_READER_INIT_FROM_BUFFER (buf);
guint16 sync;
guint8 bsid;
GST_MEMDUMP_OBJECT (parse, "AC3 frame sync", GST_BUFFER_DATA (buf), 16);
sync = gst_bit_reader_get_bits_uint16_unchecked (&bits, 16);
gst_bit_reader_skip_unchecked (&bits, 16 + 8);
bsid = gst_bit_reader_peek_bits_uint8_unchecked (&bits, 5);
if (G_UNLIKELY (sync != 0x0b77))
return FALSE;
GST_LOG_OBJECT (parse, "bsid = %d", bsid);
if (bsid <= 10) {
if (eac)
*eac = FALSE;
return gst_ac3_parse_frame_header_ac3 (parse, buf, framesize, rate, chans,
blocks, sid);
} else if (bsid <= 16) {
if (eac)
*eac = TRUE;
return gst_ac3_parse_frame_header_eac3 (parse, buf, framesize, rate, chans,
blocks, sid);
} else {
GST_DEBUG_OBJECT (parse, "unexpected bsid %d", bsid);
return FALSE;
}
}
static gboolean
gst_ac3_parse_check_valid_frame (GstBaseParse * parse,
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
{
GstAc3Parse *ac3parse = GST_AC3_PARSE (parse);
GstBuffer *buf = frame->buffer;
GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buf);
gint off;
gboolean sync, drain;
if (G_UNLIKELY (GST_BUFFER_SIZE (buf) < 6))
return FALSE;
off = gst_byte_reader_masked_scan_uint32 (&reader, 0xffff0000, 0x0b770000,
0, GST_BUFFER_SIZE (buf));
GST_LOG_OBJECT (parse, "possible sync at buffer offset %d", off);
/* didn't find anything that looks like a sync word, skip */
if (off < 0) {
*skipsize = GST_BUFFER_SIZE (buf) - 3;
return FALSE;
}
/* possible frame header, but not at offset 0? skip bytes before sync */
if (off > 0) {
*skipsize = off;
return FALSE;
}
/* make sure the values in the frame header look sane */
if (!gst_ac3_parse_frame_header (ac3parse, buf, framesize, NULL, NULL,
NULL, NULL, NULL)) {
*skipsize = off + 2;
return FALSE;
}
GST_LOG_OBJECT (parse, "got frame");
sync = GST_BASE_PARSE_FRAME_SYNC (frame);
drain = GST_BASE_PARSE_FRAME_DRAIN (frame);
if (!sync && !drain) {
guint16 word = 0;
GST_DEBUG_OBJECT (ac3parse, "resyncing; checking next frame syncword");
if (!gst_byte_reader_skip (&reader, *framesize) ||
!gst_byte_reader_get_uint16_be (&reader, &word)) {
GST_DEBUG_OBJECT (ac3parse, "... but not sufficient data");
gst_base_parse_set_min_frame_size (parse, *framesize + 6);
*skipsize = 0;
return FALSE;
} else {
if (word != 0x0b77) {
GST_DEBUG_OBJECT (ac3parse, "0x%x not OK", word);
*skipsize = off + 2;
return FALSE;
} else {
/* ok, got sync now, let's assume constant frame size */
gst_base_parse_set_min_frame_size (parse, *framesize);
}
}
}
return TRUE;
}
static GstFlowReturn
gst_ac3_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
{
GstAc3Parse *ac3parse = GST_AC3_PARSE (parse);
GstBuffer *buf = frame->buffer;
guint fsize, rate, chans, blocks, sid;
gboolean eac;
if (!gst_ac3_parse_frame_header (ac3parse, buf, &fsize, &rate, &chans,
&blocks, &sid, &eac))
goto broken_header;
GST_LOG_OBJECT (parse, "size: %u, rate: %u, chans: %u", fsize, rate, chans);
if (G_UNLIKELY (sid)) {
/* dependent frame, no need to (ac)count for or consider further */
GST_LOG_OBJECT (parse, "sid: %d", sid);
frame->flags |= GST_BASE_PARSE_FRAME_FLAG_NO_FRAME;
/* TODO maybe also mark as DELTA_UNIT,
* if that does not surprise baseparse elsewhere */
/* occupies same time space as previous base frame */
if (G_LIKELY (GST_BUFFER_TIMESTAMP (buf) >= GST_BUFFER_DURATION (buf)))
GST_BUFFER_TIMESTAMP (buf) -= GST_BUFFER_DURATION (buf);
/* only return if we already arranged for caps */
if (G_LIKELY (ac3parse->sample_rate > 0))
return GST_FLOW_OK;
}
if (G_UNLIKELY (ac3parse->sample_rate != rate || ac3parse->channels != chans
|| ac3parse->eac != ac3parse->eac)) {
GstCaps *caps = gst_caps_new_simple (eac ? "audio/x-eac3" : "audio/x-ac3",
"framed", G_TYPE_BOOLEAN, TRUE, "rate", G_TYPE_INT, rate,
"channels", G_TYPE_INT, chans, NULL);
gst_buffer_set_caps (buf, caps);
gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps);
gst_caps_unref (caps);
ac3parse->sample_rate = rate;
ac3parse->channels = chans;
ac3parse->eac = eac;
gst_base_parse_set_frame_props (parse, rate, 256 * blocks, 2, 2);
}
return GST_FLOW_OK;
/* ERRORS */
broken_header:
{
/* this really shouldn't ever happen */
GST_ELEMENT_ERROR (parse, STREAM, DECODE, (NULL), (NULL));
return GST_FLOW_ERROR;
}
}

View file

@ -1,73 +0,0 @@
/* GStreamer AC3 parser
* Copyright (C) 2009 Tim-Philipp Müller <tim centricular net>
* Copyright (C) 2009 Mark Nauwelaerts <mnauw users sf net>
* Copyright (C) 2009 Nokia Corporation. All rights reserved.
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* 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.
*/
#ifndef __GST_AC3_PARSE_H__
#define __GST_AC3_PARSE_H__
#include <gst/gst.h>
#include <gst/baseparse/gstbaseparse.h>
G_BEGIN_DECLS
#define GST_TYPE_AC3_PARSE \
(gst_ac3_parse_get_type())
#define GST_AC3_PARSE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_AC3_PARSE, GstAc3Parse))
#define GST_AC3_PARSE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_AC3_PARSE, GstAc3ParseClass))
#define GST_IS_AC3_PARSE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_AC3_PARSE))
#define GST_IS_AC3_PARSE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_AC3_PARSE))
typedef struct _GstAc3Parse GstAc3Parse;
typedef struct _GstAc3ParseClass GstAc3ParseClass;
/**
* GstAc3Parse:
*
* The opaque GstAc3Parse object
*/
struct _GstAc3Parse {
GstBaseParse baseparse;
/*< private >*/
gint sample_rate;
gint channels;
gboolean eac;
};
/**
* GstAc3ParseClass:
* @parent_class: Element parent class.
*
* The opaque GstAc3ParseClass data structure.
*/
struct _GstAc3ParseClass {
GstBaseParseClass baseparse_class;
};
GType gst_ac3_parse_get_type (void);
G_END_DECLS
#endif /* __GST_AC3_PARSE_H__ */

View file

@ -1,378 +0,0 @@
/* GStreamer Adaptive Multi-Rate parser plugin
* Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
* Copyright (C) 2008 Nokia Corporation. All rights reserved.
*
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* 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.
*/
/**
* SECTION:element-amrparse
* @short_description: AMR parser
* @see_also: #GstAmrnbDec, #GstAmrnbEnc
*
* This is an AMR parser capable of handling both narrow-band and wideband
* formats.
*
* <refsect2>
* <title>Example launch line</title>
* |[
* gst-launch filesrc location=abc.amr ! amrparse ! amrdec ! audioresample ! audioconvert ! alsasink
* ]|
* </refsect2>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include "gstamrparse.h"
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/AMR, " "rate = (int) 8000, " "channels = (int) 1;"
"audio/AMR-WB, " "rate = (int) 16000, " "channels = (int) 1;")
);
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-amr-nb-sh; audio/x-amr-wb-sh"));
GST_DEBUG_CATEGORY_STATIC (gst_amrparse_debug);
#define GST_CAT_DEFAULT gst_amrparse_debug
static const gint block_size_nb[16] =
{ 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
static const gint block_size_wb[16] =
{ 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, 0, 0 };
/* AMR has a "hardcoded" framerate of 50fps */
#define AMR_FRAMES_PER_SECOND 50
#define AMR_FRAME_DURATION (GST_SECOND/AMR_FRAMES_PER_SECOND)
#define AMR_MIME_HEADER_SIZE 9
gboolean gst_amrparse_start (GstBaseParse * parse);
gboolean gst_amrparse_stop (GstBaseParse * parse);
static gboolean gst_amrparse_sink_setcaps (GstBaseParse * parse,
GstCaps * caps);
gboolean gst_amrparse_check_valid_frame (GstBaseParse * parse,
GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
GstFlowReturn gst_amrparse_parse_frame (GstBaseParse * parse,
GstBaseParseFrame * frame);
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_amrparse_debug, "amrparse", 0, \
"AMR-NB audio stream parser");
GST_BOILERPLATE_FULL (GstAmrParse, gst_amrparse, GstBaseParse,
GST_TYPE_BASE_PARSE, _do_init);
/**
* gst_amrparse_base_init:
* @klass: #GstElementClass.
*
*/
static void
gst_amrparse_base_init (gpointer klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_template));
gst_element_class_set_details_simple (element_class,
"AMR audio stream parser", "Codec/Parser/Audio",
"Adaptive Multi-Rate audio parser",
"Ronald Bultje <rbultje@ronald.bitfreak.net>");
}
/**
* gst_amrparse_class_init:
* @klass: GstAmrParseClass.
*
*/
static void
gst_amrparse_class_init (GstAmrParseClass * klass)
{
GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
parse_class->start = GST_DEBUG_FUNCPTR (gst_amrparse_start);
parse_class->stop = GST_DEBUG_FUNCPTR (gst_amrparse_stop);
parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_amrparse_sink_setcaps);
parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_amrparse_parse_frame);
parse_class->check_valid_frame =
GST_DEBUG_FUNCPTR (gst_amrparse_check_valid_frame);
}
/**
* gst_amrparse_init:
* @amrparse: #GstAmrParse
* @klass: #GstAmrParseClass.
*
*/
static void
gst_amrparse_init (GstAmrParse * amrparse, GstAmrParseClass * klass)
{
/* init rest */
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (amrparse), 62);
GST_DEBUG ("initialized");
}
/**
* gst_amrparse_set_src_caps:
* @amrparse: #GstAmrParse.
*
* Set source pad caps according to current knowledge about the
* audio stream.
*
* Returns: TRUE if caps were successfully set.
*/
static gboolean
gst_amrparse_set_src_caps (GstAmrParse * amrparse)
{
GstCaps *src_caps = NULL;
gboolean res = FALSE;
if (amrparse->wide) {
GST_DEBUG_OBJECT (amrparse, "setting srcpad caps to AMR-WB");
src_caps = gst_caps_new_simple ("audio/AMR-WB",
"channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 16000, NULL);
} else {
GST_DEBUG_OBJECT (amrparse, "setting srcpad caps to AMR-NB");
/* Max. size of NB frame is 31 bytes, so we can set the min. frame
size to 32 (+1 for next frame header) */
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (amrparse), 32);
src_caps = gst_caps_new_simple ("audio/AMR",
"channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL);
}
gst_pad_use_fixed_caps (GST_BASE_PARSE (amrparse)->srcpad);
res = gst_pad_set_caps (GST_BASE_PARSE (amrparse)->srcpad, src_caps);
gst_caps_unref (src_caps);
return res;
}
/**
* gst_amrparse_sink_setcaps:
* @sinkpad: GstPad
* @caps: GstCaps
*
* Returns: TRUE on success.
*/
static gboolean
gst_amrparse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
{
GstAmrParse *amrparse;
GstStructure *structure;
const gchar *name;
amrparse = GST_AMRPARSE (parse);
structure = gst_caps_get_structure (caps, 0);
name = gst_structure_get_name (structure);
GST_DEBUG_OBJECT (amrparse, "setcaps: %s", name);
if (!strncmp (name, "audio/x-amr-wb-sh", 17)) {
amrparse->block_size = block_size_wb;
amrparse->wide = 1;
} else if (!strncmp (name, "audio/x-amr-nb-sh", 17)) {
amrparse->block_size = block_size_nb;
amrparse->wide = 0;
} else {
GST_WARNING ("Unknown caps");
return FALSE;
}
amrparse->need_header = FALSE;
gst_base_parse_set_frame_props (GST_BASE_PARSE (amrparse), 50, 1, 2, 2);
gst_amrparse_set_src_caps (amrparse);
return TRUE;
}
/**
* gst_amrparse_parse_header:
* @amrparse: #GstAmrParse
* @data: Header data to be parsed.
* @skipsize: Output argument where the frame size will be stored.
*
* Check if the given data contains an AMR mime header.
*
* Returns: TRUE on success.
*/
static gboolean
gst_amrparse_parse_header (GstAmrParse * amrparse,
const guint8 * data, gint * skipsize)
{
GST_DEBUG_OBJECT (amrparse, "Parsing header data");
if (!memcmp (data, "#!AMR-WB\n", 9)) {
GST_DEBUG_OBJECT (amrparse, "AMR-WB detected");
amrparse->block_size = block_size_wb;
amrparse->wide = TRUE;
*skipsize = amrparse->header = 9;
} else if (!memcmp (data, "#!AMR\n", 6)) {
GST_DEBUG_OBJECT (amrparse, "AMR-NB detected");
amrparse->block_size = block_size_nb;
amrparse->wide = FALSE;
*skipsize = amrparse->header = 6;
} else
return FALSE;
gst_amrparse_set_src_caps (amrparse);
return TRUE;
}
/**
* gst_amrparse_check_valid_frame:
* @parse: #GstBaseParse.
* @buffer: #GstBuffer.
* @framesize: Output variable where the found frame size is put.
* @skipsize: Output variable which tells how much data needs to be skipped
* until a frame header is found.
*
* Implementation of "check_valid_frame" vmethod in #GstBaseParse class.
*
* Returns: TRUE if the given data contains valid frame.
*/
gboolean
gst_amrparse_check_valid_frame (GstBaseParse * parse,
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
{
GstBuffer *buffer;
const guint8 *data;
gint fsize, mode, dsize;
GstAmrParse *amrparse;
amrparse = GST_AMRPARSE (parse);
buffer = frame->buffer;
data = GST_BUFFER_DATA (buffer);
dsize = GST_BUFFER_SIZE (buffer);
GST_LOG ("buffer: %d bytes", dsize);
if (amrparse->need_header) {
if (dsize >= AMR_MIME_HEADER_SIZE &&
gst_amrparse_parse_header (amrparse, data, skipsize)) {
amrparse->need_header = FALSE;
gst_base_parse_set_frame_props (GST_BASE_PARSE (amrparse), 50, 1, 2, 2);
} else {
GST_WARNING ("media doesn't look like a AMR format");
}
/* We return FALSE, so this frame won't get pushed forward. Instead,
the "skip" value is set, so next time we will receive a valid frame. */
return FALSE;
}
/* Does this look like a possible frame header candidate? */
if ((data[0] & 0x83) == 0) {
/* Yep. Retrieve the frame size */
mode = (data[0] >> 3) & 0x0F;
fsize = amrparse->block_size[mode] + 1; /* +1 for the header byte */
/* We recognize this data as a valid frame when:
* - We are in sync. There is no need for extra checks then
* - We are in EOS. There might not be enough data to check next frame
* - Sync is lost, but the following data after this frame seem
* to contain a valid header as well (and there is enough data to
* perform this check)
*/
if (fsize &&
(GST_BASE_PARSE_FRAME_SYNC (frame) || GST_BASE_PARSE_FRAME_DRAIN (frame)
|| (dsize > fsize && (data[fsize] & 0x83) == 0))) {
*framesize = fsize;
return TRUE;
}
}
GST_LOG ("sync lost");
return FALSE;
}
/**
* gst_amrparse_parse_frame:
* @parse: #GstBaseParse.
* @buffer: #GstBuffer.
*
* Implementation of "parse" vmethod in #GstBaseParse class.
*
* Returns: #GstFlowReturn defining the parsing status.
*/
GstFlowReturn
gst_amrparse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
{
return GST_FLOW_OK;
}
/**
* gst_amrparse_start:
* @parse: #GstBaseParse.
*
* Implementation of "start" vmethod in #GstBaseParse class.
*
* Returns: TRUE on success.
*/
gboolean
gst_amrparse_start (GstBaseParse * parse)
{
GstAmrParse *amrparse;
amrparse = GST_AMRPARSE (parse);
GST_DEBUG ("start");
amrparse->need_header = TRUE;
amrparse->header = 0;
return TRUE;
}
/**
* gst_amrparse_stop:
* @parse: #GstBaseParse.
*
* Implementation of "stop" vmethod in #GstBaseParse class.
*
* Returns: TRUE on success.
*/
gboolean
gst_amrparse_stop (GstBaseParse * parse)
{
GstAmrParse *amrparse;
amrparse = GST_AMRPARSE (parse);
GST_DEBUG ("stop");
amrparse->need_header = TRUE;
amrparse->header = 0;
return TRUE;
}

View file

@ -1,82 +0,0 @@
/* GStreamer Adaptive Multi-Rate parser
* Copyright (C) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
* Copyright (C) 2008 Nokia Corporation. All rights reserved.
*
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* 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.
*/
#ifndef __GST_AMRPARSE_H__
#define __GST_AMRPARSE_H__
#include <gst/gst.h>
#include <gst/baseparse/gstbaseparse.h>
G_BEGIN_DECLS
#define GST_TYPE_AMRPARSE \
(gst_amrparse_get_type())
#define GST_AMRPARSE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_AMRPARSE, GstAmrParse))
#define GST_AMRPARSE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_AMRPARSE, GstAmrParseClass))
#define GST_IS_AMRPARSE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_AMRPARSE))
#define GST_IS_AMRPARSE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_AMRPARSE))
typedef struct _GstAmrParse GstAmrParse;
typedef struct _GstAmrParseClass GstAmrParseClass;
/**
* GstAmrParse:
* @element: the parent element.
* @block_size: Pointer to frame size lookup table.
* @need_header: Tells whether the MIME header should be read in the beginning.
* @wide: Wideband mode.
* @eos: Indicates the EOS situation. Set when EOS event is received.
* @sync: Tells whether the parser is in sync.
* @framecount: Total amount of frames handled.
* @bytecount: Total amount of bytes handled.
* @ts: Timestamp of the current media.
*
* The opaque GstAacParse data structure.
*/
struct _GstAmrParse {
GstBaseParse element;
const gint *block_size;
gboolean need_header;
gint header;
gboolean wide;
};
/**
* GstAmrParseClass:
* @parent_class: Element parent class.
*
* The opaque GstAmrParseClass data structure.
*/
struct _GstAmrParseClass {
GstBaseParseClass parent_class;
};
GType gst_amrparse_get_type (void);
G_END_DECLS
#endif /* __GST_AMRPARSE_H__ */

View file

@ -1,451 +0,0 @@
/* GStreamer DCA parser
* Copyright (C) 2010 Tim-Philipp Müller <tim centricular net>
*
* 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.
*/
/**
* SECTION:element-dcaparse
* @short_description: DCA (DTS Coherent Acoustics) parser
* @see_also: #GstAmrParse, #GstAACParse, #GstAc3Parse
*
* This is a DCA (DTS Coherent Acoustics) parser.
*
* <refsect2>
* <title>Example launch line</title>
* |[
* gst-launch filesrc location=abc.dts ! dcaparse ! dtsdec ! audioresample ! audioconvert ! autoaudiosink
* ]|
* </refsect2>
*/
/* TODO:
* - should accept framed and unframed input (needs decodebin fixes first)
* - seeking in raw .dts files doesn't seem to work, but duration estimate ok
*
* - if frames have 'odd' durations, the frame durations (plus timestamps)
* aren't adjusted up occasionally to make up for rounding error gaps.
* (e.g. if 512 samples per frame @ 48kHz = 10.666666667 ms/frame)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include "gstdcaparse.h"
#include <gst/base/gstbytereader.h>
#include <gst/base/gstbitreader.h>
GST_DEBUG_CATEGORY_STATIC (dca_parse_debug);
#define GST_CAT_DEFAULT dca_parse_debug
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-dts,"
" framed = (boolean) true,"
" channels = (int) [ 1, 8 ],"
" rate = (int) [ 8000, 192000 ],"
" depth = (int) { 14, 16 },"
" endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }"));
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-dts, framed = (boolean) false"));
static void gst_dca_parse_finalize (GObject * object);
static gboolean gst_dca_parse_start (GstBaseParse * parse);
static gboolean gst_dca_parse_stop (GstBaseParse * parse);
static gboolean gst_dca_parse_check_valid_frame (GstBaseParse * parse,
GstBaseParseFrame * frame, guint * size, gint * skipsize);
static GstFlowReturn gst_dca_parse_parse_frame (GstBaseParse * parse,
GstBaseParseFrame * frame);
GST_BOILERPLATE (GstDcaParse, gst_dca_parse, GstBaseParse, GST_TYPE_BASE_PARSE);
static void
gst_dca_parse_base_init (gpointer klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_template));
gst_element_class_set_details_simple (element_class,
"DTS Coherent Acoustics audio stream parser", "Codec/Parser/Audio",
"DCA parser", "Tim-Philipp Müller <tim centricular net>");
}
static void
gst_dca_parse_class_init (GstDcaParseClass * klass)
{
GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GST_DEBUG_CATEGORY_INIT (dca_parse_debug, "dcaparse", 0,
"DCA audio stream parser");
object_class->finalize = gst_dca_parse_finalize;
parse_class->start = GST_DEBUG_FUNCPTR (gst_dca_parse_start);
parse_class->stop = GST_DEBUG_FUNCPTR (gst_dca_parse_stop);
parse_class->check_valid_frame =
GST_DEBUG_FUNCPTR (gst_dca_parse_check_valid_frame);
parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_dca_parse_parse_frame);
}
static void
gst_dca_parse_reset (GstDcaParse * dcaparse)
{
dcaparse->channels = -1;
dcaparse->rate = -1;
dcaparse->depth = -1;
dcaparse->endianness = -1;
dcaparse->block_size = -1;
dcaparse->frame_size = -1;
dcaparse->last_sync = 0;
}
static void
gst_dca_parse_init (GstDcaParse * dcaparse, GstDcaParseClass * klass)
{
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (dcaparse),
DCA_MIN_FRAMESIZE);
gst_dca_parse_reset (dcaparse);
}
static void
gst_dca_parse_finalize (GObject * object)
{
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static gboolean
gst_dca_parse_start (GstBaseParse * parse)
{
GstDcaParse *dcaparse = GST_DCA_PARSE (parse);
GST_DEBUG_OBJECT (parse, "starting");
gst_dca_parse_reset (dcaparse);
return TRUE;
}
static gboolean
gst_dca_parse_stop (GstBaseParse * parse)
{
GST_DEBUG_OBJECT (parse, "stopping");
return TRUE;
}
static gboolean
gst_dca_parse_parse_header (GstDcaParse * dcaparse,
const GstByteReader * reader, guint * frame_size,
guint * sample_rate, guint * channels, guint * depth,
gint * endianness, guint * num_blocks, guint * samples_per_block,
gboolean * terminator)
{
static const int sample_rates[16] = { 0, 8000, 16000, 32000, 0, 0, 11025,
22050, 44100, 0, 0, 12000, 24000, 48000, 96000, 192000
};
static const guint8 channels_table[16] = { 1, 2, 2, 2, 2, 3, 3, 4, 4, 5,
6, 6, 6, 7, 8, 8
};
GstByteReader r = *reader;
guint16 hdr[8];
guint32 marker;
guint chans, lfe, i;
if (gst_byte_reader_get_remaining (&r) < (4 + sizeof (hdr)))
return FALSE;
marker = gst_byte_reader_peek_uint32_be_unchecked (&r);
/* raw big endian or 14-bit big endian */
if (marker == 0x7FFE8001 || marker == 0x1FFFE800) {
for (i = 0; i < G_N_ELEMENTS (hdr); ++i)
hdr[i] = gst_byte_reader_get_uint16_be_unchecked (&r);
} else
/* raw little endian or 14-bit little endian */
if (marker == 0xFE7F0180 || marker == 0xFF1F00E8) {
for (i = 0; i < G_N_ELEMENTS (hdr); ++i)
hdr[i] = gst_byte_reader_get_uint16_le_unchecked (&r);
} else {
return FALSE;
}
GST_LOG_OBJECT (dcaparse, "dts sync marker 0x%08x at offset %u", marker,
gst_byte_reader_get_pos (reader));
/* 14-bit mode */
if (marker == 0x1FFFE800 || marker == 0xFF1F00E8) {
if ((hdr[2] & 0xFFF0) != 0x07F0)
return FALSE;
/* discard top 2 bits (2 void), shift in 2 */
hdr[0] = (hdr[0] << 2) | ((hdr[1] >> 12) & 0x0003);
/* discard top 4 bits (2 void, 2 shifted into hdr[0]), shift in 4 etc. */
hdr[1] = (hdr[1] << 4) | ((hdr[2] >> 10) & 0x000F);
hdr[2] = (hdr[2] << 6) | ((hdr[3] >> 8) & 0x003F);
hdr[3] = (hdr[3] << 8) | ((hdr[4] >> 6) & 0x00FF);
hdr[4] = (hdr[4] << 10) | ((hdr[5] >> 4) & 0x03FF);
hdr[5] = (hdr[5] << 12) | ((hdr[6] >> 2) & 0x0FFF);
hdr[6] = (hdr[6] << 14) | ((hdr[7] >> 0) & 0x3FFF);
g_assert (hdr[0] == 0x7FFE && hdr[1] == 0x8001);
}
GST_LOG_OBJECT (dcaparse, "frame header: %04x%04x%04x%04x",
hdr[2], hdr[3], hdr[4], hdr[5]);
*terminator = (hdr[2] & 0x80) ? FALSE : TRUE;
*samples_per_block = ((hdr[2] >> 10) & 0x1f) + 1;
*num_blocks = ((hdr[2] >> 2) & 0x7F) + 1;
*frame_size = (((hdr[2] & 0x03) << 12) | (hdr[3] >> 4)) + 1;
chans = ((hdr[3] & 0x0F) << 2) | (hdr[4] >> 14);
*sample_rate = sample_rates[(hdr[4] >> 10) & 0x0F];
lfe = (hdr[5] >> 9) & 0x03;
GST_TRACE_OBJECT (dcaparse, "frame size %u, num_blocks %u, rate %u, "
"samples per block %u", *frame_size, *num_blocks, *sample_rate,
*samples_per_block);
if (*num_blocks < 6 || *frame_size < 96 || *sample_rate == 0)
return FALSE;
if (marker == 0x1FFFE800 || marker == 0xFF1F00E8)
*frame_size = (*frame_size * 16) / 14; /* FIXME: round up? */
if (chans < G_N_ELEMENTS (channels_table))
*channels = channels_table[chans] + ((lfe) ? 1 : 0);
else
*channels = 0;
if (depth)
*depth = (marker == 0x1FFFE800 || marker == 0xFF1F00E8) ? 14 : 16;
if (endianness)
*endianness = (marker == 0xFE7F0180 || marker == 0xFF1F00E8) ?
G_LITTLE_ENDIAN : G_BIG_ENDIAN;
GST_TRACE_OBJECT (dcaparse, "frame size %u, channels %u, rate %u, "
"num_blocks %u, samples_per_block %u", *frame_size, *channels,
*sample_rate, *num_blocks, *samples_per_block);
return TRUE;
}
static gint
gst_dca_parse_find_sync (GstDcaParse * dcaparse, GstByteReader * reader,
const GstBuffer * buf, guint32 * sync)
{
guint32 best_sync = 0;
guint best_offset = G_MAXUINT;
gint off;
/* FIXME: verify syncs via _parse_header() here already */
/* Raw little endian */
off = gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0xfe7f0180,
0, GST_BUFFER_SIZE (buf));
if (off >= 0 && off < best_offset) {
best_offset = off;
best_sync = 0xfe7f0180;
}
/* Raw big endian */
off = gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x7ffe8001,
0, GST_BUFFER_SIZE (buf));
if (off >= 0 && off < best_offset) {
best_offset = off;
best_sync = 0x7ffe8001;
}
/* FIXME: check next 2 bytes as well for 14-bit formats (but then don't
* forget to adjust the *skipsize= in _check_valid_frame() */
/* 14-bit little endian */
off = gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0xff1f00e8,
0, GST_BUFFER_SIZE (buf));
if (off >= 0 && off < best_offset) {
best_offset = off;
best_sync = 0xff1f00e8;
}
/* 14-bit big endian */
off = gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x1fffe800,
0, GST_BUFFER_SIZE (buf));
if (off >= 0 && off < best_offset) {
best_offset = off;
best_sync = 0x1fffe800;
}
if (best_offset == G_MAXUINT)
return -1;
*sync = best_sync;
return best_offset;
}
static gboolean
gst_dca_parse_check_valid_frame (GstBaseParse * parse,
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
{
GstDcaParse *dcaparse = GST_DCA_PARSE (parse);
GstBuffer *buf = frame->buffer;
GstByteReader r = GST_BYTE_READER_INIT_FROM_BUFFER (buf);
gboolean parser_draining;
gboolean parser_in_sync;
gboolean terminator;
guint32 sync = 0;
guint size, rate, chans, num_blocks, samples_per_block;
gint off = -1;
if (G_UNLIKELY (GST_BUFFER_SIZE (buf) < 16))
return FALSE;
parser_in_sync = GST_BASE_PARSE_FRAME_SYNC (frame);
if (G_LIKELY (parser_in_sync && dcaparse->last_sync != 0)) {
off = gst_byte_reader_masked_scan_uint32 (&r, 0xffffffff,
dcaparse->last_sync, 0, GST_BUFFER_SIZE (buf));
}
if (G_UNLIKELY (off < 0)) {
off = gst_dca_parse_find_sync (dcaparse, &r, buf, &sync);
}
/* didn't find anything that looks like a sync word, skip */
if (off < 0) {
*skipsize = GST_BUFFER_SIZE (buf) - 3;
GST_DEBUG_OBJECT (dcaparse, "no sync, skipping %d bytes", *skipsize);
return FALSE;
}
GST_LOG_OBJECT (parse, "possible sync %08x at buffer offset %d", sync, off);
/* possible frame header, but not at offset 0? skip bytes before sync */
if (off > 0) {
*skipsize = off;
return FALSE;
}
/* make sure the values in the frame header look sane */
if (!gst_dca_parse_parse_header (dcaparse, &r, &size, &rate, &chans, NULL,
NULL, &num_blocks, &samples_per_block, &terminator)) {
*skipsize = 4;
return FALSE;
}
GST_LOG_OBJECT (parse, "got frame, sync %08x, size %u, rate %d, channels %d",
sync, size, rate, chans);
*framesize = size;
dcaparse->last_sync = sync;
parser_draining = GST_BASE_PARSE_FRAME_DRAIN (frame);
if (!parser_in_sync && !parser_draining) {
/* check for second frame to be sure */
GST_DEBUG_OBJECT (dcaparse, "resyncing; checking next frame syncword");
if (GST_BUFFER_SIZE (buf) >= (size + 16)) {
guint s2, r2, c2, n2, s3;
gboolean t;
GST_MEMDUMP ("buf", GST_BUFFER_DATA (buf), size + 16);
gst_byte_reader_init_from_buffer (&r, buf);
gst_byte_reader_skip_unchecked (&r, size);
if (!gst_dca_parse_parse_header (dcaparse, &r, &s2, &r2, &c2, NULL, NULL,
&n2, &s3, &t)) {
GST_DEBUG_OBJECT (dcaparse, "didn't find second syncword");
*skipsize = 4;
return FALSE;
}
/* ok, got sync now, let's assume constant frame size */
gst_base_parse_set_min_frame_size (parse, size);
} else {
/* FIXME: baseparse always seems to hand us buffers of min_frame_size
* bytes, which is unhelpful here */
GST_LOG_OBJECT (dcaparse, "next sync out of reach (%u < %u)",
GST_BUFFER_SIZE (buf), size + 16);
/* *skipsize = 0; */
/* return FALSE; */
}
}
return TRUE;
}
static GstFlowReturn
gst_dca_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
{
GstDcaParse *dcaparse = GST_DCA_PARSE (parse);
GstBuffer *buf = frame->buffer;
GstByteReader r = GST_BYTE_READER_INIT_FROM_BUFFER (buf);
guint size, rate, chans, depth, block_size, num_blocks, samples_per_block;
gint endianness;
gboolean terminator;
if (!gst_dca_parse_parse_header (dcaparse, &r, &size, &rate, &chans, &depth,
&endianness, &num_blocks, &samples_per_block, &terminator))
goto broken_header;
block_size = num_blocks * samples_per_block;
if (G_UNLIKELY (dcaparse->rate != rate || dcaparse->channels != chans
|| dcaparse->depth != depth || dcaparse->endianness != endianness
|| (!terminator && dcaparse->block_size != block_size)
|| (size != dcaparse->frame_size))) {
GstCaps *caps;
caps = gst_caps_new_simple ("audio/x-dts",
"framed", G_TYPE_BOOLEAN, TRUE,
"rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, chans,
"endianness", G_TYPE_INT, endianness, "depth", G_TYPE_INT, depth,
"block-size", G_TYPE_INT, block_size, "frame-size", G_TYPE_INT, size,
NULL);
gst_buffer_set_caps (buf, caps);
gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps);
gst_caps_unref (caps);
dcaparse->rate = rate;
dcaparse->channels = chans;
dcaparse->depth = depth;
dcaparse->endianness = endianness;
dcaparse->block_size = block_size;
dcaparse->frame_size = size;
gst_base_parse_set_frame_props (parse, rate, block_size, 0, 0);
}
return GST_FLOW_OK;
/* ERRORS */
broken_header:
{
/* this really shouldn't ever happen */
GST_ELEMENT_ERROR (parse, STREAM, DECODE, (NULL), (NULL));
return GST_FLOW_ERROR;
}
}

View file

@ -1,78 +0,0 @@
/* GStreamer DCA parser
* Copyright (C) 2010 Tim-Philipp Müller <tim centricular net>
*
* 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.
*/
#ifndef __GST_DCA_PARSE_H__
#define __GST_DCA_PARSE_H__
#include <gst/gst.h>
#include <gst/baseparse/gstbaseparse.h>
G_BEGIN_DECLS
#define GST_TYPE_DCA_PARSE \
(gst_dca_parse_get_type())
#define GST_DCA_PARSE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_DCA_PARSE, GstDcaParse))
#define GST_DCA_PARSE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_DCA_PARSE, GstDcaParseClass))
#define GST_IS_DCA_PARSE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_DCA_PARSE))
#define GST_IS_DCA_PARSE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_DCA_PARSE))
#define DCA_MIN_FRAMESIZE 96
#define DCA_MAX_FRAMESIZE 18725 /* 16384*16/14 */
typedef struct _GstDcaParse GstDcaParse;
typedef struct _GstDcaParseClass GstDcaParseClass;
/**
* GstDcaParse:
*
* The opaque GstDcaParse object
*/
struct _GstDcaParse {
GstBaseParse baseparse;
/*< private >*/
gint rate;
gint channels;
gint depth;
gint endianness;
gint block_size;
gint frame_size;
guint32 last_sync;
};
/**
* GstDcaParseClass:
* @parent_class: Element parent class.
*
* The opaque GstDcaParseClass data structure.
*/
struct _GstDcaParseClass {
GstBaseParseClass baseparse_class;
};
GType gst_dca_parse_get_type (void);
G_END_DECLS
#endif /* __GST_DCA_PARSE_H__ */

File diff suppressed because it is too large Load diff

View file

@ -1,92 +0,0 @@
/* GStreamer
*
* Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
* Copyright (C) 2009 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
* Copyright (C) 2009 Nokia Corporation. All rights reserved.
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* 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.
*/
#ifndef __GST_FLAC_PARSE_H__
#define __GST_FLAC_PARSE_H__
#include <gst/gst.h>
#include <gst/baseparse/gstbaseparse.h>
G_BEGIN_DECLS
#define GST_TYPE_FLAC_PARSE (gst_flac_parse_get_type())
#define GST_FLAC_PARSE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FLAC_PARSE,GstFlacParse))
#define GST_FLAC_PARSE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FLAC_PARSE,GstFlacParseClass))
#define GST_FLAC_PARSE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_FLAC_PARSE,GstFlacParseClass))
#define GST_IS_FLAC_PARSE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FLAC_PARSE))
#define GST_IS_FLAC_PARSE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FLAC_PARSE))
#define GST_FLAC_PARSE_CAST(obj) ((GstFlacParse *)(obj))
typedef struct _GstFlacParse GstFlacParse;
typedef struct _GstFlacParseClass GstFlacParseClass;
typedef enum {
GST_FLAC_PARSE_STATE_INIT,
GST_FLAC_PARSE_STATE_HEADERS,
GST_FLAC_PARSE_STATE_GENERATE_HEADERS,
GST_FLAC_PARSE_STATE_DATA
} GstFlacParseState;
typedef struct {
guint8 type;
} GstFlacParseSubFrame;
struct _GstFlacParse {
GstBaseParse parent;
/* Properties */
gboolean check_frame_checksums;
GstFlacParseState state;
gint64 upstream_length;
/* STREAMINFO content */
guint16 min_blocksize, max_blocksize;
guint32 min_framesize, max_framesize;
guint32 samplerate;
guint8 channels;
guint8 bps;
guint64 total_samples;
/* Current frame */
guint64 offset;
guint8 blocking_strategy;
guint16 block_size;
guint64 sample_number;
GstTagList *tags;
GList *headers;
GstBuffer *seektable;
};
struct _GstFlacParseClass {
GstBaseParseClass parent_class;
};
GType gst_flac_parse_get_type (void);
G_END_DECLS
#endif /* __GST_FLAC_PARSE_H__ */

File diff suppressed because it is too large Load diff

View file

@ -1,111 +0,0 @@
/* GStreamer MPEG audio parser
* Copyright (C) 2006-2007 Jan Schmidt <thaytan@mad.scientist.com>
* Copyright (C) 2010 Mark Nauwelaerts <mnauw users sf net>
* Copyright (C) 2010 Nokia Corporation. All rights reserved.
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* 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.
*/
#ifndef __GST_MPEG_AUDIO_PARSE_H__
#define __GST_MPEG_AUDIO_PARSE_H__
#include <gst/gst.h>
#include <gst/baseparse/gstbaseparse.h>
G_BEGIN_DECLS
#define GST_TYPE_MPEG_AUDIO_PARSE \
(gst_mpeg_audio_parse_get_type())
#define GST_MPEG_AUDIO_PARSE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_MPEG_AUDIO_PARSE, GstMpegAudioParse))
#define GST_MPEG_AUDIO_PARSE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_MPEG_AUDIO_PARSE, GstMpegAudioParseClass))
#define GST_IS_MPEG_AUDIO_PARSE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_MPEG_AUDIO_PARSE))
#define GST_IS_MPEG_AUDIO_PARSE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_MPEG_AUDIO_PARSE))
typedef struct _GstMpegAudioParse GstMpegAudioParse;
typedef struct _GstMpegAudioParseClass GstMpegAudioParseClass;
/**
* GstMpegAudioParse:
*
* The opaque GstMpegAudioParse object
*/
struct _GstMpegAudioParse {
GstBaseParse baseparse;
/*< private >*/
gint rate;
gint channels;
gint layer;
gint version;
GstClockTime max_bitreservoir;
/* samples per frame */
gint spf;
gboolean sent_codec_tag;
guint last_posted_bitrate;
gint last_posted_crc, last_crc;
guint last_posted_channel_mode, last_mode;
/* Bitrate from non-vbr headers */
guint32 hdr_bitrate;
/* Xing info */
guint32 xing_flags;
guint32 xing_frames;
GstClockTime xing_total_time;
guint32 xing_bytes;
/* percent -> filepos mapping */
guchar xing_seek_table[100];
/* filepos -> percent mapping */
guint16 xing_seek_table_inverse[256];
guint32 xing_vbr_scale;
guint xing_bitrate;
/* VBRI info */
guint32 vbri_frames;
GstClockTime vbri_total_time;
guint32 vbri_bytes;
guint vbri_bitrate;
guint vbri_seek_points;
guint32 *vbri_seek_table;
gboolean vbri_valid;
/* LAME info */
guint32 encoder_delay;
guint32 encoder_padding;
};
/**
* GstMpegAudioParseClass:
* @parent_class: Element parent class.
*
* The opaque GstMpegAudioParseClass data structure.
*/
struct _GstMpegAudioParseClass {
GstBaseParseClass baseparse_class;
};
GType gst_mpeg_audio_parse_get_type (void);
G_END_DECLS
#endif /* __GST_MPEG_AUDIO_PARSE_H__ */

View file

@ -1,57 +0,0 @@
/* GStreamer audio parsers
* Copyright (C) 2009 Tim-Philipp Müller <tim centricular net>
*
* 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstaacparse.h"
#include "gstamrparse.h"
#include "gstac3parse.h"
#include "gstdcaparse.h"
#include "gstflacparse.h"
#include "gstmpegaudioparse.h"
static gboolean
plugin_init (GstPlugin * plugin)
{
gboolean ret;
ret = gst_element_register (plugin, "aacparse",
GST_RANK_PRIMARY + 1, GST_TYPE_AACPARSE);
ret &= gst_element_register (plugin, "amrparse",
GST_RANK_PRIMARY + 1, GST_TYPE_AMRPARSE);
ret &= gst_element_register (plugin, "ac3parse",
GST_RANK_PRIMARY + 1, GST_TYPE_AC3_PARSE);
ret &= gst_element_register (plugin, "dcaparse",
GST_RANK_PRIMARY + 1, GST_TYPE_DCA_PARSE);
ret &= gst_element_register (plugin, "flacparse",
GST_RANK_PRIMARY + 1, GST_TYPE_FLAC_PARSE);
ret &= gst_element_register (plugin, "mpegaudioparse",
GST_RANK_PRIMARY + 2, GST_TYPE_MPEG_AUDIO_PARSE);
return ret;
}
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"audioparsersbad",
"audioparsers",
plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);

View file

@ -154,15 +154,11 @@ check_PROGRAMS = \
$(check_ofa) \
$(check_timidity) \
$(check_kate) \
elements/aacparse \
elements/ac3parse \
elements/amrparse \
elements/autoconvert \
elements/autovideoconvert \
elements/asfmux \
elements/camerabin \
elements/dataurisrc \
elements/flacparse \
elements/legacyresample \
$(check_jifmux) \
elements/jpegparse \
@ -171,7 +167,6 @@ check_PROGRAMS = \
elements/mxfdemux \
elements/mxfmux \
elements/id3mux \
elements/mpegaudioparse \
pipelines/mxf \
$(check_mimic) \
elements/rtpmux \
@ -237,23 +232,6 @@ elements_rtpmux_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstrtp-0.10 $(GST_BASE_LIBS)
elements_assrender_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(AM_CFLAGS)
elements_assrender_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstvideo-0.10 -lgstapp-0.10 $(GST_BASE_LIBS) $(LDADD)
# parser unit test convenience lib
noinst_LTLIBRARIES = libparser.la
libparser_la_SOURCES = elements/parser.c elements/parser.h
libparser_la_CFLAGS = \
-I$(top_srcdir)/tests/check \
$(GST_CHECK_CFLAGS) $(GST_OPTION_CFLAGS)
elements_aacparse_LDADD = libparser.la $(LDADD)
elements_ac3parse_LDADD = libparser.la $(LDADD)
elements_amrparse_LDADD = libparser.la $(LDADD)
elements_flacparse_LDADD = libparser.la $(LDADD)
elements_mpegaudioparse_LDADD = libparser.la $(LDADD)
EXTRA_DIST = gst-plugins-bad.supp
orc_cog_CFLAGS = $(ORC_CFLAGS)

View file

@ -1,7 +1,4 @@
.dirstamp
aacparse
ac3parse
amrparse
asfmux
assrender
autoconvert
@ -12,7 +9,6 @@ deinterleave
dataurisrc
faac
faad
flacparse
gdpdepay
gdppay
id3mux
@ -22,8 +18,8 @@ jifmux
jpegparse
kate
legacyresample
logoinsert
mpeg2enc
mpegaudioparse
mplex
mxfdemux
mxfmux

View file

@ -1,240 +0,0 @@
/*
* GStreamer
*
* unit test for aacparse
*
* Copyright (C) 2008 Nokia Corporation. All rights reserved.
*
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* 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.
*/
#include <gst/check/gstcheck.h>
#include "parser.h"
#define SRC_CAPS_CDATA "audio/mpeg, framed=(boolean)false, codec_data=(buffer)1190"
#define SRC_CAPS_TMPL "audio/mpeg, framed=(boolean)false, mpegversion=(int){2,4}"
#define SINK_CAPS \
"audio/mpeg, framed=(boolean)true"
#define SINK_CAPS_MPEG2 \
"audio/mpeg, framed=(boolean)true, mpegversion=2, rate=48000, channels=2"
#define SINK_CAPS_MPEG4 \
"audio/mpeg, framed=(boolean)true, mpegversion=4, rate=96000, channels=2"
#define SINK_CAPS_TMPL "audio/mpeg, framed=(boolean)true, mpegversion=(int){2,4}"
GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (SINK_CAPS_TMPL)
);
GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (SRC_CAPS_TMPL)
);
/* some data */
static guint8 adif_header[] = {
'A', 'D', 'I', 'F'
};
static guint8 adts_frame_mpeg2[] = {
0xff, 0xf9, 0x4c, 0x80, 0x01, 0xff, 0xfc, 0x21, 0x10, 0xd3, 0x20, 0x0c,
0x32, 0x00, 0xc7
};
static guint8 adts_frame_mpeg4[] = {
0xff, 0xf1, 0x4c, 0x80, 0x01, 0xff, 0xfc, 0x21, 0x10, 0xd3, 0x20, 0x0c,
0x32, 0x00, 0xc7
};
static guint8 garbage_frame[] = {
0xff, 0xff, 0xff, 0xff, 0xff
};
/*
* Test if the parser pushes data with ADIF header properly and detects the
* stream to MPEG4 properly.
*/
GST_START_TEST (test_parse_adif_normal)
{
GstParserTest ptest;
/* ADIF header */
gst_parser_test_init (&ptest, adif_header, sizeof (adif_header), 1);
/* well, no garbage, followed by random data */
ptest.series[2].size = 100;
ptest.series[2].num = 3;
/* and we do not really expect output frames */
ptest.framed = FALSE;
/* Check that the negotiated caps are as expected */
/* For ADIF parser assumes that data is always version 4 */
ptest.sink_caps =
gst_caps_from_string (SINK_CAPS_MPEG4 ", stream-format=(string)adif");
gst_parser_test_run (&ptest, NULL);
gst_caps_unref (ptest.sink_caps);
}
GST_END_TEST;
GST_START_TEST (test_parse_adts_normal)
{
gst_parser_test_normal (adts_frame_mpeg4, sizeof (adts_frame_mpeg4));
}
GST_END_TEST;
GST_START_TEST (test_parse_adts_drain_single)
{
gst_parser_test_drain_single (adts_frame_mpeg4, sizeof (adts_frame_mpeg4));
}
GST_END_TEST;
GST_START_TEST (test_parse_adts_drain_garbage)
{
gst_parser_test_drain_garbage (adts_frame_mpeg4, sizeof (adts_frame_mpeg4),
garbage_frame, sizeof (garbage_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_adts_split)
{
gst_parser_test_split (adts_frame_mpeg4, sizeof (adts_frame_mpeg4));
}
GST_END_TEST;
GST_START_TEST (test_parse_adts_skip_garbage)
{
gst_parser_test_skip_garbage (adts_frame_mpeg4, sizeof (adts_frame_mpeg4),
garbage_frame, sizeof (garbage_frame));
}
GST_END_TEST;
/*
* Test if the src caps are set according to stream format (MPEG version).
*/
GST_START_TEST (test_parse_adts_detect_mpeg_version)
{
gst_parser_test_output_caps (adts_frame_mpeg2, sizeof (adts_frame_mpeg2),
NULL, SINK_CAPS_MPEG2 ", stream-format=(string)adts");
}
GST_END_TEST;
#define structure_get_int(s,f) \
(g_value_get_int(gst_structure_get_value(s,f)))
#define fail_unless_structure_field_int_equals(s,field,num) \
fail_unless_equals_int (structure_get_int(s,field), num)
/*
* Test if the parser handles raw stream and codec_data info properly.
*/
GST_START_TEST (test_parse_handle_codec_data)
{
GstCaps *caps;
GstStructure *s;
const gchar *stream_format;
/* Push random data. It should get through since the parser should be
* initialized because it got codec_data in the caps */
caps = gst_parser_test_get_output_caps (NULL, 100, SRC_CAPS_CDATA);
fail_unless (caps != NULL);
/* Check that the negotiated caps are as expected */
/* When codec_data is present, parser assumes that data is version 4 */
GST_LOG ("aac output caps: %" GST_PTR_FORMAT, caps);
s = gst_caps_get_structure (caps, 0);
fail_unless (gst_structure_has_name (s, "audio/mpeg"));
fail_unless_structure_field_int_equals (s, "mpegversion", 4);
fail_unless_structure_field_int_equals (s, "channels", 2);
fail_unless_structure_field_int_equals (s, "rate", 48000);
fail_unless (gst_structure_has_field (s, "codec_data"));
fail_unless (gst_structure_has_field (s, "stream-format"));
stream_format = gst_structure_get_string (s, "stream-format");
fail_unless (strcmp (stream_format, "raw") == 0);
gst_caps_unref (caps);
}
GST_END_TEST;
static Suite *
aacparse_suite (void)
{
Suite *s = suite_create ("aacparse");
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
/* ADIF tests */
tcase_add_test (tc_chain, test_parse_adif_normal);
/* ADTS tests */
tcase_add_test (tc_chain, test_parse_adts_normal);
tcase_add_test (tc_chain, test_parse_adts_drain_single);
tcase_add_test (tc_chain, test_parse_adts_drain_garbage);
tcase_add_test (tc_chain, test_parse_adts_split);
tcase_add_test (tc_chain, test_parse_adts_skip_garbage);
tcase_add_test (tc_chain, test_parse_adts_detect_mpeg_version);
/* Other tests */
tcase_add_test (tc_chain, test_parse_handle_codec_data);
return s;
}
/*
* TODO:
* - Both push- and pull-modes need to be tested
* * Pull-mode & EOS
*/
int
main (int argc, char **argv)
{
int nf;
Suite *s = aacparse_suite ();
SRunner *sr = srunner_create (s);
gst_check_init (&argc, &argv);
/* init test context */
ctx_factory = "aacparse";
ctx_sink_template = &sinktemplate;
ctx_src_template = &srctemplate;
srunner_run_all (sr, CK_NORMAL);
nf = srunner_ntests_failed (sr);
srunner_free (sr);
return nf;
}

View file

@ -1,163 +0,0 @@
/*
* GStreamer
*
* unit test for ac3parse
*
* Copyright (C) 2008 Nokia Corporation. All rights reserved.
*
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* 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.
*/
#include <gst/check/gstcheck.h>
#include "parser.h"
#define SRC_CAPS_TMPL "audio/x-ac3, framed=(boolean)false"
#define SINK_CAPS_TMPL "audio/x-ac3, framed=(boolean)true"
GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (SINK_CAPS_TMPL)
);
GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (SRC_CAPS_TMPL)
);
/* some data */
static guint8 ac3_frame[512] = {
0x0b, 0x77, 0xb6, 0xa8, 0x10, 0x40, 0x2f, 0x84,
0x29, 0xcb, 0xfe, 0x75, 0x7c, 0xf9, 0xf3, 0xe7,
0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf,
0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f,
0x3e, 0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e,
0x7c, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c,
0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9,
0xf3, 0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3,
0xe7, 0xcf, 0x9f, 0x3e, 0x7c, 0xf9, 0xf3, 0xe7,
0xcf, 0x9f, 0x3e, 0x32, 0xd3, 0xff, 0xc0, 0x06,
0xe9, 0x40, 0x00, 0x6e, 0x94, 0x00, 0x06, 0xe9,
0x40, 0x00, 0x6e, 0x94, 0x00, 0x06, 0xe9, 0x40,
0x00, 0x6e, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static guint8 garbage_frame[] = {
0xff, 0xff, 0xff, 0xff, 0xff
};
GST_START_TEST (test_parse_normal)
{
gst_parser_test_normal (ac3_frame, sizeof (ac3_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_drain_single)
{
gst_parser_test_drain_single (ac3_frame, sizeof (ac3_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_drain_garbage)
{
gst_parser_test_drain_garbage (ac3_frame, sizeof (ac3_frame),
garbage_frame, sizeof (garbage_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_split)
{
gst_parser_test_split (ac3_frame, sizeof (ac3_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_skip_garbage)
{
gst_parser_test_skip_garbage (ac3_frame, sizeof (ac3_frame),
garbage_frame, sizeof (garbage_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_detect_stream)
{
gst_parser_test_output_caps (ac3_frame, sizeof (ac3_frame),
NULL, SINK_CAPS_TMPL ",channels=1,rate=48000");
}
GST_END_TEST;
static Suite *
ac3parse_suite (void)
{
Suite *s = suite_create ("ac3parse");
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_parse_normal);
tcase_add_test (tc_chain, test_parse_drain_single);
tcase_add_test (tc_chain, test_parse_drain_garbage);
tcase_add_test (tc_chain, test_parse_split);
tcase_add_test (tc_chain, test_parse_skip_garbage);
tcase_add_test (tc_chain, test_parse_detect_stream);
return s;
}
/*
* TODO:
* - Both push- and pull-modes need to be tested
* * Pull-mode & EOS
*/
int
main (int argc, char **argv)
{
int nf;
Suite *s = ac3parse_suite ();
SRunner *sr = srunner_create (s);
gst_check_init (&argc, &argv);
/* init test context */
ctx_factory = "ac3parse";
ctx_sink_template = &sinktemplate;
ctx_src_template = &srctemplate;
srunner_run_all (sr, CK_NORMAL);
nf = srunner_ntests_failed (sr);
srunner_free (sr);
return nf;
}

View file

@ -1,327 +0,0 @@
/*
* GStreamer
*
* unit test for amrparse
*
* Copyright (C) 2008 Nokia Corporation. All rights reserved.
*
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* 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.
*/
#include <gst/check/gstcheck.h>
#include "parser.h"
#define SRC_CAPS_NB "audio/x-amr-nb-sh"
#define SRC_CAPS_WB "audio/x-amr-wb-sh"
#define SRC_CAPS_ANY "ANY"
#define SINK_CAPS_NB "audio/AMR, rate=8000 , channels=1"
#define SINK_CAPS_WB "audio/AMR-WB, rate=16000 , channels=1"
#define SINK_CAPS_ANY "ANY"
#define AMR_FRAME_DURATION (GST_SECOND/50)
static GstStaticPadTemplate sinktemplate_nb = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (SINK_CAPS_NB)
);
static GstStaticPadTemplate sinktemplate_wb = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (SINK_CAPS_WB)
);
static GstStaticPadTemplate srctemplate_nb = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (SRC_CAPS_NB)
);
static GstStaticPadTemplate srctemplate_wb = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (SRC_CAPS_WB)
);
/* some data */
static guint8 frame_data_nb[] = {
0x0c, 0x56, 0x3c, 0x52, 0xe0, 0x61, 0xbc, 0x45,
0x0f, 0x98, 0x2e, 0x01, 0x42, 0x02
};
static guint8 frame_data_wb[] = {
0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
};
static guint8 frame_hdr_nb[] = {
'#', '!', 'A', 'M', 'R', '\n'
};
static guint8 frame_hdr_wb[] = {
'#', '!', 'A', 'M', 'R', '-', 'W', 'B', '\n'
};
static guint8 garbage_frame[] = {
0xff, 0xff, 0xff, 0xff, 0xff
};
GST_START_TEST (test_parse_nb_normal)
{
gst_parser_test_normal (frame_data_nb, sizeof (frame_data_nb));
}
GST_END_TEST;
GST_START_TEST (test_parse_nb_drain_single)
{
gst_parser_test_drain_single (frame_data_nb, sizeof (frame_data_nb));
}
GST_END_TEST;
GST_START_TEST (test_parse_nb_drain_garbage)
{
gst_parser_test_drain_garbage (frame_data_nb, sizeof (frame_data_nb),
garbage_frame, sizeof (garbage_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_nb_split)
{
gst_parser_test_split (frame_data_nb, sizeof (frame_data_nb));
}
GST_END_TEST;
GST_START_TEST (test_parse_nb_skip_garbage)
{
gst_parser_test_skip_garbage (frame_data_nb, sizeof (frame_data_nb),
garbage_frame, sizeof (garbage_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_nb_detect_stream)
{
GstParserTest ptest;
GstCaps *old_ctx_caps;
/* no input caps, override ctx */
old_ctx_caps = ctx_input_caps;
ctx_input_caps = NULL;
/* AMR-NB header */
gst_parser_test_init (&ptest, frame_hdr_nb, sizeof (frame_hdr_nb), 1);
/* well, no garbage, followed by real data */
ptest.series[2].data = frame_data_nb;
ptest.series[2].size = sizeof (frame_data_nb);
ptest.series[2].num = 10;
/* header gets dropped, so ... */
/* buffer count will not match */
ptest.framed = FALSE;
/* total size a bit less */
ptest.dropped = sizeof (frame_hdr_nb);
/* Check that the negotiated caps are as expected */
ptest.sink_caps = gst_caps_from_string (SINK_CAPS_NB);
gst_parser_test_run (&ptest, NULL);
gst_caps_unref (ptest.sink_caps);
ctx_input_caps = old_ctx_caps;
}
GST_END_TEST;
GST_START_TEST (test_parse_wb_normal)
{
gst_parser_test_normal (frame_data_wb, sizeof (frame_data_wb));
}
GST_END_TEST;
GST_START_TEST (test_parse_wb_drain_single)
{
gst_parser_test_drain_single (frame_data_wb, sizeof (frame_data_wb));
}
GST_END_TEST;
GST_START_TEST (test_parse_wb_drain_garbage)
{
gst_parser_test_drain_garbage (frame_data_wb, sizeof (frame_data_wb),
garbage_frame, sizeof (garbage_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_wb_split)
{
gst_parser_test_split (frame_data_wb, sizeof (frame_data_wb));
}
GST_END_TEST;
GST_START_TEST (test_parse_wb_skip_garbage)
{
gst_parser_test_skip_garbage (frame_data_wb, sizeof (frame_data_wb),
garbage_frame, sizeof (garbage_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_wb_detect_stream)
{
GstParserTest ptest;
GstCaps *old_ctx_caps;
/* no input caps, override ctx */
old_ctx_caps = ctx_input_caps;
ctx_input_caps = NULL;
/* AMR-WB header */
gst_parser_test_init (&ptest, frame_hdr_wb, sizeof (frame_hdr_wb), 1);
/* well, no garbage, followed by real data */
ptest.series[2].data = frame_data_wb;
ptest.series[2].size = sizeof (frame_data_wb);
ptest.series[2].num = 10;
/* header gets dropped, so ... */
/* buffer count will not match */
ptest.framed = FALSE;
/* total size a bit less */
ptest.dropped = sizeof (frame_hdr_wb);
/* Check that the negotiated caps are as expected */
ptest.sink_caps = gst_caps_from_string (SINK_CAPS_WB);
gst_parser_test_run (&ptest, NULL);
gst_caps_unref (ptest.sink_caps);
ctx_input_caps = old_ctx_caps;
}
GST_END_TEST;
/*
* Create test suite.
*/
static Suite *
amrnb_parse_suite (void)
{
Suite *s = suite_create ("amrwb_parse");
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
/* AMR-NB tests */
tcase_add_test (tc_chain, test_parse_nb_normal);
tcase_add_test (tc_chain, test_parse_nb_drain_single);
tcase_add_test (tc_chain, test_parse_nb_drain_garbage);
tcase_add_test (tc_chain, test_parse_nb_split);
tcase_add_test (tc_chain, test_parse_nb_detect_stream);
tcase_add_test (tc_chain, test_parse_nb_skip_garbage);
return s;
}
static Suite *
amrwb_parse_suite (void)
{
Suite *s = suite_create ("amrnb_parse");
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
/* AMR-WB tests */
tcase_add_test (tc_chain, test_parse_wb_normal);
tcase_add_test (tc_chain, test_parse_wb_drain_single);
tcase_add_test (tc_chain, test_parse_wb_drain_garbage);
tcase_add_test (tc_chain, test_parse_wb_split);
tcase_add_test (tc_chain, test_parse_wb_detect_stream);
tcase_add_test (tc_chain, test_parse_wb_skip_garbage);
return s;
}
/*
* TODO:
* - Both push- and pull-modes need to be tested
* * Pull-mode & EOS
*/
int
main (int argc, char **argv)
{
int nf;
GstCaps *caps;
Suite *s = amrnb_parse_suite ();
SRunner *sr = srunner_create (s);
gst_check_init (&argc, &argv);
/* init test context */
ctx_factory = "amrparse";
ctx_sink_template = &sinktemplate_nb;
ctx_src_template = &srctemplate_nb;
caps = gst_caps_from_string (SRC_CAPS_NB);
g_assert (caps);
ctx_input_caps = caps;
srunner_run_all (sr, CK_NORMAL);
nf = srunner_ntests_failed (sr);
srunner_free (sr);
gst_caps_unref (caps);
s = amrwb_parse_suite ();
sr = srunner_create (s);
ctx_sink_template = &sinktemplate_wb;
ctx_src_template = &srctemplate_wb;
caps = gst_caps_from_string (SRC_CAPS_WB);
g_assert (caps);
ctx_input_caps = caps;
srunner_run_all (sr, CK_NORMAL);
nf += srunner_ntests_failed (sr);
srunner_free (sr);
gst_caps_unref (caps);
return nf;
}

View file

@ -1,299 +0,0 @@
/*
* GStreamer
*
* unit test for flacparse
*
* Copyright (C) 2010 Nokia Corporation. All rights reserved.
*
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* 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.
*/
#include <gst/check/gstcheck.h>
#include "parser.h"
#define SRC_CAPS_TMPL "audio/x-flac, framed=(boolean)false"
#define SINK_CAPS_TMPL "audio/x-flac, framed=(boolean)true"
GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (SINK_CAPS_TMPL)
);
GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (SRC_CAPS_TMPL)
);
/* some data */
static guint8 streaminfo_header[] = {
0x7f, 0x46, 0x4c, 0x41, 0x43, 0x01, 0x00, 0x00,
0x02, 0x66, 0x4c, 0x61, 0x43, 0x00, 0x00, 0x00,
0x22, 0x12, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0a, 0xc4, 0x40, 0xf0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00
};
static guint8 comment_header[] = {
0x84, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
static guint8 flac_frame[] = {
0xff, 0xf8, 0xa9, 0x08, 0x00, 0x50, 0x18, 0x06,
0x6a, 0x0c, 0xce, 0x13, 0x24, 0x19, 0x68, 0x00,
0x46, 0x23, 0x08, 0xca, 0xcb, 0x58, 0x9c, 0x26,
0x92, 0x30, 0xa6, 0x29, 0x8a, 0xca, 0xd1, 0x18,
0xae, 0x26, 0x5c, 0x90, 0x60, 0xbf, 0x11, 0xad,
0x43, 0x02, 0x06, 0x26, 0xbd, 0x35, 0xdd, 0xa3,
0x11, 0xa6, 0x4d, 0x18, 0x8c, 0x9a, 0xe4, 0x62,
0xd9, 0x23, 0x11, 0x8b, 0xcb, 0x56, 0x55, 0x45,
0xc2, 0x18, 0x56, 0xa2, 0xe2, 0xe1, 0x18, 0x99,
0x54, 0x98, 0x46, 0x4d, 0x08, 0x70, 0x9a, 0x64,
0xc4, 0x18, 0x4f, 0x27, 0x64, 0x31, 0x66, 0x27,
0x79, 0x19, 0x3c, 0x8c, 0x8c, 0xa3, 0x44, 0x18,
0x23, 0xd2, 0x6b, 0x8b, 0x64, 0x8c, 0x21, 0x84,
0xd6, 0x23, 0x13, 0x13, 0x2d, 0x44, 0xca, 0x5a,
0x23, 0x09, 0x93, 0x25, 0x18, 0x10, 0x61, 0x38,
0xb4, 0x60, 0x8f, 0x2c, 0x8d, 0x26, 0xb4, 0xc9,
0xd9, 0x19, 0x19, 0x34, 0xd7, 0x31, 0x06, 0x10,
0xc4, 0x30, 0x83, 0x17, 0xe2, 0x0c, 0x2c, 0xc4,
0xc8, 0xc9, 0x3c, 0x5e, 0x93, 0x11, 0x8a, 0x62,
0x64, 0x8c, 0x26, 0x23, 0x22, 0x30, 0x9a, 0x58,
0x86, 0x04, 0x18, 0x4c, 0xab, 0x2b, 0x26, 0x5c,
0x46, 0x88, 0xcb, 0xb1, 0x0d, 0x26, 0xbb, 0x5e,
0x8c, 0xa7, 0x64, 0x31, 0x3d, 0x31, 0x06, 0x26,
0x43, 0x17, 0xa3, 0x08, 0x61, 0x06, 0x17, 0xc4,
0x62, 0xec, 0x4d, 0x4b, 0x2e, 0x2d, 0x4a, 0x94,
0xa4, 0xc2, 0x31, 0x4c, 0x4c, 0x20, 0xc0, 0x83,
0x14, 0x8c, 0x27, 0x8b, 0x31, 0x23, 0x2f, 0x23,
0x11, 0x91, 0x94, 0x65, 0x1a, 0x20, 0xc2, 0x18,
0x86, 0x51, 0x88, 0x62, 0x7c, 0x43, 0x2e, 0xa3,
0x04, 0x18, 0x8c, 0x20, 0xc2, 0xf5, 0xaa, 0x94,
0xc2, 0x31, 0x32, 0xd2, 0xb2, 0xa2, 0x30, 0xba,
0x10, 0xc2, 0xb5, 0x89, 0xa5, 0x18, 0x10, 0x62,
0x9a, 0x10, 0x61, 0x19, 0x72, 0x71, 0x1a, 0xb9,
0x0c, 0x23, 0x46, 0x10, 0x62, 0x78, 0x81, 0x82,
0x3d, 0x75, 0xea, 0x6b, 0x51, 0x8b, 0x61, 0x06,
0x08, 0x62, 0x32, 0x5e, 0x84, 0x18, 0x27, 0x25,
0xc2, 0x6a, 0x4b, 0x51, 0x31, 0x34, 0x5e, 0x29,
0xa1, 0x3c, 0x4d, 0x26, 0x23, 0x10, 0xc2, 0x6b,
0xb1, 0x0d, 0x11, 0xae, 0x46, 0x88, 0x31, 0x35,
0xb1, 0x06, 0x08, 0x79, 0x7e, 0x4f, 0x53, 0x23,
0x29, 0xa4, 0x30, 0x20, 0x30, 0x23, 0x5a, 0xb2,
0xc8, 0x60, 0x9c, 0x93, 0x13, 0x17, 0x92, 0x98,
0x46, 0x13, 0x54, 0x53, 0x08, 0xcb, 0x13, 0xa1,
0x1a, 0x89, 0xe5, 0x46, 0x08, 0x18, 0x10, 0x30,
0x9d, 0x68, 0xc2, 0x1c, 0x46, 0x46, 0xae, 0x62,
0x1a, 0x46, 0x4e, 0x4d, 0x34, 0x8c, 0xbd, 0x26,
0xc0, 0x40, 0x62, 0xc9, 0xa9, 0x31, 0x74, 0xa8,
0x99, 0x52, 0xb0, 0x8c, 0xa9, 0x29, 0x84, 0x61,
0x19, 0x54, 0x43, 0x02, 0x06, 0x04, 0x32, 0xe5,
0x18, 0x21, 0x91, 0x8b, 0xf2, 0xcc, 0x10, 0x30,
0x8e, 0x23, 0xc4, 0x76, 0x43, 0x08, 0x30, 0x83,
0x08, 0x62, 0x6c, 0x4e, 0xe2, 0x35, 0x96, 0xd0,
0x8e, 0x89, 0x97, 0x42, 0x18, 0x91, 0x84, 0x61,
0x3c, 0x26, 0xa5, 0x2c, 0x4e, 0x17, 0x94, 0xb8,
0xb5, 0xa4, 0xcb, 0x88, 0xc9, 0x84, 0x18, 0xb9,
0x84, 0x19, 0x23, 0x2d, 0xa4, 0x64, 0x62, 0x18,
0x86, 0x53, 0x93, 0xcb, 0x30, 0x8f, 0x2f, 0x93,
0x55, 0xc4, 0xd7, 0x08, 0x62, 0xb8, 0x46, 0x84,
0x68, 0xa3, 0x02, 0xaf, 0x33
};
static guint8 garbage_frame[] = {
0xff, 0xff, 0xff, 0xff, 0xff
};
GST_START_TEST (test_parse_flac_normal)
{
gst_parser_test_normal (flac_frame, sizeof (flac_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_flac_drain_single)
{
gst_parser_test_drain_single (flac_frame, sizeof (flac_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_flac_drain_garbage)
{
/* We always output the after frame garbage too because we
* have no way of detecting it
*/
#if 0
gst_parser_test_drain_garbage (flac_frame, sizeof (flac_frame),
garbage_frame, sizeof (garbage_frame));
#endif
guint8 frame[sizeof (flac_frame) + sizeof (garbage_frame)];
memcpy (frame, flac_frame, sizeof (flac_frame));
memcpy (frame + sizeof (flac_frame), garbage_frame, sizeof (garbage_frame));
gst_parser_test_drain_single (frame, sizeof (frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_flac_split)
{
gst_parser_test_split (flac_frame, sizeof (flac_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_flac_skip_garbage)
{
/* We always include the garbage into the frame because
* we have no easy way for finding the real end of the
* frame. The decoder will later skip the garbage
*/
#if 0
gst_parser_test_skip_garbage (flac_frame, sizeof (flac_frame),
garbage_frame, sizeof (garbage_frame));
#endif
guint8 frame[sizeof (flac_frame) + sizeof (garbage_frame)];
memcpy (frame, flac_frame, sizeof (flac_frame));
memcpy (frame + sizeof (flac_frame), garbage_frame, sizeof (garbage_frame));
gst_parser_test_normal (frame, sizeof (frame));
}
GST_END_TEST;
#define structure_get_int(s,f) \
(g_value_get_int(gst_structure_get_value(s,f)))
#define fail_unless_structure_field_int_equals(s,field,num) \
fail_unless_equals_int (structure_get_int(s,field), num)
/*
* Test if the parser handles raw stream and codec_data info properly.
*/
GST_START_TEST (test_parse_flac_detect_stream)
{
GstCaps *caps;
GstStructure *s;
const GValue *streamheader;
GArray *bufarr;
gint i;
/* Push random data. It should get through since the parser should be
* initialized because it got codec_data in the caps */
caps = gst_parser_test_get_output_caps (flac_frame, sizeof (flac_frame),
SRC_CAPS_TMPL);
fail_unless (caps != NULL);
/* Check that the negotiated caps are as expected */
/* When codec_data is present, parser assumes that data is version 4 */
GST_LOG ("flac output caps: %" GST_PTR_FORMAT, caps);
s = gst_caps_get_structure (caps, 0);
fail_unless (gst_structure_has_name (s, "audio/x-flac"));
fail_unless_structure_field_int_equals (s, "channels", 1);
fail_unless_structure_field_int_equals (s, "rate", 44100);
fail_unless (gst_structure_has_field (s, "streamheader"));
streamheader = gst_structure_get_value (s, "streamheader");
fail_unless (G_VALUE_TYPE (streamheader) == GST_TYPE_ARRAY);
bufarr = g_value_peek_pointer (streamheader);
fail_unless (bufarr->len == 2);
for (i = 0; i < bufarr->len; i++) {
GstBuffer *buf;
GValue *bufval = &g_array_index (bufarr, GValue, i);
fail_unless (G_VALUE_TYPE (bufval) == GST_TYPE_BUFFER);
buf = g_value_peek_pointer (bufval);
if (i == 0) {
fail_unless (GST_BUFFER_SIZE (buf) == sizeof (streaminfo_header));
fail_unless (memcmp (buf, streaminfo_header, sizeof (streaminfo_header)));
} else if (i == 1) {
fail_unless (GST_BUFFER_SIZE (buf) == sizeof (comment_header));
fail_unless (memcmp (buf, comment_header, sizeof (comment_header)));
}
}
gst_caps_unref (caps);
}
GST_END_TEST;
static Suite *
flacparse_suite (void)
{
Suite *s = suite_create ("flacparse");
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_parse_flac_normal);
tcase_add_test (tc_chain, test_parse_flac_drain_single);
tcase_add_test (tc_chain, test_parse_flac_drain_garbage);
tcase_add_test (tc_chain, test_parse_flac_split);
tcase_add_test (tc_chain, test_parse_flac_skip_garbage);
/* Other tests */
tcase_add_test (tc_chain, test_parse_flac_detect_stream);
return s;
}
/*
* TODO:
* - Both push- and pull-modes need to be tested
* * Pull-mode & EOS
*/
int
main (int argc, char **argv)
{
int nf;
Suite *s = flacparse_suite ();
SRunner *sr = srunner_create (s);
gst_check_init (&argc, &argv);
/* init test context */
ctx_factory = "flacparse";
ctx_sink_template = &sinktemplate;
ctx_src_template = &srctemplate;
ctx_discard = 3;
ctx_headers[0].data = streaminfo_header;
ctx_headers[0].size = sizeof (streaminfo_header);
ctx_headers[1].data = comment_header;
ctx_headers[1].size = sizeof (comment_header);
/* custom offsets, and ts always repeatedly 0 */
ctx_no_metadata = TRUE;
srunner_run_all (sr, CK_NORMAL);
nf = srunner_ntests_failed (sr);
srunner_free (sr);
return nf;
}

View file

@ -1,172 +0,0 @@
/*
* GStreamer
*
* unit test for aacparse
*
* Copyright (C) 2008 Nokia Corporation. All rights reserved.
*
* Contact: Stefan Kost <stefan.kost@nokia.com>
*
* 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.
*/
#include <gst/check/gstcheck.h>
#include "parser.h"
#define SRC_CAPS_TMPL "audio/mpeg, parsed=(boolean)false, mpegversion=(int)1"
#define SINK_CAPS_TMPL "audio/mpeg, parsed=(boolean)true, mpegversion=(int)1"
GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (SINK_CAPS_TMPL)
);
GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (SRC_CAPS_TMPL)
);
const gchar *factory = "aacparse";
/* some data */
static guint8 mp3_frame[384] = {
0xff, 0xfb, 0x94, 0xc4, 0xff, 0x83, 0xc0, 0x00,
0x01, 0xa4, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
0x34, 0x80, 0x00, 0x00, 0x04, 0x00,
};
static guint8 garbage_frame[] = {
0xff, 0xff, 0xff, 0xff, 0xff
};
GST_START_TEST (test_parse_normal)
{
gst_parser_test_normal (mp3_frame, sizeof (mp3_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_drain_single)
{
gst_parser_test_drain_single (mp3_frame, sizeof (mp3_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_drain_garbage)
{
gst_parser_test_drain_garbage (mp3_frame, sizeof (mp3_frame),
garbage_frame, sizeof (garbage_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_split)
{
gst_parser_test_split (mp3_frame, sizeof (mp3_frame));
}
GST_END_TEST;
GST_START_TEST (test_parse_skip_garbage)
{
gst_parser_test_skip_garbage (mp3_frame, sizeof (mp3_frame),
garbage_frame, sizeof (garbage_frame));
}
GST_END_TEST;
#define structure_get_int(s,f) \
(g_value_get_int(gst_structure_get_value(s,f)))
#define fail_unless_structure_field_int_equals(s,field,num) \
fail_unless_equals_int (structure_get_int(s,field), num)
GST_START_TEST (test_parse_detect_stream)
{
GstStructure *s;
GstCaps *caps;
caps = gst_parser_test_get_output_caps (mp3_frame, sizeof (mp3_frame), NULL);
fail_unless (caps != NULL);
GST_LOG ("mpegaudio output caps: %" GST_PTR_FORMAT, caps);
s = gst_caps_get_structure (caps, 0);
fail_unless (gst_structure_has_name (s, "audio/mpeg"));
fail_unless_structure_field_int_equals (s, "mpegversion", 1);
fail_unless_structure_field_int_equals (s, "layer", 3);
fail_unless_structure_field_int_equals (s, "channels", 1);
fail_unless_structure_field_int_equals (s, "rate", 48000);
gst_caps_unref (caps);
}
GST_END_TEST;
static Suite *
mpegaudioparse_suite (void)
{
Suite *s = suite_create ("mpegaudioparse");
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_parse_normal);
tcase_add_test (tc_chain, test_parse_drain_single);
tcase_add_test (tc_chain, test_parse_drain_garbage);
tcase_add_test (tc_chain, test_parse_split);
tcase_add_test (tc_chain, test_parse_skip_garbage);
tcase_add_test (tc_chain, test_parse_detect_stream);
return s;
}
/*
* TODO:
* - Both push- and pull-modes need to be tested
* * Pull-mode & EOS
*/
int
main (int argc, char **argv)
{
int nf;
Suite *s = mpegaudioparse_suite ();
SRunner *sr = srunner_create (s);
gst_check_init (&argc, &argv);
/* init test context */
ctx_factory = "mpegaudioparse";
ctx_sink_template = &sinktemplate;
ctx_src_template = &srctemplate;
srunner_run_all (sr, CK_NORMAL);
nf = srunner_ntests_failed (sr);
srunner_free (sr);
return nf;
}