Merging GST_FFMPEG_NO_MIRROR branch to trunk

Original commit message from CVS:
Merging GST_FFMPEG_NO_MIRROR branch to trunk
This commit is contained in:
Edward Hervey 2007-12-17 12:43:06 +00:00
parent 22e3b86e43
commit f6186655c5
17 changed files with 705 additions and 89 deletions

101
ChangeLog
View file

@ -1,3 +1,104 @@
2007-12-17 Edward Hervey <edward.hervey@collabora.co.uk>
* configure.ac:
Minor typo in disabling cavs decoder. Now compiles AND works on x86 32
and 64 bits ! Time to merge :)
2007-12-17 Edward Hervey <edward.hervey@collabora.co.uk>
* ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps),
(gst_ffmpeg_caps_to_codecid):
* ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_open):
Handle VC-1 properly , which is handled differently from WMV3.
2007-12-17 Edward Hervey <edward.hervey@collabora.co.uk>
* autogen.sh:
Fix call to ffmpegrev
* configure.ac:
Re-apply -fPIC extra-cflag for ffmpeg while removing support for the
flac encoder which is currently broken for x86/32bits with -fPIC.
* ffmpegrev:
Switch to latest upstream revision so we can have the split-up for
flac mmx optimizations.
2007-12-15 Sebastian Dröge <slomo@circular-chaos.org>
Based on a patch by:
Hans de Goede <j dot w dot r degoede at hhs dot nl>
* ext/ffmpeg/gstffmpegcfg.c: (gst_ffmpeg_pre_me_get_type),
(gst_ffmpeg_pred_method_get_type):
NULL-terminate the GEnumValue arrays, otherwise they will cause
crashes. Fixes #503733.
2007-12-09 Sebastian Dröge <slomo@circular-chaos.org>
* configure.ac:
Don't define GST_DISABLE_DEPRECATED for releases. Fixes #498181.
2007-11-28 Edward Hervey <bilboed@bilboed.com>
* configure.ac:
Temporarily remove fPIC option for building ffmpeg
* ffmpegrev:
Switch to latest ffmpeg checkout so people can enjoy all the niceties
that have just landed (mmx optimisations for vc1 and h263, bugfixes,..)
* ext/ffmpeg/gstffmpegmux.c: (gst_ffmpegmux_collected),
(gst_ffmpegmux_change_state):
Adjust code to ffmpeg API changes.
2007-11-22 Edward Hervey <bilboed@bilboed.com>
* ext/ffmpeg/gstffmpegaudioresample.c:
(gst_ffmpegaudioresample_get_unit_size),
(gst_ffmpegaudioresample_transform):
Correct the output size of the buffer.
2007-11-15 Edward Hervey <bilboed@bilboed.com>
* ext/ffmpeg/Makefile.am:
* ext/ffmpeg/gstffmpeg.c: (plugin_init):
* ext/ffmpeg/gstffmpeg.h:
* ext/ffmpeg/gstffmpegaudioresample.c:
(gst_ffmpegaudioresample_base_init),
(gst_ffmpegaudioresample_class_init),
(gst_ffmpegaudioresample_init), (gst_ffmpegaudioresample_finalize),
(gst_ffmpegaudioresample_transform_caps),
(gst_ffmpegaudioresample_transform_size),
(gst_ffmpegaudioresample_get_unit_size),
(gst_ffmpegaudioresample_set_caps),
(gst_ffmpegaudioresample_transform),
(gst_ffmpegaudioresample_register):
Added new ffaudioresample element using the ffmpeg resampling code.
It's (way) faster than audioresample, doesn't introduce latency, but
might cause a little bit of 'clicking'.
2007-11-15 Edward Hervey <bilboed@bilboed.com>
* Makefile.am:
* autogen.sh:
* configure.ac:
* ext/ffmpeg/Makefile.am:
* ffmpegrev:
* gst-libs/ext/Makefile.am:
Initial patch of the new mirror-less build-system for gst-ffmpeg using
specific revisions of ffmpeg svn instead.
Might still have some issues, we need people to try this.
Help by : Dejan Sakelšak <sakdean at gmail dot com>
* ext/ffmpeg/gstffmpeg.c: (plugin_init):
* ext/ffmpeg/gstffmpegcodecmap.c: (gst_ffmpeg_codecid_to_caps),
(gst_ffmpeg_caps_with_codecid), (gst_ffmpeg_caps_to_codecid),
(gst_ffmpeg_get_codecid_longname):
* ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_base_init),
(gst_ffmpegdec_get_buffer), (gst_ffmpegdec_audio_frame),
(gst_ffmpegdec_register):
* ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_averror),
(gst_ffmpegdemux_register):
* ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_register):
* ext/ffmpeg/gstffmpegmux.c: (gst_ffmpegmux_register):
Update code for new ffmpeg API.
2007-12-04 Edward Hervey <bilboed@bilboed.com> 2007-12-04 Edward Hervey <bilboed@bilboed.com>
* configure.ac: * configure.ac:

View file

@ -8,7 +8,7 @@ debug:
echo $(win32) echo $(win32)
EXTRA_DIST = \ EXTRA_DIST = \
gst-ffmpeg.spec depcomp \ gst-ffmpeg.spec depcomp ffmpegrev \
AUTHORS COPYING NEWS README ChangeLog gst-ffmpeg.doap \ AUTHORS COPYING NEWS README ChangeLog gst-ffmpeg.doap \
$(win32) $(win32)

View file

