Merge branch 'master' into 0.11

unport gdkpixbuf
not merged: https://bugzilla.gnome.org/show_bug.cgi?id=654850

Conflicts:
	docs/plugins/Makefile.am
	docs/plugins/gst-plugins-good-plugins-docs.sgml
	docs/plugins/gst-plugins-good-plugins-sections.txt
	docs/plugins/gst-plugins-good-plugins.hierarchy
	docs/plugins/inspect/plugin-avi.xml
	docs/plugins/inspect/plugin-png.xml
	ext/flac/gstflacdec.c
	ext/flac/gstflacdec.h
	ext/libpng/gstpngdec.c
	ext/libpng/gstpngenc.c
	ext/speex/gstspeexdec.c
	gst/audioparsers/gstflacparse.c
	gst/flv/gstflvmux.c
	gst/rtp/gstrtpdvdepay.c
	gst/rtp/gstrtph264depay.c
This commit is contained in:
Wim Taymans 2012-03-22 11:53:24 +01:00
commit c44cd8f55b
32 changed files with 925 additions and 68 deletions

View file

@ -314,7 +314,7 @@ dnl Make sure you have a space before and after all plugins
GST_PLUGINS_NONPORTED="deinterlace interleave flx \
smpte \
videobox \
cairo cairo_gobject dv1394 \
cairo cairo_gobject dv1394 gdk_pixbuf \
oss oss4 \
osx_video osx_audio "
AC_SUBST(GST_PLUGINS_NONPORTED)
@ -386,18 +386,14 @@ AG_GST_CHECK_FEATURE(DIRECTSOUND, [DirectSound plug-in], directsoundsink, [
LDFLAGS="$LDFLAGS $DIRECTSOUND_LDFLAGS"
LIBS="$LIBS -ldsound -ldxerr9 -luser32"
AC_MSG_CHECKING(for DirectSound LDFLAGS)
AC_LINK_IFELSE([
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <windows.h>
#include <dxerr9.h>
#include <dsound.h>
int main ()
{
]], [[
DXGetErrorString9 (0);
DirectSoundCreate(NULL, NULL, NULL);
return 0;
}
]])
],
[HAVE_DIRECTSOUND="yes"],
[HAVE_DIRECTSOUND="no"])

View file

@ -868,6 +868,16 @@
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstRTSPSrc::do-rtsp-keep-alive</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Do RTSP Keep Alive</NICK>
<BLURB>Send RTSP keep alive packets, disable for old incompatible server.</BLURB>
<DEFAULT>TRUE</DEFAULT>
</ARG>
<ARG>
<NAME>GstRTPDec::skip</NAME>
<TYPE>gint</TYPE>
@ -1925,7 +1935,7 @@
<FLAGS>rwx</FLAGS>
<NICK>Seekpoints</NICK>
<BLURB>Add SEEKTABLE metadata (if > 0, number of entries, if < 0, interval in sec).</BLURB>
<DEFAULT>0</DEFAULT>
<DEFAULT>-10</DEFAULT>
</ARG>
<ARG>
@ -21525,7 +21535,7 @@
<FLAGS>rw</FLAGS>
<NICK>Transport mode</NICK>
<BLURB>Jack transport behaviour of the client.</BLURB>
<DEFAULT>No transport support</DEFAULT>
<DEFAULT></DEFAULT>
</ARG>
<ARG>
@ -21575,7 +21585,7 @@
<FLAGS>rw</FLAGS>
<NICK>Transport mode</NICK>
<BLURB>Jack transport behaviour of the client.</BLURB>
<DEFAULT>No transport support</DEFAULT>
<DEFAULT></DEFAULT>
</ARG>
<ARG>
@ -22578,3 +22588,73 @@
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstGdkPixbufOverlay::location</NAME>
<TYPE>gchar*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>location</NICK>
<BLURB>Location of image file to overlay.</BLURB>
<DEFAULT>NULL</DEFAULT>
</ARG>
<ARG>
<NAME>GstGdkPixbufOverlay::offset-x</NAME>
<TYPE>gint</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>X Offset</NICK>
<BLURB>Horizontal offset of overlay image in pixels from top-left corner of video image.</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstGdkPixbufOverlay::offset-y</NAME>
<TYPE>gint</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Y Offset</NICK>
<BLURB>Vertical offset of overlay image in pixels from top-left corner of video image.</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstGdkPixbufOverlay::overlay-height</NAME>
<TYPE>gint</TYPE>
<RANGE>>= 0</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Overlay Height</NICK>
<BLURB>Height of overlay image in pixels (0 = same as overlay image).</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstGdkPixbufOverlay::overlay-width</NAME>
<TYPE>gint</TYPE>
<RANGE>>= 0</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Overlay Width</NICK>
<BLURB>Width of overlay image in pixels (0 = same as overlay image).</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstGdkPixbufOverlay::relative-x</NAME>
<TYPE>gdouble</TYPE>
<RANGE>[0,1]</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Relative X Offset</NICK>
<BLURB>Horizontal offset of overlay image in fractions of video image width, from top-left corner of video image.</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstGdkPixbufOverlay::relative-y</NAME>
<TYPE>gdouble</TYPE>
<RANGE>[0,1]</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Relative Y Offset</NICK>
<BLURB>Vertical offset of overlay image in fractions of video image height, from top-left corner of video image.</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>

View file

@ -135,5 +135,26 @@
</caps>
</pads>
</element>
<element>
<name>wavpackparse2</name>
<longname>Wavpack audio stream parser</longname>
<class>Codec/Parser/Audio</class>
<description>Wavpack parser</description>
<author>Mark Nauwelaerts &lt;mark.nauwelaerts@collabora.co.uk&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/x-wavpack</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>audio/x-wavpack, width=(int)[ 1, 32 ], channels=(int)[ 1, 8 ], rate=(int)[ 6000, 192000 ], framed=(boolean)true; audio/x-wavpack-correction, framed=(boolean)true</details>
</caps>
</pads>
</element>
</elements>
</plugin>

View file

