Commit 3a0a2898 authored by Ronald S. Bultje's avatar Ronald S. Bultje
Browse files

Surround sound support.

Original commit message from CVS:
* ext/a52dec/gsta52dec.c: (gst_a52dec_channels), (gst_a52dec_push),
(gst_a52dec_reneg), (gst_a52dec_loop), (plugin_init):
* ext/alsa/gstalsa.c: (gst_alsa_get_caps):
* ext/alsa/gstalsaplugin.c: (plugin_init):
* ext/dts/gstdtsdec.c: (gst_dtsdec_channels),
(gst_dtsdec_renegotiate), (gst_dtsdec_loop), (plugin_init):
* ext/faad/gstfaad.c: (gst_faad_init), (gst_faad_chanpos_from_gst),
(gst_faad_chanpos_to_gst), (gst_faad_sinkconnect),
(gst_faad_srcgetcaps), (gst_faad_srcconnect), (gst_faad_chain),
(gst_faad_change_state), (plugin_init):
* ext/faad/gstfaad.h:
* ext/vorbis/vorbis.c: (plugin_init):
* ext/vorbis/vorbisdec.c: (vorbis_dec_chain):
* gst-libs/gst/audio/Makefile.am:
* gst-libs/gst/audio/audio.c: (plugin_init):
* gst-libs/gst/audio/multichannel.c:
(gst_audio_check_channel_positions),
(gst_audio_get_channel_positions),
(gst_audio_set_channel_positions),
(gst_audio_set_structure_channel_positions_list),
(add_list_to_struct), (gst_audio_set_caps_channel_positions_list),
(gst_audio_fixate_channel_positions):
* gst-libs/gst/audio/multichannel.h:
* gst-libs/gst/audio/testchannels.c: (main):
* gst/audioconvert/gstaudioconvert.c:
(gst_audio_convert_class_init), (gst_audio_convert_init),
(gst_audio_convert_dispose), (gst_audio_convert_getcaps),
(gst_audio_convert_parse_caps), (gst_audio_convert_link),
(gst_audio_convert_fixate), (gst_audio_convert_channels):
* gst/audioconvert/plugin.c: (plugin_init):
Surround sound support.
parent 78cfd8e8
2004-11-25 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* ext/a52dec/gsta52dec.c: (gst_a52dec_channels), (gst_a52dec_push),
(gst_a52dec_reneg), (gst_a52dec_loop), (plugin_init):
* ext/alsa/gstalsa.c: (gst_alsa_get_caps):
* ext/alsa/gstalsaplugin.c: (plugin_init):
* ext/dts/gstdtsdec.c: (gst_dtsdec_channels),
(gst_dtsdec_renegotiate), (gst_dtsdec_loop), (plugin_init):
* ext/faad/gstfaad.c: (gst_faad_init), (gst_faad_chanpos_from_gst),
(gst_faad_chanpos_to_gst), (gst_faad_sinkconnect),
(gst_faad_srcgetcaps), (gst_faad_srcconnect), (gst_faad_chain),
(gst_faad_change_state), (plugin_init):
* ext/faad/gstfaad.h:
* ext/vorbis/vorbis.c: (plugin_init):
* ext/vorbis/vorbisdec.c: (vorbis_dec_chain):
* gst-libs/gst/audio/Makefile.am:
* gst-libs/gst/audio/audio.c: (plugin_init):
* gst-libs/gst/audio/multichannel.c:
(gst_audio_check_channel_positions),
(gst_audio_get_channel_positions),
(gst_audio_set_channel_positions),
(gst_audio_set_structure_channel_positions_list),
(add_list_to_struct), (gst_audio_set_caps_channel_positions_list),
(gst_audio_fixate_channel_positions):
* gst-libs/gst/audio/multichannel.h:
* gst-libs/gst/audio/testchannels.c: (main):
* gst/audioconvert/gstaudioconvert.c:
(gst_audio_convert_class_init), (gst_audio_convert_init),
(gst_audio_convert_dispose), (gst_audio_convert_getcaps),
(gst_audio_convert_parse_caps), (gst_audio_convert_link),
(gst_audio_convert_fixate), (gst_audio_convert_channels):
* gst/audioconvert/plugin.c: (plugin_init):
Surround sound support.
2004-11-25 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* ext/ogg/gstoggdemux.c: (gst_ogg_demux_push):
......
......@@ -26,6 +26,7 @@
#include <sys/time.h>
#include "gst/gst-i18n-plugin.h"
#include <gst/audio/multichannel.h>
#include "gst/propertyprobe/propertyprobe.h"
#include "gstalsa.h"
#include "gstalsaclock.h"
......@@ -853,14 +854,55 @@ gst_alsa_get_caps (GstPad * pad)
/* we can never use a format we can't set caps for */
if (caps != NULL) {
gint n;
g_assert (gst_caps_get_size (caps) == 1);
add_channels (gst_caps_get_structure (caps, 0), min_rate, max_rate,
min_channels, max_channels);
if (ret) {
gst_caps_append (ret, caps);
} else {
ret = caps;
/* channel configuration */
for (n = min_channels; n < max_channels; n++) {
if (snd_pcm_hw_params_test_channels (this->handle, hw_params, n) == 0) {
GstStructure *str;
GstAudioChannelPosition pos[8] = {
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_LFE,
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT
};
switch (n) {
case 1:
pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_MONO;
break;
case 2:
case 4:
case 6:
case 8:
/* keep above */
break;
default:
/* unsupported */
pos[0] = GST_AUDIO_CHANNEL_POSITION_INVALID;
break;
}
if (pos[0] != GST_AUDIO_CHANNEL_POSITION_INVALID) {
str = gst_structure_copy (gst_caps_get_structure (caps, 0));
gst_structure_set (str, "channels", G_TYPE_INT, n, NULL);
gst_audio_set_channel_positions (str, pos);
if (!ret) {
ret = gst_caps_new_empty ();
}
gst_caps_append_structure (ret, str);
}
}
}
gst_caps_free (caps);
}
}
}
......
......@@ -56,6 +56,9 @@ plugin_init (GstPlugin * plugin)
{
int err;
if (!gst_library_load ("gstaudio"))
return FALSE;
if (!gst_element_register (plugin, "alsamixer", GST_RANK_NONE,
GST_TYPE_ALSA_MIXER))
return FALSE;
......
......@@ -33,10 +33,8 @@ GST_DEBUG_CATEGORY (vorbisparse_debug);
static gboolean
plugin_init (GstPlugin * plugin)
{
if (!gst_library_load ("gstbytestream"))
return FALSE;
if (!gst_library_load ("gsttags"))
if (!gst_library_load ("gstbytestream") ||
!gst_library_load ("gstaudio") || !gst_library_load ("gsttags"))
return FALSE;
if (!gst_element_register (plugin, "vorbisenc", GST_RANK_NONE,
......
......@@ -24,6 +24,7 @@
#include "vorbisdec.h"
#include <string.h>
#include <gst/tag/tag.h>
#include <gst/audio/multichannel.h>
GST_DEBUG_CATEGORY_EXTERN (vorbisdec_debug);
#define GST_CAT_DEFAULT vorbisdec_debug
......@@ -53,7 +54,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-raw-float, "
"rate = (int) [ 8000, 50000 ], "
"channels = (int) [ 1, 2 ], " "endianness = (int) BYTE_ORDER, "
"channels = (int) [ 1, 6 ], " "endianness = (int) BYTE_ORDER, "
/* no ifdef in macros, please
#ifdef GST_VORBIS_DEC_SEQUENTIAL
"layout = \"sequential\", "
......@@ -431,6 +432,7 @@ vorbis_dec_chain (GstPad * pad, GstData * data)
gst_element_found_tags_for_pad (GST_ELEMENT (vd), vd->srcpad, 0, list);
} else if (packet.packetno == 2) {
GstCaps *caps;
const GstAudioChannelPosition *pos = NULL;
/* done */
vorbis_synthesis_init (&vd->vd, &vd->vi);
......@@ -440,6 +442,63 @@ vorbis_dec_chain (GstPad * pad, GstData * data)
"channels", G_TYPE_INT, vd->vi.channels,
"endianness", G_TYPE_INT, G_BYTE_ORDER,
"width", G_TYPE_INT, 32, "buffer-frames", G_TYPE_INT, 0, NULL);
switch (vd->vi.channels) {
case 1:
case 2:
/* nothing */
break;
case 3:{
static GstAudioChannelPosition pos3[] = {
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
};
pos = pos3;
break;
}
case 4:{
static GstAudioChannelPosition pos4[] = {
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT
};
pos = pos4;
break;
}
case 5:{
static GstAudioChannelPosition pos5[] = {
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT
};
pos = pos5;
break;
}
case 6:{
static GstAudioChannelPosition pos6[] = {
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
GST_AUDIO_CHANNEL_POSITION_LFE
};
pos = pos6;
break;
}
default:
gst_data_unref (data);
gst_caps_free (caps);
GST_ELEMENT_ERROR (vd, STREAM, NOT_IMPLEMENTED, (NULL),
("Unsupported channel count %d", vd->vi.channels));
return;
}
if (pos) {
gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
}
if (!gst_pad_set_explicit_caps (vd->srcpad, caps)) {
gst_caps_free (caps);
return;
......
# variables used for enum/marshal generation
glib_enum_headers=multichannel.h
glib_enum_define=GST_AUDIO
glib_enum_prefix=gst_audio
built_sources = multichannel-enumtypes.c
built_headers = multichannel-enumtypes.h
BUILT_SOURCES = $(built_sources) $(built_headers)
librarydir = $(libdir)/gstreamer-@GST_MAJORMINOR@
library_LTLIBRARIES = libgstaudio.la libgstaudiofilter.la
noinst_LTLIBRARIES = libgstaudiofilterexample.la
EXTRA_DIST = gstaudiofiltertemplate.c make_filter
CLEANFILES = gstaudiofilterexample.c
CLEANFILES = gstaudiofilterexample.c \
$(BUILT_SOURCES)
libgstaudio_la_SOURCES = audio.c audioclock.c
libgstaudio_la_SOURCES = audio.c audioclock.c \
multichannel.c
nodist_libgstaudio_la_SOURCES = $(built_sources)
libgstaudioincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/audio
libgstaudioinclude_HEADERS = audio.h audioclock.h gstaudiofilter.h
libgstaudioinclude_HEADERS = \
audio.h \
audioclock.h \
gstaudiofilter.h \
multichannel.h \
multichannel-enumtypes.h
libgstaudio_la_LIBADD =
libgstaudio_la_CFLAGS = $(GST_CFLAGS)
......@@ -25,3 +42,10 @@ libgstaudiofilterexample_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
gstaudiofilterexample.c: $(srcdir)/make_filter $(srcdir)/gstaudiofiltertemplate.c
$(srcdir)/make_filter AudiofilterExample $(srcdir)/gstaudiofiltertemplate.c
noinst_PROGRAMS = testchannels
testchannels_SOURCES = testchannels.c
testchannels_CFLAGS = $(GST_CFLAGS)
testchannels_LDFLAGS = $(GST_LIBS)
include $(top_srcdir)/common/glib-gen.mak
......@@ -22,6 +22,7 @@
#endif
#include "audio.h"
#include "multichannel-enumtypes.h"
#include <gst/gststructure.h>
......@@ -267,6 +268,8 @@ gst_audio_structure_set_int (GstStructure * structure, GstAudioFieldFlag flag)
static gboolean
plugin_init (GstPlugin * plugin)
{
gst_audio_channel_position_get_type ();
return TRUE;
}
......
This diff is collapsed.
/* GStreamer Multichannel-Audio helper functions
* (c) 2004 Ronald Bultje <rbultje@ronald.bitfreak.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_AUDIO_MULTICHANNEL_H__
#define __GST_AUDIO_MULTICHANNEL_H__
#include <gst/audio/audio.h>
#include <gst/audio/multichannel-enumtypes.h>
typedef enum {
GST_AUDIO_CHANNEL_POSITION_INVALID = -1,
/* Main front speakers. Mono and left/right are mututally exclusive! */
GST_AUDIO_CHANNEL_POSITION_FRONT_MONO,
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
/* rear. Left/right and center are mututally exclusive! */
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
/* subwoofer/low-frequency */
GST_AUDIO_CHANNEL_POSITION_LFE,
/* Center front speakers. Center and left/right_of_center cannot be
* used together! */
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
/* sides */
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
/* don't use - counter */
GST_AUDIO_CHANNEL_POSITION_NUM
} GstAudioChannelPosition;
/* Retrieves or sets the positions from/to a GstStructure. Only
* works with fixed caps, caller should check for that! Caller
* g_free()s result of the getter. */
GstAudioChannelPosition *
gst_audio_get_channel_positions (GstStructure *str);
void gst_audio_set_channel_positions (GstStructure *str,
const GstAudioChannelPosition *pos);
/* Sets a (non-fixed) list of possible audio channel positions
* on a structure (this requires the "channels" property to
* be fixed!) or on a caps (here, the "channels" property may be
* unfixed and the caps may even contain multiple structures). */
void gst_audio_set_structure_channel_positions_list
(GstStructure *str,
const GstAudioChannelPosition *pos,
gint num_positions);
void gst_audio_set_caps_channel_positions_list
(GstCaps *caps,
const GstAudioChannelPosition *pos,
gint num_positions);
/* Custom fixate function. Elements that implement some sort of
* channel conversion algorhithm should use this function for
* fixating on GstAudioChannelPosition properties. It will take
* care of equal channel positioning (left/right). Caller g_free()s
* the return value. The input properties may be (and are supposed
* to be) unfixed. */
GstAudioChannelPosition *
gst_audio_fixate_channel_positions (GstStructure *str);
#endif /* __GST_AUDIO_MULTICHANNEL_H__ */
/* GStreamer Multichannel Test
* (c) 2004 Ronald Bultje <rbultje@ronald.bitfreak.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 <gst/gst.h>
#include <multichannel.c>
#include <multichannel-enumtypes.c>
gint
main (gint argc, gchar * argv[])
{
gchar *str;
GstCaps *caps;
GstAudioChannelPosition pos[2] = { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
};
/* register multichannel type */
gst_init (&argc, &argv);
gst_audio_channel_position_get_type ();
/* test some caps-string conversions */
caps = gst_caps_new_simple ("audio/x-raw-int",
"channels", G_TYPE_INT, 2, NULL);
str = gst_caps_to_string (caps);
g_print ("Test caps #1: %s\n", str);
g_free (str);
gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
str = gst_caps_to_string (caps);
g_print ("Test caps #2: %s\n", str);
g_free (str);
gst_caps_free (caps);
return 0;
}
......@@ -37,6 +37,7 @@
#endif
#include <gst/gst.h>
#include <gst/audio/multichannel.h>
#include <string.h>
#include "plugin.h"
......@@ -64,6 +65,7 @@ struct _GstAudioConvertCaps
gint width;
gint rate;
gint channels;
GstAudioChannelPosition *pos;
/* int audio caps */
gboolean sign;
......@@ -104,6 +106,7 @@ static GstElementDetails audio_convert_details = {
static void gst_audio_convert_base_init (gpointer g_class);
static void gst_audio_convert_class_init (GstAudioConvertClass * klass);
static void gst_audio_convert_init (GstAudioConvert * audio_convert);
static void gst_audio_convert_dispose (GObject * obj);
/* gstreamer functions */
static void gst_audio_convert_chain (GstPad * pad, GstData * _data);
......@@ -147,33 +150,35 @@ GST_BOILERPLATE_FULL (GstAudioConvert, gst_audio_convert, GstElement,
GST_STATIC_CAPS ( \
"audio/x-raw-int, " \
"rate = (int) [ 1, MAX ], " \
"channels = (int) [ 1, 2 ], " \
"channels = (int) [ 1, 8 ], " \
"endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
"width = (int) 8, " \
"depth = (int) [ 1, 8 ], " \
"signed = (boolean) { true, false }; " \
"audio/x-raw-int, " \
"rate = (int) [ 1, MAX ], " \
"channels = (int) [ 1, 2 ], " \
"channels = (int) [ 1, 8 ], " \
"endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
"width = (int) 16, " \
"depth = (int) [ 1, 16 ], " \
"signed = (boolean) { true, false }; " \
"audio/x-raw-int, " \
"rate = (int) [ 1, MAX ], " \
"channels = (int) [ 1, 2 ], " \
"channels = (int) [ 1, 8 ], " \
"endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
"width = (int) 32, " \
"depth = (int) [ 1, 32 ], " \
"signed = (boolean) { true, false }; " \
"audio/x-raw-float, " \
"rate = (int) [ 1, MAX ], " \
"channels = (int) [ 1, 2 ], " \
"channels = (int) [ 1, 8 ], " \
"endianness = (int) BYTE_ORDER, " \
"width = (int) 32, " \
"buffer-frames = (int) [ 0, MAX ]" \
)
static GstAudioChannelPosition *supported_positions;
static GstStaticPadTemplate gst_audio_convert_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
......@@ -204,8 +209,16 @@ static void
gst_audio_convert_class_init (GstAudioConvertClass * klass)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gint i;
gstelement_class->change_state = gst_audio_convert_change_state;
gobject_class->dispose = gst_audio_convert_dispose;
supported_positions = g_new0 (GstAudioChannelPosition,
GST_AUDIO_CHANNEL_POSITION_NUM);
for (i = 0; i < GST_AUDIO_CHANNEL_POSITION_NUM; i++)
supported_positions[i] = i;
}
static void
......@@ -233,6 +246,24 @@ gst_audio_convert_init (GstAudioConvert * this)
/* clear important variables */
this->convert_internal = NULL;
this->sinkcaps.pos = NULL;
this->srccaps.pos = NULL;
}
static void
gst_audio_convert_dispose (GObject * obj)
{
GstAudioConvert *this = GST_AUDIO_CONVERT (obj);
if (this->sinkcaps.pos) {
g_free (this->sinkcaps.pos);
this->sinkcaps.pos = NULL;
}
if (this->srccaps.pos) {
g_free (this->srccaps.pos);
this->srccaps.pos = NULL;
}
}
/*** GSTREAMER FUNCTIONS ******************************************************/
......@@ -310,6 +341,7 @@ gst_audio_convert_getcaps (GstPad * pad)
for (i = size - 1; i >= 0; i--) {
structure = gst_caps_get_structure (othercaps, i);
gst_structure_remove_field (structure, "channels");
gst_structure_remove_field (structure, "channel-positions");
gst_structure_remove_field (structure, "endianness");
gst_structure_remove_field (structure, "width");
gst_structure_remove_field (structure, "depth");
......@@ -332,6 +364,10 @@ gst_audio_convert_getcaps (GstPad * pad)
caps = gst_caps_intersect (othercaps, templcaps);
gst_caps_free (othercaps);
/* Get the channel positions in as well. */
gst_audio_set_caps_channel_positions_list (caps, supported_positions,
GST_AUDIO_CHANNEL_POSITION_NUM);
return caps;
}
......@@ -344,10 +380,17 @@ gst_audio_convert_parse_caps (const GstCaps * gst_caps,
g_return_val_if_fail (gst_caps_is_fixed (gst_caps), FALSE);
g_return_val_if_fail (caps != NULL, FALSE);
/* cleanup old */
if (caps->pos) {
g_free (caps->pos);
caps->pos = NULL;
}
caps->endianness = G_BYTE_ORDER;
caps->is_int =
(strcmp (gst_structure_get_name (structure), "audio/x-raw-int") == 0);
if (!gst_structure_get_int (structure, "channels", &caps->channels)
|| !(caps->pos = gst_audio_get_channel_positions (structure))
|| !gst_structure_get_int (structure, "width", &caps->width)
|| !gst_structure_get_int (structure, "rate", &caps->rate)
|| (caps->is_int
......@@ -359,10 +402,14 @@ gst_audio_convert_parse_caps (const GstCaps * gst_caps,
&& !gst_structure_get_int (structure, "buffer-frames",
&caps->buffer_frames))) {
GST_DEBUG ("could not get some values from structure");
g_free (caps->pos);
caps->pos = NULL;
return FALSE;
}
if (caps->is_int && caps->depth > caps->width) {
GST_DEBUG ("width > depth, not allowed - make us advertise correct caps");
g_free (caps->pos);
caps->pos = NULL;
return FALSE;
}
return TRUE;
......@@ -386,6 +433,7 @@ gst_audio_convert_link (GstPad * pad, const GstCaps * caps)
this = GST_AUDIO_CONVERT (GST_OBJECT_PARENT (pad));
otherpad = (pad == this->src ? this->sink : this->src);
ac_caps.pos = NULL;
if (!gst_audio_convert_parse_caps (caps, &ac_caps))
return GST_PAD_LINK_REFUSED;
......@@ -406,11 +454,14 @@ gst_audio_convert_link (GstPad * pad, const GstCaps * caps)
}
}
if (this->sink == pad) {
g_free (this->sinkcaps.pos);
this->sinkcaps = ac_caps;
} else {
g_free (this->srccaps.pos);
this->srccaps = ac_caps;
}
GST_LOG_OBJECT (this, "trying to set caps to %" GST_PTR_FORMAT, othercaps);
ret = gst_pad_try_set_caps_nonfixed (otherpad, othercaps);
gst_caps_free (othercaps);
if (ret < GST_PAD_LINK_OK)
......@@ -419,18 +470,24 @@ gst_audio_convert_link (GstPad * pad, const GstCaps * caps)
/* woohoo, got it */
othercaps = (GstCaps *) gst_pad_get_negotiated_caps (otherpad);
if (othercaps) {
other_ac_caps.pos = NULL;
if (!gst_audio_convert_parse_caps (othercaps, &other_ac_caps)) {
g_critical ("internal negotiation error");
return GST_PAD_LINK_REFUSED;
}
} else {
other_ac_caps = ac_caps;
other_ac_caps.pos = g_memdup (ac_caps.pos,
ac_caps.channels * sizeof (GstAudioChannelPosition));
}
if (this->sink == pad) {
g_free (this->srccaps.pos);
this->srccaps = other_ac_caps;
this->sinkcaps = ac_caps;
} else {
g_free (this->sinkcaps.pos);