From: Vincent Penquerc'h Date: Tue, 15 Nov 2011 19:53:33 +0000 (+0000) Subject: opusparse: add opusparse element X-Git-Tag: 1.19.3~507^2~15935^2~11 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5efa9ebec80e316242efed7c5cb496c9b9090030;p=platform%2Fupstream%2Fgstreamer.git opusparse: add opusparse element A very simple element that parses Opus streams from the ad hoc framing used by the Opus test vectors. --- diff --git a/ext/opus/Makefile.am b/ext/opus/Makefile.am index 57e1692..6fe723e 100644 --- a/ext/opus/Makefile.am +++ b/ext/opus/Makefile.am @@ -1,6 +1,6 @@ plugin_LTLIBRARIES = libgstopus.la -libgstopus_la_SOURCES = gstopus.c gstopusdec.c gstopusenc.c +libgstopus_la_SOURCES = gstopus.c gstopusdec.c gstopusenc.c gstopusparse.c libgstopus_la_CFLAGS = \ -DGST_USE_UNSTABLE_API \ $(GST_PLUGINS_BASE_CFLAGS) \ @@ -15,4 +15,4 @@ libgstopus_la_LIBADD = \ libgstopus_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(LIBM) libgstopus_la_LIBTOOLFLAGS = --tag=disable-static -noinst_HEADERS = gstopusenc.h gstopusdec.h +noinst_HEADERS = gstopusenc.h gstopusdec.h gstopusparse.h diff --git a/ext/opus/gstopus.c b/ext/opus/gstopus.c index 65e9dcd..c5f68a1 100644 --- a/ext/opus/gstopus.c +++ b/ext/opus/gstopus.c @@ -23,6 +23,7 @@ #include "gstopusdec.h" #include "gstopusenc.h" +#include "gstopusparse.h" #include @@ -38,6 +39,10 @@ plugin_init (GstPlugin * plugin) GST_TYPE_OPUS_DEC)) return FALSE; + if (!gst_element_register (plugin, "opusparse", GST_RANK_NONE, + GST_TYPE_OPUS_PARSE)) + return FALSE; + gst_tag_register_musicbrainz_tags (); return TRUE; diff --git a/ext/opus/gstopusparse.c b/ext/opus/gstopusparse.c new file mode 100644 index 0000000..c946875 --- /dev/null +++ b/ext/opus/gstopusparse.c @@ -0,0 +1,158 @@ +/* GStreamer + * Copyright (C) 2004 Wim Taymans + * Copyright (C) 2006 Tim-Philipp Müller + * Copyright (C) 2008 Sebastian Dröge + * + * 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-opusparse + * @see_also: opusenc, opusdec + * + * This element parses OPUS packets. + * + * + * Example pipelines + * |[ + * gst-launch -v filesrc location=opusdata ! opusparse ! opusdec ! audioconvert ! audioresample ! alsasink + * ]| Decode and plays an unmuxed Opus file. + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "gstopusparse.h" + +GST_DEBUG_CATEGORY_STATIC (opusparse_debug); +#define GST_CAT_DEFAULT opusparse_debug + +#define MAX_PAYLOAD_BYTES 1500 + +static GstStaticPadTemplate opus_parse_src_factory = +GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("audio/x-opus, framed = (boolean) true") + ); + +static GstStaticPadTemplate opus_parse_sink_factory = +GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("audio/x-opus") + ); + +G_DEFINE_TYPE (GstOpusParse, gst_opus_parse, GST_TYPE_BASE_PARSE); + +static gboolean gst_opus_parse_start (GstBaseParse * parse); +static gboolean gst_opus_parse_check_valid_frame (GstBaseParse * base, + GstBaseParseFrame * frame, guint * frame_size, gint * skip); + +static void +gst_opus_parse_class_init (GstOpusParseClass * klass) +{ + GstBaseParseClass *bpclass; + GstElementClass *element_class; + + bpclass = (GstBaseParseClass *) klass; + element_class = (GstElementClass *) klass; + + bpclass->start = GST_DEBUG_FUNCPTR (gst_opus_parse_start); + bpclass->check_valid_frame = + GST_DEBUG_FUNCPTR (gst_opus_parse_check_valid_frame); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&opus_parse_src_factory)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&opus_parse_sink_factory)); + gst_element_class_set_details_simple (element_class, "Opus audio parser", + "Codec/Parser/Audio", + "parses opus audio streams", + "Vincent Penquerc'h "); + + GST_DEBUG_CATEGORY_INIT (opusparse_debug, "opusparse", 0, + "opus parsing element"); +} + +static void +gst_opus_parse_init (GstOpusParse * parse) +{ +} + +static gboolean +gst_opus_parse_start (GstBaseParse * base) +{ + GstOpusParse *parse = GST_OPUS_PARSE (base); + GstCaps *caps; + + caps = gst_caps_from_string ("audio/x-opus"); + gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (GST_BASE_PARSE (parse)), caps); + gst_caps_unref (caps); + + return TRUE; +} + +static gboolean +gst_opus_parse_check_valid_frame (GstBaseParse * base, + GstBaseParseFrame * frame, guint * frame_size, gint * skip) +{ + GstOpusParse *parse; + guint8 *data; + gsize size; + guint32 packet_size; + int ret = FALSE; + int channels, bandwidth; + + parse = GST_OPUS_PARSE (base); + + data = GST_BUFFER_DATA (frame->buffer); + size = GST_BUFFER_SIZE (frame->buffer); + GST_DEBUG_OBJECT (parse, "Checking for frame, %u bytes in buffer", size); + if (size < 4) { + GST_DEBUG_OBJECT (parse, "Too small"); + goto beach; + } + packet_size = GST_READ_UINT32_BE (data); + GST_DEBUG_OBJECT (parse, "Packet size: %u bytes", packet_size); + if (packet_size > MAX_PAYLOAD_BYTES) { + GST_DEBUG_OBJECT (parse, "Too large"); + goto beach; + } + if (packet_size > size - 4) { + GST_DEBUG_OBJECT (parse, "Truncated"); + goto beach; + } + + channels = opus_packet_get_nb_channels (data + 8); + bandwidth = opus_packet_get_bandwidth (data + 8); + if (channels < 0 || bandwidth < 0) { + GST_DEBUG_OBJECT (parse, "It looked like a packet, but it is not"); + goto beach; + } + + GST_DEBUG_OBJECT (parse, "Got Opus packet, %d bytes"); + + *skip = 8; + *frame_size = packet_size; + ret = TRUE; + +beach: + return ret; +} diff --git a/ext/opus/gstopusparse.h b/ext/opus/gstopusparse.h new file mode 100644 index 0000000..5f9f884 --- /dev/null +++ b/ext/opus/gstopusparse.h @@ -0,0 +1,55 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * Copyright (C) <2008> Sebastian Dröge + * + * 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_OPUS_PARSE_H__ +#define __GST_OPUS_PARSE_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_OPUS_PARSE \ + (gst_opus_parse_get_type()) +#define GST_OPUS_PARSE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OPUS_PARSE,GstOpusParse)) +#define GST_OPUS_PARSE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OPUS_PARSE,GstOpusParseClass)) +#define GST_IS_OPUS_PARSE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OPUS_PARSE)) +#define GST_IS_OPUS_PARSE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OPUS_PARSE)) + +typedef struct _GstOpusParse GstOpusParse; +typedef struct _GstOpusParseClass GstOpusParseClass; + +struct _GstOpusParse { + GstBaseParse element; +}; + +struct _GstOpusParseClass { + GstBaseParseClass parent_class; +}; + +GType gst_opus_parse_get_type (void); + +G_END_DECLS + +#endif /* __GST_OPUS_PARSE_H__ */