aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2013-12-27 11:04:01 +0100
committerSebastian Dröge <sebastian@centricular.com>2013-12-27 11:04:01 +0100
commit4d912e229cc8d946e85ea967063619dd78a83ede (patch)
treeb7f9d3b2308dd2892c921cf1dad50127788684c4
parent6f5ff9b84f6e3ad68f3e777622282d5db6ccc0e0 (diff)
Imported Upstream version 1.2.2upstream/1.2.2
-rw-r--r--ChangeLog75
-rw-r--r--NEWS2
-rwxr-xr-xconfigure36
-rw-r--r--configure.ac6
-rw-r--r--ext/libav/gstavaudenc.c26
-rw-r--r--ext/libav/gstavaudenc.h1
-rw-r--r--ext/libav/gstavcodecmap.c24
-rw-r--r--ext/libav/gstavcodecmap.h42
-rw-r--r--ext/libav/gstavviddec.c82
-rw-r--r--ext/libav/gstavvidenc.c24
-rw-r--r--ext/libav/gstavvidenc.h1
-rw-r--r--gst-libav.doap10
-rw-r--r--gst-libav.spec2
13 files changed, 291 insertions, 40 deletions
diff --git a/ChangeLog b/ChangeLog
index d1c26ac..28dc75c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,80 @@
+=== release 1.2.2 ===
+
+2013-12-26 Sebastian Dröge <slomo@coaxion.net>
+
+ * configure.ac:
+ releasing 1.2.2
+
+2013-12-07 11:35:09 +0100 Mark Nauwelaerts <mnauw@users.sourceforge.net>
+
+ * ext/libav/gstavviddec.c:
+ avviddec: improve buffer handling and semantics
+ ... so as to focus on providing *a* buffer rather than one (too) tied
+ to a frame, in particular allowing multiple allocations related to a frame.
+ Fixes https://bugzilla.gnome.org/show_bug.cgi?id=697806
+
+2013-11-26 20:57:37 +0100 Mark Nauwelaerts <mnauw@users.sourceforge.net>
+
+ * ext/libav/gstavviddec.c:
+ avviddec: discard unused input frames
+ ... to avoid these piling up in list of pending frames.
+ Fixes https://bugzilla.gnome.org/show_bug.cgi?id=693772
+
+2013-11-26 20:55:43 +0100 Mark Nauwelaerts <mnauw@users.sourceforge.net>
+
+ * ext/libav/gstavviddec.c:
+ avviddec: really release frame at proper time
+ ... by also removing it from the pending list of frames,
+ where it may still be in if it has never been submitted to _finish.
+ This could happen if is a decode-only frame, or in skipped decoding
+ situation, ...
+ Fixes https://bugzilla.gnome.org/show_bug.cgi?id=693772
+
+2013-12-07 12:10:13 +0100 Mark Nauwelaerts <mnauw@users.sourceforge.net>
+
+ * ext/libav/gstavvidenc.c:
+ avvidenc: plug input_state leak
+
+2013-12-02 20:21:34 +0100 Mark Nauwelaerts <mnauw@users.sourceforge.net>
+
+ * ext/libav/gstavviddec.c:
+ avviddec: only use upstream framerate if really specified
+ Fixes https://bugzilla.gnome.org/show_bug.cgi?id=704161
+
+2013-10-26 09:34:30 +0100 Tim-Philipp Müller <tim@centricular.com>
+
+ * ext/libav/gstavaudenc.c:
+ avaudenc: post better error message if experimental codecs don't work
+ https://bugzilla.gnome.org/show_bug.cgi?id=691617
+
+2013-10-26 09:09:28 +0100 Tim-Philipp Müller <tim@centricular.com>
+
+ * ext/libav/gstavcodecmap.c:
+ codecmap: use TRUE for boolean fields in caps
+
+2013-10-14 14:50:57 -0600 Greg Rutz <greg@gsr-tek.com>
+
+ * ext/libav/gstavaudenc.c:
+ * ext/libav/gstavaudenc.h:
+ * ext/libav/gstavcodecmap.c:
+ * ext/libav/gstavcodecmap.h:
+ * ext/libav/gstavvidenc.c:
+ * ext/libav/gstavvidenc.h:
+ avenc: Add compliance property
+ Add a new property to GstFFMpegVidEnc and GstFFMpegAudEnc to supply
+ the "strict compliance" value to AVCodecContext
+ https://bugzilla.gnome.org/show_bug.cgi?id=691617
+
=== release 1.2.1 ===
-2013-11-09 Sebastian Dröge <slomo@coaxion.net>
+2013-11-09 16:02:14 +0100 Sebastian Dröge <sebastian@centricular.com>
+ * ChangeLog:
+ * NEWS:
+ * RELEASE:
* configure.ac:
- releasing 1.2.1
+ * gst-libav.doap:
+ Release 1.2.1
2013-11-04 23:20:17 +0000 Tim-Philipp Müller <tim@centricular.com>
diff --git a/NEWS b/NEWS
index 4ce6afb..18ce783 100644
--- a/NEWS
+++ b/NEWS
@@ -1,2 +1,2 @@
-This is GStreamer Libav Plugins 1.2.1
+This is GStreamer Libav Plugins 1.2.2
diff --git a/configure b/configure
index 58b17c1..0aed3f6 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for GStreamer libav 1.2.1.
+# Generated by GNU Autoconf 2.69 for GStreamer libav 1.2.2.
#
# Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer>.
#
@@ -591,8 +591,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='GStreamer libav'
PACKAGE_TARNAME='gst-libav'
-PACKAGE_VERSION='1.2.1'
-PACKAGE_STRING='GStreamer libav 1.2.1'
+PACKAGE_VERSION='1.2.2'
+PACKAGE_STRING='GStreamer libav 1.2.2'
PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer'
PACKAGE_URL=''
@@ -1519,7 +1519,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures GStreamer libav 1.2.1 to adapt to many kinds of systems.
+\`configure' configures GStreamer libav 1.2.2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1590,7 +1590,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of GStreamer libav 1.2.1:";;
+ short | recursive ) echo "Configuration of GStreamer libav 1.2.2:";;
esac
cat <<\_ACEOF
@@ -1759,7 +1759,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-GStreamer libav configure 1.2.1
+GStreamer libav configure 1.2.2
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2174,7 +2174,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by GStreamer libav $as_me 1.2.1, which was
+It was created by GStreamer libav $as_me 1.2.2, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3152,7 +3152,7 @@ fi
# Define the identity of the package.
PACKAGE='gst-libav'
- VERSION='1.2.1'
+ VERSION='1.2.2'
cat >>confdefs.h <<_ACEOF
@@ -3362,9 +3362,9 @@ END
fi
- PACKAGE_VERSION_MAJOR=$(echo 1.2.1 | cut -d'.' -f1)
- PACKAGE_VERSION_MINOR=$(echo 1.2.1 | cut -d'.' -f2)
- PACKAGE_VERSION_MICRO=$(echo 1.2.1 | cut -d'.' -f3)
+ PACKAGE_VERSION_MAJOR=$(echo 1.2.2 | cut -d'.' -f1)
+ PACKAGE_VERSION_MINOR=$(echo 1.2.2 | cut -d'.' -f2)
+ PACKAGE_VERSION_MICRO=$(echo 1.2.2 | cut -d'.' -f3)
@@ -3375,7 +3375,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking nano version" >&5
$as_echo_n "checking nano version... " >&6; }
- NANO=$(echo 1.2.1 | cut -d'.' -f4)
+ NANO=$(echo 1.2.2 | cut -d'.' -f4)
if test x"$NANO" = x || test "x$NANO" = "x0" ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: 0 (release)" >&5
@@ -8021,10 +8021,10 @@ fi
done
- GST_CURRENT=201
+ GST_CURRENT=202
GST_REVISION=0
- GST_AGE=201
- GST_LIBVERSION=201:0:201
+ GST_AGE=202
+ GST_LIBVERSION=202:0:202
@@ -12350,7 +12350,7 @@ CC="$lt_save_CC"
GST_REQ=1.2.0
-GST_PBREQ=1.2.0
+GST_PBREQ=1.2.2
ORC_REQ=0.4.16
@@ -18233,7 +18233,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by GStreamer libav $as_me 1.2.1, which was
+This file was extended by GStreamer libav $as_me 1.2.2, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -18299,7 +18299,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-GStreamer libav config.status 1.2.1
+GStreamer libav config.status 1.2.2
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index eb3e481..c1066ee 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,7 +3,7 @@ AC_PREREQ(2.62)
dnl initialize autoconf
dnl when going to/from release please set the nano (fourth number) right !
dnl releases only do Wall, cvs and prerelease does Werror too
-AC_INIT(GStreamer libav, 1.2.1,
+AC_INIT(GStreamer libav, 1.2.2,
http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer,
gst-libav)
@@ -42,11 +42,11 @@ GST_API_VERSION=1.0
AC_SUBST(GST_API_VERSION)
AG_GST_LIBTOOL_PREPARE
-AS_LIBTOOL(GST, 201, 0, 201)
+AS_LIBTOOL(GST, 202, 0, 202)
dnl *** required versions of GStreamer stuff ***
GST_REQ=1.2.0
-GST_PBREQ=1.2.0
+GST_PBREQ=1.2.2
ORC_REQ=0.4.16
ORC_CHECK([$ORC_REQ])
diff --git a/ext/libav/gstavaudenc.c b/ext/libav/gstavaudenc.c
index ee758fa..83a2eee 100644
--- a/ext/libav/gstavaudenc.c
+++ b/ext/libav/gstavaudenc.c
@@ -52,6 +52,7 @@ enum
PROP_0,
PROP_BIT_RATE,
PROP_RTP_PAYLOAD_SIZE,
+ PROP_COMPLIANCE,
};
/* A number of function prototypes are given so we can refer to them later. */
@@ -151,6 +152,11 @@ gst_ffmpegaudenc_class_init (GstFFMpegAudEncClass * klass)
g_param_spec_int ("bitrate", "Bit Rate",
"Target Audio Bitrate", 0, G_MAXINT, DEFAULT_AUDIO_BITRATE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_COMPLIANCE,
+ g_param_spec_enum ("compliance", "Compliance",
+ "Adherence of the encoder to the specifications",
+ GST_TYPE_FFMPEG_COMPLIANCE, FFMPEG_DEFAULT_COMPLIANCE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gobject_class->finalize = gst_ffmpegaudenc_finalize;
@@ -174,6 +180,8 @@ gst_ffmpegaudenc_init (GstFFMpegAudEnc * ffmpegaudenc)
ffmpegaudenc->context = avcodec_alloc_context3 (klass->in_plugin);
ffmpegaudenc->opened = FALSE;
+ ffmpegaudenc->compliance = FFMPEG_DEFAULT_COMPLIANCE;
+
gst_audio_encoder_set_drainable (GST_AUDIO_ENCODER (ffmpegaudenc), TRUE);
}
@@ -265,7 +273,7 @@ gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
}
/* if we set it in _getcaps we should set it also in _link */
- ffmpegaudenc->context->strict_std_compliance = -1;
+ ffmpegaudenc->context->strict_std_compliance = ffmpegaudenc->compliance;
/* user defined properties */
if (ffmpegaudenc->bitrate > 0) {
@@ -316,6 +324,16 @@ gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
if (avcodec_get_context_defaults3 (ffmpegaudenc->context,
oclass->in_plugin) < 0)
GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to set context defaults");
+
+ if ((oclass->in_plugin->capabilities & CODEC_CAP_EXPERIMENTAL) &&
+ ffmpegaudenc->compliance != GST_FFMPEG_EXPERIMENTAL) {
+ GST_ELEMENT_ERROR (ffmpegaudenc, LIBRARY, SETTINGS,
+ ("Codec is experimental, but settings don't allow encoders to "
+ "produce output of experimental quality"),
+ ("This codec may not create output that is conformant to the specs "
+ "or of good quality. If you must use it anyway, set the "
+ "compliance property to experimental"));
+ }
return FALSE;
}
@@ -641,6 +659,9 @@ gst_ffmpegaudenc_set_property (GObject * object,
case PROP_RTP_PAYLOAD_SIZE:
ffmpegaudenc->rtp_payload_size = g_value_get_int (value);
break;
+ case PROP_COMPLIANCE:
+ ffmpegaudenc->compliance = g_value_get_enum (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -665,6 +686,9 @@ gst_ffmpegaudenc_get_property (GObject * object,
case PROP_RTP_PAYLOAD_SIZE:
g_value_set_int (value, ffmpegaudenc->rtp_payload_size);
break;
+ case PROP_COMPLIANCE:
+ g_value_set_enum (value, ffmpegaudenc->compliance);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
diff --git a/ext/libav/gstavaudenc.h b/ext/libav/gstavaudenc.h
index b01184f..bce0900 100644
--- a/ext/libav/gstavaudenc.h
+++ b/ext/libav/gstavaudenc.h
@@ -42,6 +42,7 @@ struct _GstFFMpegAudEnc
/* cache */
gint bitrate;
gint rtp_payload_size;
+ gint compliance;
/* other settings are copied over straight,
* include a context here, rather than copy-and-past it from avcodec.h */
diff --git a/ext/libav/gstavcodecmap.c b/ext/libav/gstavcodecmap.c
index c247d01..a5be63e 100644
--- a/ext/libav/gstavcodecmap.c
+++ b/ext/libav/gstavcodecmap.c
@@ -66,6 +66,28 @@ static const struct
AV_CH_STEREO_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}
};
+GType
+gst_ffmpeg_compliance_get_type (void)
+{
+ static GType ffmpeg_compliance_type = 0;
+ static const GEnumValue compliance_types[] = {
+ {GST_FFMPEG_VERY_STRICT, "Strictly conform to older spec",
+ "verystrict"},
+ {GST_FFMPEG_STRICT, "Strictly conform to current spec", "strict"},
+ {GST_FFMPEG_NORMAL, "Normal behavior", "normal"},
+ {GST_FFMPEG_UNOFFICIAL, "Allow unofficial extensions", "unofficial"},
+ {GST_FFMPEG_EXPERIMENTAL, "Allow nonstandardized experimental things",
+ "experimental"},
+ {0, NULL, NULL}
+ };
+
+ if (!ffmpeg_compliance_type) {
+ ffmpeg_compliance_type =
+ g_enum_register_static ("GstFFMpegCompliance", compliance_types);
+ }
+ return ffmpeg_compliance_type;
+}
+
static guint64
gst_ffmpeg_channel_positions_to_layout (GstAudioChannelPosition * pos,
gint channels)
@@ -931,7 +953,7 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case AV_CODEC_ID_LJPEG:
caps =
gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/jpeg",
- "parsed", G_TYPE_BOOLEAN, 1, NULL);
+ "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
break;
case AV_CODEC_ID_SP5X:
diff --git a/ext/libav/gstavcodecmap.h b/ext/libav/gstavcodecmap.h
index 01ce9b1..f392f96 100644
--- a/ext/libav/gstavcodecmap.h
+++ b/ext/libav/gstavcodecmap.h
@@ -25,6 +25,48 @@
#include <gst/audio/audio.h>
#include <gst/video/video.h>
+/**
+ * GstFFMpegCompliance:
+ * @GST_FFMPEG_VERY_STRICT: Strictly conform to an older
+ * more strict version of the spec or reference software
+ * @GST_FFMPEG_STRICT: Strictly conform to all the things
+ * in the spec no matter what consequences.
+ * @GST_FFMPEG_NORMAL:
+ * @GST_FFMPEG_UNOFFICIAL: Allow unofficial extensions
+ * @GST_FFMPEG_EXPERIMENTAL: Allow nonstandardized
+ * experimental things.
+ *
+ * This setting instructs libav on how strictly it should follow the
+ * associated standard.
+ *
+ * From avcodec.h:
+ * Setting this to STRICT or higher means the encoder and decoder will
+ * generally do stupid things, whereas setting it to unofficial or lower
+ * will mean the encoder might produce output that is not supported by all
+ * spec-compliant decoders. Decoders don't differentiate between normal,
+ * unofficial and experimental (that is, they always try to decode things
+ * when they can) unless they are explicitly asked to behave stupidly
+ * (=strictly conform to the specs)
+ */
+typedef enum {
+ GST_FFMPEG_VERY_STRICT = FF_COMPLIANCE_VERY_STRICT,
+ GST_FFMPEG_STRICT = FF_COMPLIANCE_STRICT,
+ GST_FFMPEG_NORMAL = FF_COMPLIANCE_NORMAL,
+ GST_FFMPEG_UNOFFICIAL = FF_COMPLIANCE_UNOFFICIAL,
+ GST_FFMPEG_EXPERIMENTAL = FF_COMPLIANCE_EXPERIMENTAL,
+} GstFFMpegCompliance;
+
+/*
+ * _compliance_get_type () Returns an enum type that can be
+ * used as a property to indicate desired FFMpeg adherence to
+ * an associated specification
+ */
+
+GType
+gst_ffmpeg_compliance_get_type (void);
+#define GST_TYPE_FFMPEG_COMPLIANCE (gst_ffmpeg_compliance_get_type ())
+#define FFMPEG_DEFAULT_COMPLIANCE GST_FFMPEG_NORMAL
+
/*
* _codecid_to_caps () gets the GstCaps that belongs to
* a certain CodecID for a pad with compressed data.
diff --git a/ext/libav/gstavviddec.c b/ext/libav/gstavviddec.c
index 0635767..3453231 100644
--- a/ext/libav/gstavviddec.c
+++ b/ext/libav/gstavviddec.c
@@ -525,6 +525,7 @@ typedef struct
GstVideoCodecFrame *frame;
gboolean mapped;
GstVideoFrame vframe;
+ GstBuffer *buffer;
} GstFFMpegVidDecVideoFrame;
static GstFFMpegVidDecVideoFrame *
@@ -539,11 +540,13 @@ gst_ffmpegviddec_video_frame_new (GstVideoCodecFrame * frame)
}
static void
-gst_ffmpegviddec_video_frame_free (GstFFMpegVidDecVideoFrame * frame)
+gst_ffmpegviddec_video_frame_free (GstFFMpegVidDec * ffmpegdec,
+ GstFFMpegVidDecVideoFrame * frame)
{
if (frame->mapped)
gst_video_frame_unmap (&frame->vframe);
- gst_video_codec_frame_unref (frame->frame);
+ gst_video_decoder_release_frame (GST_VIDEO_DECODER (ffmpegdec), frame->frame);
+ gst_buffer_replace (&frame->buffer, NULL);
g_slice_free (GstFFMpegVidDecVideoFrame, frame);
}
@@ -567,6 +570,8 @@ gst_ffmpegviddec_get_buffer (AVCodecContext * context, AVFrame * picture)
* picture back from ffmpeg we can use this to correctly timestamp the output
* buffer */
picture->reordered_opaque = context->reordered_opaque;
+ GST_DEBUG_OBJECT (ffmpegdec, "opaque value SN %d",
+ (gint32) picture->reordered_opaque);
frame =
gst_video_decoder_get_frame (GST_VIDEO_DECODER (ffmpegdec),
@@ -574,6 +579,11 @@ gst_ffmpegviddec_get_buffer (AVCodecContext * context, AVFrame * picture)
if (G_UNLIKELY (frame == NULL))
goto no_frame;
+ /* now it has a buffer allocated, so it is real and will also
+ * be _released */
+ GST_VIDEO_CODEC_FRAME_FLAG_UNSET (frame,
+ GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY);
+
if (G_UNLIKELY (frame->output_buffer != NULL))
goto duplicate_frame;
@@ -597,9 +607,16 @@ gst_ffmpegviddec_get_buffer (AVCodecContext * context, AVFrame * picture)
if (ret != GST_FLOW_OK)
goto alloc_failed;
+ /* piggy-backed alloc'ed on the frame,
+ * and there was much rejoicing and we are grateful.
+ * Now take away buffer from frame, we will give it back later when decoded.
+ * This allows multiple request for a buffer per frame; unusual but possible. */
+ gst_buffer_replace (&dframe->buffer, frame->output_buffer);
+ gst_buffer_replace (&frame->output_buffer, NULL);
+
/* Fill avpicture */
info = &ffmpegdec->output_state->info;
- if (!gst_video_frame_map (&dframe->vframe, info, dframe->frame->output_buffer,
+ if (!gst_video_frame_map (&dframe->vframe, info, dframe->buffer,
GST_MAP_READWRITE))
goto invalid_frame;
dframe->mapped = TRUE;
@@ -627,7 +644,7 @@ gst_ffmpegviddec_get_buffer (AVCodecContext * context, AVFrame * picture)
}
gst_video_frame_unmap (&dframe->vframe);
dframe->mapped = FALSE;
- gst_buffer_replace (&frame->output_buffer, NULL);
+ gst_buffer_replace (&dframe->buffer, NULL);
ffmpegdec->current_dr = FALSE;
goto no_dr;
@@ -644,7 +661,7 @@ gst_ffmpegviddec_get_buffer (AVCodecContext * context, AVFrame * picture)
* the opaque data. */
picture->type = FF_BUFFER_TYPE_USER;
- GST_LOG_OBJECT (ffmpegdec, "returned frame %p", frame->output_buffer);
+ GST_LOG_OBJECT (ffmpegdec, "returned frame %p", dframe->buffer);
return 0;
@@ -669,8 +686,7 @@ invalid_frame:
{
/* alloc default buffer when we can't get one from downstream */
GST_LOG_OBJECT (ffmpegdec, "failed to map frame, fallback alloc");
- gst_buffer_unref (frame->output_buffer);
- frame->output_buffer = NULL;
+ gst_buffer_replace (&dframe->buffer, NULL);
goto fallback;
}
fallback:
@@ -696,6 +712,8 @@ no_frame:
}
}
+/* this should havesame effect as _get_buffer wrt opaque metadata,
+ * but preserving current content, if any */
static int
gst_ffmpegviddec_reget_buffer (AVCodecContext * context, AVFrame * picture)
{
@@ -756,7 +774,7 @@ gst_ffmpegviddec_release_buffer (AVCodecContext * context, AVFrame * picture)
ffmpegdec = (GstFFMpegVidDec *) context->opaque;
frame = (GstFFMpegVidDecVideoFrame *) picture->opaque;
- GST_DEBUG_OBJECT (ffmpegdec, "release frame %d",
+ GST_DEBUG_OBJECT (ffmpegdec, "release frame SN %d",
frame->frame->system_frame_number);
/* check if it was our buffer */
@@ -768,7 +786,7 @@ gst_ffmpegviddec_release_buffer (AVCodecContext * context, AVFrame * picture)
/* we remove the opaque data now */
picture->opaque = NULL;
- gst_ffmpegviddec_video_frame_free (frame);
+ gst_ffmpegviddec_video_frame_free (ffmpegdec, frame);
/* zero out the reference in ffmpeg */
for (i = 0; i < 4; i++) {
@@ -920,7 +938,8 @@ gst_ffmpegviddec_negotiate (GstFFMpegVidDec * ffmpegdec,
out_info->interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
/* try to find a good framerate */
- if (in_info->fps_d) {
+ if ((in_info->fps_d && in_info->fps_n) ||
+ GST_VIDEO_INFO_FLAG_IS_SET (in_info, GST_VIDEO_FLAG_VARIABLE_FPS)) {
/* take framerate from input when it was specified (#313970) */
fps_n = in_info->fps_n;
fps_d = in_info->fps_d;
@@ -1205,6 +1224,10 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
out_dframe = ffmpegdec->picture->opaque;
out_frame = gst_video_codec_frame_ref (out_dframe->frame);
+ /* also give back a buffer allocated by the frame, if any */
+ gst_buffer_replace (&out_frame->output_buffer, out_dframe->buffer);
+ gst_buffer_replace (&out_dframe->buffer, NULL);
+
GST_DEBUG_OBJECT (ffmpegdec,
"pts %" G_GUINT64_FORMAT " duration %" G_GUINT64_FORMAT,
out_frame->pts, out_frame->duration);
@@ -1251,6 +1274,41 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
GST_VIDEO_BUFFER_FLAG_INTERLACED);
}
+ /* cleaning time */
+ /* so we decoded this frame, frames preceding it in decoding order
+ * that still do not have a buffer allocated seem rather useless,
+ * and can be discarded, due to e.g. misparsed bogus frame
+ * or non-keyframe in skipped decoding, ...
+ * In any case, not likely to be seen again, so discard those,
+ * before they pile up and/or mess with timestamping */
+ {
+ GList *l, *ol;
+ GstVideoDecoder *dec = GST_VIDEO_DECODER (ffmpegdec);
+ gboolean old = TRUE;
+
+ ol = l = gst_video_decoder_get_frames (dec);
+ while (l) {
+ GstVideoCodecFrame *tmp = l->data;
+
+ if (tmp == frame)
+ old = FALSE;
+
+ if (old && GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (tmp)) {
+ GST_LOG_OBJECT (dec,
+ "discarding ghost frame %p (#%d) PTS:%" GST_TIME_FORMAT " DTS:%"
+ GST_TIME_FORMAT, tmp, tmp->system_frame_number,
+ GST_TIME_ARGS (tmp->pts), GST_TIME_ARGS (tmp->dts));
+ /* drop extra ref and remove from frame list */
+ gst_video_decoder_release_frame (dec, tmp);
+ } else {
+ /* drop extra ref we got */
+ gst_video_codec_frame_unref (tmp);
+ }
+ l = l->next;
+ }
+ g_list_free (ol);
+ }
+
*ret =
gst_video_decoder_finish_frame (GST_VIDEO_DECODER (ffmpegdec), out_frame);
@@ -1386,6 +1444,10 @@ gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder,
return GST_FLOW_ERROR;
}
+ /* treat frame as void until a buffer is requested for it */
+ GST_VIDEO_CODEC_FRAME_FLAG_SET (frame,
+ GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY);
+
bdata = minfo.data;
bsize = minfo.size;
diff --git a/ext/libav/gstavvidenc.c b/ext/libav/gstavvidenc.c
index 83e052c..6f32627 100644
--- a/ext/libav/gstavvidenc.c
+++ b/ext/libav/gstavvidenc.c
@@ -62,7 +62,8 @@ enum
PROP_ME_METHOD,
PROP_BUFSIZE,
PROP_RTP_PAYLOAD_SIZE,
- PROP_CFG_BASE
+ PROP_CFG_BASE,
+ PROP_COMPLIANCE,
};
#define GST_TYPE_ME_METHOD (gst_ffmpegvidenc_me_method_get_type())
@@ -206,8 +207,14 @@ gst_ffmpegvidenc_class_init (GstFFMpegVidEncClass * klass)
"RTP Payload Size", "Target GOB length", 0, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_COMPLIANCE,
+ g_param_spec_enum ("compliance", "Compliance",
+ "Adherence of the encoder to the specifications",
+ GST_TYPE_FFMPEG_COMPLIANCE, FFMPEG_DEFAULT_COMPLIANCE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
/* register additional properties, possibly dependent on the exact CODEC */
- gst_ffmpeg_cfg_install_property (klass, PROP_CFG_BASE);
+ gst_ffmpeg_cfg_install_property (klass, PROP_COMPLIANCE);
venc_class->start = gst_ffmpegvidenc_start;
venc_class->stop = gst_ffmpegvidenc_stop;
@@ -239,6 +246,7 @@ gst_ffmpegvidenc_init (GstFFMpegVidEnc * ffmpegenc)
ffmpegenc->buffer_size = 512 * 1024;
ffmpegenc->gop_size = DEFAULT_VIDEO_GOP_SIZE;
ffmpegenc->rtp_payload_size = 0;
+ ffmpegenc->compliance = FFMPEG_DEFAULT_COMPLIANCE;
ffmpegenc->lmin = 2;
ffmpegenc->lmax = 31;
@@ -301,7 +309,7 @@ gst_ffmpegvidenc_set_format (GstVideoEncoder * encoder,
}
/* if we set it in _getcaps we should set it also in _link */
- ffmpegenc->context->strict_std_compliance = -1;
+ ffmpegenc->context->strict_std_compliance = ffmpegenc->compliance;
/* user defined properties */
ffmpegenc->context->bit_rate = ffmpegenc->bitrate;
@@ -761,6 +769,9 @@ gst_ffmpegvidenc_set_property (GObject * object,
case PROP_RTP_PAYLOAD_SIZE:
ffmpegenc->rtp_payload_size = g_value_get_int (value);
break;
+ case PROP_COMPLIANCE:
+ ffmpegenc->compliance = g_value_get_enum (value);
+ break;
default:
if (!gst_ffmpeg_cfg_set_property (object, value, pspec))
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -794,6 +805,9 @@ gst_ffmpegvidenc_get_property (GObject * object,
case PROP_RTP_PAYLOAD_SIZE:
g_value_set_int (value, ffmpegenc->rtp_payload_size);
break;
+ case PROP_COMPLIANCE:
+ g_value_set_enum (value, ffmpegenc->compliance);
+ break;
default:
if (!gst_ffmpeg_cfg_get_property (object, value, pspec))
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -845,6 +859,10 @@ gst_ffmpegvidenc_stop (GstVideoEncoder * encoder)
g_free (ffmpegenc->working_buf);
ffmpegenc->working_buf = NULL;
}
+ if (ffmpegenc->input_state) {
+ gst_video_codec_state_unref (ffmpegenc->input_state);
+ ffmpegenc->input_state = NULL;
+ }
return TRUE;
}
diff --git a/ext/libav/gstavvidenc.h b/ext/libav/gstavvidenc.h
index d19dc39..e841d6c 100644
--- a/ext/libav/gstavvidenc.h
+++ b/ext/libav/gstavvidenc.h
@@ -49,6 +49,7 @@ struct _GstFFMpegVidEnc
gint gop_size;
gint buffer_size;
gint rtp_payload_size;
+ gint compliance;
guint8 *working_buf;
gsize working_buf_size;
diff --git a/gst-libav.doap b/gst-libav.doap
index c15530e..02f040d 100644
--- a/gst-libav.doap
+++ b/gst-libav.doap
@@ -34,6 +34,16 @@ colorspace conversion elements.
<release>
<Version>
+ <revision>1.2.2</revision>
+ <branch>1.2</branch>
+ <name></name>
+ <created>2013-12-26</created>
+ <file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-libav/gst-libav-1.2.2.tar.xz" />
+ </Version>
+ </release>
+
+ <release>
+ <Version>
<revision>1.2.1</revision>
<branch>1.2</branch>
<name></name>
diff --git a/gst-libav.spec b/gst-libav.spec
index 761aaab..032061b 100644
--- a/gst-libav.spec
+++ b/gst-libav.spec
@@ -4,7 +4,7 @@
%define gst_majorminor 1.0
Name: %{gstreamer}-libav
-Version: 1.2.1
+Version: 1.2.2
Release: 1
Summary: GStreamer Streaming-media framework plug-in using libav (FFmpeg).
Group: Libraries/Multimedia