@ -91,4 +91,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -30,6 +30,27 @@
</caps>
</pads>
</element>
<element>
<name>gdkpixbufoverlay</name>
<longname>GdkPixbuf Overlay</longname>
<class>Filter/Effect/Video</class>
<description>Overlay an image onto a video stream</description>
<author>Tim-Philipp Müller &lt;tim centricular net&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)16711680, green_mask=(int)65280, blue_mask=(int)255, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)16711680, green_mask=(int)65280, blue_mask=(int)255, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)32, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, alpha_mask=(int)255, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)32, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, alpha_mask=(int)255, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)32, endianness=(int)4321, red_mask=(int)16711680, green_mask=(int)65280, blue_mask=(int)255, alpha_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)32, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, alpha_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-yuv, format=(fourcc){ I420, YV12, AYUV, YUY2, UYVY, v308, v210, v216, Y41B, Y42B, Y444, Y800, Y16 , NV12, NV21, UYVP, A420, YUV9, IYU1 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)16711680, green_mask=(int)65280, blue_mask=(int)255, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)16711680, green_mask=(int)65280, blue_mask=(int)255, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)32, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, alpha_mask=(int)255, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)32, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, alpha_mask=(int)255, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)32, endianness=(int)4321, red_mask=(int)16711680, green_mask=(int)65280, blue_mask=(int)255, alpha_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)32, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, alpha_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-yuv, format=(fourcc){ I420, YV12, AYUV, YUY2, UYVY, v308, v210, v216, Y41B, Y42B, Y444, Y800, Y16 , NV12, NV21, UYVP, A420, YUV9, IYU1 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
</pads>
</element>
<element>
<name>gdkpixbufscale</name>
<longname>GdkPixbuf image scaler</longname>

View file

@ -52,4 +52,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -26,7 +26,7 @@
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>audio/x-raw-int, width=(int)32, depth=(int)[ 1, 32 ], channels=(int)[ 1, 8 ], rate=(int)[ 6000, 192000 ], endianness=(int)1234, signed=(boolean)true</details>
<details>audio/x-raw-int, width=(int)8, depth=(int)8, channels=(int)[ 1, 8 ], rate=(int)[ 6000, 192000 ], endianness=(int)1234, signed=(boolean)true; audio/x-raw-int, width=(int)16, depth=(int)16, channels=(int)[ 1, 8 ], rate=(int)[ 6000, 192000 ], endianness=(int)1234, signed=(boolean)true; audio/x-raw-int, width=(int)32, depth=(int)32, channels=(int)[ 1, 8 ], rate=(int)[ 6000, 192000 ], endianness=(int)1234, signed=(boolean)true</details>
</caps>
</pads>
</element>
@ -41,13 +41,13 @@
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/x-raw-int, width=(int)32, depth=(int)[ 1, 32 ], endianness=(int)1234, channels=(int)[ 1, 8 ], rate=(int)[ 6000, 192000 ], signed=(boolean)true</details>
<details>audio/x-raw-int, width=(int)32, depth=(int){ 24, 32 }, endianness=(int)1234, channels=(int)[ 1, 8 ], rate=(int)[ 6000, 192000 ], signed=(boolean)true</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>audio/x-wavpack, width=(int)[ 1, 32 ], channels=(int)[ 1, 2 ], rate=(int)[ 6000, 192000 ], framed=(boolean)true</details>
<details>audio/x-wavpack, width=(int)[ 1, 32 ], channels=(int)[ 1, 8 ], rate=(int)[ 6000, 192000 ], framed=(boolean)true</details>
</caps>
<caps>
<name>wvcsrc</name>

View file

@ -415,6 +415,26 @@ gst_flac_dec_scan_got_frame (GstFlacDec * flacdec, guint8 * data, guint size,
return TRUE;
}
static gboolean
gst_flac_dec_handle_decoder_error (GstFlacDec * dec, gboolean msg)
{
gboolean ret;
dec->error_count++;
if (dec->error_count > 10) {
if (msg)
GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), (NULL));
dec->last_flow = GST_FLOW_ERROR;
ret = TRUE;
} else {
GST_DEBUG_OBJECT (dec, "ignoring error for now at count %d",
dec->error_count);
ret = FALSE;
}
return ret;
}
static void
gst_flac_dec_metadata_cb (const FLAC__StreamDecoder * decoder,
const FLAC__StreamMetadata * metadata, void *client_data)
@ -495,8 +515,8 @@ gst_flac_dec_error_cb (const FLAC__StreamDecoder * d,
break;
}
GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s (%d)", error, status));
dec->last_flow = GST_FLOW_ERROR;
if (gst_flac_dec_handle_decoder_error (dec, FALSE))
GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s (%d)", error, status));
}
static FLAC__StreamDecoderReadStatus
@ -674,6 +694,8 @@ gst_flac_dec_write (GstFlacDec * flacdec, const FLAC__Frame * frame,
gst_buffer_unmap (outbuf, &map);
GST_DEBUG_OBJECT (flacdec, "pushing %d samples", samples);
if (flacdec->error_count)
flacdec->error_count--;
ret = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (flacdec), outbuf, 1);

View file