@ -5,6 +5,9 @@ DIE=0
package=gst-ffmpeg package=gst-ffmpeg
srcfile=configure.ac srcfile=configure.ac
# FFMPEG specific properties
. ./ffmpegrev
# a quick cvs co if necessary to alleviate the pain - may remove this # a quick cvs co if necessary to alleviate the pain - may remove this
# when developers get a clue ;) # when developers get a clue ;)
if test ! -d common; if test ! -d common;
@ -13,11 +16,16 @@ then
cvs co common cvs co common
fi fi
if test ! -f gst-libs/ext/ffmpeg/autogen.sh if test ! -f $FFMPEG_CO_DIR/configure
then then
rm -rf gst-libs/ext/ffmpeg # checkout ffmpeg from its repository
echo "+ getting ffmpeg from cvs" rm -rf $FFMPEG_CO_DIR
cvs co mirror-ffmpeg echo "+ getting ffmpeg from svn"
svn -r $FFMPEG_REVISION co $FFMPEG_SVN $FFMPEG_CO_DIR
else
# update ffmpeg from its repository
echo "+ updating ffmpeg checkout"
svn -r $FFMPEG_REVISION up $FFMPEG_CO_DIR
fi fi
@ -30,7 +38,23 @@ then
fi fi
. common/gst-autogen.sh . common/gst-autogen.sh
CONFIGURE_DEF_OPT='--enable-maintainer-mode --enable-gtk-doc' # Let's check if we can disable the building of the ffmpeg binary
can_disable=`$FFMPEG_CO_DIR/configure --help | grep 'disable-ffmpeg' | wc -l`
if [ $can_disable != "0" ]
then
CONFIGURE_DEF_OPT="--disable-ffmpeg"
fi
# Let's clear the 'exit 1' command when we post an Unknown option
echo "Patching ffmpeg ./configure"
sed -e '/Unknown option/ {
N
N
s/exit 1/#/
}' $FFMPEG_CO_DIR/configure > $FFMPEG_CO_DIR/configure.tmp
mv $FFMPEG_CO_DIR/configure.tmp $FFMPEG_CO_DIR/configure
chmod +x $FFMPEG_CO_DIR/configure
autogen_options $@ autogen_options $@
@ -88,17 +112,6 @@ if test -f disable; then
done done
fi fi
# remove ffmpeg's configure, it's going to get created anyway and it probably
# conflicted before this too
rm -f gst-libs/ext/ffmpeg/configure
# now, run ffmpeg's autogen
echo "+ running autogen.sh in gst-libs/ext/ffmpeg"
cd gst-libs/ext/ffmpeg
chmod +x autogen.sh
./autogen.sh || exit 1
cd ../../..
test -n "$NOCONFIGURE" && { test -n "$NOCONFIGURE" && {
echo "+ skipping configure stage for package $package, as requested." echo "+ skipping configure stage for package $package, as requested."
echo "+ autogen.sh done." echo "+ autogen.sh done."

2
common

@ -1 +1 @@
Subproject commit 423e2ea96b5f79281f4dd20d734bd968b3d95e89 Subproject commit a00d4c1966aab517c2694c61d580489ebcbce448

View file

@ -113,11 +113,14 @@ AM_CONDITIONAL(HAVE_GST_CHECK, test "x$HAVE_GST_CHECK" = "xyes")
AC_MSG_NOTICE(Using GStreamer Core Plugins in $GST_PLUGINS_DIR) AC_MSG_NOTICE(Using GStreamer Core Plugins in $GST_PLUGINS_DIR)
AC_MSG_NOTICE(Using GStreamer Base Plugins in $GSTPB_PLUGINS_DIR) AC_MSG_NOTICE(Using GStreamer Base Plugins in $GSTPB_PLUGINS_DIR)
dnl liboil is required dnl liboil is required for cpu detection for libpostproc
dnl FIXME : In theory we should be able to compile libpostproc with cpudetect
dnl capabilities, which would enable us to get rid of this
PKG_CHECK_MODULES(LIBOIL, liboil-$LIBOIL_MAJORMINOR >= $LIBOIL_REQ, HAVE_LIBOIL=yes, HAVE_LIBOIL=no) PKG_CHECK_MODULES(LIBOIL, liboil-$LIBOIL_MAJORMINOR >= $LIBOIL_REQ, HAVE_LIBOIL=yes, HAVE_LIBOIL=no)
if test "x$HAVE_LIBOIL" != "xyes" if test "x$HAVE_LIBOIL" != "xyes"
then then
AC_ERROR([liboil-$LIBOIL_REQ or later is required]) AC_MSG_ERROR([liboil-$LIBOIL_REQ or later is required])
AC_ERROR
fi fi
AC_SUBST(LIBOIL_CFLAGS) AC_SUBST(LIBOIL_CFLAGS)
@ -150,7 +153,11 @@ if test "x$USE_DEBUG" = xyes; then
fi fi
AC_SUBST(PROFILE_CFLAGS) AC_SUBST(PROFILE_CFLAGS)
DEPRECATED_CFLAGS="-DGST_DISABLE_DEPRECATED" if test "x$GST_CVS" = "xyes"; then
DEPRECATED_CFLAGS="-DGST_DISABLE_DEPRECATED"
else
DEPRECATED_CFLAGS=""
fi
AC_SUBST(DEPRECATED_CFLAGS) AC_SUBST(DEPRECATED_CFLAGS)
dnl every flag in GST_OPTION_CFLAGS can be overridden at make time dnl every flag in GST_OPTION_CFLAGS can be overridden at make time
@ -235,25 +242,47 @@ if test "x$with_system_ffmpeg" = "xyes"; then
dnl No, this is not too extreme, we want people to see and read the above dnl No, this is not too extreme, we want people to see and read the above
sleep 15 sleep 15
else else
source ./ffmpegrev
AC_MSG_NOTICE([Using ffmpeg revision $FFMPEG_REVISION])
dnl libgstffmpeg.la: include dirs
FFMPEG_CFLAGS="-I \$(top_srcdir)/gst-libs/ext/ffmpeg/libavformat \ FFMPEG_CFLAGS="-I \$(top_srcdir)/gst-libs/ext/ffmpeg/libavformat \
-I \$(top_srcdir)/gst-libs/ext/ffmpeg/libavutil \ -I \$(top_srcdir)/gst-libs/ext/ffmpeg/libavutil \
-I \$(top_srcdir)/gst-libs/ext/ffmpeg/libavcodec" -I \$(top_srcdir)/gst-libs/ext/ffmpeg/libavcodec -Wno-deprecated-declarations"
FFMPEG_LIBS="\$(top_builddir)/gst-libs/ext/ffmpeg/libavformat/libavformat.la"
dnl libgstffmpeg.la: libs to statically link to
FFMPEG_LIBS="\$(top_builddir)/gst-libs/ext/ffmpeg/libavformat/libavformat.a \
\$(top_builddir)/gst-libs/ext/ffmpeg/libavcodec/libavcodec.a \
\$(top_builddir)/gst-libs/ext/ffmpeg/libavutil/libavutil.a \
-lz"
dnl
POSTPROC_CFLAGS="-I \$(top_srcdir)/gst-libs/ext/ffmpeg/libpostproc \ POSTPROC_CFLAGS="-I \$(top_srcdir)/gst-libs/ext/ffmpeg/libpostproc \
-I \$(top_srcdir)/gst-libs/ext/ffmpeg/libavformat \ -I \$(top_srcdir)/gst-libs/ext/ffmpeg/libavformat \
-I \$(top_srcdir)/gst-libs/ext/ffmpeg/libavutil \ -I \$(top_srcdir)/gst-libs/ext/ffmpeg/libavutil \
-I \$(top_srcdir)/gst-libs/ext/ffmpeg/libavcodec" -I \$(top_srcdir)/gst-libs/ext/ffmpeg/libavcodec"
POSTPROC_LIBS="\$(top_builddir)/gst-libs/ext/ffmpeg/libavcodec/libavcodec.la"
dnl libgstpostproc.la: libs to statically link to
POSTPROC_LIBS="\$(top_builddir)/gst-libs/ext/ffmpeg/libpostproc/libpostproc.a \
\$(top_builddir)/gst-libs/ext/ffmpeg/libavutil/libavutil.a"
FFMPEG_SUBDIRS=gst-libs FFMPEG_SUBDIRS=gst-libs
AC_DEFINE(HAVE_AVI_H) AC_DEFINE(HAVE_AVI_H)
AC_DEFINE([FFMPEG_SOURCE], ["local snapshot"], [Describes where the FFmpeg libraries come from.]) AC_DEFINE([FFMPEG_SOURCE], ["local snapshot"], [Describes where the FFmpeg libraries come from.])
ac_configure_args="$ac_configure_args --disable-v4l --disable-audio-oss --disable-dv1394 --disable-vhook --disable-ffmpeg --disable-ffserver --disable-ffplay --disable-sdltest --enable-pp" ac_configure_args="$ac_configure_args --disable-vhook --disable-ffserver --disable-ffplay --enable-pp --enable-gpl --enable-static --disable-shared --disable-encoder=flac --disable-decoder=cavs --extra-cflags=-fPIC"
AC_SUBST(FFMPEG_CO_DIR)
AC_SUBST(FFMPEG_SVN)
AC_SUBST(FFMPEG_REVISION)
AC_CONFIG_SUBDIRS(gst-libs/ext/ffmpeg) AC_CONFIG_SUBDIRS(gst-libs/ext/ffmpeg)
AC_MSG_NOTICE([Using included FFMpeg code]) AC_MSG_NOTICE([Using included FFMpeg code])
fi fi
AC_SUBST(FFMPEG_CFLAGS) AC_SUBST(FFMPEG_CFLAGS)
AC_SUBST(FFMPEG_LIBS) AC_SUBST(FFMPEG_LIBS)
AC_SUBST(FFMPEG_SUBDIRS) AC_SUBST(FFMPEG_SUBDIRS)
AC_SUBST(POSTPROC_CFLAGS)
AC_SUBST(POSTPROC_LIBS)
AC_DEFINE_UNQUOTED(HAVE_FFMPEG_UNINSTALLED, $HAVE_FFMPEG_UNINSTALLED, AC_DEFINE_UNQUOTED(HAVE_FFMPEG_UNINSTALLED, $HAVE_FFMPEG_UNINSTALLED,
[Defined if building against uninstalled FFmpeg source]) [Defined if building against uninstalled FFmpeg source])

View file

@ -9,7 +9,9 @@ libgstffmpeg_la_SOURCES = gstffmpeg.c \
gstffmpegdemux.c \ gstffmpegdemux.c \
gstffmpegmux.c \ gstffmpegmux.c \
gstffmpegdeinterlace.c \ gstffmpegdeinterlace.c \
gstffmpegscale.c gstffmpegaudioresample.c
# \
# gstffmpegscale.c
libgstffmpeg_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \ libgstffmpeg_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
$(FFMPEG_CFLAGS) $(FFMPEG_CFLAGS)

View file

@ -143,10 +143,13 @@ plugin_init (GstPlugin * plugin)
gst_ffmpegdemux_register (plugin); gst_ffmpegdemux_register (plugin);
gst_ffmpegmux_register (plugin); gst_ffmpegmux_register (plugin);
gst_ffmpegdeinterlace_register (plugin); gst_ffmpegdeinterlace_register (plugin);
#if 0
gst_ffmpegscale_register (plugin); gst_ffmpegscale_register (plugin);
#endif
#if 0 #if 0
gst_ffmpegcsp_register (plugin); gst_ffmpegcsp_register (plugin);
#endif #endif
gst_ffmpegaudioresample_register (plugin);
register_protocol (&gstreamer_protocol); register_protocol (&gstreamer_protocol);

View file

@ -48,7 +48,10 @@ extern gboolean gst_ffmpegdec_register (GstPlugin * plugin);
extern gboolean gst_ffmpegenc_register (GstPlugin * plugin); extern gboolean gst_ffmpegenc_register (GstPlugin * plugin);
extern gboolean gst_ffmpegmux_register (GstPlugin * plugin); extern gboolean gst_ffmpegmux_register (GstPlugin * plugin);
extern gboolean gst_ffmpegcsp_register (GstPlugin * plugin); extern gboolean gst_ffmpegcsp_register (GstPlugin * plugin);
#if 0
extern gboolean gst_ffmpegscale_register (GstPlugin * plugin); extern gboolean gst_ffmpegscale_register (GstPlugin * plugin);
#endif
extern gboolean gst_ffmpegaudioresample_register (GstPlugin * plugin);
extern gboolean gst_ffmpegdeinterlace_register (GstPlugin * plugin); extern gboolean gst_ffmpegdeinterlace_register (GstPlugin * plugin);
int gst_ffmpeg_avcodec_open (AVCodecContext *avctx, AVCodec *codec); int gst_ffmpeg_avcodec_open (AVCodecContext *avctx, AVCodec *codec);

View file

@ -0,0 +1,294 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* This file:
* Copyright (C) 2005 Luca Ognibene <luogni@tin.it>
* Copyright (C) 2006 Martin Zlomek <martin.zlomek@itonis.tv>
*
* 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
#ifdef HAVE_FFMPEG_UNINSTALLED
#include <avcodec.h>
#else
#include <ffmpeg/avcodec.h>
#endif
#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
#include <gst/video/video.h>
#include "gstffmpeg.h"
#include "gstffmpegcodecmap.h"
typedef struct _GstFFMpegAudioResample
{
GstBaseTransform element;
GstPad *sinkpad, *srcpad;
gint in_rate, out_rate;
gint in_channels, out_channels;
ReSampleContext *res;
} GstFFMpegAudioResample;
typedef struct _GstFFMpegAudioResampleClass
{
GstBaseTransformClass parent_class;
} GstFFMpegAudioResampleClass;
#define GST_TYPE_FFMPEGAUDIORESAMPLE \
(gst_ffmpegaudioresample_get_type())
#define GST_FFMPEGAUDIORESAMPLE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGAUDIORESAMPLE,GstFFMpegAudioResample))
#define GST_FFMPEGAUDIORESAMPLE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGAUDIORESAMPLE,GstFFMpegAudioResampleClass))
#define GST_IS_FFMPEGAUDIORESAMPLE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGAUDIORESAMPLE))
#define GST_IS_FFMPEGAUDIORESAMPLE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGAUDIORESAMPLE))
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-raw-int, endianness = (int) BYTE_ORDER, signed = (boolean) true, width = (int) 16, depth = (int) 16, channels = (int) { 1 , 2 }, rate = (int) [1, MAX ]")
);
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-raw-int, endianness = (int) BYTE_ORDER, signed = (boolean) true, width = (int) 16, depth = (int) 16, channels = (int) [ 1 , 6 ], rate = (int) [1, MAX ]")
);
GST_BOILERPLATE (GstFFMpegAudioResample, gst_ffmpegaudioresample, GstBaseTransform,
GST_TYPE_BASE_TRANSFORM);
static void gst_ffmpegaudioresample_finalize (GObject * object);
static GstCaps *gst_ffmpegaudioresample_transform_caps (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps);
static gboolean gst_ffmpegaudioresample_transform_size (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps, guint size, GstCaps *othercaps,
guint * othersize);
static gboolean gst_ffmpegaudioresample_get_unit_size (GstBaseTransform * trans,
GstCaps * caps, guint * size);
static gboolean gst_ffmpegaudioresample_set_caps (GstBaseTransform * trans,
GstCaps * incaps, GstCaps * outcaps);
static GstFlowReturn gst_ffmpegaudioresample_transform (GstBaseTransform * trans,
GstBuffer * inbuf, GstBuffer * outbuf);
static void
gst_ffmpegaudioresample_base_init (gpointer g_class)
{
static GstElementDetails plugin_details = {
"FFMPEG Audio resampling element",
"Filter/Converter/Audio",
"Converts audio from one samplerate to another",
"Edward Hervey <bilboed@bilboed.com>",
};
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
gst_element_class_set_details (element_class, &plugin_details);
}
static void
gst_ffmpegaudioresample_class_init (GstFFMpegAudioResampleClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass);
gobject_class->finalize = gst_ffmpegaudioresample_finalize;
trans_class->transform_caps =
GST_DEBUG_FUNCPTR (gst_ffmpegaudioresample_transform_caps);
trans_class->get_unit_size =
GST_DEBUG_FUNCPTR (gst_ffmpegaudioresample_get_unit_size);
trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_ffmpegaudioresample_set_caps);
trans_class->transform = GST_DEBUG_FUNCPTR (gst_ffmpegaudioresample_transform);
trans_class->transform_size = GST_DEBUG_FUNCPTR (gst_ffmpegaudioresample_transform_size);
trans_class->passthrough_on_same_caps = TRUE;
}
static void
gst_ffmpegaudioresample_init (GstFFMpegAudioResample * resample, GstFFMpegAudioResampleClass * klass)
{
GstBaseTransform *trans = GST_BASE_TRANSFORM (resample);
gst_pad_set_bufferalloc_function (trans->sinkpad, NULL);
resample->res = NULL;
}
static void
gst_ffmpegaudioresample_finalize (GObject * object)
{
GstFFMpegAudioResample *resample = GST_FFMPEGAUDIORESAMPLE (object);
if (resample->res != NULL)
audio_resample_close (resample->res);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static GstCaps *
gst_ffmpegaudioresample_transform_caps (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps)
{
GstCaps *retcaps;
GstStructure * struc;
retcaps = gst_caps_copy (caps);
struc = gst_caps_get_structure (retcaps, 0);
gst_structure_set (struc, "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
GST_LOG_OBJECT (trans, "returning caps %" GST_PTR_FORMAT,
retcaps);
return retcaps;
}
static gboolean gst_ffmpegaudioresample_transform_size (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps, guint size, GstCaps *othercaps,
guint * othersize)
{
gint inrate, outrate;
gint inchanns, outchanns;
GstStructure *ins, *outs;
gboolean ret;
guint64 conv;
ins = gst_caps_get_structure (caps, 0);
outs = gst_caps_get_structure (othercaps, 0);
/* Get input/output sample rate and channels */
ret = gst_structure_get_int (ins, "rate", &inrate);
ret &= gst_structure_get_int (ins, "channels", &inchanns);
ret &= gst_structure_get_int (outs, "rate", &outrate);
ret &= gst_structure_get_int (outs, "channels", &outchanns);
if (!ret)
return FALSE;
conv = gst_util_uint64_scale(size, outrate * outchanns,
inrate * inchanns);
*othersize = (guint) conv;
GST_DEBUG_OBJECT (trans, "Transformed size from %d to %d",
size, *othersize);
return TRUE;
}
static gboolean
gst_ffmpegaudioresample_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
guint * size)
{
gint channels;
GstStructure * structure;
gboolean ret;
g_assert (size);
structure = gst_caps_get_structure (caps, 0);
ret = gst_structure_get_int (structure, "channels", &channels);
g_return_val_if_fail (ret, FALSE);
*size = 2 * channels;
return TRUE;
}
static gboolean
gst_ffmpegaudioresample_set_caps (GstBaseTransform * trans, GstCaps * incaps,
GstCaps * outcaps)
{
GstFFMpegAudioResample *resample = GST_FFMPEGAUDIORESAMPLE (trans);
GstStructure *instructure = gst_caps_get_structure (incaps, 0);
GstStructure *outstructure = gst_caps_get_structure (outcaps, 0);
GST_LOG_OBJECT (resample, "incaps:%"GST_PTR_FORMAT,
incaps);
GST_LOG_OBJECT (resample, "outcaps:%"GST_PTR_FORMAT,
outcaps);
if (!gst_structure_get_int (instructure, "channels", &resample->in_channels))
return FALSE;
if (!gst_structure_get_int (instructure, "rate", &resample->in_rate))
return FALSE;
if (!gst_structure_get_int (outstructure, "channels", &resample->out_channels))
return FALSE;
if (!gst_structure_get_int (outstructure, "rate", &resample->out_rate))
return FALSE;
resample->res = audio_resample_init (resample->out_channels, resample->in_channels,
resample->out_rate, resample->in_rate);
if (resample->res == NULL)
return FALSE;
return TRUE;
}
static GstFlowReturn
gst_ffmpegaudioresample_transform (GstBaseTransform * trans, GstBuffer * inbuf,
GstBuffer * outbuf)
{
GstFFMpegAudioResample *resample = GST_FFMPEGAUDIORESAMPLE (trans);
gint nbsamples;
gint ret;
gst_buffer_copy_metadata (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS);
nbsamples = GST_BUFFER_SIZE (inbuf) / (2 * resample->in_channels);
GST_LOG_OBJECT (resample, "input buffer duration:%"GST_TIME_FORMAT,
GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)));
GST_DEBUG_OBJECT (resample, "audio_resample(ctx, output:%p [size:%d], input:%p [size:%d], nbsamples:%d",
GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf),
GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf),
nbsamples);
ret = audio_resample (resample->res, (short *) GST_BUFFER_DATA(outbuf),
(short *) GST_BUFFER_DATA (inbuf), nbsamples);
GST_DEBUG_OBJECT (resample, "audio_resample returned %d", ret);
GST_BUFFER_DURATION(outbuf) = gst_util_uint64_scale (ret, GST_SECOND,
resample->out_rate);
GST_BUFFER_SIZE (outbuf) = ret * 2 * resample->out_channels;
GST_LOG_OBJECT (resample, "Output buffer duration:%"GST_TIME_FORMAT,
GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
return GST_FLOW_OK;
}
gboolean
gst_ffmpegaudioresample_register (GstPlugin * plugin)
{
return gst_element_register (plugin, "ffaudioresample",
GST_RANK_NONE, GST_TYPE_FFMPEGAUDIORESAMPLE);
}

