gstreamer/tests/check/elements/audioconvert.c

1462 lines
50 KiB
C
Raw Normal View History

/* GStreamer
*
* unit test for audioconvert
*
* Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
* Copyright (C) <2007> 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.
*/
#include <unistd.h>
#include <gst/check/gstcheck.h>
#include <gst/audio/audio.h>
/* For ease of programming we use globals to keep refs for our floating
* src and sink pads we create; otherwise we always have to do get_pad,
* get_peer, and then remove references in every test function */
Correct all relevant warnings found by the sparse semantic code analyzer. This include marking several symbols static... Original commit message from CVS: * ext/alsa/gstalsamixertrack.c: (gst_alsa_mixer_track_get_type): * ext/alsa/gstalsasink.c: (set_hwparams): * ext/alsa/gstalsasrc.c: (set_hwparams): * ext/gio/gstgio.c: (gst_gio_uri_handler_get_uri): * ext/ogg/gstoggmux.h: * ext/ogg/gstogmparse.c: * gst-libs/gst/audio/audio.c: * gst-libs/gst/fft/kiss_fft_f64.c: (kiss_fft_f64_alloc): * gst-libs/gst/pbutils/missing-plugins.c: (gst_missing_uri_sink_message_new), (gst_missing_element_message_new), (gst_missing_decoder_message_new), (gst_missing_encoder_message_new): * gst-libs/gst/rtp/gstbasertppayload.c: * gst-libs/gst/rtp/gstrtcpbuffer.c: (gst_rtcp_packet_bye_get_reason): * gst/audioconvert/gstaudioconvert.c: * gst/audioresample/gstaudioresample.c: * gst/ffmpegcolorspace/imgconvert.c: * gst/playback/test.c: (gen_video_element), (gen_audio_element): * gst/typefind/gsttypefindfunctions.c: * gst/videoscale/vs_4tap.c: * gst/videoscale/vs_4tap.h: * sys/v4l/gstv4lelement.c: * sys/v4l/gstv4lsrc.c: (gst_v4lsrc_get_any_caps): * sys/v4l/v4l_calls.c: * sys/v4l/v4lsrc_calls.c: (gst_v4lsrc_capture_init), (gst_v4lsrc_try_capture): * sys/ximage/ximagesink.c: (gst_ximagesink_check_xshm_calls), (gst_ximagesink_ximage_new): * sys/xvimage/xvimagesink.c: (gst_xvimagesink_check_xshm_calls), (gst_xvimagesink_xvimage_new): * tests/check/elements/audioconvert.c: * tests/check/elements/audioresample.c: (fail_unless_perfect_stream): * tests/check/elements/audiotestsrc.c: (setup_audiotestsrc): * tests/check/elements/decodebin.c: * tests/check/elements/gdpdepay.c: (setup_gdpdepay), (setup_gdpdepay_streamheader): * tests/check/elements/gdppay.c: (setup_gdppay), (GST_START_TEST), (setup_gdppay_streamheader): * tests/check/elements/gnomevfssink.c: (setup_gnomevfssink): * tests/check/elements/multifdsink.c: (setup_multifdsink): * tests/check/elements/textoverlay.c: * tests/check/elements/videorate.c: (setup_videorate): * tests/check/elements/videotestsrc.c: (setup_videotestsrc): * tests/check/elements/volume.c: (setup_volume): * tests/check/elements/vorbisdec.c: (setup_vorbisdec): * tests/check/elements/vorbistag.c: * tests/check/generic/clock-selection.c: * tests/check/generic/states.c: (setup), (teardown): * tests/check/libs/cddabasesrc.c: * tests/check/libs/video.c: * tests/check/pipelines/gio.c: * tests/check/pipelines/oggmux.c: * tests/check/pipelines/simple-launch-lines.c: (simple_launch_lines_suite): * tests/check/pipelines/streamheader.c: * tests/check/pipelines/theoraenc.c: * tests/check/pipelines/vorbisdec.c: * tests/check/pipelines/vorbisenc.c: * tests/examples/seek/scrubby.c: * tests/examples/seek/seek.c: (query_positions_elems), (query_positions_pads): * tests/icles/stress-xoverlay.c: (myclock): Correct all relevant warnings found by the sparse semantic code analyzer. This include marking several symbols static, using NULL instead of 0 for pointers and using "foo (void)" instead of "foo ()" for declarations. * win32/common/libgstrtp.def: Add gst_rtp_buffer_set_extension_data to the symbol definition file.
2008-03-03 06:04:31 +00:00
static GstPad *mysrcpad, *mysinkpad;
2011-09-29 11:46:36 +00:00
#define FORMATS "{ F32LE, F32BE, F64LE, F64BE, " \
"S32LE, S32BE, U32LE, U32BE, " \
"S24LE, S24BE, U24LE, U24BE, " \
"S16LE, S16BE, U16LE, U16BE, " \
"S8, U8 } "
#define CONVERT_CAPS_TEMPLATE_STRING \
2011-09-29 11:46:36 +00:00
"audio/x-raw, " \
"format = (string) "FORMATS", " \
"rate = (int) [ 1, MAX ], " \
2011-09-29 11:46:36 +00:00
"channels = (int) [ 1, MAX ]"
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (CONVERT_CAPS_TEMPLATE_STRING)
);
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (CONVERT_CAPS_TEMPLATE_STRING)
);
/* takes over reference for outcaps */
Correct all relevant warnings found by the sparse semantic code analyzer. This include marking several symbols static... Original commit message from CVS: * ext/alsa/gstalsamixertrack.c: (gst_alsa_mixer_track_get_type): * ext/alsa/gstalsasink.c: (set_hwparams): * ext/alsa/gstalsasrc.c: (set_hwparams): * ext/gio/gstgio.c: (gst_gio_uri_handler_get_uri): * ext/ogg/gstoggmux.h: * ext/ogg/gstogmparse.c: * gst-libs/gst/audio/audio.c: * gst-libs/gst/fft/kiss_fft_f64.c: (kiss_fft_f64_alloc): * gst-libs/gst/pbutils/missing-plugins.c: (gst_missing_uri_sink_message_new), (gst_missing_element_message_new), (gst_missing_decoder_message_new), (gst_missing_encoder_message_new): * gst-libs/gst/rtp/gstbasertppayload.c: * gst-libs/gst/rtp/gstrtcpbuffer.c: (gst_rtcp_packet_bye_get_reason): * gst/audioconvert/gstaudioconvert.c: * gst/audioresample/gstaudioresample.c: * gst/ffmpegcolorspace/imgconvert.c: * gst/playback/test.c: (gen_video_element), (gen_audio_element): * gst/typefind/gsttypefindfunctions.c: * gst/videoscale/vs_4tap.c: * gst/videoscale/vs_4tap.h: * sys/v4l/gstv4lelement.c: * sys/v4l/gstv4lsrc.c: (gst_v4lsrc_get_any_caps): * sys/v4l/v4l_calls.c: * sys/v4l/v4lsrc_calls.c: (gst_v4lsrc_capture_init), (gst_v4lsrc_try_capture): * sys/ximage/ximagesink.c: (gst_ximagesink_check_xshm_calls), (gst_ximagesink_ximage_new): * sys/xvimage/xvimagesink.c: (gst_xvimagesink_check_xshm_calls), (gst_xvimagesink_xvimage_new): * tests/check/elements/audioconvert.c: * tests/check/elements/audioresample.c: (fail_unless_perfect_stream): * tests/check/elements/audiotestsrc.c: (setup_audiotestsrc): * tests/check/elements/decodebin.c: * tests/check/elements/gdpdepay.c: (setup_gdpdepay), (setup_gdpdepay_streamheader): * tests/check/elements/gdppay.c: (setup_gdppay), (GST_START_TEST), (setup_gdppay_streamheader): * tests/check/elements/gnomevfssink.c: (setup_gnomevfssink): * tests/check/elements/multifdsink.c: (setup_multifdsink): * tests/check/elements/textoverlay.c: * tests/check/elements/videorate.c: (setup_videorate): * tests/check/elements/videotestsrc.c: (setup_videotestsrc): * tests/check/elements/volume.c: (setup_volume): * tests/check/elements/vorbisdec.c: (setup_vorbisdec): * tests/check/elements/vorbistag.c: * tests/check/generic/clock-selection.c: * tests/check/generic/states.c: (setup), (teardown): * tests/check/libs/cddabasesrc.c: * tests/check/libs/video.c: * tests/check/pipelines/gio.c: * tests/check/pipelines/oggmux.c: * tests/check/pipelines/simple-launch-lines.c: (simple_launch_lines_suite): * tests/check/pipelines/streamheader.c: * tests/check/pipelines/theoraenc.c: * tests/check/pipelines/vorbisdec.c: * tests/check/pipelines/vorbisenc.c: * tests/examples/seek/scrubby.c: * tests/examples/seek/seek.c: (query_positions_elems), (query_positions_pads): * tests/icles/stress-xoverlay.c: (myclock): Correct all relevant warnings found by the sparse semantic code analyzer. This include marking several symbols static, using NULL instead of 0 for pointers and using "foo (void)" instead of "foo ()" for declarations. * win32/common/libgstrtp.def: Add gst_rtp_buffer_set_extension_data to the symbol definition file.
2008-03-03 06:04:31 +00:00
static GstElement *
setup_audioconvert (GstCaps * outcaps)
{
GstElement *audioconvert;
GST_DEBUG ("setup_audioconvert with caps %" GST_PTR_FORMAT, outcaps);
audioconvert = gst_check_setup_element ("audioconvert");
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
g_object_set (G_OBJECT (audioconvert), "dithering", 0, NULL);
g_object_set (G_OBJECT (audioconvert), "noise-shaping", 0, NULL);
2011-11-24 20:39:14 +00:00
mysrcpad = gst_check_setup_src_pad (audioconvert, &srctemplate);
mysinkpad = gst_check_setup_sink_pad (audioconvert, &sinktemplate);
/* this installs a getcaps func that will always return the caps we set
* later */
gst_pad_use_fixed_caps (mysinkpad);
gst_pad_set_active (mysrcpad, TRUE);
gst_pad_set_active (mysinkpad, TRUE);
gst_pad_set_caps (mysinkpad, outcaps);
gst_caps_unref (outcaps);
outcaps = gst_pad_get_current_caps (mysinkpad);
fail_unless (gst_caps_is_fixed (outcaps));
gst_caps_unref (outcaps);
return audioconvert;
}
Correct all relevant warnings found by the sparse semantic code analyzer. This include marking several symbols static... Original commit message from CVS: * ext/alsa/gstalsamixertrack.c: (gst_alsa_mixer_track_get_type): * ext/alsa/gstalsasink.c: (set_hwparams): * ext/alsa/gstalsasrc.c: (set_hwparams): * ext/gio/gstgio.c: (gst_gio_uri_handler_get_uri): * ext/ogg/gstoggmux.h: * ext/ogg/gstogmparse.c: * gst-libs/gst/audio/audio.c: * gst-libs/gst/fft/kiss_fft_f64.c: (kiss_fft_f64_alloc): * gst-libs/gst/pbutils/missing-plugins.c: (gst_missing_uri_sink_message_new), (gst_missing_element_message_new), (gst_missing_decoder_message_new), (gst_missing_encoder_message_new): * gst-libs/gst/rtp/gstbasertppayload.c: * gst-libs/gst/rtp/gstrtcpbuffer.c: (gst_rtcp_packet_bye_get_reason): * gst/audioconvert/gstaudioconvert.c: * gst/audioresample/gstaudioresample.c: * gst/ffmpegcolorspace/imgconvert.c: * gst/playback/test.c: (gen_video_element), (gen_audio_element): * gst/typefind/gsttypefindfunctions.c: * gst/videoscale/vs_4tap.c: * gst/videoscale/vs_4tap.h: * sys/v4l/gstv4lelement.c: * sys/v4l/gstv4lsrc.c: (gst_v4lsrc_get_any_caps): * sys/v4l/v4l_calls.c: * sys/v4l/v4lsrc_calls.c: (gst_v4lsrc_capture_init), (gst_v4lsrc_try_capture): * sys/ximage/ximagesink.c: (gst_ximagesink_check_xshm_calls), (gst_ximagesink_ximage_new): * sys/xvimage/xvimagesink.c: (gst_xvimagesink_check_xshm_calls), (gst_xvimagesink_xvimage_new): * tests/check/elements/audioconvert.c: * tests/check/elements/audioresample.c: (fail_unless_perfect_stream): * tests/check/elements/audiotestsrc.c: (setup_audiotestsrc): * tests/check/elements/decodebin.c: * tests/check/elements/gdpdepay.c: (setup_gdpdepay), (setup_gdpdepay_streamheader): * tests/check/elements/gdppay.c: (setup_gdppay), (GST_START_TEST), (setup_gdppay_streamheader): * tests/check/elements/gnomevfssink.c: (setup_gnomevfssink): * tests/check/elements/multifdsink.c: (setup_multifdsink): * tests/check/elements/textoverlay.c: * tests/check/elements/videorate.c: (setup_videorate): * tests/check/elements/videotestsrc.c: (setup_videotestsrc): * tests/check/elements/volume.c: (setup_volume): * tests/check/elements/vorbisdec.c: (setup_vorbisdec): * tests/check/elements/vorbistag.c: * tests/check/generic/clock-selection.c: * tests/check/generic/states.c: (setup), (teardown): * tests/check/libs/cddabasesrc.c: * tests/check/libs/video.c: * tests/check/pipelines/gio.c: * tests/check/pipelines/oggmux.c: * tests/check/pipelines/simple-launch-lines.c: (simple_launch_lines_suite): * tests/check/pipelines/streamheader.c: * tests/check/pipelines/theoraenc.c: * tests/check/pipelines/vorbisdec.c: * tests/check/pipelines/vorbisenc.c: * tests/examples/seek/scrubby.c: * tests/examples/seek/seek.c: (query_positions_elems), (query_positions_pads): * tests/icles/stress-xoverlay.c: (myclock): Correct all relevant warnings found by the sparse semantic code analyzer. This include marking several symbols static, using NULL instead of 0 for pointers and using "foo (void)" instead of "foo ()" for declarations. * win32/common/libgstrtp.def: Add gst_rtp_buffer_set_extension_data to the symbol definition file.
2008-03-03 06:04:31 +00:00
static void
cleanup_audioconvert (GstElement * audioconvert)
{
GST_DEBUG ("cleanup_audioconvert");
gst_pad_set_active (mysrcpad, FALSE);
gst_pad_set_active (mysinkpad, FALSE);
gst_check_teardown_src_pad (audioconvert);
gst_check_teardown_sink_pad (audioconvert);
gst_check_teardown_element (audioconvert);
}
/* returns a newly allocated caps */
static GstCaps *
2011-09-29 11:46:36 +00:00
get_int_caps (guint channels, gint endianness, guint width,
guint depth, gboolean signedness)
{
GstCaps *caps;
2011-09-29 11:46:36 +00:00
GstAudioFormat fmt;
GstAudioInfo info;
g_assert (channels <= 2);
2011-09-29 11:46:36 +00:00
GST_DEBUG ("channels:%d, endianness:%d, width:%d, depth:%d, signedness:%d",
channels, endianness, width, depth, signedness);
2011-09-29 11:46:36 +00:00
fmt = gst_audio_format_build_integer (signedness, endianness, width, depth);
gst_audio_info_init (&info);
gst_audio_info_set_format (&info, fmt, 48000, channels, NULL);
caps = gst_audio_info_to_caps (&info);
fail_unless (caps != NULL);
GST_DEBUG ("returning caps %" GST_PTR_FORMAT, caps);
return caps;
}
static GstAudioFormat
get_float_format (gint endianness, gint width)
{
2011-09-29 11:46:36 +00:00
if (endianness == G_LITTLE_ENDIAN) {
if (width == 32)
return GST_AUDIO_FORMAT_F32LE;
2011-09-29 11:46:36 +00:00
else
return GST_AUDIO_FORMAT_F64LE;
2011-09-29 11:46:36 +00:00
} else {
if (width == 32)
return GST_AUDIO_FORMAT_F32BE;
2011-09-29 11:46:36 +00:00
else
return GST_AUDIO_FORMAT_F64BE;
2011-09-29 11:46:36 +00:00
}
}
/* returns a newly allocated caps */
static GstCaps *
get_float_caps (guint channels, gint endianness, guint width)
{
GstCaps *caps;
GstAudioInfo info;
2011-09-29 11:46:36 +00:00
g_assert (channels <= 2);
gst_audio_info_init (&info);
gst_audio_info_set_format (&info, get_float_format (endianness, width), 48000,
channels, NULL);
caps = gst_audio_info_to_caps (&info);
fail_unless (caps != NULL);
GST_DEBUG ("returning caps %" GST_PTR_FORMAT, caps);
return caps;
}
/* Copied from vorbis; the particular values used don't matter */
static GstAudioChannelPosition channelpositions[][6] = {
{ /* Mono */
GST_AUDIO_CHANNEL_POSITION_MONO},
{ /* Stereo */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
{ /* Stereo + Centre */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER},
{ /* Quadraphonic */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
},
{ /* Stereo + Centre + rear stereo */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
},
{ /* Full 5.1 Surround */
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_LFE1,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
}
};
/* we get this when recording from a soundcard with lots of input channels */
static GstAudioChannelPosition undefined_positions[][15] = {
{
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE}
};
/* For channels > 2, caps have to have channel positions. This adds some simple
* ones. Only implemented for channels between 1 and 6.
*/
static GstCaps *
2011-09-29 11:46:36 +00:00
get_float_mc_caps (guint channels, gint endianness, guint width,
const GstAudioChannelPosition * position)
{
GstCaps *caps;
GstAudioInfo info;
gst_audio_info_init (&info);
if (position) {
gst_audio_info_set_format (&info, get_float_format (endianness, width),
48000, channels, position);
} else if (channels <= 6) {
gst_audio_info_set_format (&info, get_float_format (endianness, width),
48000, channels, channelpositions[channels - 1]);
} else {
GstAudioChannelPosition pos[64];
gint i;
for (i = 0; i < 64; i++)
pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
gst_audio_info_set_format (&info, get_float_format (endianness, width),
48000, channels, pos);
}
caps = gst_audio_info_to_caps (&info);
fail_unless (caps != NULL);
GST_DEBUG ("returning caps %" GST_PTR_FORMAT, caps);
return caps;
}
static GstCaps *
2011-09-29 11:46:36 +00:00
get_int_mc_caps (guint channels, gint endianness, guint width,
guint depth, gboolean signedness, const GstAudioChannelPosition * position)
{
GstCaps *caps;
GstAudioFormat fmt;
GstAudioInfo info;
fmt = gst_audio_format_build_integer (signedness, endianness, width, depth);
gst_audio_info_init (&info);
if (position) {
gst_audio_info_set_format (&info, fmt, 48000, channels, position);
} else if (channels <= 6) {
gst_audio_info_set_format (&info, fmt, 48000, channels,
channelpositions[channels - 1]);
} else {
GstAudioChannelPosition pos[64];
gint i;
for (i = 0; i < 64; i++)
pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
gst_audio_info_set_format (&info, fmt, 48000, channels, pos);
}
caps = gst_audio_info_to_caps (&info);
fail_unless (caps != NULL);
GST_DEBUG ("returning caps %" GST_PTR_FORMAT, caps);
return caps;
}
/* eats the refs to the caps */
static void
verify_convert (const gchar * which, void *in, int inlength,
GstCaps * incaps, void *out, int outlength, GstCaps * outcaps,
GstFlowReturn expected_flow)
{
GstBuffer *inbuffer, *outbuffer;
GstElement *audioconvert;
GST_DEBUG ("verifying conversion %s", which);
GST_DEBUG ("incaps: %" GST_PTR_FORMAT, incaps);
GST_DEBUG ("outcaps: %" GST_PTR_FORMAT, outcaps);
ASSERT_CAPS_REFCOUNT (incaps, "incaps", 1);
ASSERT_CAPS_REFCOUNT (outcaps, "outcaps", 1);
audioconvert = setup_audioconvert (outcaps);
ASSERT_CAPS_REFCOUNT (outcaps, "outcaps", 1);
fail_unless (gst_element_set_state (audioconvert,
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
"could not set to playing");
gst_pad_push_event (mysrcpad, gst_event_new_caps (incaps));
GST_DEBUG ("Creating buffer of %d bytes", inlength);
inbuffer = gst_buffer_new_and_alloc (inlength);
2011-03-28 12:12:24 +00:00
gst_buffer_fill (inbuffer, 0, in, inlength);
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
/* pushing gives away my reference ... */
GST_DEBUG ("push it");
fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), expected_flow);
GST_DEBUG ("pushed it");
if (expected_flow != GST_FLOW_OK)
goto done;
/* ... and puts a new buffer on the global list */
fail_unless (g_list_length (buffers) == 1);
fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
2011-03-28 12:12:24 +00:00
fail_unless_equals_int (gst_buffer_get_size (outbuffer), outlength);
2011-03-28 12:12:24 +00:00
gst_check_buffer_data (outbuffer, out, outlength);
#if 0
if (memcmp (GST_BUFFER_DATA (outbuffer), out, outlength) != 0) {
g_print ("\nInput data:\n");
gst_util_dump_mem (in, inlength);
g_print ("\nConverted data:\n");
gst_util_dump_mem (GST_BUFFER_DATA (outbuffer), outlength);
g_print ("\nExpected data:\n");
gst_util_dump_mem (out, outlength);
}
fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, outlength) == 0,
"failed converting %s", which);
2011-03-28 12:12:24 +00:00
#endif
/* make sure that the channel positions are not lost */
{
GstStructure *in_s, *out_s;
gint out_chans;
in_s = gst_caps_get_structure (incaps, 0);
out_s = gst_caps_get_structure (gst_pad_get_current_caps (mysinkpad), 0);
fail_unless (gst_structure_get_int (out_s, "channels", &out_chans));
/* positions for 1 and 2 channels are implicit if not provided */
if (out_chans > 2 && gst_structure_has_field (in_s, "channel-positions")) {
if (!gst_structure_has_field (out_s, "channel-positions")) {
g_error ("Channel layout got lost somewhere:\n\nIns : %s\nOuts: %s\n",
gst_structure_to_string (in_s), gst_structure_to_string (out_s));
}
}
}
buffers = g_list_remove (buffers, outbuffer);
gst_buffer_unref (outbuffer);
done:
fail_unless (gst_element_set_state (audioconvert,
GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
/* cleanup */
GST_DEBUG ("cleanup audioconvert");
cleanup_audioconvert (audioconvert);
GST_DEBUG ("cleanup, unref incaps");
gst_caps_unref (incaps);
}
#define RUN_CONVERSION(which, inarray, in_get_caps, outarray, out_get_caps) \
verify_convert (which, inarray, sizeof (inarray), \
in_get_caps, outarray, sizeof (outarray), out_get_caps, GST_FLOW_OK)
#define RUN_CONVERSION_TO_FAIL(which, inarray, in_caps, outarray, out_caps) \
verify_convert (which, inarray, sizeof (inarray), \
in_caps, outarray, sizeof (outarray), out_caps, GST_FLOW_NOT_NEGOTIATED)
GST_START_TEST (test_int16)
{
/* stereo to mono */
{
gint16 in[] = { 16384, -256, 1024, 1024 };
gint16 out[] = { 8064, 1024 };
RUN_CONVERSION ("int16 stereo to mono",
2011-09-29 11:46:36 +00:00
in, get_int_caps (2, G_BYTE_ORDER, 16, 16, TRUE),
out, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE));
}
/* mono to stereo */
{
gint16 in[] = { 512, 1024 };
gint16 out[] = { 512, 512, 1024, 1024 };
RUN_CONVERSION ("int16 mono to stereo",
2011-09-29 11:46:36 +00:00
in, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE),
out, get_int_caps (2, G_BYTE_ORDER, 16, 16, TRUE));
}
/* signed -> unsigned */
{
gint16 in[] = { 0, -32767, 32767, -32768 };
guint16 out[] = { 32768, 1, 65535, 0 };
RUN_CONVERSION ("int16 signed to unsigned",
2011-09-29 11:46:36 +00:00
in, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE),
out, get_int_caps (1, G_BYTE_ORDER, 16, 16, FALSE));
RUN_CONVERSION ("int16 unsigned to signed",
2011-09-29 11:46:36 +00:00
out, get_int_caps (1, G_BYTE_ORDER, 16, 16, FALSE),
in, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE));
}
}
GST_END_TEST;
GST_START_TEST (test_float32)
{
/* stereo to mono */
{
gfloat in[] = { 0.6, -0.0078125, 0.03125, 0.03125 };
gfloat out[] = { 0.29609375, 0.03125 };
RUN_CONVERSION ("float32 stereo to mono",
2011-09-29 11:46:36 +00:00
in, get_float_caps (2, G_BYTE_ORDER, 32),
out, get_float_caps (1, G_BYTE_ORDER, 32));
}
/* mono to stereo */
{
gfloat in[] = { 0.015625, 0.03125 };
gfloat out[] = { 0.015625, 0.015625, 0.03125, 0.03125 };
RUN_CONVERSION ("float32 mono to stereo",
2011-09-29 11:46:36 +00:00
in, get_float_caps (1, G_BYTE_ORDER, 32),
out, get_float_caps (2, G_BYTE_ORDER, 32));
}
}
GST_END_TEST;
GST_START_TEST (test_int_conversion)
{
/* 8 <-> 16 signed */
/* NOTE: if audioconvert was doing dithering we'd have a problem */
{
gint8 in[] = { 0, 1, 2, 127, -127 };
gint16 out[] = { 0, 256, 512, 32512, -32512 };
RUN_CONVERSION ("int 8bit to 16bit signed",
2011-09-29 11:46:36 +00:00
in, get_int_caps (1, G_BYTE_ORDER, 8, 8, TRUE),
out, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE)
);
RUN_CONVERSION ("int 16bit signed to 8bit",
2011-09-29 11:46:36 +00:00
out, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE),
in, get_int_caps (1, G_BYTE_ORDER, 8, 8, TRUE)
);
}
/* 16 -> 8 signed */
{
gint16 in[] = { 0, 127, 128, 256, 256 + 127, 256 + 128 };
gint8 out[] = { 0, 0, 1, 1, 1, 2 };
RUN_CONVERSION ("16 bit to 8 signed",
2011-09-29 11:46:36 +00:00
in, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE),
out, get_int_caps (1, G_BYTE_ORDER, 8, 8, TRUE)
);
}
/* 8 unsigned <-> 16 signed */
/* NOTE: if audioconvert was doing dithering we'd have a problem */
{
guint8 in[] = { 128, 129, 130, 255, 1 };
gint16 out[] = { 0, 256, 512, 32512, -32512 };
GstCaps *incaps, *outcaps;
/* exploded for easier valgrinding */
2011-09-29 11:46:36 +00:00
incaps = get_int_caps (1, G_BYTE_ORDER, 8, 8, FALSE);
outcaps = get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE);
GST_DEBUG ("incaps: %" GST_PTR_FORMAT, incaps);
GST_DEBUG ("outcaps: %" GST_PTR_FORMAT, outcaps);
RUN_CONVERSION ("8 unsigned to 16 signed", in, incaps, out, outcaps);
RUN_CONVERSION ("16 signed to 8 unsigned", out, get_int_caps (1,
2011-09-29 11:46:36 +00:00
G_BYTE_ORDER, 16, 16, TRUE), in, get_int_caps (1, G_BYTE_ORDER, 8,
8, FALSE)
);
}
/* 8 <-> 24 signed */
/* NOTE: if audioconvert was doing dithering we'd have a problem */
{
gint8 in[] = { 0, 1, 127 };
guint8 out[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x7f };
/* out has the bytes in little-endian, so that's how they should be
* interpreted during conversion */
2011-09-29 11:46:36 +00:00
RUN_CONVERSION ("8 to 24 signed", in, get_int_caps (1, G_BYTE_ORDER, 8, 8,
TRUE), out, get_int_caps (1, G_LITTLE_ENDIAN, 24, 24, TRUE)
);
2011-09-29 11:46:36 +00:00
RUN_CONVERSION ("24 signed to 8", out, get_int_caps (1, G_LITTLE_ENDIAN, 24,
24, TRUE), in, get_int_caps (1, G_BYTE_ORDER, 8, 8, TRUE)
);
}
/* 16 bit signed <-> unsigned */
{
gint16 in[] = { 0, 128, -128 };
guint16 out[] = { 32768, 32896, 32640 };
RUN_CONVERSION ("16 signed to 16 unsigned",
2011-09-29 11:46:36 +00:00
in, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE),
out, get_int_caps (1, G_BYTE_ORDER, 16, 16, FALSE)
);
RUN_CONVERSION ("16 unsigned to 16 signed",
2011-09-29 11:46:36 +00:00
out, get_int_caps (1, G_BYTE_ORDER, 16, 16, FALSE),
in, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE)
);
}
/* 32 bit signed -> 16 bit signed for rounding check */
/* NOTE: if audioconvert was doing dithering we'd have a problem */
{
gint32 in[] = { 0, G_MININT32, G_MAXINT32,
(32 << 16), (32 << 16) + (1 << 15), (32 << 16) - (1 << 15),
(32 << 16) + (2 << 15), (32 << 16) - (2 << 15),
(-32 << 16) + (1 << 15), (-32 << 16) - (1 << 15),
(-32 << 16) + (2 << 15), (-32 << 16) - (2 << 15),
(-32 << 16)
};
gint16 out[] = { 0, G_MININT16, G_MAXINT16,
32, 33, 32,
33, 31,
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
-31, -32,
-31, -33,
-32
};
RUN_CONVERSION ("32 signed to 16 signed for rounding",
2011-09-29 11:46:36 +00:00
in, get_int_caps (1, G_BYTE_ORDER, 32, 32, TRUE),
out, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE)
);
}
/* 32 bit signed -> 16 bit unsigned for rounding check */
/* NOTE: if audioconvert was doing dithering we'd have a problem */
{
gint32 in[] = { 0, G_MININT32, G_MAXINT32,
(32 << 16), (32 << 16) + (1 << 15), (32 << 16) - (1 << 15),
(32 << 16) + (2 << 15), (32 << 16) - (2 << 15),
(-32 << 16) + (1 << 15), (-32 << 16) - (1 << 15),
(-32 << 16) + (2 << 15), (-32 << 16) - (2 << 15),
(-32 << 16)
};
guint16 out[] = { (1 << 15), 0, G_MAXUINT16,
(1 << 15) + 32, (1 << 15) + 33, (1 << 15) + 32,
(1 << 15) + 33, (1 << 15) + 31,
(1 << 15) - 31, (1 << 15) - 32,
(1 << 15) - 31, (1 << 15) - 33,
(1 << 15) - 32
};
RUN_CONVERSION ("32 signed to 16 unsigned for rounding",
2011-09-29 11:46:36 +00:00
in, get_int_caps (1, G_BYTE_ORDER, 32, 32, TRUE),
out, get_int_caps (1, G_BYTE_ORDER, 16, 16, FALSE)
);
}
}
GST_END_TEST;
GST_START_TEST (test_float_conversion)
{
/* 32 float <-> 16 signed */
/* NOTE: if audioconvert was doing dithering we'd have a problem */
{
gfloat in_le[] =
{ GFLOAT_TO_LE (0.0), GFLOAT_TO_LE (1.0), GFLOAT_TO_LE (-1.0),
GFLOAT_TO_LE (0.5), GFLOAT_TO_LE (-0.5), GFLOAT_TO_LE (1.1),
GFLOAT_TO_LE (-1.1)
};
gfloat in_be[] =
{ GFLOAT_TO_BE (0.0), GFLOAT_TO_BE (1.0), GFLOAT_TO_BE (-1.0),
GFLOAT_TO_BE (0.5), GFLOAT_TO_BE (-0.5), GFLOAT_TO_BE (1.1),
GFLOAT_TO_BE (-1.1)
};
gint16 out[] = { 0, 32767, -32768, 16384, -16384, 32767, -32768 };
/* only one direction conversion, the other direction does
* not produce exactly the same as the input due to floating
* point rounding errors etc. */
RUN_CONVERSION ("32 float le to 16 signed",
2011-09-29 11:46:36 +00:00
in_le, get_float_caps (1, G_LITTLE_ENDIAN, 32),
out, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE));
RUN_CONVERSION ("32 float be to 16 signed",
2011-09-29 11:46:36 +00:00
in_be, get_float_caps (1, G_BIG_ENDIAN, 32),
out, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE));
}
{
gint16 in[] = { 0, -32768, 16384, -16384 };
gfloat out[] = { 0.0, -1.0, 0.5, -0.5 };
RUN_CONVERSION ("16 signed to 32 float",
2011-09-29 11:46:36 +00:00
in, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE),
out, get_float_caps (1, G_BYTE_ORDER, 32));
}
/* 64 float <-> 16 signed */
/* NOTE: if audioconvert was doing dithering we'd have a problem */
{
gdouble in_le[] =
{ GDOUBLE_TO_LE (0.0), GDOUBLE_TO_LE (1.0), GDOUBLE_TO_LE (-1.0),
GDOUBLE_TO_LE (0.5), GDOUBLE_TO_LE (-0.5), GDOUBLE_TO_LE (1.1),
GDOUBLE_TO_LE (-1.1)
};
gdouble in_be[] =
{ GDOUBLE_TO_BE (0.0), GDOUBLE_TO_BE (1.0), GDOUBLE_TO_BE (-1.0),
GDOUBLE_TO_BE (0.5), GDOUBLE_TO_BE (-0.5), GDOUBLE_TO_BE (1.1),
GDOUBLE_TO_BE (-1.1)
};
gint16 out[] = { 0, 32767, -32768, 16384, -16384, 32767, -32768 };
/* only one direction conversion, the other direction does
* not produce exactly the same as the input due to floating
* point rounding errors etc. */
RUN_CONVERSION ("64 float LE to 16 signed",
2011-09-29 11:46:36 +00:00
in_le, get_float_caps (1, G_LITTLE_ENDIAN, 64),
out, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE));
RUN_CONVERSION ("64 float BE to 16 signed",
2011-09-29 11:46:36 +00:00
in_be, get_float_caps (1, G_BIG_ENDIAN, 64),
out, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE));
}
{
gint16 in[] = { 0, -32768, 16384, -16384 };
gdouble out[] = { 0.0,
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
(gdouble) (-32768L << 16) / 2147483647.0, /* ~ -1.0 */
(gdouble) (16384L << 16) / 2147483647.0, /* ~ 0.5 */
(gdouble) (-16384L << 16) / 2147483647.0, /* ~ -0.5 */
};
RUN_CONVERSION ("16 signed to 64 float",
2011-09-29 11:46:36 +00:00
in, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE),
out, get_float_caps (1, G_BYTE_ORDER, 64));
}
{
gint32 in[] = { 0, (-1L << 31), (1L << 30), (-1L << 30) };
gdouble out[] = { 0.0,
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
(gdouble) (-1L << 31) / 2147483647.0, /* ~ -1.0 */
(gdouble) (1L << 30) / 2147483647.0, /* ~ 0.5 */
(gdouble) (-1L << 30) / 2147483647.0, /* ~ -0.5 */
};
RUN_CONVERSION ("32 signed to 64 float",
2011-09-29 11:46:36 +00:00
in, get_int_caps (1, G_BYTE_ORDER, 32, 32, TRUE),
out, get_float_caps (1, G_BYTE_ORDER, 64));
}
/* 64-bit float <-> 32-bit float */
{
gdouble in[] = { 0.0, 1.0, -1.0, 0.5, -0.5 };
gfloat out[] = { 0.0, 1.0, -1.0, 0.5, -0.5 };
RUN_CONVERSION ("64 float to 32 float",
2011-09-29 11:46:36 +00:00
in, get_float_caps (1, G_BYTE_ORDER, 64),
out, get_float_caps (1, G_BYTE_ORDER, 32));
RUN_CONVERSION ("32 float to 64 float",
2011-09-29 11:46:36 +00:00
out, get_float_caps (1, G_BYTE_ORDER, 32),
in, get_float_caps (1, G_BYTE_ORDER, 64));
}
/* 32-bit float little endian <-> big endian */
{
gfloat le[] = { GFLOAT_TO_LE (0.0), GFLOAT_TO_LE (1.0), GFLOAT_TO_LE (-1.0),
GFLOAT_TO_LE (0.5), GFLOAT_TO_LE (-0.5)
};
gfloat be[] = { GFLOAT_TO_BE (0.0), GFLOAT_TO_BE (1.0), GFLOAT_TO_BE (-1.0),
GFLOAT_TO_BE (0.5), GFLOAT_TO_BE (-0.5)
};
RUN_CONVERSION ("32 float LE to BE",
2011-09-29 11:46:36 +00:00
le, get_float_caps (1, G_LITTLE_ENDIAN, 32),
be, get_float_caps (1, G_BIG_ENDIAN, 32));
RUN_CONVERSION ("32 float BE to LE",
2011-09-29 11:46:36 +00:00
be, get_float_caps (1, G_BIG_ENDIAN, 32),
le, get_float_caps (1, G_LITTLE_ENDIAN, 32));
}
/* 64-bit float little endian <-> big endian */
{
gdouble le[] =
{ GDOUBLE_TO_LE (0.0), GDOUBLE_TO_LE (1.0), GDOUBLE_TO_LE (-1.0),
GDOUBLE_TO_LE (0.5), GDOUBLE_TO_LE (-0.5)
};
gdouble be[] =
{ GDOUBLE_TO_BE (0.0), GDOUBLE_TO_BE (1.0), GDOUBLE_TO_BE (-1.0),
GDOUBLE_TO_BE (0.5), GDOUBLE_TO_BE (-0.5)
};
RUN_CONVERSION ("64 float LE to BE",
2011-09-29 11:46:36 +00:00
le, get_float_caps (1, G_LITTLE_ENDIAN, 64),
be, get_float_caps (1, G_BIG_ENDIAN, 64));
RUN_CONVERSION ("64 float BE to LE",
2011-09-29 11:46:36 +00:00
be, get_float_caps (1, G_BIG_ENDIAN, 64),
le, get_float_caps (1, G_LITTLE_ENDIAN, 64));
}
}
GST_END_TEST;
GST_START_TEST (test_multichannel_conversion)
{
{
gfloat in[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
gfloat out[] = { 0.0, 0.0 };
RUN_CONVERSION ("3 channels to 1", in, get_float_mc_caps (3,
G_BYTE_ORDER, 32, NULL), out, get_float_caps (1, G_BYTE_ORDER, 32));
RUN_CONVERSION ("1 channels to 3", out, get_float_caps (1, G_BYTE_ORDER,
32), in, get_float_mc_caps (3, G_BYTE_ORDER, 32, NULL));
}
{
gint16 in[] = { 0, 0, 0, 0, 0, 0 };
gint16 out[] = { 0, 0 };
RUN_CONVERSION ("3 channels to 1", in, get_int_mc_caps (3,
G_BYTE_ORDER, 16, 16, TRUE, NULL), out,
get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE));
2011-09-29 11:46:36 +00:00
RUN_CONVERSION ("1 channels to 3", out, get_int_caps (1, G_BYTE_ORDER, 16,
16, TRUE), in, get_int_mc_caps (3, G_BYTE_ORDER, 16, 16, TRUE,
NULL));
}
{
gint16 in[] = { 1, 2 };
gint16 out[] = { 1, 1, 2, 2 };
GstAudioChannelPosition in_layout[1] = { GST_AUDIO_CHANNEL_POSITION_MONO };
GstAudioChannelPosition out_layout[2] =
{ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
};
GstCaps *in_caps =
get_int_mc_caps (1, G_BYTE_ORDER, 16, 16, TRUE, in_layout);
GstCaps *out_caps =
get_int_mc_caps (2, G_BYTE_ORDER, 16, 16, TRUE, out_layout);
RUN_CONVERSION ("1 channels to 2 with standard layout", in,
in_caps, out, out_caps);
}
{
gint16 in[] = { 1, 2 };
gint16 out[] = { 1, 1, 2, 2 };
2011-09-29 11:46:36 +00:00
GstCaps *in_caps = get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE);
GstCaps *out_caps = get_int_caps (2, G_BYTE_ORDER, 16, 16, TRUE);
RUN_CONVERSION ("1 channels to 2 with standard layout and no positions set",
in, gst_caps_copy (in_caps), out, gst_caps_copy (out_caps));
RUN_CONVERSION ("2 channels to 1 with standard layout and no positions set",
out, out_caps, in, in_caps);
}
{
gint16 in[] = { 1, 2 };
gint16 out[] = { 1, 0, 2, 0 };
GstAudioChannelPosition in_layout[1] =
{ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT };
GstAudioChannelPosition out_layout[2] =
{ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
};
GstCaps *in_caps =
get_int_mc_caps (1, G_BYTE_ORDER, 16, 16, TRUE, in_layout);
GstCaps *out_caps =
get_int_mc_caps (2, G_BYTE_ORDER, 16, 16, TRUE, out_layout);
RUN_CONVERSION ("1 channels to 2 with non-standard layout", in,
in_caps, out, out_caps);
}
{
gint16 in[] = { 1, 2, 3, 4 };
gint16 out[] = { 2, 4 };
GstAudioChannelPosition in_layout[2] =
{ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
};
GstAudioChannelPosition out_layout[1] =
{ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER };
GstCaps *in_caps =
get_int_mc_caps (2, G_BYTE_ORDER, 16, 16, TRUE, in_layout);
GstCaps *out_caps =
get_int_mc_caps (1, G_BYTE_ORDER, 16, 16, TRUE, out_layout);
RUN_CONVERSION ("2 channels to 1 with non-standard layout", in,
in_caps, out, out_caps);
}
{
gint16 in[] = { 1, 2, 3, 4 };
gint16 out[] = { 2, 4 };
GstAudioChannelPosition in_layout[2] =
{ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
};
GstAudioChannelPosition out_layout[1] = { GST_AUDIO_CHANNEL_POSITION_MONO };
GstCaps *in_caps =
get_int_mc_caps (2, G_BYTE_ORDER, 16, 16, TRUE, in_layout);
GstCaps *out_caps =
get_int_mc_caps (1, G_BYTE_ORDER, 16, 16, TRUE, out_layout);
RUN_CONVERSION ("2 channels to 1 with standard layout", in,
in_caps, out, out_caps);
}
{
gint16 in[] = { 1, 2, 3, 4 };
gst-libs/gst/audio/multichannel.c: Allow rear center together with rear left/right and other previously conflicting c... Original commit message from CVS: * gst-libs/gst/audio/multichannel.c: (gst_audio_check_channel_positions), (gst_audio_set_structure_channel_positions_list), (gst_audio_fixate_channel_positions): Allow rear center together with rear left/right and other previously conflicting channel positions. The reason why they weren't allowed was the channel mixing implementation in audioconvert. Also take this into account when fixing channel layouts. Allow setting channel positions for 1/2 channels when using gst_audio_set_structure_channel_position(). * gst/audioconvert/gstchannelmix.c: (gst_channel_mix_fill_compatible), (gst_channel_mix_detect_pos), (gst_channel_mix_fill_one_other), (gst_channel_mix_fill_others), (gst_channel_mix_fill_special), (gst_channel_mix_fill_matrix): Major rewrite of the channel mixing. We now allow previously conflicting channel positions to appear together (rear center and rear left/right for example). Fixes bug #533817. Rework the way channels are mixed together to take more possible channel positions into account, properly mix from/to side channels and don't assume that either center, left&right or nothing of a specific position is available anymore. * tests/check/elements/audioconvert.c: (GST_START_TEST): Adjust unit tests with non-standard 1/2 channel layouts to the more correct new behaviour. Add a unit test for 5.1->Stereo downmixing.
2008-05-29 11:34:09 +00:00
gint16 out[] = { 1, 3 };
GstAudioChannelPosition in_layout[2] =
{ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER
};
GstAudioChannelPosition out_layout[1] = { GST_AUDIO_CHANNEL_POSITION_MONO };
GstCaps *in_caps =
get_int_mc_caps (2, G_BYTE_ORDER, 16, 16, TRUE, in_layout);
GstCaps *out_caps =
get_int_mc_caps (1, G_BYTE_ORDER, 16, 16, TRUE, out_layout);
RUN_CONVERSION ("2 channels to 1 with non-standard layout", in,
in_caps, out, out_caps);
}
{
gint16 in[] = { 1, 2, 3, 4 };
gint16 out[] = { 1, 3 };
GstAudioChannelPosition in_layout[2] =
{ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT
};
GstAudioChannelPosition out_layout[1] = { GST_AUDIO_CHANNEL_POSITION_MONO };
GstCaps *in_caps =
get_int_mc_caps (2, G_BYTE_ORDER, 16, 16, TRUE, in_layout);
GstCaps *out_caps =
get_int_mc_caps (1, G_BYTE_ORDER, 16, 16, TRUE, out_layout);
RUN_CONVERSION ("2 channels to 1 with non-standard layout", in,
in_caps, out, out_caps);
}
gst-libs/gst/audio/multichannel.c: Allow rear center together with rear left/right and other previously conflicting c... Original commit message from CVS: * gst-libs/gst/audio/multichannel.c: (gst_audio_check_channel_positions), (gst_audio_set_structure_channel_positions_list), (gst_audio_fixate_channel_positions): Allow rear center together with rear left/right and other previously conflicting channel positions. The reason why they weren't allowed was the channel mixing implementation in audioconvert. Also take this into account when fixing channel layouts. Allow setting channel positions for 1/2 channels when using gst_audio_set_structure_channel_position(). * gst/audioconvert/gstchannelmix.c: (gst_channel_mix_fill_compatible), (gst_channel_mix_detect_pos), (gst_channel_mix_fill_one_other), (gst_channel_mix_fill_others), (gst_channel_mix_fill_special), (gst_channel_mix_fill_matrix): Major rewrite of the channel mixing. We now allow previously conflicting channel positions to appear together (rear center and rear left/right for example). Fixes bug #533817. Rework the way channels are mixed together to take more possible channel positions into account, properly mix from/to side channels and don't assume that either center, left&right or nothing of a specific position is available anymore. * tests/check/elements/audioconvert.c: (GST_START_TEST): Adjust unit tests with non-standard 1/2 channel layouts to the more correct new behaviour. Add a unit test for 5.1->Stereo downmixing.
2008-05-29 11:34:09 +00:00
{
gint16 in[] = { 4, 5, 4, 2, 2, 1 };
gint16 out[] = { 3, 3 };
GstCaps *in_caps = get_int_mc_caps (6, G_BYTE_ORDER, 16, 16, TRUE, NULL);
2011-09-29 11:46:36 +00:00
GstCaps *out_caps = get_int_caps (2, G_BYTE_ORDER, 16, 16, TRUE);
gst-libs/gst/audio/multichannel.c: Allow rear center together with rear left/right and other previously conflicting c... Original commit message from CVS: * gst-libs/gst/audio/multichannel.c: (gst_audio_check_channel_positions), (gst_audio_set_structure_channel_positions_list), (gst_audio_fixate_channel_positions): Allow rear center together with rear left/right and other previously conflicting channel positions. The reason why they weren't allowed was the channel mixing implementation in audioconvert. Also take this into account when fixing channel layouts. Allow setting channel positions for 1/2 channels when using gst_audio_set_structure_channel_position(). * gst/audioconvert/gstchannelmix.c: (gst_channel_mix_fill_compatible), (gst_channel_mix_detect_pos), (gst_channel_mix_fill_one_other), (gst_channel_mix_fill_others), (gst_channel_mix_fill_special), (gst_channel_mix_fill_matrix): Major rewrite of the channel mixing. We now allow previously conflicting channel positions to appear together (rear center and rear left/right for example). Fixes bug #533817. Rework the way channels are mixed together to take more possible channel positions into account, properly mix from/to side channels and don't assume that either center, left&right or nothing of a specific position is available anymore. * tests/check/elements/audioconvert.c: (GST_START_TEST): Adjust unit tests with non-standard 1/2 channel layouts to the more correct new behaviour. Add a unit test for 5.1->Stereo downmixing.
2008-05-29 11:34:09 +00:00
RUN_CONVERSION ("5.1 to 2 channels", in, in_caps, out, out_caps);
}
{
gint16 in[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
gint16 out[] = { 0, 0 };
GstAudioChannelPosition in_layout[11] = {
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_LFE1,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
};
GstCaps *in_caps =
get_int_mc_caps (11, G_BYTE_ORDER, 16, 16, TRUE, in_layout);
GstCaps *out_caps = get_int_mc_caps (2, G_BYTE_ORDER, 16, 16, TRUE, NULL);
RUN_CONVERSION ("11 channels to 2", in,
gst_caps_copy (in_caps), out, gst_caps_copy (out_caps));
}
{
gint16 in[] = { 0, 0 };
gint16 out[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
GstAudioChannelPosition out_layout[11] = {
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_LFE1,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
};
GstCaps *in_caps = get_int_mc_caps (2, G_BYTE_ORDER, 16, 16, TRUE, NULL);
GstCaps *out_caps =
get_int_mc_caps (11, G_BYTE_ORDER, 16, 16, TRUE, out_layout);
RUN_CONVERSION ("2 channels to 11", in,
gst_caps_copy (in_caps), out, gst_caps_copy (out_caps));
}
}
GST_END_TEST;
GST_START_TEST (test_caps_negotiation)
{
GstElement *src, *ac1, *ac2, *ac3, *sink;
GstElement *pipeline;
GstPad *ac3_src;
GstCaps *caps1, *caps2;
pipeline = gst_pipeline_new ("test");
/* create elements */
src = gst_element_factory_make ("audiotestsrc", "src");
ac1 = gst_element_factory_make ("audioconvert", "ac1");
ac2 = gst_element_factory_make ("audioconvert", "ac2");
ac3 = gst_element_factory_make ("audioconvert", "ac3");
sink = gst_element_factory_make ("fakesink", "sink");
Don't use bad gst_element_get_pad(). Original commit message from CVS: * ext/ogg/gstoggdemux.c: (gst_ogg_pad_typefind): * gst/playback/decodetest.c: (new_decoded_pad_cb): * gst/playback/gstdecodebin.c: (gst_decode_bin_init), (try_to_link_1), (elem_is_dynamic), (close_link), (type_found), (cleanup_decodebin): * gst/playback/gstdecodebin2.c: (gst_decode_bin_init), (connect_element), (gst_decode_group_control_demuxer_pad): * gst/playback/gstplaybasebin.c: (queue_remove_probe), (queue_out_of_data), (gen_preroll_element), (preroll_unlinked), (mute_group_type): * gst/playback/gstplaybin.c: (gst_play_bin_vis_blocked), (gst_play_bin_set_property), (handoff), (gen_video_element), (gen_text_element), (gen_audio_element), (gen_vis_element), (remove_sinks), (add_sink), (setup_sinks): * gst/playback/gstplaybin2.c: (pad_added_cb), (no_more_pads_cb): * gst/playback/gstplaysink.c: (gst_play_sink_get_video_sink), (gst_play_sink_get_audio_sink), (gst_play_sink_vis_unblocked), (gst_play_sink_vis_blocked), (gst_play_sink_set_vis_plugin), (gst_play_sink_get_vis_plugin), (gst_play_sink_set_mute), (gen_video_chain), (gen_text_chain), (gen_audio_chain), (gen_vis_chain), (gst_play_sink_reconfigure), (gst_play_sink_set_font_desc), (gst_play_sink_get_font_desc), (gst_play_sink_request_pad): * gst/playback/gsturidecodebin.c: (type_found), (setup_source): * gst/playback/test.c: (gen_video_element), (gen_audio_element), (cb_newpad): * gst/playback/test6.c: (new_decoded_pad_cb): * tests/check/elements/audioconvert.c: (GST_START_TEST): * tests/check/elements/audiorate.c: (test_injector_chain), (do_perfect_stream_test): * tests/check/elements/ffmpegcolorspace.c: (GST_START_TEST): * tests/check/elements/gdpdepay.c: (GST_START_TEST): * tests/check/elements/gnomevfssink.c: * tests/check/elements/textoverlay.c: (notgst_check_setup_src_pad2), (notgst_check_teardown_src_pad2): * tests/check/elements/videotestsrc.c: (GST_START_TEST): * tests/check/libs/cddabasesrc.c: (GST_START_TEST): * tests/check/pipelines/oggmux.c: (test_pipeline): * tests/check/pipelines/streamheader.c: (GST_START_TEST): * tests/check/pipelines/theoraenc.c: (GST_START_TEST): * tests/check/pipelines/vorbisenc.c: (GST_START_TEST): * tests/examples/seek/scrubby.c: (make_wav_pipeline): * tests/examples/seek/seek.c: (make_mod_pipeline), (make_dv_pipeline), (make_wav_pipeline), (make_flac_pipeline), (make_sid_pipeline), (make_parse_pipeline), (make_vorbis_pipeline), (make_theora_pipeline), (make_vorbis_theora_pipeline), (make_avi_msmpeg4v3_mp3_pipeline), (make_mp3_pipeline), (make_avi_pipeline), (make_mpeg_pipeline), (make_mpegnt_pipeline), (update_fill), (msg_buffering): Don't use bad gst_element_get_pad().
2008-05-21 16:36:50 +00:00
ac3_src = gst_element_get_static_pad (ac3, "src");
/* test with 2 audioconvert elements */
gst_bin_add_many (GST_BIN (pipeline), src, ac1, ac3, sink, NULL);
gst_element_link_many (src, ac1, ac3, sink, NULL);
/* Set to PAUSED and wait for PREROLL */
fail_if (gst_element_set_state (pipeline, GST_STATE_PAUSED) ==
GST_STATE_CHANGE_FAILURE, "Failed to set test pipeline to PAUSED");
fail_if (gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE) !=
GST_STATE_CHANGE_SUCCESS, "Failed to set test pipeline to PAUSED");
caps1 = gst_pad_query_caps (ac3_src, NULL);
fail_if (caps1 == NULL, "gst_pad_query_caps returned NULL");
GST_DEBUG ("Caps size 1 : %d", gst_caps_get_size (caps1));
fail_if (gst_element_set_state (pipeline, GST_STATE_READY) ==
GST_STATE_CHANGE_FAILURE, "Failed to set test pipeline back to READY");
fail_if (gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE) !=
GST_STATE_CHANGE_SUCCESS, "Failed to set test pipeline back to READY");
/* test with 3 audioconvert elements */
gst_element_unlink (ac1, ac3);
gst_bin_add (GST_BIN (pipeline), ac2);
gst_element_link_many (ac1, ac2, ac3, NULL);
fail_if (gst_element_set_state (pipeline, GST_STATE_PAUSED) ==
GST_STATE_CHANGE_FAILURE, "Failed to set test pipeline back to PAUSED");
fail_if (gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE) !=
GST_STATE_CHANGE_SUCCESS, "Failed to set test pipeline back to PAUSED");
caps2 = gst_pad_query_caps (ac3_src, NULL);
fail_if (caps2 == NULL, "gst_pad_query_caps returned NULL");
GST_DEBUG ("Caps size 2 : %d", gst_caps_get_size (caps2));
fail_unless (gst_caps_get_size (caps1) == gst_caps_get_size (caps2));
gst_caps_unref (caps1);
gst_caps_unref (caps2);
fail_if (gst_element_set_state (pipeline, GST_STATE_NULL) ==
GST_STATE_CHANGE_FAILURE, "Failed to set test pipeline back to NULL");
fail_if (gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE) !=
GST_STATE_CHANGE_SUCCESS, "Failed to set test pipeline back to NULL");
gst_object_unref (ac3_src);
gst_object_unref (pipeline);
}
GST_END_TEST;
GST_START_TEST (test_convert_undefined_multichannel)
{
/* (A) CONVERSION FROM 'WORSE' TO 'BETTER' FORMAT */
/* 1 channel, NONE positions, int8 => int16 */
{
guint16 out[] = { 0x2000 };
guint8 in[] = { 0x20 };
GstCaps *out_caps = get_int_mc_caps (1, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[1 - 1]);
GstCaps *in_caps = get_int_mc_caps (1, G_BYTE_ORDER, 8, 8, FALSE,
undefined_positions[1 - 1]);
RUN_CONVERSION ("1 channel, undefined layout, identity conversion, "
"int8 => int16", in, in_caps, out, out_caps);
}
/* 2 channels, NONE positions, int8 => int16 */
{
guint16 out[] = { 0x8000, 0x2000 };
guint8 in[] = { 0x80, 0x20 };
GstCaps *out_caps = get_int_mc_caps (2, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[2 - 1]);
GstCaps *in_caps = get_int_mc_caps (2, G_BYTE_ORDER, 8, 8, FALSE,
undefined_positions[2 - 1]);
RUN_CONVERSION ("2 channels, undefined layout, identity conversion, "
"int8 => int16", in, in_caps, out, out_caps);
}
/* 6 channels, NONE positions, int8 => int16 */
{
guint16 out[] = { 0x0000, 0x2000, 0x8000, 0x2000, 0x0000, 0xff00 };
guint8 in[] = { 0x00, 0x20, 0x80, 0x20, 0x00, 0xff };
GstCaps *out_caps = get_int_mc_caps (6, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[6 - 1]);
GstCaps *in_caps = get_int_mc_caps (6, G_BYTE_ORDER, 8, 8, FALSE,
undefined_positions[6 - 1]);
RUN_CONVERSION ("6 channels, undefined layout, identity conversion, "
"int8 => int16", in, in_caps, out, out_caps);
}
/* 9 channels, NONE positions, int8 => int16 */
{
guint16 out[] = { 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000, 0xff00, 0x0000
};
guint8 in[] = { 0x00, 0xff, 0x00, 0x20, 0x80, 0x20, 0x00, 0xff, 0x00 };
GstCaps *out_caps = get_int_mc_caps (9, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[9 - 1]);
GstCaps *in_caps = get_int_mc_caps (9, G_BYTE_ORDER, 8, 8, FALSE,
undefined_positions[9 - 1]);
RUN_CONVERSION ("9 channels, undefined layout, identity conversion, "
"int8 => int16", in, in_caps, out, out_caps);
}
/* 15 channels, NONE positions, int8 => int16 */
{
guint16 out[] =
{ 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000, 0x0000, 0xff00,
0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000, 0x0000
};
guint8 in[] =
{ 0x00, 0xff, 0x00, 0x20, 0x80, 0x20, 0x00, 0xff, 0x00, 0xff, 0x00,
0x20, 0x80, 0x20, 0x00
};
GstCaps *out_caps = get_int_mc_caps (15, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[15 - 1]);
GstCaps *in_caps = get_int_mc_caps (15, G_BYTE_ORDER, 8, 8, FALSE,
undefined_positions[15 - 1]);
RUN_CONVERSION ("15 channels, undefined layout, identity conversion, "
"int8 => int16", in, in_caps, out, out_caps);
}
/* (B) CONVERSION FROM 'BETTER' TO 'WORSE' FORMAT */
/* 1 channel, NONE positions, int16 => int8 */
{
guint16 in[] = { 0x2000 };
guint8 out[] = { 0x20 };
GstCaps *in_caps = get_int_mc_caps (1, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[1 - 1]);
GstCaps *out_caps = get_int_mc_caps (1, G_BYTE_ORDER, 8, 8, FALSE,
undefined_positions[1 - 1]);
RUN_CONVERSION ("1 channel, undefined layout, identity conversion, "
"int16 => int8", in, in_caps, out, out_caps);
}
/* 2 channels, NONE positions, int16 => int8 */
{
guint16 in[] = { 0x8000, 0x2000 };
guint8 out[] = { 0x80, 0x20 };
GstCaps *in_caps = get_int_mc_caps (2, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[2 - 1]);
GstCaps *out_caps = get_int_mc_caps (2, G_BYTE_ORDER, 8, 8, FALSE,
undefined_positions[2 - 1]);
RUN_CONVERSION ("2 channels, undefined layout, identity conversion, "
"int16 => int8", in, in_caps, out, out_caps);
}
/* 6 channels, NONE positions, int16 => int8 */
{
guint16 in[] = { 0x0000, 0x2000, 0x8000, 0x2000, 0x0000, 0xff00 };
guint8 out[] = { 0x00, 0x20, 0x80, 0x20, 0x00, 0xff };
GstCaps *in_caps = get_int_mc_caps (6, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[6 - 1]);
GstCaps *out_caps = get_int_mc_caps (6, G_BYTE_ORDER, 8, 8, FALSE,
undefined_positions[6 - 1]);
RUN_CONVERSION ("6 channels, undefined layout, identity conversion, "
"int16 => int8", in, in_caps, out, out_caps);
}
/* 9 channels, NONE positions, int16 => int8 */
{
guint16 in[] = { 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000, 0xff00, 0x0000
};
guint8 out[] = { 0x00, 0xff, 0x00, 0x20, 0x80, 0x20, 0x00, 0xff, 0x00 };
GstCaps *in_caps = get_int_mc_caps (9, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[9 - 1]);
GstCaps *out_caps = get_int_mc_caps (9, G_BYTE_ORDER, 8, 8, FALSE,
undefined_positions[9 - 1]);
RUN_CONVERSION ("9 channels, undefined layout, identity conversion, "
"int16 => int8", in, in_caps, out, out_caps);
}
/* 15 channels, NONE positions, int16 => int8 */
{
guint16 in[] = { 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000, 0xff00, 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000
};
guint8 out[] =
{ 0x00, 0xff, 0x00, 0x20, 0x80, 0x20, 0x00, 0xff, 0x00, 0xff, 0x00,
0x20, 0x80, 0x20, 0x00
};
GstCaps *in_caps = get_int_mc_caps (15, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[15 - 1]);
GstCaps *out_caps = get_int_mc_caps (15, G_BYTE_ORDER, 8, 8, FALSE,
undefined_positions[15 - 1]);
RUN_CONVERSION ("15 channels, undefined layout, identity conversion, "
"int16 => int8", in, in_caps, out, out_caps);
}
/* (C) NO CONVERSION, SAME FORMAT */
/* 1 channel, NONE positions, int16 => int16 */
{
guint16 in[] = { 0x2000 };
guint16 out[] = { 0x2000 };
GstCaps *in_caps = get_int_mc_caps (1, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[1 - 1]);
GstCaps *out_caps = get_int_mc_caps (1, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[1 - 1]);
RUN_CONVERSION ("1 channel, undefined layout, identity conversion, "
"int16 => int16", in, in_caps, out, out_caps);
}
/* 2 channels, NONE positions, int16 => int16 */
{
guint16 in[] = { 0x8000, 0x2000 };
guint16 out[] = { 0x8000, 0x2000 };
GstCaps *in_caps = get_int_mc_caps (2, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[2 - 1]);
GstCaps *out_caps = get_int_mc_caps (2, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[2 - 1]);
RUN_CONVERSION ("2 channels, undefined layout, identity conversion, "
"int16 => int16", in, in_caps, out, out_caps);
}
/* 6 channels, NONE positions, int16 => int16 */
{
guint16 in[] = { 0x0000, 0x2000, 0x8000, 0x2000, 0x0000, 0xff00 };
guint16 out[] = { 0x0000, 0x2000, 0x8000, 0x2000, 0x0000, 0xff00 };
GstCaps *in_caps = get_int_mc_caps (6, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[6 - 1]);
GstCaps *out_caps = get_int_mc_caps (6, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[6 - 1]);
RUN_CONVERSION ("6 channels, undefined layout, identity conversion, "
"int16 => int16", in, in_caps, out, out_caps);
}
/* 9 channels, NONE positions, int16 => int16 */
{
guint16 in[] = { 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000, 0xff00, 0x0000
};
guint16 out[] = { 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000, 0xff00, 0x0000
};
GstCaps *in_caps = get_int_mc_caps (9, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[9 - 1]);
GstCaps *out_caps = get_int_mc_caps (9, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[9 - 1]);
RUN_CONVERSION ("9 channels, undefined layout, identity conversion, "
"int16 => int16", in, in_caps, out, out_caps);
}
/* 15 channels, NONE positions, int16 => int16 */
{
guint16 in[] = { 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000, 0xff00, 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000
};
guint16 out[] = { 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000, 0xff00, 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000
};
GstCaps *in_caps = get_int_mc_caps (15, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[15 - 1]);
GstCaps *out_caps = get_int_mc_caps (15, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[15 - 1]);
RUN_CONVERSION ("15 channels, undefined layout, identity conversion, "
"int16 => int16", in, in_caps, out, out_caps);
}
/* (C) int16 => float */
/* 9 channels, NONE positions, int16 => float */
{
guint16 in[] = { 0x0000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000,
0x0000, 0x8000, 0x0000
};
gfloat out[] = { -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0 };
GstCaps *in_caps = get_int_mc_caps (9, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[9 - 1]);
GstCaps *out_caps =
get_float_mc_caps (9, G_BYTE_ORDER, 32, undefined_positions[9 - 1]);
RUN_CONVERSION ("9 channels, undefined layout, identity conversion, "
"int16 => float", in, in_caps, out, out_caps);
}
/* 15 channels, NONE positions, int16 => float */
{
guint16 in[] = { 0x0000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000,
0x0000, 0x8000, 0x0000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000,
0x0000
};
gfloat out[] =
{ -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0,
0.0, -1.0
};
GstCaps *in_caps = get_int_mc_caps (15, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[15 - 1]);
GstCaps *out_caps =
get_float_mc_caps (15, G_BYTE_ORDER, 32, undefined_positions[15 - 1]);
RUN_CONVERSION ("15 channels, undefined layout, identity conversion, "
"int16 => float", in, in_caps, out, out_caps);
}
/* 9 channels, NONE positions, int16 => float (same as above, but no
* position on output caps to see if audioconvert transforms correctly) */
{
guint16 in[] = { 0x0000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000,
0x0000, 0x8000, 0x0000
};
gfloat out[] = { -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0 };
GstCaps *in_caps = get_int_mc_caps (9, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[9 - 1]);
GstCaps *out_caps =
get_float_mc_caps (9, G_BYTE_ORDER, 32, undefined_positions[9 - 1]);
gst_structure_remove_field (gst_caps_get_structure (out_caps, 0),
"channel-mask");
RUN_CONVERSION ("9 channels, undefined layout, identity conversion, "
"int16 => float", in, in_caps, out, out_caps);
}
/* 15 channels, NONE positions, int16 => float (same as above, but no
* position on output caps to see if audioconvert transforms correctly) */
{
guint16 in[] = { 0x0000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000,
0x0000, 0x8000, 0x0000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000,
0x0000
};
gfloat out[] =
{ -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0,
0.0, -1.0
};
GstCaps *in_caps = get_int_mc_caps (15, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[15 - 1]);
GstCaps *out_caps =
get_float_mc_caps (15, G_BYTE_ORDER, 32, undefined_positions[15 - 1]);
gst_structure_remove_field (gst_caps_get_structure (out_caps, 0),
"channel-mask");
RUN_CONVERSION ("15 channels, undefined layout, identity conversion, "
"int16 => float", in, in_caps, out, out_caps);
}
/* 8 channels, NONE positions => 2 channels: should fail, no mixing allowed */
{
guint16 in[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
gfloat out[] = { -1.0, -1.0 };
GstCaps *in_caps = get_int_mc_caps (8, G_BYTE_ORDER, 16, 16, FALSE,
undefined_positions[8 - 1]);
GstCaps *out_caps = get_float_mc_caps (2, G_BYTE_ORDER, 32, NULL);
RUN_CONVERSION_TO_FAIL ("8 channels with layout => 2 channels",
in, in_caps, out, out_caps);
}
/* 8 channels, with positions => 2 channels (makes sure channel-position
* fields are removed properly in some cases in ::transform_caps, so we
* don't up with caps with 2 channels and 8 channel positions) */
{
GstAudioChannelPosition layout8ch[] = {
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_LFE1,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT
};
gint16 in[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
gint16 out[] = { 0, 0 };
GstCaps *in_caps =
get_int_mc_caps (8, G_BYTE_ORDER, 16, 16, TRUE, layout8ch);
GstCaps *out_caps = get_int_mc_caps (2, G_BYTE_ORDER, 16, 16, TRUE, NULL);
RUN_CONVERSION ("8 channels with layout => 2 channels",
in, in_caps, out, out_caps);
}
}
GST_END_TEST;
Correct all relevant warnings found by the sparse semantic code analyzer. This include marking several symbols static... Original commit message from CVS: * ext/alsa/gstalsamixertrack.c: (gst_alsa_mixer_track_get_type): * ext/alsa/gstalsasink.c: (set_hwparams): * ext/alsa/gstalsasrc.c: (set_hwparams): * ext/gio/gstgio.c: (gst_gio_uri_handler_get_uri): * ext/ogg/gstoggmux.h: * ext/ogg/gstogmparse.c: * gst-libs/gst/audio/audio.c: * gst-libs/gst/fft/kiss_fft_f64.c: (kiss_fft_f64_alloc): * gst-libs/gst/pbutils/missing-plugins.c: (gst_missing_uri_sink_message_new), (gst_missing_element_message_new), (gst_missing_decoder_message_new), (gst_missing_encoder_message_new): * gst-libs/gst/rtp/gstbasertppayload.c: * gst-libs/gst/rtp/gstrtcpbuffer.c: (gst_rtcp_packet_bye_get_reason): * gst/audioconvert/gstaudioconvert.c: * gst/audioresample/gstaudioresample.c: * gst/ffmpegcolorspace/imgconvert.c: * gst/playback/test.c: (gen_video_element), (gen_audio_element): * gst/typefind/gsttypefindfunctions.c: * gst/videoscale/vs_4tap.c: * gst/videoscale/vs_4tap.h: * sys/v4l/gstv4lelement.c: * sys/v4l/gstv4lsrc.c: (gst_v4lsrc_get_any_caps): * sys/v4l/v4l_calls.c: * sys/v4l/v4lsrc_calls.c: (gst_v4lsrc_capture_init), (gst_v4lsrc_try_capture): * sys/ximage/ximagesink.c: (gst_ximagesink_check_xshm_calls), (gst_ximagesink_ximage_new): * sys/xvimage/xvimagesink.c: (gst_xvimagesink_check_xshm_calls), (gst_xvimagesink_xvimage_new): * tests/check/elements/audioconvert.c: * tests/check/elements/audioresample.c: (fail_unless_perfect_stream): * tests/check/elements/audiotestsrc.c: (setup_audiotestsrc): * tests/check/elements/decodebin.c: * tests/check/elements/gdpdepay.c: (setup_gdpdepay), (setup_gdpdepay_streamheader): * tests/check/elements/gdppay.c: (setup_gdppay), (GST_START_TEST), (setup_gdppay_streamheader): * tests/check/elements/gnomevfssink.c: (setup_gnomevfssink): * tests/check/elements/multifdsink.c: (setup_multifdsink): * tests/check/elements/textoverlay.c: * tests/check/elements/videorate.c: (setup_videorate): * tests/check/elements/videotestsrc.c: (setup_videotestsrc): * tests/check/elements/volume.c: (setup_volume): * tests/check/elements/vorbisdec.c: (setup_vorbisdec): * tests/check/elements/vorbistag.c: * tests/check/generic/clock-selection.c: * tests/check/generic/states.c: (setup), (teardown): * tests/check/libs/cddabasesrc.c: * tests/check/libs/video.c: * tests/check/pipelines/gio.c: * tests/check/pipelines/oggmux.c: * tests/check/pipelines/simple-launch-lines.c: (simple_launch_lines_suite): * tests/check/pipelines/streamheader.c: * tests/check/pipelines/theoraenc.c: * tests/check/pipelines/vorbisdec.c: * tests/check/pipelines/vorbisenc.c: * tests/examples/seek/scrubby.c: * tests/examples/seek/seek.c: (query_positions_elems), (query_positions_pads): * tests/icles/stress-xoverlay.c: (myclock): Correct all relevant warnings found by the sparse semantic code analyzer. This include marking several symbols static, using NULL instead of 0 for pointers and using "foo (void)" instead of "foo ()" for declarations. * win32/common/libgstrtp.def: Add gst_rtp_buffer_set_extension_data to the symbol definition file.
2008-03-03 06:04:31 +00:00
static Suite *
audioconvert_suite (void)
{
Suite *s = suite_create ("audioconvert");
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_int16);
tcase_add_test (tc_chain, test_float32);
tcase_add_test (tc_chain, test_int_conversion);
tcase_add_test (tc_chain, test_float_conversion);
tcase_add_test (tc_chain, test_multichannel_conversion);
tcase_add_test (tc_chain, test_caps_negotiation);
tcase_add_test (tc_chain, test_convert_undefined_multichannel);
return s;
}
GST_CHECK_MAIN (audioconvert);