@ -58,6 +58,8 @@ struct _GstFlacDec {
/* from the stream info, needed for scanning */
guint16 min_blocksize;
guint16 max_blocksize;
gint error_count;
};
struct _GstFlacDecClass {

View file

@ -203,7 +203,7 @@ static const GstFlacEncParams flacenc_params[] = {
#define DEFAULT_QUALITY 5
#define DEFAULT_PADDING 0
#define DEFAULT_SEEKPOINTS 0
#define DEFAULT_SEEKPOINTS -10
#define GST_TYPE_FLAC_ENC_QUALITY (gst_flac_enc_quality_get_type ())
static GType

View file

@ -1,12 +1,15 @@
plugin_LTLIBRARIES = libgstgdkpixbuf.la
libgstgdkpixbuf_la_SOURCES = gstgdkpixbuf.c gstgdkpixbufsink.c pixbufscale.c
libgstgdkpixbuf_la_SOURCES = gstgdkpixbuf.c gstgdkpixbufsink.c pixbufscale.c \
gstgdkpixbufoverlay.c
libgstgdkpixbuf_la_CFLAGS = \
$(GST_PLUGINS_BASE_CFLAGS) \
$(GST_CONTROLLER_CFLAGS) \
$(GST_BASE_CFLAGS) \
$(GST_CFLAGS) $(GDK_PIXBUF_CFLAGS)
libgstgdkpixbuf_la_LIBADD = \
$(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_MAJORMINOR) \
$(GST_CONTROLLER_LIBS) \
$(GST_BASE_LIBS) \
$(GST_LIBS) $(GDK_PIXBUF_LIBS)
libgstgdkpixbuf_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
@ -14,6 +17,7 @@ libgstgdkpixbuf_la_LIBTOOLFLAGS = --tag=disable-static
noinst_HEADERS = \
gstgdkpixbuf.h \
gstgdkpixbufoverlay.h \
gstgdkpixbufsink.h \
pixbufscale.h \
gstgdkanimation.h

View file

@ -27,6 +27,7 @@
#include <string.h>
#include "gstgdkpixbuf.h"
#include "gstgdkpixbufoverlay.h"
#include "gstgdkpixbufsink.h"
#include "pixbufscale.h"
@ -589,6 +590,10 @@ plugin_init (GstPlugin * plugin)
gst_gdk_pixbuf_type_find, NULL, GST_CAPS_ANY, NULL);
#endif
if (!gst_element_register (plugin, "gdkpixbufoverlay", GST_RANK_NONE,
GST_TYPE_GDK_PIXBUF_OVERLAY))
return FALSE;
if (!gst_element_register (plugin, "gdkpixbufsink", GST_RANK_NONE,
GST_TYPE_GDK_PIXBUF_SINK))
return FALSE;

View file

@ -0,0 +1,508 @@
/* GStreamer GdkPixbuf overlay
* Copyright (C) 2012 Tim-Philipp Müller <tim centricular net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Suite 500,
* Boston, MA 02110-1335, USA.
*/
/**
* SECTION:element-gdkpixbufoverlay
* @see_also:
*
* The gdkpixbufoverlay element overlays an image loaded from file onto
* a video stream.
*
* Changing the positioning or overlay width and height properties at runtime
* is supported, but it might be prudent to to protect the property setting
* code with GST_BASE_TRANSFORM_LOCK and GST_BASE_TRANSFORM_UNLOCK, as
* g_object_set() is not atomic for multiple properties passed in one go.
*
* Changing the image at runtime is currently not supported.
*
* Negative offsets are also not yet supported.
*
* <refsect2>
* <title>Example launch line</title>
* |[
* gst-launch -v videotestsrc ! gdkpixbufoverlay location=image.png ! autovideosink
* ]|
* Overlays the image in image.png onto the test video picture produced by
* videotestsrc.
* </refsect2>
*
* Since: 0.10.33
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gstgdkpixbufoverlay.h"
GST_DEBUG_CATEGORY_STATIC (gdkpixbufoverlay_debug);
#define GST_CAT_DEFAULT gdkpixbufoverlay_debug
static void gst_gdk_pixbuf_overlay_set_property (GObject * object,
guint property_id, const GValue * value, GParamSpec * pspec);
static void gst_gdk_pixbuf_overlay_get_property (GObject * object,
guint property_id, GValue * value, GParamSpec * pspec);
static void gst_gdk_pixbuf_overlay_finalize (GObject * object);
static gboolean gst_gdk_pixbuf_overlay_start (GstBaseTransform * trans);
static gboolean gst_gdk_pixbuf_overlay_stop (GstBaseTransform * trans);
static GstFlowReturn
gst_gdk_pixbuf_overlay_transform_ip (GstBaseTransform * trans, GstBuffer * buf);
static void gst_gdk_pixbuf_overlay_before_transform (GstBaseTransform * trans,
GstBuffer * outbuf);
static gboolean
gst_gdk_pixbuf_overlay_set_caps (GstBaseTransform * trans, GstCaps * incaps,
GstCaps * outcaps);
enum
{
PROP_0,
PROP_LOCATION,
PROP_OFFSET_X,
PROP_OFFSET_Y,
PROP_RELATIVE_X,
PROP_RELATIVE_Y,
PROP_OVERLAY_WIDTH,
PROP_OVERLAY_HEIGHT
};
#define VIDEO_CAPS \
GST_VIDEO_CAPS_BGRx ";" \
GST_VIDEO_CAPS_RGB ";" \
GST_VIDEO_CAPS_BGR ";" \
GST_VIDEO_CAPS_RGBx ";" \
GST_VIDEO_CAPS_xRGB ";" \
GST_VIDEO_CAPS_xBGR ";" \
GST_VIDEO_CAPS_RGBA ";" \
GST_VIDEO_CAPS_BGRA ";" \
GST_VIDEO_CAPS_ARGB ";" \
GST_VIDEO_CAPS_ABGR ";" \
GST_VIDEO_CAPS_YUV ("{I420, YV12, AYUV, YUY2, UYVY, v308, v210," \
" v216, Y41B, Y42B, Y444, Y800, Y16, NV12, NV21, UYVP, A420," \
" YUV9, IYU1}")
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (VIDEO_CAPS)
);
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (VIDEO_CAPS)
);
GST_BOILERPLATE (GstGdkPixbufOverlay, gst_gdk_pixbuf_overlay,
GstVideoFilter, GST_TYPE_VIDEO_FILTER);
static void
gst_gdk_pixbuf_overlay_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_add_static_pad_template (element_class, &sink_template);
gst_element_class_add_static_pad_template (element_class, &src_template);
gst_element_class_set_details_simple (element_class,
"GdkPixbuf Overlay", "Filter/Effect/Video",
"Overlay an image onto a video stream",
"Tim-Philipp Müller <tim centricular net>");
}
static void
gst_gdk_pixbuf_overlay_class_init (GstGdkPixbufOverlayClass * klass)
{
GstBaseTransformClass *basetrans_class = GST_BASE_TRANSFORM_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property = gst_gdk_pixbuf_overlay_set_property;
gobject_class->get_property = gst_gdk_pixbuf_overlay_get_property;
gobject_class->finalize = gst_gdk_pixbuf_overlay_finalize;
basetrans_class->start = GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_overlay_start);
basetrans_class->stop = GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_overlay_stop);
basetrans_class->set_caps =
GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_overlay_set_caps);
basetrans_class->transform_ip =
GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_overlay_transform_ip);
basetrans_class->before_transform =
GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_overlay_before_transform);
g_object_class_install_property (gobject_class, PROP_LOCATION,
g_param_spec_string ("location", "location",
"Location of image file to overlay", NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_OFFSET_X,
g_param_spec_int ("offset-x", "X Offset",
"Horizontal offset of overlay image in pixels from top-left corner "
"of video image", G_MININT, G_MAXINT, 0,
GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_OFFSET_Y,
g_param_spec_int ("offset-y", "Y Offset",
"Vertical offset of overlay image in pixels from top-left corner "
"of video image", G_MININT, G_MAXINT, 0,
GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_RELATIVE_X,
g_param_spec_double ("relative-x", "Relative X Offset",
"Horizontal offset of overlay image in fractions of video image "
"width, from top-left corner of video image", 0.0, 1.0, 0.0,
GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_RELATIVE_Y,
g_param_spec_double ("relative-y", "Relative Y Offset",
"Vertical offset of overlay image in fractions of video image "
"height, from top-left corner of video image", 0.0, 1.0, 0.0,
GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_OVERLAY_WIDTH,
g_param_spec_int ("overlay-width", "Overlay Width",
"Width of overlay image in pixels (0 = same as overlay image)", 0,
G_MAXINT, 0,
GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_OVERLAY_HEIGHT,
g_param_spec_int ("overlay-height", "Overlay Height",
"Height of overlay image in pixels (0 = same as overlay image)", 0,
G_MAXINT, 0,
GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS));
GST_DEBUG_CATEGORY_INIT (gdkpixbufoverlay_debug, "gdkpixbufoverlay", 0,
"debug category for gdkpixbufoverlay element");
}
static void
gst_gdk_pixbuf_overlay_init (GstGdkPixbufOverlay * overlay,
GstGdkPixbufOverlayClass * overlay_class)
{
overlay->offset_x = 0;
overlay->offset_y = 0;
overlay->relative_x = 0.0;
overlay->relative_y = 0.0;
overlay->overlay_width = 0;
overlay->overlay_height = 0;
}
void
gst_gdk_pixbuf_overlay_set_property (GObject * object, guint property_id,
const GValue * value, GParamSpec * pspec)
{
GstGdkPixbufOverlay *overlay = GST_GDK_PIXBUF_OVERLAY (object);
GST_OBJECT_LOCK (overlay);
switch (property_id) {
case PROP_LOCATION:
g_free (overlay->location);
overlay->location = g_value_dup_string (value);
break;
case PROP_OFFSET_X:
overlay->offset_x = g_value_get_int (value);
overlay->update_composition = TRUE;
break;
case PROP_OFFSET_Y:
overlay->offset_y = g_value_get_int (value);
overlay->update_composition = TRUE;
break;
case PROP_RELATIVE_X:
overlay->relative_x = g_value_get_double (value);
overlay->update_composition = TRUE;
break;
case PROP_RELATIVE_Y:
overlay->relative_y = g_value_get_double (value);
overlay->update_composition = TRUE;
break;
case PROP_OVERLAY_WIDTH:
overlay->overlay_width = g_value_get_int (value);
overlay->update_composition = TRUE;
break;
case PROP_OVERLAY_HEIGHT:
overlay->overlay_height = g_value_get_int (value);
overlay->update_composition = TRUE;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
GST_OBJECT_UNLOCK (overlay);
}
void
gst_gdk_pixbuf_overlay_get_property (GObject * object, guint property_id,
GValue * value, GParamSpec * pspec)
{
GstGdkPixbufOverlay *overlay = GST_GDK_PIXBUF_OVERLAY (object);
GST_OBJECT_LOCK (overlay);
switch (property_id) {
case PROP_LOCATION:
g_value_set_string (value, overlay->location);
break;
case PROP_OFFSET_X:
g_value_set_int (value, overlay->offset_x);
break;
case PROP_OFFSET_Y:
g_value_set_int (value, overlay->offset_y);
break;
case PROP_RELATIVE_X:
g_value_set_double (value, overlay->relative_x);
break;
case PROP_RELATIVE_Y:
g_value_set_double (value, overlay->relative_y);
break;
case PROP_OVERLAY_WIDTH:
g_value_set_int (value, overlay->overlay_width);
break;
case PROP_OVERLAY_HEIGHT:
g_value_set_int (value, overlay->overlay_height);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
GST_OBJECT_UNLOCK (overlay);
}
void
gst_gdk_pixbuf_overlay_finalize (GObject * object)
{
GstGdkPixbufOverlay *overlay = GST_GDK_PIXBUF_OVERLAY (object);
g_free (overlay->location);
overlay->location = NULL;
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static gboolean
gst_gdk_pixbuf_overlay_load_image (GstGdkPixbufOverlay * overlay, GError ** err)
{
GdkPixbuf *pixbuf;
guint8 *pixels, *p;
gint width, height, stride, w, h;
pixbuf = gdk_pixbuf_new_from_file (overlay->location, err);
if (pixbuf == NULL)
return FALSE;
if (!gdk_pixbuf_get_has_alpha (pixbuf)) {
GdkPixbuf *alpha_pixbuf;
/* FIXME: we could do this much more efficiently ourselves below, but
* we're lazy for now */
/* FIXME: perhaps expose substitute_color via properties */
alpha_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
g_object_unref (pixbuf);
pixbuf = alpha_pixbuf;
}
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
stride = gdk_pixbuf_get_rowstride (pixbuf);
pixels = gdk_pixbuf_get_pixels (pixbuf);
/* the memory layout in GdkPixbuf is R-G-B-A, we want:
* - B-G-R-A on little-endian platforms
* - A-R-G-B on big-endian platforms
*/
for (h = 0; h < height; ++h) {
p = pixels + (h * stride);
for (w = 0; w < width; ++w) {
guint8 tmp;
/* R-G-B-A ==> B-G-R-A */
tmp = p[0];
p[0] = p[2];
p[2] = tmp;
if (G_BYTE_ORDER == G_BIG_ENDIAN) {
/* B-G-R-A ==> A-R-G-B */
/* we can probably assume sane alignment */
*((guint32 *) p) = GUINT32_SWAP_LE_BE (*((guint32 *) p));
}
p += 4;
}
}
overlay->pixels = gst_buffer_new ();
GST_BUFFER_DATA (overlay->pixels) = pixels;
/* assume we have row padding even for the last row */
GST_BUFFER_SIZE (overlay->pixels) = height * stride;
/* transfer ownership of pixbuf to buffer */
GST_BUFFER_MALLOCDATA (overlay->pixels) = (guint8 *) pixbuf;
GST_BUFFER_FREE_FUNC (overlay->pixels) = (GFreeFunc) g_object_unref;
overlay->pixels_width = width;
overlay->pixels_height = height;
overlay->pixels_stride = stride;
overlay->update_composition = TRUE;
GST_INFO_OBJECT (overlay, "Loaded image, %d x %d", width, height);
return TRUE;
}
static gboolean
gst_gdk_pixbuf_overlay_start (GstBaseTransform * trans)
{
GstGdkPixbufOverlay *overlay = GST_GDK_PIXBUF_OVERLAY (trans);
GError *err = NULL;
if (overlay->location != NULL) {
if (!gst_gdk_pixbuf_overlay_load_image (overlay, &err))
goto error_loading_image;
gst_base_transform_set_passthrough (trans, FALSE);
} else {
GST_WARNING_OBJECT (overlay, "no image location set, doing nothing");
gst_base_transform_set_passthrough (trans, TRUE);
}
return TRUE;
/* ERRORS */
error_loading_image:
{
GST_ELEMENT_ERROR (overlay, RESOURCE, OPEN_READ,
("Could not load overlay image."), ("%s", err->message));
g_error_free (err);
return FALSE;
}
}
static gboolean
gst_gdk_pixbuf_overlay_stop (GstBaseTransform * trans)
{
GstGdkPixbufOverlay *overlay = GST_GDK_PIXBUF_OVERLAY (trans);
if (overlay->comp) {
gst_video_overlay_composition_unref (overlay->comp);
overlay->comp = NULL;
}
gst_buffer_replace (&overlay->pixels, NULL);
return TRUE;
}
static gboolean
gst_gdk_pixbuf_overlay_set_caps (GstBaseTransform * trans, GstCaps * incaps,
GstCaps * outcaps)
{
GstGdkPixbufOverlay *overlay = GST_GDK_PIXBUF_OVERLAY (trans);
GstVideoFormat video_format;
int w, h;
if (!gst_video_format_parse_caps (incaps, &video_format, &w, &h))
return FALSE;
overlay->format = video_format;
overlay->width = w;
overlay->height = h;
return TRUE;
}
static void
gst_gdk_pixbuf_overlay_update_composition (GstGdkPixbufOverlay * overlay)
{
GstVideoOverlayComposition *comp;
GstVideoOverlayRectangle *rect;
gint x, y, width, height;
x = overlay->offset_x + (overlay->relative_x * overlay->pixels_width);
y = overlay->offset_y + (overlay->relative_y * overlay->pixels_height);
/* FIXME: this should work, but seems to crash */
if (x < 0)
x = 0;
if (y < 0)
y = 0;
width = overlay->overlay_width;
if (width == 0)
width = overlay->pixels_width;
height = overlay->overlay_height;
if (height == 0)
height = overlay->pixels_height;
GST_DEBUG_OBJECT (overlay, "overlay image dimensions: %d x %d",
overlay->pixels_width, overlay->pixels_height);
GST_DEBUG_OBJECT (overlay, "properties: x,y: %d,%d (%g%%,%g%%) - WxH: %dx%d",
overlay->offset_x, overlay->offset_y,
overlay->relative_x * 100.0, overlay->relative_y * 100.0,
overlay->overlay_height, overlay->overlay_width);
GST_DEBUG_OBJECT (overlay, "overlay rendered: %d x %d @ %d,%d (onto %d x %d)",
width, height, x, y, overlay->width, overlay->height);
rect = gst_video_overlay_rectangle_new_argb (overlay->pixels,
overlay->pixels_width, overlay->pixels_height, overlay->pixels_stride,
x, y, width, height, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE);
comp = gst_video_overlay_composition_new (rect);
gst_video_overlay_rectangle_unref (rect);
if (overlay->comp)
gst_video_overlay_composition_unref (overlay->comp);
overlay->comp = comp;
}
static void
gst_gdk_pixbuf_overlay_before_transform (GstBaseTransform * trans,
GstBuffer * outbuf)
{
GstClockTime stream_time;
stream_time = gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME,
GST_BUFFER_TIMESTAMP (outbuf));
if (GST_CLOCK_TIME_IS_VALID (stream_time))
gst_object_sync_values (G_OBJECT (trans), stream_time);
}
static GstFlowReturn
gst_gdk_pixbuf_overlay_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
{
GstGdkPixbufOverlay *overlay = GST_GDK_PIXBUF_OVERLAY (trans);
GST_OBJECT_LOCK (overlay);
if (G_UNLIKELY (overlay->update_composition)) {
gst_gdk_pixbuf_overlay_update_composition (overlay);
overlay->update_composition = FALSE;
}
GST_OBJECT_UNLOCK (overlay);
gst_video_overlay_composition_blend (overlay->comp, buf);
return GST_FLOW_OK;
}