View file

@ -87,7 +87,7 @@ gst_ffmpeg_mb_decision_get_type (void)
static const GEnumValue ffmpeg_mb_decisions[] = { static const GEnumValue ffmpeg_mb_decisions[] = {
{FF_MB_DECISION_SIMPLE, "Use method set by mb-cmp", "simple"}, {FF_MB_DECISION_SIMPLE, "Use method set by mb-cmp", "simple"},
{FF_MB_DECISION_BITS, {FF_MB_DECISION_BITS,
"Chooses the one which needs the fewest bits aka vhq mode", "bits"}, "Chooses the one which needs the fewest bits aka vhq mode", "bits"},
{FF_MB_DECISION_RD, "Rate Distortion", "rd"}, {FF_MB_DECISION_RD, "Rate Distortion", "rd"},
{0, NULL, NULL}, {0, NULL, NULL},
}; };
@ -223,6 +223,7 @@ gst_ffmpeg_pre_me_get_type (void)
{0, "Disabled", "off"}, {0, "Disabled", "off"},
{1, "Only after I-frames", "key"}, {1, "Only after I-frames", "key"},
{2, "Always", "all"}, {2, "Always", "all"},
{0, NULL, NULL}
}; };
ffmpeg_pre_me_type = ffmpeg_pre_me_type =
@ -243,6 +244,7 @@ gst_ffmpeg_pred_method_get_type (void)
{FF_PRED_LEFT, "Left", "left"}, {FF_PRED_LEFT, "Left", "left"},
{FF_PRED_PLANE, "Plane", "plane"}, {FF_PRED_PLANE, "Plane", "plane"},
{FF_PRED_MEDIAN, "Median", "median"}, {FF_PRED_MEDIAN, "Median", "median"},
{0, NULL, NULL}
}; };
ffmpeg_pred_method = ffmpeg_pred_method =
@ -265,22 +267,22 @@ gst_ffmpeg_flags_get_type (void)
{CODEC_FLAG_GMC, "GMC", "gmc"}, {CODEC_FLAG_GMC, "GMC", "gmc"},
{CODEC_FLAG_MV0, "Always try a MB with MV (0,0)", "mv0"}, {CODEC_FLAG_MV0, "Always try a MB with MV (0,0)", "mv0"},
{CODEC_FLAG_PART, {CODEC_FLAG_PART,
"Store MV, DC and AC coefficients in seperate partitions", "part"}, "Store MV, DC and AC coefficients in seperate partitions", "part"},
{CODEC_FLAG_GRAY, "Only decode/encode grayscale", "gray"}, {CODEC_FLAG_GRAY, "Only decode/encode grayscale", "gray"},
{CODEC_FLAG_NORMALIZE_AQP, {CODEC_FLAG_NORMALIZE_AQP,
"Normalize Adaptive Quantization (masking, etc)", "aqp"}, "Normalize Adaptive Quantization (masking, etc)", "aqp"},
{CODEC_FLAG_TRELLIS_QUANT, "Trellis Quantization", "trellis"}, {CODEC_FLAG_TRELLIS_QUANT, "Trellis Quantization", "trellis"},
{CODEC_FLAG_GLOBAL_HEADER, {CODEC_FLAG_GLOBAL_HEADER,
"Global headers in extradata instead of every keyframe", "Global headers in extradata instead of every keyframe",
"global-headers"}, "global-headers"},
{CODEC_FLAG_AC_PRED, "H263 Advanced Intra Coding / MPEG4 AC prediction", {CODEC_FLAG_AC_PRED, "H263 Advanced Intra Coding / MPEG4 AC prediction",
"aic"}, "aic"},
{CODEC_FLAG_H263P_UMV, "Unlimited Motion Vector", "umv"}, {CODEC_FLAG_H263P_UMV, "Unlimited Motion Vector", "umv"},
{CODEC_FLAG_CBP_RD, "Rate Distoration Optimization for CBP", "cbp-rd"}, {CODEC_FLAG_CBP_RD, "Rate Distoration Optimization for CBP", "cbp-rd"},
{CODEC_FLAG_QP_RD, "Rate Distoration Optimization for QP selection", {CODEC_FLAG_QP_RD, "Rate Distoration Optimization for QP selection",
"qp-rd"}, "qp-rd"},
{CODEC_FLAG_SVCD_SCAN_OFFSET, {CODEC_FLAG_SVCD_SCAN_OFFSET,
"Reserve space for SVCD scan offset user data", "scanoffset"}, "Reserve space for SVCD scan offset user data", "scanoffset"},
{CODEC_FLAG_CLOSED_GOP, "Closed GOP", "closedgop"}, {CODEC_FLAG_CLOSED_GOP, "Closed GOP", "closedgop"},
{0, NULL, NULL}, {0, NULL, NULL},
}; };

