diff --git a/gst/rawparse/Makefile.am b/gst/rawparse/Makefile.am index 03eeb48a59..3bd8438675 100644 --- a/gst/rawparse/Makefile.am +++ b/gst/rawparse/Makefile.am @@ -3,6 +3,7 @@ plugin_LTLIBRARIES = libgstrawparse.la libgstrawparse_la_SOURCES = \ gstrawparse.c \ + gstunalignedaudioparse.c \ gstaudioparse.c \ gstvideoparse.c \ plugin.c @@ -19,6 +20,8 @@ libgstrawparse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstrawparse_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS) noinst_HEADERS = \ + unalignedaudio.h \ + gstunalignedaudioparse.h \ gstaudioparse.h \ gstrawparse.h \ gstvideoparse.h diff --git a/gst/rawparse/gstaudioparse.c b/gst/rawparse/gstaudioparse.c index 04477f5c23..b60118b364 100644 --- a/gst/rawparse/gstaudioparse.c +++ b/gst/rawparse/gstaudioparse.c @@ -33,6 +33,7 @@ #define GLIB_DISABLE_DEPRECATION_WARNINGS #include "gstaudioparse.h" +#include "unalignedaudio.h" #include @@ -159,6 +160,7 @@ gst_audio_parse_class_init (GstAudioParseClass * klass) caps = gst_caps_from_string (GST_AUDIO_CAPS_MAKE (GST_AUDIO_FORMATS_ALL) ", layout = (string) { interleaved, non-interleaved }; " + GST_UNALIGNED_RAW_AUDIO_CAPS "; " "audio/x-alaw, rate=(int)[1,MAX], channels=(int)[1,MAX]; " "audio/x-mulaw, rate=(int)[1,MAX], channels=(int)[1,MAX]"); @@ -371,11 +373,24 @@ gst_audio_parse_get_caps (GstRawParse * rp) if (ap->use_sink_caps) { gint rate; GstCaps *caps = gst_pad_get_current_caps (rp->sinkpad); + GstStructure *structure; + if (!caps) { GST_WARNING_OBJECT (ap, "Sink pad has no caps, but we were asked to use its caps"); return NULL; } + + /* For unaligned raw data, the output caps stay the same, + * except that audio/x-unaligned-raw becomes audio/x-raw, + * since audioparse aligns the sample data */ + structure = gst_caps_get_structure (caps, 0); + if (gst_structure_has_name (structure, "audio/x-unaligned-raw")) { + caps = gst_caps_make_writable (caps); + structure = gst_caps_get_structure (caps, 0); + gst_structure_set_name (structure, "audio/x-raw"); + } + if (!gst_audio_info_from_caps (&info, caps)) { GST_WARNING_OBJECT (ap, "Failed to parse caps %" GST_PTR_FORMAT, caps); gst_caps_unref (caps); diff --git a/gst/rawparse/gstunalignedaudioparse.c b/gst/rawparse/gstunalignedaudioparse.c new file mode 100644 index 0000000000..62a83f3638 --- /dev/null +++ b/gst/rawparse/gstunalignedaudioparse.c @@ -0,0 +1,125 @@ +/* GStreamer + * Copyright (C) 2016 Carlos Rafael Giani + * + * gstunalignedaudioparse.c: + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include "gstunalignedaudioparse.h" +#include "unalignedaudio.h" + + +GST_DEBUG_CATEGORY (unaligned_audio_parse_debug); +#define GST_CAT_DEFAULT unaligned_audio_parse_debug + + +struct _GstUnalignedAudioParse +{ + GstBin parent; + GstElement *inner_parser; +}; + + +struct _GstUnalignedAudioParseClass +{ + GstBinClass parent_class; +}; + + +static GstStaticPadTemplate static_sink_template = +GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (GST_UNALIGNED_RAW_AUDIO_CAPS) + ); + + +static GstStaticPadTemplate static_src_template = +GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS (GST_AUDIO_CAPS_MAKE (GST_AUDIO_FORMATS_ALL) + ", layout = (string) { interleaved, non-interleaved }") + ); + + + + +G_DEFINE_TYPE (GstUnalignedAudioParse, gst_unaligned_audio_parse, GST_TYPE_BIN); + + +static void +gst_unaligned_audio_parse_class_init (GstUnalignedAudioParseClass * klass) +{ + GstElementClass *element_class; + + GST_DEBUG_CATEGORY_INIT (unaligned_audio_parse_debug, "unalignedaudioparse", + 0, "Unaligned raw audio parser"); + + element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&static_sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&static_src_template)); + + gst_element_class_set_static_metadata (element_class, + "unalignedaudioparse", + "Codec/Parser/Bin/Audio", + "Parse unaligned raw audio data", + "Carlos Rafael Giani "); +} + + +static void +gst_unaligned_audio_parse_init (GstUnalignedAudioParse * unaligned_audio_parse) +{ + GstPad *inner_pad; + GstPad *ghostpad; + + unaligned_audio_parse->inner_parser = + gst_element_factory_make ("audioparse", "inner_parser"); + g_assert (unaligned_audio_parse->inner_parser != NULL); + + g_object_set (G_OBJECT (unaligned_audio_parse->inner_parser), + "use-sink-caps", TRUE, NULL); + + gst_bin_add (GST_BIN (unaligned_audio_parse), + unaligned_audio_parse->inner_parser); + + inner_pad = + gst_element_get_static_pad (unaligned_audio_parse->inner_parser, "sink"); + ghostpad = + gst_ghost_pad_new_from_template ("sink", inner_pad, + gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS + (unaligned_audio_parse), "sink")); + gst_element_add_pad (GST_ELEMENT (unaligned_audio_parse), ghostpad); + gst_object_unref (GST_OBJECT (inner_pad)); + + inner_pad = gst_element_get_static_pad (unaligned_audio_parse->inner_parser, + "src"); + ghostpad = + gst_ghost_pad_new_from_template ("src", inner_pad, + gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS + (unaligned_audio_parse), "src")); + gst_element_add_pad (GST_ELEMENT (unaligned_audio_parse), ghostpad); + gst_object_unref (GST_OBJECT (inner_pad)); +} diff --git a/gst/rawparse/gstunalignedaudioparse.h b/gst/rawparse/gstunalignedaudioparse.h new file mode 100644 index 0000000000..a07bee7ebe --- /dev/null +++ b/gst/rawparse/gstunalignedaudioparse.h @@ -0,0 +1,49 @@ +/* GStreamer + * Copyright (C) 2016 Carlos Rafael Giani + * + * gstunalignedaudioparse.h: + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GST_UNALIGNED_AUDIO_PARSE_H___ +#define __GST_UNALIGNED_AUDIO_PARSE_H___ + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_UNALIGNED_AUDIO_PARSE \ + (gst_unaligned_audio_parse_get_type()) +#define GST_UNALIGNED_AUDIO_PARSE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_UNALIGNED_AUDIO_PARSE, GstUnalignedAudioParse)) +#define GST_UNALIGNED_AUDIO_PARSE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_UNALIGNED_AUDIO_PARSE, GstUnalignedAudioParseClass)) +#define GST_UNALIGNED_AUDIO_PARSE_CAST(obj) \ + ((GstUnalignedAudioParse *)(obj)) +#define GST_IS_UNALIGNED_AUDIO_PARSE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_UNALIGNED_AUDIO_PARSE)) +#define GST_IS_UNALIGNED_AUDIO_PARSE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_UNALIGNED_AUDIO_PARSE)) + +typedef struct _GstUnalignedAudioParse GstUnalignedAudioParse; +typedef struct _GstUnalignedAudioParseClass GstUnalignedAudioParseClass; + +GType gst_unaligned_audio_parse_get_type (void); + +G_END_DECLS + +#endif /* __GST_UNALIGNED_AUDIO_PARSE_H___ */ diff --git a/gst/rawparse/plugin.c b/gst/rawparse/plugin.c index dc860e18f8..bb21f77b15 100644 --- a/gst/rawparse/plugin.c +++ b/gst/rawparse/plugin.c @@ -3,6 +3,7 @@ #endif #include +#include "gstunalignedaudioparse.h" #include "gstaudioparse.h" #include "gstvideoparse.h" @@ -15,6 +16,8 @@ plugin_init (GstPlugin * plugin) gst_video_parse_get_type ()); ret &= gst_element_register (plugin, "audioparse", GST_RANK_NONE, gst_audio_parse_get_type ()); + ret &= gst_element_register (plugin, "unalignedaudioparse", GST_RANK_MARGINAL, + gst_unaligned_audio_parse_get_type ()); return ret; } diff --git a/gst/rawparse/unalignedaudio.h b/gst/rawparse/unalignedaudio.h new file mode 100644 index 0000000000..15d499525f --- /dev/null +++ b/gst/rawparse/unalignedaudio.h @@ -0,0 +1,35 @@ +/* GStreamer + * Copyright (C) 2016 Carlos Rafael Giani + * + * unalignedaudio.h: + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GST_UNALIGNED_AUDIO_H__ +#define __GST_UNALIGNED_AUDIO_H__ + +#include +#include + +#define GST_UNALIGNED_RAW_AUDIO_CAPS \ + "audio/x-unaligned-raw" \ + ", format = (string) " GST_AUDIO_FORMATS_ALL \ + ", rate = (int) [ 1, MAX ]" \ + ", channels = (int) [ 1, MAX ]" \ + ", layout = (string) { interleaved, non-interleaved }" + +#endif /* __GST_UNALIGNED_AUDIO_H__ */