View file

@ -0,0 +1,87 @@
/* GStreamer GdkPixbuf overlay
* Copyright (C) 2012 Tim-Philipp Müller <tim centricular net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef _GST_GDK_PIXBUF_OVERLAY_H_
#define _GST_GDK_PIXBUF_OVERLAY_H_
#include <gst/video/video.h>
#include <gst/video/gstvideofilter.h>
#include <gst/video/video-overlay-composition.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
G_BEGIN_DECLS
#define GST_TYPE_GDK_PIXBUF_OVERLAY (gst_gdk_pixbuf_overlay_get_type())
#define GST_GDK_PIXBUF_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GDK_PIXBUF_OVERLAY,GstGdkPixbufOverlay))
#define GST_GDK_PIXBUF_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GDK_PIXBUF_OVERLAY,GstGdkPixbufOverlayClass))
#define GST_IS_GDK_PIXBUF_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GDK_PIXBUF_OVERLAY))
#define GST_IS_GDK_PIXBUF_OVERLAY_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GDK_PIXBUF_OVERLAY))
typedef struct _GstGdkPixbufOverlay GstGdkPixbufOverlay;
typedef struct _GstGdkPixbufOverlayClass GstGdkPixbufOverlayClass;
/**
* GstGdkPixbufOverlay:
*
* The opaque element instance structure.
*/
struct _GstGdkPixbufOverlay
{
GstVideoFilter videofilter;
/* negotiated format */
GstVideoFormat format;
gint width;
gint height;
/* properties */
gchar * location;
gint offset_x;
gint offset_y;
gdouble relative_x;
gdouble relative_y;
gint overlay_width;
gint overlay_height;
/* the loaded image */
GstBuffer * pixels;
guint pixels_width;
guint pixels_height;
guint pixels_stride;
GstVideoOverlayComposition * comp;
/* render position or dimension has changed */
gboolean update_composition;
};
struct _GstGdkPixbufOverlayClass
{
GstVideoFilterClass videofilter_class;
};
GType gst_gdk_pixbuf_overlay_get_type (void);
G_END_DECLS
#endif

View file

@ -61,7 +61,8 @@ static GstStaticPadTemplate gst_pngdec_src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGBA, RGB }"))
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
("{ RGBA, RGB, ARGB64, GRAY8, GRAY16_BE }"))
);
static GstStaticPadTemplate gst_pngdec_sink_pad_template =
@ -406,15 +407,15 @@ gst_pngdec_caps_create_and_set (GstPngDec * pngdec)
/* Get bits per channel */
bpc = png_get_bit_depth (pngdec->png, pngdec->info);
if (bpc > 8) {
/* Add alpha channel if 16-bit depth */
png_set_add_alpha (pngdec->png, 0xffff, PNG_FILLER_BEFORE);
png_set_swap (pngdec->png);
}
/* Get Color type */
color_type = png_get_color_type (pngdec->png, pngdec->info);
/* Add alpha channel if 16-bit depth, but not for GRAY images */
if ((bpc > 8) && (color_type != PNG_COLOR_TYPE_GRAY)) {
png_set_add_alpha (pngdec->png, 0xffff, PNG_FILLER_BEFORE);
png_set_swap (pngdec->png);
}
#if 0
/* We used to have this HACK to reverse the outgoing bytes, but the problem
* that originally required the hack seems to have been in ffmpegcolorspace's
@ -424,11 +425,16 @@ gst_pngdec_caps_create_and_set (GstPngDec * pngdec)
png_set_bgr (pngdec->png);
#endif
/* Gray scale converted to RGB and upscaled to 8 bits */
/* Gray scale with alpha channel converted to RGB */
if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
GST_LOG_OBJECT (pngdec,
"converting grayscale png with alpha channel to RGB");
png_set_gray_to_rgb (pngdec->png);
}
/* Gray scale converted to upscaled to 8 bits */
if ((color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
(color_type == PNG_COLOR_TYPE_GRAY)) {
GST_LOG_OBJECT (pngdec, "converting grayscale png to RGB");
png_set_gray_to_rgb (pngdec->png);
if (bpc < 8) { /* Convert to 8 bits */
GST_LOG_OBJECT (pngdec, "converting grayscale image to 8 bits");
#if PNG_LIBPNG_VER < 10400
@ -466,7 +472,18 @@ gst_pngdec_caps_create_and_set (GstPngDec * pngdec)
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
GST_LOG_OBJECT (pngdec, "we have an alpha channel, depth is 32 bits");
format = GST_VIDEO_FORMAT_RGBA;
if (bpc == 1)
format = GST_VIDEO_FORMAT_RGBA;
else
format = GST_VIDEO_FORMAT_ARGB64;
break;
case PNG_COLOR_TYPE_GRAY:
GST_LOG_OBJECT (pngdec,
"We have an gray image, depth is 8 or 16 (be) bits");
if (bpc == 1)
format = GST_VIDEO_FORMAT_GRAY8;
else
format = GST_VIDEO_FORMAT_GRAY16_BE;
break;
default:
GST_ELEMENT_ERROR (pngdec, STREAM, NOT_IMPLEMENTED, (NULL),

View file

@ -64,7 +64,7 @@ static GstStaticPadTemplate pngenc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGBA, RGB, GRAY8 }"))
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ RGBA, RGB, GRAY8, GRAY16_BE }"))
);
/* static GstElementClass *parent_class = NULL; */
@ -153,12 +153,19 @@ gst_pngenc_setcaps (GstPngEnc * pngenc, GstCaps * caps)
switch (GST_VIDEO_INFO_FORMAT (&info)) {
case GST_VIDEO_FORMAT_RGBA:
pngenc->png_color_type = PNG_COLOR_TYPE_RGBA;
pngenc->depth = 8;
break;
case GST_VIDEO_FORMAT_RGB:
pngenc->png_color_type = PNG_COLOR_TYPE_RGB;
pngenc->depth = 8;
break;
case GST_VIDEO_FORMAT_GRAY8:
pngenc->png_color_type = PNG_COLOR_TYPE_GRAY;
pngenc->depth = 8;
break;
case GST_VIDEO_FORMAT_GRAY16_BE:
pngenc->png_color_type = PNG_COLOR_TYPE_GRAY;
pngenc->depth = 16;
break;
default:
ret = FALSE;
@ -314,7 +321,7 @@ gst_pngenc_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
pngenc->png_info_ptr,
pngenc->width,
pngenc->height,
8,
pngenc->depth,
pngenc->png_color_type,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

View file

@ -52,6 +52,7 @@ struct _GstPngEnc
GstVideoInfo info;
gint png_color_type;
gint depth;
gint width;
gint height;
guint compression_level;

View file

@ -310,8 +310,9 @@ gst_speex_dec_parse_comments (GstSpeexDec * dec, GstBuffer * buf)
GST_INFO_OBJECT (dec, "tags: %" GST_PTR_FORMAT, list);
gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (dec),
gst_event_new_tag (list));
gst_audio_decoder_merge_tags (GST_AUDIO_DECODER (dec), list,
GST_TAG_MERGE_REPLACE);
gst_tag_list_free (list);
g_free (encoder);
g_free (ver);

View file

@ -78,9 +78,10 @@ gst_wavpack_stream_reader_push_back_byte (void *id, int c)
GST_DEBUG ("Pushing back one byte: 0x%x", c);
if (rid->position == 0)
return rid->position;
rid->position -= 1;
if (rid->position < 0)
rid->position = 0;
return rid->position;
}

View file

@ -378,7 +378,8 @@ typedef enum
static FrameHeaderCheckReturn
gst_flac_parse_frame_header_is_valid (GstFlacParse * flacparse,
const guint8 * data, guint size, gboolean set, guint16 * block_size_ret)
const guint8 * data, guint size, gboolean set, guint16 * block_size_ret,
gboolean * suspect)
{
GstBitReader reader = GST_BIT_READER_INIT (data, size);
guint8 blocking_strategy;
@ -572,6 +573,8 @@ gst_flac_parse_frame_header_is_valid (GstFlacParse * flacparse,
/* TODO: can we know we're on the last frame, to avoid warning ? */
GST_WARNING_OBJECT (flacparse, "Block size is not constant");
block_size = flacparse->block_size;
if (suspect)
*suspect = TRUE;
}
}
}
@ -620,6 +623,7 @@ gst_flac_parse_frame_is_valid (GstFlacParse * flacparse,
guint i, search_start, search_end;
FrameHeaderCheckReturn header_ret;
guint16 block_size;
gboolean suspect_start = FALSE, suspect_end = FALSE;
gboolean result = FALSE;
buffer = frame->buffer;
@ -630,7 +634,7 @@ gst_flac_parse_frame_is_valid (GstFlacParse * flacparse,
header_ret =
gst_flac_parse_frame_header_is_valid (flacparse, map.data, map.size, TRUE,
&block_size);
&block_size, &suspect_start);
if (header_ret == FRAME_HEADER_INVALID) {
*ret = 0;
goto cleanup;
@ -650,16 +654,23 @@ gst_flac_parse_frame_is_valid (GstFlacParse * flacparse,
for (i = search_start; i < search_end; i++, remaining--) {
if ((GST_READ_UINT16_BE (map.data + i) & 0xfffe) == 0xfff8) {
GST_LOG_OBJECT (flacparse, "possible frame end at offset %d", i);
suspect_end = FALSE;
header_ret =
gst_flac_parse_frame_header_is_valid (flacparse, map.data + i,
remaining, FALSE, NULL);
remaining, FALSE, NULL, &suspect_end);
if (header_ret == FRAME_HEADER_VALID) {
if (flacparse->check_frame_checksums) {
guint16 actual_crc = gst_flac_calculate_crc16 (map.data, i - 2);
guint16 expected_crc = GST_READ_UINT16_BE (map.data + i - 2);
if (actual_crc != expected_crc)
GST_LOG_OBJECT (flacparse,
"checking checksum, frame suspect (%d, %d)",
suspect_start, suspect_end);
if (actual_crc != expected_crc) {
GST_DEBUG_OBJECT (flacparse, "checksum did not match");
continue;
}
}
*ret = i;
flacparse->block_size = block_size;
@ -691,6 +702,15 @@ gst_flac_parse_frame_is_valid (GstFlacParse * flacparse,
}
}
/* so we searched to expected end and found nothing,
* give up on this frame (start) */
if (flacparse->max_framesize && i > 2 * flacparse->max_framesize) {
GST_LOG_OBJECT (flacparse,
"could not determine valid frame end, discarding frame (start)");
*ret = 1;
return FALSE;
}
need_more:
max = flacparse->max_framesize + 16;
if (max == 16)
@ -1397,7 +1417,7 @@ gst_flac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame,
flacparse->offset = GST_BUFFER_OFFSET (buffer);
ret =
gst_flac_parse_frame_header_is_valid (flacparse,
map.data, map.size, TRUE, NULL);
map.data, map.size, TRUE, NULL, NULL);
if (ret != FRAME_HEADER_VALID) {
GST_ERROR_OBJECT (flacparse,
"Baseclass didn't provide a complete frame");

View file

@ -1984,7 +1984,8 @@ gst_deinterlace_chain (GstPad * pad, GstBuffer * buf)
self->fields = self->new_fields;
if (self->new_mode != -1)
self->mode = self->new_mode;
self->new_mode = self->new_fields = -1;
self->new_mode = -1;
self->new_fields = -1;
self->reconfigure = FALSE;
GST_OBJECT_UNLOCK (self);

View file

@ -43,7 +43,7 @@ FUNCT_NAME_YUY2 (GstDeinterlaceMethodGreedyH *self, const guint8 * L1, const gui
gint64 MotionSense;
gint64 i;
glong LoopCtr;
glong oldbx;
glong oldbx = 0;
gint64 QW256B;
gint64 LastAvg = 0; //interp value from left qword
@ -262,7 +262,7 @@ FUNCT_NAME_UYVY (GstDeinterlaceMethodGreedyH *self, const guint8 * L1, const gui
gint64 MotionSense;
gint64 i;
glong LoopCtr;
glong oldbx;
glong oldbx = 0;
gint64 QW256B;
gint64 LastAvg = 0; //interp value from left qword

View file

@ -92,7 +92,7 @@ long Last8;
int64_t Max_Vals = 0x0000000000000000ull;
int64_t ShiftMask = 0xfefffefffefffeffull;
long oldbx;
long oldbx = 0;
// pretend it's indented -->>
__asm__ __volatile__

View file

@ -1165,6 +1165,7 @@ gst_flv_mux_write_header (GstFlvMux * mux)
"streamable=false. Will ignore that and create streamable output "
"instead");
}
gst_query_unref (query);
}
header = gst_flv_mux_create_header (mux);

View file

@ -1654,6 +1654,7 @@ gst_qt_mux_start_file (GstQTMux * qtmux)
"streamable=false. Will ignore that and create streamable output "
"instead");
}
gst_query_unref (query);
}
/* let downstream know we think in BYTES and expect to do seeking later on */

