summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2012-03-29 17:41:53 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2012-03-29 17:41:53 +0200
commit860ccd414dbb313fabf065b92838f0f39037584b (patch)
tree0d5c0d3510db3ca3d7e6487420e8d09f74ae1961 /ext
parenta9ec4d62a89dd53aa295af02c7d5f57ef936359b (diff)
parentd84d98943af42ce645ee022207bcf04e747d2d4a (diff)
Merge remote-tracking branch 'origin/0.10'
Conflicts: NEWS RELEASE common configure.ac docs/libs/gst-plugins-bad-libs-sections.txt docs/plugins/gst-plugins-bad-plugins.args docs/plugins/gst-plugins-bad-plugins.hierarchy docs/plugins/gst-plugins-bad-plugins.interfaces docs/plugins/inspect/plugin-adpcmdec.xml docs/plugins/inspect/plugin-adpcmenc.xml docs/plugins/inspect/plugin-assrender.xml docs/plugins/inspect/plugin-audiovisualizers.xml docs/plugins/inspect/plugin-autoconvert.xml docs/plugins/inspect/plugin-bayer.xml docs/plugins/inspect/plugin-bz2.xml docs/plugins/inspect/plugin-camerabin2.xml docs/plugins/inspect/plugin-celt.xml docs/plugins/inspect/plugin-dataurisrc.xml docs/plugins/inspect/plugin-debugutilsbad.xml docs/plugins/inspect/plugin-dtmf.xml docs/plugins/inspect/plugin-dtsdec.xml docs/plugins/inspect/plugin-dvbsuboverlay.xml docs/plugins/inspect/plugin-dvdspu.xml docs/plugins/inspect/plugin-faac.xml docs/plugins/inspect/plugin-faad.xml docs/plugins/inspect/plugin-gsm.xml docs/plugins/inspect/plugin-h264parse.xml docs/plugins/inspect/plugin-mms.xml docs/plugins/inspect/plugin-modplug.xml docs/plugins/inspect/plugin-mpeg2enc.xml docs/plugins/inspect/plugin-mpegdemux2.xml docs/plugins/inspect/plugin-mpegtsdemux.xml docs/plugins/inspect/plugin-mpegvideoparse.xml docs/plugins/inspect/plugin-mplex.xml docs/plugins/inspect/plugin-pcapparse.xml docs/plugins/inspect/plugin-rawparse.xml docs/plugins/inspect/plugin-rtpmux.xml docs/plugins/inspect/plugin-rtpvp8.xml docs/plugins/inspect/plugin-scaletempo.xml docs/plugins/inspect/plugin-schro.xml docs/plugins/inspect/plugin-sdp.xml docs/plugins/inspect/plugin-segmentclip.xml docs/plugins/inspect/plugin-shm.xml docs/plugins/inspect/plugin-videomaxrate.xml docs/plugins/inspect/plugin-videoparsersbad.xml docs/plugins/inspect/plugin-vp8.xml docs/plugins/inspect/plugin-y4mdec.xml ext/celt/gstceltdec.c ext/dts/gstdtsdec.c ext/modplug/gstmodplug.cc ext/opus/gstopusenc.c gst-libs/gst/video/gstbasevideocodec.c gst-libs/gst/video/gstbasevideocodec.h gst-libs/gst/video/gstbasevideodecoder.c gst-libs/gst/video/gstbasevideodecoder.h gst-libs/gst/video/gstbasevideoencoder.c gst-libs/gst/video/gstbasevideoencoder.h gst/adpcmdec/Makefile.am gst/audiovisualizers/gstbaseaudiovisualizer.c gst/h264parse/gsth264parse.c gst/mpegdemux/mpegtsparse.c gst/mpegtsdemux/mpegtsbase.c gst/mpegtsdemux/mpegtspacketizer.c gst/mpegtsdemux/mpegtsparse.c gst/mpegtsdemux/tsdemux.c gst/mpegtsdemux/tsdemux.h gst/mxf/mxfdemux.c gst/rawparse/gstaudioparse.c gst/videoparsers/gsth263parse.c gst/videoparsers/gsth264parse.c sys/d3dvideosink/d3dvideosink.c sys/decklink/gstdecklinksink.cpp sys/dvb/gstdvbsrc.c sys/shm/gstshmsrc.c sys/vdpau/h264/gstvdph264dec.c sys/vdpau/mpeg/gstvdpmpegdec.c tests/examples/opencv/gst_element_print_properties.c win32/common/config.h
Diffstat (limited to 'ext')
-rw-r--r--ext/Makefile.am8
-rw-r--r--ext/assrender/gstassrender.c3
-rw-r--r--ext/celt/gstceltdec.c4
-rw-r--r--ext/cog/gstcogcolorspace.c2
-rw-r--r--ext/curl/gstcurlsink.c2
-rw-r--r--ext/directfb/dfbvideosink.c2
-rw-r--r--ext/dts/gstdtsdec.c32
-rw-r--r--ext/dts/gstdtsdec.h2
-rw-r--r--ext/faad/gstfaad.c2
-rw-r--r--ext/flite/gstflite.c3
-rw-r--r--ext/flite/gstflitetestsrc.c3
-rw-r--r--ext/gme/gstgme.c4
-rw-r--r--ext/gsettings/gstgsettingsaudiosink.c5
-rw-r--r--ext/gsettings/gstgsettingsaudiosrc.c4
-rw-r--r--ext/gsettings/gstgsettingsvideosink.c4
-rw-r--r--ext/gsettings/gstgsettingsvideosrc.c4
-rw-r--r--ext/modplug/gstmodplug.cc19
-rw-r--r--ext/musepack/gstmusepackdec.c4
-rw-r--r--ext/openal/gstopenalsink.c4
-rw-r--r--ext/opencv/MotionCells.cpp7
-rw-r--r--ext/opencv/MotionCells.h5
-rw-r--r--ext/opencv/gstfaceblur.c3
-rw-r--r--ext/opencv/gstfacedetect.c172
-rw-r--r--ext/opencv/gstopencvutils.c4
-rw-r--r--ext/opencv/gstopencvvideofilter.c2
-rw-r--r--ext/opencv/gsttemplatematch.h7
-rw-r--r--ext/opencv/motioncells_wrapper.cpp7
-rw-r--r--ext/opus/gstopusenc.c83
-rw-r--r--ext/resindvd/resindvdsrc.c58
-rw-r--r--ext/rsvg/gstrsvgoverlay.c13
-rw-r--r--ext/timidity/gstwildmidi.c4
-rw-r--r--ext/vp8/gstvp8enc.c2
-rw-r--r--ext/wayland/Makefile.am13
-rw-r--r--ext/wayland/gstwaylandsink.c681
-rw-r--r--ext/wayland/gstwaylandsink.h131
35 files changed, 1111 insertions, 192 deletions
diff --git a/ext/Makefile.am b/ext/Makefile.am
index a1636f690..0d57dc3bb 100644
--- a/ext/Makefile.am
+++ b/ext/Makefile.am
@@ -94,6 +94,12 @@ else
DIRECTFB_DIR=
endif
+if USE_WAYLAND
+WAYLAND_DIR=wayland
+else
+WAYLAND_DIR=
+endif
+
if USE_DIVX
DIVX_DIR=divx
else
@@ -409,6 +415,7 @@ SUBDIRS=\
$(DC1394_DIR) \
$(DIRAC_DIR) \
$(DIRECTFB_DIR) \
+ $(WAYLAND_DIR) \
$(DIVX_DIR) \
$(DTS_DIR) \
$(RESINDVD_DIR) \
@@ -469,6 +476,7 @@ DIST_SUBDIRS = \
dc1394 \
dirac \
directfb \
+ wayland \
faac \
faad \
flite \
diff --git a/ext/assrender/gstassrender.c b/ext/assrender/gstassrender.c
index 882efc92e..b33444d81 100644
--- a/ext/assrender/gstassrender.c
+++ b/ext/assrender/gstassrender.c
@@ -31,6 +31,9 @@
* </refsect2>
*/
+/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
+ * with newer GLib versions (>= 2.31.0) */
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
#ifdef HAVE_CONFIG_H
# include <config.h>
diff --git a/ext/celt/gstceltdec.c b/ext/celt/gstceltdec.c
index be93a831c..f647baac7 100644
--- a/ext/celt/gstceltdec.c
+++ b/ext/celt/gstceltdec.c
@@ -291,8 +291,8 @@ gst_celt_dec_parse_comments (GstCeltDec * 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);
g_free (encoder);
g_free (ver);
diff --git a/ext/cog/gstcogcolorspace.c b/ext/cog/gstcogcolorspace.c
index f81df6cc2..f3de99ade 100644
--- a/ext/cog/gstcogcolorspace.c
+++ b/ext/cog/gstcogcolorspace.c
@@ -372,7 +372,7 @@ gst_cogcolorspace_caps_get_chroma_site (GstCaps * caps)
s = gst_video_parse_caps_chroma_site (caps);
if (s == NULL)
- return COG_COLOR_MATRIX_SDTV;
+ return COG_CHROMA_SITE_MPEG2;
if (strcmp (s, "jpeg") == 0) {
return COG_CHROMA_SITE_JPEG;
diff --git a/ext/curl/gstcurlsink.c b/ext/curl/gstcurlsink.c
index a06843522..2ed5b20a6 100644
--- a/ext/curl/gstcurlsink.c
+++ b/ext/curl/gstcurlsink.c
@@ -850,7 +850,7 @@ gst_curl_sink_handle_transfer (GstCurlSink * sink)
if (!proxy_conn_established && (resp_proxy != RESPONSE_CONNECT_PROXY)
&& proxy_auth) {
curl_easy_getinfo (sink->curl, CURLINFO_HTTP_CONNECTCODE, &resp_proxy);
- if ((resp_proxy == RESPONSE_CONNECT_PROXY)) {
+ if (resp_proxy == RESPONSE_CONNECT_PROXY) {
GST_LOG ("received HTTP/1.0 200 Connection Established");
/* Workaround: redefine HTTP headers before connecting to HTTP server.
* When talking to proxy, the Content-Length: 0 is send with the request.
diff --git a/ext/directfb/dfbvideosink.c b/ext/directfb/dfbvideosink.c
index 038e3ee33..0d73172e3 100644
--- a/ext/directfb/dfbvideosink.c
+++ b/ext/directfb/dfbvideosink.c
@@ -1658,7 +1658,7 @@ gst_dfbvideosink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
res = dest->Unlock (dest);
- res = dest->Release (dest);
+ dest->Release (dest);
if (dfbvideosink->backbuffer) {
if (dfbvideosink->vsync) {
diff --git a/ext/dts/gstdtsdec.c b/ext/dts/gstdtsdec.c
index 07335d84a..ca7e35dc6 100644
--- a/ext/dts/gstdtsdec.c
+++ b/ext/dts/gstdtsdec.c
@@ -132,8 +132,6 @@ static gboolean gst_dtsdec_parse (GstAudioDecoder * dec, GstAdapter * adapter,
gint * offset, gint * length);
static GstFlowReturn gst_dtsdec_handle_frame (GstAudioDecoder * dec,
GstBuffer * buffer);
-static GstFlowReturn gst_dtsdec_pre_push (GstAudioDecoder * bdec,
- GstBuffer ** buffer);
static GstFlowReturn gst_dtsdec_chain (GstPad * pad, GstObject * parent,
GstBuffer * buf);
@@ -173,7 +171,6 @@ gst_dtsdec_class_init (GstDtsDecClass * klass)
gstbase_class->set_format = GST_DEBUG_FUNCPTR (gst_dtsdec_set_format);
gstbase_class->parse = GST_DEBUG_FUNCPTR (gst_dtsdec_parse);
gstbase_class->handle_frame = GST_DEBUG_FUNCPTR (gst_dtsdec_handle_frame);
- gstbase_class->pre_push = GST_DEBUG_FUNCPTR (gst_dtsdec_pre_push);
/**
* GstDtsDec::drc
@@ -257,10 +254,6 @@ gst_dtsdec_stop (GstAudioDecoder * dec)
dca_free (dts->state);
dts->state = NULL;
}
- if (dts->pending_tags) {
- gst_tag_list_free (dts->pending_tags);
- dts->pending_tags = NULL;
- }
return TRUE;
}
@@ -284,7 +277,7 @@ gst_dtsdec_parse (GstAudioDecoder * bdec, GstAdapter * adapter,
bit_rate = dts->bit_rate;
sample_rate = dts->sample_rate;
flags = 0;
- while (av >= 7) {
+ while (size >= 7) {
length = dca_syncinfo (dts->state, data, &flags,
&sample_rate, &bit_rate, &frame_length);
@@ -447,28 +440,9 @@ gst_dtsdec_update_streaminfo (GstDtsDec * dts)
/* 1 => open bitrate, 2 => variable bitrate, 3 => lossless */
gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_BITRATE,
(guint) dts->bit_rate, NULL);
-
- if (dts->pending_tags) {
- gst_tag_list_free (dts->pending_tags);
- dts->pending_tags = NULL;
- }
-
- dts->pending_tags = taglist;
- }
-}
-
-static GstFlowReturn
-gst_dtsdec_pre_push (GstAudioDecoder * bdec, GstBuffer ** buffer)
-{
- GstDtsDec *dts = GST_DTSDEC (bdec);
-
- if (G_UNLIKELY (dts->pending_tags)) {
- gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (dts),
- gst_event_new_tag (dts->pending_tags));
- dts->pending_tags = NULL;
+ gst_audio_decoder_merge_tags (GST_AUDIO_DECODER (dts), taglist,
+ GST_TAG_MERGE_REPLACE);
}
-
- return GST_FLOW_OK;
}
static GstFlowReturn
diff --git a/ext/dts/gstdtsdec.h b/ext/dts/gstdtsdec.h
index 16b7e91ea..b37b59024 100644
--- a/ext/dts/gstdtsdec.h
+++ b/ext/dts/gstdtsdec.h
@@ -68,8 +68,6 @@ struct _GstDtsDec {
#else
dts_state_t *state;
#endif
-
- GstTagList *pending_tags;
};
struct _GstDtsDecClass {
diff --git a/ext/faad/gstfaad.c b/ext/faad/gstfaad.c
index 1db422986..f753a55f1 100644
--- a/ext/faad/gstfaad.c
+++ b/ext/faad/gstfaad.c
@@ -828,6 +828,8 @@ decode_failed:
{
GST_AUDIO_DECODER_ERROR (faad, 1, STREAM, DECODE, (NULL),
("decoding error: %s", faacDecGetErrorMessage (info.error)), ret);
+ if (ret == GST_FLOW_OK)
+ gst_audio_decoder_finish_frame (dec, NULL, 1);
goto out;
}
negotiation_failed:
diff --git a/ext/flite/gstflite.c b/ext/flite/gstflite.c
index 2995d9f3e..d75bd2ffe 100644
--- a/ext/flite/gstflite.c
+++ b/ext/flite/gstflite.c
@@ -24,7 +24,6 @@
#include <gst/gst.h>
#include <flite/flite.h>
-GType gst_flite_synth_get_type (void);
GType gst_flite_test_src_get_type (void);
@@ -33,8 +32,6 @@ plugin_init (GstPlugin * plugin)
{
flite_init ();
-// gst_element_register (plugin, "flitesynth", GST_RANK_NONE,
-// gst_flite_synth_get_type ());
gst_element_register (plugin, "flitetestsrc", GST_RANK_NONE,
gst_flite_test_src_get_type ());
diff --git a/ext/flite/gstflitetestsrc.c b/ext/flite/gstflitetestsrc.c
index a08dcbb7f..e7efc20b8 100644
--- a/ext/flite/gstflitetestsrc.c
+++ b/ext/flite/gstflitetestsrc.c
@@ -372,10 +372,9 @@ gst_flite_test_src_get_times (GstBaseSrc * basesrc, GstBuffer * buffer,
}
#endif
+/* there is no header for libflite_cmu_us_kal */
cst_voice *register_cmu_us_kal ();
-
-
static gboolean
gst_flite_test_src_start (GstBaseSrc * basesrc)
{
diff --git a/ext/gme/gstgme.c b/ext/gme/gstgme.c
index 9ba59e1fa..07e240e47 100644
--- a/ext/gme/gstgme.c
+++ b/ext/gme/gstgme.c
@@ -18,6 +18,10 @@
* Boston, MA 02111-1307, USA.
*/
+/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
+ * with newer GLib versions (>= 2.31.0) */
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
diff --git a/ext/gsettings/gstgsettingsaudiosink.c b/ext/gsettings/gstgsettingsaudiosink.c
index f4155b3bc..12d848938 100644
--- a/ext/gsettings/gstgsettingsaudiosink.c
+++ b/ext/gsettings/gstgsettingsaudiosink.c
@@ -160,8 +160,9 @@ static void
on_changed (GSettings * settings, gchar * key, GstGSettingsAudioSink * sink)
{
gboolean changed = FALSE;
- if (!g_str_has_suffix (key, "audiosink"));
- return;
+
+ if (!g_str_has_suffix (key, "audiosink"))
+ return;
GST_OBJECT_LOCK (sink);
if ((sink->profile == GST_GSETTINGS_AUDIOSINK_PROFILE_SOUNDS &&
diff --git a/ext/gsettings/gstgsettingsaudiosrc.c b/ext/gsettings/gstgsettingsaudiosrc.c
index 7b9bd1f18..c30f12271 100644
--- a/ext/gsettings/gstgsettingsaudiosrc.c
+++ b/ext/gsettings/gstgsettingsaudiosrc.c
@@ -104,8 +104,8 @@ fail:
static void
on_changed (GSettings * settings, gchar * key, GstGSettingsAudioSrc * src)
{
- if (!g_str_equal (key, "audiosrc"));
- return;
+ if (!g_str_equal (key, "audiosrc"))
+ return;
gst_gsettings_audio_src_change_child (src);
}
diff --git a/ext/gsettings/gstgsettingsvideosink.c b/ext/gsettings/gstgsettingsvideosink.c
index f04e8054c..e225ec14e 100644
--- a/ext/gsettings/gstgsettingsvideosink.c
+++ b/ext/gsettings/gstgsettingsvideosink.c
@@ -104,8 +104,8 @@ fail:
static void
on_changed (GSettings * settings, gchar * key, GstGSettingsVideoSink * sink)
{
- if (!g_str_has_suffix (key, "videosink"));
- return;
+ if (!g_str_has_suffix (key, "videosink"))
+ return;
gst_gsettings_video_sink_change_child (sink);
}
diff --git a/ext/gsettings/gstgsettingsvideosrc.c b/ext/gsettings/gstgsettingsvideosrc.c
index 877656814..6c2a5b03e 100644
--- a/ext/gsettings/gstgsettingsvideosrc.c
+++ b/ext/gsettings/gstgsettingsvideosrc.c
@@ -104,8 +104,8 @@ fail:
static void
on_changed (GSettings * settings, gchar * key, GstGSettingsVideoSrc * src)
{
- if (!g_str_equal (key, "videosrc"));
- return;
+ if (!g_str_equal (key, "videosrc"))
+ return;
gst_gsettings_video_src_change_child (src);
}
diff --git a/ext/modplug/gstmodplug.cc b/ext/modplug/gstmodplug.cc
index d849a44e1..3d7cbc04f 100644
--- a/ext/modplug/gstmodplug.cc
+++ b/ext/modplug/gstmodplug.cc
@@ -491,6 +491,10 @@ gst_modplug_load_song (GstModPlug * modplug)
gst_structure_get_int (structure, "channels", &modplug->channel);
gst_structure_get_int (structure, "rate", &modplug->frequency);
+
+ GST_DEBUG_OBJECT (modplug,
+ "Audio settings: %d bits, %d channel(s), %d Hz sampling rate",
+ modplug->bits, modplug->channel, modplug->frequency);
gst_pad_set_caps (modplug->srcpad, newcaps);
gst_caps_unref (newcaps);
@@ -672,7 +676,8 @@ gst_modplug_loop (GstModPlug * modplug)
if (modplug->offset == modplug->song_size) {
GstTagList *tags;
gboolean ok;
- gchar comment[16384];
+ #define COMMENT_SIZE 16384
+ gchar comment[COMMENT_SIZE];
GstSegment seg;
ok = gst_modplug_load_song (modplug);
@@ -695,7 +700,9 @@ gst_modplug_loop (GstModPlug * modplug)
GST_TAG_BEATS_PER_MINUTE,
(gdouble) modplug->mSoundFile->GetMusicTempo (), NULL);
- if (modplug->mSoundFile->GetSongComments ((gchar *) & comment, 16384, 32)) {
+ if (modplug->mSoundFile->GetSongComments ((gchar *) & comment,
+ COMMENT_SIZE, 32)) {
+ comment[COMMENT_SIZE - 1] = '\0';
gst_tag_list_add (tags, GST_TAG_MERGE_APPEND,
GST_TAG_COMMENT, comment, NULL);
}
@@ -713,7 +720,7 @@ gst_modplug_loop (GstModPlug * modplug)
gfloat temp;
temp = (gfloat) modplug->song_length / modplug->seek_at;
- seek_to_pos = (int) (modplug->mSoundFile->GetMaxPosition () / temp);
+ seek_to_pos = (gint) (modplug->mSoundFile->GetMaxPosition () / temp);
GST_DEBUG_OBJECT (modplug, "Seeking to row %d", seek_to_pos);
@@ -722,7 +729,9 @@ gst_modplug_loop (GstModPlug * modplug)
}
/* read and output a buffer */
- out = gst_buffer_new_allocate (NULL, modplug->read_bytes, NULL);
+ GST_LOG_OBJECT (modplug, "Read %d bytes", (gint)modplug->read_bytes);
+ /* libmodplug 0.8.7 trashes memory */
+ out = gst_buffer_new_allocate (NULL, modplug->read_bytes * 2, NULL);
gst_buffer_map (out, &map, GST_MAP_WRITE);
if (!modplug->mSoundFile->Read (map.data, modplug->read_bytes)) {
@@ -730,6 +739,7 @@ gst_modplug_loop (GstModPlug * modplug)
goto eos;
}
gst_buffer_unmap (out, &map);
+ gst_buffer_resize (out, 0, modplug->read_bytes);
GST_BUFFER_DURATION (out) =
gst_util_uint64_scale_int (modplug->read_samples, GST_SECOND,
@@ -796,6 +806,7 @@ gst_modplug_change_state (GstElement * element, GstStateChange transition)
}
if (modplug->mSoundFile) {
modplug->mSoundFile->Destroy ();
+ delete modplug->mSoundFile;
modplug->mSoundFile = NULL;
}
break;
diff --git a/ext/musepack/gstmusepackdec.c b/ext/musepack/gstmusepackdec.c
index 30a34bff3..0401686bb 100644
--- a/ext/musepack/gstmusepackdec.c
+++ b/ext/musepack/gstmusepackdec.c
@@ -19,6 +19,10 @@
* Boston, MA 02111-1307, USA.
*/
+/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
+ * with newer GLib versions (>= 2.31.0) */
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
diff --git a/ext/openal/gstopenalsink.c b/ext/openal/gstopenalsink.c
index ece590531..70398ee49 100644
--- a/ext/openal/gstopenalsink.c
+++ b/ext/openal/gstopenalsink.c
@@ -20,6 +20,10 @@
* Boston, MA 02111-1307, USA.
*/
+/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
+ * with newer GLib versions (>= 2.31.0) */
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
/**
* SECTION:element-openalsink
*
diff --git a/ext/opencv/MotionCells.cpp b/ext/opencv/MotionCells.cpp
index 5223bc7f7..6d18a9993 100644
--- a/ext/opencv/MotionCells.cpp
+++ b/ext/opencv/MotionCells.cpp
@@ -42,6 +42,13 @@
* Boston, MA 02111-1307, USA.
*/
+/* This breaks the build for reasons that aren't entirely clear to me yet */
+#if 0
+//#ifdef HAVE_CONFIG_H
+//#include "config.h"
+//#endif
+#endif
+
#include <cstdlib>
#include <errno.h>
#include <math.h>
diff --git a/ext/opencv/MotionCells.h b/ext/opencv/MotionCells.h
index ee84fd6b5..68a2fec57 100644
--- a/ext/opencv/MotionCells.h
+++ b/ext/opencv/MotionCells.h
@@ -46,7 +46,12 @@
#define MOTIONCELLS_H_
#include <cv.h> // includes OpenCV definitions
+#ifdef HAVE_HIGHGUI_H
#include <highgui.h> // includes highGUI definitions
+#endif
+#ifdef HAVE_OPENCV2_HIGHGUI_HIGHGUI_C_H
+#include <opencv2/highgui/highgui_c.h> // includes highGUI definitions
+#endif
#include <iostream>
#include <fstream>
#include <vector>
diff --git a/ext/opencv/gstfaceblur.c b/ext/opencv/gstfaceblur.c
index b4b6711b8..6a73db915 100644
--- a/ext/opencv/gstfaceblur.c
+++ b/ext/opencv/gstfaceblur.c
@@ -68,7 +68,8 @@
GST_DEBUG_CATEGORY_STATIC (gst_face_blur_debug);
#define GST_CAT_DEFAULT gst_face_blur_debug
-#define DEFAULT_PROFILE "/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml"
+#define HAAR_CASCADES_DIR OPENCV_PREFIX "/share/opencv/haarcascades/"
+#define DEFAULT_PROFILE HAAR_CASCADES_DIR "haarcascade_frontalface_default.xml"
/* Filter signals and args */
enum
diff --git a/ext/opencv/gstfacedetect.c b/ext/opencv/gstfacedetect.c
index 7f2121626..5a0c09fd2 100644
--- a/ext/opencv/gstfacedetect.c
+++ b/ext/opencv/gstfacedetect.c
@@ -82,10 +82,11 @@
GST_DEBUG_CATEGORY_STATIC (gst_face_detect_debug);
#define GST_CAT_DEFAULT gst_face_detect_debug
-#define DEFAULT_FACE_PROFILE "/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml"
-#define DEFAULT_NOSE_PROFILE "/usr/share/opencv/haarcascades/haarcascade_mcs_nose.xml"
-#define DEFAULT_MOUTH_PROFILE "/usr/share/opencv/haarcascades/haarcascade_mcs_mouth.xml"
-#define DEFAULT_EYES_PROFILE "/usr/share/opencv/haarcascades/haarcascade_mcs_eyepair_small.xml"
+#define HAAR_CASCADES_DIR OPENCV_PREFIX "/share/opencv/haarcascades/"
+#define DEFAULT_FACE_PROFILE HAAR_CASCADES_DIR "haarcascade_frontalface_default.xml"
+#define DEFAULT_NOSE_PROFILE HAAR_CASCADES_DIR "haarcascade_mcs_nose.xml"
+#define DEFAULT_MOUTH_PROFILE HAAR_CASCADES_DIR "haarcascade_mcs_mouth.xml"
+#define DEFAULT_EYES_PROFILE HAAR_CASCADES_DIR "haarcascade_mcs_eyepair_small.xml"
#define DEFAULT_SCALE_FACTOR 1.1
#define DEFAULT_FLAGS 0
#define DEFAULT_MIN_NEIGHBORS 3
@@ -471,6 +472,19 @@ gst_face_detect_message_new (GstFaceDetect * filter, GstBuffer * buf)
return gst_message_new_element (GST_OBJECT (filter), s);
}
+static CvSeq *
+gst_face_detect_run_detector (GstFaceDetect * filter,
+ CvHaarClassifierCascade * detector, gint min_size_width,
+ gint min_size_height)
+{
+ return cvHaarDetectObjects (filter->cvGray, detector,
+ filter->cvStorage, filter->scale_factor, filter->min_neighbors,
+ filter->flags, cvSize (min_size_width, min_size_height)
+#if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2)
+ , cvSize (min_size_width + 2, min_size_height + 2)
+#endif
+ );
+}
/*
* Performs the face detection
@@ -483,9 +497,11 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
if (filter->cvFaceDetect) {
GstMessage *msg = NULL;
+ GstStructure *s;
GValue facelist = { 0 };
+ GValue facedata = { 0 };
CvSeq *faces;
- CvSeq *mouth, *nose, *eyes;
+ CvSeq *mouth = NULL, *nose = NULL, *eyes = NULL;
gint i;
gboolean do_display = FALSE;
@@ -500,96 +516,77 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
cvCvtColor (img, filter->cvGray, CV_RGB2GRAY);
cvClearMemStorage (filter->cvStorage);
- faces =
- cvHaarDetectObjects (filter->cvGray, filter->cvFaceDetect,
- filter->cvStorage, filter->scale_factor, filter->min_neighbors,
- filter->flags, cvSize (filter->min_size_width, filter->min_size_height)
-#if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2)
- , cvSize (filter->min_size_width + 2, filter->min_size_height + 2)
-#endif
- );
+ faces = gst_face_detect_run_detector (filter, filter->cvFaceDetect,
+ filter->min_size_width, filter->min_size_height);
- if (faces && faces->total > 0) {
- msg = gst_face_detect_message_new (filter, buf);
- g_value_init (&facelist, GST_TYPE_LIST);
- }
+ msg = gst_face_detect_message_new (filter, buf);
+ g_value_init (&facelist, GST_TYPE_LIST);
for (i = 0; i < (faces ? faces->total : 0); i++) {
CvRect *r = (CvRect *) cvGetSeqElem (faces, i);
- GValue value = { 0 };
- GstStructure *s;
guint mw = filter->min_size_width / 8;
guint mh = filter->min_size_height / 8;
- guint rnx, rny, rnw, rnh;
- guint rmx, rmy, rmw, rmh;
- guint rex, rey, rew, reh;
+ guint rnx = 0, rny = 0, rnw, rnh;
+ guint rmx = 0, rmy = 0, rmw, rmh;
+ guint rex = 0, rey = 0, rew, reh;
gboolean have_nose, have_mouth, have_eyes;
/* detect face features */
- rnx = r->x + r->width / 4;
- rny = r->y + r->height / 4;
- rnw = r->width / 2;
- rnh = r->height / 2;
- cvSetImageROI (filter->cvGray, cvRect (rnx, rny, rnw, rnh));
- nose =
- cvHaarDetectObjects (filter->cvGray, filter->cvNoseDetect,
- filter->cvStorage, filter->scale_factor, filter->min_neighbors,
- filter->flags, cvSize (mw, mh)
-#if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2)
- , cvSize (mw + 2, mh + 2)
-#endif
- );
- have_nose = (nose && nose->total);
- cvResetImageROI (filter->cvGray);
-
- rmx = r->x;
- rmy = r->y + r->height / 2;
- rmw = r->width;
- rmh = r->height / 2;
- cvSetImageROI (filter->cvGray, cvRect (rmx, rmy, rmw, rmh));
- mouth =
- cvHaarDetectObjects (filter->cvGray, filter->cvMouthDetect,
- filter->cvStorage, filter->scale_factor, filter->min_neighbors,
- filter->flags, cvSize (mw, mh)
-#if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2)
- , cvSize (mw + 2, mh + 2)
-#endif
- );
- have_mouth = (mouth && mouth->total);
- cvResetImageROI (filter->cvGray);
-
- rex = r->x;
- rey = r->y;
- rew = r->width;
- reh = r->height / 2;
- cvSetImageROI (filter->cvGray, cvRect (rex, rey, rew, reh));
- eyes =
- cvHaarDetectObjects (filter->cvGray, filter->cvEyesDetect,
- filter->cvStorage, filter->scale_factor, filter->min_neighbors,
- filter->flags, cvSize (mw, mh)
-#if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2)
- , cvSize (mw + 2, mh + 2)
-#endif
- );
- have_eyes = (eyes && eyes->total);
- cvResetImageROI (filter->cvGray);
+ if (filter->cvNoseDetect) {
+ rnx = r->x + r->width / 4;
+ rny = r->y + r->height / 4;
+ rnw = r->width / 2;
+ rnh = r->height / 2;
+ cvSetImageROI (filter->cvGray, cvRect (rnx, rny, rnw, rnh));
+ nose =
+ gst_face_detect_run_detector (filter, filter->cvNoseDetect, mw, mh);
+ have_nose = (nose && nose->total);
+ cvResetImageROI (filter->cvGray);
+ } else {
+ have_nose = FALSE;
+ }
+
+ if (filter->cvMouthDetect) {
+ rmx = r->x;
+ rmy = r->y + r->height / 2;
+ rmw = r->width;
+ rmh = r->height / 2;
+ cvSetImageROI (filter->cvGray, cvRect (rmx, rmy, rmw, rmh));
+ mouth =
+ gst_face_detect_run_detector (filter, filter->cvMouthDetect, mw,
+ mh);
+ have_mouth = (mouth && mouth->total);
+ cvResetImageROI (filter->cvGray);
+ } else {
+ have_mouth = FALSE;
+ }
+
+ if (filter->cvEyesDetect) {
+ rex = r->x;
+ rey = r->y;
+ rew = r->width;
+ reh = r->height / 2;
+ cvSetImageROI (filter->cvGray, cvRect (rex, rey, rew, reh));
+ eyes =
+ gst_face_detect_run_detector (filter, filter->cvEyesDetect, mw, mh);
+ have_eyes = (eyes && eyes->total);
+ cvResetImageROI (filter->cvGray);
+ } else {
+ have_eyes = FALSE;
+ }
GST_LOG_OBJECT (filter,
"%2d/%2d: x,y = %4u,%4u: w.h = %4u,%4u : features(e,n,m) = %d,%d,%d",
i, faces->total, r->x, r->y, r->width, r->height,
have_eyes, have_nose, have_mouth);
- /* ignore 'face' where we don't fix mount/nose/eyes ? */
- if (!(have_eyes && have_nose && have_mouth))
- continue;
-
s = gst_structure_new ("face",
"x", G_TYPE_UINT, r->x,
"y", G_TYPE_UINT, r->y,
"width", G_TYPE_UINT, r->width,
"height", G_TYPE_UINT, r->height, NULL);
- if (nose && nose->total) {
+ if (have_nose) {
CvRect *sr = (CvRect *) cvGetSeqElem (nose, 0);
GST_LOG_OBJECT (filter, "nose/%d: x,y = %4u,%4u: w.h = %4u,%4u",
nose->total, rnx + sr->x, rny + sr->y, sr->width, sr->height);
@@ -599,7 +596,7 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
"nose->width", G_TYPE_UINT, sr->width,
"nose->height", G_TYPE_UINT, sr->height, NULL);
}
- if (mouth && mouth->total) {
+ if (have_mouth) {
CvRect *sr = (CvRect *) cvGetSeqElem (mouth, 0);
GST_LOG_OBJECT (filter, "mouth/%d: x,y = %4u,%4u: w.h = %4u,%4u",
mouth->total, rmx + sr->x, rmy + sr->y, sr->width, sr->height);
@@ -609,7 +606,7 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
"mouth->width", G_TYPE_UINT, sr->width,
"mouth->height", G_TYPE_UINT, sr->height, NULL);
}
- if (eyes && eyes->total) {
+ if (have_eyes) {
CvRect *sr = (CvRect *) cvGetSeqElem (eyes, 0);
GST_LOG_OBJECT (filter, "eyes/%d: x,y = %4u,%4u: w.h = %4u,%4u",
eyes->total, rex + sr->x, rey + sr->y, sr->width, sr->height);
@@ -620,10 +617,11 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
"eyes->height", G_TYPE_UINT, sr->height, NULL);
}
- g_value_init (&value, GST_TYPE_STRUCTURE);
- gst_value_set_structure (&value, s);
- gst_value_list_append_value (&facelist, &value);
- g_value_unset (&value);
+ g_value_init (&facedata, GST_TYPE_STRUCTURE);
+ g_value_take_boxed (&facedata, s);
+ gst_value_list_append_value (&facelist, &facedata);
+ g_value_unset (&facedata);
+ s = NULL;
if (do_display) {
CvPoint center;
@@ -642,7 +640,7 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
cvEllipse (img, center, axes, 0.0, 0.0, 360.0, CV_RGB (cr, cg, cb),
3, 8, 0);
- if (nose && nose->total) {
+ if (have_nose) {
CvRect *sr = (CvRect *) cvGetSeqElem (nose, 0);
w = sr->width / 2;
@@ -654,7 +652,7 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
cvEllipse (img, center, axes, 0.0, 0.0, 360.0, CV_RGB (cr, cg, cb),
1, 8, 0);
}
- if (mouth && mouth->total) {
+ if (have_mouth) {
CvRect *sr = (CvRect *) cvGetSeqElem (mouth, 0);
w = sr->width / 2;
@@ -666,7 +664,7 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
cvEllipse (img, center, axes, 0.0, 0.0, 360.0, CV_RGB (cr, cg, cb),
1, 8, 0);
}
- if (eyes && eyes->total) {
+ if (have_eyes) {
CvRect *sr = (CvRect *) cvGetSeqElem (eyes, 0);
w = sr->width / 2;
@@ -681,11 +679,9 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
}
}
- if (msg) {
- gst_structure_set_value (msg->structure, "faces", &facelist);
- g_value_unset (&facelist);
- gst_element_post_message (GST_ELEMENT (filter), msg);
- }
+ gst_structure_set_value (msg->structure, "faces", &facelist);
+ g_value_unset (&facelist);
+ gst_element_post_message (GST_ELEMENT (filter), msg);
}
return GST_FLOW_OK;
diff --git a/ext/opencv/gstopencvutils.c b/ext/opencv/gstopencvutils.c
index 554b38be9..daaf0651f 100644
--- a/ext/opencv/gstopencvutils.c
+++ b/ext/opencv/gstopencvutils.c
@@ -19,6 +19,10 @@
* Boston, MA 02111-1307, USA.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "gstopencvutils.h"
static gboolean
diff --git a/ext/opencv/gstopencvvideofilter.c b/ext/opencv/gstopencvvideofilter.c
index 2d6cb6d84..5eeda942b 100644
--- a/ext/opencv/gstopencvvideofilter.c
+++ b/ext/opencv/gstopencvvideofilter.c
@@ -122,6 +122,8 @@ gst_opencv_video_filter_finalize (GObject * obj)
if (transform->cvImage)
cvReleaseImage (&transform->cvImage);
+ if (transform->out_cvImage)
+ cvReleaseImage (&transform->out_cvImage);
G_OBJECT_CLASS (parent_class)->finalize (obj);
}
diff --git a/ext/opencv/gsttemplatematch.h b/ext/opencv/gsttemplatematch.h
index 7b4b38852..8d99f982e 100644
--- a/ext/opencv/gsttemplatematch.h
+++ b/ext/opencv/gsttemplatematch.h
@@ -48,7 +48,12 @@
#include <gst/gst.h>
#include <cv.h>
-#include <highgui.h>
+#ifdef HAVE_HIGHGUI_H
+#include <highgui.h> // includes highGUI definitions
+#endif
+#ifdef HAVE_OPENCV2_HIGHGUI_HIGHGUI_C_H
+#include <opencv2/highgui/highgui_c.h> // includes highGUI definitions
+#endif
G_BEGIN_DECLS
/* #defines don't like whitespacey bits */
diff --git a/ext/opencv/motioncells_wrapper.cpp b/ext/opencv/motioncells_wrapper.cpp
index d50968677..f55802bb4 100644
--- a/ext/opencv/motioncells_wrapper.cpp
+++ b/ext/opencv/motioncells_wrapper.cpp
@@ -42,6 +42,13 @@
* Boston, MA 02111-1307, USA.
*/
+/* This breaks the build for reasons that aren't entirely clear to me yet */
+#if 0
+//#ifdef HAVE_CONFIG_H
+//#include "config.h"
+//#endif
+#endif
+
#include <stdio.h>
#include <limits.h>
#include "motioncells_wrapper.h"
diff --git a/ext/opus/gstopusenc.c b/ext/opus/gstopusenc.c
index 9c10d1a4b..be95fb798 100644
--- a/ext/opus/gstopusenc.c
+++ b/ext/opus/gstopusenc.c
@@ -368,11 +368,9 @@ gst_opus_enc_setup_base_class (GstOpusEnc * enc, GstAudioEncoder * benc)
{
gst_audio_encoder_set_latency (benc,
gst_opus_enc_get_latency (enc), gst_opus_enc_get_latency (enc));
- gst_audio_encoder_set_frame_samples_min (benc,
- enc->frame_samples * enc->n_channels * 2);
- gst_audio_encoder_set_frame_samples_max (benc,
- enc->frame_samples * enc->n_channels * 2);
- gst_audio_encoder_set_frame_max (benc, 0);
+ gst_audio_encoder_set_frame_samples_min (benc, enc->frame_samples);
+ gst_audio_encoder_set_frame_samples_max (benc, enc->frame_samples);
+ gst_audio_encoder_set_frame_max (benc, 1);
}
static gint
@@ -789,6 +787,9 @@ gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf)
gsize bytes = enc->frame_samples * enc->n_channels * 2;
gint ret = GST_FLOW_OK;
GstMapInfo map;
+ GstMapInfo omap;
+ gint outsize;
+ GstBuffer *outbuf;
g_mutex_lock (enc->property_lock);
@@ -813,50 +814,46 @@ gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf)
goto done;
}
- while (size) {
- gint encoded_size;
- GstBuffer *outbuf;
- GstMapInfo omap;
-
- outbuf = gst_buffer_new_and_alloc (enc->max_payload_size * enc->n_channels);
- if (!outbuf)
- goto done;
-
- GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)",
- enc->frame_samples, (int) bytes);
-
- gst_buffer_map (outbuf, &omap, GST_MAP_WRITE);
- encoded_size =
- opus_multistream_encode (enc->state, (const gint16 *) data,
- enc->frame_samples, omap.data, enc->max_payload_size * enc->n_channels);
- gst_buffer_unmap (outbuf, &omap);
-
- if (encoded_size < 0) {
- GST_ERROR_OBJECT (enc, "Encoding failed: %d", encoded_size);
- ret = GST_FLOW_ERROR;
- goto done;
- } else if (encoded_size > enc->max_payload_size) {
- GST_WARNING_OBJECT (enc,
- "Encoded size %d is higher than max payload size (%d bytes)",
- encoded_size, enc->max_payload_size);
- ret = GST_FLOW_ERROR;
- goto done;
- }
+ g_assert (size == bytes);
+
+ outbuf = gst_buffer_new_and_alloc (enc->max_payload_size * enc->n_channels);
+ if (!outbuf)
+ goto done;
+
+ GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)",
+ enc->frame_samples, (int) bytes);
+
+ gst_buffer_map (outbuf, &omap, GST_MAP_WRITE);
- GST_DEBUG_OBJECT (enc, "Output packet is %u bytes", encoded_size);
- gst_buffer_set_size (outbuf, encoded_size);
+ GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)",
+ enc->frame_samples, (int) bytes);
- ret =
- gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc), outbuf,
- enc->frame_samples);
+ outsize =
+ opus_multistream_encode (enc->state, (const gint16 *) data,
+ enc->frame_samples, GST_BUFFER_DATA (outbuf),
+ enc->max_payload_size * enc->n_channels);
- if ((GST_FLOW_OK != ret) && (GST_FLOW_NOT_LINKED != ret))
- goto done;
+ gst_buffer_unmap (outbuf, &omap);
- data += bytes;
- size -= bytes;
+ if (outsize < 0) {
+ GST_ERROR_OBJECT (enc, "Encoding failed: %d", outsize);
+ ret = GST_FLOW_ERROR;
+ goto done;
+ } else if (outsize > enc->max_payload_size) {
+ GST_WARNING_OBJECT (enc,
+ "Encoded size %d is higher than max payload size (%d bytes)",
+ outsize, enc->max_payload_size);
+ ret = GST_FLOW_ERROR;
+ goto done;
}
+ GST_DEBUG_OBJECT (enc, "Output packet is %u bytes", outsize);
+ GST_BUFFER_SIZE (outbuf) = outsize;
+
+ ret =
+ gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc), outbuf,
+ enc->frame_samples);
+
done:
if (bdata)
diff --git a/ext/resindvd/resindvdsrc.c b/ext/resindvd/resindvdsrc.c
index 8ce39a1b2..0b29615bf 100644
--- a/ext/resindvd/resindvdsrc.c
+++ b/ext/resindvd/resindvdsrc.c
@@ -1037,6 +1037,7 @@ rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock)
break;
case DVDNAV_CELL_CHANGE:{
dvdnav_cell_change_event_t *event = (dvdnav_cell_change_event_t *) data;
+ GstMessage *message;
src->pgc_duration = MPEGTIME_TO_GSTTIME (event->pgc_length);
/* event->cell_start has the wrong time - it doesn't handle
@@ -1050,6 +1051,10 @@ rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock)
GST_TIME_FORMAT, GST_TIME_ARGS (src->pgc_duration),
GST_TIME_ARGS (src->cur_position));
+ message = gst_message_new_duration (GST_OBJECT (src), GST_FORMAT_TIME,
+ src->pgc_duration);
+ gst_element_post_message (GST_ELEMENT (src), message);
+
rsn_dvdsrc_prepare_streamsinfo_event (src);
src->need_tag_update = TRUE;
@@ -2423,6 +2428,53 @@ rsn_dvdsrc_src_event (GstBaseSrc * basesrc, GstEvent * event)
return res;
}
+static void
+rsn_dvdsrc_post_title_info (GstElement * element)
+{
+ resinDvdSrc *src = RESINDVDSRC (element);
+ GstMessage *message;
+ GstStructure *s;
+ int32_t n, ntitles;
+ int res;
+ GValue array = { 0 };
+
+ res = dvdnav_get_number_of_titles (src->dvdnav, &ntitles);
+ if (res != DVDNAV_STATUS_OK) {
+ GST_WARNING_OBJECT (src, "Failed to get number of titles: %d", res);
+ return;
+ }
+
+ g_value_init (&array, GST_TYPE_ARRAY);
+
+ s = gst_structure_new ("application/x-gst-dvd", "event",
+ G_TYPE_STRING, "dvd-title-info", NULL);
+
+ for (n = 0; n < ntitles; ++n) {
+ uint64_t *times, duration;
+ uint32_t nchapters;
+ GValue item = { 0 };
+
+ g_value_init (&item, G_TYPE_UINT64);
+
+ nchapters =
+ dvdnav_describe_title_chapters (src->dvdnav, n, &times, &duration);
+ if (nchapters == 0) {
+ GST_WARNING_OBJECT (src, "Failed to get title %d info", n);
+ g_value_set_uint64 (&item, GST_CLOCK_TIME_NONE);
+ } else {
+ g_value_set_uint64 (&item, gst_util_uint64_scale (duration, GST_SECOND,
+ 90000));
+ }
+ gst_value_array_append_value (&array, &item);
+ g_value_unset (&item);
+ }
+ gst_structure_set_value (s, "title-durations", &array);
+ g_value_unset (&array);
+
+ message = gst_message_new_element (GST_OBJECT (src), s);
+ gst_element_post_message (GST_ELEMENT_CAST (src), message);
+}
+
static GstStateChangeReturn
rsn_dvdsrc_change_state (GstElement * element, GstStateChange transition)
{
@@ -2459,6 +2511,9 @@ rsn_dvdsrc_change_state (GstElement * element, GstStateChange transition)
rsn_dvdsrc_check_nav_blocks (src);
g_mutex_unlock (src->dvd_lock);
break;
+ case GST_STATE_CHANGE_READY_TO_PAUSED:
+ rsn_dvdsrc_post_title_info (element);
+ break;
default:
break;
}
@@ -2486,6 +2541,9 @@ rsn_dvdsrc_src_query (GstBaseSrc * basesrc, GstQuery * query)
if (format == GST_FORMAT_TIME) {
if (src->pgc_duration != GST_CLOCK_TIME_NONE) {
val = src->pgc_duration;
+
+ GST_DEBUG_OBJECT (src, "duration : %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (val));
gst_query_set_duration (query, format, val);
res = TRUE;
}
diff --git a/ext/rsvg/gstrsvgoverlay.c b/ext/rsvg/gstrsvgoverlay.c
index 9d4ce6025..5c9efba74 100644
--- a/ext/rsvg/gstrsvgoverlay.c
+++ b/ext/rsvg/gstrsvgoverlay.c
@@ -72,7 +72,7 @@ enum
{
PROP_0,
PROP_DATA,
- PROP_FILENAME,
+ PROP_LOCATION,
PROP_FIT_TO_FRAME,
PROP_X,
PROP_Y,
@@ -164,6 +164,8 @@ gst_rsvg_overlay_set_svg_data (GstRsvgOverlay * overlay, const gchar * data,
overlay->svg_width = svg_dimension.width;
overlay->svg_height = svg_dimension.height;
gst_base_transform_set_passthrough (btrans, FALSE);
+ GST_INFO_OBJECT (overlay, "updated SVG, %d x %d", overlay->svg_width,
+ overlay->svg_height);
}
}
}
@@ -184,7 +186,7 @@ gst_rsvg_overlay_set_property (GObject * object, guint prop_id,
FALSE);
break;
}
- case PROP_FILENAME:
+ case PROP_LOCATION:
{
gst_rsvg_overlay_set_svg_data (overlay, g_value_get_string (value), TRUE);
break;
@@ -336,7 +338,7 @@ gst_rsvg_overlay_data_sink_event (GstPad * pad, GstEvent * event)
GST_RSVG_UNLOCK (overlay);
}
- case GST_EVENT_FLUSH_START:
+ case GST_EVENT_FLUSH_STOP:
gst_adapter_clear (overlay->adapter);
break;
@@ -436,10 +438,11 @@ gst_rsvg_overlay_stop (GstBaseTransform * btrans)
if (overlay->handle) {
g_object_unref (overlay->handle);
- g_object_unref (overlay->adapter);
overlay->handle = NULL;
}
+ gst_adapter_clear (overlay->adapter);
+
return TRUE;
}
@@ -474,7 +477,7 @@ gst_rsvg_overlay_class_init (GstRsvgOverlayClass * klass)
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DATA,
g_param_spec_string ("data", "data", "SVG data.", "",
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FILENAME,
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LOCATION,
g_param_spec_string ("location", "location", "SVG file location.", "",
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FIT_TO_FRAME,
diff --git a/ext/timidity/gstwildmidi.c b/ext/timidity/gstwildmidi.c
index 59d433237..c8570a05b 100644
--- a/ext/timidity/gstwildmidi.c
+++ b/ext/timidity/gstwildmidi.c
@@ -38,6 +38,10 @@
* </refsect2>
*/
+/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
+ * with newer GLib versions (>= 2.31.0) */
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
diff --git a/ext/vp8/gstvp8enc.c b/ext/vp8/gstvp8enc.c
index 189d8df0b..d21ed23f4 100644
--- a/ext/vp8/gstvp8enc.c
+++ b/ext/vp8/gstvp8enc.c
@@ -827,7 +827,7 @@ gst_vp8_enc_set_format (GstBaseVideoEncoder * base_video_encoder,
/* prepare cached image buffer setup */
image = &encoder->image;
- memset (image, 0, sizeof (image));
+ memset (image, 0, sizeof (*image));
image->fmt = VPX_IMG_FMT_I420;
image->bps = 12;
diff --git a/ext/wayland/Makefile.am b/ext/wayland/Makefile.am
new file mode 100644
index 000000000..122e8f09e
--- /dev/null
+++ b/ext/wayland/Makefile.am
@@ -0,0 +1,13 @@
+plugin_LTLIBRARIES = libgstwaylandsink.la
+
+libgstwaylandsink_la_SOURCES = gstwaylandsink.c
+libgstwaylandsink_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
+ $(WAYLAND_CFLAGS)
+libgstwaylandsink_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
+ -lgstvideo-$(GST_MAJORMINOR) \
+ -lgstinterfaces-$(GST_MAJORMINOR) \
+ $(WAYLAND_LIBS) $(LIBOIL_LIBS)
+libgstwaylandsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+libgstwaylandsink_la_LIBTOOLFLAGS = --tag=disable-static
+
+noinst_HEADERS = gstwaylandsink.h
diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c
new file mode 100644
index 000000000..ecc026dc4
--- /dev/null
+++ b/ext/wayland/gstwaylandsink.c
@@ -0,0 +1,681 @@
+/*
+ * GStreamer Wayland video sink
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Copyright (C) 2011 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/**
+ * SECTION:element-waylandsink
+ *
+ * The waylandsink is creating its own window and render the decoded video frames to that.
+ * Setup the Wayland environment as described in
+ * <ulink url="http://wayland.freedesktop.org/building.html">Wayland</ulink> home page.
+ * The current implementaion is based on weston compositor.
+ *
+ * <refsect2>
+ * <title>Example pipelines</title>
+ * |[
+ * gst-launch -v videotestsrc ! waylandsink
+ * ]| test the video rendering in wayland
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gstwaylandsink.h"
+
+/* signals */
+enum
+{
+ SIGNAL_0,
+ SIGNAL_FRAME_READY,
+ LAST_SIGNAL
+};
+
+/* Properties */
+enum
+{
+ PROP_0,
+ PROP_WAYLAND_DISPLAY
+};
+
+GST_DEBUG_CATEGORY (gstwayland_debug);
+#define GST_CAT_DEFAULT gstwayland_debug
+
+static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("video/x-raw-rgb, "
+ "framerate = (fraction) [ 0, MAX ], "
+ "endianness = (int) 4321,"
+ "red_mask = (int) 65280, "
+ "green_mask = (int) 16711680, "
+ "blue_mask = (int) -16777216,"
+ "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ] "));
+
+G_DEFINE_TYPE (GstWlBuffer, gst_wlbuffer, GST_TYPE_BUFFER);
+
+/*Fixme: Add more interfaces */
+GST_BOILERPLATE (GstWaylandSink, gst_wayland_sink, GstVideoSink,
+ GST_TYPE_VIDEO_SINK);
+
+static void gst_wlbuffer_finalize (GstWlBuffer * wbuffer);
+
+static void gst_wayland_sink_get_property (GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec);
+static void gst_wayland_sink_set_property (GObject * object,
+ guint prop_id, const GValue * value, GParamSpec * pspec);
+static void gst_wayland_sink_finalize (GObject * object);
+static GstCaps *gst_wayland_sink_get_caps (GstBaseSink * bsink);
+static gboolean gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
+static gboolean gst_wayland_sink_start (GstBaseSink * bsink);
+static gboolean gst_wayland_sink_stop (GstBaseSink * bsink);
+static GstFlowReturn
+gst_wayland_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset,
+ guint size, GstCaps * caps, GstBuffer ** buf);
+static gboolean gst_wayland_sink_preroll (GstBaseSink * bsink,
+ GstBuffer * buffer);
+static gboolean gst_wayland_sink_render (GstBaseSink * bsink,
+ GstBuffer * buffer);
+static void gst_wayland_bufferpool_clear (GstWaylandSink * sink);
+static void
+gst_wayland_buffer_destroy (GstWaylandSink * sink, GstWlBuffer * buffer);
+
+static int event_mask_update (uint32_t mask, void *data);
+static struct display *create_display (void);
+static void display_handle_global (struct wl_display *display, uint32_t id,
+ const char *interface, uint32_t version, void *data);
+static void redraw (void *data, struct wl_callback *callback, uint32_t time);
+static void create_window (GstWaylandSink * sink, struct display *display,
+ int width, int height);
+
+static void
+gst_wlbuffer_init (GstWlBuffer * buffer)
+{
+ buffer->wbuffer = NULL;
+ buffer->wlsink = NULL;
+}
+
+static void
+gst_wlbuffer_class_init (GstWlBufferClass * klass)
+{
+ GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (klass);
+
+ mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
+ gst_wlbuffer_finalize;
+}
+
+static void
+gst_wlbuffer_finalize (GstWlBuffer * wbuffer)
+{
+ GstWaylandSink *sink = NULL;
+
+ g_return_if_fail (wbuffer != NULL);
+
+ GST_DEBUG_OBJECT (sink, "Finalizing the WlBuffer");
+ sink = wbuffer->wlsink;
+ if (!sink) {
+ GST_WARNING_OBJECT (wbuffer, "No sink..");
+ goto beach;
+ }
+
+ GST_DEBUG_OBJECT (sink, "recycling buffer %p in pool", wbuffer);
+ /* need to increment the refcount again to recycle */
+ gst_buffer_ref (GST_BUFFER (wbuffer));
+ g_mutex_lock (sink->pool_lock);
+ sink->buffer_pool = g_slist_prepend (sink->buffer_pool, wbuffer);
+ g_mutex_unlock (sink->pool_lock);
+
+beach:
+ return;
+}
+
+static void
+gst_wayland_sink_base_init (gpointer gclass)
+{
+
+ GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&sink_template));
+
+ gst_element_class_set_details_simple (element_class,
+ "wayland video sink", "Sink/Video",
+ "Output to wayland surface",
+ "Sreerenj Balachandran <sreerenj.balachandran@intel.com>");
+}
+
+static void
+gst_wayland_sink_class_init (GstWaylandSinkClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstBaseSinkClass *gstbasesink_class;
+
+ gobject_class = (GObjectClass *) klass;
+ gstbasesink_class = (GstBaseSinkClass *) klass;
+
+ gobject_class->set_property = gst_wayland_sink_set_property;
+ gobject_class->get_property = gst_wayland_sink_get_property;
+ gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_wayland_sink_finalize);
+
+ gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_wayland_sink_get_caps);
+ gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_wayland_sink_set_caps);
+ gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_wayland_sink_start);
+ gstbasesink_class->buffer_alloc =
+ GST_DEBUG_FUNCPTR (gst_wayland_sink_buffer_alloc);
+ gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_wayland_sink_stop);
+ gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_wayland_sink_preroll);
+ gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_wayland_sink_render);
+
+ g_object_class_install_property (gobject_class, PROP_WAYLAND_DISPLAY,
+ g_param_spec_pointer ("wayland-display", "Wayland Display",
+ "Wayland Display handle created by the application ",
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ parent_class = g_type_class_peek_parent (klass);
+}
+
+static void
+gst_wayland_sink_init (GstWaylandSink * sink,
+ GstWaylandSinkClass * wayland_sink_class)
+{
+
+ sink->caps = NULL;
+ sink->render_finish = TRUE;
+ sink->display = NULL;
+ sink->window = NULL;
+
+ sink->pool_lock = g_mutex_new ();
+ sink->buffer_pool = NULL;
+
+ sink->wayland_lock = g_mutex_new ();
+}
+
+static void
+gst_wayland_sink_get_property (GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec)
+{
+ GstWaylandSink *sink = GST_WAYLAND_SINK (object);
+
+ switch (prop_id) {
+ case PROP_WAYLAND_DISPLAY:
+ g_value_set_pointer (value, sink->display);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_wayland_sink_set_property (GObject * object,
+ guint prop_id, const GValue * value, GParamSpec * pspec)
+{
+ GstWaylandSink *sink = GST_WAYLAND_SINK (object);
+
+ switch (prop_id) {
+ case PROP_WAYLAND_DISPLAY:
+ sink->display = g_value_get_pointer (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+destroy_display (struct display *display)
+{
+ if (display->shm)
+ wl_shm_destroy (display->shm);
+
+ if (display->shell)
+ wl_shell_destroy (display->shell);
+
+ if (display->compositor)
+ wl_compositor_destroy (display->compositor);
+
+ wl_display_flush (display->display);
+ wl_display_destroy (display->display);
+ free (display);
+}
+
+static void
+destroy_window (struct window *window)
+{
+ if (window->shell_surface)
+ wl_shell_surface_destroy (window->shell_surface);
+ if (window->surface)
+ wl_surface_destroy (window->surface);
+ free (window);
+}
+
+static void
+gst_wayland_sink_finalize (GObject * object)
+{
+ GstWaylandSink *sink = GST_WAYLAND_SINK (object);
+
+ GST_DEBUG_OBJECT (sink, "Finalizing the sink..");
+
+ if (sink->window)
+ destroy_window (sink->window);
+ if (sink->display)
+ destroy_display (sink->display);
+
+ if (sink->pool_lock) {
+ g_mutex_free (sink->pool_lock);
+ sink->pool_lock = NULL;
+ }
+
+ if (sink->buffer_pool) {
+ gst_wayland_bufferpool_clear (sink);
+ }
+
+ g_mutex_free (sink->wayland_lock);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static GstCaps *
+gst_wayland_sink_get_caps (GstBaseSink * bsink)
+{
+ return gst_caps_copy (gst_static_pad_template_get_caps (&sink_template));
+}
+
+static int
+event_mask_update (uint32_t mask, void *data)
+{
+ struct display *d = data;
+
+ d->mask = mask;
+
+ return 0;
+}
+
+static void
+shm_format (void *data, struct wl_shm *wl_shm, uint32_t format)
+{
+ struct display *d = data;
+
+ d->formats |= (1 << format);
+}
+
+struct wl_shm_listener shm_listenter = {
+ shm_format
+};
+
+static void
+display_handle_global (struct wl_display *display, uint32_t id,
+ const char *interface, uint32_t version, void *data)
+{
+ struct display *d = data;
+
+ if (strcmp (interface, "wl_compositor") == 0) {
+ d->compositor = wl_display_bind (display, id, &wl_compositor_interface);
+ } else if (strcmp (interface, "wl_shell") == 0) {
+ d->shell = wl_display_bind (display, id, &wl_shell_interface);
+ } else if (strcmp (interface, "wl_shm") == 0) {
+ d->shm = wl_display_bind (display, id, &wl_shm_interface);
+ wl_shm_add_listener (d->shm, &shm_listenter, d);
+ }
+
+}
+
+static struct display *
+create_display (void)
+{
+ struct display *display;
+
+ display = malloc (sizeof *display);
+ display->display = wl_display_connect (NULL);
+ assert (display->display);
+
+ wl_display_add_global_listener (display->display,
+ display_handle_global, display);
+
+ wl_display_iterate (display->display, WL_DISPLAY_READABLE);
+ wl_display_roundtrip (display->display);
+
+ if (!(display->formats & (1 << WL_SHM_FORMAT_XRGB8888))) {
+ GST_ERROR ("WL_SHM_FORMAT_XRGB32 not available");
+ return NULL;
+ }
+
+ wl_display_get_fd (display->display, event_mask_update, display);
+
+ return display;
+}
+
+static GstWlBuffer *
+wayland_buffer_create (GstWaylandSink * sink)
+{
+ char filename[1024];
+ int fd, size, stride;
+ static void *data;
+ static int init = 0;
+ GstWlBuffer *wbuffer;
+
+ GST_DEBUG_OBJECT (sink, "Creating wayland-shm buffers");
+
+ wbuffer = (GstWlBuffer *) gst_mini_object_new (GST_TYPE_WLBUFFER);
+ wbuffer->wlsink = gst_object_ref (sink);
+
+ snprintf (filename, 256, "%s-%d-%s", "/tmp/wayland-shm", init++, "XXXXXX");
+
+ fd = mkstemp (filename);
+ if (fd < 0) {
+ GST_ERROR_OBJECT (sink, "open %s failed:", filename);
+ exit (0);
+ }
+
+ stride = sink->video_width * 4;
+ size = stride * sink->video_height;
+
+ if (ftruncate (fd, size) < 0) {
+ GST_ERROR_OBJECT (sink, "ftruncate failed:");
+ close (fd);
+ exit (0);
+ }
+
+ data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ unlink (filename);
+ if (data == MAP_FAILED) {
+ GST_ELEMENT_ERROR (sink, LIBRARY, SHUTDOWN, (NULL),
+ ("mmap() failed: %s", strerror (errno)));
+ close (fd);
+ exit (0);
+ }
+
+ wbuffer->wbuffer = wl_shm_create_buffer (sink->display->shm, fd,
+ sink->video_width, sink->video_height, stride, WL_SHM_FORMAT_XRGB8888);
+
+ close (fd);
+
+ GST_BUFFER_DATA (wbuffer) = data;
+ GST_BUFFER_SIZE (wbuffer) = size;
+
+ return wbuffer;
+}
+
+static void
+gst_wayland_buffer_destroy (GstWaylandSink * sink, GstWlBuffer * buffer)
+{
+ if (buffer->wlsink) {
+ buffer->wlsink = NULL;
+ gst_object_unref (sink);
+ }
+
+ GST_MINI_OBJECT_CLASS (gst_wlbuffer_parent_class)->finalize (GST_MINI_OBJECT
+ (buffer));
+}
+
+static void
+gst_wayland_bufferpool_clear (GstWaylandSink * sink)
+{
+ g_mutex_lock (sink->pool_lock);
+ while (sink->buffer_pool) {
+ GstWlBuffer *buffer = sink->buffer_pool->data;
+
+ sink->buffer_pool = g_slist_delete_link (sink->buffer_pool,
+ sink->buffer_pool);
+ gst_wayland_buffer_destroy (sink, buffer);
+ }
+ g_mutex_unlock (sink->pool_lock);
+}
+
+static GstFlowReturn
+gst_wayland_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
+ GstCaps * caps, GstBuffer ** buf)
+{
+ GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
+ GstWlBuffer *buffer = NULL;
+ GstFlowReturn ret = GST_FLOW_OK;
+ GstStructure *structure = NULL;
+ GstCaps *desired_caps = NULL;
+
+ GST_LOG_OBJECT (sink, "a buffer of %u bytes was requested with caps "
+ "%" GST_PTR_FORMAT " and offset %" G_GUINT64_FORMAT, size, caps, offset);
+
+ desired_caps = gst_caps_copy (caps);
+ structure = gst_caps_get_structure (desired_caps, 0);
+
+ if (gst_structure_get_int (structure, "width", &sink->video_width) &&
+ gst_structure_get_int (structure, "height", &sink->video_height)) {
+ sink->bpp = size / sink->video_width / sink->video_height;
+ }
+
+ g_mutex_lock (sink->pool_lock);
+ while (sink->buffer_pool) {
+ buffer = (GstWlBuffer *) sink->buffer_pool->data;
+
+ if (buffer) {
+ sink->buffer_pool =
+ g_slist_delete_link (sink->buffer_pool, sink->buffer_pool);
+ } else {
+ break;
+ }
+ }
+
+ g_mutex_unlock (sink->pool_lock);
+
+ if (!buffer)
+ buffer = wayland_buffer_create (sink);
+
+ if (buffer)
+ gst_buffer_set_caps (GST_BUFFER (buffer), caps);
+
+ *buf = GST_BUFFER (buffer);
+
+ gst_caps_unref (desired_caps);
+
+ return ret;
+}
+
+static gboolean
+gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
+{
+ GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
+ const GstStructure *structure;
+ GstCaps *allowed_caps;
+ gboolean ret = TRUE;
+
+ GST_LOG_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps);
+
+ allowed_caps = gst_pad_get_caps (GST_BASE_SINK_PAD (bsink));
+
+ if (!gst_caps_can_intersect (allowed_caps, caps))
+ return FALSE;
+
+ structure = gst_caps_get_structure (caps, 0);
+
+ ret &= gst_structure_get_int (structure, "width", &sink->video_width);
+ ret &= gst_structure_get_int (structure, "height", &sink->video_height);
+
+ if (!ret)
+ return FALSE;
+
+ gst_caps_replace (&sink->caps, caps);
+
+ return TRUE;
+}
+
+static const struct wl_callback_listener frame_listener;
+
+static void
+redraw (void *data, struct wl_callback *callback, uint32_t time)
+{
+
+ GstWaylandSink *sink = (GstWaylandSink *) data;
+
+ sink->render_finish = TRUE;
+}
+
+static void
+create_window (GstWaylandSink * sink, struct display *display, int width,
+ int height)
+{
+ struct window *window;
+
+ if (sink->window)
+ return;
+
+ g_mutex_lock (sink->wayland_lock);
+
+ window = malloc (sizeof *window);
+ window->display = display;
+ window->width = width;
+ window->height = height;
+ window->surface = wl_compositor_create_surface (display->compositor);
+
+ window->shell_surface = wl_shell_get_shell_surface (display->shell,
+ window->surface);
+ /* wl_shell_surface_set_toplevel (window->shell_surface); */
+ wl_shell_surface_set_fullscreen (window->shell_surface,
+ WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL);
+
+ sink->window = window;
+
+ g_mutex_unlock (sink->wayland_lock);
+}
+
+static gboolean
+gst_wayland_sink_start (GstBaseSink * bsink)
+{
+ GstWaylandSink *sink = (GstWaylandSink *) bsink;
+ gboolean result = TRUE;
+
+ GST_DEBUG_OBJECT (sink, "start");
+
+ if (!sink->display)
+ sink->display = create_display ();
+
+ return result;
+}
+
+static gboolean
+gst_wayland_sink_stop (GstBaseSink * bsink)
+{
+ GstWaylandSink *sink = (GstWaylandSink *) bsink;
+
+ GST_DEBUG_OBJECT (sink, "stop");
+
+ return TRUE;
+}
+
+static GstFlowReturn
+gst_wayland_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
+{
+ GST_DEBUG_OBJECT (bsink, "preroll buffer %p, data = %p", buffer,
+ GST_BUFFER_DATA (buffer));
+ return gst_wayland_sink_render (bsink, buffer);
+}
+
+static GstFlowReturn
+gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
+{
+ GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
+ gboolean mem_cpy = TRUE;
+ GstVideoRectangle src, dst, res;
+
+ GST_LOG_OBJECT (sink,
+ "render buffer %p, data = %p, timestamp = %" GST_TIME_FORMAT, buffer,
+ GST_BUFFER_DATA (buffer), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
+
+ if (!sink->window)
+ create_window (sink, sink->display, sink->video_width, sink->video_height);
+
+ if (sink->render_finish) {
+ if (GST_IS_WLBUFFER (buffer)) {
+ GstWlBuffer *tmp_buffer = (GstWlBuffer *) buffer;
+
+ /* Does it have a waylandbuffer ? */
+ if (tmp_buffer->wbuffer) {
+ mem_cpy = FALSE;
+ GST_DEBUG_OBJECT (sink, "we have a buffer (%p) we allocated "
+ "ourselves and it has a wayland buffer, no memcpy then", buffer);
+ sink->window->buffer = tmp_buffer->wbuffer;
+ } else {
+ /* No wayland buffer, that's a malloc */
+ GST_DEBUG_OBJECT (sink, "we have a buffer (%p) we allocated "
+ "ourselves but it does not hold a wayland buffer", buffer);
+ }
+ } else {
+ /* Not our baby! */
+ GST_DEBUG_OBJECT (sink, "we have a buffer (%p) we did not allocate",
+ buffer);
+ }
+
+ if (mem_cpy) {
+
+ GstWlBuffer *wlbuf = wayland_buffer_create (sink);
+
+ memcpy (GST_BUFFER_DATA (wlbuf), GST_BUFFER_DATA (buffer),
+ GST_BUFFER_SIZE (buffer));
+ sink->window->buffer = wlbuf->wbuffer;
+ }
+
+ src.w = sink->video_width;
+ src.h = sink->video_height;
+ dst.w = sink->window->width;
+ dst.h = sink->window->height;
+
+ gst_video_sink_center_rect (src, dst, &res, FALSE);
+
+ sink->render_finish = FALSE;
+
+ wl_buffer_damage (sink->window->buffer, 0, 0, res.w, res.h);
+
+ wl_surface_attach (sink->window->surface, sink->window->buffer, 0, 0);
+
+ wl_surface_damage (sink->window->surface, 0, 0, res.w, res.h);
+
+ if (sink->callback)
+ wl_callback_destroy (sink->callback);
+
+ sink->callback = wl_surface_frame (sink->window->surface);
+ wl_callback_add_listener (sink->callback, &frame_listener, sink);
+ wl_display_iterate (sink->display->display, sink->display->mask);
+
+ } else
+ GST_LOG_OBJECT (sink,
+ "Waiting to get the signal from compositor to render the next frame..");
+
+ return GST_FLOW_OK;
+}
+
+static const struct wl_callback_listener frame_listener = {
+ redraw
+};
+
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+ GST_DEBUG_CATEGORY_INIT (gstwayland_debug, "waylandsink", 0,
+ " wayland video sink");
+
+ return gst_element_register (plugin, "waylandsink", GST_RANK_MARGINAL,
+ GST_TYPE_WAYLAND_SINK);
+}
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "waylandsink",
+ "Wayland Video Sink", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME,
+ GST_PACKAGE_ORIGIN)
diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h
new file mode 100644
index 000000000..f9c1ca87c
--- /dev/null
+++ b/ext/wayland/gstwaylandsink.h
@@ -0,0 +1,131 @@
+/*
+ * GStreamer Wayland video sink
+ * Copyright (C) 2011 Intel Corporation
+ * Copyright (C) 2011 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __GST_WAYLAND_VIDEO_SINK_H__
+#define __GST_WAYLAND_VIDEO_SINK_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/video/gstvideosink.h>
+
+#include <wayland-client.h>
+
+#define GST_TYPE_WAYLAND_SINK \
+ (gst_wayland_sink_get_type())
+#define GST_WAYLAND_SINK(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WAYLAND_SINK,GstWaylandSink))
+#define GST_WAYLAND_SINK_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_WAYLAND_SINK,GstWaylandSinkClass))
+#define GST_IS_WAYLAND_SINK(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WAYLAND_SINK))
+#define GST_IS_WAYLAND_SINK_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_WAYLAND_SINK))
+#define GST_WAYLAND_SINK_GET_CLASS(inst) \
+ (G_TYPE_INSTANCE_GET_CLASS ((inst), GST_TYPE_WAYLAND_SINK, GstWaylandSinkClass))
+
+struct display
+{
+ struct wl_display *display;
+ struct wl_compositor *compositor;
+ struct wl_shell *shell;
+ struct wl_shm *shm;
+ uint32_t formats;
+ uint32_t mask;
+};
+
+struct window
+{
+ struct display *display;
+ int width, height;
+ struct wl_surface *surface;
+ struct wl_shell_surface *shell_surface;
+ struct wl_buffer *buffer;
+};
+
+typedef struct _GstWaylandSink GstWaylandSink;
+typedef struct _GstWaylandSinkClass GstWaylandSinkClass;
+
+#define GST_TYPE_WLBUFFER (gst_wlbuffer_get_type())
+#define GST_IS_WLBUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_WLBUFFER))
+#define GST_WLBUFFER (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_WLBUFFER, GstWlBuffer))
+
+typedef struct _GstWlBuffer GstWlBuffer;
+typedef struct _GstWlBufferClass GstWlBufferClass;
+
+struct _GstWlBuffer {
+ GstBuffer buffer; /* Extending GstBuffer */
+
+ struct wl_buffer *wbuffer;
+
+ GstWaylandSink *wlsink;
+};
+
+struct _GstWlBufferClass
+{
+ GstBufferClass parent_class;
+};
+
+struct _GstWaylandSink
+{
+
+ GstVideoSink parent;
+
+ GstCaps *caps;
+
+ struct display *display;
+ struct window *window;
+ struct wl_callback *callback;
+
+ GMutex *pool_lock;
+ GSList *buffer_pool;
+
+ GMutex *wayland_lock;
+
+ gint video_width;
+ gint video_height;
+ guint bpp;
+
+ gboolean render_finish;
+
+};
+
+struct _GstWaylandSinkClass
+{
+ GstVideoSinkClass parent;
+};
+
+GType gst_wayland_sink_get_type (void) G_GNUC_CONST;
+GType gst_wlbuffer_get_type (void);
+
+G_END_DECLS
+#endif /* __GST_WAYLAND_VIDEO_SINK_H__ */