View file

@ -193,13 +193,10 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
switch (codec_id) { switch (codec_id) {
case CODEC_ID_MPEG1VIDEO: case CODEC_ID_MPEG1VIDEO:
/* For decoding, CODEC_ID_MPEG2VIDEO is preferred... So omit here */ /* FIXME: bitrate */
if (encode) { caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg",
/* FIXME: bitrate */ "mpegversion", G_TYPE_INT, 1,
caps = gst_ff_vid_caps_new (context, codec_id, "video/mpeg", "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
"mpegversion", G_TYPE_INT, 1,
"systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
}
break; break;
case CODEC_ID_MPEG2VIDEO: case CODEC_ID_MPEG2VIDEO:
@ -288,12 +285,9 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
break; break;
case CODEC_ID_MP2: case CODEC_ID_MP2:
/* we use CODEC_ID_MP3 for decoding */ /* FIXME: bitrate */
if (encode) { caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
/* FIXME: bitrate */ "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
"mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
}
break; break;
case CODEC_ID_MP3: case CODEC_ID_MP3:
@ -310,26 +304,15 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
} }
break; break;
case CODEC_ID_VORBIS: case CODEC_ID_AC3:
/* This one is disabled for several reasons: /* FIXME: bitrate */
* - GStreamer already has perfect Ogg and Vorbis support caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-ac3", NULL);
* - The ffmpeg implementation depends on libvorbis/libogg,
* which are not included in the ffmpeg that GStreamer ships.
* - The ffmpeg implementation depends on shared objects between
* the ogg demuxer and vorbis decoder, which GStreamer doesn't.
*/
break; break;
case CODEC_ID_AC3: case CODEC_ID_ATRAC3:
/* Decoding is disabled, because: caps = gst_ff_aud_caps_new (context, codec_id, "audio/atrac3", NULL);
* - it depends on liba52, which we don't ship in ffmpeg.
* - we already have a liba52 plugin ourselves.
*/
if (encode) {
/* FIXME: bitrate */
caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-ac3", NULL);
}
break; break;
case CODEC_ID_DTS: case CODEC_ID_DTS:
caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dts", NULL); caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-dts", NULL);
break; break;
@ -554,12 +537,15 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6-flash", NULL); caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6-flash", NULL);
break; break;
case CODEC_ID_VP6A:
caps = gst_ff_vid_caps_new (context, codec_id, "video/x-vp6-alpha", NULL);
break;
case CODEC_ID_THEORA: case CODEC_ID_THEORA:
caps = gst_ff_vid_caps_new (context, codec_id, "video/x-theora", NULL); caps = gst_ff_vid_caps_new (context, codec_id, "video/x-theora", NULL);
break; break;
case CODEC_ID_AAC: case CODEC_ID_AAC:
case CODEC_ID_MPEG4AAC:
caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg", caps = gst_ff_aud_caps_new (context, codec_id, "audio/mpeg",
"mpegversion", G_TYPE_INT, 4, NULL); "mpegversion", G_TYPE_INT, 4, NULL);
break; break;
@ -645,10 +631,14 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
break; break;
case CODEC_ID_WMV3: case CODEC_ID_WMV3:
case CODEC_ID_VC1:
caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv", caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
"wmvversion", G_TYPE_INT, 3, NULL); "wmvversion", G_TYPE_INT, 3, NULL);
break; break;
case CODEC_ID_VC1:
caps = gst_ff_vid_caps_new (context, codec_id, "video/x-wmv",
"wmvversion", G_TYPE_INT, 3, "fourcc", GST_TYPE_FOURCC,
GST_MAKE_FOURCC('W', 'V', 'C', '1'), NULL);
break;
case CODEC_ID_QDM2: case CODEC_ID_QDM2:
caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-qdm2", NULL); caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-qdm2", NULL);
break; break;
@ -685,6 +675,14 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
} }
break; break;
case CODEC_ID_KMVC:
caps = gst_ff_vid_caps_new (context, codec_id, "video/x-kmvc", NULL);
break;
case CODEC_ID_NUV:
caps = gst_ff_vid_caps_new (context, codec_id, "video/x-nuv", NULL);
break;
case CODEC_ID_PNG: case CODEC_ID_PNG:
caps = gst_ff_vid_caps_new (context, codec_id, "image/png", NULL); caps = gst_ff_vid_caps_new (context, codec_id, "image/png", NULL);
break; break;
@ -811,6 +809,7 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_ADPCM_IMA_DK4: case CODEC_ID_ADPCM_IMA_DK4:
case CODEC_ID_ADPCM_IMA_WS: case CODEC_ID_ADPCM_IMA_WS:
case CODEC_ID_ADPCM_IMA_SMJPEG: case CODEC_ID_ADPCM_IMA_SMJPEG:
case CODEC_ID_ADPCM_IMA_AMV:
case CODEC_ID_ADPCM_MS: case CODEC_ID_ADPCM_MS:
case CODEC_ID_ADPCM_4XM: case CODEC_ID_ADPCM_4XM:
case CODEC_ID_ADPCM_XA: case CODEC_ID_ADPCM_XA:
@ -823,6 +822,10 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_ADPCM_SBPRO_2: case CODEC_ID_ADPCM_SBPRO_2:
case CODEC_ID_ADPCM_SBPRO_3: case CODEC_ID_ADPCM_SBPRO_3:
case CODEC_ID_ADPCM_SBPRO_4: case CODEC_ID_ADPCM_SBPRO_4:
case CODEC_ID_ADPCM_EA_R1:
case CODEC_ID_ADPCM_EA_R2:
case CODEC_ID_ADPCM_EA_R3:
case CODEC_ID_ADPCM_THP:
{ {
gchar *layout = NULL; gchar *layout = NULL;
@ -845,6 +848,9 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_ADPCM_IMA_SMJPEG: case CODEC_ID_ADPCM_IMA_SMJPEG:
layout = "smjpeg"; layout = "smjpeg";
break; break;
case CODEC_ID_ADPCM_IMA_AMV:
layout = "amv";
break;
case CODEC_ID_ADPCM_MS: case CODEC_ID_ADPCM_MS:
layout = "microsoft"; layout = "microsoft";
break; break;
@ -881,6 +887,18 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_ADPCM_SBPRO_4: case CODEC_ID_ADPCM_SBPRO_4:
layout = "sbpro4"; layout = "sbpro4";
break; break;
case CODEC_ID_ADPCM_EA_R1:
layout = "ea-r1";
break;
case CODEC_ID_ADPCM_EA_R2:
layout = "ea-r3";
break;
case CODEC_ID_ADPCM_EA_R3:
layout = "ea-r3";
break;
case CODEC_ID_ADPCM_THP:
layout = "thp";
break;
default: default:
g_assert (0); /* don't worry, we never get here */ g_assert (0); /* don't worry, we never get here */
break; break;
@ -905,6 +923,11 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
caps = gst_ff_aud_caps_new (context, codec_id, "audio/AMR-WB", NULL); caps = gst_ff_aud_caps_new (context, codec_id, "audio/AMR-WB", NULL);
break; break;
case CODEC_ID_NELLYMOSER:
caps =
gst_ff_aud_caps_new (context, codec_id, "audio/x-nellymoser", NULL);
break;
case CODEC_ID_RA_144: case CODEC_ID_RA_144:
case CODEC_ID_RA_288: case CODEC_ID_RA_288:
case CODEC_ID_COOK: case CODEC_ID_COOK:
@ -1571,7 +1594,7 @@ gst_ffmpeg_caps_with_codecid (enum CodecID codec_id,
gst_structure_get_int (str, "unknown_svq3_flag", gst_structure_get_int (str, "unknown_svq3_flag",
&unknown_svq3_flag)) { &unknown_svq3_flag)) {
context->extradata = (guint8 *) av_mallocz (0x64); context->extradata = (guint8 *) av_mallocz (0x64);
g_stpcpy (context->extradata, "SVQ3"); g_stpcpy ((gchar *) context->extradata, "SVQ3");
flags = 1 << 3; flags = 1 << 3;
flags |= low_delay; flags |= low_delay;
flags = flags << 2; flags = flags << 2;
@ -2032,7 +2055,14 @@ gst_ffmpeg_caps_to_codecid (const GstCaps * caps, AVCodecContext * context)
id = CODEC_ID_WMV2; id = CODEC_ID_WMV2;
break; break;
case 3: case 3:
id = CODEC_ID_WMV3; {
guint32 fourcc;
if (gst_structure_get_fourcc (structure, "fourcc", &fourcc)) {
if (fourcc == GST_MAKE_FOURCC ('W', 'V', 'C', '1'))
id = CODEC_ID_VC1;
} else
id = CODEC_ID_WMV3;
}
break; break;
} }
} }
@ -2088,6 +2118,9 @@ gst_ffmpeg_caps_to_codecid (const GstCaps * caps, AVCodecContext * context)
} else if (!strcmp (mimetype, "audio/x-ac3")) { } else if (!strcmp (mimetype, "audio/x-ac3")) {
id = CODEC_ID_AC3; id = CODEC_ID_AC3;
audio = TRUE; audio = TRUE;
} else if (!strcmp (mimetype, "audio/atrac3")) {
id = CODEC_ID_ATRAC3;
audio = TRUE;
} else if (!strcmp (mimetype, "audio/x-dts")) { } else if (!strcmp (mimetype, "audio/x-dts")) {
id = CODEC_ID_DTS; id = CODEC_ID_DTS;
audio = TRUE; audio = TRUE;
@ -2157,6 +2190,9 @@ gst_ffmpeg_caps_to_codecid (const GstCaps * caps, AVCodecContext * context)
} else if (!strcmp (mimetype, "video/x-vp6-flash")) { } else if (!strcmp (mimetype, "video/x-vp6-flash")) {
id = CODEC_ID_VP6F; id = CODEC_ID_VP6F;
video = TRUE; video = TRUE;
} else if (!strcmp (mimetype, "video/x-vp6-alpha")) {
id = CODEC_ID_VP6A;
video = TRUE;
} else if (!strcmp (mimetype, "video/x-flash-screen")) { } else if (!strcmp (mimetype, "video/x-flash-screen")) {
id = CODEC_ID_FLASHSV; id = CODEC_ID_FLASHSV;
video = TRUE; video = TRUE;
@ -2367,6 +2403,9 @@ gst_ffmpeg_caps_to_codecid (const GstCaps * caps, AVCodecContext * context)
} }
} }
} else if (!strcmp (mimetype, "audio/x-nellymoser")) {
id = CODEC_ID_NELLYMOSER;
audio = TRUE;
} else if (!strncmp (mimetype, "audio/x-gst_ff-", 15)) { } else if (!strncmp (mimetype, "audio/x-gst_ff-", 15)) {
gchar ext[16]; gchar ext[16];
AVCodec *codec; AVCodec *codec;
@ -2465,6 +2504,9 @@ gst_ffmpeg_get_codecid_longname (enum CodecID codec_id)
case CODEC_ID_AC3: case CODEC_ID_AC3:
name = "AC-3 audio"; name = "AC-3 audio";
break; break;
case CODEC_ID_ATRAC3:
name = "Sony ATRAC-3";
break;
case CODEC_ID_DTS: case CODEC_ID_DTS:
name = "DTS Audio"; name = "DTS Audio";
break; break;
@ -2564,6 +2606,9 @@ gst_ffmpeg_get_codecid_longname (enum CodecID codec_id)
case CODEC_ID_VP6F: case CODEC_ID_VP6F:
name = "VP6 Flash video"; name = "VP6 Flash video";
break; break;
case CODEC_ID_VP6A:
name = "VP6 Alpha video";
break;
case CODEC_ID_FLASHSV: case CODEC_ID_FLASHSV:
name = "Flash Screen Video"; name = "Flash Screen Video";
break; break;
@ -2571,7 +2616,6 @@ gst_ffmpeg_get_codecid_longname (enum CodecID codec_id)
name = "Theora video"; name = "Theora video";
break; break;
case CODEC_ID_AAC: case CODEC_ID_AAC:
case CODEC_ID_MPEG4AAC:
name = "MPEG-2/4 AAC audio"; name = "MPEG-2/4 AAC audio";
break; break;
case CODEC_ID_ASV1: case CODEC_ID_ASV1:
@ -2745,6 +2789,12 @@ gst_ffmpeg_get_codecid_longname (enum CodecID codec_id)
case CODEC_ID_ADPCM_IMA_SMJPEG: case CODEC_ID_ADPCM_IMA_SMJPEG:
name = "IMA/SMJPEG ADPCM audio"; name = "IMA/SMJPEG ADPCM audio";
break; break;
case CODEC_ID_ADPCM_IMA_AMV:
name = "IMA/AMV ADPCM audio";
break;
case CODEC_ID_ADPCM_THP:
name = "Nintendo THP ADPCM audio";
break;
case CODEC_ID_ADPCM_MS: case CODEC_ID_ADPCM_MS:
name = "Microsoft ADPCM audio"; name = "Microsoft ADPCM audio";
break; break;
@ -2781,6 +2831,15 @@ gst_ffmpeg_get_codecid_longname (enum CodecID codec_id)
case CODEC_ID_ADPCM_YAMAHA: case CODEC_ID_ADPCM_YAMAHA:
name = "Yamaha ADPCM"; name = "Yamaha ADPCM";
break; break;
case CODEC_ID_ADPCM_EA_R1:
name = "EA ADPCM R1";
break;
case CODEC_ID_ADPCM_EA_R2:
name = "EA ADPCM R2";
break;
case CODEC_ID_ADPCM_EA_R3:
name = "EA ADPCM R3";
break;
case CODEC_ID_RA_144: case CODEC_ID_RA_144:
name = "Realaudio 14k4bps"; name = "Realaudio 14k4bps";
break; break;
@ -2850,6 +2909,15 @@ gst_ffmpeg_get_codecid_longname (enum CodecID codec_id)
case CODEC_ID_AMR_WB: case CODEC_ID_AMR_WB:
name = "3GPP AMR WideBand speech audio codec"; name = "3GPP AMR WideBand speech audio codec";
break; break;
case CODEC_ID_KMVC:
name = "Karl Morton's video Codec";
break;
case CODEC_ID_NUV:
name = "NuppelVideo codec";
break;
case CODEC_ID_NELLYMOSER:
name = "Nellymoser ASAO audio codec";
break;
default: default:
GST_LOG ("Unknown codecID 0x%x", codec_id); GST_LOG ("Unknown codecID 0x%x", codec_id);
break; break;

View file

@ -230,7 +230,8 @@ gst_ffmpegdec_base_init (GstFFMpegDecClass * klass)
details.description = g_strdup_printf ("FFMPEG %s decoder", details.description = g_strdup_printf ("FFMPEG %s decoder",
params->in_plugin->name); params->in_plugin->name);
details.author = "Wim Taymans <wim@fluendo.com>, " details.author = "Wim Taymans <wim@fluendo.com>, "
"Ronald Bultje <rbultje@ronald.bitfreak.net>"; "Ronald Bultje <rbultje@ronald.bitfreak.net>, "
"Edward Hervey <bilboed@bilboed.com>";
gst_element_class_set_details (element_class, &details); gst_element_class_set_details (element_class, &details);
g_free (details.longname); g_free (details.longname);
g_free (details.klass); g_free (details.klass);
@ -497,6 +498,7 @@ gst_ffmpegdec_open (GstFFMpegDec * ffmpegdec)
case CODEC_ID_MPEG4: case CODEC_ID_MPEG4:
case CODEC_ID_MJPEG: case CODEC_ID_MJPEG:
case CODEC_ID_MP3: case CODEC_ID_MP3:
case CODEC_ID_VC1:
GST_LOG_OBJECT (ffmpegdec, "not using parser, blacklisted codec"); GST_LOG_OBJECT (ffmpegdec, "not using parser, blacklisted codec");
ffmpegdec->pctx = NULL; ffmpegdec->pctx = NULL;
break; break;
@ -693,6 +695,8 @@ gst_ffmpegdec_get_buffer (AVCodecContext * context, AVFrame * picture)
switch (context->codec_type) { switch (context->codec_type) {
case CODEC_TYPE_VIDEO: case CODEC_TYPE_VIDEO:
/* some ffmpeg video plugins don't see the point in setting codec_type ... */
case CODEC_TYPE_UNKNOWN:
avcodec_align_dimensions (context, &width, &height); avcodec_align_dimensions (context, &width, &height);
bufsize = avpicture_get_size (context->pix_fmt, width, height); bufsize = avpicture_get_size (context->pix_fmt, width, height);
@ -1586,7 +1590,7 @@ gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec,
GstBuffer ** outbuf, GstFlowReturn * ret) GstBuffer ** outbuf, GstFlowReturn * ret)
{ {
gint len = -1; gint len = -1;
gint have_data; gint have_data = AVCODEC_MAX_AUDIO_FRAME_SIZE;
GST_DEBUG_OBJECT (ffmpegdec, GST_DEBUG_OBJECT (ffmpegdec,
"size:%d, ts:%" GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT "size:%d, ts:%" GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT
@ -1602,7 +1606,7 @@ gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec,
ffmpegdec->last_buffer = NULL; ffmpegdec->last_buffer = NULL;
} }
len = avcodec_decode_audio (ffmpegdec->context, len = avcodec_decode_audio2 (ffmpegdec->context,
(int16_t *) GST_BUFFER_DATA (*outbuf), &have_data, data, size); (int16_t *) GST_BUFFER_DATA (*outbuf), &have_data, data, size);
GST_DEBUG_OBJECT (ffmpegdec, GST_DEBUG_OBJECT (ffmpegdec,
"Decode audio: len=%d, have_data=%d", len, have_data); "Decode audio: len=%d, have_data=%d", len, have_data);
@ -2242,10 +2246,18 @@ gst_ffmpegdec_register (GstPlugin * plugin)
in_plugin = first_avcodec; in_plugin = first_avcodec;
GST_LOG ("Registering decoders");
while (in_plugin) { while (in_plugin) {
GstFFMpegDecClassParams *params; GstFFMpegDecClassParams *params;
GstCaps *srccaps = NULL, *sinkcaps = NULL; GstCaps *srccaps = NULL, *sinkcaps = NULL;
gchar *type_name; gchar *type_name;
gchar *plugin_name;
/* only decoders */
if (!in_plugin->decode) {
goto next;
}
/* no quasi-codecs, please */ /* no quasi-codecs, please */
if (in_plugin->id == CODEC_ID_RAWVIDEO || if (in_plugin->id == CODEC_ID_RAWVIDEO ||
@ -2254,30 +2266,46 @@ gst_ffmpegdec_register (GstPlugin * plugin)
goto next; goto next;
} }
/* only decoders */ /* no codecs for which we're GUARANTEED to have better alternatives */
if (!in_plugin->decode) { /* MPEG1VIDEO : the mpeg2video decoder is preferred */
/* MP2 : Use MP3 for decoding */
if (!strcmp (in_plugin->name, "gif") ||
!strcmp (in_plugin->name, "vorbis") ||
!strcmp (in_plugin->name, "mpeg1video") ||
!strcmp (in_plugin->name, "mp2")) {
GST_LOG ("Ignoring decoder %s", in_plugin->name);
goto next; goto next;
} }
/* name */ /* name */
if (!gst_ffmpeg_get_codecid_longname (in_plugin->id)) { if (!gst_ffmpeg_get_codecid_longname (in_plugin->id)) {
GST_INFO ("Add decoder %s (%d) please", in_plugin->name, in_plugin->id); GST_WARNING ("Add a longname mapping for decoder %s (%d) please",
in_plugin->name, in_plugin->id);
goto next; goto next;
} }
/* first make sure we've got a supported type */ /* first make sure we've got a supported type */
sinkcaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, FALSE); sinkcaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, FALSE);
if (!sinkcaps) {
GST_WARNING ("Couldn't get input caps for decoder '%s'", in_plugin->name);
}
if (in_plugin->type == CODEC_TYPE_VIDEO) { if (in_plugin->type == CODEC_TYPE_VIDEO) {
srccaps = gst_caps_from_string ("video/x-raw-rgb; video/x-raw-yuv"); srccaps = gst_caps_from_string ("video/x-raw-rgb; video/x-raw-yuv");
} else { } else {
srccaps = srccaps =
gst_ffmpeg_codectype_to_caps (in_plugin->type, NULL, in_plugin->id); gst_ffmpeg_codectype_to_caps (in_plugin->type, NULL, in_plugin->id);
} }
if (!sinkcaps || !srccaps) if (!sinkcaps || !srccaps) {
GST_WARNING ("Couldn't get source or sink caps for decoder %s",
in_plugin->name);
goto next; goto next;
}
/* construct the type */ /* construct the type */
type_name = g_strdup_printf ("ffdec_%s", in_plugin->name); plugin_name = g_strdup ((gchar *) in_plugin->name);
g_strdelimit (plugin_name, NULL, '_');
type_name = g_strdup_printf ("ffdec_%s", plugin_name);
g_free (plugin_name);
/* if it's already registered, drop it */ /* if it's already registered, drop it */
if (g_type_from_name (type_name)) { if (g_type_from_name (type_name)) {
@ -2338,5 +2366,7 @@ gst_ffmpegdec_register (GstPlugin * plugin)
in_plugin = in_plugin->next; in_plugin = in_plugin->next;
} }
GST_LOG ("Finished Registering decoders");
return TRUE; return TRUE;
} }

View file

@ -143,9 +143,6 @@ gst_ffmpegdemux_averror (gint av_errno)
case AVERROR_NUMEXPECTED: case AVERROR_NUMEXPECTED:
message = "Number syntax expected in filename"; message = "Number syntax expected in filename";
break; break;
case AVERROR_INVALIDDATA:
message = "Invalid data found";
break;
case AVERROR_NOMEM: case AVERROR_NOMEM:
message = "Not enough memory"; message = "Not enough memory";
break; break;
@ -1458,6 +1455,8 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
in_plugin = first_iformat; in_plugin = first_iformat;
GST_LOG ("Registering demuxers");
while (in_plugin) { while (in_plugin) {
gchar *type_name, *typefind_name; gchar *type_name, *typefind_name;
gchar *p, *name = NULL; gchar *p, *name = NULL;
@ -1465,6 +1464,9 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
gint rank; gint rank;
gboolean register_typefind_func = TRUE; gboolean register_typefind_func = TRUE;
GST_LOG ("Attempting to handle ffmpeg demuxer plugin %s [%s]",
in_plugin->name, in_plugin->long_name);
/* no emulators */ /* no emulators */
if (!strncmp (in_plugin->long_name, "raw ", 4) || if (!strncmp (in_plugin->long_name, "raw ", 4) ||
!strncmp (in_plugin->long_name, "pcm ", 4) || !strncmp (in_plugin->long_name, "pcm ", 4) ||
@ -1546,6 +1548,7 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
/* Try to find the caps that belongs here */ /* Try to find the caps that belongs here */
sinkcaps = gst_ffmpeg_formatid_to_caps (name); sinkcaps = gst_ffmpeg_formatid_to_caps (name);
if (!sinkcaps) { if (!sinkcaps) {
GST_WARNING ("Couldn't get sinkcaps for demuxer %s", in_plugin->name);
goto next; goto next;
} }
/* This is a bit ugly, but we just take all formats /* This is a bit ugly, but we just take all formats
@ -1604,5 +1607,7 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
in_plugin = in_plugin->next; in_plugin = in_plugin->next;
} }
GST_LOG ("Finished registering demuxers");
return TRUE; return TRUE;
} }

View file

@ -946,6 +946,8 @@ gst_ffmpegenc_register (GstPlugin * plugin)
in_plugin = first_avcodec; in_plugin = first_avcodec;
GST_LOG ("Registering encoders");
/* build global ffmpeg param/property info */ /* build global ffmpeg param/property info */
gst_ffmpeg_cfg_init (); gst_ffmpeg_cfg_init ();
@ -967,9 +969,17 @@ gst_ffmpegenc_register (GstPlugin * plugin)
goto next; goto next;
} }
/* no codecs for which we're GUARANTEED to have better alternatives */
if (!strcmp (in_plugin->name, "vorbis") ||
!strcmp (in_plugin->name, "gif") || !strcmp (in_plugin->name, "flac")) {
GST_LOG ("Ignoring encoder %s", in_plugin->name);
goto next;
}
/* name */ /* name */
if (!gst_ffmpeg_get_codecid_longname (in_plugin->id)) { if (!gst_ffmpeg_get_codecid_longname (in_plugin->id)) {
GST_INFO ("Add encoder %s (%d) please", in_plugin->name, in_plugin->id); GST_WARNING ("Add a longname mapping for encoder %s (%d) please",
in_plugin->name, in_plugin->id);
goto next; goto next;
} }
@ -982,9 +992,11 @@ gst_ffmpegenc_register (GstPlugin * plugin)
sinkcaps = sinkcaps =
gst_ffmpeg_codectype_to_caps (in_plugin->type, NULL, in_plugin->id); gst_ffmpeg_codectype_to_caps (in_plugin->type, NULL, in_plugin->id);
} }
if (!sinkcaps || !srccaps) if (!sinkcaps || !srccaps) {
GST_WARNING ("Couldn't get either source/sink caps for encoder %s",
in_plugin->name);
goto next; goto next;
}
/* construct the type */ /* construct the type */
type_name = g_strdup_printf ("ffenc_%s", in_plugin->name); type_name = g_strdup_printf ("ffenc_%s", in_plugin->name);
@ -1018,5 +1030,7 @@ gst_ffmpegenc_register (GstPlugin * plugin)
in_plugin = in_plugin->next; in_plugin = in_plugin->next;
} }
GST_LOG ("Finished registering encoders");
return TRUE; return TRUE;
} }

