aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2013-07-14 12:56:33 +0200
committerSebastian Dröge <slomo@circular-chaos.org>2013-07-14 12:57:09 +0200
commitedfcc936c71f04396d751d6a1e26ed3f47d2cd76 (patch)
tree34339688099ea368bc1362b84b1b3610dcca6e3c
parent921e9840af479d38d6189e800de97b88ecd3c822 (diff)
New upstream development snapshot.debian/1.1.2-1
-rw-r--r--debian/changelog5
-rw-r--r--debian/control4
-rw-r--r--debian/patches/03_git-2013-04-26.patch8465
-rw-r--r--debian/patches/04_gstreamer-1.0.patch18
-rw-r--r--debian/patches/series2
5 files changed, 6 insertions, 8488 deletions
diff --git a/debian/changelog b/debian/changelog
index 6886ea5..a38066c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,9 +1,12 @@
-gst-libav1.0 (1.0.7-3) UNRELEASED; urgency=low
+gst-libav1.0 (1.1.2-1) experimental; urgency=low
* debian/control,
debian/README.Debian,
debian/watch:
+ Replace all occurences of ffmpeg with libav (Closes: #707216).
+ * New upstream development snapshot:
+ + debian/control:
+ - Build depend on GStreamer and gst-plugins-base >= 1.1.2.
-- Sebastian Dröge <slomo@debian.org> Wed, 08 May 2013 11:55:06 +0200
diff --git a/debian/control b/debian/control
index 7d6f713..0003f95 100644
--- a/debian/control
+++ b/debian/control
@@ -18,8 +18,8 @@ Build-Depends: debhelper (>= 9),
zlib1g-dev,
libglib2.0-dev (>= 2.32),
pkg-config (>= 0.11.0),
- libgstreamer1.0-dev (>= 1.0.0),
- libgstreamer-plugins-base1.0-dev (>= 1.0.0),
+ libgstreamer1.0-dev (>= 1.1.2),
+ libgstreamer-plugins-base1.0-dev (>= 1.1.2),
liborc-0.4-dev (>= 1:0.4.16),
libavcodec-dev (>= 6:9~beta2),
libavformat-dev (>= 6:9~beta2),
diff --git a/debian/patches/03_git-2013-04-26.patch b/debian/patches/03_git-2013-04-26.patch
deleted file mode 100644
index d1c6f1a..0000000
--- a/debian/patches/03_git-2013-04-26.patch
+++ /dev/null
@@ -1,8465 +0,0 @@
-diff --git a/ext/Makefile.am b/ext/Makefile.am
-index bbdb9f0..16718f6 100644
---- a/ext/Makefile.am
-+++ b/ext/Makefile.am
-@@ -1 +1,4 @@
--SUBDIRS = libav libswscale
-+# disable/skip avvideoscale until someone makes it work
-+SUBDIRS = libav
-+
-+DIST_SUBDIRS = libav libswscale
-diff --git a/ext/libav/Makefile.am b/ext/libav/Makefile.am
-index a1e51f4..24d0eb9 100644
---- a/ext/libav/Makefile.am
-+++ b/ext/libav/Makefile.am
-@@ -10,9 +10,9 @@ libgstlibav_la_SOURCES = gstav.c \
- gstavprotocol.c \
- gstavcodecmap.c \
- gstavutils.c \
-- gstavenc.c \
-+ gstavaudenc.c \
- gstavvidenc.c \
-- gstavdec.c \
-+ gstavauddec.c \
- gstavviddec.c \
- gstavcfg.c \
- gstavdemux.c \
-@@ -40,7 +40,9 @@ noinst_HEADERS = \
- gstav.h \
- gstavcodecmap.h \
- gstavutils.h \
-- gstavenc.h \
-+ gstavauddec.h \
-+ gstavviddec.h \
-+ gstavaudenc.h \
- gstavvidenc.h \
- gstavcfg.h \
-- gstavpipe.h
-+ gstavprotocol.h
-diff --git a/ext/libav/gstav.c b/ext/libav/gstav.c
-index 8c88a13..7884a51 100644
---- a/ext/libav/gstav.c
-+++ b/ext/libav/gstav.c
-@@ -13,8 +13,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
- /* First, include the header file for the plugin, to bring in the
-@@ -45,7 +45,7 @@ gst_ffmpeg_avcodec_open (AVCodecContext * avctx, AVCodec * codec)
- int ret;
-
- g_static_mutex_lock (&gst_avcodec_mutex);
-- ret = avcodec_open (avctx, codec);
-+ ret = avcodec_open2 (avctx, codec, NULL);
- g_static_mutex_unlock (&gst_avcodec_mutex);
-
- return ret;
-@@ -69,7 +69,7 @@ gst_ffmpeg_av_find_stream_info (AVFormatContext * ic)
- int ret;
-
- g_static_mutex_lock (&gst_avcodec_mutex);
-- ret = av_find_stream_info (ic);
-+ ret = avformat_find_stream_info (ic, NULL);
- g_static_mutex_unlock (&gst_avcodec_mutex);
-
- return ret;
-@@ -83,9 +83,6 @@ gst_ffmpeg_log_callback (void *ptr, int level, const char *fmt, va_list vl)
- gint len = strlen (fmt);
- gchar *fmt2 = NULL;
-
-- if (_shut_up_I_am_probing)
-- return;
--
- switch (level) {
- case AV_LOG_QUIET:
- gst_level = GST_LEVEL_NONE;
-@@ -117,10 +114,6 @@ gst_ffmpeg_log_callback (void *ptr, int level, const char *fmt, va_list vl)
- }
- #endif
-
--#ifndef GST_DISABLE_GST_DEBUG
--gboolean _shut_up_I_am_probing = FALSE;
--#endif
--
- static gboolean
- plugin_init (GstPlugin * plugin)
- {
-@@ -145,13 +138,9 @@ plugin_init (GstPlugin * plugin)
- gst_ffmpegscale_register (plugin);
- #endif
- #if 0
-- gst_ffmpegcsp_register (plugin);
- gst_ffmpegaudioresample_register (plugin);
- #endif
-
-- av_register_protocol2 (&gstreamer_protocol, sizeof (URLProtocol));
-- av_register_protocol2 (&gstpipe_protocol, sizeof (URLProtocol));
--
- /* Now we can return the pointer to the newly created Plugin object. */
- return TRUE;
- }
-diff --git a/ext/libav/gstav.h b/ext/libav/gstav.h
-index 5cd69a5..82e2972 100644
---- a/ext/libav/gstav.h
-+++ b/ext/libav/gstav.h
-@@ -13,8 +13,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
- /* First, include the header file for the plugin, to bring in the
-@@ -36,21 +36,16 @@ GST_DEBUG_CATEGORY_EXTERN (ffmpeg_debug);
-
- G_BEGIN_DECLS
-
--#ifndef GST_DISABLE_GST_DEBUG
--extern gboolean _shut_up_I_am_probing;
--#endif
--
- extern gboolean gst_ffmpegdemux_register (GstPlugin * plugin);
- extern gboolean gst_ffmpegauddec_register (GstPlugin * plugin);
- extern gboolean gst_ffmpegviddec_register (GstPlugin * plugin);
- extern gboolean gst_ffmpegaudenc_register (GstPlugin * plugin);
- extern gboolean gst_ffmpegvidenc_register (GstPlugin * plugin);
- extern gboolean gst_ffmpegmux_register (GstPlugin * plugin);
--extern gboolean gst_ffmpegcsp_register (GstPlugin * plugin);
- #if 0
- extern gboolean gst_ffmpegscale_register (GstPlugin * plugin);
--#endif
- extern gboolean gst_ffmpegaudioresample_register (GstPlugin * plugin);
-+#endif
- extern gboolean gst_ffmpegdeinterlace_register (GstPlugin * plugin);
-
- int gst_ffmpeg_avcodec_open (AVCodecContext *avctx, AVCodec *codec);
-@@ -59,9 +54,6 @@ int gst_ffmpeg_av_find_stream_info(AVFormatContext *ic);
-
- G_END_DECLS
-
--extern URLProtocol gstreamer_protocol;
--extern URLProtocol gstpipe_protocol;
--
- /* use GST_FFMPEG URL_STREAMHEADER with URL_WRONLY if the first
- * buffer should be used as streamheader property on the pad's caps. */
- #define GST_FFMPEG_URL_STREAMHEADER 16
-diff --git a/ext/libav/gstavauddec.c b/ext/libav/gstavauddec.c
-new file mode 100644
-index 0000000..e6646af
---- /dev/null
-+++ b/ext/libav/gstavauddec.c
-@@ -0,0 +1,893 @@
-+/* GStreamer
-+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
-+ * Copyright (C) <2012> Collabora Ltd.
-+ * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Library General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Library General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Library General Public
-+ * License along with this library; if not, write to the
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+#include "config.h"
-+#endif
-+
-+#include <assert.h>
-+#include <string.h>
-+
-+#include <libavcodec/avcodec.h>
-+
-+#include <gst/gst.h>
-+
-+#include "gstav.h"
-+#include "gstavcodecmap.h"
-+#include "gstavutils.h"
-+#include "gstavauddec.h"
-+
-+GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE);
-+
-+/* A number of function prototypes are given so we can refer to them later. */
-+static void gst_ffmpegauddec_base_init (GstFFMpegAudDecClass * klass);
-+static void gst_ffmpegauddec_class_init (GstFFMpegAudDecClass * klass);
-+static void gst_ffmpegauddec_init (GstFFMpegAudDec * ffmpegdec);
-+static void gst_ffmpegauddec_finalize (GObject * object);
-+
-+static gboolean gst_ffmpegauddec_stop (GstAudioDecoder * decoder);
-+static void gst_ffmpegauddec_flush (GstAudioDecoder * decoder, gboolean hard);
-+static gboolean gst_ffmpegauddec_set_format (GstAudioDecoder * decoder,
-+ GstCaps * caps);
-+static GstFlowReturn gst_ffmpegauddec_handle_frame (GstAudioDecoder * decoder,
-+ GstBuffer * inbuf);
-+
-+static gboolean gst_ffmpegauddec_negotiate (GstFFMpegAudDec * ffmpegdec,
-+ gboolean force);
-+
-+static void gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec);
-+
-+#define GST_FFDEC_PARAMS_QDATA g_quark_from_static_string("avdec-params")
-+
-+static GstElementClass *parent_class = NULL;
-+
-+static void
-+gst_ffmpegauddec_base_init (GstFFMpegAudDecClass * klass)
-+{
-+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-+ GstPadTemplate *sinktempl, *srctempl;
-+ GstCaps *sinkcaps, *srccaps;
-+ AVCodec *in_plugin;
-+ gchar *longname, *description;
-+
-+ in_plugin =
-+ (AVCodec *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
-+ GST_FFDEC_PARAMS_QDATA);
-+ g_assert (in_plugin != NULL);
-+
-+ /* construct the element details struct */
-+ longname = g_strdup_printf ("libav %s decoder", in_plugin->long_name);
-+ description = g_strdup_printf ("libav %s decoder", in_plugin->name);
-+ gst_element_class_set_metadata (element_class, longname,
-+ "Codec/Decoder/Audio", description,
-+ "Wim Taymans <wim.taymans@gmail.com>, "
-+ "Ronald Bultje <rbultje@ronald.bitfreak.net>, "
-+ "Edward Hervey <bilboed@bilboed.com>");
-+ g_free (longname);
-+ g_free (description);
-+
-+ /* get the caps */
-+ sinkcaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, FALSE);
-+ if (!sinkcaps) {
-+ GST_DEBUG ("Couldn't get sink caps for decoder '%s'", in_plugin->name);
-+ sinkcaps = gst_caps_from_string ("unknown/unknown");
-+ }
-+ srccaps = gst_ffmpeg_codectype_to_audio_caps (NULL,
-+ in_plugin->id, FALSE, in_plugin);
-+ if (!srccaps) {
-+ GST_DEBUG ("Couldn't get source caps for decoder '%s'", in_plugin->name);
-+ srccaps = gst_caps_from_string ("audio/x-raw");
-+ }
-+
-+ /* pad templates */
-+ sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
-+ GST_PAD_ALWAYS, sinkcaps);
-+ srctempl = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, srccaps);
-+
-+ gst_element_class_add_pad_template (element_class, srctempl);
-+ gst_element_class_add_pad_template (element_class, sinktempl);
-+
-+ klass->in_plugin = in_plugin;
-+ klass->srctempl = srctempl;
-+ klass->sinktempl = sinktempl;
-+}
-+
-+static void
-+gst_ffmpegauddec_class_init (GstFFMpegAudDecClass * klass)
-+{
-+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-+ GstAudioDecoderClass *gstaudiodecoder_class = GST_AUDIO_DECODER_CLASS (klass);
-+
-+ parent_class = g_type_class_peek_parent (klass);
-+
-+ gobject_class->finalize = gst_ffmpegauddec_finalize;
-+
-+ gstaudiodecoder_class->stop = GST_DEBUG_FUNCPTR (gst_ffmpegauddec_stop);
-+ gstaudiodecoder_class->set_format =
-+ GST_DEBUG_FUNCPTR (gst_ffmpegauddec_set_format);
-+ gstaudiodecoder_class->handle_frame =
-+ GST_DEBUG_FUNCPTR (gst_ffmpegauddec_handle_frame);
-+ gstaudiodecoder_class->flush = GST_DEBUG_FUNCPTR (gst_ffmpegauddec_flush);
-+}
-+
-+static void
-+gst_ffmpegauddec_init (GstFFMpegAudDec * ffmpegdec)
-+{
-+ GstFFMpegAudDecClass *klass =
-+ (GstFFMpegAudDecClass *) G_OBJECT_GET_CLASS (ffmpegdec);
-+
-+ /* some ffmpeg data */
-+ ffmpegdec->context = avcodec_alloc_context3 (klass->in_plugin);
-+ ffmpegdec->opened = FALSE;
-+
-+ gst_audio_decoder_set_drainable (GST_AUDIO_DECODER (ffmpegdec), TRUE);
-+ gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (ffmpegdec), TRUE);
-+}
-+
-+static void
-+gst_ffmpegauddec_finalize (GObject * object)
-+{
-+ GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) object;
-+
-+ if (ffmpegdec->context != NULL)
-+ av_free (ffmpegdec->context);
-+ ffmpegdec->context = NULL;
-+
-+ G_OBJECT_CLASS (parent_class)->finalize (object);
-+}
-+
-+/* With LOCK */
-+static void
-+gst_ffmpegauddec_close (GstFFMpegAudDec * ffmpegdec)
-+{
-+ GST_LOG_OBJECT (ffmpegdec, "closing libav codec");
-+
-+ gst_caps_replace (&ffmpegdec->last_caps, NULL);
-+ gst_buffer_replace (&ffmpegdec->outbuf, NULL);
-+
-+ gst_ffmpeg_avcodec_close (ffmpegdec->context);
-+ ffmpegdec->opened = FALSE;
-+
-+ if (ffmpegdec->context->extradata) {
-+ av_free (ffmpegdec->context->extradata);
-+ ffmpegdec->context->extradata = NULL;
-+ }
-+}
-+
-+static gboolean
-+gst_ffmpegauddec_stop (GstAudioDecoder * decoder)
-+{
-+ GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) decoder;
-+
-+ GST_OBJECT_LOCK (ffmpegdec);
-+ gst_ffmpegauddec_close (ffmpegdec);
-+ GST_OBJECT_UNLOCK (ffmpegdec);
-+ gst_audio_info_init (&ffmpegdec->info);
-+ gst_caps_replace (&ffmpegdec->last_caps, NULL);
-+
-+ return TRUE;
-+}
-+
-+/* with LOCK */
-+static gboolean
-+gst_ffmpegauddec_open (GstFFMpegAudDec * ffmpegdec)
-+{
-+ GstFFMpegAudDecClass *oclass;
-+
-+ oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
-+
-+ if (gst_ffmpeg_avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0)
-+ goto could_not_open;
-+
-+ ffmpegdec->opened = TRUE;
-+
-+ GST_LOG_OBJECT (ffmpegdec, "Opened libav codec %s, id %d",
-+ oclass->in_plugin->name, oclass->in_plugin->id);
-+
-+ gst_audio_info_init (&ffmpegdec->info);
-+
-+ return TRUE;
-+
-+ /* ERRORS */
-+could_not_open:
-+ {
-+ gst_ffmpegauddec_close (ffmpegdec);
-+ GST_DEBUG_OBJECT (ffmpegdec, "avdec_%s: Failed to open libav codec",
-+ oclass->in_plugin->name);
-+ return FALSE;
-+ }
-+}
-+
-+typedef struct
-+{
-+ GstBuffer *buffer;
-+ GstMapInfo map;
-+} BufferInfo;
-+
-+/* called when ffmpeg wants us to allocate a buffer to write the decoded frame
-+ * into. We try to give it memory from our pool */
-+static int
-+gst_ffmpegauddec_get_buffer (AVCodecContext * context, AVFrame * frame)
-+{
-+ GstFFMpegAudDec *ffmpegdec;
-+ GstAudioInfo *info;
-+ BufferInfo *buffer_info;
-+
-+ ffmpegdec = (GstFFMpegAudDec *) context->opaque;
-+ if (G_UNLIKELY (!gst_ffmpegauddec_negotiate (ffmpegdec, FALSE)))
-+ goto negotiate_failed;
-+
-+ /* Always use the default allocator for planar audio formats because
-+ * we will have to copy and deinterleave later anyway */
-+ if (av_sample_fmt_is_planar (ffmpegdec->context->sample_fmt))
-+ goto fallback;
-+
-+ info = gst_audio_decoder_get_audio_info (GST_AUDIO_DECODER (ffmpegdec));
-+
-+ buffer_info = g_slice_new (BufferInfo);
-+ buffer_info->buffer =
-+ gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER (ffmpegdec),
-+ frame->nb_samples * info->bpf);
-+ gst_buffer_map (buffer_info->buffer, &buffer_info->map, GST_MAP_WRITE);
-+ frame->opaque = buffer_info;
-+ frame->data[0] = buffer_info->map.data;
-+ frame->extended_data = frame->data;
-+ frame->linesize[0] = buffer_info->map.size;
-+ frame->type = FF_BUFFER_TYPE_USER;
-+
-+ return 0;
-+ /* fallbacks */
-+negotiate_failed:
-+ {
-+ GST_DEBUG_OBJECT (ffmpegdec, "negotiate failed");
-+ goto fallback;
-+ }
-+fallback:
-+ {
-+ return avcodec_default_get_buffer (context, frame);
-+ }
-+}
-+
-+static gboolean
-+gst_ffmpegauddec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
-+{
-+ GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) decoder;
-+ GstFFMpegAudDecClass *oclass;
-+ gboolean ret = TRUE;
-+
-+ oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
-+
-+ GST_DEBUG_OBJECT (ffmpegdec, "setcaps called");
-+
-+ GST_OBJECT_LOCK (ffmpegdec);
-+
-+ if (ffmpegdec->last_caps && gst_caps_is_equal (ffmpegdec->last_caps, caps)) {
-+ GST_DEBUG_OBJECT (ffmpegdec, "same caps");
-+ GST_OBJECT_UNLOCK (ffmpegdec);
-+ return TRUE;
-+ }
-+
-+ gst_caps_replace (&ffmpegdec->last_caps, caps);
-+
-+ /* close old session */
-+ if (ffmpegdec->opened) {
-+ GST_OBJECT_UNLOCK (ffmpegdec);
-+ gst_ffmpegauddec_drain (ffmpegdec);
-+ GST_OBJECT_LOCK (ffmpegdec);
-+ gst_ffmpegauddec_close (ffmpegdec);
-+ }
-+
-+ /* get size and so */
-+ gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
-+ oclass->in_plugin->type, caps, ffmpegdec->context);
-+
-+ /* workaround encoder bugs */
-+ ffmpegdec->context->workaround_bugs |= FF_BUG_AUTODETECT;
-+ ffmpegdec->context->err_recognition = 1;
-+
-+ ffmpegdec->context->opaque = ffmpegdec;
-+ ffmpegdec->context->get_buffer = gst_ffmpegauddec_get_buffer;
-+ ffmpegdec->context->reget_buffer = NULL;
-+ ffmpegdec->context->release_buffer = NULL;
-+
-+ /* open codec - we don't select an output pix_fmt yet,
-+ * simply because we don't know! We only get it
-+ * during playback... */
-+ if (!gst_ffmpegauddec_open (ffmpegdec))
-+ goto open_failed;
-+
-+done:
-+ GST_OBJECT_UNLOCK (ffmpegdec);
-+
-+ return ret;
-+
-+ /* ERRORS */
-+open_failed:
-+ {
-+ GST_DEBUG_OBJECT (ffmpegdec, "Failed to open");
-+ ret = FALSE;
-+ goto done;
-+ }
-+}
-+
-+static gboolean
-+gst_ffmpegauddec_negotiate (GstFFMpegAudDec * ffmpegdec, gboolean force)
-+{
-+ GstFFMpegAudDecClass *oclass;
-+ gint depth;
-+ GstAudioFormat format;
-+ GstAudioChannelPosition pos[64] = { 0, };
-+
-+ oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
-+
-+ depth = av_smp_format_depth (ffmpegdec->context->sample_fmt) * 8;
-+ format = gst_ffmpeg_smpfmt_to_audioformat (ffmpegdec->context->sample_fmt);
-+ if (format == GST_AUDIO_FORMAT_UNKNOWN)
-+ goto no_caps;
-+
-+ if (!force && ffmpegdec->info.rate ==
-+ ffmpegdec->context->sample_rate &&
-+ ffmpegdec->info.channels == ffmpegdec->context->channels &&
-+ ffmpegdec->info.finfo->depth == depth)
-+ return TRUE;
-+
-+ GST_DEBUG_OBJECT (ffmpegdec,
-+ "Renegotiating audio from %dHz@%dchannels (%d) to %dHz@%dchannels (%d)",
-+ ffmpegdec->info.rate, ffmpegdec->info.channels,
-+ ffmpegdec->info.finfo->depth,
-+ ffmpegdec->context->sample_rate, ffmpegdec->context->channels, depth);
-+
-+ gst_ffmpeg_channel_layout_to_gst (ffmpegdec->context->channel_layout,
-+ ffmpegdec->context->channels, pos);
-+ memcpy (ffmpegdec->ffmpeg_layout, pos,
-+ sizeof (GstAudioChannelPosition) * ffmpegdec->context->channels);
-+
-+ /* Get GStreamer channel layout */
-+ gst_audio_channel_positions_to_valid_order (pos,
-+ ffmpegdec->context->channels);
-+ ffmpegdec->needs_reorder =
-+ memcmp (pos, ffmpegdec->ffmpeg_layout,
-+ sizeof (pos[0]) * ffmpegdec->context->channels) != 0;
-+ gst_audio_info_set_format (&ffmpegdec->info, format,
-+ ffmpegdec->context->sample_rate, ffmpegdec->context->channels, pos);
-+
-+ if (!gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (ffmpegdec),
-+ &ffmpegdec->info))
-+ goto caps_failed;
-+
-+ return TRUE;
-+
-+ /* ERRORS */
-+no_caps:
-+ {
-+#ifdef HAVE_LIBAV_UNINSTALLED
-+ /* using internal ffmpeg snapshot */
-+ GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION,
-+ ("Could not find GStreamer caps mapping for libav codec '%s'.",
-+ oclass->in_plugin->name), (NULL));
-+#else
-+ /* using external ffmpeg */
-+ GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION,
-+ ("Could not find GStreamer caps mapping for libav codec '%s', and "
-+ "you are using an external libavcodec. This is most likely due to "
-+ "a packaging problem and/or libavcodec having been upgraded to a "
-+ "version that is not compatible with this version of "
-+ "gstreamer-libav. Make sure your gstreamer-libav and libavcodec "
-+ "packages come from the same source/repository.",
-+ oclass->in_plugin->name), (NULL));
-+#endif
-+ return FALSE;
-+ }
-+caps_failed:
-+ {
-+ GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
-+ ("Could not set caps for libav decoder (%s), not fixed?",
-+ oclass->in_plugin->name));
-+
-+ return FALSE;
-+ }
-+}
-+
-+static void
-+gst_avpacket_init (AVPacket * packet, guint8 * data, guint size)
-+{
-+ memset (packet, 0, sizeof (AVPacket));
-+ packet->data = data;
-+ packet->size = size;
-+}
-+
-+static gint
-+gst_ffmpegauddec_audio_frame (GstFFMpegAudDec * ffmpegdec,
-+ AVCodec * in_plugin, guint8 * data, guint size,
-+ GstBuffer ** outbuf, GstFlowReturn * ret)
-+{
-+ gint len = -1;
-+ gint have_data = AVCODEC_MAX_AUDIO_FRAME_SIZE;
-+ AVPacket packet;
-+ AVFrame frame;
-+
-+ GST_DEBUG_OBJECT (ffmpegdec, "size: %d", size);
-+
-+ gst_avpacket_init (&packet, data, size);
-+ memset (&frame, 0, sizeof (frame));
-+ avcodec_get_frame_defaults (&frame);
-+ len = avcodec_decode_audio4 (ffmpegdec->context, &frame, &have_data, &packet);
-+
-+ GST_DEBUG_OBJECT (ffmpegdec,
-+ "Decode audio: len=%d, have_data=%d", len, have_data);
-+
-+ if (len >= 0 && have_data > 0) {
-+ BufferInfo *buffer_info = frame.opaque;
-+ gint nsamples, channels, byte_per_sample;
-+ gsize output_size;
-+
-+ if (!gst_ffmpegauddec_negotiate (ffmpegdec, FALSE)) {
-+ *outbuf = NULL;
-+ *ret = GST_FLOW_NOT_NEGOTIATED;
-+ len = -1;
-+ goto beach;
-+ }
-+
-+ channels = ffmpegdec->info.channels;
-+ nsamples = frame.nb_samples;
-+ byte_per_sample = ffmpegdec->info.finfo->width / 8;
-+
-+ /* frame.linesize[0] might contain padding, allocate only what's needed */
-+ output_size = nsamples * byte_per_sample * channels;
-+
-+ GST_DEBUG_OBJECT (ffmpegdec, "Creating output buffer");
-+ if (buffer_info) {
-+ *outbuf = buffer_info->buffer;
-+ gst_buffer_unmap (buffer_info->buffer, &buffer_info->map);
-+ g_slice_free (BufferInfo, buffer_info);
-+ frame.opaque = NULL;
-+ } else if (av_sample_fmt_is_planar (ffmpegdec->context->sample_fmt)
-+ && channels > 1) {
-+ gint i, j;
-+ GstMapInfo minfo;
-+
-+ /* note: linesize[0] might contain padding, allocate only what's needed */
-+ *outbuf =
-+ gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER
-+ (ffmpegdec), output_size);
-+
-+ gst_buffer_map (*outbuf, &minfo, GST_MAP_WRITE);
-+
-+ switch (ffmpegdec->info.finfo->width) {
-+ case 8:{
-+ guint8 *odata = minfo.data;
-+
-+ for (i = 0; i < nsamples; i++) {
-+ for (j = 0; j < channels; j++) {
-+ odata[j] = ((const guint8 *) frame.extended_data[j])[i];
-+ }
-+ odata += channels;
-+ }
-+ break;
-+ }
-+ case 16:{
-+ guint16 *odata = (guint16 *) minfo.data;
-+
-+ for (i = 0; i < nsamples; i++) {
-+ for (j = 0; j < channels; j++) {
-+ odata[j] = ((const guint16 *) frame.extended_data[j])[i];
-+ }
-+ odata += channels;
-+ }
-+ break;
-+ }
-+ case 32:{
-+ guint32 *odata = (guint32 *) minfo.data;
-+
-+ for (i = 0; i < nsamples; i++) {
-+ for (j = 0; j < channels; j++) {
-+ odata[j] = ((const guint32 *) frame.extended_data[j])[i];
-+ }
-+ odata += channels;
-+ }
-+ break;
-+ }
-+ case 64:{
-+ guint64 *odata = (guint64 *) minfo.data;
-+
-+ for (i = 0; i < nsamples; i++) {
-+ for (j = 0; j < channels; j++) {
-+ odata[j] = ((const guint64 *) frame.extended_data[j])[i];
-+ }
-+ odata += channels;
-+ }
-+ break;
-+ }
-+ default:
-+ g_assert_not_reached ();
-+ break;
-+ }
-+ gst_buffer_unmap (*outbuf, &minfo);
-+ } else {
-+ *outbuf =
-+ gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER
-+ (ffmpegdec), output_size);
-+ gst_buffer_fill (*outbuf, 0, frame.data[0], output_size);
-+ }
-+
-+ GST_DEBUG_OBJECT (ffmpegdec, "Buffer created. Size: %d", have_data);
-+
-+ /* Reorder channels to the GStreamer channel order */
-+ if (ffmpegdec->needs_reorder) {
-+ *outbuf = gst_buffer_make_writable (*outbuf);
-+ gst_audio_buffer_reorder_channels (*outbuf, ffmpegdec->info.finfo->format,
-+ ffmpegdec->info.channels, ffmpegdec->ffmpeg_layout,
-+ ffmpegdec->info.position);
-+ }
-+ } else {
-+ *outbuf = NULL;
-+ }
-+
-+beach:
-+ GST_DEBUG_OBJECT (ffmpegdec, "return flow %d, out %p, len %d",
-+ *ret, *outbuf, len);
-+ return len;
-+}
-+
-+/* gst_ffmpegauddec_frame:
-+ * ffmpegdec:
-+ * data: pointer to the data to decode
-+ * size: size of data in bytes
-+ * got_data: 0 if no data was decoded, != 0 otherwise.
-+ * in_time: timestamp of data
-+ * in_duration: duration of data
-+ * ret: GstFlowReturn to return in the chain function
-+ *
-+ * Decode the given frame and pushes it downstream.
-+ *
-+ * Returns: Number of bytes used in decoding, -1 on error/failure.
-+ */
-+
-+static gint
-+gst_ffmpegauddec_frame (GstFFMpegAudDec * ffmpegdec,
-+ guint8 * data, guint size, gint * got_data, GstFlowReturn * ret)
-+{
-+ GstFFMpegAudDecClass *oclass;
-+ GstBuffer *outbuf = NULL;
-+ gint have_data = 0, len = 0;
-+
-+ if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
-+ goto no_codec;
-+
-+ GST_LOG_OBJECT (ffmpegdec, "data:%p, size:%d", data, size);
-+
-+ *ret = GST_FLOW_OK;
-+ ffmpegdec->context->frame_number++;
-+
-+ oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
-+
-+ len =
-+ gst_ffmpegauddec_audio_frame (ffmpegdec, oclass->in_plugin, data, size,
-+ &outbuf, ret);
-+
-+ if (outbuf)
-+ have_data = 1;
-+
-+ if (len < 0 || have_data < 0) {
-+ GST_WARNING_OBJECT (ffmpegdec,
-+ "avdec_%s: decoding error (len: %d, have_data: %d)",
-+ oclass->in_plugin->name, len, have_data);
-+ *got_data = 0;
-+ goto beach;
-+ } else if (len == 0 && have_data == 0) {
-+ *got_data = 0;
-+ goto beach;
-+ } else {
-+ /* this is where I lost my last clue on ffmpeg... */
-+ *got_data = 1;
-+ }
-+
-+ if (outbuf) {
-+ GST_LOG_OBJECT (ffmpegdec, "Decoded data, now storing buffer %p", outbuf);
-+
-+ if (ffmpegdec->outbuf)
-+ ffmpegdec->outbuf = gst_buffer_append (ffmpegdec->outbuf, outbuf);
-+ else
-+ ffmpegdec->outbuf = outbuf;
-+ } else {
-+ GST_DEBUG_OBJECT (ffmpegdec, "We didn't get a decoded buffer");
-+ }
-+
-+beach:
-+ return len;
-+
-+ /* ERRORS */
-+no_codec:
-+ {
-+ GST_ERROR_OBJECT (ffmpegdec, "no codec context");
-+ return -1;
-+ }
-+}
-+
-+static void
-+gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec)
-+{
-+ GstFFMpegAudDecClass *oclass;
-+
-+ oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
-+
-+ if (oclass->in_plugin->capabilities & CODEC_CAP_DELAY) {
-+ gint have_data, len, try = 0;
-+
-+ GST_LOG_OBJECT (ffmpegdec,
-+ "codec has delay capabilities, calling until libav has drained everything");
-+
-+ do {
-+ GstFlowReturn ret;
-+
-+ len = gst_ffmpegauddec_frame (ffmpegdec, NULL, 0, &have_data, &ret);
-+ if (len < 0 || have_data == 0)
-+ break;
-+ } while (try++ < 10);
-+ }
-+
-+ if (ffmpegdec->outbuf)
-+ gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (ffmpegdec),
-+ ffmpegdec->outbuf, 1);
-+ ffmpegdec->outbuf = NULL;
-+}
-+
-+static void
-+gst_ffmpegauddec_flush (GstAudioDecoder * decoder, gboolean hard)
-+{
-+ GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) decoder;
-+
-+ if (ffmpegdec->opened) {
-+ avcodec_flush_buffers (ffmpegdec->context);
-+ }
-+}
-+
-+static GstFlowReturn
-+gst_ffmpegauddec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
-+{
-+ GstFFMpegAudDec *ffmpegdec;
-+ GstFFMpegAudDecClass *oclass;
-+ guint8 *data, *bdata;
-+ GstMapInfo map;
-+ gint size, bsize, len, have_data;
-+ GstFlowReturn ret = GST_FLOW_OK;
-+
-+ ffmpegdec = (GstFFMpegAudDec *) decoder;
-+
-+ if (G_UNLIKELY (!ffmpegdec->opened))
-+ goto not_negotiated;
-+
-+ if (inbuf == NULL) {
-+ gst_ffmpegauddec_drain (ffmpegdec);
-+ return GST_FLOW_OK;
-+ }
-+
-+ inbuf = gst_buffer_ref (inbuf);
-+
-+ oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
-+
-+ GST_LOG_OBJECT (ffmpegdec,
-+ "Received new data of size %" G_GSIZE_FORMAT ", offset:%" G_GUINT64_FORMAT
-+ ", ts:%" GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT,
-+ gst_buffer_get_size (inbuf), GST_BUFFER_OFFSET (inbuf),
-+ GST_TIME_ARGS (GST_BUFFER_PTS (inbuf)),
-+ GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)));
-+
-+ /* workarounds, functions write to buffers:
-+ * libavcodec/svq1.c:svq1_decode_frame writes to the given buffer.
-+ * libavcodec/svq3.c:svq3_decode_slice_header too.
-+ * ffmpeg devs know about it and will fix it (they said). */
-+ if (oclass->in_plugin->id == CODEC_ID_SVQ1 ||
-+ oclass->in_plugin->id == CODEC_ID_SVQ3) {
-+ inbuf = gst_buffer_make_writable (inbuf);
-+ }
-+
-+ gst_buffer_map (inbuf, &map, GST_MAP_READ);
-+
-+ bdata = map.data;
-+ bsize = map.size;
-+
-+ do {
-+ data = bdata;
-+ size = bsize;
-+
-+ /* decode a frame of audio now */
-+ len = gst_ffmpegauddec_frame (ffmpegdec, data, size, &have_data, &ret);
-+
-+ if (ret != GST_FLOW_OK) {
-+ GST_LOG_OBJECT (ffmpegdec, "breaking because of flow ret %s",
-+ gst_flow_get_name (ret));
-+ /* bad flow return, make sure we discard all data and exit */
-+ bsize = 0;
-+ break;
-+ }
-+
-+ if (len == 0 && !have_data) {
-+ /* nothing was decoded, this could be because no data was available or
-+ * because we were skipping frames.
-+ * If we have no context we must exit and wait for more data, we keep the
-+ * data we tried. */
-+ GST_LOG_OBJECT (ffmpegdec, "Decoding didn't return any data, breaking");
-+ break;
-+ } else if (len < 0) {
-+ /* a decoding error happened, we must break and try again with next data. */
-+ GST_LOG_OBJECT (ffmpegdec, "Decoding error, breaking");
-+ bsize = 0;
-+ break;
-+ }
-+ /* prepare for the next round, for codecs with a context we did this
-+ * already when using the parser. */
-+ bsize -= len;
-+ bdata += len;
-+
-+ GST_LOG_OBJECT (ffmpegdec, "Before (while bsize>0). bsize:%d , bdata:%p",
-+ bsize, bdata);
-+ } while (bsize > 0);
-+
-+ gst_buffer_unmap (inbuf, &map);
-+ gst_buffer_unref (inbuf);
-+
-+ if (ffmpegdec->outbuf)
-+ ret =
-+ gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (ffmpegdec),
-+ ffmpegdec->outbuf, 1);
-+ ffmpegdec->outbuf = NULL;
-+
-+ if (bsize > 0) {
-+ GST_DEBUG_OBJECT (ffmpegdec, "Dropping %d bytes of data", bsize);
-+ }
-+
-+ return ret;
-+
-+ /* ERRORS */
-+not_negotiated:
-+ {
-+ oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
-+ GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
-+ ("avdec_%s: input format was not set before data start",
-+ oclass->in_plugin->name));
-+ return GST_FLOW_NOT_NEGOTIATED;
-+ }
-+}
-+
-+gboolean
-+gst_ffmpegauddec_register (GstPlugin * plugin)
-+{
-+ GTypeInfo typeinfo = {
-+ sizeof (GstFFMpegAudDecClass),
-+ (GBaseInitFunc) gst_ffmpegauddec_base_init,
-+ NULL,
-+ (GClassInitFunc) gst_ffmpegauddec_class_init,
-+ NULL,
-+ NULL,
-+ sizeof (GstFFMpegAudDec),
-+ 0,
-+ (GInstanceInitFunc) gst_ffmpegauddec_init,
-+ };
-+ GType type;
-+ AVCodec *in_plugin;
-+ gint rank;
-+
-+ in_plugin = av_codec_next (NULL);
-+
-+ GST_LOG ("Registering decoders");
-+
-+ while (in_plugin) {
-+ gchar *type_name;
-+ gchar *plugin_name;
-+
-+ /* only decoders */
-+ if (!av_codec_is_decoder (in_plugin)
-+ || in_plugin->type != AVMEDIA_TYPE_AUDIO) {
-+ goto next;
-+ }
-+
-+ /* no quasi-codecs, please */
-+ if (in_plugin->id >= CODEC_ID_PCM_S16LE &&
-+ in_plugin->id <= CODEC_ID_PCM_BLURAY) {
-+ goto next;
-+ }
-+
-+ /* No decoders depending on external libraries (we don't build them, but
-+ * people who build against an external ffmpeg might have them.
-+ * We have native gstreamer plugins for all of those libraries anyway. */
-+ if (!strncmp (in_plugin->name, "lib", 3)) {
-+ GST_DEBUG
-+ ("Not using external library decoder %s. Use the gstreamer-native ones instead.",
-+ in_plugin->name);
-+ goto next;
-+ }
-+
-+ GST_DEBUG ("Trying plugin %s [%s]", in_plugin->name, in_plugin->long_name);
-+
-+ /* no codecs for which we're GUARANTEED to have better alternatives */
-+ /* MP1 : Use MP3 for decoding */
-+ /* MP2 : Use MP3 for decoding */
-+ /* Theora: Use libtheora based theoradec */
-+ if (!strcmp (in_plugin->name, "vorbis") ||
-+ !strcmp (in_plugin->name, "wavpack") ||
-+ !strcmp (in_plugin->name, "mp1") ||
-+ !strcmp (in_plugin->name, "mp2") ||
-+ !strcmp (in_plugin->name, "libfaad") ||
-+ !strcmp (in_plugin->name, "mpeg4aac") ||
-+ !strcmp (in_plugin->name, "ass") ||
-+ !strcmp (in_plugin->name, "srt") ||
-+ !strcmp (in_plugin->name, "pgssub") ||
-+ !strcmp (in_plugin->name, "dvdsub") ||
-+ !strcmp (in_plugin->name, "dvbsub")) {
-+ GST_LOG ("Ignoring decoder %s", in_plugin->name);
-+ goto next;
-+ }
-+
-+ /* construct the type */
-+ plugin_name = g_strdup ((gchar *) in_plugin->name);
-+ g_strdelimit (plugin_name, NULL, '_');
-+ type_name = g_strdup_printf ("avdec_%s", plugin_name);
-+ g_free (plugin_name);
-+
-+ type = g_type_from_name (type_name);
-+
-+ if (!type) {
-+ /* create the gtype now */
-+ type =
-+ g_type_register_static (GST_TYPE_AUDIO_DECODER, type_name, &typeinfo,
-+ 0);
-+ g_type_set_qdata (type, GST_FFDEC_PARAMS_QDATA, (gpointer) in_plugin);
-+ }
-+
-+ /* (Ronald) MPEG-4 gets a higher priority because it has been well-
-+ * tested and by far outperforms divxdec/xviddec - so we prefer it.
-+ * msmpeg4v3 same, as it outperforms divxdec for divx3 playback.
-+ * VC1/WMV3 are not working and thus unpreferred for now. */
-+ switch (in_plugin->id) {
-+ case CODEC_ID_RA_144:
-+ case CODEC_ID_RA_288:
-+ case CODEC_ID_COOK:
-+ rank = GST_RANK_PRIMARY;
-+ break;
-+ /* SIPR: decoder should have a higher rank than realaudiodec.
-+ */
-+ case CODEC_ID_SIPR:
-+ rank = GST_RANK_SECONDARY;
-+ break;
-+ case CODEC_ID_MP3:
-+ rank = GST_RANK_NONE;
-+ break;
-+ default:
-+ rank = GST_RANK_MARGINAL;
-+ break;
-+ }
-+ if (!gst_element_register (plugin, type_name, rank, type)) {
-+ g_warning ("Failed to register %s", type_name);
-+ g_free (type_name);
-+ return FALSE;
-+ }
-+
-+ g_free (type_name);
-+
-+ next:
-+ in_plugin = av_codec_next (in_plugin);
-+ }
-+
-+ GST_LOG ("Finished Registering decoders");
-+
-+ return TRUE;
-+}
-diff --git a/ext/libav/gstavauddec.h b/ext/libav/gstavauddec.h
-new file mode 100644
-index 0000000..23d11fd
---- /dev/null
-+++ b/ext/libav/gstavauddec.h
-@@ -0,0 +1,73 @@
-+/* 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., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
-+ */
-+#ifndef __GST_FFMPEGAUDDEC_H__
-+#define __GST_FFMPEGAUDDEC_H__
-+
-+G_BEGIN_DECLS
-+
-+#include <gst/gst.h>
-+#include <gst/audio/audio.h>
-+#include <gst/audio/gstaudiodecoder.h>
-+#include <libavcodec/avcodec.h>
-+
-+typedef struct _GstFFMpegAudDec GstFFMpegAudDec;
-+struct _GstFFMpegAudDec
-+{
-+ GstAudioDecoder parent;
-+
-+ /* decoding */
-+ AVCodecContext *context;
-+ gboolean opened;
-+
-+ /* prevent reopening the decoder on GST_EVENT_CAPS when caps are same as last time. */
-+ GstCaps *last_caps;
-+
-+ /* Stores current buffers to push as GstAudioDecoder wants 1:1 mapping for input/output buffers */
-+ GstBuffer *outbuf;
-+
-+ /* current output format */
-+ GstAudioInfo info;
-+ GstAudioChannelPosition ffmpeg_layout[64];
-+ gboolean needs_reorder;
-+};
-+
-+typedef struct _GstFFMpegAudDecClass GstFFMpegAudDecClass;
-+
-+struct _GstFFMpegAudDecClass
-+{
-+ GstAudioDecoderClass parent_class;
-+
-+ AVCodec *in_plugin;
-+ GstPadTemplate *srctempl, *sinktempl;
-+};
-+
-+#define GST_TYPE_FFMPEGDEC \
-+ (gst_ffmpegauddec_get_type())
-+#define GST_FFMPEGDEC(obj) \
-+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGDEC,GstFFMpegAudDec))
-+#define GST_FFMPEGAUDDEC_CLASS(klass) \
-+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGDEC,GstFFMpegAudDecClass))
-+#define GST_IS_FFMPEGDEC(obj) \
-+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGDEC))
-+#define GST_IS_FFMPEGAUDDEC_CLASS(klass) \
-+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGDEC))
-+
-+G_END_DECLS
-+
-+#endif
-diff --git a/ext/libav/gstavaudenc.c b/ext/libav/gstavaudenc.c
-new file mode 100644
-index 0000000..2db08bb
---- /dev/null
-+++ b/ext/libav/gstavaudenc.c
-@@ -0,0 +1,752 @@
-+/* GStreamer
-+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
-+ * Copyright (C) <2012> Collabora Ltd.
-+ * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Library General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Library General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Library General Public
-+ * License along with this library; if not, write to the
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+#include "config.h"
-+#endif
-+
-+#include <assert.h>
-+#include <string.h>
-+/* for stats file handling */
-+#include <stdio.h>
-+#include <glib/gstdio.h>
-+#include <errno.h>
-+
-+#include <libavcodec/avcodec.h>
-+
-+#include <gst/gst.h>
-+
-+#include "gstav.h"
-+#include "gstavcodecmap.h"
-+#include "gstavutils.h"
-+#include "gstavaudenc.h"
-+
-+#define DEFAULT_AUDIO_BITRATE 128000
-+
-+enum
-+{
-+ /* FILL ME */
-+ LAST_SIGNAL
-+};
-+
-+enum
-+{
-+ PROP_0,
-+ PROP_BIT_RATE,
-+ PROP_RTP_PAYLOAD_SIZE,
-+};
-+
-+/* A number of function prototypes are given so we can refer to them later. */
-+static void gst_ffmpegaudenc_class_init (GstFFMpegAudEncClass * klass);
-+static void gst_ffmpegaudenc_base_init (GstFFMpegAudEncClass * klass);
-+static void gst_ffmpegaudenc_init (GstFFMpegAudEnc * ffmpegaudenc);
-+static void gst_ffmpegaudenc_finalize (GObject * object);
-+
-+static GstCaps *gst_ffmpegaudenc_getcaps (GstAudioEncoder * encoder,
-+ GstCaps * filter);
-+static gboolean gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder,
-+ GstAudioInfo * info);
-+static GstFlowReturn gst_ffmpegaudenc_handle_frame (GstAudioEncoder * encoder,
-+ GstBuffer * inbuf);
-+static gboolean gst_ffmpegaudenc_stop (GstAudioEncoder * encoder);
-+static void gst_ffmpegaudenc_flush (GstAudioEncoder * encoder);
-+
-+static void gst_ffmpegaudenc_set_property (GObject * object,
-+ guint prop_id, const GValue * value, GParamSpec * pspec);
-+static void gst_ffmpegaudenc_get_property (GObject * object,
-+ guint prop_id, GValue * value, GParamSpec * pspec);
-+
-+#define GST_FFENC_PARAMS_QDATA g_quark_from_static_string("avenc-params")
-+
-+static GstElementClass *parent_class = NULL;
-+
-+/*static guint gst_ffmpegaudenc_signals[LAST_SIGNAL] = { 0 }; */
-+
-+static void
-+gst_ffmpegaudenc_base_init (GstFFMpegAudEncClass * klass)
-+{
-+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-+ AVCodec *in_plugin;
-+ GstPadTemplate *srctempl = NULL, *sinktempl = NULL;
-+ GstCaps *srccaps = NULL, *sinkcaps = NULL;
-+ gchar *longname, *description;
-+
-+ in_plugin =
-+ (AVCodec *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
-+ GST_FFENC_PARAMS_QDATA);
-+ g_assert (in_plugin != NULL);
-+
-+ /* construct the element details struct */
-+ longname = g_strdup_printf ("libav %s encoder", in_plugin->long_name);
-+ description = g_strdup_printf ("libav %s encoder", in_plugin->name);
-+ gst_element_class_set_metadata (element_class, longname,
-+ "Codec/Encoder/Audio", description,
-+ "Wim Taymans <wim.taymans@gmail.com>, "
-+ "Ronald Bultje <rbultje@ronald.bitfreak.net>");
-+ g_free (longname);
-+ g_free (description);
-+
-+ if (!(srccaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, TRUE))) {
-+ GST_DEBUG ("Couldn't get source caps for encoder '%s'", in_plugin->name);
-+ srccaps = gst_caps_new_empty_simple ("unknown/unknown");
-+ }
-+
-+ sinkcaps = gst_ffmpeg_codectype_to_audio_caps (NULL,
-+ in_plugin->id, TRUE, in_plugin);
-+ if (!sinkcaps) {
-+ GST_DEBUG ("Couldn't get sink caps for encoder '%s'", in_plugin->name);
-+ sinkcaps = gst_caps_new_empty_simple ("unknown/unknown");
-+ }
-+
-+ /* pad templates */
-+ sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
-+ GST_PAD_ALWAYS, sinkcaps);
-+ srctempl = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, srccaps);
-+
-+ gst_element_class_add_pad_template (element_class, srctempl);
-+ gst_element_class_add_pad_template (element_class, sinktempl);
-+
-+ klass->in_plugin = in_plugin;
-+ klass->srctempl = srctempl;
-+ klass->sinktempl = sinktempl;
-+
-+ return;
-+}
-+
-+static void
-+gst_ffmpegaudenc_class_init (GstFFMpegAudEncClass * klass)
-+{
-+ GObjectClass *gobject_class;
-+ GstAudioEncoderClass *gstaudioencoder_class;
-+
-+ gobject_class = (GObjectClass *) klass;
-+ gstaudioencoder_class = (GstAudioEncoderClass *) klass;
-+
-+ parent_class = g_type_class_peek_parent (klass);
-+
-+ gobject_class->set_property = gst_ffmpegaudenc_set_property;
-+ gobject_class->get_property = gst_ffmpegaudenc_get_property;
-+
-+ /* FIXME: could use -1 for a sensible per-codec defaults */
-+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BIT_RATE,
-+ g_param_spec_int ("bitrate", "Bit Rate",
-+ "Target Audio Bitrate", 0, G_MAXINT, DEFAULT_AUDIO_BITRATE,
-+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-+
-+ gobject_class->finalize = gst_ffmpegaudenc_finalize;
-+
-+ gstaudioencoder_class->stop = GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_stop);
-+ gstaudioencoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_getcaps);
-+ gstaudioencoder_class->flush = GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_flush);
-+ gstaudioencoder_class->set_format =
-+ GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_set_format);
-+ gstaudioencoder_class->handle_frame =
-+ GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_handle_frame);
-+}
-+
-+static void
-+gst_ffmpegaudenc_init (GstFFMpegAudEnc * ffmpegaudenc)
-+{
-+ GstFFMpegAudEncClass *klass =
-+ (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
-+
-+ /* ffmpeg objects */
-+ ffmpegaudenc->context = avcodec_alloc_context3 (klass->in_plugin);
-+ ffmpegaudenc->opened = FALSE;
-+
-+ gst_audio_encoder_set_drainable (GST_AUDIO_ENCODER (ffmpegaudenc), TRUE);
-+}
-+
-+static void
-+gst_ffmpegaudenc_finalize (GObject * object)
-+{
-+ GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) object;
-+
-+ /* clean up remaining allocated data */
-+ av_free (ffmpegaudenc->context);
-+
-+ G_OBJECT_CLASS (parent_class)->finalize (object);
-+}
-+
-+static gboolean
-+gst_ffmpegaudenc_stop (GstAudioEncoder * encoder)
-+{
-+ GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
-+
-+ /* close old session */
-+ gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
-+ ffmpegaudenc->opened = FALSE;
-+
-+ return TRUE;
-+}
-+
-+static void
-+gst_ffmpegaudenc_flush (GstAudioEncoder * encoder)
-+{
-+ GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
-+
-+ if (ffmpegaudenc->opened) {
-+ avcodec_flush_buffers (ffmpegaudenc->context);
-+ }
-+}
-+
-+static GstCaps *
-+gst_ffmpegaudenc_getcaps (GstAudioEncoder * encoder, GstCaps * filter)
-+{
-+ GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
-+ GstCaps *caps = NULL;
-+
-+ GST_DEBUG_OBJECT (ffmpegaudenc, "getting caps");
-+
-+ /* audio needs no special care */
-+ caps = gst_audio_encoder_proxy_getcaps (encoder, NULL, filter);
-+
-+ GST_DEBUG_OBJECT (ffmpegaudenc, "audio caps, return %" GST_PTR_FORMAT, caps);
-+
-+ return caps;
-+}
-+
-+static gboolean
-+gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
-+{
-+ GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
-+ GstCaps *other_caps;
-+ GstCaps *allowed_caps;
-+ GstCaps *icaps;
-+ gsize frame_size;
-+ GstFFMpegAudEncClass *oclass =
-+ (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
-+
-+ /* close old session */
-+ if (ffmpegaudenc->opened) {
-+ gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
-+ ffmpegaudenc->opened = FALSE;
-+ }
-+
-+ /* if we set it in _getcaps we should set it also in _link */
-+ ffmpegaudenc->context->strict_std_compliance = -1;
-+
-+ /* user defined properties */
-+ if (ffmpegaudenc->bitrate > 0) {
-+ GST_INFO_OBJECT (ffmpegaudenc, "Setting avcontext to bitrate %d",
-+ ffmpegaudenc->bitrate);
-+ ffmpegaudenc->context->bit_rate = ffmpegaudenc->bitrate;
-+ ffmpegaudenc->context->bit_rate_tolerance = ffmpegaudenc->bitrate;
-+ } else {
-+ GST_INFO_OBJECT (ffmpegaudenc, "Using avcontext default bitrate %d",
-+ ffmpegaudenc->context->bit_rate);
-+ }
-+
-+ /* RTP payload used for GOB production (for Asterisk) */
-+ if (ffmpegaudenc->rtp_payload_size) {
-+ ffmpegaudenc->context->rtp_payload_size = ffmpegaudenc->rtp_payload_size;
-+ }
-+
-+ /* some other defaults */
-+ ffmpegaudenc->context->rc_strategy = 2;
-+ ffmpegaudenc->context->b_frame_strategy = 0;
-+ ffmpegaudenc->context->coder_type = 0;
-+ ffmpegaudenc->context->context_model = 0;
-+ ffmpegaudenc->context->scenechange_threshold = 0;
-+ ffmpegaudenc->context->inter_threshold = 0;
-+
-+ /* fetch pix_fmt and so on */
-+ gst_ffmpeg_audioinfo_to_context (info, ffmpegaudenc->context);
-+ if (!ffmpegaudenc->context->time_base.den) {
-+ ffmpegaudenc->context->time_base.den = GST_AUDIO_INFO_RATE (info);
-+ ffmpegaudenc->context->time_base.num = 1;
-+ ffmpegaudenc->context->ticks_per_frame = 1;
-+ }
-+
-+ if (ffmpegaudenc->context->channel_layout) {
-+ gst_ffmpeg_channel_layout_to_gst (ffmpegaudenc->context->channel_layout,
-+ ffmpegaudenc->context->channels, ffmpegaudenc->ffmpeg_layout);
-+ ffmpegaudenc->needs_reorder =
-+ (memcmp (ffmpegaudenc->ffmpeg_layout, info->position,
-+ sizeof (GstAudioChannelPosition) *
-+ ffmpegaudenc->context->channels) != 0);
-+ }
-+
-+ /* open codec */
-+ if (gst_ffmpeg_avcodec_open (ffmpegaudenc->context, oclass->in_plugin) < 0) {
-+ if (ffmpegaudenc->context->priv_data)
-+ gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
-+ GST_DEBUG_OBJECT (ffmpegaudenc, "avenc_%s: Failed to open FFMPEG codec",
-+ oclass->in_plugin->name);
-+ return FALSE;
-+ }
-+
-+ /* some codecs support more than one format, first auto-choose one */
-+ GST_DEBUG_OBJECT (ffmpegaudenc, "picking an output format ...");
-+ allowed_caps = gst_pad_get_allowed_caps (GST_AUDIO_ENCODER_SRC_PAD (encoder));
-+ if (!allowed_caps) {
-+ GST_DEBUG_OBJECT (ffmpegaudenc, "... but no peer, using template caps");
-+ /* we need to copy because get_allowed_caps returns a ref, and
-+ * get_pad_template_caps doesn't */
-+ allowed_caps =
-+ gst_pad_get_pad_template_caps (GST_AUDIO_ENCODER_SRC_PAD (encoder));
-+ }
-+ GST_DEBUG_OBJECT (ffmpegaudenc, "chose caps %" GST_PTR_FORMAT, allowed_caps);
-+ gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
-+ oclass->in_plugin->type, allowed_caps, ffmpegaudenc->context);
-+
-+ /* try to set this caps on the other side */
-+ other_caps = gst_ffmpeg_codecid_to_caps (oclass->in_plugin->id,
-+ ffmpegaudenc->context, TRUE);
-+
-+ if (!other_caps) {
-+ gst_caps_unref (allowed_caps);
-+ gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
-+ GST_DEBUG ("Unsupported codec - no caps found");
-+ return FALSE;
-+ }
-+
-+ icaps = gst_caps_intersect (allowed_caps, other_caps);
-+ gst_caps_unref (allowed_caps);
-+ gst_caps_unref (other_caps);
-+ if (gst_caps_is_empty (icaps)) {
-+ gst_caps_unref (icaps);
-+ return FALSE;
-+ }
-+ icaps = gst_caps_truncate (icaps);
-+
-+ if (!gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (ffmpegaudenc),
-+ icaps)) {
-+ gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
-+ gst_caps_unref (icaps);
-+ return FALSE;
-+ }
-+ gst_caps_unref (icaps);
-+
-+ frame_size = ffmpegaudenc->context->frame_size;
-+ if (frame_size > 1) {
-+ gst_audio_encoder_set_frame_samples_min (GST_AUDIO_ENCODER (ffmpegaudenc),
-+ frame_size);
-+ gst_audio_encoder_set_frame_samples_max (GST_AUDIO_ENCODER (ffmpegaudenc),
-+ frame_size);
-+ gst_audio_encoder_set_frame_max (GST_AUDIO_ENCODER (ffmpegaudenc), 1);
-+ } else {
-+ gst_audio_encoder_set_frame_samples_min (GST_AUDIO_ENCODER (ffmpegaudenc),
-+ 0);
-+ gst_audio_encoder_set_frame_samples_max (GST_AUDIO_ENCODER (ffmpegaudenc),
-+ 0);
-+ gst_audio_encoder_set_frame_max (GST_AUDIO_ENCODER (ffmpegaudenc), 0);
-+ }
-+
-+ /* success! */
-+ ffmpegaudenc->opened = TRUE;
-+
-+ return TRUE;
-+}
-+
-+
-+static GstFlowReturn
-+gst_ffmpegaudenc_encode_audio (GstFFMpegAudEnc * ffmpegaudenc,
-+ guint8 * audio_in, guint in_size, gint * have_data)
-+{
-+ GstAudioEncoder *enc;
-+ AVCodecContext *ctx;
-+ gint res;
-+ GstFlowReturn ret;
-+ GstAudioInfo *info;
-+ AVPacket pkt;
-+ AVFrame frame;
-+ gboolean planar;
-+
-+ enc = GST_AUDIO_ENCODER (ffmpegaudenc);
-+
-+ ctx = ffmpegaudenc->context;
-+
-+ GST_LOG_OBJECT (ffmpegaudenc, "encoding buffer ");
-+
-+ memset (&pkt, 0, sizeof (pkt));
-+ memset (&frame, 0, sizeof (frame));
-+ avcodec_get_frame_defaults (&frame);
-+
-+ info = gst_audio_encoder_get_audio_info (enc);
-+ planar = av_sample_fmt_is_planar (ffmpegaudenc->context->sample_fmt);
-+
-+ if (planar && info->channels > 1) {
-+ gint channels, nsamples;
-+ gint i, j;
-+
-+ nsamples = frame.nb_samples = in_size / info->bpf;
-+ channels = info->channels;
-+
-+ if (info->channels > AV_NUM_DATA_POINTERS) {
-+ frame.extended_data = g_new (uint8_t *, info->channels);
-+ } else {
-+ frame.extended_data = frame.data;
-+ }
-+
-+ frame.extended_data[0] = g_malloc (in_size);
-+ frame.linesize[0] = in_size / channels;
-+ for (i = 1; i < channels; i++)
-+ frame.extended_data[i] = frame.extended_data[i - 1] + frame.linesize[0];
-+
-+ switch (info->finfo->width) {
-+ case 8:{
-+ const guint8 *idata = (const guint8 *) audio_in;
-+
-+ for (i = 0; i < nsamples; i++) {
-+ for (j = 0; j < channels; j++) {
-+ ((guint8 *) frame.extended_data[j])[i] = idata[j];
-+ }
-+ idata += channels;
-+ }
-+ break;
-+ }
-+ case 16:{
-+ const guint16 *idata = (const guint16 *) audio_in;
-+
-+ for (i = 0; i < nsamples; i++) {
-+ for (j = 0; j < channels; j++) {
-+ ((guint16 *) frame.extended_data[j])[i] = idata[j];
-+ }
-+ idata += channels;
-+ }
-+ break;
-+ }
-+ case 32:{
-+ const guint32 *idata = (const guint32 *) audio_in;
-+
-+ for (i = 0; i < nsamples; i++) {
-+ for (j = 0; j < channels; j++) {
-+ ((guint32 *) frame.extended_data[j])[i] = idata[j];
-+ }
-+ idata += channels;
-+ }
-+
-+ break;
-+ }
-+ case 64:{
-+ const guint64 *idata = (const guint64 *) audio_in;
-+
-+ for (i = 0; i < nsamples; i++) {
-+ for (j = 0; j < channels; j++) {
-+ ((guint64 *) frame.extended_data[j])[i] = idata[j];
-+ }
-+ idata += channels;
-+ }
-+
-+ break;
-+ }
-+ default:
-+ g_assert_not_reached ();
-+ break;
-+ }
-+
-+ } else {
-+ frame.data[0] = audio_in;
-+ frame.extended_data = frame.data;
-+ frame.linesize[0] = in_size;
-+ frame.nb_samples = in_size / info->bpf;
-+ }
-+
-+ res = avcodec_encode_audio2 (ctx, &pkt, &frame, have_data);
-+ if (planar && info->channels > 1)
-+ g_free (frame.data[0]);
-+ if (frame.extended_data != frame.data)
-+ g_free (frame.extended_data);
-+
-+ if (res < 0) {
-+ char error_str[128] = { 0, };
-+
-+ av_strerror (res, error_str, sizeof (error_str));
-+ GST_ERROR_OBJECT (enc, "Failed to encode buffer: %d - %s", res, error_str);
-+ return GST_FLOW_OK;
-+ }
-+ GST_LOG_OBJECT (ffmpegaudenc, "got output size %d", res);
-+
-+ if (*have_data) {
-+ GstBuffer *outbuf;
-+ const AVCodec *codec;
-+
-+ GST_LOG_OBJECT (ffmpegaudenc, "pushing size %d", pkt.size);
-+
-+ outbuf =
-+ gst_buffer_new_wrapped_full (0, pkt.data, pkt.size, 0, pkt.size,
-+ pkt.data, av_free);
-+
-+ codec = ffmpegaudenc->context->codec;
-+ if ((codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) {
-+ ret = gst_audio_encoder_finish_frame (enc, outbuf, -1);
-+ } else {
-+ ret = gst_audio_encoder_finish_frame (enc, outbuf, frame.nb_samples);
-+ }
-+ } else {
-+ GST_LOG_OBJECT (ffmpegaudenc, "no output produced");
-+ ret = GST_FLOW_OK;
-+ }
-+
-+ return ret;
-+}
-+
-+static void
-+gst_ffmpegaudenc_drain (GstFFMpegAudEnc * ffmpegaudenc)
-+{
-+ GstFFMpegAudEncClass *oclass;
-+
-+ oclass = (GstFFMpegAudEncClass *) (G_OBJECT_GET_CLASS (ffmpegaudenc));
-+
-+ if (oclass->in_plugin->capabilities & CODEC_CAP_DELAY) {
-+ gint have_data, try = 0;
-+
-+ GST_LOG_OBJECT (ffmpegaudenc,
-+ "codec has delay capabilities, calling until libav has drained everything");
-+
-+ do {
-+ GstFlowReturn ret;
-+
-+ ret = gst_ffmpegaudenc_encode_audio (ffmpegaudenc, NULL, 0, &have_data);
-+ if (ret != GST_FLOW_OK || have_data == 0)
-+ break;
-+ } while (try++ < 10);
-+ }
-+}
-+
-+static GstFlowReturn
-+gst_ffmpegaudenc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf)
-+{
-+ GstFFMpegAudEnc *ffmpegaudenc;
-+ gsize size;
-+ GstFlowReturn ret;
-+ guint8 *in_data;
-+ GstMapInfo map;
-+ gint have_data;
-+
-+ ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
-+
-+ if (G_UNLIKELY (!ffmpegaudenc->opened))
-+ goto not_negotiated;
-+
-+ if (!inbuf) {
-+ gst_ffmpegaudenc_drain (ffmpegaudenc);
-+ return GST_FLOW_OK;
-+ }
-+
-+ inbuf = gst_buffer_ref (inbuf);
-+
-+ GST_DEBUG_OBJECT (ffmpegaudenc,
-+ "Received time %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT
-+ ", size %" G_GSIZE_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (inbuf)),
-+ GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)), gst_buffer_get_size (inbuf));
-+
-+ /* Reorder channels to the GStreamer channel order */
-+ if (ffmpegaudenc->needs_reorder) {
-+ GstAudioInfo *info = gst_audio_encoder_get_audio_info (encoder);
-+
-+ inbuf = gst_buffer_make_writable (inbuf);
-+ gst_audio_buffer_reorder_channels (inbuf, info->finfo->format,
-+ info->channels, info->position, ffmpegaudenc->ffmpeg_layout);
-+ }
-+
-+ gst_buffer_map (inbuf, &map, GST_MAP_READ);
-+ in_data = map.data;
-+ size = map.size;
-+ ret = gst_ffmpegaudenc_encode_audio (ffmpegaudenc, in_data, size, &have_data);
-+ gst_buffer_unmap (inbuf, &map);
-+ gst_buffer_unref (inbuf);
-+
-+ if (ret != GST_FLOW_OK)
-+ goto push_failed;
-+
-+ return GST_FLOW_OK;
-+
-+ /* ERRORS */
-+not_negotiated:
-+ {
-+ GST_ELEMENT_ERROR (ffmpegaudenc, CORE, NEGOTIATION, (NULL),
-+ ("not configured to input format before data start"));
-+ gst_buffer_unref (inbuf);
-+ return GST_FLOW_NOT_NEGOTIATED;
-+ }
-+push_failed:
-+ {
-+ GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to push buffer %d (%s)", ret,
-+ gst_flow_get_name (ret));
-+ return ret;
-+ }
-+}
-+
-+static void
-+gst_ffmpegaudenc_set_property (GObject * object,
-+ guint prop_id, const GValue * value, GParamSpec * pspec)
-+{
-+ GstFFMpegAudEnc *ffmpegaudenc;
-+
-+ /* Get a pointer of the right type. */
-+ ffmpegaudenc = (GstFFMpegAudEnc *) (object);
-+
-+ if (ffmpegaudenc->opened) {
-+ GST_WARNING_OBJECT (ffmpegaudenc,
-+ "Can't change properties once decoder is setup !");
-+ return;
-+ }
-+
-+ /* Check the argument id to see which argument we're setting. */
-+ switch (prop_id) {
-+ case PROP_BIT_RATE:
-+ ffmpegaudenc->bitrate = g_value_get_int (value);
-+ break;
-+ case PROP_RTP_PAYLOAD_SIZE:
-+ ffmpegaudenc->rtp_payload_size = g_value_get_int (value);
-+ break;
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+ break;
-+ }
-+}
-+
-+/* The set function is simply the inverse of the get fuction. */
-+static void
-+gst_ffmpegaudenc_get_property (GObject * object,
-+ guint prop_id, GValue * value, GParamSpec * pspec)
-+{
-+ GstFFMpegAudEnc *ffmpegaudenc;
-+
-+ /* It's not null if we got it, but it might not be ours */
-+ ffmpegaudenc = (GstFFMpegAudEnc *) (object);
-+
-+ switch (prop_id) {
-+ case PROP_BIT_RATE:
-+ g_value_set_int (value, ffmpegaudenc->bitrate);
-+ break;
-+ break;
-+ case PROP_RTP_PAYLOAD_SIZE:
-+ g_value_set_int (value, ffmpegaudenc->rtp_payload_size);
-+ break;
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+ break;
-+ }
-+}
-+
-+gboolean
-+gst_ffmpegaudenc_register (GstPlugin * plugin)
-+{
-+ GTypeInfo typeinfo = {
-+ sizeof (GstFFMpegAudEncClass),
-+ (GBaseInitFunc) gst_ffmpegaudenc_base_init,
-+ NULL,
-+ (GClassInitFunc) gst_ffmpegaudenc_class_init,
-+ NULL,
-+ NULL,
-+ sizeof (GstFFMpegAudEnc),
-+ 0,
-+ (GInstanceInitFunc) gst_ffmpegaudenc_init,
-+ };
-+ GType type;
-+ AVCodec *in_plugin;
-+
-+
-+ GST_LOG ("Registering encoders");
-+
-+ in_plugin = av_codec_next (NULL);
-+ while (in_plugin) {
-+ gchar *type_name;
-+ guint rank;
-+
-+ /* Skip non-AV codecs */
-+ if (in_plugin->type != AVMEDIA_TYPE_AUDIO)
-+ goto next;
-+
-+ /* no quasi codecs, please */
-+ if ((in_plugin->id >= CODEC_ID_PCM_S16LE &&
-+ in_plugin->id <= CODEC_ID_PCM_BLURAY)) {
-+ goto next;
-+ }
-+
-+ /* No encoders depending on external libraries (we don't build them, but
-+ * people who build against an external ffmpeg might have them.
-+ * We have native gstreamer plugins for all of those libraries anyway. */
-+ if (!strncmp (in_plugin->name, "lib", 3)) {
-+ GST_DEBUG
-+ ("Not using external library encoder %s. Use the gstreamer-native ones instead.",
-+ in_plugin->name);
-+ goto next;
-+ }
-+
-+ /* only encoders */
-+ if (!av_codec_is_encoder (in_plugin)) {
-+ goto next;
-+ }
-+
-+ /* FIXME : We should have a method to know cheaply whether we have a mapping
-+ * for the given plugin or not */
-+
-+ GST_DEBUG ("Trying plugin %s [%s]", in_plugin->name, in_plugin->long_name);
-+
-+ /* no codecs for which we're GUARANTEED to have better alternatives */
-+ if (!strcmp (in_plugin->name, "vorbis")
-+ || !strcmp (in_plugin->name, "flac")) {
-+ GST_LOG ("Ignoring encoder %s", in_plugin->name);
-+ goto next;
-+ }
-+
-+ /* construct the type */
-+ type_name = g_strdup_printf ("avenc_%s", in_plugin->name);
-+
-+ type = g_type_from_name (type_name);
-+
-+ if (!type) {
-+
-+ /* create the glib type now */
-+ type =
-+ g_type_register_static (GST_TYPE_AUDIO_ENCODER, type_name, &typeinfo,
-+ 0);
-+ g_type_set_qdata (type, GST_FFENC_PARAMS_QDATA, (gpointer) in_plugin);
-+
-+ {
-+ static const GInterfaceInfo preset_info = {
-+ NULL,
-+ NULL,
-+ NULL
-+ };
-+ g_type_add_interface_static (type, GST_TYPE_PRESET, &preset_info);
-+ }
-+ }
-+
-+ switch (in_plugin->id) {
-+ /* avenc_aac: see https://bugzilla.gnome.org/show_bug.cgi?id=691617 */
-+ case CODEC_ID_AAC:
-+ rank = GST_RANK_NONE;
-+ break;
-+ default:
-+ rank = GST_RANK_SECONDARY;
-+ break;
-+ }
-+
-+ if (!gst_element_register (plugin, type_name, rank, type)) {
-+ g_free (type_name);
-+ return FALSE;
-+ }
-+
-+ g_free (type_name);
-+
-+ next:
-+ in_plugin = av_codec_next (in_plugin);
-+ }
-+
-+ GST_LOG ("Finished registering encoders");
-+
-+ return TRUE;
-+}
-diff --git a/ext/libav/gstavaudenc.h b/ext/libav/gstavaudenc.h
-new file mode 100644
-index 0000000..b01184f
---- /dev/null
-+++ b/ext/libav/gstavaudenc.h
-@@ -0,0 +1,77 @@
-+/* 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., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
-+ */
-+
-+/* First, include the header file for the plugin, to bring in the
-+ * object definition and other useful things.
-+ */
-+
-+#ifndef __GST_FFMPEGAUDENC_H__
-+#define __GST_FFMPEGAUDENC_H__
-+
-+G_BEGIN_DECLS
-+
-+#include <gst/gst.h>
-+#include <gst/audio/gstaudioencoder.h>
-+#include <libavcodec/avcodec.h>
-+
-+typedef struct _GstFFMpegAudEnc GstFFMpegAudEnc;
-+
-+struct _GstFFMpegAudEnc
-+{
-+ GstAudioEncoder parent;
-+
-+ AVCodecContext *context;
-+ gboolean opened;
-+
-+ /* cache */
-+ gint bitrate;
-+ gint rtp_payload_size;
-+
-+ /* other settings are copied over straight,
-+ * include a context here, rather than copy-and-past it from avcodec.h */
-+ AVCodecContext config;
-+
-+ GstAudioChannelPosition ffmpeg_layout[64];
-+ gboolean needs_reorder;
-+};
-+
-+typedef struct _GstFFMpegAudEncClass GstFFMpegAudEncClass;
-+
-+struct _GstFFMpegAudEncClass
-+{
-+ GstAudioEncoderClass parent_class;
-+
-+ AVCodec *in_plugin;
-+ GstPadTemplate *srctempl, *sinktempl;
-+};
-+
-+#define GST_TYPE_FFMPEGAUDENC \
-+ (gst_ffmpegaudenc_get_type())
-+#define GST_FFMPEGAUDENC(obj) \
-+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGAUDENC,GstFFMpegAudEnc))
-+#define GST_FFMPEGAUDENC_CLASS(klass) \
-+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGAUDENC,GstFFMpegAudEncClass))
-+#define GST_IS_FFMPEGAUDENC(obj) \
-+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGAUDENC))
-+#define GST_IS_FFMPEGAUDENC_CLASS(klass) \
-+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGAUDENC))
-+
-+G_END_DECLS
-+
-+#endif /* __GST_FFMPEGAUDENC_H__ */
-diff --git a/ext/libav/gstavcfg.c b/ext/libav/gstavcfg.c
-index 5ee23dd..1d7c9d7 100644
---- a/ext/libav/gstavcfg.c
-+++ b/ext/libav/gstavcfg.c
-@@ -16,8 +16,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
-
-@@ -147,7 +147,6 @@ gst_ffmpeg_dct_algo_get_type (void)
- {FF_DCT_FASTINT, "Fast Integer", "fastint"},
- {FF_DCT_INT, "Accurate Integer", "int"},
- {FF_DCT_MMX, "MMX", "mmx"},
-- {FF_DCT_MLIB, "MLIB", "mlib"},
- {FF_DCT_ALTIVEC, "ALTIVEC", "altivec"},
- {FF_DCT_FAAN, "FAAN", "faan"},
- {0, NULL, NULL},
-@@ -173,8 +172,6 @@ gst_ffmpeg_idct_algo_get_type (void)
- {FF_IDCT_SIMPLE, "Simple", "simple"},
- {FF_IDCT_SIMPLEMMX, "Simple MMX", "simplemmx"},
- {FF_IDCT_LIBMPEG2MMX, "LIBMPEG2MMX", "libmpeg2mmx"},
-- {FF_IDCT_PS2, "PS2", "ps2"},
-- {FF_IDCT_MLIB, "MLIB", "mlib"},
- {FF_IDCT_ARM, "ARM", "arm"},
- {FF_IDCT_ALTIVEC, "ALTIVEC", "altivec"},
- {FF_IDCT_SH4, "SH4", "sh4"},
-@@ -263,16 +260,11 @@ gst_ffmpeg_flags_get_type (void)
-
- if (!ffmpeg_flags_type) {
- static const GFlagsValue ffmpeg_flags[] = {
-- {CODEC_FLAG_OBMC, "Use overlapped block motion compensation (h263+)",
-- "obmc"},
- {CODEC_FLAG_QSCALE, "Use fixed qscale", "qscale"},
- {CODEC_FLAG_4MV, "Allow 4 MV per MB", "4mv"},
-- {CODEC_FLAG_H263P_AIV, "H.263 alternative inter VLC", "aiv"},
- {CODEC_FLAG_QPEL, "Quartel Pel Motion Compensation", "qpel"},
- {CODEC_FLAG_GMC, "GMC", "gmc"},
- {CODEC_FLAG_MV0, "Always try a MB with MV (0,0)", "mv0"},
-- {CODEC_FLAG_PART,
-- "Store MV, DC and AC coefficients in seperate partitions", "part"},
- {CODEC_FLAG_LOOP_FILTER, "Loop filter", "loop-filter"},
- {CODEC_FLAG_GRAY, "Only decode/encode grayscale", "gray"},
- {CODEC_FLAG_NORMALIZE_AQP,
-@@ -282,13 +274,9 @@ gst_ffmpeg_flags_get_type (void)
- "global-headers"},
- {CODEC_FLAG_AC_PRED, "H263 Advanced Intra Coding / MPEG4 AC prediction",
- "aic"},
-- {CODEC_FLAG_H263P_UMV, "Unlimited Motion Vector", "umv"},
- {CODEC_FLAG_CBP_RD, "Rate Distoration Optimization for CBP", "cbp-rd"},
- {CODEC_FLAG_QP_RD, "Rate Distoration Optimization for QP selection",
- "qp-rd"},
-- {CODEC_FLAG_H263P_SLICE_STRUCT, "H263 slice struct", "ss"},
-- {CODEC_FLAG_SVCD_SCAN_OFFSET,
-- "Reserve space for SVCD scan offset user data", "scanoffset"},
- {CODEC_FLAG_CLOSED_GOP, "Closed GOP", "closedgop"},
- {0, NULL, NULL},
- };
-@@ -750,10 +738,8 @@ gst_ffmpeg_cfg_install_property (GstFFMpegVidEncClass * klass, guint base)
- prop_id = base;
- g_return_if_fail (base > 0);
-
-- ctx = avcodec_alloc_context ();
-- if (ctx)
-- avcodec_get_context_defaults (ctx);
-- else
-+ ctx = avcodec_alloc_context3 (klass->in_plugin);
-+ if (!ctx)
- g_warning ("could not get context");
-
- for (list = property_list; list; list = list->next) {
-diff --git a/ext/libav/gstavcfg.h b/ext/libav/gstavcfg.h
-index 5251eb2..2aef665 100644
---- a/ext/libav/gstavcfg.h
-+++ b/ext/libav/gstavcfg.h
-@@ -13,8 +13,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
-
-diff --git a/ext/libav/gstavcodecmap.c b/ext/libav/gstavcodecmap.c
-index 7b28800..cac15ee 100644
---- a/ext/libav/gstavcodecmap.c
-+++ b/ext/libav/gstavcodecmap.c
-@@ -15,8 +15,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
- #ifdef HAVE_CONFIG_H
-@@ -27,6 +27,7 @@
-
- #include <gst/gst.h>
- #include <libavcodec/avcodec.h>
-+#include <libavutil/channel_layout.h>
-
- #include "gstav.h"
- #include "gstavcodecmap.h"
-@@ -35,44 +36,6 @@
- #include <gst/audio/audio.h>
- #include <gst/pbutils/codec-utils.h>
-
--/*
-- * Read a palette from a caps.
-- */
--
--static void
--gst_ffmpeg_get_palette (const GstCaps * caps, AVCodecContext * context)
--{
-- GstStructure *str = gst_caps_get_structure (caps, 0);
-- const GValue *palette_v;
-- GstBuffer *palette;
--
-- /* do we have a palette? */
-- if ((palette_v = gst_structure_get_value (str, "palette_data")) && context) {
-- palette = gst_value_get_buffer (palette_v);
-- GST_DEBUG ("got palette data %p", palette);
-- if (gst_buffer_get_size (palette) >= AVPALETTE_SIZE) {
-- if (context->palctrl)
-- av_free (context->palctrl);
-- context->palctrl = av_malloc (sizeof (AVPaletteControl));
-- context->palctrl->palette_changed = 1;
-- gst_buffer_extract (palette, 0, context->palctrl->palette,
-- AVPALETTE_SIZE);
-- GST_DEBUG ("extracted palette data");
-- }
-- }
--}
--
--static void
--gst_ffmpeg_set_palette (GstCaps * caps, AVCodecContext * context)
--{
-- if (context->palctrl) {
-- GstBuffer *palette = gst_buffer_new_and_alloc (AVPALETTE_SIZE);
--
-- gst_buffer_fill (palette, 0, context->palctrl->palette, AVPALETTE_SIZE);
-- gst_caps_set_simple (caps, "palette_data", GST_TYPE_BUFFER, palette, NULL);
-- }
--}
--
- /* IMPORTANT: Keep this sorted by the ffmpeg channel masks */
- static const struct
- {
-@@ -80,34 +43,60 @@ static const struct
- GstAudioChannelPosition gst;
- } _ff_to_gst_layout[] = {
- {
-- CH_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
-- CH_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
-- CH_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
-- CH_LOW_FREQUENCY, GST_AUDIO_CHANNEL_POSITION_LFE1}, {
-- CH_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT}, {
-- CH_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
-- CH_FRONT_LEFT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER}, {
-- CH_FRONT_RIGHT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
-- CH_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
-- CH_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT}, {
-- CH_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}, {
-- CH_TOP_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_CENTER}, {
-- CH_TOP_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT}, {
-- CH_TOP_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER}, {
-- CH_TOP_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT}, {
-- CH_TOP_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT}, {
-- CH_TOP_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER}, {
-- CH_TOP_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT}, {
-- CH_STEREO_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
-- CH_STEREO_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}
-+ AV_CH_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
-+ AV_CH_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
-+ AV_CH_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
-+ AV_CH_LOW_FREQUENCY, GST_AUDIO_CHANNEL_POSITION_LFE1}, {
-+ AV_CH_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT}, {
-+ AV_CH_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
-+ AV_CH_FRONT_LEFT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER}, {
-+ AV_CH_FRONT_RIGHT_OF_CENTER,
-+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
-+ AV_CH_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
-+ AV_CH_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT}, {
-+ AV_CH_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}, {
-+ AV_CH_TOP_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_CENTER}, {
-+ AV_CH_TOP_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT}, {
-+ AV_CH_TOP_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER}, {
-+ AV_CH_TOP_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT}, {
-+ AV_CH_TOP_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT}, {
-+ AV_CH_TOP_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER}, {
-+ AV_CH_TOP_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT}, {
-+ AV_CH_STEREO_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
-+ AV_CH_STEREO_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}
- };
-
-+static guint64
-+gst_ffmpeg_channel_positions_to_layout (GstAudioChannelPosition * pos,
-+ gint channels)
-+{
-+ gint i, j;
-+ guint64 ret = 0;
-+ gint channels_found = 0;
-+
-+ if (!pos)
-+ return 0;
-+
-+ for (i = 0; i < channels; i++) {
-+ for (j = 0; j < G_N_ELEMENTS (_ff_to_gst_layout); j++) {
-+ if (_ff_to_gst_layout[j].gst == pos[i]) {
-+ ret |= _ff_to_gst_layout[j].ff;
-+ channels_found++;
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (channels_found != channels)
-+ return 0;
-+ return ret;
-+}
-+
- gboolean
--gst_ffmpeg_channel_layout_to_gst (AVCodecContext * context,
-+gst_ffmpeg_channel_layout_to_gst (guint64 channel_layout, gint channels,
- GstAudioChannelPosition * pos)
- {
-- guint nchannels = 0, channels = context->channels;
-- guint64 channel_layout = context->channel_layout;
-+ guint nchannels = 0;
- gboolean none_layout = FALSE;
-
- if (channel_layout == 0) {
-@@ -170,6 +159,52 @@ gst_ffmpeg_channel_layout_to_gst (AVCodecContext * context,
- return TRUE;
- }
-
-+static void
-+gst_ffmpeg_video_set_pix_fmts (GstCaps * caps, const enum AVPixelFormat *fmts)
-+{
-+ GValue va = { 0, };
-+ GValue v = { 0, };
-+ GstVideoFormat format;
-+
-+ if (!fmts || fmts[0] == -1) {
-+ gint i;
-+
-+ g_value_init (&va, GST_TYPE_LIST);
-+ g_value_init (&v, G_TYPE_STRING);
-+ for (i = 0; i <= PIX_FMT_NB; i++) {
-+ format = gst_ffmpeg_pixfmt_to_videoformat (i);
-+ if (format == GST_VIDEO_FORMAT_UNKNOWN)
-+ continue;
-+ g_value_set_string (&v, gst_video_format_to_string (format));
-+ gst_value_list_append_value (&va, &v);
-+ }
-+ gst_caps_set_value (caps, "format", &va);
-+ g_value_unset (&v);
-+ g_value_unset (&va);
-+ return;
-+ }
-+
-+ /* Only a single format */
-+ g_value_init (&va, GST_TYPE_LIST);
-+ g_value_init (&v, G_TYPE_STRING);
-+ while (*fmts != -1) {
-+ format = gst_ffmpeg_pixfmt_to_videoformat (*fmts);
-+ if (format != GST_VIDEO_FORMAT_UNKNOWN) {
-+ g_value_set_string (&v, gst_video_format_to_string (format));
-+ gst_value_list_append_value (&va, &v);
-+ }
-+ fmts++;
-+ }
-+ if (gst_value_list_get_size (&va) == 1) {
-+ /* The single value is still in v */
-+ gst_caps_set_value (caps, "format", &v);
-+ } else if (gst_value_list_get_size (&va) > 1) {
-+ gst_caps_set_value (caps, "format", &va);
-+ }
-+ g_value_unset (&v);
-+ g_value_unset (&va);
-+}
-+
- /* this macro makes a caps width fixed or unfixed width/height
- * properties depending on whether we've got a context.
- *
-@@ -179,10 +214,10 @@ gst_ffmpeg_channel_layout_to_gst (AVCodecContext * context,
- * but I'm too lazy today. Maybe later.
- */
- static GstCaps *
--gst_ff_vid_caps_new (AVCodecContext * context, enum CodecID codec_id,
-- gboolean encode, const char *mimetype, const char *fieldname, ...)
-+gst_ff_vid_caps_new (AVCodecContext * context, AVCodec * codec,
-+ enum CodecID codec_id, gboolean encode, const char *mimetype,
-+ const char *fieldname, ...)
- {
-- GstStructure *structure = NULL;
- GstCaps *caps = NULL;
- va_list var_args;
- gint i;
-@@ -252,32 +287,58 @@ gst_ff_vid_caps_new (AVCodecContext * context, enum CodecID codec_id,
- {
- static struct
- {
-- guint32 csp;
-+ const gchar *csp;
- gint width, height;
- gint par_n, par_d;
- gint framerate_n, framerate_d;
- } profiles[] = {
- {
-- GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 480, 10, 11, 30000, 1001}, {
-- GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 480, 40, 33, 30000, 1001}, {
-- GST_MAKE_FOURCC ('I', '4', '2', '0'), 720, 576, 59, 54, 25, 1}, {
-- GST_MAKE_FOURCC ('I', '4', '2', '0'), 720, 576, 118, 81, 25, 1}, {
-- GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 576, 59, 54, 25, 1}, {
-- GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 576, 118, 81, 25, 1}
-- };
-+ "Y41B", 720, 480, 8, 9, 30000, 1001}, {
-+ "Y41B", 720, 480, 32, 27, 30000, 1001}, {
-+ "Y42B", 720, 480, 8, 9, 30000, 1001}, {
-+ "Y42B", 720, 480, 32, 27, 30000, 1001}, {
-+ "I420", 720, 576, 16, 15, 25, 1}, {
-+ "I420", 720, 576, 64, 45, 25, 1}, {
-+ "Y41B", 720, 576, 16, 15, 25, 1}, {
-+ "Y41B", 720, 576, 64, 45, 25, 1}, {
-+ "Y42B", 720, 576, 16, 15, 25, 1}, {
-+ "Y42B", 720, 576, 64, 45, 25, 1}, {
-+ "Y42B", 1280, 1080, 1, 1, 30000, 1001}, {
-+ "Y42B", 1280, 1080, 3, 2, 30000, 1001}, {
-+ "Y42B", 1440, 1080, 1, 1, 25, 1}, {
-+ "Y42B", 1440, 1080, 4, 3, 25, 1}, {
-+ "Y42B", 960, 720, 1, 1, 60000, 1001}, {
-+ "Y42B", 960, 720, 4, 3, 60000, 1001}, {
-+ "Y42B", 960, 720, 1, 1, 50, 1}, {
-+ "Y42B", 960, 720, 4, 3, 50, 1},};
- GstCaps *temp;
- gint n_sizes = G_N_ELEMENTS (profiles);
-
-- caps = gst_caps_new_empty ();
-- for (i = 0; i < n_sizes; i++) {
-- temp = gst_caps_new_simple (mimetype,
-- "width", G_TYPE_INT, profiles[i].width,
-- "height", G_TYPE_INT, profiles[i].height,
-- "framerate", GST_TYPE_FRACTION, profiles[i].framerate_n,
-- profiles[i].framerate_d, "pixel-aspect-ratio", GST_TYPE_FRACTION,
-- profiles[i].par_n, profiles[i].par_d, NULL);
--
-- gst_caps_append (caps, temp);
-+ if (strcmp (mimetype, "video/x-raw") == 0) {
-+ caps = gst_caps_new_empty ();
-+ for (i = 0; i < n_sizes; i++) {
-+ temp = gst_caps_new_simple (mimetype,
-+ "format", G_TYPE_STRING, profiles[i].csp,
-+ "width", G_TYPE_INT, profiles[i].width,
-+ "height", G_TYPE_INT, profiles[i].height,
-+ "framerate", GST_TYPE_FRACTION, profiles[i].framerate_n,
-+ profiles[i].framerate_d, "pixel-aspect-ratio",
-+ GST_TYPE_FRACTION, profiles[i].par_n, profiles[i].par_d, NULL);
-+
-+ gst_caps_append (caps, temp);
-+ }
-+ } else {
-+ caps = gst_caps_new_empty ();
-+ for (i = 0; i < n_sizes; i++) {
-+ temp = gst_caps_new_simple (mimetype,
-+ "width", G_TYPE_INT, profiles[i].width,
-+ "height", G_TYPE_INT, profiles[i].height,
-+ "framerate", GST_TYPE_FRACTION, profiles[i].framerate_n,
-+ profiles[i].framerate_d, "pixel-aspect-ratio",
-+ GST_TYPE_FRACTION, profiles[i].par_n, profiles[i].par_d, NULL);
-+
-+ gst_caps_append (caps, temp);
-+ }
- }
- break;
- }
-@@ -294,7 +355,40 @@ gst_ff_vid_caps_new (AVCodecContext * context, enum CodecID codec_id,
- break;
- }
- default:
-+ {
-+ if (codec && codec->supported_framerates
-+ && codec->supported_framerates[0].num != 0
-+ && codec->supported_framerates[0].den != 0) {
-+ GValue va = { 0, };
-+ GValue v = { 0, };
-+ const AVRational *rates = codec->supported_framerates;
-+
-+ if (rates[1].num == 0 && rates[1].den == 0) {
-+ caps =
-+ gst_caps_new_simple (mimetype, "framerate", GST_TYPE_FRACTION,
-+ rates[0].num, rates[0].den, NULL);
-+ } else {
-+ g_value_init (&va, GST_TYPE_LIST);
-+ g_value_init (&v, GST_TYPE_FRACTION);
-+
-+ while (rates->num != 0 && rates->den != 0) {
-+ gst_value_set_fraction (&v, rates->num, rates->den);
-+ gst_value_list_append_value (&va, &v);
-+ rates++;
-+ }
-+
-+ caps = gst_caps_new_simple (mimetype, NULL, NULL, NULL);
-+ gst_caps_set_value (caps, "framerate", &va);
-+ g_value_unset (&va);
-+ g_value_unset (&v);
-+ }
-+
-+ } else {
-+ caps = gst_caps_new_empty_simple (mimetype);
-+ }
-+
- break;
-+ }
- }
- }
-
-@@ -302,27 +396,84 @@ gst_ff_vid_caps_new (AVCodecContext * context, enum CodecID codec_id,
- * default unfixed setting */
- if (!caps) {
- GST_DEBUG ("Creating default caps");
-- caps = gst_caps_new_simple (mimetype, NULL, NULL, NULL);
-+ caps = gst_caps_new_empty_simple (mimetype);
- }
-
-- for (i = 0; i < gst_caps_get_size (caps); i++) {
-- va_start (var_args, fieldname);
-- structure = gst_caps_get_structure (caps, i);
-- gst_structure_set_valist (structure, fieldname, var_args);
-- va_end (var_args);
-- }
-+ va_start (var_args, fieldname);
-+ gst_caps_set_simple_valist (caps, fieldname, var_args);
-+ va_end (var_args);
-
- return caps;
- }
-
-+static gint
-+get_nbits_set (guint64 n)
-+{
-+ gint i, x;
-+
-+ x = 0;
-+ for (i = 0; i < 64; i++) {
-+ if ((n & (G_GUINT64_CONSTANT (1) << i)))
-+ x++;
-+ }
-+
-+ return x;
-+}
-+
-+static void
-+gst_ffmpeg_audio_set_sample_fmts (GstCaps * caps,
-+ const enum AVSampleFormat *fmts)
-+{
-+ GValue va = { 0, };
-+ GValue v = { 0, };
-+ GstAudioFormat format;
-+
-+ if (!fmts || fmts[0] == -1) {
-+ gint i;
-+
-+ g_value_init (&va, GST_TYPE_LIST);
-+ g_value_init (&v, G_TYPE_STRING);
-+ for (i = 0; i <= AV_SAMPLE_FMT_DBL; i++) {
-+ format = gst_ffmpeg_smpfmt_to_audioformat (i);
-+ if (format == GST_AUDIO_FORMAT_UNKNOWN)
-+ continue;
-+ g_value_set_string (&v, gst_audio_format_to_string (format));
-+ gst_value_list_append_value (&va, &v);
-+ }
-+ gst_caps_set_value (caps, "format", &va);
-+ g_value_unset (&v);
-+ g_value_unset (&va);
-+ return;
-+ }
-+
-+ g_value_init (&va, GST_TYPE_LIST);
-+ g_value_init (&v, G_TYPE_STRING);
-+ while (*fmts != -1) {
-+ format = gst_ffmpeg_smpfmt_to_audioformat (*fmts);
-+ if (format != GST_AUDIO_FORMAT_UNKNOWN) {
-+ g_value_set_string (&v, gst_audio_format_to_string (format));
-+ gst_value_list_append_value (&va, &v);
-+ }
-+ fmts++;
-+ }
-+ if (gst_value_list_get_size (&va) == 1) {
-+ /* The single value is still in v */
-+ gst_caps_set_value (caps, "format", &v);
-+ } else if (gst_value_list_get_size (&va) > 1) {
-+ gst_caps_set_value (caps, "format", &va);
-+ }
-+ g_value_unset (&v);
-+ g_value_unset (&va);
-+}
-+
- /* same for audio - now with channels/sample rate
- */
- static GstCaps *
--gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
-- gboolean encode, const char *mimetype, const char *fieldname, ...)
-+gst_ff_aud_caps_new (AVCodecContext * context, AVCodec * codec,
-+ enum CodecID codec_id, gboolean encode, const char *mimetype,
-+ const char *fieldname, ...)
- {
- GstCaps *caps = NULL;
-- GstStructure *structure = NULL;
- gint i;
- va_list var_args;
-
-@@ -334,7 +485,8 @@ gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
- "rate", G_TYPE_INT, context->sample_rate,
- "channels", G_TYPE_INT, context->channels, NULL);
-
-- if (gst_ffmpeg_channel_layout_to_gst (context, pos)) {
-+ if (gst_ffmpeg_channel_layout_to_gst (context->channel_layout,
-+ context->channels, pos)) {
- guint64 mask;
-
- if (gst_audio_channel_positions_to_mask (pos, context->channels, FALSE,
-@@ -422,10 +574,6 @@ gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
- break;
- }
-
-- /* TODO: handle context->channel_layouts here to set
-- * the list of channel layouts supported by the encoder.
-- * Unfortunately no encoder uses this yet....
-- */
- /* regardless of encode/decode, open up channels if applicable */
- /* Until decoders/encoders expose the maximum number of channels
- * they support, we whitelist them here. */
-@@ -438,15 +586,40 @@ gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
- break;
- }
-
-- if (maxchannels == 1)
-- caps = gst_caps_new_simple (mimetype,
-- "channels", G_TYPE_INT, maxchannels, NULL);
-- else
-- caps = gst_caps_new_simple (mimetype,
-- "channels", GST_TYPE_INT_RANGE, 1, maxchannels, NULL);
-+ if (codec && codec->channel_layouts) {
-+ const uint64_t *layouts = codec->channel_layouts;
-+ GstAudioChannelPosition pos[64];
-+
-+ caps = gst_caps_new_empty ();
-+ while (*layouts) {
-+ gint nbits_set = get_nbits_set (*layouts);
-+
-+ if (gst_ffmpeg_channel_layout_to_gst (*layouts, nbits_set, pos)) {
-+ guint64 mask;
-+
-+ if (gst_audio_channel_positions_to_mask (pos, nbits_set, FALSE,
-+ &mask)) {
-+ GstCaps *tmp =
-+ gst_caps_new_simple (mimetype, "channel-mask", GST_TYPE_BITMASK,
-+ mask,
-+ "channels", G_TYPE_INT, nbits_set, NULL);
-+
-+ gst_caps_append (caps, tmp);
-+ }
-+ }
-+ layouts++;
-+ }
-+ } else {
-+ if (maxchannels == 1)
-+ caps = gst_caps_new_simple (mimetype,
-+ "channels", G_TYPE_INT, maxchannels, NULL);
-+ else
-+ caps = gst_caps_new_simple (mimetype,
-+ "channels", GST_TYPE_INT_RANGE, 1, maxchannels, NULL);
-+ }
-+
- if (n_rates) {
- GValue list = { 0, };
-- GstStructure *structure;
-
- g_value_init (&list, GST_TYPE_LIST);
- for (i = 0; i < n_rates; i++) {
-@@ -457,21 +630,41 @@ gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
- gst_value_list_append_value (&list, &v);
- g_value_unset (&v);
- }
-- structure = gst_caps_get_structure (caps, 0);
-- gst_structure_set_value (structure, "rate", &list);
-+ gst_caps_set_value (caps, "rate", &list);
- g_value_unset (&list);
-- } else
-+ } else if (codec && codec->supported_samplerates
-+ && codec->supported_samplerates[0]) {
-+ GValue va = { 0, };
-+ GValue v = { 0, };
-+
-+ if (!codec->supported_samplerates[1]) {
-+ gst_caps_set_simple (caps, "rate", G_TYPE_INT,
-+ codec->supported_samplerates[0], NULL);
-+ } else {
-+ const int *rates = codec->supported_samplerates;
-+
-+ g_value_init (&va, GST_TYPE_LIST);
-+ g_value_init (&v, G_TYPE_INT);
-+
-+ while (*rates) {
-+ g_value_set_int (&v, *rates);
-+ gst_value_list_append_value (&va, &v);
-+ rates++;
-+ }
-+ gst_caps_set_value (caps, "rate", &va);
-+ g_value_unset (&va);
-+ g_value_unset (&v);
-+ }
-+ } else {
- gst_caps_set_simple (caps, "rate", GST_TYPE_INT_RANGE, 4000, 96000, NULL);
-+ }
- } else {
- caps = gst_caps_new_empty_simple (mimetype);
- }
-
-- for (i = 0; i < gst_caps_get_size (caps); i++) {
-- va_start (var_args, fieldname);
-- structure = gst_caps_get_structure (caps, i);
-- gst_structure_set_valist (structure, fieldname, var_args);
-- va_end (var_args);
-- }
-+ va_start (var_args, fieldname);
-+ gst_caps_set_simple_valist (caps, fieldname, var_args);
-+ va_end (var_args);
-
- return caps;
- }
-@@ -504,7 +697,7 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- switch (codec_id) {
- case CODEC_ID_MPEG1VIDEO:
- /* FIXME: bitrate */
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/mpeg",
-+ caps = gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/mpeg",
- "mpegversion", G_TYPE_INT, 1,
- "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
- break;
-@@ -512,9 +705,10 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- case CODEC_ID_MPEG2VIDEO:
- if (encode) {
- /* FIXME: bitrate */
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/mpeg",
-- "mpegversion", G_TYPE_INT, 2,
-- "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/mpeg",
-+ "mpegversion", G_TYPE_INT, 2, "systemstream", G_TYPE_BOOLEAN, FALSE,
-+ NULL);
- } else {
- /* decode both MPEG-1 and MPEG-2; width/height/fps are all in
- * the MPEG video stream headers, so may be omitted from caps. */
-@@ -530,23 +724,25 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
-
- case CODEC_ID_H263:
- if (encode) {
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-h263",
-- "variant", G_TYPE_STRING, "itu",
-- "h263version", G_TYPE_STRING, "h263", NULL);
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-h263", "variant", G_TYPE_STRING, "itu", "h263version",
-+ G_TYPE_STRING, "h263", NULL);
- } else {
- /* don't pass codec_id, we can decode other variants with the H263
- * decoder that don't have specific size requirements
- */
- caps =
-- gst_ff_vid_caps_new (context, CODEC_ID_NONE, encode, "video/x-h263",
-- "variant", G_TYPE_STRING, "itu", NULL);
-+ gst_ff_vid_caps_new (context, NULL, CODEC_ID_NONE, encode,
-+ "video/x-h263", "variant", G_TYPE_STRING, "itu", NULL);
- }
- break;
-
- case CODEC_ID_H263P:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-h263",
-- "variant", G_TYPE_STRING, "itu",
-- "h263version", G_TYPE_STRING, "h263p", NULL);
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-h263",
-+ "variant", G_TYPE_STRING, "itu", "h263version", G_TYPE_STRING,
-+ "h263p", NULL);
- if (encode && context) {
-
- gst_caps_set_simple (caps,
-@@ -560,13 +756,14 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
-
- case CODEC_ID_H263I:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-intel-h263",
-- "variant", G_TYPE_STRING, "intel", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-intel-h263", "variant", G_TYPE_STRING, "intel", NULL);
- break;
-
- case CODEC_ID_H261:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-h261", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-h261",
-+ NULL);
- break;
-
- case CODEC_ID_RV10:
-@@ -593,7 +790,7 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
-
- /* FIXME: context->sub_id must be filled in during decoding */
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode,
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
- "video/x-pn-realvideo", "systemstream", G_TYPE_BOOLEAN, FALSE,
- "rmversion", G_TYPE_INT, version, NULL);
- if (context) {
-@@ -609,20 +806,21 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
-
- case CODEC_ID_MP1:
- /* FIXME: bitrate */
-- caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg",
-+ caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
- "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 1, NULL);
- break;
-
- case CODEC_ID_MP2:
- /* FIXME: bitrate */
-- caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg",
-+ caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
- "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
- break;
-
- case CODEC_ID_MP3:
- if (encode) {
- /* FIXME: bitrate */
-- caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg",
-+ caps =
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
- "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
- } else {
- /* Decodes MPEG-1 layer 1/2/3. Samplerate, channels et al are
-@@ -635,14 +833,14 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
-
- case CODEC_ID_MUSEPACK7:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode,
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode,
- "audio/x-ffmpeg-parsed-musepack", "streamversion", G_TYPE_INT, 7,
- NULL);
- break;
-
- case CODEC_ID_MUSEPACK8:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode,
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode,
- "audio/x-ffmpeg-parsed-musepack", "streamversion", G_TYPE_INT, 8,
- NULL);
- break;
-@@ -650,41 +848,44 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- case CODEC_ID_AC3:
- /* FIXME: bitrate */
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-ac3", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-ac3",
-+ NULL);
- break;
-
- case CODEC_ID_EAC3:
- /* FIXME: bitrate */
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-eac3", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-eac3",
-+ NULL);
- break;
-
- case CODEC_ID_TRUEHD:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-true-hd",
-- NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode,
-+ "audio/x-true-hd", NULL);
- break;
-
- case CODEC_ID_ATRAC1:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode,
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode,
- "audio/x-vnd.sony.atrac1", NULL);
- break;
-
- case CODEC_ID_ATRAC3:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode,
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode,
- "audio/x-vnd.sony.atrac3", NULL);
- break;
-
- case CODEC_ID_DTS:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-dts", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dts",
-+ NULL);
- break;
-
- case CODEC_ID_APE:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode,
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode,
- "audio/x-ffmpeg-parsed-ape", NULL);
- if (context) {
- gst_caps_set_simple (caps,
-@@ -694,12 +895,14 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
-
- case CODEC_ID_MLP:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-mlp", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-mlp",
-+ NULL);
- break;
-
- case CODEC_ID_IMC:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-imc", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-imc",
-+ NULL);
- break;
-
- /* MJPEG is normal JPEG, Motion-JPEG and Quicktime MJPEG-A. MJPEGB
-@@ -710,18 +913,20 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- case CODEC_ID_MJPEG:
- case CODEC_ID_LJPEG:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "image/jpeg", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/jpeg",
-+ NULL);
- break;
-
- case CODEC_ID_SP5X:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/sp5x", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/sp5x",
-+ NULL);
- break;
-
- case CODEC_ID_MJPEGB:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-mjpeg-b",
-- NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-mjpeg-b", NULL);
- break;
-
- case CODEC_ID_MPEG4:
-@@ -731,41 +936,42 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- switch (context->codec_tag) {
- case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-divx",
-- "divxversion", G_TYPE_INT, 5, NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL);
- break;
- case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
- default:
- /* FIXME: bitrate */
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/mpeg",
-- "systemstream", G_TYPE_BOOLEAN, FALSE,
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/mpeg", "systemstream", G_TYPE_BOOLEAN, FALSE,
- "mpegversion", G_TYPE_INT, 4, NULL);
- break;
- }
- } else {
- /* The trick here is to separate xvid, divx, mpeg4, 3ivx et al */
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/mpeg",
-- "mpegversion", G_TYPE_INT, 4,
-- "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/mpeg",
-+ "mpegversion", G_TYPE_INT, 4, "systemstream", G_TYPE_BOOLEAN, FALSE,
-+ NULL);
- if (encode) {
-- gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
-- "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL));
-+ gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
-+ encode, "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL));
- } else {
-- gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
-- "video/x-divx", "divxversion", GST_TYPE_INT_RANGE, 4, 5,
-- NULL));
-- gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
-- "video/x-xvid", NULL));
-- gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
-- "video/x-3ivx", NULL));
-+ gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
-+ encode, "video/x-divx", "divxversion", GST_TYPE_INT_RANGE, 4,
-+ 5, NULL));
-+ gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
-+ encode, "video/x-xvid", NULL));
-+ gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
-+ encode, "video/x-3ivx", NULL));
- }
- }
- break;
-
- case CODEC_ID_RAWVIDEO:
- caps =
-- gst_ffmpeg_codectype_to_caps (AVMEDIA_TYPE_VIDEO, context, codec_id,
-- encode);
-+ gst_ffmpeg_codectype_to_video_caps (context, codec_id, encode, NULL);
- break;
-
- case CODEC_ID_MSMPEG4V1:
-@@ -775,11 +981,12 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- gint version = 41 + codec_id - CODEC_ID_MSMPEG4V1;
-
- /* encode-FIXME: bitrate */
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-msmpeg",
-- "msmpegversion", G_TYPE_INT, version, NULL);
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-msmpeg", "msmpegversion", G_TYPE_INT, version, NULL);
- if (!encode && codec_id == CODEC_ID_MSMPEG4V3) {
-- gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
-- "video/x-divx", "divxversion", G_TYPE_INT, 3, NULL));
-+ gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
-+ encode, "video/x-divx", "divxversion", G_TYPE_INT, 3, NULL));
- }
- }
- break;
-@@ -789,30 +996,34 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- {
- gint version = (codec_id == CODEC_ID_WMV1) ? 1 : 2;
-
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-wmv",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-wmv",
- "wmvversion", G_TYPE_INT, version, NULL);
- }
- break;
-
- case CODEC_ID_FLV1:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-flash-video",
-- "flvversion", G_TYPE_INT, 1, NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-flash-video", "flvversion", G_TYPE_INT, 1, NULL);
- break;
-
- case CODEC_ID_SVQ1:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-svq",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-svq",
- "svqversion", G_TYPE_INT, 1, NULL);
- break;
-
- case CODEC_ID_SVQ3:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-svq",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-svq",
- "svqversion", G_TYPE_INT, 3, NULL);
- break;
-
- case CODEC_ID_DVAUDIO:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-dv", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dv",
-+ NULL);
- break;
-
- case CODEC_ID_DVVIDEO:
-@@ -846,11 +1057,13 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- format = "I420";
- break;
- }
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-dv",
-- "systemstream", G_TYPE_BOOLEAN, FALSE,
-- "format", G_TYPE_STRING, format, NULL);
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-dv",
-+ "systemstream", G_TYPE_BOOLEAN, FALSE, "format", G_TYPE_STRING,
-+ format, NULL);
- } else {
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-dv",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-dv",
- "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
- }
- }
-@@ -862,21 +1075,24 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;
-
- if (context) {
-- caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-wma",
-- "wmaversion", G_TYPE_INT, version,
-- "block_align", G_TYPE_INT, context->block_align,
-- "bitrate", G_TYPE_INT, context->bit_rate, NULL);
-+ caps =
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
-+ "wmaversion", G_TYPE_INT, version, "block_align", G_TYPE_INT,
-+ context->block_align, "bitrate", G_TYPE_INT, context->bit_rate,
-+ NULL);
- } else {
-- caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-wma",
-- "wmaversion", G_TYPE_INT, version,
-- "block_align", GST_TYPE_INT_RANGE, 0, G_MAXINT,
-- "bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
-+ caps =
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
-+ "wmaversion", G_TYPE_INT, version, "block_align",
-+ GST_TYPE_INT_RANGE, 0, G_MAXINT, "bitrate", GST_TYPE_INT_RANGE, 0,
-+ G_MAXINT, NULL);
- }
- }
- break;
- case CODEC_ID_WMAPRO:
- {
-- caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-wma",
-+ caps =
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
- "wmaversion", G_TYPE_INT, 3, NULL);
- break;
- }
-@@ -884,7 +1100,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- case CODEC_ID_WMAVOICE:
- {
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-wms", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wms",
-+ NULL);
- break;
- }
-
-@@ -893,15 +1110,16 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- {
- gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;
-
-- caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-mace",
-+ caps =
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-mace",
- "maceversion", G_TYPE_INT, version, NULL);
- }
- break;
-
- case CODEC_ID_HUFFYUV:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-huffyuv",
-- NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-huffyuv", NULL);
- if (context) {
- gst_caps_set_simple (caps,
- "bpp", G_TYPE_INT, context->bits_per_coded_sample, NULL);
-@@ -910,84 +1128,93 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
-
- case CODEC_ID_CYUV:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode,
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
- "video/x-compressed-yuv", NULL);
- break;
-
- case CODEC_ID_H264:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-h264",
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-h264",
- "alignment", G_TYPE_STRING, "au", NULL);
- break;
-
- case CODEC_ID_INDEO5:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-indeo",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-indeo",
- "indeoversion", G_TYPE_INT, 5, NULL);
- break;
-
- case CODEC_ID_INDEO4:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-indeo",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-indeo",
- "indeoversion", G_TYPE_INT, 4, NULL);
- break;
-
- case CODEC_ID_INDEO3:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-indeo",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-indeo",
- "indeoversion", G_TYPE_INT, 3, NULL);
- break;
-
- case CODEC_ID_INDEO2:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-indeo",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-indeo",
- "indeoversion", G_TYPE_INT, 2, NULL);
- break;
-
- case CODEC_ID_FLASHSV:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode,
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
- "video/x-flash-screen", NULL);
- break;
-
- case CODEC_ID_VP3:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp3", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vp3",
-+ NULL);
- break;
-
- case CODEC_ID_VP5:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp5", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vp5",
-+ NULL);
- break;
-
- case CODEC_ID_VP6:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp6", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vp6",
-+ NULL);
- break;
-
- case CODEC_ID_VP6F:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp6-flash",
-- NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-vp6-flash", NULL);
- break;
-
- case CODEC_ID_VP6A:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp6-alpha",
-- NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-vp6-alpha", NULL);
- break;
-
- case CODEC_ID_VP8:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp8", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vp8",
-+ NULL);
- break;
-
- case CODEC_ID_THEORA:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-theora",
-- NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-theora", NULL);
- break;
-
- case CODEC_ID_AAC:
- {
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
-+ NULL);
-
- if (!encode) {
- GValue arr = { 0, };
-@@ -1029,45 +1256,50 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- break;
- }
- case CODEC_ID_AAC_LATM: /* LATM/LOAS AAC syntax */
-- caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg",
-+ caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
- "mpegversion", G_TYPE_INT, 4, "stream-format", G_TYPE_STRING, "loas",
- NULL);
- break;
-
- case CODEC_ID_ASV1:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-asus",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-asus",
- "asusversion", G_TYPE_INT, 1, NULL);
- break;
- case CODEC_ID_ASV2:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-asus",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-asus",
- "asusversion", G_TYPE_INT, 2, NULL);
- break;
-
- case CODEC_ID_FFV1:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-ffv",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-ffv",
- "ffvversion", G_TYPE_INT, 1, NULL);
- break;
-
- case CODEC_ID_4XM:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-4xm", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-4xm",
-+ NULL);
- break;
-
- case CODEC_ID_XAN_WC3:
- case CODEC_ID_XAN_WC4:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-xan",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-xan",
- "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
- break;
-
- case CODEC_ID_CLJR:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode,
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
- "video/x-cirrus-logic-accupak", NULL);
- break;
-
- case CODEC_ID_FRAPS:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-fraps",
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-fraps",
- NULL);
- break;
-
-@@ -1078,26 +1310,28 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- break;
-
- case CODEC_ID_VCR1:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-ati-vcr",
-- "vcrversion", G_TYPE_INT, 1, NULL);
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-ati-vcr", "vcrversion", G_TYPE_INT, 1, NULL);
- break;
-
- case CODEC_ID_RPZA:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-apple-video",
-- NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-apple-video", NULL);
- break;
-
- case CODEC_ID_CINEPAK:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-cinepak",
-- NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-cinepak", NULL);
- break;
-
- /* WS_VQA belogns here (order) */
-
- case CODEC_ID_MSRLE:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-rle",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-rle",
- "layout", G_TYPE_STRING, "microsoft", NULL);
- if (context) {
- gst_caps_set_simple (caps,
-@@ -1108,7 +1342,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- break;
-
- case CODEC_ID_QTRLE:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-rle",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-rle",
- "layout", G_TYPE_STRING, "quicktime", NULL);
- if (context) {
- gst_caps_set_simple (caps,
-@@ -1120,54 +1355,59 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
-
- case CODEC_ID_MSVIDEO1:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode,
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
- "video/x-msvideocodec", "msvideoversion", G_TYPE_INT, 1, NULL);
- break;
-
- case CODEC_ID_WMV3:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-wmv",
-- "wmvversion", G_TYPE_INT, 3, NULL);
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-wmv",
-+ "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WMV3", NULL);
- break;
- case CODEC_ID_VC1:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-wmv",
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-wmv",
- "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WVC1", NULL);
- break;
- case CODEC_ID_QDM2:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-qdm2", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-qdm2",
-+ NULL);
- break;
-
- case CODEC_ID_MSZH:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-mszh", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-mszh",
-+ NULL);
- break;
-
- case CODEC_ID_ZLIB:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-zlib", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-zlib",
-+ NULL);
- break;
-
- case CODEC_ID_TRUEMOTION1:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-truemotion",
-- "trueversion", G_TYPE_INT, 1, NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-truemotion", "trueversion", G_TYPE_INT, 1, NULL);
- break;
- case CODEC_ID_TRUEMOTION2:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-truemotion",
-- "trueversion", G_TYPE_INT, 2, NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-truemotion", "trueversion", G_TYPE_INT, 2, NULL);
- break;
-
- case CODEC_ID_ULTI:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-ultimotion",
-- NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-ultimotion", NULL);
- break;
-
- case CODEC_ID_TSCC:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-camtasia",
-- NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-camtasia", NULL);
- if (context) {
- gst_caps_set_simple (caps,
- "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
-@@ -1178,142 +1418,164 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
-
- case CODEC_ID_KMVC:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-kmvc", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-kmvc",
-+ NULL);
- break;
-
- case CODEC_ID_NUV:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-nuv", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-nuv",
-+ NULL);
- break;
-
- case CODEC_ID_GIF:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "image/gif", NULL);
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/gif",
-+ NULL);
- break;
-
- case CODEC_ID_PNG:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "image/png", NULL);
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/png",
-+ NULL);
- break;
-
- case CODEC_ID_PPM:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "image/ppm", NULL);
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/ppm",
-+ NULL);
- break;
-
- case CODEC_ID_PBM:
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, "image/pbm", NULL);
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/pbm",
-+ NULL);
- break;
-
- case CODEC_ID_PAM:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode,
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
- "image/x-portable-anymap", NULL);
- break;
-
- case CODEC_ID_PGM:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode,
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
- "image/x-portable-graymap", NULL);
- break;
-
- case CODEC_ID_PCX:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "image/x-pcx", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/x-pcx",
-+ NULL);
- break;
-
- case CODEC_ID_SGI:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "image/x-sgi", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/x-sgi",
-+ NULL);
- break;
-
- case CODEC_ID_TARGA:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "image/x-tga", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/x-tga",
-+ NULL);
- break;
-
- case CODEC_ID_TIFF:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "image/tiff", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/tiff",
-+ NULL);
- break;
-
- case CODEC_ID_SUNRAST:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "image/x-sun-raster",
-- NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "image/x-sun-raster", NULL);
- break;
-
- case CODEC_ID_SMC:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-smc", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-smc",
-+ NULL);
- break;
-
- case CODEC_ID_QDRAW:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-qdrw", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-qdrw",
-+ NULL);
- break;
-
- case CODEC_ID_DNXHD:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-dnxhd",
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-dnxhd",
- NULL);
- break;
-
- case CODEC_ID_PRORES:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-prores",
-- NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-prores", NULL);
- break;
-
- case CODEC_ID_MIMIC:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-mimic",
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-mimic",
- NULL);
- break;
-
- case CODEC_ID_VMNC:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vmnc", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vmnc",
-+ NULL);
- break;
-
- case CODEC_ID_TRUESPEECH:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-truespeech",
-- NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode,
-+ "audio/x-truespeech", NULL);
- break;
-
- case CODEC_ID_QCELP:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/qcelp", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/qcelp",
-+ NULL);
- break;
-
- case CODEC_ID_AMV:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-amv", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-amv",
-+ NULL);
- break;
-
- case CODEC_ID_AASC:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-aasc", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-aasc",
-+ NULL);
- break;
-
- case CODEC_ID_LOCO:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-loco", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-loco",
-+ NULL);
- break;
-
- case CODEC_ID_ZMBV:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-zmbv", NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-zmbv",
-+ NULL);
- break;
-
- case CODEC_ID_LAGARITH:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-lagarith",
-- NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-lagarith", NULL);
- break;
-
- case CODEC_ID_CSCD:
- caps =
-- gst_ff_vid_caps_new (context, codec_id, encode, "video/x-camstudio",
-- NULL);
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode,
-+ "video/x-camstudio", NULL);
- if (context) {
- gst_caps_set_simple (caps,
- "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
-@@ -1328,8 +1590,6 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- case CODEC_ID_FLIC:
- case CODEC_ID_VMDVIDEO:
- case CODEC_ID_VMDAUDIO:
-- case CODEC_ID_SONIC:
-- case CODEC_ID_SONIC_LS:
- case CODEC_ID_SNOW:
- case CODEC_ID_VIXL:
- case CODEC_ID_QPEG:
-@@ -1379,7 +1639,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- break;
- }
-
-- caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-raw",
-+ caps =
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-raw",
- "format", G_TYPE_STRING, gst_audio_format_to_string (format),
- "layout", G_TYPE_STRING, "interleaved", NULL);
- }
-@@ -1387,18 +1648,20 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
-
- case CODEC_ID_PCM_MULAW:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-mulaw",
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-mulaw",
- NULL);
- break;
-
- case CODEC_ID_PCM_ALAW:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-alaw", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-alaw",
-+ NULL);
- break;
-
- case CODEC_ID_ADPCM_G722:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/G722", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/G722",
-+ NULL);
- if (context)
- gst_caps_set_simple (caps,
- "block_align", G_TYPE_INT, context->block_align,
-@@ -1408,7 +1671,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- case CODEC_ID_ADPCM_G726:
- {
- /* the G726 decoder can also handle G721 */
-- caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-adpcm",
-+ caps =
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-adpcm",
- "layout", G_TYPE_STRING, "g726", NULL);
- if (context)
- gst_caps_set_simple (caps,
-@@ -1541,7 +1805,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
-
- /* FIXME: someone please check whether we need additional properties
- * in this caps definition. */
-- caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-adpcm",
-+ caps =
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-adpcm",
- "layout", G_TYPE_STRING, layout, NULL);
- if (context)
- gst_caps_set_simple (caps,
-@@ -1551,34 +1816,39 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- break;
-
- case CODEC_ID_AMR_NB:
-- caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/AMR", NULL);
-+ caps =
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/AMR",
-+ NULL);
- break;
-
- case CODEC_ID_AMR_WB:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/AMR-WB", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/AMR-WB",
-+ NULL);
- break;
-
- case CODEC_ID_GSM:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-gsm", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-gsm",
-+ NULL);
- break;
-
- case CODEC_ID_GSM_MS:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/ms-gsm", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/ms-gsm",
-+ NULL);
- break;
-
- case CODEC_ID_NELLYMOSER:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-nellymoser",
-- NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode,
-+ "audio/x-nellymoser", NULL);
- break;
-
- case CODEC_ID_SIPR:
- {
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-sipro",
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-sipro",
- NULL);
- if (context) {
- gst_caps_set_simple (caps,
-@@ -1610,7 +1880,7 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
-
- /* FIXME: properties? */
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode,
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode,
- "audio/x-pn-realaudio", "raversion", G_TYPE_INT, version, NULL);
- if (context) {
- gst_caps_set_simple (caps,
-@@ -1647,7 +1917,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
-
- /* FIXME: someone please check whether we need additional properties
- * in this caps definition. */
-- caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-dpcm",
-+ caps =
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dpcm",
- "layout", G_TYPE_STRING, layout, NULL);
- if (context)
- gst_caps_set_simple (caps,
-@@ -1662,7 +1933,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
-
- case CODEC_ID_ALAC:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-alac", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-alac",
-+ NULL);
- if (context) {
- gst_caps_set_simple (caps,
- "samplesize", G_TYPE_INT, context->bits_per_coded_sample, NULL);
-@@ -1677,6 +1949,10 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- }
- break;
-
-+ case CODEC_ID_S302M:
-+ caps = gst_caps_new_empty_simple ("audio/x-smpte-302m");
-+ break;
-+
- case CODEC_ID_DVD_SUBTITLE:
- case CODEC_ID_DVB_SUBTITLE:
- caps = NULL;
-@@ -1686,7 +1962,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- break;
- case CODEC_ID_TTA:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-tta", NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-tta",
-+ NULL);
- if (context) {
- gst_caps_set_simple (caps,
- "samplesize", G_TYPE_INT, context->bits_per_coded_sample, NULL);
-@@ -1694,8 +1971,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- break;
- case CODEC_ID_TWINVQ:
- caps =
-- gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-twin-vq",
-- NULL);
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode,
-+ "audio/x-twin-vq", NULL);
- break;
- default:
- GST_DEBUG ("Unknown codec ID %d, please add mapping here", codec_id);
-@@ -1714,12 +1991,14 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- switch (codec->type) {
- case AVMEDIA_TYPE_VIDEO:
- mime = g_strdup_printf ("video/x-gst-av-%s", codec->name);
-- caps = gst_ff_vid_caps_new (context, codec_id, encode, mime, NULL);
-+ caps =
-+ gst_ff_vid_caps_new (context, NULL, codec_id, encode, mime, NULL);
- g_free (mime);
- break;
- case AVMEDIA_TYPE_AUDIO:
- mime = g_strdup_printf ("audio/x-gst-av-%s", codec->name);
-- caps = gst_ff_aud_caps_new (context, codec_id, encode, mime, NULL);
-+ caps =
-+ gst_ff_aud_caps_new (context, NULL, codec_id, encode, mime, NULL);
- if (context)
- gst_caps_set_simple (caps,
- "block_align", G_TYPE_INT, context->block_align,
-@@ -1743,11 +2022,6 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- gst_buffer_unref (data);
- }
-
-- /* palette */
-- if (context) {
-- gst_ffmpeg_set_palette (caps, context);
-- }
--
- GST_LOG ("caps for codec_id=%d: %" GST_PTR_FORMAT, codec_id, caps);
-
- } else {
-@@ -1764,7 +2038,7 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- * See below for usefullness
- */
-
--GstCaps *
-+static GstCaps *
- gst_ffmpeg_pixfmt_to_caps (enum PixelFormat pix_fmt, AVCodecContext * context,
- enum CodecID codec_id)
- {
-@@ -1774,7 +2048,7 @@ gst_ffmpeg_pixfmt_to_caps (enum PixelFormat pix_fmt, AVCodecContext * context,
- format = gst_ffmpeg_pixfmt_to_videoformat (pix_fmt);
-
- if (format != GST_VIDEO_FORMAT_UNKNOWN) {
-- caps = gst_ff_vid_caps_new (context, codec_id, TRUE, "video/x-raw",
-+ caps = gst_ff_vid_caps_new (context, NULL, codec_id, TRUE, "video/x-raw",
- "format", G_TYPE_STRING, gst_video_format_to_string (format), NULL);
- }
-
-@@ -1787,41 +2061,55 @@ gst_ffmpeg_pixfmt_to_caps (enum PixelFormat pix_fmt, AVCodecContext * context,
- return caps;
- }
-
--/* Convert a FFMPEG Sample Format and optional AVCodecContext
-- * to a GstCaps. If the context is ommitted, no fixed values
-- * for video/audio size will be included in the GstCaps
-- *
-- * See below for usefullness
-- */
--
--static GstCaps *
--gst_ffmpeg_smpfmt_to_caps (enum AVSampleFormat sample_fmt,
-- AVCodecContext * context, enum CodecID codec_id)
-+GstAudioFormat
-+gst_ffmpeg_smpfmt_to_audioformat (enum AVSampleFormat sample_fmt)
- {
-- GstCaps *caps = NULL;
-- GstAudioFormat format;
--
- switch (sample_fmt) {
-+ case AV_SAMPLE_FMT_U8:
-+ case AV_SAMPLE_FMT_U8P:
-+ return GST_AUDIO_FORMAT_U8;
-+ break;
- case AV_SAMPLE_FMT_S16:
-- format = GST_AUDIO_FORMAT_S16;
-+ case AV_SAMPLE_FMT_S16P:
-+ return GST_AUDIO_FORMAT_S16;
- break;
- case AV_SAMPLE_FMT_S32:
-- format = GST_AUDIO_FORMAT_S32;
-+ case AV_SAMPLE_FMT_S32P:
-+ return GST_AUDIO_FORMAT_S32;
- break;
- case AV_SAMPLE_FMT_FLT:
-- format = GST_AUDIO_FORMAT_F32;
-+ case AV_SAMPLE_FMT_FLTP:
-+ return GST_AUDIO_FORMAT_F32;
- break;
- case AV_SAMPLE_FMT_DBL:
-- format = GST_AUDIO_FORMAT_F64;
-+ case AV_SAMPLE_FMT_DBLP:
-+ return GST_AUDIO_FORMAT_F64;
- break;
- default:
- /* .. */
-- format = GST_AUDIO_FORMAT_UNKNOWN;
-+ return GST_AUDIO_FORMAT_UNKNOWN;
- break;
- }
-+}
-+
-+/* Convert a FFMPEG Sample Format and optional AVCodecContext
-+ * to a GstCaps. If the context is ommitted, no fixed values
-+ * for video/audio size will be included in the GstCaps
-+ *
-+ * See below for usefullness
-+ */
-+
-+static GstCaps *
-+gst_ffmpeg_smpfmt_to_caps (enum AVSampleFormat sample_fmt,
-+ AVCodecContext * context, AVCodec * codec, enum CodecID codec_id)
-+{
-+ GstCaps *caps = NULL;
-+ GstAudioFormat format;
-+
-+ format = gst_ffmpeg_smpfmt_to_audioformat (sample_fmt);
-
- if (format != GST_AUDIO_FORMAT_UNKNOWN) {
-- caps = gst_ff_aud_caps_new (context, codec_id, TRUE, "audio/x-raw",
-+ caps = gst_ff_aud_caps_new (context, codec, codec_id, TRUE, "audio/x-raw",
- "format", G_TYPE_STRING, gst_audio_format_to_string (format),
- "layout", G_TYPE_STRING, "interleaved", NULL);
- GST_LOG ("caps for sample_fmt=%d: %" GST_PTR_FORMAT, sample_fmt, caps);
-@@ -1832,6 +2120,22 @@ gst_ffmpeg_smpfmt_to_caps (enum AVSampleFormat sample_fmt,
- return caps;
- }
-
-+static gboolean
-+caps_has_field (GstCaps * caps, const gchar * field)
-+{
-+ guint i, n;
-+
-+ n = gst_caps_get_size (caps);
-+ for (i = 0; i < n; i++) {
-+ GstStructure *s = gst_caps_get_structure (caps, i);
-+
-+ if (gst_structure_has_field (s, field))
-+ return TRUE;
-+ }
-+
-+ return FALSE;
-+}
-+
- GstCaps *
- gst_ffmpeg_codectype_to_audio_caps (AVCodecContext * context,
- enum CodecID codec_id, gboolean encode, AVCodec * codec)
-@@ -1846,32 +2150,17 @@ gst_ffmpeg_codectype_to_audio_caps (AVCodecContext * context,
-
- if (context) {
- /* Specific codec context */
-- caps = gst_ffmpeg_smpfmt_to_caps (context->sample_fmt, context, codec_id);
-- } else if (codec && codec->sample_fmts) {
-- GstCaps *temp;
-- int i;
--
-- caps = gst_caps_new_empty ();
-- for (i = 0; codec->sample_fmts[i] != -1; i++) {
-- temp =
-- gst_ffmpeg_smpfmt_to_caps (codec->sample_fmts[i], context, codec_id);
-- if (temp != NULL)
-- gst_caps_append (caps, temp);
-- }
-+ caps =
-+ gst_ffmpeg_smpfmt_to_caps (context->sample_fmt, context, codec,
-+ codec_id);
- } else {
-- GstCaps *temp;
-- enum AVSampleFormat i;
-- AVCodecContext ctx = { 0, };
--
-- ctx.channels = -1;
-- caps = gst_caps_new_empty ();
-- for (i = 0; i <= AV_SAMPLE_FMT_DBL; i++) {
-- temp = gst_ffmpeg_smpfmt_to_caps (i, encode ? &ctx : NULL, codec_id);
-- if (temp != NULL) {
-- gst_caps_append (caps, temp);
-- }
-- }
-+ caps = gst_ff_aud_caps_new (context, codec, codec_id, encode, "audio/x-raw",
-+ "layout", G_TYPE_STRING, "interleaved", NULL);
-+ if (!caps_has_field (caps, "format"))
-+ gst_ffmpeg_audio_set_sample_fmts (caps,
-+ codec ? codec->sample_fmts : NULL);
- }
-+
- return caps;
- }
-
-@@ -1887,50 +2176,12 @@ gst_ffmpeg_codectype_to_video_caps (AVCodecContext * context,
- if (context) {
- caps = gst_ffmpeg_pixfmt_to_caps (context->pix_fmt, context, codec_id);
- } else {
-- GstCaps *temp;
-- enum PixelFormat i;
-- AVCodecContext ctx = { 0, };
--
-- caps = gst_caps_new_empty ();
-- for (i = 0; i < PIX_FMT_NB; i++) {
-- ctx.width = -1;
-- ctx.pix_fmt = i;
-- temp = gst_ffmpeg_pixfmt_to_caps (i, encode ? &ctx : NULL, codec_id);
-- if (temp != NULL) {
-- gst_caps_append (caps, temp);
-- }
-- }
-- }
-- return caps;
--}
--
--/* Convert a FFMPEG codec Type and optional AVCodecContext
-- * to a GstCaps. If the context is ommitted, no fixed values
-- * for video/audio size will be included in the GstCaps
-- *
-- * AVMediaType is primarily meant for uncompressed data GstCaps!
-- */
--
--GstCaps *
--gst_ffmpeg_codectype_to_caps (enum AVMediaType codec_type,
-- AVCodecContext * context, enum CodecID codec_id, gboolean encode)
--{
-- GstCaps *caps;
--
-- switch (codec_type) {
-- case AVMEDIA_TYPE_VIDEO:
-- caps =
-- gst_ffmpeg_codectype_to_video_caps (context, codec_id, encode, NULL);
-- break;
-- case AVMEDIA_TYPE_AUDIO:
-- caps =
-- gst_ffmpeg_codectype_to_audio_caps (context, codec_id, encode, NULL);
-- break;
-- default:
-- caps = NULL;
-- break;
-+ caps =
-+ gst_ff_vid_caps_new (context, codec, codec_id, encode, "video/x-raw",
-+ NULL);
-+ if (!caps_has_field (caps, "format"))
-+ gst_ffmpeg_video_set_pix_fmts (caps, codec ? codec->pix_fmts : NULL);
- }
--
- return caps;
- }
-
-@@ -2033,8 +2284,6 @@ gst_ffmpeg_caps_to_pixfmt (const GstCaps * caps,
- context->sample_aspect_ratio.num);
- }
-
-- gst_ffmpeg_get_palette (caps, context);
--
- if (!raw)
- return;
-
-@@ -2182,6 +2431,11 @@ static const PixToFmt pixtofmttable[] = {
- {GST_VIDEO_FORMAT_I420_10BE, PIX_FMT_YUV420P10BE},
- {GST_VIDEO_FORMAT_I422_10LE, PIX_FMT_YUV422P10LE},
- {GST_VIDEO_FORMAT_I422_10BE, PIX_FMT_YUV422P10BE},
-+ {GST_VIDEO_FORMAT_Y444_10LE, PIX_FMT_YUV444P10LE},
-+ {GST_VIDEO_FORMAT_Y444_10BE, PIX_FMT_YUV444P10BE},
-+ {GST_VIDEO_FORMAT_GBR, PIX_FMT_GBRP},
-+ {GST_VIDEO_FORMAT_GBR_10LE, PIX_FMT_GBRP10LE},
-+ {GST_VIDEO_FORMAT_GBR_10BE, PIX_FMT_GBRP10BE},
- };
-
- GstVideoFormat
-@@ -2230,6 +2484,112 @@ gst_ffmpeg_videoinfo_to_context (GstVideoInfo * info, AVCodecContext * context)
- gst_ffmpeg_videoformat_to_pixfmt (GST_VIDEO_INFO_FORMAT (info));
- }
-
-+void
-+gst_ffmpeg_audioinfo_to_context (GstAudioInfo * info, AVCodecContext * context)
-+{
-+ const AVCodec *codec;
-+ const enum AVSampleFormat *smpl_fmts;
-+ enum AVSampleFormat smpl_fmt = -1;
-+
-+ context->channels = info->channels;
-+ context->sample_rate = info->rate;
-+ context->channel_layout =
-+ gst_ffmpeg_channel_positions_to_layout (info->position, info->channels);
-+
-+ codec = context->codec;
-+
-+ smpl_fmts = codec->sample_fmts;
-+
-+ switch (info->finfo->format) {
-+ case GST_AUDIO_FORMAT_F32:
-+ if (smpl_fmts) {
-+ while (*smpl_fmts != -1) {
-+ if (*smpl_fmts == AV_SAMPLE_FMT_FLT) {
-+ smpl_fmt = *smpl_fmts;
-+ break;
-+ } else if (*smpl_fmts == AV_SAMPLE_FMT_FLTP) {
-+ smpl_fmt = *smpl_fmts;
-+ }
-+
-+ smpl_fmts++;
-+ }
-+ } else {
-+ smpl_fmt = AV_SAMPLE_FMT_FLT;
-+ }
-+ break;
-+ case GST_AUDIO_FORMAT_F64:
-+ if (smpl_fmts) {
-+ while (*smpl_fmts != -1) {
-+ if (*smpl_fmts == AV_SAMPLE_FMT_DBL) {
-+ smpl_fmt = *smpl_fmts;
-+ break;
-+ } else if (*smpl_fmts == AV_SAMPLE_FMT_DBLP) {
-+ smpl_fmt = *smpl_fmts;
-+ }
-+
-+ smpl_fmts++;
-+ }
-+ } else {
-+ smpl_fmt = AV_SAMPLE_FMT_DBL;
-+ }
-+ break;
-+ case GST_AUDIO_FORMAT_S32:
-+ if (smpl_fmts) {
-+ while (*smpl_fmts != -1) {
-+ if (*smpl_fmts == AV_SAMPLE_FMT_S32) {
-+ smpl_fmt = *smpl_fmts;
-+ break;
-+ } else if (*smpl_fmts == AV_SAMPLE_FMT_S32P) {
-+ smpl_fmt = *smpl_fmts;
-+ }
-+
-+ smpl_fmts++;
-+ }
-+ } else {
-+ smpl_fmt = AV_SAMPLE_FMT_S32;
-+ }
-+ break;
-+ case GST_AUDIO_FORMAT_S16:
-+ if (smpl_fmts) {
-+ while (*smpl_fmts != -1) {
-+ if (*smpl_fmts == AV_SAMPLE_FMT_S16) {
-+ smpl_fmt = *smpl_fmts;
-+ break;
-+ } else if (*smpl_fmts == AV_SAMPLE_FMT_S16P) {
-+ smpl_fmt = *smpl_fmts;
-+ }
-+
-+ smpl_fmts++;
-+ }
-+ } else {
-+ smpl_fmt = AV_SAMPLE_FMT_S16;
-+ }
-+ break;
-+ case GST_AUDIO_FORMAT_U8:
-+ if (smpl_fmts) {
-+ while (*smpl_fmts != -1) {
-+ if (*smpl_fmts == AV_SAMPLE_FMT_U8) {
-+ smpl_fmt = *smpl_fmts;
-+ break;
-+ } else if (*smpl_fmts == AV_SAMPLE_FMT_U8P) {
-+ smpl_fmt = *smpl_fmts;
-+ }
-+
-+ smpl_fmts++;
-+ }
-+ } else {
-+ smpl_fmt = AV_SAMPLE_FMT_U8;
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ g_assert (smpl_fmt != -1);
-+
-+ context->sample_fmt = smpl_fmt;
-+}
-+
- /* Convert a GstCaps and a FFMPEG codec Type to a
- * AVCodecContext. If the context is ommitted, no fixed values
- * for video/audio size will be included in the context
-diff --git a/ext/libav/gstavcodecmap.h b/ext/libav/gstavcodecmap.h
-index 52e5bec..01ce9b1 100644
---- a/ext/libav/gstavcodecmap.h
-+++ b/ext/libav/gstavcodecmap.h
-@@ -13,8 +13,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
- #ifndef __GST_FFMPEG_CODECMAP_H__
-@@ -41,11 +41,6 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
- */
-
- GstCaps *
--gst_ffmpeg_codectype_to_caps (enum AVMediaType codec_type,
-- AVCodecContext *context,
-- enum CodecID codec_id,
-- gboolean encode);
--GstCaps *
- gst_ffmpeg_codectype_to_audio_caps (AVCodecContext *context,
- enum CodecID codec_id,
- gboolean encode,
-@@ -91,9 +86,15 @@ void
- gst_ffmpeg_videoinfo_to_context (GstVideoInfo *info,
- AVCodecContext *context);
-
-+void
-+gst_ffmpeg_audioinfo_to_context (GstAudioInfo *info,
-+ AVCodecContext *context);
-+
- GstVideoFormat gst_ffmpeg_pixfmt_to_videoformat (enum PixelFormat pixfmt);
- enum PixelFormat gst_ffmpeg_videoformat_to_pixfmt (GstVideoFormat format);
-
-+GstAudioFormat gst_ffmpeg_smpfmt_to_audioformat (enum AVSampleFormat sample_fmt);
-+
- /*
- * _formatid_to_caps () is meant for muxers/demuxers, it
- * transforms a name (ffmpeg way of ID'ing these, why don't
-@@ -104,19 +105,6 @@ enum PixelFormat gst_ffmpeg_videoformat_to_pixfmt (GstVideoFormat format);
- GstCaps *
- gst_ffmpeg_formatid_to_caps (const gchar *format_name);
-
--GstVideoFormat
--gst_ffmpeg_pixfmt_to_video_format (enum PixelFormat pix_fmt);
--
--/* Convert a FFMPEG Pixel Format and optional AVCodecContext
-- * to a GstCaps. If the context is ommitted, no fixed values
-- * for video/audio size will be included in the GstCaps
-- *
-- * See below for usefullness
-- */
--
--GstCaps *
--gst_ffmpeg_pixfmt_to_caps (enum PixelFormat pix_fmt, AVCodecContext * context, enum CodecID codec_id);
--
- /*
- * _formatid_get_codecids () can be used to get the codecIDs
- * (CODEC_ID_NONE-terminated list) that fit that specific
-@@ -131,7 +119,7 @@ gst_ffmpeg_formatid_get_codecids (const gchar *format_name,
-
-
- gboolean
--gst_ffmpeg_channel_layout_to_gst (AVCodecContext * context,
-+gst_ffmpeg_channel_layout_to_gst (guint64 channel_layout, gint channels,
- GstAudioChannelPosition * pos);
-
- #endif /* __GST_FFMPEG_CODECMAP_H__ */
-diff --git a/ext/libav/gstavdec.c b/ext/libav/gstavdec.c
-deleted file mode 100644
-index 8291099..0000000
---- a/ext/libav/gstavdec.c
-+++ /dev/null
-@@ -1,1457 +0,0 @@
--/* 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 <assert.h>
--#include <string.h>
--
--#include <libavcodec/avcodec.h>
--
--#include <gst/gst.h>
--
--#include "gstav.h"
--#include "gstavcodecmap.h"
--#include "gstavutils.h"
--
--GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE);
--
--typedef struct _GstFFMpegAudDec GstFFMpegAudDec;
--
--#define MAX_TS_MASK 0xff
--
--/* for each incomming buffer we keep all timing info in a structure like this.
-- * We keep a circular array of these structures around to store the timing info.
-- * The index in the array is what we pass as opaque data (to pictures) and
-- * pts (to parsers) so that ffmpeg can remember them for us. */
--typedef struct
--{
-- gint idx;
-- GstClockTime dts;
-- GstClockTime pts;
-- GstClockTime duration;
-- gint64 offset;
--} GstTSInfo;
--
--struct _GstFFMpegAudDec
--{
-- GstElement element;
--
-- /* We need to keep track of our pads, so we do so here. */
-- GstPad *srcpad;
-- GstPad *sinkpad;
--
-- /* decoding */
-- AVCodecContext *context;
-- gboolean opened;
--
-- /* current output format */
-- gint channels, samplerate, depth;
-- GstAudioChannelPosition ffmpeg_layout[64], gst_layout[64];
--
-- gboolean discont;
-- gboolean clear_ts;
--
-- /* for tracking DTS/PTS */
-- GstClockTime next_out;
--
-- /* parsing */
-- gboolean turnoff_parser; /* used for turning off aac raw parsing
-- * See bug #566250 */
-- AVCodecParserContext *pctx;
-- GstBuffer *pcache;
--
-- /* clipping segment */
-- GstSegment segment;
--
-- GstTSInfo ts_info[MAX_TS_MASK + 1];
-- gint ts_idx;
--
-- /* reverse playback queue */
-- GList *queued;
--
-- /* prevent reopening the decoder on GST_EVENT_CAPS when caps are same as last time. */
-- GstCaps *last_caps;
--};
--
--typedef struct _GstFFMpegAudDecClass GstFFMpegAudDecClass;
--
--struct _GstFFMpegAudDecClass
--{
-- GstElementClass parent_class;
--
-- AVCodec *in_plugin;
-- GstPadTemplate *srctempl, *sinktempl;
--};
--
--#define GST_TS_INFO_NONE &ts_info_none
--static const GstTSInfo ts_info_none = { -1, -1, -1, -1 };
--
--static const GstTSInfo *
--gst_ts_info_store (GstFFMpegAudDec * dec, GstClockTime dts, GstClockTime pts,
-- GstClockTime duration, gint64 offset)
--{
-- gint idx = dec->ts_idx;
-- dec->ts_info[idx].idx = idx;
-- dec->ts_info[idx].dts = dts;
-- dec->ts_info[idx].pts = pts;
-- dec->ts_info[idx].duration = duration;
-- dec->ts_info[idx].offset = offset;
-- dec->ts_idx = (idx + 1) & MAX_TS_MASK;
--
-- return &dec->ts_info[idx];
--}
--
--static const GstTSInfo *
--gst_ts_info_get (GstFFMpegAudDec * dec, gint idx)
--{
-- if (G_UNLIKELY (idx < 0 || idx > MAX_TS_MASK))
-- return GST_TS_INFO_NONE;
--
-- return &dec->ts_info[idx];
--}
--
--#define GST_TYPE_FFMPEGDEC \
-- (gst_ffmpegauddec_get_type())
--#define GST_FFMPEGDEC(obj) \
-- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGDEC,GstFFMpegAudDec))
--#define GST_FFMPEGAUDDEC_CLASS(klass) \
-- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGDEC,GstFFMpegAudDecClass))
--#define GST_IS_FFMPEGDEC(obj) \
-- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGDEC))
--#define GST_IS_FFMPEGAUDDEC_CLASS(klass) \
-- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGDEC))
--
--/* A number of function prototypes are given so we can refer to them later. */
--static void gst_ffmpegauddec_base_init (GstFFMpegAudDecClass * klass);
--static void gst_ffmpegauddec_class_init (GstFFMpegAudDecClass * klass);
--static void gst_ffmpegauddec_init (GstFFMpegAudDec * ffmpegdec);
--static void gst_ffmpegauddec_finalize (GObject * object);
--
--static gboolean gst_ffmpegauddec_setcaps (GstFFMpegAudDec * ffmpegdec,
-- GstCaps * caps);
--static gboolean gst_ffmpegauddec_sink_event (GstPad * pad, GstObject * parent,
-- GstEvent * event);
--static gboolean gst_ffmpegauddec_sink_query (GstPad * pad, GstObject * parent,
-- GstQuery * query);
--static GstFlowReturn gst_ffmpegauddec_chain (GstPad * pad, GstObject * parent,
-- GstBuffer * buf);
--
--static GstStateChangeReturn gst_ffmpegauddec_change_state (GstElement * element,
-- GstStateChange transition);
--
--static gboolean gst_ffmpegauddec_negotiate (GstFFMpegAudDec * ffmpegdec,
-- gboolean force);
--
--static void gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec);
--
--#define GST_FFDEC_PARAMS_QDATA g_quark_from_static_string("avdec-params")
--
--static GstElementClass *parent_class = NULL;
--
--static void
--gst_ffmpegauddec_base_init (GstFFMpegAudDecClass * klass)
--{
-- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-- GstPadTemplate *sinktempl, *srctempl;
-- GstCaps *sinkcaps, *srccaps;
-- AVCodec *in_plugin;
-- gchar *longname, *description;
--
-- in_plugin =
-- (AVCodec *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
-- GST_FFDEC_PARAMS_QDATA);
-- g_assert (in_plugin != NULL);
--
-- /* construct the element details struct */
-- longname = g_strdup_printf ("libav %s decoder", in_plugin->long_name);
-- description = g_strdup_printf ("libav %s decoder", in_plugin->name);
-- gst_element_class_set_metadata (element_class, longname,
-- "Codec/Decoder/Audio", description,
-- "Wim Taymans <wim.taymans@gmail.com>, "
-- "Ronald Bultje <rbultje@ronald.bitfreak.net>, "
-- "Edward Hervey <bilboed@bilboed.com>");
-- g_free (longname);
-- g_free (description);
--
-- /* get the caps */
-- sinkcaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, FALSE);
-- if (!sinkcaps) {
-- GST_DEBUG ("Couldn't get sink caps for decoder '%s'", in_plugin->name);
-- sinkcaps = gst_caps_from_string ("unknown/unknown");
-- }
-- srccaps = gst_ffmpeg_codectype_to_audio_caps (NULL,
-- in_plugin->id, FALSE, in_plugin);
-- if (!srccaps) {
-- GST_DEBUG ("Couldn't get source caps for decoder '%s'", in_plugin->name);
-- srccaps = gst_caps_from_string ("unknown/unknown");
-- }
--
-- /* pad templates */
-- sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
-- GST_PAD_ALWAYS, sinkcaps);
-- srctempl = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, srccaps);
--
-- gst_element_class_add_pad_template (element_class, srctempl);
-- gst_element_class_add_pad_template (element_class, sinktempl);
--
-- klass->in_plugin = in_plugin;
-- klass->srctempl = srctempl;
-- klass->sinktempl = sinktempl;
--}
--
--static void
--gst_ffmpegauddec_class_init (GstFFMpegAudDecClass * klass)
--{
-- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-- GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
--
-- parent_class = g_type_class_peek_parent (klass);
--
-- gobject_class->finalize = gst_ffmpegauddec_finalize;
--
-- gstelement_class->change_state = gst_ffmpegauddec_change_state;
--}
--
--static void
--gst_ffmpegauddec_init (GstFFMpegAudDec * ffmpegdec)
--{
-- GstFFMpegAudDecClass *oclass;
--
-- oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
--
-- /* setup pads */
-- ffmpegdec->sinkpad = gst_pad_new_from_template (oclass->sinktempl, "sink");
-- gst_pad_set_query_function (ffmpegdec->sinkpad,
-- GST_DEBUG_FUNCPTR (gst_ffmpegauddec_sink_query));
-- gst_pad_set_event_function (ffmpegdec->sinkpad,
-- GST_DEBUG_FUNCPTR (gst_ffmpegauddec_sink_event));
-- gst_pad_set_chain_function (ffmpegdec->sinkpad,
-- GST_DEBUG_FUNCPTR (gst_ffmpegauddec_chain));
-- gst_element_add_pad (GST_ELEMENT (ffmpegdec), ffmpegdec->sinkpad);
--
-- ffmpegdec->srcpad = gst_pad_new_from_template (oclass->srctempl, "src");
-- gst_pad_use_fixed_caps (ffmpegdec->srcpad);
-- gst_element_add_pad (GST_ELEMENT (ffmpegdec), ffmpegdec->srcpad);
--
-- /* some ffmpeg data */
-- ffmpegdec->context = avcodec_alloc_context ();
-- ffmpegdec->pctx = NULL;
-- ffmpegdec->pcache = NULL;
-- ffmpegdec->opened = FALSE;
--
-- gst_segment_init (&ffmpegdec->segment, GST_FORMAT_TIME);
--}
--
--static void
--gst_ffmpegauddec_finalize (GObject * object)
--{
-- GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) object;
--
-- if (ffmpegdec->context != NULL)
-- av_free (ffmpegdec->context);
--
-- G_OBJECT_CLASS (parent_class)->finalize (object);
--}
--
--static void
--gst_ffmpegauddec_reset_ts (GstFFMpegAudDec * ffmpegdec)
--{
-- ffmpegdec->next_out = GST_CLOCK_TIME_NONE;
--}
--
--/* with LOCK */
--static void
--gst_ffmpegauddec_close (GstFFMpegAudDec * ffmpegdec)
--{
-- if (!ffmpegdec->opened)
-- return;
--
-- GST_LOG_OBJECT (ffmpegdec, "closing libav codec");
--
-- gst_caps_replace (&ffmpegdec->last_caps, NULL);
--
-- if (ffmpegdec->context->priv_data)
-- gst_ffmpeg_avcodec_close (ffmpegdec->context);
-- ffmpegdec->opened = FALSE;
--
-- if (ffmpegdec->context->palctrl) {
-- av_free (ffmpegdec->context->palctrl);
-- ffmpegdec->context->palctrl = NULL;
-- }
--
-- if (ffmpegdec->context->extradata) {
-- av_free (ffmpegdec->context->extradata);
-- ffmpegdec->context->extradata = NULL;
-- }
--
-- if (ffmpegdec->pctx) {
-- if (ffmpegdec->pcache) {
-- gst_buffer_unref (ffmpegdec->pcache);
-- ffmpegdec->pcache = NULL;
-- }
-- av_parser_close (ffmpegdec->pctx);
-- ffmpegdec->pctx = NULL;
-- }
--}
--
--/* with LOCK */
--static gboolean
--gst_ffmpegauddec_open (GstFFMpegAudDec * ffmpegdec)
--{
-- GstFFMpegAudDecClass *oclass;
--
-- oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
--
-- if (gst_ffmpeg_avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0)
-- goto could_not_open;
--
-- ffmpegdec->opened = TRUE;
--
-- GST_LOG_OBJECT (ffmpegdec, "Opened libav codec %s, id %d",
-- oclass->in_plugin->name, oclass->in_plugin->id);
--
-- if (!ffmpegdec->turnoff_parser) {
-- ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
-- if (ffmpegdec->pctx)
-- GST_LOG_OBJECT (ffmpegdec, "Using parser %p", ffmpegdec->pctx);
-- else
-- GST_LOG_OBJECT (ffmpegdec, "No parser for codec");
-- } else {
-- GST_LOG_OBJECT (ffmpegdec, "Parser deactivated for format");
-- }
--
-- ffmpegdec->samplerate = 0;
-- ffmpegdec->channels = 0;
-- ffmpegdec->depth = 0;
--
-- gst_ffmpegauddec_reset_ts (ffmpegdec);
--
-- return TRUE;
--
-- /* ERRORS */
--could_not_open:
-- {
-- gst_ffmpegauddec_close (ffmpegdec);
-- GST_DEBUG_OBJECT (ffmpegdec, "avdec_%s: Failed to open libav codec",
-- oclass->in_plugin->name);
-- return FALSE;
-- }
--}
--
--static gboolean
--gst_ffmpegauddec_setcaps (GstFFMpegAudDec * ffmpegdec, GstCaps * caps)
--{
-- GstFFMpegAudDecClass *oclass;
-- GstStructure *structure;
-- gboolean ret = TRUE;
--
-- oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
--
-- GST_DEBUG_OBJECT (ffmpegdec, "setcaps called");
--
-- GST_OBJECT_LOCK (ffmpegdec);
--
-- /* close old session */
-- if (ffmpegdec->opened) {
-- GST_OBJECT_UNLOCK (ffmpegdec);
-- gst_ffmpegauddec_drain (ffmpegdec);
-- GST_OBJECT_LOCK (ffmpegdec);
-- gst_ffmpegauddec_close (ffmpegdec);
--
-- /* and reset the defaults that were set when a context is created */
-- avcodec_get_context_defaults (ffmpegdec->context);
-- }
--
-- /* default is to let format decide if it needs a parser */
-- ffmpegdec->turnoff_parser = FALSE;
--
-- /* get size and so */
-- gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
-- oclass->in_plugin->type, caps, ffmpegdec->context);
--
-- /* get pixel aspect ratio if it's set */
-- structure = gst_caps_get_structure (caps, 0);
--
-- /* for AAC we only use av_parse if not on stream-format==raw or ==loas */
-- if (oclass->in_plugin->id == CODEC_ID_AAC
-- || oclass->in_plugin->id == CODEC_ID_AAC_LATM) {
-- const gchar *format = gst_structure_get_string (structure, "stream-format");
--
-- if (format == NULL || strcmp (format, "raw") == 0) {
-- ffmpegdec->turnoff_parser = TRUE;
-- }
-- }
--
-- /* for FLAC, don't parse if it's already parsed */
-- if (oclass->in_plugin->id == CODEC_ID_FLAC) {
-- if (gst_structure_has_field (structure, "streamheader"))
-- ffmpegdec->turnoff_parser = TRUE;
-- }
--
-- /* workaround encoder bugs */
-- ffmpegdec->context->workaround_bugs |= FF_BUG_AUTODETECT;
-- ffmpegdec->context->error_recognition = 1;
--
-- /* open codec - we don't select an output pix_fmt yet,
-- * simply because we don't know! We only get it
-- * during playback... */
-- if (!gst_ffmpegauddec_open (ffmpegdec))
-- goto open_failed;
--
--done:
-- GST_OBJECT_UNLOCK (ffmpegdec);
--
-- return ret;
--
-- /* ERRORS */
--open_failed:
-- {
-- GST_DEBUG_OBJECT (ffmpegdec, "Failed to open");
-- ret = FALSE;
-- goto done;
-- }
--}
--
--static gboolean
--gst_ffmpegauddec_negotiate (GstFFMpegAudDec * ffmpegdec, gboolean force)
--{
-- GstFFMpegAudDecClass *oclass;
-- GstCaps *caps;
-- gint depth;
-- GstAudioChannelPosition pos[64] = { 0, };
--
-- oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
--
-- depth = av_smp_format_depth (ffmpegdec->context->sample_fmt);
-- gst_ffmpeg_channel_layout_to_gst (ffmpegdec->context, pos);
--
-- if (!force && ffmpegdec->samplerate ==
-- ffmpegdec->context->sample_rate &&
-- ffmpegdec->channels == ffmpegdec->context->channels &&
-- ffmpegdec->depth == depth)
-- return TRUE;
--
-- GST_DEBUG_OBJECT (ffmpegdec,
-- "Renegotiating audio from %dHz@%dchannels (%d) to %dHz@%dchannels (%d)",
-- ffmpegdec->samplerate, ffmpegdec->channels,
-- ffmpegdec->depth,
-- ffmpegdec->context->sample_rate, ffmpegdec->context->channels, depth);
--
-- ffmpegdec->samplerate = ffmpegdec->context->sample_rate;
-- ffmpegdec->channels = ffmpegdec->context->channels;
-- ffmpegdec->depth = depth;
-- memcpy (ffmpegdec->ffmpeg_layout, pos,
-- sizeof (GstAudioChannelPosition) * ffmpegdec->context->channels);
--
-- /* Get GStreamer channel layout */
-- memcpy (ffmpegdec->gst_layout,
-- ffmpegdec->ffmpeg_layout,
-- sizeof (GstAudioChannelPosition) * ffmpegdec->channels);
-- gst_audio_channel_positions_to_valid_order (ffmpegdec->gst_layout,
-- ffmpegdec->channels);
--
-- caps = gst_ffmpeg_codectype_to_caps (oclass->in_plugin->type,
-- ffmpegdec->context, oclass->in_plugin->id, FALSE);
--
-- if (caps == NULL)
-- goto no_caps;
--
-- GST_LOG_OBJECT (ffmpegdec, "output caps %" GST_PTR_FORMAT, caps);
--
-- if (!gst_pad_set_caps (ffmpegdec->srcpad, caps))
-- goto caps_failed;
--
-- gst_caps_unref (caps);
--
-- return TRUE;
--
-- /* ERRORS */
--no_caps:
-- {
--#ifdef HAVE_LIBAV_UNINSTALLED
-- /* using internal ffmpeg snapshot */
-- GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION,
-- ("Could not find GStreamer caps mapping for libav codec '%s'.",
-- oclass->in_plugin->name), (NULL));
--#else
-- /* using external ffmpeg */
-- GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION,
-- ("Could not find GStreamer caps mapping for libav codec '%s', and "
-- "you are using an external libavcodec. This is most likely due to "
-- "a packaging problem and/or libavcodec having been upgraded to a "
-- "version that is not compatible with this version of "
-- "gstreamer-libav. Make sure your gstreamer-libav and libavcodec "
-- "packages come from the same source/repository.",
-- oclass->in_plugin->name), (NULL));
--#endif
-- return FALSE;
-- }
--caps_failed:
-- {
-- GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
-- ("Could not set caps for libav decoder (%s), not fixed?",
-- oclass->in_plugin->name));
-- gst_caps_unref (caps);
--
-- return FALSE;
-- }
--}
--
--static void
--clear_queued (GstFFMpegAudDec * ffmpegdec)
--{
-- g_list_foreach (ffmpegdec->queued, (GFunc) gst_mini_object_unref, NULL);
-- g_list_free (ffmpegdec->queued);
-- ffmpegdec->queued = NULL;
--}
--
--static GstFlowReturn
--flush_queued (GstFFMpegAudDec * ffmpegdec)
--{
-- GstFlowReturn res = GST_FLOW_OK;
--
-- while (ffmpegdec->queued) {
-- GstBuffer *buf = GST_BUFFER_CAST (ffmpegdec->queued->data);
--
-- GST_LOG_OBJECT (ffmpegdec, "pushing buffer %p, offset %"
-- G_GUINT64_FORMAT ", timestamp %"
-- GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT, buf,
-- GST_BUFFER_OFFSET (buf),
-- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
-- GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
--
-- /* iterate ouput queue an push downstream */
-- res = gst_pad_push (ffmpegdec->srcpad, buf);
--
-- ffmpegdec->queued =
-- g_list_delete_link (ffmpegdec->queued, ffmpegdec->queued);
-- }
-- return res;
--}
--
--static void
--gst_avpacket_init (AVPacket * packet, guint8 * data, guint size)
--{
-- memset (packet, 0, sizeof (AVPacket));
-- packet->data = data;
-- packet->size = size;
--}
--
--/* returns TRUE if buffer is within segment, else FALSE.
-- * if Buffer is on segment border, it's timestamp and duration will be clipped */
--static gboolean
--clip_audio_buffer (GstFFMpegAudDec * dec, GstBuffer * buf, GstClockTime in_ts,
-- GstClockTime in_dur)
--{
-- GstClockTime stop;
-- gint64 diff;
-- guint64 ctime, cstop;
-- gboolean res = TRUE;
-- gsize size, offset;
--
-- size = gst_buffer_get_size (buf);
-- offset = 0;
--
-- GST_LOG_OBJECT (dec,
-- "timestamp:%" GST_TIME_FORMAT ", duration:%" GST_TIME_FORMAT
-- ", size %" G_GSIZE_FORMAT, GST_TIME_ARGS (in_ts), GST_TIME_ARGS (in_dur),
-- size);
--
-- /* can't clip without TIME segment */
-- if (G_UNLIKELY (dec->segment.format != GST_FORMAT_TIME))
-- goto beach;
--
-- /* we need a start time */
-- if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (in_ts)))
-- goto beach;
--
-- /* trust duration */
-- stop = in_ts + in_dur;
--
-- res = gst_segment_clip (&dec->segment, GST_FORMAT_TIME, in_ts, stop, &ctime,
-- &cstop);
-- if (G_UNLIKELY (!res))
-- goto out_of_segment;
--
-- /* see if some clipping happened */
-- if (G_UNLIKELY ((diff = ctime - in_ts) > 0)) {
-- /* bring clipped time to bytes */
-- diff =
-- gst_util_uint64_scale_int (diff, dec->samplerate,
-- GST_SECOND) * (dec->depth * dec->channels);
--
-- GST_DEBUG_OBJECT (dec, "clipping start to %" GST_TIME_FORMAT " %"
-- G_GINT64_FORMAT " bytes", GST_TIME_ARGS (ctime), diff);
--
-- offset += diff;
-- size -= diff;
-- }
-- if (G_UNLIKELY ((diff = stop - cstop) > 0)) {
-- /* bring clipped time to bytes */
-- diff =
-- gst_util_uint64_scale_int (diff, dec->samplerate,
-- GST_SECOND) * (dec->depth * dec->channels);
--
-- GST_DEBUG_OBJECT (dec, "clipping stop to %" GST_TIME_FORMAT " %"
-- G_GINT64_FORMAT " bytes", GST_TIME_ARGS (cstop), diff);
--
-- size -= diff;
-- }
-- gst_buffer_resize (buf, offset, size);
-- GST_BUFFER_TIMESTAMP (buf) = ctime;
-- GST_BUFFER_DURATION (buf) = cstop - ctime;
--
--beach:
-- GST_LOG_OBJECT (dec, "%sdropping", (res ? "not " : ""));
-- return res;
--
-- /* ERRORS */
--out_of_segment:
-- {
-- GST_LOG_OBJECT (dec, "out of segment");
-- goto beach;
-- }
--}
--
--static gint
--gst_ffmpegauddec_audio_frame (GstFFMpegAudDec * ffmpegdec,
-- AVCodec * in_plugin, guint8 * data, guint size,
-- const GstTSInfo * dec_info, GstBuffer ** outbuf, GstFlowReturn * ret)
--{
-- gint len = -1;
-- gint have_data = AVCODEC_MAX_AUDIO_FRAME_SIZE;
-- GstClockTime out_pts, out_duration;
-- GstMapInfo map;
-- gint64 out_offset;
-- int16_t *odata;
-- AVPacket packet;
--
-- GST_DEBUG_OBJECT (ffmpegdec,
-- "size:%d, offset:%" G_GINT64_FORMAT ", dts:%" GST_TIME_FORMAT ", pts:%"
-- GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT ", ffmpegdec->next_out:%"
-- GST_TIME_FORMAT, size, dec_info->offset, GST_TIME_ARGS (dec_info->dts),
-- GST_TIME_ARGS (dec_info->pts), GST_TIME_ARGS (dec_info->duration),
-- GST_TIME_ARGS (ffmpegdec->next_out));
--
-- *outbuf = new_aligned_buffer (AVCODEC_MAX_AUDIO_FRAME_SIZE);
--
-- gst_buffer_map (*outbuf, &map, GST_MAP_WRITE);
-- odata = (int16_t *) map.data;
--
-- gst_avpacket_init (&packet, data, size);
-- len = avcodec_decode_audio3 (ffmpegdec->context, odata, &have_data, &packet);
--
-- GST_DEBUG_OBJECT (ffmpegdec,
-- "Decode audio: len=%d, have_data=%d", len, have_data);
--
-- if (len >= 0 && have_data > 0) {
-- GstAudioFormat fmt;
--
-- /* Buffer size */
-- gst_buffer_unmap (*outbuf, &map);
-- gst_buffer_resize (*outbuf, 0, have_data);
--
-- GST_DEBUG_OBJECT (ffmpegdec, "Creating output buffer");
-- if (!gst_ffmpegauddec_negotiate (ffmpegdec, FALSE)) {
-- gst_buffer_unref (*outbuf);
-- *outbuf = NULL;
-- len = -1;
-- goto beach;
-- }
--
-- /*
-- * Timestamps:
-- *
-- * 1) Copy input timestamp if valid
-- * 2) else interpolate from previous input timestamp
-- */
-- /* always take timestamps from the input buffer if any */
-- if (GST_CLOCK_TIME_IS_VALID (dec_info->pts)) {
-- out_pts = dec_info->pts;
-- } else {
-- out_pts = ffmpegdec->next_out;
-- }
--
-- /*
-- * Duration:
-- *
-- * 1) calculate based on number of samples
-- */
-- out_duration = gst_util_uint64_scale (have_data, GST_SECOND,
-- ffmpegdec->depth * ffmpegdec->channels * ffmpegdec->samplerate);
--
-- /* offset:
-- *
-- * Just copy
-- */
-- out_offset = dec_info->offset;
--
-- GST_DEBUG_OBJECT (ffmpegdec,
-- "Buffer created. Size:%d , pts:%" GST_TIME_FORMAT " , duration:%"
-- GST_TIME_FORMAT, have_data,
-- GST_TIME_ARGS (out_pts), GST_TIME_ARGS (out_duration));
--
-- GST_BUFFER_PTS (*outbuf) = out_pts;
-- GST_BUFFER_DURATION (*outbuf) = out_duration;
-- GST_BUFFER_OFFSET (*outbuf) = out_offset;
--
-- /* the next timestamp we'll use when interpolating */
-- if (GST_CLOCK_TIME_IS_VALID (out_pts))
-- ffmpegdec->next_out = out_pts + out_duration;
--
-- /* now see if we need to clip the buffer against the segment boundaries. */
-- if (G_UNLIKELY (!clip_audio_buffer (ffmpegdec, *outbuf, out_pts,
-- out_duration)))
-- goto clipped;
--
--
-- /* Reorder channels to the GStreamer channel order */
-- /* Only the width really matters here... and it's stored as depth */
-- fmt =
-- gst_audio_format_build_integer (TRUE, G_BYTE_ORDER,
-- ffmpegdec->depth * 8, ffmpegdec->depth * 8);
--
-- gst_audio_buffer_reorder_channels (*outbuf, fmt,
-- ffmpegdec->channels, ffmpegdec->ffmpeg_layout, ffmpegdec->gst_layout);
-- } else {
-- gst_buffer_unmap (*outbuf, &map);
-- gst_buffer_unref (*outbuf);
-- *outbuf = NULL;
-- }
--
--beach:
-- GST_DEBUG_OBJECT (ffmpegdec, "return flow %d, out %p, len %d",
-- *ret, *outbuf, len);
-- return len;
--
-- /* ERRORS */
--clipped:
-- {
-- GST_DEBUG_OBJECT (ffmpegdec, "buffer clipped");
-- gst_buffer_unref (*outbuf);
-- *outbuf = NULL;
-- goto beach;
-- }
--}
--
--/* gst_ffmpegauddec_frame:
-- * ffmpegdec:
-- * data: pointer to the data to decode
-- * size: size of data in bytes
-- * got_data: 0 if no data was decoded, != 0 otherwise.
-- * in_time: timestamp of data
-- * in_duration: duration of data
-- * ret: GstFlowReturn to return in the chain function
-- *
-- * Decode the given frame and pushes it downstream.
-- *
-- * Returns: Number of bytes used in decoding, -1 on error/failure.
-- */
--
--static gint
--gst_ffmpegauddec_frame (GstFFMpegAudDec * ffmpegdec,
-- guint8 * data, guint size, gint * got_data, const GstTSInfo * dec_info,
-- GstFlowReturn * ret)
--{
-- GstFFMpegAudDecClass *oclass;
-- GstBuffer *outbuf = NULL;
-- gint have_data = 0, len = 0;
--
-- if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
-- goto no_codec;
--
-- GST_LOG_OBJECT (ffmpegdec, "data:%p, size:%d, id:%d", data, size,
-- dec_info->idx);
--
-- *ret = GST_FLOW_OK;
-- ffmpegdec->context->frame_number++;
--
-- oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
--
-- len =
-- gst_ffmpegauddec_audio_frame (ffmpegdec, oclass->in_plugin, data, size,
-- dec_info, &outbuf, ret);
--
-- /* if we did not get an output buffer and we have a pending discont, don't
-- * clear the input timestamps, we will put them on the next buffer because
-- * else we might create the first buffer with a very big timestamp gap. */
-- if (outbuf == NULL && ffmpegdec->discont) {
-- GST_DEBUG_OBJECT (ffmpegdec, "no buffer but keeping timestamp");
-- ffmpegdec->clear_ts = FALSE;
-- }
--
-- if (outbuf)
-- have_data = 1;
--
-- if (len < 0 || have_data < 0) {
-- GST_WARNING_OBJECT (ffmpegdec,
-- "avdec_%s: decoding error (len: %d, have_data: %d)",
-- oclass->in_plugin->name, len, have_data);
-- *got_data = 0;
-- goto beach;
-- } else if (len == 0 && have_data == 0) {
-- *got_data = 0;
-- goto beach;
-- } else {
-- /* this is where I lost my last clue on ffmpeg... */
-- *got_data = 1;
-- }
--
-- if (outbuf) {
-- GST_LOG_OBJECT (ffmpegdec,
-- "Decoded data, now pushing buffer %p with offset %" G_GINT64_FORMAT
-- ", timestamp %" GST_TIME_FORMAT " and duration %" GST_TIME_FORMAT,
-- outbuf, GST_BUFFER_OFFSET (outbuf),
-- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
-- GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
--
-- /* mark pending discont */
-- if (ffmpegdec->discont) {
-- GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
-- ffmpegdec->discont = FALSE;
-- }
-- if (ffmpegdec->segment.rate > 0.0) {
-- /* and off we go */
-- *ret = gst_pad_push (ffmpegdec->srcpad, outbuf);
-- } else {
-- /* reverse playback, queue frame till later when we get a discont. */
-- GST_DEBUG_OBJECT (ffmpegdec, "queued frame");
-- ffmpegdec->queued = g_list_prepend (ffmpegdec->queued, outbuf);
-- *ret = GST_FLOW_OK;
-- }
-- } else {
-- GST_DEBUG_OBJECT (ffmpegdec, "We didn't get a decoded buffer");
-- }
--
--beach:
-- return len;
--
-- /* ERRORS */
--no_codec:
-- {
-- GST_ERROR_OBJECT (ffmpegdec, "no codec context");
-- return -1;
-- }
--}
--
--static void
--gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec)
--{
-- GstFFMpegAudDecClass *oclass;
--
-- oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
--
-- if (oclass->in_plugin->capabilities & CODEC_CAP_DELAY) {
-- gint have_data, len, try = 0;
--
-- GST_LOG_OBJECT (ffmpegdec,
-- "codec has delay capabilities, calling until libav has drained everything");
--
-- do {
-- GstFlowReturn ret;
--
-- len =
-- gst_ffmpegauddec_frame (ffmpegdec, NULL, 0, &have_data, &ts_info_none,
-- &ret);
-- if (len < 0 || have_data == 0)
-- break;
-- } while (try++ < 10);
-- }
-- if (ffmpegdec->segment.rate < 0.0) {
-- /* if we have some queued frames for reverse playback, flush them now */
-- flush_queued (ffmpegdec);
-- }
--}
--
--static void
--gst_ffmpegauddec_flush_pcache (GstFFMpegAudDec * ffmpegdec)
--{
-- if (ffmpegdec->pctx) {
-- gint size, bsize;
-- guint8 *data;
-- guint8 bdata[FF_INPUT_BUFFER_PADDING_SIZE];
--
-- bsize = FF_INPUT_BUFFER_PADDING_SIZE;
-- memset (bdata, 0, bsize);
--
-- /* parse some dummy data to work around some ffmpeg weirdness where it keeps
-- * the previous pts around */
-- av_parser_parse2 (ffmpegdec->pctx, ffmpegdec->context,
-- &data, &size, bdata, bsize, -1, -1, -1);
-- ffmpegdec->pctx->pts = -1;
-- ffmpegdec->pctx->dts = -1;
-- }
--
-- if (ffmpegdec->pcache) {
-- gst_buffer_unref (ffmpegdec->pcache);
-- ffmpegdec->pcache = NULL;
-- }
--}
--
--static gboolean
--gst_ffmpegauddec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
--{
-- GstFFMpegAudDec *ffmpegdec;
-- gboolean ret = FALSE;
--
-- ffmpegdec = (GstFFMpegAudDec *) parent;
--
-- GST_DEBUG_OBJECT (ffmpegdec, "Handling %s event",
-- GST_EVENT_TYPE_NAME (event));
--
-- switch (GST_EVENT_TYPE (event)) {
-- case GST_EVENT_EOS:
-- {
-- gst_ffmpegauddec_drain (ffmpegdec);
-- break;
-- }
-- case GST_EVENT_FLUSH_STOP:
-- {
-- if (ffmpegdec->opened) {
-- avcodec_flush_buffers (ffmpegdec->context);
-- }
-- gst_ffmpegauddec_reset_ts (ffmpegdec);
-- gst_ffmpegauddec_flush_pcache (ffmpegdec);
-- gst_segment_init (&ffmpegdec->segment, GST_FORMAT_TIME);
-- clear_queued (ffmpegdec);
-- break;
-- }
-- case GST_EVENT_CAPS:
-- {
-- GstCaps *caps;
--
-- gst_event_parse_caps (event, &caps);
--
-- if (!ffmpegdec->last_caps
-- || !gst_caps_is_equal (ffmpegdec->last_caps, caps)) {
-- ret = gst_ffmpegauddec_setcaps (ffmpegdec, caps);
-- if (ret) {
-- gst_caps_replace (&ffmpegdec->last_caps, caps);
-- }
-- } else {
-- ret = TRUE;
-- }
--
-- gst_event_unref (event);
-- goto done;
-- }
-- case GST_EVENT_SEGMENT:
-- {
-- GstSegment segment;
--
-- gst_event_copy_segment (event, &segment);
--
-- switch (segment.format) {
-- case GST_FORMAT_TIME:
-- /* fine, our native segment format */
-- break;
-- case GST_FORMAT_BYTES:
-- {
-- gint bit_rate;
--
-- bit_rate = ffmpegdec->context->bit_rate;
--
-- /* convert to time or fail */
-- if (!bit_rate)
-- goto no_bitrate;
--
-- GST_DEBUG_OBJECT (ffmpegdec, "bitrate: %d", bit_rate);
--
-- /* convert values to TIME */
-- if (segment.start != -1)
-- segment.start =
-- gst_util_uint64_scale_int (segment.start, GST_SECOND, bit_rate);
-- if (segment.stop != -1)
-- segment.stop =
-- gst_util_uint64_scale_int (segment.stop, GST_SECOND, bit_rate);
-- if (segment.time != -1)
-- segment.time =
-- gst_util_uint64_scale_int (segment.time, GST_SECOND, bit_rate);
--
-- /* unref old event */
-- gst_event_unref (event);
--
-- /* create new converted time segment */
-- segment.format = GST_FORMAT_TIME;
-- /* FIXME, bitrate is not good enough too find a good stop, let's
-- * hope start and time were 0... meh. */
-- segment.stop = -1;
-- event = gst_event_new_segment (&segment);
-- break;
-- }
-- default:
-- /* invalid format */
-- goto invalid_format;
-- }
--
-- GST_DEBUG_OBJECT (ffmpegdec, "SEGMENT in time %" GST_SEGMENT_FORMAT,
-- &segment);
--
-- /* and store the values */
-- gst_segment_copy_into (&segment, &ffmpegdec->segment);
-- break;
-- }
-- default:
-- break;
-- }
--
-- /* and push segment downstream */
-- ret = gst_pad_push_event (ffmpegdec->srcpad, event);
--
--done:
--
-- return ret;
--
-- /* ERRORS */
--no_bitrate:
-- {
-- GST_WARNING_OBJECT (ffmpegdec, "no bitrate to convert BYTES to TIME");
-- gst_event_unref (event);
-- goto done;
-- }
--invalid_format:
-- {
-- GST_WARNING_OBJECT (ffmpegdec, "unknown format received in NEWSEGMENT");
-- gst_event_unref (event);
-- goto done;
-- }
--}
--
--static gboolean
--gst_ffmpegauddec_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
--{
-- GstFFMpegAudDec *ffmpegdec;
-- gboolean ret = FALSE;
--
-- ffmpegdec = (GstFFMpegAudDec *) parent;
--
-- GST_DEBUG_OBJECT (ffmpegdec, "Handling %s query",
-- GST_QUERY_TYPE_NAME (query));
--
-- switch (GST_QUERY_TYPE (query)) {
-- case GST_QUERY_ACCEPT_CAPS:
-- {
-- GstPadTemplate *templ;
--
-- ret = FALSE;
-- if ((templ = GST_PAD_PAD_TEMPLATE (pad))) {
-- GstCaps *tcaps;
--
-- if ((tcaps = GST_PAD_TEMPLATE_CAPS (templ))) {
-- GstCaps *caps;
--
-- gst_query_parse_accept_caps (query, &caps);
-- gst_query_set_accept_caps_result (query,
-- gst_caps_is_subset (caps, tcaps));
-- ret = TRUE;
-- }
-- }
-- break;
-- }
-- default:
-- ret = gst_pad_query_default (pad, parent, query);
-- break;
-- }
-- return ret;
--}
--
--static GstFlowReturn
--gst_ffmpegauddec_chain (GstPad * pad, GstObject * parent, GstBuffer * inbuf)
--{
-- GstFFMpegAudDec *ffmpegdec;
-- GstFFMpegAudDecClass *oclass;
-- guint8 *data, *bdata;
-- GstMapInfo map;
-- gint size, bsize, len, have_data;
-- GstFlowReturn ret = GST_FLOW_OK;
-- GstClockTime in_pts, in_dts, in_duration;
-- gboolean discont;
-- gint64 in_offset;
-- const GstTSInfo *in_info;
-- const GstTSInfo *dec_info;
--
-- ffmpegdec = (GstFFMpegAudDec *) parent;
--
-- if (G_UNLIKELY (!ffmpegdec->opened))
-- goto not_negotiated;
--
-- discont = GST_BUFFER_IS_DISCONT (inbuf);
--
-- /* The discont flags marks a buffer that is not continuous with the previous
-- * buffer. This means we need to clear whatever data we currently have. We let
-- * ffmpeg continue with the data that it has. We currently drain the old
-- * frames that might be inside the decoder and we clear any partial data in
-- * the pcache, we might be able to remove the drain and flush too. */
-- if (G_UNLIKELY (discont)) {
-- GST_DEBUG_OBJECT (ffmpegdec, "received DISCONT");
-- /* drain what we have queued */
-- gst_ffmpegauddec_drain (ffmpegdec);
-- gst_ffmpegauddec_flush_pcache (ffmpegdec);
-- ffmpegdec->discont = TRUE;
-- gst_ffmpegauddec_reset_ts (ffmpegdec);
-- }
-- /* by default we clear the input timestamp after decoding each frame so that
-- * interpollation can work. */
-- ffmpegdec->clear_ts = TRUE;
--
-- oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
--
-- /* parse cache joining. If there is cached data */
-- if (ffmpegdec->pcache) {
-- /* join with previous data */
-- GST_LOG_OBJECT (ffmpegdec, "join parse cache");
-- inbuf = gst_buffer_append (ffmpegdec->pcache, inbuf);
-- /* no more cached data, we assume we can consume the complete cache */
-- ffmpegdec->pcache = NULL;
-- }
--
-- in_dts = GST_BUFFER_DTS (inbuf);
-- in_pts = GST_BUFFER_PTS (inbuf);
-- in_duration = GST_BUFFER_DURATION (inbuf);
-- in_offset = GST_BUFFER_OFFSET (inbuf);
--
-- /* get handle to timestamp info, we can pass this around to ffmpeg */
-- in_info =
-- gst_ts_info_store (ffmpegdec, in_dts, in_pts, in_duration, in_offset);
--
-- GST_LOG_OBJECT (ffmpegdec,
-- "Received new data of size %u, offset:%" G_GUINT64_FORMAT ", ts:%"
-- GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT ", info %d",
-- gst_buffer_get_size (inbuf), GST_BUFFER_OFFSET (inbuf),
-- GST_TIME_ARGS (in_pts), GST_TIME_ARGS (in_duration), in_info->idx);
--
-- /* workarounds, functions write to buffers:
-- * libavcodec/svq1.c:svq1_decode_frame writes to the given buffer.
-- * libavcodec/svq3.c:svq3_decode_slice_header too.
-- * ffmpeg devs know about it and will fix it (they said). */
-- if (oclass->in_plugin->id == CODEC_ID_SVQ1 ||
-- oclass->in_plugin->id == CODEC_ID_SVQ3) {
-- inbuf = gst_buffer_make_writable (inbuf);
-- }
--
-- gst_buffer_map (inbuf, &map, GST_MAP_READ);
--
-- bdata = map.data;
-- bsize = map.size;
--
-- GST_LOG_OBJECT (ffmpegdec,
-- "Received new data of size %u, offset:%" G_GUINT64_FORMAT ", dts:%"
-- GST_TIME_FORMAT ", pts:%" GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT
-- ", info %d", bsize, in_offset, GST_TIME_ARGS (in_dts),
-- GST_TIME_ARGS (in_pts), GST_TIME_ARGS (in_duration), in_info->idx);
--
-- do {
-- /* parse, if at all possible */
-- if (ffmpegdec->pctx) {
-- gint res;
--
-- GST_LOG_OBJECT (ffmpegdec,
-- "Calling av_parser_parse2 with offset %" G_GINT64_FORMAT ", ts:%"
-- GST_TIME_FORMAT " size %d", in_offset, GST_TIME_ARGS (in_pts), bsize);
--
-- /* feed the parser. We pass the timestamp info so that we can recover all
-- * info again later */
-- res = av_parser_parse2 (ffmpegdec->pctx, ffmpegdec->context,
-- &data, &size, bdata, bsize, in_info->idx, in_info->idx, in_offset);
--
-- GST_LOG_OBJECT (ffmpegdec,
-- "parser returned res %d and size %d, id %" G_GINT64_FORMAT, res, size,
-- (gint64) ffmpegdec->pctx->pts);
--
-- /* store pts for decoding */
-- if (ffmpegdec->pctx->pts != AV_NOPTS_VALUE && ffmpegdec->pctx->pts != -1)
-- dec_info = gst_ts_info_get (ffmpegdec, ffmpegdec->pctx->pts);
-- else {
-- /* ffmpeg sometimes loses track after a flush, help it by feeding a
-- * valid start time */
-- ffmpegdec->pctx->pts = in_info->idx;
-- ffmpegdec->pctx->dts = in_info->idx;
-- dec_info = in_info;
-- }
--
-- GST_LOG_OBJECT (ffmpegdec, "consuming %d bytes. id %d", size,
-- dec_info->idx);
--
-- if (res) {
-- /* there is output, set pointers for next round. */
-- bsize -= res;
-- bdata += res;
-- } else {
-- /* Parser did not consume any data, make sure we don't clear the
-- * timestamp for the next round */
-- ffmpegdec->clear_ts = FALSE;
-- }
--
-- /* if there is no output, we must break and wait for more data. also the
-- * timestamp in the context is not updated. */
-- if (size == 0) {
-- if (bsize > 0)
-- continue;
-- else
-- break;
-- }
-- } else {
-- data = bdata;
-- size = bsize;
--
-- dec_info = in_info;
-- }
--
-- /* decode a frame of audio now */
-- len =
-- gst_ffmpegauddec_frame (ffmpegdec, data, size, &have_data, dec_info,
-- &ret);
--
-- if (ret != GST_FLOW_OK) {
-- GST_LOG_OBJECT (ffmpegdec, "breaking because of flow ret %s",
-- gst_flow_get_name (ret));
-- /* bad flow return, make sure we discard all data and exit */
-- bsize = 0;
-- break;
-- }
-- if (!ffmpegdec->pctx) {
-- if (len == 0 && !have_data) {
-- /* nothing was decoded, this could be because no data was available or
-- * because we were skipping frames.
-- * If we have no context we must exit and wait for more data, we keep the
-- * data we tried. */
-- GST_LOG_OBJECT (ffmpegdec, "Decoding didn't return any data, breaking");
-- break;
-- } else if (len < 0) {
-- /* a decoding error happened, we must break and try again with next data. */
-- GST_LOG_OBJECT (ffmpegdec, "Decoding error, breaking");
-- bsize = 0;
-- break;
-- }
-- /* prepare for the next round, for codecs with a context we did this
-- * already when using the parser. */
-- bsize -= len;
-- bdata += len;
-- } else {
-- if (len == 0) {
-- /* nothing was decoded, this could be because no data was available or
-- * because we were skipping frames. Since we have a parser we can
-- * continue with the next frame */
-- GST_LOG_OBJECT (ffmpegdec,
-- "Decoding didn't return any data, trying next");
-- } else if (len < 0) {
-- /* we have a context that will bring us to the next frame */
-- GST_LOG_OBJECT (ffmpegdec, "Decoding error, trying next");
-- }
-- }
--
-- /* make sure we don't use the same old timestamp for the next frame and let
-- * the interpollation take care of it. */
-- if (ffmpegdec->clear_ts) {
-- in_dts = GST_CLOCK_TIME_NONE;
-- in_pts = GST_CLOCK_TIME_NONE;
-- in_duration = GST_CLOCK_TIME_NONE;
-- in_offset = GST_BUFFER_OFFSET_NONE;
-- in_info = GST_TS_INFO_NONE;
-- } else {
-- ffmpegdec->clear_ts = TRUE;
-- }
--
-- GST_LOG_OBJECT (ffmpegdec, "Before (while bsize>0). bsize:%d , bdata:%p",
-- bsize, bdata);
-- } while (bsize > 0);
--
-- gst_buffer_unmap (inbuf, &map);
--
-- /* keep left-over */
-- if (ffmpegdec->pctx && bsize > 0) {
-- in_pts = GST_BUFFER_PTS (inbuf);
-- in_dts = GST_BUFFER_DTS (inbuf);
-- in_offset = GST_BUFFER_OFFSET (inbuf);
--
-- GST_LOG_OBJECT (ffmpegdec,
-- "Keeping %d bytes of data with offset %" G_GINT64_FORMAT ", pts %"
-- GST_TIME_FORMAT, bsize, in_offset, GST_TIME_ARGS (in_pts));
--
-- ffmpegdec->pcache = gst_buffer_copy_region (inbuf, GST_BUFFER_COPY_ALL,
-- gst_buffer_get_size (inbuf) - bsize, bsize);
-- /* we keep timestamp, even though all we really know is that the correct
-- * timestamp is not below the one from inbuf */
-- GST_BUFFER_PTS (ffmpegdec->pcache) = in_pts;
-- GST_BUFFER_DTS (ffmpegdec->pcache) = in_dts;
-- GST_BUFFER_OFFSET (ffmpegdec->pcache) = in_offset;
-- } else if (bsize > 0) {
-- GST_DEBUG_OBJECT (ffmpegdec, "Dropping %d bytes of data", bsize);
-- }
-- gst_buffer_unref (inbuf);
--
-- return ret;
--
-- /* ERRORS */
--not_negotiated:
-- {
-- oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
-- GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
-- ("avdec_%s: input format was not set before data start",
-- oclass->in_plugin->name));
-- gst_buffer_unref (inbuf);
-- return GST_FLOW_NOT_NEGOTIATED;
-- }
--}
--
--static GstStateChangeReturn
--gst_ffmpegauddec_change_state (GstElement * element, GstStateChange transition)
--{
-- GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) element;
-- GstStateChangeReturn ret;
--
-- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
--
-- switch (transition) {
-- case GST_STATE_CHANGE_PAUSED_TO_READY:
-- GST_OBJECT_LOCK (ffmpegdec);
-- gst_ffmpegauddec_close (ffmpegdec);
-- GST_OBJECT_UNLOCK (ffmpegdec);
-- clear_queued (ffmpegdec);
-- break;
-- default:
-- break;
-- }
--
-- return ret;
--}
--
--gboolean
--gst_ffmpegauddec_register (GstPlugin * plugin)
--{
-- GTypeInfo typeinfo = {
-- sizeof (GstFFMpegAudDecClass),
-- (GBaseInitFunc) gst_ffmpegauddec_base_init,
-- NULL,
-- (GClassInitFunc) gst_ffmpegauddec_class_init,
-- NULL,
-- NULL,
-- sizeof (GstFFMpegAudDec),
-- 0,
-- (GInstanceInitFunc) gst_ffmpegauddec_init,
-- };
-- GType type;
-- AVCodec *in_plugin;
-- gint rank;
--
-- in_plugin = av_codec_next (NULL);
--
-- GST_LOG ("Registering decoders");
--
-- while (in_plugin) {
-- gchar *type_name;
-- gchar *plugin_name;
--
-- /* only decoders */
-- if (!in_plugin->decode || in_plugin->type != AVMEDIA_TYPE_AUDIO) {
-- goto next;
-- }
--
-- /* no quasi-codecs, please */
-- if (in_plugin->id >= CODEC_ID_PCM_S16LE &&
-- in_plugin->id <= CODEC_ID_PCM_BLURAY) {
-- goto next;
-- }
--
-- /* No decoders depending on external libraries (we don't build them, but
-- * people who build against an external ffmpeg might have them.
-- * We have native gstreamer plugins for all of those libraries anyway. */
-- if (!strncmp (in_plugin->name, "lib", 3)) {
-- GST_DEBUG
-- ("Not using external library decoder %s. Use the gstreamer-native ones instead.",
-- in_plugin->name);
-- goto next;
-- }
--
-- GST_DEBUG ("Trying plugin %s [%s]", in_plugin->name, in_plugin->long_name);
--
-- /* no codecs for which we're GUARANTEED to have better alternatives */
-- /* MP1 : Use MP3 for decoding */
-- /* MP2 : Use MP3 for decoding */
-- /* Theora: Use libtheora based theoradec */
-- if (!strcmp (in_plugin->name, "vorbis") ||
-- !strcmp (in_plugin->name, "wavpack") ||
-- !strcmp (in_plugin->name, "mp1") ||
-- !strcmp (in_plugin->name, "mp2") ||
-- !strcmp (in_plugin->name, "libfaad") ||
-- !strcmp (in_plugin->name, "mpeg4aac") ||
-- !strcmp (in_plugin->name, "ass") ||
-- !strcmp (in_plugin->name, "srt") ||
-- !strcmp (in_plugin->name, "pgssub") ||
-- !strcmp (in_plugin->name, "dvdsub") ||
-- !strcmp (in_plugin->name, "dvbsub")) {
-- GST_LOG ("Ignoring decoder %s", in_plugin->name);
-- goto next;
-- }
--
-- /* construct the type */
-- plugin_name = g_strdup ((gchar *) in_plugin->name);
-- g_strdelimit (plugin_name, NULL, '_');
-- type_name = g_strdup_printf ("avdec_%s", plugin_name);
-- g_free (plugin_name);
--
-- type = g_type_from_name (type_name);
--
-- if (!type) {
-- /* create the gtype now */
-- type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
-- g_type_set_qdata (type, GST_FFDEC_PARAMS_QDATA, (gpointer) in_plugin);
-- }
--
-- /* (Ronald) MPEG-4 gets a higher priority because it has been well-
-- * tested and by far outperforms divxdec/xviddec - so we prefer it.
-- * msmpeg4v3 same, as it outperforms divxdec for divx3 playback.
-- * VC1/WMV3 are not working and thus unpreferred for now. */
-- switch (in_plugin->id) {
-- case CODEC_ID_RA_144:
-- case CODEC_ID_RA_288:
-- case CODEC_ID_COOK:
-- rank = GST_RANK_PRIMARY;
-- break;
-- /* SIPR: decoder should have a higher rank than realaudiodec.
-- */
-- case CODEC_ID_SIPR:
-- rank = GST_RANK_SECONDARY;
-- break;
-- case CODEC_ID_MP3:
-- rank = GST_RANK_NONE;
-- break;
-- default:
-- rank = GST_RANK_MARGINAL;
-- break;
-- }
-- if (!gst_element_register (plugin, type_name, rank, type)) {
-- g_warning ("Failed to register %s", type_name);
-- g_free (type_name);
-- return FALSE;
-- }
--
-- g_free (type_name);
--
-- next:
-- in_plugin = av_codec_next (in_plugin);
-- }
--
-- GST_LOG ("Finished Registering decoders");
--
-- return TRUE;
--}
-diff --git a/ext/libav/gstavdeinterlace.c b/ext/libav/gstavdeinterlace.c
-index 65961f6..faa81bb 100644
---- a/ext/libav/gstavdeinterlace.c
-+++ b/ext/libav/gstavdeinterlace.c
-@@ -16,8 +16,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
- #ifdef HAVE_CONFIG_H
-@@ -203,7 +203,7 @@ gst_ffmpegdeinterlace_sink_setcaps (GstPad * pad, GstCaps * caps)
- }
- gst_ffmpegdeinterlace_update_passthrough (deinterlace);
-
-- ctx = avcodec_alloc_context ();
-+ ctx = avcodec_alloc_context3 (NULL);
- ctx->width = deinterlace->width;
- ctx->height = deinterlace->height;
- ctx->pix_fmt = PIX_FMT_NB;
-diff --git a/ext/libav/gstavdemux.c b/ext/libav/gstavdemux.c
-index bee67a5..de0341f 100644
---- a/ext/libav/gstavdemux.c
-+++ b/ext/libav/gstavdemux.c
-@@ -15,8 +15,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
- #ifdef HAVE_CONFIG_H
-@@ -32,7 +32,7 @@
- #include "gstav.h"
- #include "gstavcodecmap.h"
- #include "gstavutils.h"
--#include "gstavpipe.h"
-+#include "gstavprotocol.h"
-
- #define MAX_STREAMS 20
-
-@@ -332,7 +332,14 @@ gst_ffmpegdemux_close (GstFFMpegDemux * demux)
- demux->audiopads = 0;
-
- /* close demuxer context from ffmpeg */
-- av_close_input_file (demux->context);
-+ if (demux->seekable)
-+ gst_ffmpegdata_close (demux->context->pb);
-+ else
-+ gst_ffmpeg_pipe_close (demux->context->pb);
-+ demux->context->pb = NULL;
-+ avformat_close_input (&demux->context);
-+ if (demux->context)
-+ avformat_free_context (demux->context);
- demux->context = NULL;
-
- GST_OBJECT_LOCK (demux);
-@@ -995,7 +1002,7 @@ gst_ffmpegdemux_get_stream (GstFFMpegDemux * demux, AVStream * avstream)
-
-
- stream_id =
-- gst_pad_create_stream_id_printf (pad, GST_ELEMENT_CAST (demux), "%u",
-+ gst_pad_create_stream_id_printf (pad, GST_ELEMENT_CAST (demux), "%03u",
- avstream->index);
- gst_pad_push_event (pad, gst_event_new_stream_start (stream_id));
- g_free (stream_id);
-@@ -1115,9 +1122,9 @@ gst_ffmpegdemux_read_tags (GstFFMpegDemux * demux)
- static gboolean
- gst_ffmpegdemux_open (GstFFMpegDemux * demux)
- {
-+ AVIOContext *iocontext = NULL;
- GstFFMpegDemuxClass *oclass =
- (GstFFMpegDemuxClass *) G_OBJECT_GET_CLASS (demux);
-- gchar *location;
- gint res, n_streams, i;
- #if 0
- /* Re-enable once converted to new AVMetaData API
-@@ -1133,15 +1140,14 @@ gst_ffmpegdemux_open (GstFFMpegDemux * demux)
-
- /* open via our input protocol hack */
- if (demux->seekable)
-- location = g_strdup_printf ("gstreamer://%p", demux->sinkpad);
-+ res = gst_ffmpegdata_open (demux->sinkpad, AVIO_FLAG_READ, &iocontext);
- else
-- location = g_strdup_printf ("gstpipe://%p", &demux->ffpipe);
-- GST_DEBUG_OBJECT (demux, "about to call av_open_input_file %s", location);
-+ res = gst_ffmpeg_pipe_open (&demux->ffpipe, AVIO_FLAG_READ, &iocontext);
-
-- res = av_open_input_file (&demux->context, location,
-- oclass->in_plugin, 0, NULL);
-+ demux->context = avformat_alloc_context ();
-+ demux->context->pb = iocontext;
-+ res = avformat_open_input (&demux->context, NULL, oclass->in_plugin, NULL);
-
-- g_free (location);
- GST_DEBUG_OBJECT (demux, "av_open_input returned %d", res);
- if (res < 0)
- goto open_failed;
-diff --git a/ext/libav/gstavenc.c b/ext/libav/gstavenc.c
-deleted file mode 100644
-index 312787e..0000000
---- a/ext/libav/gstavenc.c
-+++ /dev/null
-@@ -1,825 +0,0 @@
--/* 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 <assert.h>
--#include <string.h>
--/* for stats file handling */
--#include <stdio.h>
--#include <glib/gstdio.h>
--#include <errno.h>
--
--#include <libavcodec/avcodec.h>
--
--#include <gst/gst.h>
--
--#include "gstav.h"
--#include "gstavcodecmap.h"
--#include "gstavutils.h"
--#include "gstavenc.h"
--
--#define DEFAULT_AUDIO_BITRATE 128000
--
--enum
--{
-- /* FILL ME */
-- LAST_SIGNAL
--};
--
--enum
--{
-- ARG_0,
-- ARG_BIT_RATE,
-- ARG_BUFSIZE,
-- ARG_RTP_PAYLOAD_SIZE,
--};
--
--/* A number of function prototypes are given so we can refer to them later. */
--static void gst_ffmpegaudenc_class_init (GstFFMpegAudEncClass * klass);
--static void gst_ffmpegaudenc_base_init (GstFFMpegAudEncClass * klass);
--static void gst_ffmpegaudenc_init (GstFFMpegAudEnc * ffmpegaudenc);
--static void gst_ffmpegaudenc_finalize (GObject * object);
--
--static gboolean gst_ffmpegaudenc_setcaps (GstFFMpegAudEnc * ffmpegenc,
-- GstCaps * caps);
--static GstCaps *gst_ffmpegaudenc_getcaps (GstFFMpegAudEnc * ffmpegenc,
-- GstCaps * filter);
--static GstFlowReturn gst_ffmpegaudenc_chain_audio (GstPad * pad,
-- GstObject * parent, GstBuffer * buffer);
--static gboolean gst_ffmpegaudenc_query_sink (GstPad * pad, GstObject * parent,
-- GstQuery * query);
--static gboolean gst_ffmpegaudenc_event_sink (GstPad * pad, GstObject * parent,
-- GstEvent * event);
--
--static void gst_ffmpegaudenc_set_property (GObject * object,
-- guint prop_id, const GValue * value, GParamSpec * pspec);
--static void gst_ffmpegaudenc_get_property (GObject * object,
-- guint prop_id, GValue * value, GParamSpec * pspec);
--
--static GstStateChangeReturn gst_ffmpegaudenc_change_state (GstElement * element,
-- GstStateChange transition);
--
--#define GST_FFENC_PARAMS_QDATA g_quark_from_static_string("avenc-params")
--
--static GstElementClass *parent_class = NULL;
--
--/*static guint gst_ffmpegaudenc_signals[LAST_SIGNAL] = { 0 }; */
--
--static void
--gst_ffmpegaudenc_base_init (GstFFMpegAudEncClass * klass)
--{
-- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-- AVCodec *in_plugin;
-- GstPadTemplate *srctempl = NULL, *sinktempl = NULL;
-- GstCaps *srccaps = NULL, *sinkcaps = NULL;
-- gchar *longname, *description;
--
-- in_plugin =
-- (AVCodec *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
-- GST_FFENC_PARAMS_QDATA);
-- g_assert (in_plugin != NULL);
--
-- /* construct the element details struct */
-- longname = g_strdup_printf ("libav %s encoder", in_plugin->long_name);
-- description = g_strdup_printf ("libav %s encoder", in_plugin->name);
-- gst_element_class_set_metadata (element_class, longname,
-- "Codec/Encoder/Audio", description,
-- "Wim Taymans <wim.taymans@gmail.com>, "
-- "Ronald Bultje <rbultje@ronald.bitfreak.net>");
-- g_free (longname);
-- g_free (description);
--
-- if (!(srccaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, TRUE))) {
-- GST_DEBUG ("Couldn't get source caps for encoder '%s'", in_plugin->name);
-- srccaps = gst_caps_new_empty_simple ("unknown/unknown");
-- }
--
-- sinkcaps = gst_ffmpeg_codectype_to_audio_caps (NULL,
-- in_plugin->id, TRUE, in_plugin);
-- if (!sinkcaps) {
-- GST_DEBUG ("Couldn't get sink caps for encoder '%s'", in_plugin->name);
-- sinkcaps = gst_caps_new_empty_simple ("unknown/unknown");
-- }
--
-- /* pad templates */
-- sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
-- GST_PAD_ALWAYS, sinkcaps);
-- srctempl = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, srccaps);
--
-- gst_element_class_add_pad_template (element_class, srctempl);
-- gst_element_class_add_pad_template (element_class, sinktempl);
--
-- klass->in_plugin = in_plugin;
-- klass->srctempl = srctempl;
-- klass->sinktempl = sinktempl;
-- klass->sinkcaps = NULL;
--
-- return;
--}
--
--static void
--gst_ffmpegaudenc_class_init (GstFFMpegAudEncClass * klass)
--{
-- GObjectClass *gobject_class;
-- GstElementClass *gstelement_class;
--
-- gobject_class = (GObjectClass *) klass;
-- gstelement_class = (GstElementClass *) klass;
--
-- parent_class = g_type_class_peek_parent (klass);
--
-- gobject_class->set_property = gst_ffmpegaudenc_set_property;
-- gobject_class->get_property = gst_ffmpegaudenc_get_property;
--
-- /* FIXME: could use -1 for a sensible per-codec defaults */
-- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BIT_RATE,
-- g_param_spec_int ("bitrate", "Bit Rate",
-- "Target Audio Bitrate", 0, G_MAXINT, DEFAULT_AUDIO_BITRATE,
-- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
--
-- gstelement_class->change_state = gst_ffmpegaudenc_change_state;
--
-- gobject_class->finalize = gst_ffmpegaudenc_finalize;
--}
--
--static void
--gst_ffmpegaudenc_init (GstFFMpegAudEnc * ffmpegaudenc)
--{
-- GstFFMpegAudEncClass *oclass =
-- (GstFFMpegAudEncClass *) (G_OBJECT_GET_CLASS (ffmpegaudenc));
--
-- /* setup pads */
-- ffmpegaudenc->sinkpad = gst_pad_new_from_template (oclass->sinktempl, "sink");
-- gst_pad_set_event_function (ffmpegaudenc->sinkpad,
-- gst_ffmpegaudenc_event_sink);
-- gst_pad_set_query_function (ffmpegaudenc->sinkpad,
-- gst_ffmpegaudenc_query_sink);
-- gst_pad_set_chain_function (ffmpegaudenc->sinkpad,
-- gst_ffmpegaudenc_chain_audio);
--
-- ffmpegaudenc->srcpad = gst_pad_new_from_template (oclass->srctempl, "src");
-- gst_pad_use_fixed_caps (ffmpegaudenc->srcpad);
--
-- /* ffmpeg objects */
-- ffmpegaudenc->context = avcodec_alloc_context ();
-- ffmpegaudenc->opened = FALSE;
--
-- gst_element_add_pad (GST_ELEMENT (ffmpegaudenc), ffmpegaudenc->sinkpad);
-- gst_element_add_pad (GST_ELEMENT (ffmpegaudenc), ffmpegaudenc->srcpad);
--
-- ffmpegaudenc->adapter = gst_adapter_new ();
--}
--
--static void
--gst_ffmpegaudenc_finalize (GObject * object)
--{
-- GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) object;
--
--
-- /* close old session */
-- if (ffmpegaudenc->opened) {
-- gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
-- ffmpegaudenc->opened = FALSE;
-- }
--
-- /* clean up remaining allocated data */
-- av_free (ffmpegaudenc->context);
--
-- g_object_unref (ffmpegaudenc->adapter);
--
-- G_OBJECT_CLASS (parent_class)->finalize (object);
--}
--
--static GstCaps *
--gst_ffmpegaudenc_getcaps (GstFFMpegAudEnc * ffmpegaudenc, GstCaps * filter)
--{
-- GstCaps *caps = NULL;
--
-- GST_DEBUG_OBJECT (ffmpegaudenc, "getting caps");
--
-- /* audio needs no special care */
-- caps = gst_pad_get_pad_template_caps (ffmpegaudenc->sinkpad);
--
-- if (filter) {
-- GstCaps *tmp;
-- tmp = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
-- gst_caps_unref (caps);
-- caps = tmp;
-- }
--
-- GST_DEBUG_OBJECT (ffmpegaudenc,
-- "audio caps, return template %" GST_PTR_FORMAT, caps);
--
-- return caps;
--}
--
--static gboolean
--gst_ffmpegaudenc_setcaps (GstFFMpegAudEnc * ffmpegaudenc, GstCaps * caps)
--{
-- GstCaps *other_caps;
-- GstCaps *allowed_caps;
-- GstCaps *icaps;
-- GstFFMpegAudEncClass *oclass =
-- (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
--
-- /* close old session */
-- if (ffmpegaudenc->opened) {
-- gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
-- ffmpegaudenc->opened = FALSE;
-- }
--
-- /* set defaults */
-- avcodec_get_context_defaults (ffmpegaudenc->context);
--
-- /* if we set it in _getcaps we should set it also in _link */
-- ffmpegaudenc->context->strict_std_compliance = -1;
--
-- /* user defined properties */
-- if (ffmpegaudenc->bitrate > 0) {
-- GST_INFO_OBJECT (ffmpegaudenc, "Setting avcontext to bitrate %d",
-- ffmpegaudenc->bitrate);
-- ffmpegaudenc->context->bit_rate = ffmpegaudenc->bitrate;
-- ffmpegaudenc->context->bit_rate_tolerance = ffmpegaudenc->bitrate;
-- } else {
-- GST_INFO_OBJECT (ffmpegaudenc, "Using avcontext default bitrate %d",
-- ffmpegaudenc->context->bit_rate);
-- }
--
-- /* RTP payload used for GOB production (for Asterisk) */
-- if (ffmpegaudenc->rtp_payload_size) {
-- ffmpegaudenc->context->rtp_payload_size = ffmpegaudenc->rtp_payload_size;
-- }
--
-- /* some other defaults */
-- ffmpegaudenc->context->rc_strategy = 2;
-- ffmpegaudenc->context->b_frame_strategy = 0;
-- ffmpegaudenc->context->coder_type = 0;
-- ffmpegaudenc->context->context_model = 0;
-- ffmpegaudenc->context->scenechange_threshold = 0;
-- ffmpegaudenc->context->inter_threshold = 0;
--
--
-- /* fetch pix_fmt and so on */
-- gst_ffmpeg_caps_with_codectype (oclass->in_plugin->type,
-- caps, ffmpegaudenc->context);
-- if (!ffmpegaudenc->context->time_base.den) {
-- ffmpegaudenc->context->time_base.den = 25;
-- ffmpegaudenc->context->time_base.num = 1;
-- ffmpegaudenc->context->ticks_per_frame = 1;
-- }
--
-- /* open codec */
-- if (gst_ffmpeg_avcodec_open (ffmpegaudenc->context, oclass->in_plugin) < 0) {
-- if (ffmpegaudenc->context->priv_data)
-- gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
-- if (ffmpegaudenc->context->stats_in)
-- g_free (ffmpegaudenc->context->stats_in);
-- GST_DEBUG_OBJECT (ffmpegaudenc, "avenc_%s: Failed to open FFMPEG codec",
-- oclass->in_plugin->name);
-- return FALSE;
-- }
--
-- /* second pass stats buffer no longer needed */
-- if (ffmpegaudenc->context->stats_in)
-- g_free (ffmpegaudenc->context->stats_in);
--
-- /* some codecs support more than one format, first auto-choose one */
-- GST_DEBUG_OBJECT (ffmpegaudenc, "picking an output format ...");
-- allowed_caps = gst_pad_get_allowed_caps (ffmpegaudenc->srcpad);
-- if (!allowed_caps) {
-- GST_DEBUG_OBJECT (ffmpegaudenc, "... but no peer, using template caps");
-- /* we need to copy because get_allowed_caps returns a ref, and
-- * get_pad_template_caps doesn't */
-- allowed_caps = gst_pad_get_pad_template_caps (ffmpegaudenc->srcpad);
-- }
-- GST_DEBUG_OBJECT (ffmpegaudenc, "chose caps %" GST_PTR_FORMAT, allowed_caps);
-- gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
-- oclass->in_plugin->type, allowed_caps, ffmpegaudenc->context);
--
-- /* try to set this caps on the other side */
-- other_caps = gst_ffmpeg_codecid_to_caps (oclass->in_plugin->id,
-- ffmpegaudenc->context, TRUE);
--
-- if (!other_caps) {
-- gst_caps_unref (allowed_caps);
-- gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
-- GST_DEBUG ("Unsupported codec - no caps found");
-- return FALSE;
-- }
--
-- icaps = gst_caps_intersect (allowed_caps, other_caps);
-- gst_caps_unref (allowed_caps);
-- gst_caps_unref (other_caps);
-- if (gst_caps_is_empty (icaps)) {
-- gst_caps_unref (icaps);
-- return FALSE;
-- }
--
-- if (gst_caps_get_size (icaps) > 1) {
-- GstCaps *newcaps;
--
-- newcaps =
-- gst_caps_new_full (gst_structure_copy (gst_caps_get_structure (icaps,
-- 0)), NULL);
-- gst_caps_unref (icaps);
-- icaps = newcaps;
-- }
--
-- if (!gst_pad_set_caps (ffmpegaudenc->srcpad, icaps)) {
-- gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
-- gst_caps_unref (icaps);
-- return FALSE;
-- }
-- gst_caps_unref (icaps);
--
-- /* success! */
-- ffmpegaudenc->opened = TRUE;
--
-- return TRUE;
--}
--
--
--static GstFlowReturn
--gst_ffmpegaudenc_encode_audio (GstFFMpegAudEnc * ffmpegaudenc,
-- guint8 * audio_in, guint in_size, guint max_size, GstClockTime timestamp,
-- GstClockTime duration, gboolean discont)
--{
-- GstBuffer *outbuf;
-- AVCodecContext *ctx;
-- GstMapInfo map;
-- gint res;
-- GstFlowReturn ret;
--
-- ctx = ffmpegaudenc->context;
--
-- /* We need to provide at least ffmpegs minimal buffer size */
-- outbuf = gst_buffer_new_and_alloc (max_size + FF_MIN_BUFFER_SIZE);
-- gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
--
-- GST_LOG_OBJECT (ffmpegaudenc, "encoding buffer of max size %d", max_size);
-- if (ffmpegaudenc->buffer_size != max_size)
-- ffmpegaudenc->buffer_size = max_size;
--
-- res = avcodec_encode_audio (ctx, map.data, max_size, (short *) audio_in);
--
-- if (res < 0) {
-- gst_buffer_unmap (outbuf, &map);
-- GST_ERROR_OBJECT (ffmpegaudenc, "Failed to encode buffer: %d", res);
-- gst_buffer_unref (outbuf);
-- return GST_FLOW_OK;
-- }
-- GST_LOG_OBJECT (ffmpegaudenc, "got output size %d", res);
-- gst_buffer_unmap (outbuf, &map);
-- gst_buffer_resize (outbuf, 0, res);
--
-- GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
-- GST_BUFFER_DURATION (outbuf) = duration;
-- if (discont)
-- GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
--
-- GST_LOG_OBJECT (ffmpegaudenc, "pushing size %d, timestamp %" GST_TIME_FORMAT,
-- res, GST_TIME_ARGS (timestamp));
--
-- ret = gst_pad_push (ffmpegaudenc->srcpad, outbuf);
--
-- return ret;
--}
--
--static GstFlowReturn
--gst_ffmpegaudenc_chain_audio (GstPad * pad, GstObject * parent,
-- GstBuffer * inbuf)
--{
-- GstFFMpegAudEnc *ffmpegaudenc;
-- GstFFMpegAudEncClass *oclass;
-- AVCodecContext *ctx;
-- GstClockTime timestamp, duration;
-- gsize size, frame_size;
-- gint osize;
-- GstFlowReturn ret;
-- gint out_size;
-- gboolean discont;
-- guint8 *in_data;
--
-- ffmpegaudenc = (GstFFMpegAudEnc *) parent;
-- oclass = (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
--
-- if (G_UNLIKELY (!ffmpegaudenc->opened))
-- goto not_negotiated;
--
-- ctx = ffmpegaudenc->context;
--
-- size = gst_buffer_get_size (inbuf);
-- timestamp = GST_BUFFER_TIMESTAMP (inbuf);
-- duration = GST_BUFFER_DURATION (inbuf);
-- discont = GST_BUFFER_IS_DISCONT (inbuf);
--
-- GST_DEBUG_OBJECT (ffmpegaudenc,
-- "Received time %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT
-- ", size %" G_GSIZE_FORMAT, GST_TIME_ARGS (timestamp),
-- GST_TIME_ARGS (duration), size);
--
-- frame_size = ctx->frame_size;
-- osize = av_get_bits_per_sample_format (ctx->sample_fmt) / 8;
--
-- if (frame_size > 1) {
-- /* we have a frame_size, feed the encoder multiples of this frame size */
-- guint avail, frame_bytes;
--
-- if (discont) {
-- GST_LOG_OBJECT (ffmpegaudenc, "DISCONT, clear adapter");
-- gst_adapter_clear (ffmpegaudenc->adapter);
-- ffmpegaudenc->discont = TRUE;
-- }
--
-- if (gst_adapter_available (ffmpegaudenc->adapter) == 0) {
-- /* lock on to new timestamp */
-- GST_LOG_OBJECT (ffmpegaudenc, "taking buffer timestamp %" GST_TIME_FORMAT,
-- GST_TIME_ARGS (timestamp));
-- ffmpegaudenc->adapter_ts = timestamp;
-- ffmpegaudenc->adapter_consumed = 0;
-- } else {
-- GstClockTime upstream_time;
-- GstClockTime consumed_time;
-- guint64 bytes;
--
-- /* use timestamp at head of the adapter */
-- consumed_time =
-- gst_util_uint64_scale (ffmpegaudenc->adapter_consumed, GST_SECOND,
-- ctx->sample_rate);
-- timestamp = ffmpegaudenc->adapter_ts + consumed_time;
-- GST_LOG_OBJECT (ffmpegaudenc, "taking adapter timestamp %" GST_TIME_FORMAT
-- " and adding consumed time %" GST_TIME_FORMAT,
-- GST_TIME_ARGS (ffmpegaudenc->adapter_ts),
-- GST_TIME_ARGS (consumed_time));
--
-- /* check with upstream timestamps, if too much deviation,
-- * forego some timestamp perfection in favour of upstream syncing
-- * (particularly in case these do not happen to come in multiple
-- * of frame size) */
-- upstream_time =
-- gst_adapter_prev_timestamp (ffmpegaudenc->adapter, &bytes);
-- if (GST_CLOCK_TIME_IS_VALID (upstream_time)) {
-- GstClockTimeDiff diff;
--
-- upstream_time +=
-- gst_util_uint64_scale (bytes, GST_SECOND,
-- ctx->sample_rate * osize * ctx->channels);
-- diff = upstream_time - timestamp;
-- /* relaxed difference, rather than half a sample or so ... */
-- if (diff > GST_SECOND / 10 || diff < -GST_SECOND / 10) {
-- GST_DEBUG_OBJECT (ffmpegaudenc, "adapter timestamp drifting, "
-- "taking upstream timestamp %" GST_TIME_FORMAT,
-- GST_TIME_ARGS (upstream_time));
-- timestamp = upstream_time;
-- /* samples corresponding to bytes */
-- ffmpegaudenc->adapter_consumed = bytes / (osize * ctx->channels);
-- ffmpegaudenc->adapter_ts = upstream_time -
-- gst_util_uint64_scale (ffmpegaudenc->adapter_consumed, GST_SECOND,
-- ctx->sample_rate);
-- ffmpegaudenc->discont = TRUE;
-- }
-- }
-- }
--
-- GST_LOG_OBJECT (ffmpegaudenc, "pushing buffer in adapter");
-- gst_adapter_push (ffmpegaudenc->adapter, inbuf);
--
-- /* first see how many bytes we need to feed to the decoder. */
-- frame_bytes = frame_size * osize * ctx->channels;
-- avail = gst_adapter_available (ffmpegaudenc->adapter);
--
-- GST_LOG_OBJECT (ffmpegaudenc, "frame_bytes %u, avail %u", frame_bytes,
-- avail);
--
-- /* while there is more than a frame size in the adapter, consume it */
-- while (avail >= frame_bytes) {
-- GST_LOG_OBJECT (ffmpegaudenc, "taking %u bytes from the adapter",
-- frame_bytes);
--
-- /* Note that we take frame_bytes and add frame_size.
-- * Makes sense when resyncing because you don't have to count channels
-- * or samplesize to divide by the samplerate */
--
-- /* take an audio buffer out of the adapter */
-- in_data = (guint8 *) gst_adapter_map (ffmpegaudenc->adapter, frame_bytes);
-- ffmpegaudenc->adapter_consumed += frame_size;
--
-- /* calculate timestamp and duration relative to start of adapter and to
-- * the amount of samples we consumed */
-- duration =
-- gst_util_uint64_scale (ffmpegaudenc->adapter_consumed, GST_SECOND,
-- ctx->sample_rate);
-- duration -= (timestamp - ffmpegaudenc->adapter_ts);
--
-- /* 4 times the input size should be big enough... */
-- out_size = frame_bytes * 4;
--
-- ret =
-- gst_ffmpegaudenc_encode_audio (ffmpegaudenc, in_data, frame_bytes,
-- out_size, timestamp, duration, ffmpegaudenc->discont);
--
-- gst_adapter_unmap (ffmpegaudenc->adapter);
-- gst_adapter_flush (ffmpegaudenc->adapter, frame_bytes);
--
-- if (ret != GST_FLOW_OK)
-- goto push_failed;
--
-- /* advance the adapter timestamp with the duration */
-- timestamp += duration;
--
-- ffmpegaudenc->discont = FALSE;
-- avail = gst_adapter_available (ffmpegaudenc->adapter);
-- }
-- GST_LOG_OBJECT (ffmpegaudenc, "%u bytes left in the adapter", avail);
-- } else {
-- GstMapInfo map;
-- /* we have no frame_size, feed the encoder all the data and expect a fixed
-- * output size */
-- int coded_bps = av_get_bits_per_sample (oclass->in_plugin->id);
--
-- GST_LOG_OBJECT (ffmpegaudenc, "coded bps %d, osize %d", coded_bps, osize);
--
-- out_size = size / osize;
-- if (coded_bps)
-- out_size = (out_size * coded_bps) / 8;
--
-- gst_buffer_map (inbuf, &map, GST_MAP_READ);
-- in_data = map.data;
-- size = map.size;
-- ret = gst_ffmpegaudenc_encode_audio (ffmpegaudenc, in_data, size, out_size,
-- timestamp, duration, discont);
-- gst_buffer_unmap (inbuf, &map);
-- gst_buffer_unref (inbuf);
--
-- if (ret != GST_FLOW_OK)
-- goto push_failed;
-- }
--
-- return GST_FLOW_OK;
--
-- /* ERRORS */
--not_negotiated:
-- {
-- GST_ELEMENT_ERROR (ffmpegaudenc, CORE, NEGOTIATION, (NULL),
-- ("not configured to input format before data start"));
-- gst_buffer_unref (inbuf);
-- return GST_FLOW_NOT_NEGOTIATED;
-- }
--push_failed:
-- {
-- GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to push buffer %d (%s)", ret,
-- gst_flow_get_name (ret));
-- return ret;
-- }
--}
--
--static gboolean
--gst_ffmpegaudenc_event_sink (GstPad * pad, GstObject * parent, GstEvent * event)
--{
-- GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) parent;
--
-- switch (GST_EVENT_TYPE (event)) {
-- case GST_EVENT_CAPS:
-- {
-- GstCaps *caps;
-- gboolean ret;
--
-- gst_event_parse_caps (event, &caps);
-- ret = gst_ffmpegaudenc_setcaps (ffmpegaudenc, caps);
-- gst_event_unref (event);
-- return ret;
-- }
-- default:
-- break;
-- }
--
-- return gst_pad_event_default (pad, parent, event);
--}
--
--static gboolean
--gst_ffmpegaudenc_query_sink (GstPad * pad, GstObject * parent, GstQuery * query)
--{
-- GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) parent;
-- gboolean res = FALSE;
--
-- switch (GST_QUERY_TYPE (query)) {
-- case GST_QUERY_CAPS:
-- {
-- GstCaps *filter, *caps;
--
-- gst_query_parse_caps (query, &filter);
-- caps = gst_ffmpegaudenc_getcaps (ffmpegaudenc, filter);
-- gst_query_set_caps_result (query, caps);
-- gst_caps_unref (caps);
-- res = TRUE;
-- break;
-- }
-- default:
-- res = gst_pad_query_default (pad, parent, query);
-- break;
-- }
--
-- return res;
--}
--
--static void
--gst_ffmpegaudenc_set_property (GObject * object,
-- guint prop_id, const GValue * value, GParamSpec * pspec)
--{
-- GstFFMpegAudEnc *ffmpegaudenc;
--
-- /* Get a pointer of the right type. */
-- ffmpegaudenc = (GstFFMpegAudEnc *) (object);
--
-- if (ffmpegaudenc->opened) {
-- GST_WARNING_OBJECT (ffmpegaudenc,
-- "Can't change properties once decoder is setup !");
-- return;
-- }
--
-- /* Check the argument id to see which argument we're setting. */
-- switch (prop_id) {
-- case ARG_BIT_RATE:
-- ffmpegaudenc->bitrate = g_value_get_int (value);
-- break;
-- case ARG_BUFSIZE:
-- break;
-- case ARG_RTP_PAYLOAD_SIZE:
-- ffmpegaudenc->rtp_payload_size = g_value_get_int (value);
-- break;
-- default:
-- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-- break;
-- }
--}
--
--/* The set function is simply the inverse of the get fuction. */
--static void
--gst_ffmpegaudenc_get_property (GObject * object,
-- guint prop_id, GValue * value, GParamSpec * pspec)
--{
-- GstFFMpegAudEnc *ffmpegaudenc;
--
-- /* It's not null if we got it, but it might not be ours */
-- ffmpegaudenc = (GstFFMpegAudEnc *) (object);
--
-- switch (prop_id) {
-- case ARG_BIT_RATE:
-- g_value_set_int (value, ffmpegaudenc->bitrate);
-- break;
-- break;
-- case ARG_BUFSIZE:
-- g_value_set_int (value, ffmpegaudenc->buffer_size);
-- break;
-- case ARG_RTP_PAYLOAD_SIZE:
-- g_value_set_int (value, ffmpegaudenc->rtp_payload_size);
-- break;
-- default:
-- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-- break;
-- }
--}
--
--static GstStateChangeReturn
--gst_ffmpegaudenc_change_state (GstElement * element, GstStateChange transition)
--{
-- GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) element;
-- GstStateChangeReturn result;
--
-- switch (transition) {
-- default:
-- break;
-- }
--
-- result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
--
-- switch (transition) {
-- case GST_STATE_CHANGE_PAUSED_TO_READY:
-- if (ffmpegaudenc->opened) {
-- gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
-- ffmpegaudenc->opened = FALSE;
-- }
-- gst_adapter_clear (ffmpegaudenc->adapter);
-- break;
-- default:
-- break;
-- }
-- return result;
--}
--
--gboolean
--gst_ffmpegaudenc_register (GstPlugin * plugin)
--{
-- GTypeInfo typeinfo = {
-- sizeof (GstFFMpegAudEncClass),
-- (GBaseInitFunc) gst_ffmpegaudenc_base_init,
-- NULL,
-- (GClassInitFunc) gst_ffmpegaudenc_class_init,
-- NULL,
-- NULL,
-- sizeof (GstFFMpegAudEnc),
-- 0,
-- (GInstanceInitFunc) gst_ffmpegaudenc_init,
-- };
-- GType type;
-- AVCodec *in_plugin;
--
--
-- GST_LOG ("Registering encoders");
--
-- in_plugin = av_codec_next (NULL);
-- while (in_plugin) {
-- gchar *type_name;
--
-- /* Skip non-AV codecs */
-- if (in_plugin->type != AVMEDIA_TYPE_AUDIO)
-- goto next;
--
-- /* no quasi codecs, please */
-- if ((in_plugin->id >= CODEC_ID_PCM_S16LE &&
-- in_plugin->id <= CODEC_ID_PCM_BLURAY)) {
-- goto next;
-- }
--
-- /* No encoders depending on external libraries (we don't build them, but
-- * people who build against an external ffmpeg might have them.
-- * We have native gstreamer plugins for all of those libraries anyway. */
-- if (!strncmp (in_plugin->name, "lib", 3)) {
-- GST_DEBUG
-- ("Not using external library encoder %s. Use the gstreamer-native ones instead.",
-- in_plugin->name);
-- goto next;
-- }
--
-- /* only encoders */
-- if (!in_plugin->encode) {
-- goto next;
-- }
--
-- /* FIXME : We should have a method to know cheaply whether we have a mapping
-- * for the given plugin or not */
--
-- GST_DEBUG ("Trying plugin %s [%s]", in_plugin->name, in_plugin->long_name);
--
-- /* no codecs for which we're GUARANTEED to have better alternatives */
-- if (!strcmp (in_plugin->name, "vorbis")
-- || !strcmp (in_plugin->name, "flac")) {
-- GST_LOG ("Ignoring encoder %s", in_plugin->name);
-- goto next;
-- }
--
-- /* construct the type */
-- type_name = g_strdup_printf ("avenc_%s", in_plugin->name);
--
-- type = g_type_from_name (type_name);
--
-- if (!type) {
--
-- /* create the glib type now */
-- type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
-- g_type_set_qdata (type, GST_FFENC_PARAMS_QDATA, (gpointer) in_plugin);
--
-- {
-- static const GInterfaceInfo preset_info = {
-- NULL,
-- NULL,
-- NULL
-- };
-- g_type_add_interface_static (type, GST_TYPE_PRESET, &preset_info);
-- }
-- }
--
-- if (!gst_element_register (plugin, type_name, GST_RANK_SECONDARY, type)) {
-- g_free (type_name);
-- return FALSE;
-- }
--
-- g_free (type_name);
--
-- next:
-- in_plugin = av_codec_next (in_plugin);
-- }
--
-- GST_LOG ("Finished registering encoders");
--
-- return TRUE;
--}
-diff --git a/ext/libav/gstavenc.h b/ext/libav/gstavenc.h
-deleted file mode 100644
-index 019b168..0000000
---- a/ext/libav/gstavenc.h
-+++ /dev/null
-@@ -1,82 +0,0 @@
--/* 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.
-- */
--
--/* First, include the header file for the plugin, to bring in the
-- * object definition and other useful things.
-- */
--
--#ifndef __GST_FFMPEGAUDENC_H__
--#define __GST_FFMPEGAUDENC_H__
--
--G_BEGIN_DECLS
--
--#include <gst/base/gstadapter.h>
--
--typedef struct _GstFFMpegAudEnc GstFFMpegAudEnc;
--
--struct _GstFFMpegAudEnc
--{
-- GstElement element;
--
-- /* We need to keep track of our pads, so we do so here. */
-- GstPad *srcpad;
-- GstPad *sinkpad;
--
-- AVCodecContext *context;
-- gboolean opened;
-- GstClockTime adapter_ts;
-- guint64 adapter_consumed;
-- GstAdapter *adapter;
-- gboolean discont;
--
-- /* cache */
-- gint bitrate;
-- gint buffer_size;
-- gint rtp_payload_size;
--
-- /* other settings are copied over straight,
-- * include a context here, rather than copy-and-past it from avcodec.h */
-- AVCodecContext config;
--};
--
--typedef struct _GstFFMpegAudEncClass GstFFMpegAudEncClass;
--
--struct _GstFFMpegAudEncClass
--{
-- GstElementClass parent_class;
--
-- AVCodec *in_plugin;
-- GstPadTemplate *srctempl, *sinktempl;
-- GstCaps *sinkcaps;
--};
--
--#define GST_TYPE_FFMPEGAUDENC \
-- (gst_ffmpegaudenc_get_type())
--#define GST_FFMPEGAUDENC(obj) \
-- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGAUDENC,GstFFMpegAudEnc))
--#define GST_FFMPEGAUDENC_CLASS(klass) \
-- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGAUDENC,GstFFMpegAudEncClass))
--#define GST_IS_FFMPEGAUDENC(obj) \
-- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGAUDENC))
--#define GST_IS_FFMPEGAUDENC_CLASS(klass) \
-- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGAUDENC))
--
--G_END_DECLS
--
--#endif /* __GST_FFMPEGAUDENC_H__ */
-diff --git a/ext/libav/gstavmux.c b/ext/libav/gstavmux.c
-index d9e8969..b302270 100644
---- a/ext/libav/gstavmux.c
-+++ b/ext/libav/gstavmux.c
-@@ -13,8 +13,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
- #ifdef HAVE_CONFIG_H
-@@ -24,12 +24,14 @@
- #include <string.h>
-
- #include <libavformat/avformat.h>
-+#include <libavutil/opt.h>
- #include <gst/gst.h>
- #include <gst/base/gstcollectpads.h>
-
- #include "gstav.h"
- #include "gstavcodecmap.h"
- #include "gstavutils.h"
-+#include "gstavprotocol.h"
-
- typedef struct _GstFFMpegMux GstFFMpegMux;
- typedef struct _GstFFMpegMuxPad GstFFMpegMuxPad;
-@@ -57,8 +59,8 @@ struct _GstFFMpegMux
- /*< private > */
- /* event_function is the collectpads default eventfunction */
- GstPadEventFunction event_function;
-- int preload;
- int max_delay;
-+ int preload;
- };
-
- typedef struct _GstFFMpegMuxClass GstFFMpegMuxClass;
-@@ -89,12 +91,6 @@ enum
-
- enum
- {
-- ARG_0,
-- /* FILL ME */
--};
--
--enum
--{
- PROP_0,
- PROP_PRELOAD,
- PROP_MAXDELAY
-@@ -301,8 +297,8 @@ gst_ffmpegmux_class_init (GstFFMpegMuxClass * klass)
-
- g_object_class_install_property (gobject_class, PROP_PRELOAD,
- g_param_spec_int ("preload", "preload",
-- "Set the initial demux-decode delay (in microseconds)", 0, G_MAXINT,
-- 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-+ "Set the initial demux-decode delay (in microseconds)",
-+ 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (gobject_class, PROP_MAXDELAY,
- g_param_spec_int ("maxdelay", "maxdelay",
-@@ -329,17 +325,13 @@ gst_ffmpegmux_init (GstFFMpegMux * ffmpegmux, GstFFMpegMuxClass * g_class)
- gst_collect_pads_set_function (ffmpegmux->collect,
- (GstCollectPadsFunction) gst_ffmpegmux_collected, ffmpegmux);
-
-- ffmpegmux->context = g_new0 (AVFormatContext, 1);
-+ ffmpegmux->context = avformat_alloc_context ();
- ffmpegmux->context->oformat = oclass->in_plugin;
- ffmpegmux->context->nb_streams = 0;
-- g_snprintf (ffmpegmux->context->filename,
-- sizeof (ffmpegmux->context->filename),
-- "gstreamer://%p", ffmpegmux->srcpad);
- ffmpegmux->opened = FALSE;
-
- ffmpegmux->videopads = 0;
- ffmpegmux->audiopads = 0;
-- ffmpegmux->preload = 0;
- ffmpegmux->max_delay = 0;
- }
-
-@@ -391,7 +383,9 @@ gst_ffmpegmux_finalize (GObject * object)
- {
- GstFFMpegMux *ffmpegmux = (GstFFMpegMux *) object;
-
-- g_free (ffmpegmux->context);
-+ avformat_free_context (ffmpegmux->context);
-+ ffmpegmux->context = NULL;
-+
- gst_object_unref (ffmpegmux->collect);
-
- if (G_OBJECT_CLASS (parent_class)->finalize)
-@@ -445,10 +439,10 @@ gst_ffmpegmux_request_new_pad (GstElement * element,
- gst_element_add_pad (element, pad);
-
- /* AVStream needs to be created */
-- st = av_new_stream (ffmpegmux->context, collect_pad->padnum);
-+ st = avformat_new_stream (ffmpegmux->context, NULL);
-+ st->id = collect_pad->padnum;
- st->codec->codec_type = type;
- st->codec->codec_id = CODEC_ID_NONE; /* this is a check afterwards */
-- st->stream_copy = 1; /* we're not the actual encoder */
- st->codec->bit_rate = bitrate;
- st->codec->frame_size = framesize;
- /* we fill in codec during capsnego */
-@@ -480,7 +474,7 @@ gst_ffmpegmux_setcaps (GstPad * pad, GstCaps * caps)
- collect_pad = (GstFFMpegMuxPad *) gst_pad_get_element_private (pad);
-
- st = ffmpegmux->context->streams[collect_pad->padnum];
-- ffmpegmux->context->preload = ffmpegmux->preload;
-+ av_opt_set_int (&ffmpegmux->context, "preload", ffmpegmux->preload, 0);
- ffmpegmux->context->max_delay = ffmpegmux->max_delay;
-
- /* for the format-specific guesses, we'll go to
-@@ -554,7 +548,7 @@ gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data)
-
- /* open "file" (gstreamer protocol to next element) */
- if (!ffmpegmux->opened) {
-- int open_flags = URL_WRONLY;
-+ int open_flags = AVIO_FLAG_WRITE;
-
- /* we do need all streams to have started capsnego,
- * or things will go horribly wrong */
-@@ -648,21 +642,15 @@ gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data)
- open_flags |= GST_FFMPEG_URL_STREAMHEADER;
- }
-
-- if (url_fopen (&ffmpegmux->context->pb,
-- ffmpegmux->context->filename, open_flags) < 0) {
-+ if (gst_ffmpegdata_open (ffmpegmux->srcpad, open_flags,
-+ &ffmpegmux->context->pb) < 0) {
- GST_ELEMENT_ERROR (ffmpegmux, LIBRARY, TOO_LAZY, (NULL),
- ("Failed to open stream context in avmux"));
- return GST_FLOW_ERROR;
- }
-
-- if (av_set_parameters (ffmpegmux->context, NULL) < 0) {
-- GST_ELEMENT_ERROR (ffmpegmux, LIBRARY, INIT, (NULL),
-- ("Failed to initialize muxer"));
-- return GST_FLOW_ERROR;
-- }
--
- /* now open the mux format */
-- if (av_write_header (ffmpegmux->context) < 0) {
-+ if (avformat_write_header (ffmpegmux->context, NULL) < 0) {
- GST_ELEMENT_ERROR (ffmpegmux, LIBRARY, SETTINGS, (NULL),
- ("Failed to write file header - check codec settings"));
- return GST_FLOW_ERROR;
-@@ -672,7 +660,7 @@ gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data)
- ffmpegmux->opened = TRUE;
-
- /* flush the header so it will be used as streamheader */
-- put_flush_packet (ffmpegmux->context->pb);
-+ avio_flush (ffmpegmux->context->pb);
- }
-
- /* take the one with earliest timestamp,
-@@ -779,8 +767,8 @@ gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data)
- /* close down */
- av_write_trailer (ffmpegmux->context);
- ffmpegmux->opened = FALSE;
-- put_flush_packet (ffmpegmux->context->pb);
-- url_fclose (ffmpegmux->context->pb);
-+ avio_flush (ffmpegmux->context->pb);
-+ gst_ffmpegdata_close (ffmpegmux->context->pb);
- gst_pad_push_event (ffmpegmux->srcpad, gst_event_new_eos ());
- return GST_FLOW_EOS;
- }
-@@ -818,7 +806,7 @@ gst_ffmpegmux_change_state (GstElement * element, GstStateChange transition)
- gst_tag_setter_reset_tags (GST_TAG_SETTER (ffmpegmux));
- if (ffmpegmux->opened) {
- ffmpegmux->opened = FALSE;
-- url_fclose (ffmpegmux->context->pb);
-+ gst_ffmpegdata_close (ffmpegmux->context->pb);
- }
- break;
- case GST_STATE_CHANGE_READY_TO_NULL:
-diff --git a/ext/libav/gstavpipe.h b/ext/libav/gstavpipe.h
-deleted file mode 100644
-index 5ded77f..0000000
---- a/ext/libav/gstavpipe.h
-+++ /dev/null
-@@ -1,72 +0,0 @@
--/* GStreamer
-- * Copyright (C) <2006> Mark Nauwelaerts <manauw@skynet.be>
-- *
-- * 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_FFMPEGPIPE_H__
--#define __GST_FFMPEGPIPE_H__
--
--#include <gst/base/gstadapter.h>
--#include "gstav.h"
--
--G_BEGIN_DECLS
--
--/* pipe protocol helpers */
--#define GST_FFMPEG_PIPE_MUTEX_LOCK(m) G_STMT_START { \
-- GST_LOG_OBJECT (m, "locking tlock from thread %p", g_thread_self ()); \
-- g_mutex_lock (&m->tlock); \
-- GST_LOG_OBJECT (m, "locked tlock from thread %p", g_thread_self ()); \
--} G_STMT_END
--
--#define GST_FFMPEG_PIPE_MUTEX_UNLOCK(m) G_STMT_START { \
-- GST_LOG_OBJECT (m, "unlocking tlock from thread %p", g_thread_self ()); \
-- g_mutex_unlock (&m->tlock); \
--} G_STMT_END
--
--#define GST_FFMPEG_PIPE_WAIT(m) G_STMT_START { \
-- GST_LOG_OBJECT (m, "thread %p waiting", g_thread_self ()); \
-- g_cond_wait (&m->cond, &m->tlock); \
--} G_STMT_END
--
--#define GST_FFMPEG_PIPE_SIGNAL(m) G_STMT_START { \
-- GST_LOG_OBJECT (m, "signalling from thread %p", g_thread_self ()); \
-- g_cond_signal (&m->cond); \
--} G_STMT_END
--
--typedef struct _GstFFMpegPipe GstFFMpegPipe;
--
--struct _GstFFMpegPipe
--{
-- /* lock for syncing */
-- GMutex tlock;
-- /* with TLOCK */
-- /* signals counterpart thread to have a look */
-- GCond cond;
-- /* seen eos */
-- gboolean eos;
-- /* flowreturn obtained by src task */
-- GstFlowReturn srcresult;
-- /* adpater collecting data */
-- GstAdapter *adapter;
-- /* amount needed in adapter by src task */
-- guint needed;
--};
--
--G_END_DECLS
--
--#endif /* __GST_FFMPEGPIPE_H__ */
-diff --git a/ext/libav/gstavprotocol.c b/ext/libav/gstavprotocol.c
-index 9c4b052..5d01eaa 100644
---- a/ext/libav/gstavprotocol.c
-+++ b/ext/libav/gstavprotocol.c
-@@ -14,8 +14,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
- #ifdef HAVE_CONFIG_H
-@@ -29,7 +29,7 @@
- #include <gst/gst.h>
-
- #include "gstav.h"
--#include "gstavpipe.h"
-+#include "gstavprotocol.h"
-
- typedef struct _GstProtocolInfo GstProtocolInfo;
-
-@@ -43,63 +43,14 @@ struct _GstProtocolInfo
- };
-
- static int
--gst_ffmpegdata_open (URLContext * h, const char *filename, int flags)
--{
-- GstProtocolInfo *info;
-- GstPad *pad;
--
-- GST_LOG ("Opening %s", filename);
--
-- info = g_new0 (GstProtocolInfo, 1);
--
-- info->set_streamheader = flags & GST_FFMPEG_URL_STREAMHEADER;
-- flags &= ~GST_FFMPEG_URL_STREAMHEADER;
-- h->flags &= ~GST_FFMPEG_URL_STREAMHEADER;
--
-- /* we don't support R/W together */
-- if (flags != URL_RDONLY && flags != URL_WRONLY) {
-- GST_WARNING ("Only read-only or write-only are supported");
-- return -EINVAL;
-- }
--
-- if (sscanf (&filename[12], "%p", &pad) != 1) {
-- GST_WARNING ("could not decode pad from %s", filename);
-- return -EIO;
-- }
--
-- /* make sure we're a pad and that we're of the right type */
-- g_return_val_if_fail (GST_IS_PAD (pad), -EINVAL);
--
-- switch (flags) {
-- case URL_RDONLY:
-- g_return_val_if_fail (GST_PAD_IS_SINK (pad), -EINVAL);
-- break;
-- case URL_WRONLY:
-- g_return_val_if_fail (GST_PAD_IS_SRC (pad), -EINVAL);
-- break;
-- }
--
-- info->eos = FALSE;
-- info->pad = pad;
-- info->offset = 0;
--
-- h->priv_data = (void *) info;
-- h->is_streamed = FALSE;
-- h->max_packet_size = 0;
--
-- return 0;
--}
--
--static int
--gst_ffmpegdata_peek (URLContext * h, unsigned char *buf, int size)
-+gst_ffmpegdata_peek (void *priv_data, unsigned char *buf, int size)
- {
- GstProtocolInfo *info;
- GstBuffer *inbuf = NULL;
- GstFlowReturn ret;
- int total = 0;
-
-- g_return_val_if_fail (h->flags == URL_RDONLY, AVERROR (EIO));
-- info = (GstProtocolInfo *) h->priv_data;
-+ info = (GstProtocolInfo *) priv_data;
-
- GST_DEBUG ("Pulling %d bytes at position %" G_GUINT64_FORMAT, size,
- info->offset);
-@@ -131,17 +82,17 @@ gst_ffmpegdata_peek (URLContext * h, unsigned char *buf, int size)
- }
-
- static int
--gst_ffmpegdata_read (URLContext * h, unsigned char *buf, int size)
-+gst_ffmpegdata_read (void *priv_data, unsigned char *buf, int size)
- {
- gint res;
- GstProtocolInfo *info;
-
-- info = (GstProtocolInfo *) h->priv_data;
-+ info = (GstProtocolInfo *) priv_data;
-
- GST_DEBUG ("Reading %d bytes of data at position %" G_GUINT64_FORMAT, size,
- info->offset);
-
-- res = gst_ffmpegdata_peek (h, buf, size);
-+ res = gst_ffmpegdata_peek (priv_data, buf, size);
- if (res >= 0)
- info->offset += res;
-
-@@ -151,15 +102,13 @@ gst_ffmpegdata_read (URLContext * h, unsigned char *buf, int size)
- }
-
- static int
--gst_ffmpegdata_write (URLContext * h, const unsigned char *buf, int size)
-+gst_ffmpegdata_write (void *priv_data, uint8_t * buf, int size)
- {
- GstProtocolInfo *info;
- GstBuffer *outbuf;
-
- GST_DEBUG ("Writing %d bytes", size);
-- info = (GstProtocolInfo *) h->priv_data;
--
-- g_return_val_if_fail (h->flags != URL_RDONLY, -EIO);
-+ info = (GstProtocolInfo *) priv_data;
-
- /* create buffer and push data further */
- outbuf = gst_buffer_new_and_alloc (size);
-@@ -174,7 +123,7 @@ gst_ffmpegdata_write (URLContext * h, const unsigned char *buf, int size)
- }
-
- static int64_t
--gst_ffmpegdata_seek (URLContext * h, int64_t pos, int whence)
-+gst_ffmpegdata_seek (void *priv_data, int64_t pos, int whence)
- {
- GstProtocolInfo *info;
- guint64 newpos = 0, oldpos;
-@@ -182,76 +131,68 @@ gst_ffmpegdata_seek (URLContext * h, int64_t pos, int whence)
- GST_DEBUG ("Seeking to %" G_GINT64_FORMAT ", whence=%d",
- (gint64) pos, whence);
-
-- info = (GstProtocolInfo *) h->priv_data;
-+ info = (GstProtocolInfo *) priv_data;
-
- /* TODO : if we are push-based, we need to return sensible info */
-
-- switch (h->flags) {
-- case URL_RDONLY:
-- {
-- /* sinkpad */
-- switch (whence) {
-- case SEEK_SET:
-- newpos = (guint64) pos;
-- break;
-- case SEEK_CUR:
-- newpos = info->offset + pos;
-- break;
-- case SEEK_END:
-- case AVSEEK_SIZE:
-- /* ffmpeg wants to know the current end position in bytes ! */
-- {
-- gint64 duration;
--
-- GST_DEBUG ("Seek end");
--
-- if (gst_pad_is_linked (info->pad))
-- if (gst_pad_query_duration (GST_PAD_PEER (info->pad),
-- GST_FORMAT_BYTES, &duration))
-- newpos = ((guint64) duration) + pos;
-- }
-- break;
-- default:
-- g_assert (0);
-- break;
-+ if (GST_PAD_IS_SINK (info->pad)) {
-+ /* sinkpad */
-+ switch (whence) {
-+ case SEEK_SET:
-+ newpos = (guint64) pos;
-+ break;
-+ case SEEK_CUR:
-+ newpos = info->offset + pos;
-+ break;
-+ case SEEK_END:
-+ case AVSEEK_SIZE:
-+ /* ffmpeg wants to know the current end position in bytes ! */
-+ {
-+ gint64 duration;
-+
-+ GST_DEBUG ("Seek end");
-+
-+ if (gst_pad_is_linked (info->pad))
-+ if (gst_pad_query_duration (GST_PAD_PEER (info->pad),
-+ GST_FORMAT_BYTES, &duration))
-+ newpos = ((guint64) duration) + pos;
- }
-- /* FIXME : implement case for push-based behaviour */
-- if (whence != AVSEEK_SIZE)
-- info->offset = newpos;
-+ break;
-+ default:
-+ g_assert (0);
-+ break;
- }
-- break;
-- case URL_WRONLY:
-- {
-- GstSegment segment;
--
-- oldpos = info->offset;
--
-- /* srcpad */
-- switch (whence) {
-- case SEEK_SET:
-- {
-- info->offset = (guint64) pos;
-- break;
-- }
-- case SEEK_CUR:
-- info->offset += pos;
-- break;
-- default:
-- break;
-+ /* FIXME : implement case for push-based behaviour */
-+ if (whence != AVSEEK_SIZE)
-+ info->offset = newpos;
-+ } else if (GST_PAD_IS_SRC (info->pad)) {
-+ GstSegment segment;
-+
-+ oldpos = info->offset;
-+
-+ /* srcpad */
-+ switch (whence) {
-+ case SEEK_SET:
-+ {
-+ info->offset = (guint64) pos;
-+ break;
- }
-- newpos = info->offset;
-+ case SEEK_CUR:
-+ info->offset += pos;
-+ break;
-+ default:
-+ break;
-+ }
-+ newpos = info->offset;
-
-- if (newpos != oldpos) {
-- gst_segment_init (&segment, GST_FORMAT_BYTES);
-- segment.start = newpos;
-- segment.time = newpos;
-- gst_pad_push_event (info->pad, gst_event_new_segment (&segment));
-- }
-- break;
-+ if (newpos != oldpos) {
-+ gst_segment_init (&segment, GST_FORMAT_BYTES);
-+ segment.start = newpos;
-+ segment.time = newpos;
-+ gst_pad_push_event (info->pad, gst_event_new_segment (&segment));
- }
-- default:
-- g_assert (0);
-- break;
-+ } else {
-+ g_assert_not_reached ();
- }
-
- GST_DEBUG ("Now at offset %" G_GUINT64_FORMAT " (returning %" G_GUINT64_FORMAT
-@@ -259,84 +200,90 @@ gst_ffmpegdata_seek (URLContext * h, int64_t pos, int whence)
- return newpos;
- }
-
--static int
--gst_ffmpegdata_close (URLContext * h)
-+int
-+gst_ffmpegdata_close (AVIOContext * h)
- {
- GstProtocolInfo *info;
-
-- info = (GstProtocolInfo *) h->priv_data;
-+ info = (GstProtocolInfo *) h->opaque;
- if (info == NULL)
- return 0;
-
- GST_LOG ("Closing file");
-
-- switch (h->flags) {
-- case URL_WRONLY:
-- {
-- /* send EOS - that closes down the stream */
-- gst_pad_push_event (info->pad, gst_event_new_eos ());
-- break;
-- }
-- default:
-- break;
-+ if (GST_PAD_IS_SRC (info->pad)) {
-+ /* send EOS - that closes down the stream */
-+ gst_pad_push_event (info->pad, gst_event_new_eos ());
- }
-
- /* clean up data */
- g_free (info);
-- h->priv_data = NULL;
-+ h->opaque = NULL;
-+
-+ av_freep (&h->buffer);
-+ av_free (h);
-
- return 0;
- }
-
-+int
-+gst_ffmpegdata_open (GstPad * pad, int flags, AVIOContext ** context)
-+{
-+ GstProtocolInfo *info;
-+ static const int buffer_size = 4096;
-+ unsigned char *buffer = NULL;
-
--URLProtocol gstreamer_protocol = {
-- /*.name = */ "gstreamer",
-- /*.url_open = */ gst_ffmpegdata_open,
-- /*.url_read = */ gst_ffmpegdata_read,
-- /*.url_write = */ gst_ffmpegdata_write,
-- /*.url_seek = */ gst_ffmpegdata_seek,
-- /*.url_close = */ gst_ffmpegdata_close,
--};
-+ info = g_new0 (GstProtocolInfo, 1);
-
-+ info->set_streamheader = flags & GST_FFMPEG_URL_STREAMHEADER;
-+ flags &= ~GST_FFMPEG_URL_STREAMHEADER;
-
--/* specialized protocol for cross-thread pushing,
-- * based on ffmpeg's pipe protocol */
-+ /* we don't support R/W together */
-+ if ((flags & AVIO_FLAG_WRITE) && (flags & AVIO_FLAG_READ)) {
-+ GST_WARNING ("Only read-only or write-only are supported");
-+ return -EINVAL;
-+ }
-
--static int
--gst_ffmpeg_pipe_open (URLContext * h, const char *filename, int flags)
--{
-- GstFFMpegPipe *ffpipe;
-+ /* make sure we're a pad and that we're of the right type */
-+ g_return_val_if_fail (GST_IS_PAD (pad), -EINVAL);
-
-- GST_LOG ("Opening %s", filename);
-+ if ((flags & AVIO_FLAG_READ))
-+ g_return_val_if_fail (GST_PAD_IS_SINK (pad), -EINVAL);
-+ if ((flags & AVIO_FLAG_WRITE))
-+ g_return_val_if_fail (GST_PAD_IS_SRC (pad), -EINVAL);
-
-- /* we don't support W together */
-- if (flags != URL_RDONLY) {
-- GST_WARNING ("Only read-only is supported");
-- return -EINVAL;
-- }
-+ info->eos = FALSE;
-+ info->pad = pad;
-+ info->offset = 0;
-
-- if (sscanf (&filename[10], "%p", &ffpipe) != 1) {
-- GST_WARNING ("could not decode pipe info from %s", filename);
-- return -EIO;
-+ buffer = av_malloc (buffer_size);
-+ if (buffer == NULL) {
-+ GST_WARNING ("Failed to allocate buffer");
-+ return -ENOMEM;
- }
-
-- /* sanity check */
-- g_return_val_if_fail (GST_IS_ADAPTER (ffpipe->adapter), -EINVAL);
--
-- h->priv_data = (void *) ffpipe;
-- h->is_streamed = TRUE;
-- h->max_packet_size = 0;
-+ *context =
-+ avio_alloc_context (buffer, buffer_size, flags, (void *) info,
-+ gst_ffmpegdata_read, gst_ffmpegdata_write, gst_ffmpegdata_seek);
-+ (*context)->seekable = AVIO_SEEKABLE_NORMAL;
-+ if (!(flags & AVIO_FLAG_WRITE)) {
-+ (*context)->buf_ptr = (*context)->buf_end;
-+ (*context)->write_flag = 0;
-+ }
-
- return 0;
- }
-
-+/* specialized protocol for cross-thread pushing,
-+ * based on ffmpeg's pipe protocol */
-+
- static int
--gst_ffmpeg_pipe_read (URLContext * h, unsigned char *buf, int size)
-+gst_ffmpeg_pipe_read (void *priv_data, uint8_t * buf, int size)
- {
- GstFFMpegPipe *ffpipe;
- guint available;
-
-- ffpipe = (GstFFMpegPipe *) h->priv_data;
-+ ffpipe = (GstFFMpegPipe *) priv_data;
-
- GST_LOG ("requested size %d", size);
-
-@@ -366,21 +313,38 @@ gst_ffmpeg_pipe_read (URLContext * h, unsigned char *buf, int size)
- return size;
- }
-
--static int
--gst_ffmpeg_pipe_close (URLContext * h)
-+int
-+gst_ffmpeg_pipe_close (AVIOContext * h)
- {
- GST_LOG ("Closing pipe");
-
-- h->priv_data = NULL;
-+ h->opaque = NULL;
-+ av_freep (&h->buffer);
-+ av_free (h);
-
- return 0;
- }
-
--URLProtocol gstpipe_protocol = {
-- "gstpipe",
-- gst_ffmpeg_pipe_open,
-- gst_ffmpeg_pipe_read,
-- NULL,
-- NULL,
-- gst_ffmpeg_pipe_close,
--};
-+int
-+gst_ffmpeg_pipe_open (GstFFMpegPipe * ffpipe, int flags, AVIOContext ** context)
-+{
-+ static const int buffer_size = 4096;
-+ unsigned char *buffer = NULL;
-+
-+ /* sanity check */
-+ g_return_val_if_fail (GST_IS_ADAPTER (ffpipe->adapter), -EINVAL);
-+
-+ buffer = av_malloc (buffer_size);
-+ if (buffer == NULL) {
-+ GST_WARNING ("Failed to allocate buffer");
-+ return -ENOMEM;
-+ }
-+
-+ *context =
-+ avio_alloc_context (buffer, buffer_size, 0, (void *) ffpipe,
-+ gst_ffmpeg_pipe_read, NULL, NULL);
-+ (*context)->seekable = 0;
-+ (*context)->buf_ptr = (*context)->buf_end;
-+
-+ return 0;
-+}
-diff --git a/ext/libav/gstavprotocol.h b/ext/libav/gstavprotocol.h
-new file mode 100644
-index 0000000..f4b2ba8
---- /dev/null
-+++ b/ext/libav/gstavprotocol.h
-@@ -0,0 +1,78 @@
-+/* GStreamer
-+ * Copyright (C) <2006> Mark Nauwelaerts <manauw@skynet.be>
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Library General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Library General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Library General Public
-+ * License along with this library; if not, write to the
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
-+ */
-+
-+
-+#ifndef __GST_FFMPEGPROTOCOL_H__
-+#define __GST_FFMPEGPROTOCOL_H__
-+
-+#include <gst/base/gstadapter.h>
-+#include "gstav.h"
-+
-+G_BEGIN_DECLS
-+
-+/* pipe protocol helpers */
-+#define GST_FFMPEG_PIPE_MUTEX_LOCK(m) G_STMT_START { \
-+ GST_LOG_OBJECT (m, "locking tlock from thread %p", g_thread_self ()); \
-+ g_mutex_lock (&m->tlock); \
-+ GST_LOG_OBJECT (m, "locked tlock from thread %p", g_thread_self ()); \
-+} G_STMT_END
-+
-+#define GST_FFMPEG_PIPE_MUTEX_UNLOCK(m) G_STMT_START { \
-+ GST_LOG_OBJECT (m, "unlocking tlock from thread %p", g_thread_self ()); \
-+ g_mutex_unlock (&m->tlock); \
-+} G_STMT_END
-+
-+#define GST_FFMPEG_PIPE_WAIT(m) G_STMT_START { \
-+ GST_LOG_OBJECT (m, "thread %p waiting", g_thread_self ()); \
-+ g_cond_wait (&m->cond, &m->tlock); \
-+} G_STMT_END
-+
-+#define GST_FFMPEG_PIPE_SIGNAL(m) G_STMT_START { \
-+ GST_LOG_OBJECT (m, "signalling from thread %p", g_thread_self ()); \
-+ g_cond_signal (&m->cond); \
-+} G_STMT_END
-+
-+typedef struct _GstFFMpegPipe GstFFMpegPipe;
-+
-+struct _GstFFMpegPipe
-+{
-+ /* lock for syncing */
-+ GMutex tlock;
-+ /* with TLOCK */
-+ /* signals counterpart thread to have a look */
-+ GCond cond;
-+ /* seen eos */
-+ gboolean eos;
-+ /* flowreturn obtained by src task */
-+ GstFlowReturn srcresult;
-+ /* adpater collecting data */
-+ GstAdapter *adapter;
-+ /* amount needed in adapter by src task */
-+ guint needed;
-+};
-+
-+int gst_ffmpeg_pipe_open (GstFFMpegPipe *ffpipe, int flags, AVIOContext ** context);
-+int gst_ffmpeg_pipe_close (AVIOContext * h);
-+
-+int gst_ffmpegdata_open (GstPad * pad, int flags, AVIOContext ** context);
-+int gst_ffmpegdata_close (AVIOContext * h);
-+
-+G_END_DECLS
-+
-+#endif /* __GST_FFMPEGPROTOCOL_H__ */
-diff --git a/ext/libav/gstavutils.c b/ext/libav/gstavutils.c
-index f7a80f6..403a6b6 100644
---- a/ext/libav/gstavutils.c
-+++ b/ext/libav/gstavutils.c
-@@ -13,8 +13,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
- #ifdef HAVE_CONFIG_H
-@@ -25,6 +25,11 @@
- #ifdef __APPLE__
- #include <sys/sysctl.h>
- #endif
-+#ifdef __MINGW32__
-+#include <stdlib.h>
-+#endif
-+
-+#include <libavutil/mem.h>
-
- G_CONST_RETURN gchar *
- gst_ffmpeg_get_codecid_longname (enum CodecID codec_id)
-@@ -44,16 +49,21 @@ av_smp_format_depth (enum AVSampleFormat smp_fmt)
- gint depth = -1;
- switch (smp_fmt) {
- case AV_SAMPLE_FMT_U8:
-+ case AV_SAMPLE_FMT_U8P:
- depth = 1;
- break;
- case AV_SAMPLE_FMT_S16:
-+ case AV_SAMPLE_FMT_S16P:
- depth = 2;
- break;
- case AV_SAMPLE_FMT_S32:
-+ case AV_SAMPLE_FMT_S32P:
- case AV_SAMPLE_FMT_FLT:
-+ case AV_SAMPLE_FMT_FLTP:
- depth = 4;
- break;
- case AV_SAMPLE_FMT_DBL:
-+ case AV_SAMPLE_FMT_DBLP:
- depth = 8;
- break;
- default:
-@@ -476,7 +486,6 @@ gst_ffmpeg_auto_max_threads (void)
- if (n < 1)
- n = 1;
-
-- GST_INFO ("threads: %d", n);
- g_once_init_leave (&n_threads, n);
- }
-
-diff --git a/ext/libav/gstavutils.h b/ext/libav/gstavutils.h
-index ebe49fb..97415eb 100644
---- a/ext/libav/gstavutils.h
-+++ b/ext/libav/gstavutils.h
-@@ -13,8 +13,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
- #ifndef __GST_FFMPEG_UTILS_H__
-diff --git a/ext/libav/gstavviddec.c b/ext/libav/gstavviddec.c
-index 7675a71..f2b5b38 100644
---- a/ext/libav/gstavviddec.c
-+++ b/ext/libav/gstavviddec.c
-@@ -13,8 +13,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
- #ifdef HAVE_CONFIG_H
-@@ -35,78 +35,17 @@
- #include "gstav.h"
- #include "gstavcodecmap.h"
- #include "gstavutils.h"
-+#include "gstavviddec.h"
-
- GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE);
-
--typedef struct _GstFFMpegVidDec GstFFMpegVidDec;
--
- #define MAX_TS_MASK 0xff
-
--struct _GstFFMpegVidDec
--{
-- GstVideoDecoder parent;
--
-- GstVideoCodecState *input_state;
-- GstVideoCodecState *output_state;
--
-- /* decoding */
-- AVCodecContext *context;
-- AVFrame *picture;
-- gboolean opened;
--
-- /* current context */
-- enum PixelFormat ctx_pix_fmt;
-- gint ctx_width;
-- gint ctx_height;
-- gint ctx_par_n;
-- gint ctx_par_d;
-- gint ctx_ticks;
-- gint ctx_time_d;
-- gint ctx_time_n;
-- gint ctx_interlaced;
--
-- guint8 *padded;
-- guint padded_size;
--
-- gboolean current_dr; /* if direct rendering is enabled */
--
-- /* some properties */
-- enum AVDiscard skip_frame;
-- gint lowres;
-- gboolean direct_rendering;
-- gboolean debug_mv;
-- int max_threads;
--
-- gboolean is_realvideo;
--
-- GstCaps *last_caps;
--};
--
--typedef struct _GstFFMpegVidDecClass GstFFMpegVidDecClass;
--
--struct _GstFFMpegVidDecClass
--{
-- GstVideoDecoderClass parent_class;
--
-- AVCodec *in_plugin;
--};
--
--#define GST_TYPE_FFMPEGDEC \
-- (gst_ffmpegviddec_get_type())
--#define GST_FFMPEGDEC(obj) \
-- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGDEC,GstFFMpegVidDec))
--#define GST_FFMPEGVIDDEC_CLASS(klass) \
-- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGDEC,GstFFMpegVidDecClass))
--#define GST_IS_FFMPEGDEC(obj) \
-- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGDEC))
--#define GST_IS_FFMPEGVIDDEC_CLASS(klass) \
-- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGDEC))
--
- #define DEFAULT_LOWRES 0
- #define DEFAULT_SKIPFRAME 0
- #define DEFAULT_DIRECT_RENDERING TRUE
- #define DEFAULT_DEBUG_MV FALSE
--#define DEFAULT_MAX_THREADS 1
-+#define DEFAULT_MAX_THREADS 0
-
- enum
- {
-@@ -234,7 +173,12 @@ gst_ffmpegviddec_base_init (GstFFMpegVidDecClass * klass)
- GST_DEBUG ("Couldn't get sink caps for decoder '%s'", in_plugin->name);
- sinkcaps = gst_caps_new_empty_simple ("unknown/unknown");
- }
-- srccaps = gst_caps_new_empty_simple ("video/x-raw");
-+ srccaps = gst_ffmpeg_codectype_to_video_caps (NULL,
-+ in_plugin->id, FALSE, in_plugin);
-+ if (!srccaps) {
-+ GST_DEBUG ("Couldn't get source caps for decoder '%s'", in_plugin->name);
-+ srccaps = gst_caps_from_string ("video/x-raw");
-+ }
-
- /* pad templates */
- sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
-@@ -301,8 +245,11 @@ gst_ffmpegviddec_class_init (GstFFMpegVidDecClass * klass)
- static void
- gst_ffmpegviddec_init (GstFFMpegVidDec * ffmpegdec)
- {
-+ GstFFMpegVidDecClass *klass =
-+ (GstFFMpegVidDecClass *) G_OBJECT_GET_CLASS (ffmpegdec);
-+
- /* some ffmpeg data */
-- ffmpegdec->context = avcodec_alloc_context ();
-+ ffmpegdec->context = avcodec_alloc_context3 (klass->in_plugin);
- ffmpegdec->picture = avcodec_alloc_frame ();
- ffmpegdec->opened = FALSE;
- ffmpegdec->skip_frame = ffmpegdec->lowres = 0;
-@@ -321,10 +268,7 @@ gst_ffmpegviddec_finalize (GObject * object)
- ffmpegdec->context = NULL;
- }
-
-- if (ffmpegdec->picture != NULL) {
-- av_free (ffmpegdec->picture);
-- ffmpegdec->picture = NULL;
-- }
-+ avcodec_free_frame (&ffmpegdec->picture);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
- }
-@@ -334,9 +278,6 @@ gst_ffmpegviddec_finalize (GObject * object)
- static void
- gst_ffmpegviddec_close (GstFFMpegVidDec * ffmpegdec)
- {
-- if (!ffmpegdec->opened)
-- return;
--
- GST_LOG_OBJECT (ffmpegdec, "closing ffmpeg codec");
-
- gst_caps_replace (&ffmpegdec->last_caps, NULL);
-@@ -345,10 +286,7 @@ gst_ffmpegviddec_close (GstFFMpegVidDec * ffmpegdec)
- gst_ffmpeg_avcodec_close (ffmpegdec->context);
- ffmpegdec->opened = FALSE;
-
-- if (ffmpegdec->context->palctrl) {
-- av_free (ffmpegdec->context->palctrl);
-- ffmpegdec->context->palctrl = NULL;
-- }
-+ gst_buffer_replace (&ffmpegdec->palette, NULL);
-
- if (ffmpegdec->context->extradata) {
- av_free (ffmpegdec->context->extradata);
-@@ -397,6 +335,25 @@ could_not_open:
- }
- }
-
-+static void
-+gst_ffmpegviddec_get_palette (GstFFMpegVidDec * ffmpegdec,
-+ GstVideoCodecState * state)
-+{
-+ GstStructure *str = gst_caps_get_structure (state->caps, 0);
-+ const GValue *palette_v;
-+ GstBuffer *palette;
-+
-+ /* do we have a palette? */
-+ if ((palette_v = gst_structure_get_value (str, "palette_data"))) {
-+ palette = gst_value_get_buffer (palette_v);
-+ GST_DEBUG ("got palette data %p", palette);
-+ if (gst_buffer_get_size (palette) >= AVPALETTE_SIZE) {
-+ gst_buffer_replace (&ffmpegdec->palette, palette);
-+ }
-+ }
-+}
-+
-+
- static gboolean
- gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
- GstVideoCodecState * state)
-@@ -428,9 +385,6 @@ gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
- gst_ffmpegviddec_drain (ffmpegdec);
- GST_OBJECT_LOCK (ffmpegdec);
- gst_ffmpegviddec_close (ffmpegdec);
--
-- /* and reset the defaults that were set when a context is created */
-- avcodec_get_context_defaults (ffmpegdec->context);
- }
-
- gst_caps_replace (&ffmpegdec->last_caps, state->caps);
-@@ -452,6 +406,8 @@ gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
- GST_LOG_OBJECT (ffmpegdec, "size after %dx%d", ffmpegdec->context->width,
- ffmpegdec->context->height);
-
-+ gst_ffmpegviddec_get_palette (ffmpegdec, state);
-+
- if (!ffmpegdec->context->time_base.den || !ffmpegdec->context->time_base.num) {
- GST_DEBUG_OBJECT (ffmpegdec, "forcing 25/1 framerate");
- ffmpegdec->context->time_base.num = 1;
-@@ -460,7 +416,7 @@ gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
-
- /* workaround encoder bugs */
- ffmpegdec->context->workaround_bugs |= FF_BUG_AUTODETECT;
-- ffmpegdec->context->error_recognition = 1;
-+ ffmpegdec->context->err_recognition = 1;
-
- /* for slow cpus */
- ffmpegdec->context->lowres = ffmpegdec->lowres;
-@@ -471,30 +427,16 @@ gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
- ffmpegdec->context->debug_mv = ffmpegdec->debug_mv;
-
- {
-- const gchar *env = g_getenv ("GST_AVVIDDEC_MAX_THREADS");
-- int max_threads = ffmpegdec->max_threads;
- GstQuery *query;
- gboolean is_live;
-
-- if (env != NULL) {
-- if (g_str_equal (env, "auto"))
-- max_threads = 0;
-- else
-- max_threads = MAX (atoi (env), 0);
--
-- if (max_threads != 1) {
-- GST_WARNING_OBJECT (ffmpegdec, "max threads forced to %d, this might "
-- "lead to decoding errors or artefacts", max_threads);
-- }
-- }
--
-- if (max_threads == 0) {
-+ if (ffmpegdec->max_threads == 0) {
- if (!(oclass->in_plugin->capabilities & CODEC_CAP_AUTO_THREADS))
- ffmpegdec->context->thread_count = gst_ffmpeg_auto_max_threads ();
- else
- ffmpegdec->context->thread_count = 0;
- } else
-- ffmpegdec->context->thread_count = max_threads;
-+ ffmpegdec->context->thread_count = ffmpegdec->max_threads;
-
- query = gst_query_new_latency ();
- is_live = FALSE;
-@@ -505,11 +447,10 @@ gst_ffmpegviddec_set_format (GstVideoDecoder * decoder,
- }
- gst_query_unref (query);
-
-- /* Slice based threading is broken in libav 0.8 */
- if (is_live)
-- ffmpegdec->context->thread_type = 0; /* FF_THREAD_SLICE */
-+ ffmpegdec->context->thread_type = FF_THREAD_SLICE;
- else
-- ffmpegdec->context->thread_type = /* FF_THREAD_SLICE | */ FF_THREAD_FRAME;
-+ ffmpegdec->context->thread_type = FF_THREAD_SLICE | FF_THREAD_FRAME;
- }
-
- /* open codec - we don't select an output pix_fmt yet,
-@@ -683,6 +624,7 @@ fallback:
- duplicate_frame:
- {
- GST_WARNING_OBJECT (ffmpegdec, "already alloc'ed output buffer for frame");
-+ gst_video_codec_frame_unref (frame);
- return -1;
- }
- no_frame:
-@@ -1155,12 +1097,12 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
- /* now decode the frame */
- gst_avpacket_init (&packet, data, size);
-
-- if (ffmpegdec->context->palctrl) {
-+ if (ffmpegdec->palette) {
- guint8 *pal;
-
- pal = av_packet_new_side_data (&packet, AV_PKT_DATA_PALETTE,
- AVPALETTE_SIZE);
-- memcpy (pal, ffmpegdec->context->palctrl->palette, AVPALETTE_SIZE);
-+ gst_buffer_extract (ffmpegdec->palette, 0, pal, AVPALETTE_SIZE);
- GST_DEBUG_OBJECT (ffmpegdec, "copy pal %p %p", &packet, pal);
- }
-
-@@ -1358,10 +1300,9 @@ gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder,
- gboolean do_padding;
-
- GST_LOG_OBJECT (ffmpegdec,
-- "Received new data of size %u, dts %" GST_TIME_FORMAT ", pts:%"
-- GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT,
-- gst_buffer_get_size (frame->input_buffer),
-- GST_TIME_ARGS (frame->dts),
-+ "Received new data of size %" G_GSIZE_FORMAT ", dts %" GST_TIME_FORMAT
-+ ", pts:%" GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT,
-+ gst_buffer_get_size (frame->input_buffer), GST_TIME_ARGS (frame->dts),
- GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->duration));
-
- if (!gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ)) {
-@@ -1723,7 +1664,8 @@ gst_ffmpegviddec_register (GstPlugin * plugin)
- gchar *plugin_name;
-
- /* only video decoders */
-- if (!in_plugin->decode || in_plugin->type != AVMEDIA_TYPE_VIDEO)
-+ if (!av_codec_is_decoder (in_plugin)
-+ || in_plugin->type != AVMEDIA_TYPE_VIDEO)
- goto next;
-
- /* no quasi-codecs, please */
-diff --git a/ext/libav/gstavviddec.h b/ext/libav/gstavviddec.h
-new file mode 100644
-index 0000000..c8649c4
---- /dev/null
-+++ b/ext/libav/gstavviddec.h
-@@ -0,0 +1,93 @@
-+/* 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., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
-+ */
-+#ifndef __GST_FFMPEGVIDDEC_H__
-+#define __GST_FFMPEGVIDDEC_H__
-+
-+G_BEGIN_DECLS
-+
-+#include <gst/gst.h>
-+#include <gst/video/video.h>
-+#include <gst/video/gstvideodecoder.h>
-+#include <libavcodec/avcodec.h>
-+
-+typedef struct _GstFFMpegVidDec GstFFMpegVidDec;
-+struct _GstFFMpegVidDec
-+{
-+ GstVideoDecoder parent;
-+
-+ GstVideoCodecState *input_state;
-+ GstVideoCodecState *output_state;
-+
-+ /* decoding */
-+ AVCodecContext *context;
-+ AVFrame *picture;
-+ gboolean opened;
-+
-+ /* current context */
-+ enum PixelFormat ctx_pix_fmt;
-+ gint ctx_width;
-+ gint ctx_height;
-+ gint ctx_par_n;
-+ gint ctx_par_d;
-+ gint ctx_ticks;
-+ gint ctx_time_d;
-+ gint ctx_time_n;
-+ gint ctx_interlaced;
-+ GstBuffer *palette;
-+
-+ guint8 *padded;
-+ guint padded_size;
-+
-+ gboolean current_dr; /* if direct rendering is enabled */
-+
-+ /* some properties */
-+ enum AVDiscard skip_frame;
-+ gint lowres;
-+ gboolean direct_rendering;
-+ gboolean debug_mv;
-+ int max_threads;
-+
-+ gboolean is_realvideo;
-+
-+ GstCaps *last_caps;
-+};
-+
-+typedef struct _GstFFMpegVidDecClass GstFFMpegVidDecClass;
-+
-+struct _GstFFMpegVidDecClass
-+{
-+ GstVideoDecoderClass parent_class;
-+
-+ AVCodec *in_plugin;
-+};
-+
-+#define GST_TYPE_FFMPEGDEC \
-+ (gst_ffmpegviddec_get_type())
-+#define GST_FFMPEGDEC(obj) \
-+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGDEC,GstFFMpegVidDec))
-+#define GST_FFMPEGVIDDEC_CLASS(klass) \
-+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGDEC,GstFFMpegVidDecClass))
-+#define GST_IS_FFMPEGDEC(obj) \
-+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGDEC))
-+#define GST_IS_FFMPEGVIDDEC_CLASS(klass) \
-+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGDEC))
-+
-+G_END_DECLS
-+
-+#endif
-diff --git a/ext/libav/gstavvidenc.c b/ext/libav/gstavvidenc.c
-index b747613..7b24c45 100644
---- a/ext/libav/gstavvidenc.c
-+++ b/ext/libav/gstavvidenc.c
-@@ -13,8 +13,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
- #ifdef HAVE_CONFIG_H
-@@ -56,13 +56,13 @@ enum
-
- enum
- {
-- ARG_0,
-- ARG_BIT_RATE,
-- ARG_GOP_SIZE,
-- ARG_ME_METHOD,
-- ARG_BUFSIZE,
-- ARG_RTP_PAYLOAD_SIZE,
-- ARG_CFG_BASE
-+ PROP_0,
-+ PROP_BIT_RATE,
-+ PROP_GOP_SIZE,
-+ PROP_ME_METHOD,
-+ PROP_BUFSIZE,
-+ PROP_RTP_PAYLOAD_SIZE,
-+ PROP_CFG_BASE
- };
-
- #define GST_TYPE_ME_METHOD (gst_ffmpegvidenc_me_method_get_type())
-@@ -98,6 +98,8 @@ static gboolean gst_ffmpegvidenc_set_format (GstVideoEncoder * encoder,
- GstVideoCodecState * state);
- static gboolean gst_ffmpegvidenc_propose_allocation (GstVideoEncoder * encoder,
- GstQuery * query);
-+static gboolean gst_ffmpegvidenc_reset (GstVideoEncoder * encoder,
-+ gboolean hard);
-
- static GstCaps *gst_ffmpegvidenc_getcaps (GstVideoEncoder * encoder,
- GstCaps * filter);
-@@ -144,7 +146,12 @@ gst_ffmpegvidenc_base_init (GstFFMpegVidEncClass * klass)
- srccaps = gst_caps_new_empty_simple ("unknown/unknown");
- }
-
-- sinkcaps = gst_caps_new_empty_simple ("video/x-raw");
-+ sinkcaps = gst_ffmpeg_codectype_to_video_caps (NULL,
-+ in_plugin->id, TRUE, in_plugin);
-+ if (!sinkcaps) {
-+ GST_DEBUG ("Couldn't get sink caps for encoder '%s'", in_plugin->name);
-+ sinkcaps = gst_caps_new_empty_simple ("unknown/unknown");
-+ }
-
- /* pad templates */
- sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
-@@ -157,7 +164,6 @@ gst_ffmpegvidenc_base_init (GstFFMpegVidEncClass * klass)
- klass->in_plugin = in_plugin;
- klass->srctempl = srctempl;
- klass->sinktempl = sinktempl;
-- klass->sinkcaps = NULL;
-
- return;
- }
-@@ -178,30 +184,30 @@ gst_ffmpegvidenc_class_init (GstFFMpegVidEncClass * klass)
-
- /* FIXME: could use -1 for a sensible per-codec default based on
- * e.g. input resolution and framerate */
-- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BIT_RATE,
-+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BIT_RATE,
- g_param_spec_int ("bitrate", "Bit Rate",
- "Target Video Bitrate", 0, G_MAXINT, DEFAULT_VIDEO_BITRATE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_GOP_SIZE,
-+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_GOP_SIZE,
- g_param_spec_int ("gop-size", "GOP Size",
- "Number of frames within one GOP", 0, G_MAXINT,
- DEFAULT_VIDEO_GOP_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ME_METHOD,
-+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ME_METHOD,
- g_param_spec_enum ("me-method", "ME Method", "Motion Estimation Method",
- GST_TYPE_ME_METHOD, ME_EPZS,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BUFSIZE,
-+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BUFSIZE,
- g_param_spec_int ("buffer-size", "Buffer Size",
- "Size of the video buffers", 0, G_MAXINT, 0,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (G_OBJECT_CLASS (klass),
-- ARG_RTP_PAYLOAD_SIZE, g_param_spec_int ("rtp-payload-size",
-+ PROP_RTP_PAYLOAD_SIZE, g_param_spec_int ("rtp-payload-size",
- "RTP Payload Size", "Target GOB length", 0, G_MAXINT, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /* register additional properties, possibly dependent on the exact CODEC */
-- gst_ffmpeg_cfg_install_property (klass, ARG_CFG_BASE);
-+ gst_ffmpeg_cfg_install_property (klass, PROP_CFG_BASE);
-
- venc_class->stop = gst_ffmpegvidenc_stop;
- venc_class->finish = gst_ffmpegvidenc_finish;
-@@ -209,6 +215,7 @@ gst_ffmpegvidenc_class_init (GstFFMpegVidEncClass * klass)
- venc_class->getcaps = gst_ffmpegvidenc_getcaps;
- venc_class->set_format = gst_ffmpegvidenc_set_format;
- venc_class->propose_allocation = gst_ffmpegvidenc_propose_allocation;
-+ venc_class->reset = gst_ffmpegvidenc_reset;
-
- gobject_class->finalize = gst_ffmpegvidenc_finalize;
- }
-@@ -216,8 +223,11 @@ gst_ffmpegvidenc_class_init (GstFFMpegVidEncClass * klass)
- static void
- gst_ffmpegvidenc_init (GstFFMpegVidEnc * ffmpegenc)
- {
-+ GstFFMpegVidEncClass *klass =
-+ (GstFFMpegVidEncClass *) G_OBJECT_GET_CLASS (ffmpegenc);
-+
- /* ffmpeg objects */
-- ffmpegenc->context = avcodec_alloc_context ();
-+ ffmpegenc->context = avcodec_alloc_context3 (klass->in_plugin);
- ffmpegenc->picture = avcodec_alloc_frame ();
- ffmpegenc->opened = FALSE;
-
-@@ -243,15 +253,9 @@ gst_ffmpegvidenc_finalize (GObject * object)
-
- gst_ffmpeg_cfg_finalize (ffmpegenc);
-
-- /* close old session */
-- if (ffmpegenc->opened) {
-- gst_ffmpeg_avcodec_close (ffmpegenc->context);
-- ffmpegenc->opened = FALSE;
-- }
--
- /* clean up remaining allocated data */
- av_free (ffmpegenc->context);
-- av_free (ffmpegenc->picture);
-+ avcodec_free_frame (&ffmpegenc->picture);
-
- g_free (ffmpegenc->filename);
-
-@@ -262,117 +266,13 @@ static GstCaps *
- gst_ffmpegvidenc_getcaps (GstVideoEncoder * encoder, GstCaps * filter)
- {
- GstFFMpegVidEnc *ffmpegenc = (GstFFMpegVidEnc *) encoder;
-- GstFFMpegVidEncClass *oclass =
-- (GstFFMpegVidEncClass *) G_OBJECT_GET_CLASS (ffmpegenc);
-- AVCodecContext *ctx = NULL;
-- enum PixelFormat pixfmt;
- GstCaps *caps = NULL;
-- gint i;
-
- GST_DEBUG_OBJECT (ffmpegenc, "getting caps");
-
-- /* cached */
-- if (oclass->sinkcaps) {
-- caps = gst_video_encoder_proxy_getcaps (encoder, oclass->sinkcaps, filter);
-- GST_DEBUG_OBJECT (ffmpegenc, "return cached caps %" GST_PTR_FORMAT, caps);
-- return caps;
-- }
--
-- /* create cache etc. */
--
-- /* shut up the logging while we autoprobe; we don't want warnings and
-- * errors about unsupported formats */
-- /* FIXME: if someone cares about this disabling the logging for other
-- * instances/threads/..., one could investigate if there is a way to
-- * set this as a struct member on the av context, and check it from the
-- * log handler */
--#ifndef GST_DISABLE_GST_DEBUG
-- _shut_up_I_am_probing = TRUE;
--#endif
-- GST_DEBUG_OBJECT (ffmpegenc, "probing caps");
-- i = pixfmt = 0;
-- /* check pixfmt until deemed finished */
-- for (pixfmt = 0;; pixfmt++) {
-- GstCaps *tmpcaps;
--
-- /* override looping all pixfmt if codec declares pixfmts;
-- * these may not properly check and report supported pixfmt during _init */
-- if (oclass->in_plugin->pix_fmts) {
-- if ((pixfmt = oclass->in_plugin->pix_fmts[i++]) == PIX_FMT_NONE) {
-- GST_DEBUG_OBJECT (ffmpegenc,
-- "At the end of official pixfmt for this codec, breaking out");
-- break;
-- }
-- GST_DEBUG_OBJECT (ffmpegenc,
-- "Got an official pixfmt [%d], attempting to get caps", pixfmt);
-- tmpcaps = gst_ffmpeg_pixfmt_to_caps (pixfmt, NULL, oclass->in_plugin->id);
-- if (tmpcaps) {
-- GST_DEBUG_OBJECT (ffmpegenc, "Got caps, breaking out");
-- if (!caps)
-- caps = gst_caps_new_empty ();
-- gst_caps_append (caps, tmpcaps);
-- continue;
-- }
-- GST_DEBUG_OBJECT (ffmpegenc,
-- "Couldn't figure out caps without context, trying again with a context");
-- }
--
-- GST_DEBUG_OBJECT (ffmpegenc, "pixfmt :%d", pixfmt);
-- if (pixfmt >= PIX_FMT_NB) {
-- GST_WARNING ("Invalid pixfmt, breaking out");
-- break;
-- }
--
-- /* need to start with a fresh codec_context each time around, since
-- * codec_close may have released stuff causing the next pass to segfault */
-- ctx = avcodec_alloc_context ();
-- if (!ctx) {
-- GST_DEBUG_OBJECT (ffmpegenc, "no context");
-- break;
-- }
--
-- /* set some default properties */
-- ctx->width = DEFAULT_WIDTH;
-- ctx->height = DEFAULT_HEIGHT;
-- ctx->time_base.num = 1;
-- ctx->time_base.den = 25;
-- ctx->ticks_per_frame = 1;
-- ctx->bit_rate = DEFAULT_VIDEO_BITRATE;
-- /* makes it silent */
-- ctx->strict_std_compliance = -1;
--
-- ctx->pix_fmt = pixfmt;
--
-- GST_DEBUG ("Attempting to open codec");
-- if (gst_ffmpeg_avcodec_open (ctx, oclass->in_plugin) >= 0 &&
-- ctx->pix_fmt == pixfmt) {
-- ctx->width = -1;
-- if (!caps)
-- caps = gst_caps_new_empty ();
-- tmpcaps = gst_ffmpeg_codectype_to_caps (oclass->in_plugin->type, ctx,
-- oclass->in_plugin->id, TRUE);
-- if (tmpcaps)
-- gst_caps_append (caps, tmpcaps);
-- else
-- GST_LOG_OBJECT (ffmpegenc,
-- "Couldn't get caps for oclass->in_plugin->name:%s",
-- oclass->in_plugin->name);
-- gst_ffmpeg_avcodec_close (ctx);
-- } else {
-- GST_DEBUG_OBJECT (ffmpegenc, "Opening codec failed with pixfmt : %d",
-- pixfmt);
-- }
-- if (ctx->priv_data)
-- gst_ffmpeg_avcodec_close (ctx);
-- av_free (ctx);
-- }
--#ifndef GST_DISABLE_GST_DEBUG
-- _shut_up_I_am_probing = FALSE;
--#endif
--
-- oclass->sinkcaps = caps;
--
-- return gst_video_encoder_proxy_getcaps (encoder, caps, filter);
-+ caps = gst_video_encoder_proxy_getcaps (encoder, NULL, filter);
-+ GST_DEBUG_OBJECT (ffmpegenc, "return caps %" GST_PTR_FORMAT, caps);
-+ return caps;
- }
-
- static gboolean
-@@ -394,9 +294,6 @@ gst_ffmpegvidenc_set_format (GstVideoEncoder * encoder,
- ffmpegenc->opened = FALSE;
- }
-
-- /* set defaults */
-- avcodec_get_context_defaults (ffmpegenc->context);
--
- /* if we set it in _getcaps we should set it also in _link */
- ffmpegenc->context->strict_std_compliance = -1;
-
-@@ -546,16 +443,7 @@ gst_ffmpegvidenc_set_format (GstVideoEncoder * encoder,
- gst_caps_unref (icaps);
- return FALSE;
- }
--
-- if (gst_caps_get_size (icaps) > 1) {
-- GstCaps *newcaps;
--
-- newcaps =
-- gst_caps_new_full (gst_structure_copy (gst_caps_get_structure (icaps,
-- 0)), NULL);
-- gst_caps_unref (icaps);
-- icaps = newcaps;
-- }
-+ icaps = gst_caps_truncate (icaps);
-
- /* Store input state and set output state */
- if (ffmpegenc->input_state)
-@@ -796,24 +684,28 @@ gst_ffmpegvidenc_flush_buffers (GstFFMpegVidEnc * ffmpegenc, gboolean send)
- (("Could not write to file \"%s\"."), ffmpegenc->filename),
- GST_ERROR_SYSTEM);
-
-- if (gst_video_encoder_allocate_output_frame (GST_VIDEO_ENCODER (ffmpegenc),
-- frame, ret_size) != GST_FLOW_OK) {
-+ if (send) {
-+ if (gst_video_encoder_allocate_output_frame (GST_VIDEO_ENCODER
-+ (ffmpegenc), frame, ret_size) != GST_FLOW_OK) {
- #ifndef GST_DISABLE_GST_DEBUG
-- GstFFMpegVidEncClass *oclass =
-- (GstFFMpegVidEncClass *) (G_OBJECT_GET_CLASS (ffmpegenc));
-- GST_WARNING_OBJECT (ffmpegenc,
-- "avenc_%s: failed to allocate buffer", oclass->in_plugin->name);
-+ GstFFMpegVidEncClass *oclass =
-+ (GstFFMpegVidEncClass *) (G_OBJECT_GET_CLASS (ffmpegenc));
-+ GST_WARNING_OBJECT (ffmpegenc,
-+ "avenc_%s: failed to allocate buffer", oclass->in_plugin->name);
- #endif /* GST_DISABLE_GST_DEBUG */
-- gst_video_codec_frame_unref (frame);
-- break;
-- }
-- outbuf = frame->output_buffer;
-- gst_buffer_fill (outbuf, 0, ffmpegenc->working_buf, ret_size);
-+ gst_video_codec_frame_unref (frame);
-+ break;
-+ }
-+ outbuf = frame->output_buffer;
-+ gst_buffer_fill (outbuf, 0, ffmpegenc->working_buf, ret_size);
-
-- if (ffmpegenc->context->coded_frame->key_frame)
-- GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
-+ if (ffmpegenc->context->coded_frame->key_frame)
-+ GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
-
-- gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (ffmpegenc), frame);
-+ gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (ffmpegenc), frame);
-+ } else {
-+ gst_video_codec_frame_unref (frame);
-+ }
- }
- }
-
-@@ -835,18 +727,18 @@ gst_ffmpegvidenc_set_property (GObject * object,
-
- /* Check the argument id to see which argument we're setting. */
- switch (prop_id) {
-- case ARG_BIT_RATE:
-+ case PROP_BIT_RATE:
- ffmpegenc->bitrate = g_value_get_int (value);
- break;
-- case ARG_GOP_SIZE:
-+ case PROP_GOP_SIZE:
- ffmpegenc->gop_size = g_value_get_int (value);
- break;
-- case ARG_ME_METHOD:
-+ case PROP_ME_METHOD:
- ffmpegenc->me_method = g_value_get_enum (value);
- break;
-- case ARG_BUFSIZE:
-+ case PROP_BUFSIZE:
- break;
-- case ARG_RTP_PAYLOAD_SIZE:
-+ case PROP_RTP_PAYLOAD_SIZE:
- ffmpegenc->rtp_payload_size = g_value_get_int (value);
- break;
- default:
-@@ -867,19 +759,19 @@ gst_ffmpegvidenc_get_property (GObject * object,
- ffmpegenc = (GstFFMpegVidEnc *) (object);
-
- switch (prop_id) {
-- case ARG_BIT_RATE:
-+ case PROP_BIT_RATE:
- g_value_set_int (value, ffmpegenc->bitrate);
- break;
-- case ARG_GOP_SIZE:
-+ case PROP_GOP_SIZE:
- g_value_set_int (value, ffmpegenc->gop_size);
- break;
-- case ARG_ME_METHOD:
-+ case PROP_ME_METHOD:
- g_value_set_enum (value, ffmpegenc->me_method);
- break;
-- case ARG_BUFSIZE:
-+ case PROP_BUFSIZE:
- g_value_set_int (value, ffmpegenc->buffer_size);
- break;
-- case ARG_RTP_PAYLOAD_SIZE:
-+ case PROP_RTP_PAYLOAD_SIZE:
- g_value_set_int (value, ffmpegenc->rtp_payload_size);
- break;
- default:
-@@ -890,15 +782,26 @@ gst_ffmpegvidenc_get_property (GObject * object,
- }
-
- static gboolean
--gst_ffmpegvidenc_stop (GstVideoEncoder * encoder)
-+gst_ffmpegvidenc_reset (GstVideoEncoder * encoder, gboolean hard)
- {
- GstFFMpegVidEnc *ffmpegenc = (GstFFMpegVidEnc *) encoder;
-
-- gst_ffmpegvidenc_flush_buffers (ffmpegenc, FALSE);
- if (ffmpegenc->opened) {
-- gst_ffmpeg_avcodec_close (ffmpegenc->context);
-- ffmpegenc->opened = FALSE;
-+ avcodec_flush_buffers (ffmpegenc->context);
- }
-+
-+ return TRUE;
-+}
-+
-+static gboolean
-+gst_ffmpegvidenc_stop (GstVideoEncoder * encoder)
-+{
-+ GstFFMpegVidEnc *ffmpegenc = (GstFFMpegVidEnc *) encoder;
-+
-+ gst_ffmpegvidenc_flush_buffers (ffmpegenc, FALSE);
-+ gst_ffmpeg_avcodec_close (ffmpegenc->context);
-+ ffmpegenc->opened = FALSE;
-+
- if (ffmpegenc->file) {
- fclose (ffmpegenc->file);
- ffmpegenc->file = NULL;
-@@ -971,7 +874,8 @@ gst_ffmpegvidenc_register (GstPlugin * plugin)
- }
-
- /* only video encoders */
-- if (!in_plugin->encode || in_plugin->type != AVMEDIA_TYPE_VIDEO)
-+ if (!av_codec_is_encoder (in_plugin)
-+ || in_plugin->type != AVMEDIA_TYPE_VIDEO)
- goto next;
-
- /* FIXME : We should have a method to know cheaply whether we have a mapping
-diff --git a/ext/libav/gstavvidenc.h b/ext/libav/gstavvidenc.h
-index eb201b3..d19dc39 100644
---- a/ext/libav/gstavvidenc.h
-+++ b/ext/libav/gstavvidenc.h
-@@ -13,8 +13,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
- /* First, include the header file for the plugin, to bring in the
-@@ -26,7 +26,9 @@
-
- G_BEGIN_DECLS
-
-+#include <gst/gst.h>
- #include <gst/video/gstvideoencoder.h>
-+#include <libavcodec/avcodec.h>
-
- typedef struct _GstFFMpegVidEnc GstFFMpegVidEnc;
-
-@@ -76,7 +78,6 @@ struct _GstFFMpegVidEncClass
-
- AVCodec *in_plugin;
- GstPadTemplate *srctempl, *sinktempl;
-- GstCaps *sinkcaps;
- };
-
- #define GST_TYPE_FFMPEGVIDENC \
-diff --git a/ext/libswscale/gstffmpegscale.c b/ext/libswscale/gstffmpegscale.c
-index ce980a8..a2b0248 100644
---- a/ext/libswscale/gstffmpegscale.c
-+++ b/ext/libswscale/gstffmpegscale.c
-@@ -15,8 +15,8 @@
- *
- * 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.
-+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-+ * Boston, MA 02110-1301, USA.
- */
-
- #ifdef HAVE_CONFIG_H
-@@ -246,44 +246,15 @@ gst_ffmpegscale_caps_remove_format_info (GstCaps * caps)
- {
- int i;
- GstStructure *structure;
-- GstCaps *rgbcaps;
-- GstCaps *graycaps;
-
- caps = gst_caps_copy (caps);
-
- for (i = 0; i < gst_caps_get_size (caps); i++) {
- structure = gst_caps_get_structure (caps, i);
-
-- gst_structure_set_name (structure, "video/x-raw-yuv");
- gst_structure_remove_field (structure, "format");
-- gst_structure_remove_field (structure, "endianness");
-- gst_structure_remove_field (structure, "depth");
-- gst_structure_remove_field (structure, "bpp");
-- gst_structure_remove_field (structure, "red_mask");
-- gst_structure_remove_field (structure, "green_mask");
-- gst_structure_remove_field (structure, "blue_mask");
-- gst_structure_remove_field (structure, "alpha_mask");
-- gst_structure_remove_field (structure, "palette_data");
- }
-
-- rgbcaps = gst_caps_copy (caps);
--
-- for (i = 0; i < gst_caps_get_size (rgbcaps); i++) {
-- structure = gst_caps_get_structure (rgbcaps, i);
--
-- gst_structure_set_name (structure, "video/x-raw-rgb");
-- }
-- graycaps = gst_caps_copy (caps);
--
-- for (i = 0; i < gst_caps_get_size (graycaps); i++) {
-- structure = gst_caps_get_structure (graycaps, i);
--
-- gst_structure_set_name (structure, "video/x-raw-gray");
-- }
--
-- gst_caps_append (caps, graycaps);
-- gst_caps_append (caps, rgbcaps);
--
- return caps;
- }
-
-diff --git a/gst-libs/ext/Makefile.am b/gst-libs/ext/Makefile.am
-index b1054e1..12f35c8 100644
---- a/gst-libs/ext/Makefile.am
-+++ b/gst-libs/ext/Makefile.am
-@@ -23,7 +23,7 @@ clean-local:
-
- dist-clean:
- cd libav && $(MAKE) distclean
-- rm -rf $(TMP_DIST_DIR)
-+ rm -rf libav/$(TMP_DIST_DIR)
- rm -f Makefile
- rm -f libav/.version
- rm -f libav/.config
-@@ -36,19 +36,19 @@ maintainer-clean: distclean
- maintainerclean: maintainer-clean
-
- dist-local:
-- GIT_DIR=libav/.git git checkout-index --prefix=../$(TMP_DIST_DIR)/libav/ -a
-- touch $(TMP_DIST_DIR)/libav/config.mak
-+ GIT_DIR=libav/.git git checkout-index --prefix=$(TMP_DIST_DIR)/libav/ -a
-+ touch libav/$(TMP_DIST_DIR)/libav/config.mak
- echo "Patching libav ./configure"
-- sed -e '/Unknown option/ {N;N;s/exit 1//; }' $(TMP_DIST_DIR)/libav/configure > $(TMP_DIST_DIR)/libav/configure.tmp
-- mv $(TMP_DIST_DIR)/libav/configure.tmp $(TMP_DIST_DIR)/libav/configure
-- chmod +x $(TMP_DIST_DIR)/libav/configure
-+ sed -e '/Unknown option/ {N;N;s/exit 1//; }' libav/$(TMP_DIST_DIR)/libav/configure > libav/$(TMP_DIST_DIR)/libav/configure.tmp
-+ mv libav/$(TMP_DIST_DIR)/libav/configure.tmp libav/$(TMP_DIST_DIR)/libav/configure
-+ chmod +x libav/$(TMP_DIST_DIR)/libav/configure
-
- distdir: dist-local
-- cp -r $(TMP_DIST_DIR)/libav ${distdir}
-+ cp -r libav/$(TMP_DIST_DIR)/libav ${distdir}
- cp -f $(top_srcdir)/gst-libs/ext/Makefile.am $(top_srcdir)/gst-libs/ext/Makefile.in ${distdir}
-- rm -rf $(TMP_DIST_DIR)
-+ rm -rf libav/$(TMP_DIST_DIR)
-
- dist: dist-local
-- cd $(TMP_DIST_DIR) && tar -czf libav.tar.gz libav
-- mv $(TMP_DIST_DIR)/libav.tar.gz ./
-- rm -rf $(TMP_DIST_DIR)
-+ cd libav/$(TMP_DIST_DIR) && tar -czf libav.tar.gz libav
-+ mv libav/$(TMP_DIST_DIR)/libav.tar.gz ./
-+ rm -rf libav/$(TMP_DIST_DIR)
diff --git a/debian/patches/04_gstreamer-1.0.patch b/debian/patches/04_gstreamer-1.0.patch
deleted file mode 100644
index ef78e88..0000000
--- a/debian/patches/04_gstreamer-1.0.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-Index: gst-libav1.0/ext/libav/gstavcodecmap.c
-===================================================================
---- gst-libav1.0.orig/ext/libav/gstavcodecmap.c 2012-12-18 11:46:01.518162985 +0100
-+++ gst-libav1.0/ext/libav/gstavcodecmap.c 2012-12-18 11:46:14.610162737 +0100
-@@ -2426,12 +2426,7 @@
- {GST_VIDEO_FORMAT_I420_10LE, PIX_FMT_YUV420P10LE},
- {GST_VIDEO_FORMAT_I420_10BE, PIX_FMT_YUV420P10BE},
- {GST_VIDEO_FORMAT_I422_10LE, PIX_FMT_YUV422P10LE},
-- {GST_VIDEO_FORMAT_I422_10BE, PIX_FMT_YUV422P10BE},
-- {GST_VIDEO_FORMAT_Y444_10LE, PIX_FMT_YUV444P10LE},
-- {GST_VIDEO_FORMAT_Y444_10BE, PIX_FMT_YUV444P10BE},
-- {GST_VIDEO_FORMAT_GBR, PIX_FMT_GBRP},
-- {GST_VIDEO_FORMAT_GBR_10LE, PIX_FMT_GBRP10LE},
-- {GST_VIDEO_FORMAT_GBR_10BE, PIX_FMT_GBRP10BE},
-+ {GST_VIDEO_FORMAT_I422_10BE, PIX_FMT_YUV422P10BE}
- };
-
- GstVideoFormat
diff --git a/debian/patches/series b/debian/patches/series
index 2238249..cea5087 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,4 +1,2 @@
02_plugin-dependencies.patch
-03_git-2013-04-26.patch
-04_gstreamer-1.0.patch
99_ltmain_as-needed.patch