View file

@ -1903,6 +1903,7 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
GstMatroskaTrackContext *track = NULL;
GstSegment seeksegment = { 0, };
gboolean update = TRUE;
gboolean pad_locked = FALSE;
if (pad)
track = gst_pad_get_element_private (pad);
@ -2001,6 +2002,7 @@ next:
* forever. */
GST_DEBUG_OBJECT (demux, "Waiting for streaming to stop");
GST_PAD_STREAM_LOCK (demux->common.sinkpad);
pad_locked = TRUE;
/* pull mode without index can do some scanning */
if (!demux->streaming && !entry) {
@ -2069,13 +2071,17 @@ exit:
(GstTaskFunction) gst_matroska_demux_loop, demux->common.sinkpad);
/* streaming can continue now */
GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
if (pad_locked) {
GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
}
return TRUE;
seek_error:
{
GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
if (pad_locked) {
GST_PAD_STREAM_UNLOCK (demux->common.sinkpad);
}
GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Got a seek error"));
return FALSE;
}

View file

@ -2361,6 +2361,7 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
"streamable=false. Will ignore that and create streamable output "
"instead");
}
gst_query_unref (query);
}
if (!strcmp (mux->doctype, GST_MATROSKA_DOCTYPE_WEBM)) {

View file

@ -336,12 +336,14 @@ gst_rtp_dv_depay_process (GstRTPBaseDepayload * base, GstBuffer * in)
GST_LOG_OBJECT (dvdepay, "got block at location %d", location);
}
/* get the byte offset of the dif block */
offset = location * 80;
if (location != -1) {
/* get the byte offset of the dif block */
offset = location * 80;
/* And copy it in, provided the location is sane. */
if (offset >= 0 && offset <= dvdepay->frame_size - 80)
gst_buffer_fill (dvdepay->acc, offset, payload, 80);
/* And copy it in, provided the location is sane. */
if (offset <= dvdepay->frame_size - 80)
gst_buffer_fill (dvdepay->acc, offset, payload, 80);
}
payload += 80;
payload_len -= 80;

View file

@ -170,6 +170,7 @@ gst_rtsp_src_buffer_mode_get_type (void)
#define DEFAULT_CONNECTION_SPEED 0
#define DEFAULT_NAT_METHOD GST_RTSP_NAT_DUMMY
#define DEFAULT_DO_RTCP TRUE
#define DEFAULT_DO_RTSP_KEEP_ALIVE TRUE
#define DEFAULT_PROXY NULL
#define DEFAULT_RTP_BLOCKSIZE 0
#define DEFAULT_USER_ID NULL
@ -191,6 +192,7 @@ enum
PROP_CONNECTION_SPEED,
PROP_NAT_METHOD,
PROP_DO_RTCP,
PROP_DO_RTSP_KEEP_ALIVE,
PROP_PROXY,
PROP_RTP_BLOCKSIZE,
PROP_USER_ID,
@ -372,6 +374,20 @@ gst_rtspsrc_class_init (GstRTSPSrcClass * klass)
"Send RTCP packets, disable for old incompatible server.",
DEFAULT_DO_RTCP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstRTSPSrc::do-rtsp-keep-alive
*
* Enable RTSP keep laive support. Some old server don't like RTSP
* keep alive and then this property needs to be set to FALSE.
*
* Since: 0.10.32
*/
g_object_class_install_property (gobject_class, PROP_DO_RTSP_KEEP_ALIVE,
g_param_spec_boolean ("do-rtsp-keep-alive", "Do RTSP Keep Alive",
"Send RTSP keep alive packets, disable for old incompatible server.",
DEFAULT_DO_RTSP_KEEP_ALIVE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstRTSPSrc::proxy
*
@ -492,6 +508,7 @@ gst_rtspsrc_init (GstRTSPSrc * src)
src->connection_speed = DEFAULT_CONNECTION_SPEED;
src->nat_method = DEFAULT_NAT_METHOD;
src->do_rtcp = DEFAULT_DO_RTCP;
src->do_rtsp_keep_alive = DEFAULT_DO_RTSP_KEEP_ALIVE;
gst_rtspsrc_set_proxy (src, DEFAULT_PROXY);
src->rtp_blocksize = DEFAULT_RTP_BLOCKSIZE;
src->user_id = g_strdup (DEFAULT_USER_ID);
@ -650,6 +667,9 @@ gst_rtspsrc_set_property (GObject * object, guint prop_id, const GValue * value,
case PROP_DO_RTCP:
rtspsrc->do_rtcp = g_value_get_boolean (value);
break;
case PROP_DO_RTSP_KEEP_ALIVE:
rtspsrc->do_rtsp_keep_alive = g_value_get_boolean (value);
break;
case PROP_PROXY:
gst_rtspsrc_set_proxy (rtspsrc, g_value_get_string (value));
break;
@ -740,6 +760,9 @@ gst_rtspsrc_get_property (GObject * object, guint prop_id, GValue * value,
case PROP_DO_RTCP:
g_value_set_boolean (value, rtspsrc->do_rtcp);
break;
case PROP_DO_RTSP_KEEP_ALIVE:
g_value_set_boolean (value, rtspsrc->do_rtsp_keep_alive);
break;
case PROP_PROXY:
{
gchar *str;
@ -3420,6 +3443,12 @@ gst_rtspsrc_send_keep_alive (GstRTSPSrc * src)
GstRTSPMethod method;
gchar *control;
if (src->do_rtsp_keep_alive == FALSE) {
GST_DEBUG_OBJECT (src, "do-rtsp-keep-alive is FALSE, not sending.");
gst_rtsp_connection_reset_timeout (src->conninfo.connection);
return GST_RTSP_OK;
}
GST_DEBUG_OBJECT (src, "creating server keep-alive");
/* find a method to use for keep-alive */
@ -3764,7 +3793,11 @@ gst_rtspsrc_loop_udp (GstRTSPSrc * src)
goto connect_error;
continue;
case GST_RTSP_ENET:
GST_DEBUG_OBJECT (src, "An ethernet problem occured.");
default:
GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
("Unhandled return value %d.", res));
goto receive_error;
}
@ -3923,17 +3956,17 @@ no_protocols:
("Could not receive any UDP packets for %.4f seconds, maybe your "
"firewall is blocking it. No other protocols to try.",
gst_guint64_to_gdouble (src->udp_timeout / 1000000.0)));
return GST_FLOW_ERROR;
return GST_RTSP_ERROR;
}
open_failed:
{
GST_DEBUG_OBJECT (src, "open failed");
return GST_FLOW_OK;
return GST_RTSP_OK;
}
play_failed:
{
GST_DEBUG_OBJECT (src, "play failed");
return GST_FLOW_OK;
return GST_RTSP_OK;
}
}

View file

@ -204,6 +204,7 @@ struct _GstRTSPSrc {
guint64 connection_speed;
GstRTSPNatMethod nat_method;
gboolean do_rtcp;
gboolean do_rtsp_keep_alive;
gchar *proxy_host;
guint proxy_port;
gchar *proxy_user;

View file

@ -408,8 +408,7 @@ gst_smpte_blend_i420 (guint8 * in1, guint8 * in2, guint8 * out, GstMask * mask,
gint i, j;
gint min, max;
guint8 *in1u, *in1v, *in2u, *in2v, *outu, *outv;
gint lumsize = width * height;
gint chromsize = lumsize >> 2;
gint uoffset, voffset, ystr, ustr, vstr;
if (border == 0)
border++;
@ -417,12 +416,19 @@ gst_smpte_blend_i420 (guint8 * in1, guint8 * in2, guint8 * out, GstMask * mask,
min = pos - border;
max = pos;
in1u = in1 + lumsize;
in1v = in1u + chromsize;
in2u = in2 + lumsize;
in2v = in2u + chromsize;
outu = out + lumsize;
outv = outu + chromsize;
uoffset = I420_U_OFFSET (width, height);
voffset = I420_V_OFFSET (width, height);
ystr = I420_Y_ROWSTRIDE (width);
ustr = I420_U_ROWSTRIDE (width);
vstr = I420_V_ROWSTRIDE (width);
in1u = in1 + uoffset;
in1v = in1 + voffset;
in2u = in2 + uoffset;
in2v = in2 + voffset;
outu = out + uoffset;
outv = out + voffset;
maskp = mask->data;
@ -431,12 +437,25 @@ gst_smpte_blend_i420 (guint8 * in1, guint8 * in2, guint8 * out, GstMask * mask,
value = *maskp++;
value = ((CLAMP (value, min, max) - min) << 8) / border;
*out++ = ((*in1++ * value) + (*in2++ * (256 - value))) >> 8;
out[j] = ((in1[j] * value) + (in2[j] * (256 - value))) >> 8;
if (!(i & 1) && !(j & 1)) {
*outu++ = ((*in1u++ * value) + (*in2u++ * (256 - value))) >> 8;
*outv++ = ((*in1v++ * value) + (*in2v++ * (256 - value))) >> 8;
outu[j / 2] =
((in1u[j / 2] * value) + (in2u[j / 2] * (256 - value))) >> 8;
outv[j / 2] =
((in1v[j / 2] * value) + (in2v[j / 2] * (256 - value))) >> 8;
}
}
out += ystr;
in1 += ystr;
in2 += ystr;
if (!(i & 1)) {
outu += ustr;
in1u += ustr;
in2u += ustr;
outv += vstr;
in1v += vstr;
in2v += vstr;
}
}
}

View file

@ -1053,8 +1053,7 @@ gst_ximage_src_get_caps (GstBaseSrc * bs, GstCaps * filter)
if (s->endx >= s->startx && s->endy >= s->starty) {
/* this means user has put in values */
if (s->startx < xcontext->width && s->endx < xcontext->width &&
s->starty < xcontext->height && s->endy < xcontext->height &&
s->startx >= 0 && s->starty >= 0) {
s->starty < xcontext->height && s->endy < xcontext->height) {
/* values are fine */
s->width = width = s->endx - s->startx + 1;
s->height = height = s->endy - s->starty + 1;