View file

@ -481,7 +481,7 @@ gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data)
ffmpegmux->opened = TRUE; ffmpegmux->opened = TRUE;
/* flush the header so it will be used as streamheader */ /* flush the header so it will be used as streamheader */
put_flush_packet (&ffmpegmux->context->pb); put_flush_packet (ffmpegmux->context->pb);
} }
/* take the one with earliest timestamp, /* take the one with earliest timestamp,
@ -556,8 +556,8 @@ gst_ffmpegmux_collected (GstCollectPads * pads, gpointer user_data)
/* close down */ /* close down */
av_write_trailer (ffmpegmux->context); av_write_trailer (ffmpegmux->context);
ffmpegmux->opened = FALSE; ffmpegmux->opened = FALSE;
put_flush_packet (&ffmpegmux->context->pb); put_flush_packet (ffmpegmux->context->pb);
url_fclose (&ffmpegmux->context->pb); url_fclose (ffmpegmux->context->pb);
gst_pad_push_event (ffmpegmux->srcpad, gst_event_new_eos ()); gst_pad_push_event (ffmpegmux->srcpad, gst_event_new_eos ());
return GST_FLOW_UNEXPECTED; return GST_FLOW_UNEXPECTED;
} }
@ -598,7 +598,7 @@ gst_ffmpegmux_change_state (GstElement * element, GstStateChange transition)
} }
if (ffmpegmux->opened) { if (ffmpegmux->opened) {
ffmpegmux->opened = FALSE; ffmpegmux->opened = FALSE;
url_fclose (&ffmpegmux->context->pb); url_fclose (ffmpegmux->context->pb);
} }
break; break;
case GST_STATE_CHANGE_READY_TO_NULL: case GST_STATE_CHANGE_READY_TO_NULL:
@ -673,6 +673,8 @@ gst_ffmpegmux_register (GstPlugin * plugin)
in_plugin = first_oformat; in_plugin = first_oformat;
GST_LOG ("Registering muxers");
while (in_plugin) { while (in_plugin) {
gchar *type_name; gchar *type_name;
gchar *p; gchar *p;
@ -682,11 +684,15 @@ gst_ffmpegmux_register (GstPlugin * plugin)
/* Try to find the caps that belongs here */ /* Try to find the caps that belongs here */
srccaps = gst_ffmpeg_formatid_to_caps (in_plugin->name); srccaps = gst_ffmpeg_formatid_to_caps (in_plugin->name);
if (!srccaps) { if (!srccaps) {
GST_WARNING ("Couldn't get source caps for muxer %s", in_plugin->name);
goto next; goto next;
} }
if (!gst_ffmpeg_formatid_get_codecids (in_plugin->name, if (!gst_ffmpeg_formatid_get_codecids (in_plugin->name,
&video_ids, &audio_ids)) { &video_ids, &audio_ids)) {
gst_caps_unref (srccaps); gst_caps_unref (srccaps);
GST_WARNING
("Couldn't get sink caps for muxer %s, mapping maybe missing ?",
in_plugin->name);
goto next; goto next;
} }
videosinkcaps = video_ids ? gst_ffmpegmux_get_id_caps (video_ids) : NULL; videosinkcaps = video_ids ? gst_ffmpegmux_get_id_caps (video_ids) : NULL;
@ -749,5 +755,7 @@ gst_ffmpegmux_register (GstPlugin * plugin)
in_plugin = in_plugin->next; in_plugin = in_plugin->next;
} }
GST_LOG ("Finished registering muxers");
return TRUE; return TRUE;
} }

