mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-04 05:22:30 +00:00
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:
commit
c44cd8f55b
32 changed files with 925 additions and 68 deletions
12
configure.ac
12
configure.ac
|
@ -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"])
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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 <mark.nauwelaerts@collabora.co.uk></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>
|
|
@ -91,4 +91,4 @@
|
|||
</pads>
|
||||
</element>
|
||||
</elements>
|
||||
</plugin>
|
||||
</plugin>
|
||||
|
|
|
@ -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 <tim centricular net></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>
|
||||
|
|
|
@ -52,4 +52,4 @@
|
|||
</pads>
|
||||
</element>
|
||||
</elements>
|
||||
</plugin>
|
||||
</plugin>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -58,6 +58,8 @@ struct _GstFlacDec {
|
|||
/* from the stream info, needed for scanning */
|
||||
guint16 min_blocksize;
|
||||
guint16 max_blocksize;
|
||||
|
||||
gint error_count;
|
||||
};
|
||||
|
||||
struct _GstFlacDecClass {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
508
ext/gdk_pixbuf/gstgdkpixbufoverlay.c
Normal file
508
ext/gdk_pixbuf/gstgdkpixbufoverlay.c
Normal 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;
|
||||
}
|
87
ext/gdk_pixbuf/gstgdkpixbufoverlay.h
Normal file
87
ext/gdk_pixbuf/gstgdkpixbufoverlay.h
Normal 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
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -52,6 +52,7 @@ struct _GstPngEnc
|
|||
|
||||
GstVideoInfo info;
|
||||
gint png_color_type;
|
||||
gint depth;
|
||||
gint width;
|
||||
gint height;
|
||||
guint compression_level;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue