mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-03 01:02:19 +00:00
vorbisdec: also support ivorbis tremor decoder
... which only needs a bit of refactoring and extracting to support the minor difference in (i)vorbis interface. Fixes #609063.
This commit is contained in:
parent
5e06eaa517
commit
32dff24552
8 changed files with 428 additions and 60 deletions
23
configure.ac
23
configure.ac
|
@ -584,6 +584,29 @@ AG_GST_CHECK_FEATURE(GNOME_VFS, [GNOME VFS], gnomevfs, [
|
||||||
)
|
)
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl *** ivorbis ***
|
||||||
|
dnl AM_PATH_IVORBIS only takes two options
|
||||||
|
translit(dnm, m, l) AM_CONDITIONAL(USE_IVORBIS, true)
|
||||||
|
AG_GST_CHECK_FEATURE(IVORBIS, [integer vorbis plug-in], ivorbisdec, [
|
||||||
|
AG_GST_PKG_CHECK_MODULES(IVORBIS, vorbisidec)
|
||||||
|
if test $HAVE_IVORBIS = no
|
||||||
|
then
|
||||||
|
IVORBIS_LIBS=
|
||||||
|
IVORBIS_CFLAGS=
|
||||||
|
AC_CHECK_LIB(vorbisidec, vorbis_block_init,
|
||||||
|
[IVORBIS_LIBS=-lvorbisidec
|
||||||
|
HAVE_IVORBIS=yes
|
||||||
|
case $host in
|
||||||
|
arm-*-*)
|
||||||
|
IVORBIS_CFLAGS="-D_ARM_ASSEM_ $IVORBIS_CFLAGS"
|
||||||
|
esac
|
||||||
|
],
|
||||||
|
HAVE_IVORBIS=no)
|
||||||
|
AC_SUBST(IVORBIS_LIBS)
|
||||||
|
AC_SUBST(IVORBIS_CFLAGS)
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
dnl *** libgio ***
|
dnl *** libgio ***
|
||||||
translit(dnm, m, l) AM_CONDITIONAL(USE_GIO, true)
|
translit(dnm, m, l) AM_CONDITIONAL(USE_GIO, true)
|
||||||
AG_GST_CHECK_FEATURE(GIO, [GIO library], gio, [
|
AG_GST_CHECK_FEATURE(GIO, [GIO library], gio, [
|
||||||
|
|
|
@ -42,9 +42,17 @@ endif
|
||||||
|
|
||||||
if USE_VORBIS
|
if USE_VORBIS
|
||||||
VORBIS_DIR=vorbis
|
VORBIS_DIR=vorbis
|
||||||
else
|
endif
|
||||||
|
|
||||||
|
if USE_IVORBIS
|
||||||
|
VORBIS_DIR=vorbis
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !USE_VORBIS
|
||||||
|
if !USE_IVORBIS
|
||||||
VORBIS_DIR=
|
VORBIS_DIR=
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
if USE_THEORA
|
if USE_THEORA
|
||||||
THEORA_DIR=theora
|
THEORA_DIR=theora
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
plugin_LTLIBRARIES = libgstvorbis.la
|
plugin_LTLIBRARIES =
|
||||||
|
|
||||||
|
if USE_VORBIS
|
||||||
|
plugin_LTLIBRARIES += libgstvorbis.la
|
||||||
|
|
||||||
libgstvorbis_la_SOURCES = gstvorbis.c \
|
libgstvorbis_la_SOURCES = gstvorbis.c \
|
||||||
gstvorbisdec.c \
|
gstvorbisdec.c \
|
||||||
|
gstvorbisdeclib.c \
|
||||||
gstvorbisenc.c \
|
gstvorbisenc.c \
|
||||||
gstvorbisparse.c \
|
gstvorbisparse.c \
|
||||||
gstvorbistag.c \
|
gstvorbistag.c \
|
||||||
gstvorbiscommon.c
|
gstvorbiscommon.c
|
||||||
|
|
||||||
libgstvorbis_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(VORBIS_CFLAGS)
|
libgstvorbis_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(VORBIS_CFLAGS)
|
||||||
## AM_PATH_VORBIS also sets VORBISENC_LIBS
|
## AM_PATH_VORBIS also sets VORBISENC_LIBS
|
||||||
libgstvorbis_la_LIBADD = \
|
libgstvorbis_la_LIBADD = \
|
||||||
$(top_builddir)/gst-libs/gst/tag/libgsttag-@GST_MAJORMINOR@.la \
|
$(top_builddir)/gst-libs/gst/tag/libgsttag-@GST_MAJORMINOR@.la \
|
||||||
|
@ -16,9 +20,26 @@ libgstvorbis_la_LIBADD = \
|
||||||
$(VORBIS_LIBS) $(VORBISENC_LIBS)
|
$(VORBIS_LIBS) $(VORBISENC_LIBS)
|
||||||
libgstvorbis_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
libgstvorbis_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||||
libgstvorbis_la_LIBTOOLFLAGS = --tag=disable-static
|
libgstvorbis_la_LIBTOOLFLAGS = --tag=disable-static
|
||||||
|
endif
|
||||||
|
|
||||||
|
if USE_IVORBIS
|
||||||
|
plugin_LTLIBRARIES += libgstivorbisdec.la
|
||||||
|
|
||||||
|
libgstivorbisdec_la_SOURCES = gstivorbisdec.c \
|
||||||
|
gstvorbisdec.c gstvorbisdeclib.c gstvorbiscommon.c
|
||||||
|
libgstivorbisdec_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
|
||||||
|
-DTREMOR $(IVORBIS_CFLAGS)
|
||||||
|
libgstivorbisdec_la_LIBADD = \
|
||||||
|
$(top_builddir)/gst-libs/gst/tag/libgsttag-@GST_MAJORMINOR@.la \
|
||||||
|
$(top_builddir)/gst-libs/gst/audio/libgstaudio-@GST_MAJORMINOR@.la \
|
||||||
|
$(GST_LIBS) $(IVORBIS_LIBS)
|
||||||
|
libgstivorbisdec_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||||
|
libgstivorbisdec_la_LIBTOOLFLAGS = --tag=disable-static
|
||||||
|
endif
|
||||||
|
|
||||||
noinst_HEADERS = gstvorbisenc.h \
|
noinst_HEADERS = gstvorbisenc.h \
|
||||||
gstvorbisdec.h \
|
gstvorbisdec.h \
|
||||||
|
gstvorbisdeclib.h \
|
||||||
gstvorbisparse.h \
|
gstvorbisparse.h \
|
||||||
gstvorbistag.h \
|
gstvorbistag.h \
|
||||||
gstvorbiscommon.h
|
gstvorbiscommon.h
|
||||||
|
|
47
ext/vorbis/gstivorbisdec.c
Normal file
47
ext/vorbis/gstivorbisdec.c
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||||
|
*
|
||||||
|
* 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 "gstvorbisdec.h"
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY (vorbisdec_debug);
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
plugin_init (GstPlugin * plugin)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* if tremor is around, there is probably good reason for it, so preferred */
|
||||||
|
if (!gst_element_register (plugin, "ivorbisdec", GST_RANK_PRIMARY + 1,
|
||||||
|
gst_vorbis_dec_get_type ()))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_INIT (vorbisdec_debug, "ivorbisdec", 0,
|
||||||
|
"vorbis decoding element (integer decoder)");
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||||
|
GST_VERSION_MINOR,
|
||||||
|
"ivorbisdec",
|
||||||
|
"Vorbis Tremor decoder",
|
||||||
|
plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
|
|
@ -52,25 +52,13 @@ GST_DEBUG_CATEGORY_EXTERN (vorbisdec_debug);
|
||||||
#define GST_CAT_DEFAULT vorbisdec_debug
|
#define GST_CAT_DEFAULT vorbisdec_debug
|
||||||
|
|
||||||
static const GstElementDetails vorbis_dec_details =
|
static const GstElementDetails vorbis_dec_details =
|
||||||
GST_ELEMENT_DETAILS ("Vorbis audio decoder",
|
GST_VORBIS_DEC_ELEMENT_DETAILS;
|
||||||
"Codec/Decoder/Audio",
|
|
||||||
"decode raw vorbis streams to float audio",
|
|
||||||
"Benjamin Otte <in7y118@public.uni-hamburg.de>");
|
|
||||||
|
|
||||||
static GstStaticPadTemplate vorbis_dec_src_factory =
|
static GstStaticPadTemplate vorbis_dec_src_factory =
|
||||||
GST_STATIC_PAD_TEMPLATE ("src",
|
GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS ("audio/x-raw-float, "
|
GST_VORBIS_DEC_SRC_CAPS);
|
||||||
"rate = (int) [ 1, MAX ], "
|
|
||||||
"channels = (int) [ 1, 256 ], " "endianness = (int) BYTE_ORDER, "
|
|
||||||
/* no ifdef in macros, please
|
|
||||||
#ifdef GST_VORBIS_DEC_SEQUENTIAL
|
|
||||||
"layout = \"sequential\", "
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
"width = (int) 32")
|
|
||||||
);
|
|
||||||
|
|
||||||
static GstStaticPadTemplate vorbis_dec_sink_factory =
|
static GstStaticPadTemplate vorbis_dec_sink_factory =
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
|
@ -79,7 +67,8 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_STATIC_CAPS ("audio/x-vorbis")
|
GST_STATIC_CAPS ("audio/x-vorbis")
|
||||||
);
|
);
|
||||||
|
|
||||||
GST_BOILERPLATE (GstVorbisDec, gst_vorbis_dec, GstElement, GST_TYPE_ELEMENT);
|
GST_BOILERPLATE (GST_VORBIS_DEC_GLIB_TYPE_NAME, gst_vorbis_dec, GstElement,
|
||||||
|
GST_TYPE_ELEMENT);
|
||||||
|
|
||||||
static void vorbis_dec_finalize (GObject * object);
|
static void vorbis_dec_finalize (GObject * object);
|
||||||
static gboolean vorbis_dec_sink_event (GstPad * pad, GstEvent * event);
|
static gboolean vorbis_dec_sink_event (GstPad * pad, GstEvent * event);
|
||||||
|
@ -560,6 +549,7 @@ vorbis_handle_identification_packet (GstVorbisDec * vd)
|
||||||
{
|
{
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
const GstAudioChannelPosition *pos = NULL;
|
const GstAudioChannelPosition *pos = NULL;
|
||||||
|
gint width = GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH;
|
||||||
|
|
||||||
switch (vd->vi.channels) {
|
switch (vd->vi.channels) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -589,11 +579,24 @@ vorbis_handle_identification_packet (GstVorbisDec * vd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vd->width = 4;
|
/* negotiate width with downstream */
|
||||||
|
caps = gst_pad_get_allowed_caps (vd->srcpad);
|
||||||
|
if (caps) {
|
||||||
|
if (!gst_caps_is_empty (caps)) {
|
||||||
|
GstStructure *s;
|
||||||
|
|
||||||
|
s = gst_caps_get_structure (caps, 0);
|
||||||
|
/* template ensures 16 or 32 */
|
||||||
|
gst_structure_get_int (s, "width", &width);
|
||||||
|
}
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
}
|
||||||
|
vd->width = width >> 3;
|
||||||
|
|
||||||
caps = gst_caps_copy (gst_pad_get_pad_template_caps (vd->srcpad));
|
caps = gst_caps_copy (gst_pad_get_pad_template_caps (vd->srcpad));
|
||||||
gst_caps_set_simple (caps, "rate", G_TYPE_INT, vd->vi.rate,
|
gst_caps_set_simple (caps, "rate", G_TYPE_INT, vd->vi.rate,
|
||||||
"channels", G_TYPE_INT, vd->vi.channels);
|
"channels", G_TYPE_INT, vd->vi.channels,
|
||||||
|
"width", G_TYPE_INT, width, NULL);
|
||||||
|
|
||||||
if (pos) {
|
if (pos) {
|
||||||
gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
|
gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
|
||||||
|
@ -620,8 +623,8 @@ vorbis_handle_comment_packet (GstVorbisDec * vd, ogg_packet * packet)
|
||||||
GST_DEBUG_OBJECT (vd, "parsing comment packet");
|
GST_DEBUG_OBJECT (vd, "parsing comment packet");
|
||||||
|
|
||||||
buf = gst_buffer_new ();
|
buf = gst_buffer_new ();
|
||||||
GST_BUFFER_DATA (buf) = packet->packet;
|
GST_BUFFER_DATA (buf) = gst_ogg_packet_data (packet);
|
||||||
GST_BUFFER_SIZE (buf) = packet->bytes;
|
GST_BUFFER_SIZE (buf) = gst_ogg_packet_size (packet);
|
||||||
|
|
||||||
list =
|
list =
|
||||||
gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\003vorbis", 7,
|
gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\003vorbis", 7,
|
||||||
|
@ -738,12 +741,12 @@ vorbis_handle_header_packet (GstVorbisDec * vd, ogg_packet * packet)
|
||||||
GST_DEBUG_OBJECT (vd, "parsing header packet");
|
GST_DEBUG_OBJECT (vd, "parsing header packet");
|
||||||
|
|
||||||
/* Packetno = 0 if the first byte is exactly 0x01 */
|
/* Packetno = 0 if the first byte is exactly 0x01 */
|
||||||
packet->b_o_s = (packet->packet[0] == 0x1) ? 1 : 0;
|
packet->b_o_s = ((gst_ogg_packet_data (packet))[0] == 0x1) ? 1 : 0;
|
||||||
|
|
||||||
if ((ret = vorbis_synthesis_headerin (&vd->vi, &vd->vc, packet)))
|
if ((ret = vorbis_synthesis_headerin (&vd->vi, &vd->vc, packet)))
|
||||||
goto header_read_error;
|
goto header_read_error;
|
||||||
|
|
||||||
switch (packet->packet[0]) {
|
switch ((gst_ogg_packet_data (packet))[0]) {
|
||||||
case 0x01:
|
case 0x01:
|
||||||
res = vorbis_handle_identification_packet (vd);
|
res = vorbis_handle_identification_packet (vd);
|
||||||
break;
|
break;
|
||||||
|
@ -770,27 +773,6 @@ header_read_error:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These samples can be outside of the float -1.0 -- 1.0 range, this
|
|
||||||
* is allowed, downstream elements are supposed to clip */
|
|
||||||
static void
|
|
||||||
copy_samples (float *out, float **in, guint samples, gint channels)
|
|
||||||
{
|
|
||||||
gint i, j;
|
|
||||||
|
|
||||||
#ifdef GST_VORBIS_DEC_SEQUENTIAL
|
|
||||||
for (i = 0; i < channels; i++) {
|
|
||||||
memcpy (out, in[i], samples * sizeof (float));
|
|
||||||
out += samples;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
for (j = 0; j < samples; j++) {
|
|
||||||
for (i = 0; i < channels; i++) {
|
|
||||||
*out++ = in[i][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
vorbis_dec_push_forward (GstVorbisDec * dec, GstBuffer * buf)
|
vorbis_dec_push_forward (GstVorbisDec * dec, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
|
@ -855,7 +837,7 @@ static GstFlowReturn
|
||||||
vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
|
vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
|
||||||
GstClockTime timestamp, GstClockTime duration)
|
GstClockTime timestamp, GstClockTime duration)
|
||||||
{
|
{
|
||||||
float **pcm;
|
vorbis_sample_t **pcm;
|
||||||
guint sample_count;
|
guint sample_count;
|
||||||
GstBuffer *out;
|
GstBuffer *out;
|
||||||
GstFlowReturn result;
|
GstFlowReturn result;
|
||||||
|
@ -899,8 +881,8 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
|
||||||
goto wrong_samples;
|
goto wrong_samples;
|
||||||
|
|
||||||
/* copy samples in buffer */
|
/* copy samples in buffer */
|
||||||
copy_samples ((float *) GST_BUFFER_DATA (out), pcm, sample_count,
|
copy_samples ((vorbis_sample_t *) GST_BUFFER_DATA (out), pcm, sample_count,
|
||||||
vd->vi.channels);
|
vd->vi.channels, vd->width);
|
||||||
|
|
||||||
GST_LOG_OBJECT (vd, "setting output size to %d", size);
|
GST_LOG_OBJECT (vd, "setting output size to %d", size);
|
||||||
GST_BUFFER_SIZE (out) = size;
|
GST_BUFFER_SIZE (out) = size;
|
||||||
|
@ -952,22 +934,24 @@ wrong_samples:
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
vorbis_dec_decode_buffer (GstVorbisDec * vd, GstBuffer * buffer)
|
vorbis_dec_decode_buffer (GstVorbisDec * vd, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
ogg_packet packet;
|
ogg_packet *packet;
|
||||||
|
ogg_packet_wrapper packet_wrapper;
|
||||||
GstFlowReturn result = GST_FLOW_OK;
|
GstFlowReturn result = GST_FLOW_OK;
|
||||||
|
|
||||||
/* make ogg_packet out of the buffer */
|
/* make ogg_packet out of the buffer */
|
||||||
packet.packet = GST_BUFFER_DATA (buffer);
|
gst_ogg_packet_wrapper_from_buffer (&packet_wrapper, buffer);
|
||||||
packet.bytes = GST_BUFFER_SIZE (buffer);
|
packet = gst_ogg_packet_from_wrapper (&packet_wrapper);
|
||||||
packet.granulepos = -1;
|
/* set some more stuff */
|
||||||
packet.packetno = 0; /* we don't care */
|
packet->granulepos = -1;
|
||||||
|
packet->packetno = 0; /* we don't care */
|
||||||
/* EOS does not matter, it is used in vorbis to implement clipping the last
|
/* EOS does not matter, it is used in vorbis to implement clipping the last
|
||||||
* block of samples based on the granulepos. We clip based on segments. */
|
* block of samples based on the granulepos. We clip based on segments. */
|
||||||
packet.e_o_s = 0;
|
packet->e_o_s = 0;
|
||||||
|
|
||||||
GST_LOG_OBJECT (vd, "decode buffer of size %ld", packet.bytes);
|
GST_LOG_OBJECT (vd, "decode buffer of size %ld", packet->bytes);
|
||||||
|
|
||||||
/* error out on empty header packets, but just skip empty data packets */
|
/* error out on empty header packets, but just skip empty data packets */
|
||||||
if (G_UNLIKELY (packet.bytes == 0)) {
|
if (G_UNLIKELY (packet->bytes == 0)) {
|
||||||
if (vd->initialized)
|
if (vd->initialized)
|
||||||
goto empty_buffer;
|
goto empty_buffer;
|
||||||
else
|
else
|
||||||
|
@ -975,19 +959,19 @@ vorbis_dec_decode_buffer (GstVorbisDec * vd, GstBuffer * buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* switch depending on packet type */
|
/* switch depending on packet type */
|
||||||
if (packet.packet[0] & 1) {
|
if ((gst_ogg_packet_data (packet))[0] & 1) {
|
||||||
if (vd->initialized) {
|
if (vd->initialized) {
|
||||||
GST_WARNING_OBJECT (vd, "Already initialized, so ignoring header packet");
|
GST_WARNING_OBJECT (vd, "Already initialized, so ignoring header packet");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
result = vorbis_handle_header_packet (vd, &packet);
|
result = vorbis_handle_header_packet (vd, packet);
|
||||||
} else {
|
} else {
|
||||||
GstClockTime timestamp, duration;
|
GstClockTime timestamp, duration;
|
||||||
|
|
||||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||||
duration = GST_BUFFER_DURATION (buffer);
|
duration = GST_BUFFER_DURATION (buffer);
|
||||||
|
|
||||||
result = vorbis_handle_data_packet (vd, &packet, timestamp, duration);
|
result = vorbis_handle_data_packet (vd, packet, timestamp, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <vorbis/codec.h>
|
#include "gstvorbisdeclib.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
122
ext/vorbis/gstvorbisdeclib.c
Normal file
122
ext/vorbis/gstvorbisdeclib.c
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2010 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
|
||||||
|
* Copyright (C) 2010 Nokia Corporation. All rights reserved.
|
||||||
|
* Contact: Stefan Kost <stefan.kost@nokia.com>
|
||||||
|
*
|
||||||
|
* Tremor modifications <2006>:
|
||||||
|
* Chris Lord, OpenedHand Ltd. <chris@openedhand.com>, http://www.o-hand.com/
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "gstvorbisdeclib.h"
|
||||||
|
|
||||||
|
#ifndef TREMOR
|
||||||
|
/* These samples can be outside of the float -1.0 -- 1.0 range, this
|
||||||
|
* is allowed, downstream elements are supposed to clip */
|
||||||
|
void
|
||||||
|
copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
|
||||||
|
gint channels, gint width)
|
||||||
|
{
|
||||||
|
gint i, j;
|
||||||
|
|
||||||
|
g_assert (width == 4);
|
||||||
|
|
||||||
|
#ifdef GST_VORBIS_DEC_SEQUENTIAL
|
||||||
|
for (i = 0; i < channels; i++) {
|
||||||
|
memcpy (out, in[i], samples * sizeof (float));
|
||||||
|
out += samples;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (j = 0; j < samples; j++) {
|
||||||
|
for (i = 0; i < channels; i++) {
|
||||||
|
*out++ = in[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Taken from Tremor, misc.h */
|
||||||
|
#ifdef _ARM_ASSEM_
|
||||||
|
static inline ogg_int32_t
|
||||||
|
CLIP_TO_15 (ogg_int32_t x)
|
||||||
|
{
|
||||||
|
int tmp;
|
||||||
|
asm volatile ("subs %1, %0, #32768\n\t"
|
||||||
|
"movpl %0, #0x7f00\n\t"
|
||||||
|
"orrpl %0, %0, #0xff\n"
|
||||||
|
"adds %1, %0, #32768\n\t"
|
||||||
|
"movmi %0, #0x8000":"+r" (x), "=r" (tmp)
|
||||||
|
::"cc");
|
||||||
|
|
||||||
|
return (x);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline ogg_int32_t
|
||||||
|
CLIP_TO_15 (ogg_int32_t x)
|
||||||
|
{
|
||||||
|
int ret = x;
|
||||||
|
|
||||||
|
ret -= ((x <= 32767) - 1) & (x - 32767);
|
||||||
|
ret -= ((x >= -32768) - 1) & (x + 32768);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
copy_samples_32 (gint32 * out, ogg_int32_t ** in, guint samples, gint channels)
|
||||||
|
{
|
||||||
|
gint i, j;
|
||||||
|
|
||||||
|
for (j = 0; j < samples; j++) {
|
||||||
|
for (i = 0; i < channels; i++) {
|
||||||
|
*out++ = CLIP_TO_15 (in[i][j] >> 9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
copy_samples_16 (gint16 * out, ogg_int32_t ** in, guint samples, gint channels)
|
||||||
|
{
|
||||||
|
gint i, j;
|
||||||
|
|
||||||
|
for (j = 0; j < samples; j++) {
|
||||||
|
for (i = 0; i < channels; i++) {
|
||||||
|
*out++ = CLIP_TO_15 (in[i][j] >> 9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
|
||||||
|
gint channels, gint width)
|
||||||
|
{
|
||||||
|
if (width == 4) {
|
||||||
|
copy_samples_32 ((gint32 *) out, in, samples, channels);
|
||||||
|
} else if (width == 2) {
|
||||||
|
copy_samples_16 ((gint16 *) out, in, samples, channels);
|
||||||
|
} else {
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
163
ext/vorbis/gstvorbisdeclib.h
Normal file
163
ext/vorbis/gstvorbisdeclib.h
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
/* GStreamer
|
||||||
|
* Copyright (C) 2010 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
|
||||||
|
* Copyright (C) 2010 Nokia Corporation. All rights reserved.
|
||||||
|
* Contact: Stefan Kost <stefan.kost@nokia.com>
|
||||||
|
*
|
||||||
|
* Tremor modifications <2006>:
|
||||||
|
* Chris Lord, OpenedHand Ltd. <chris@openedhand.com>, http://www.o-hand.com/
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GST_VORBIS_DEC_LIB_H__
|
||||||
|
#define __GST_VORBIS_DEC_LIB_H__
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
#ifndef TREMOR
|
||||||
|
|
||||||
|
#include <vorbis/codec.h>
|
||||||
|
|
||||||
|
typedef float vorbis_sample_t;
|
||||||
|
typedef ogg_packet ogg_packet_wrapper;
|
||||||
|
|
||||||
|
#define GST_VORBIS_DEC_ELEMENT_DETAILS \
|
||||||
|
GST_ELEMENT_DETAILS ("Vorbis audio decoder", \
|
||||||
|
"Codec/Decoder/Audio", \
|
||||||
|
"decode raw vorbis streams to float audio", \
|
||||||
|
"Benjamin Otte <in7y118@public.uni-hamburg.de>")
|
||||||
|
|
||||||
|
#define GST_VORBIS_DEC_SRC_CAPS \
|
||||||
|
GST_STATIC_CAPS ("audio/x-raw-float, " "rate = (int) [ 1, MAX ], " \
|
||||||
|
"channels = (int) [ 1, 256 ], " "endianness = (int) BYTE_ORDER, " \
|
||||||
|
"width = (int) 32")
|
||||||
|
|
||||||
|
#define GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH (32)
|
||||||
|
|
||||||
|
#define GST_VORBIS_DEC_GLIB_TYPE_NAME GstVorbisDec
|
||||||
|
|
||||||
|
static inline guint8 *
|
||||||
|
gst_ogg_packet_data (ogg_packet * p)
|
||||||
|
{
|
||||||
|
return (guint8 *) p->packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gint
|
||||||
|
gst_ogg_packet_size (ogg_packet * p)
|
||||||
|
{
|
||||||
|
return p->bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gst_ogg_packet_wrapper_from_buffer (ogg_packet * packet, GstBuffer * buffer)
|
||||||
|
{
|
||||||
|
packet->packet = GST_BUFFER_DATA (buffer);
|
||||||
|
packet->bytes = GST_BUFFER_SIZE (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ogg_packet *
|
||||||
|
gst_ogg_packet_from_wrapper (ogg_packet_wrapper * packet)
|
||||||
|
{
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <tremor/ivorbiscodec.h>
|
||||||
|
|
||||||
|
typedef ogg_int32_t vorbis_sample_t;
|
||||||
|
typedef struct _ogg_packet_wrapper ogg_packet_wrapper;
|
||||||
|
|
||||||
|
struct _ogg_packet_wrapper {
|
||||||
|
ogg_packet packet;
|
||||||
|
ogg_reference ref;
|
||||||
|
ogg_buffer buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GST_VORBIS_DEC_ELEMENT_DETAILS \
|
||||||
|
GST_ELEMENT_DETAILS ("Vorbis audio decoder", \
|
||||||
|
"Codec/Decoder/Audio", \
|
||||||
|
"decode raw vorbis streams to integer audio", \
|
||||||
|
"Benjamin Otte <in7y118@public.uni-hamburg.de>\n" \
|
||||||
|
"Chris Lord <chris@openedhand.com>")
|
||||||
|
|
||||||
|
#define GST_VORBIS_DEC_SRC_CAPS \
|
||||||
|
GST_STATIC_CAPS ("audio/x-raw-int, " \
|
||||||
|
"rate = (int) [ 1, MAX ], " \
|
||||||
|
"channels = (int) [ 1, 6 ], " \
|
||||||
|
"endianness = (int) BYTE_ORDER, " \
|
||||||
|
"width = (int) { 16, 32 }, " \
|
||||||
|
"depth = (int) 16, " "signed = (boolean) true")
|
||||||
|
|
||||||
|
#define GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH (16)
|
||||||
|
|
||||||
|
/* we need a different type name here */
|
||||||
|
#define GST_VORBIS_DEC_GLIB_TYPE_NAME GstIVorbisDec
|
||||||
|
|
||||||
|
/* and still have it compile */
|
||||||
|
typedef struct _GstVorbisDec GstIVorbisDec;
|
||||||
|
typedef struct _GstVorbisDecClass GstIVorbisDecClass;
|
||||||
|
|
||||||
|
/* compensate minor variation */
|
||||||
|
#define vorbis_synthesis(a, b) vorbis_synthesis (a, b, 1)
|
||||||
|
|
||||||
|
static inline guint8 *
|
||||||
|
gst_ogg_packet_data (ogg_packet * p)
|
||||||
|
{
|
||||||
|
return (guint8 *) p->packet->buffer->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gint
|
||||||
|
gst_ogg_packet_size (ogg_packet * p)
|
||||||
|
{
|
||||||
|
return p->packet->buffer->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gst_ogg_packet_wrapper_from_buffer (ogg_packet_wrapper * packet,
|
||||||
|
GstBuffer * buffer)
|
||||||
|
{
|
||||||
|
ogg_reference *ref = &packet->ref;
|
||||||
|
ogg_buffer *buf = &packet->buf;
|
||||||
|
|
||||||
|
buf->data = GST_BUFFER_DATA (buffer);
|
||||||
|
buf->size = GST_BUFFER_SIZE (buffer);
|
||||||
|
buf->refcount = 1;
|
||||||
|
buf->ptr.owner = NULL;
|
||||||
|
buf->ptr.next = NULL;
|
||||||
|
|
||||||
|
ref->buffer = buf;
|
||||||
|
ref->begin = 0;
|
||||||
|
ref->length = buf->size;
|
||||||
|
ref->next = NULL;
|
||||||
|
|
||||||
|
packet->packet.packet = ref;
|
||||||
|
packet->packet.bytes = ref->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ogg_packet *
|
||||||
|
gst_ogg_packet_from_wrapper (ogg_packet_wrapper * packet)
|
||||||
|
{
|
||||||
|
return &(packet->packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void copy_samples (vorbis_sample_t *out, vorbis_sample_t **in,
|
||||||
|
guint samples, gint channels, gint width);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __GST_VORBIS_DEC_LIB_H__ */
|
Loading…
Reference in a new issue