4
ffmpegrev Normal file
View file

@ -0,0 +1,4 @@
# 6315, 10844, 10876, 10910, 10932, 10939
FFMPEG_REVISION=11247
FFMPEG_CO_DIR=gst-libs/ext/ffmpeg
FFMPEG_SVN=svn://svn.mplayerhq.hu/ffmpeg/trunk

View file

@ -10,6 +10,46 @@
SUBDIRS = SUBDIRS =
DIST_SUBDIRS = ffmpeg DIST_SUBDIRS = ffmpeg
TMP_DIST_DIR=ffmpeg-dist
DIST_DIR=$(TMP_DIST_DIR)/.ffmpeg
all-local: all-local:
cd ffmpeg && $(MAKE) cd ffmpeg && $(MAKE)
clean-local:
cd ffmpeg && $(MAKE) distclean
dist-clean:
rm -rf $(TMP_DIST_DIR)
dist-local: dist-clean
svn -r $(FFMPEG_REVISION) co $(FFMPEG_SVN) $(TMP_DIST_DIR)
mkdir $(DIST_DIR)
pwd
cp $(TMP_DIST_DIR)/*.c $(TMP_DIST_DIR)/*.h $(TMP_DIST_DIR)/Makefile $(TMP_DIST_DIR)/configure $(TMP_DIST_DIR)/version.sh $(DIST_DIR)
cp $(TMP_DIST_DIR)/common.mak $(TMP_DIST_DIR)/Changelog $(TMP_DIST_DIR)/COPYING.* $(TMP_DIST_DIR)/INSTALL $(DIST_DIR)
cp $(TMP_DIST_DIR)/Doxyfile $(TMP_DIST_DIR)/ffinstall.nsi $(TMP_DIST_DIR)/CREDITS $(TMP_DIST_DIR)/MAINTAINERS $(DIST_DIR)
@for d in `cd $(TMP_DIST_DIR) && ls -d */`; \
do mkdir $(DIST_DIR)/$$d; \
cp $(TMP_DIST_DIR)/$$d* $(DIST_DIR)/$$d; \
if [ `ls -d $(TMP_DIST_DIR)/$$d*/ | wc -w` != "" ]; \
then for id in `cd $(TMP_DIST_DIR)/$$d && ls -d */`; \
do mkdir $(DIST_DIR)/$$d$$id; \
cp $(TMP_DIST_DIR)/$$d$$id/*.c $(TMP_DIST_DIR)/$$d$$id/*.h $(DIST_DIR)/$$d$$id; \
done \
fi \
done
rm -rf ffmpeg
mv $(DIST_DIR) ffmpeg
echo "Patching ffmpeg ./configure"
sed -e '/Unknown option/ {N;N;s/exit 1//; }' ffmpeg/configure > ffmpeg/configure.tmp
mv ffmpeg/configure.tmp ffmpeg/configure
chmod +x ffmpeg/configure
rm -rf $(TMP_DIST_DIR)
distdir: dist-local
cp -r ffmpeg Makefile* ${distdir}
dist: dist-local
tar -czf ffmpeg.tar.gz ffmpeg