diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-03-29 17:41:53 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-03-29 17:41:53 +0200 |
commit | 860ccd414dbb313fabf065b92838f0f39037584b (patch) | |
tree | 0d5c0d3510db3ca3d7e6487420e8d09f74ae1961 /ext | |
parent | a9ec4d62a89dd53aa295af02c7d5f57ef936359b (diff) | |
parent | d84d98943af42ce645ee022207bcf04e747d2d4a (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')
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, ×, &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__ */ |