Merge branch 'master' into 0.11
authorWim Taymans <wim.taymans@collabora.co.uk>
Tue, 24 May 2011 07:47:15 +0000 (09:47 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Tue, 24 May 2011 07:47:15 +0000 (09:47 +0200)
Conflicts:
gst-libs/gst/video/convertframe.c

243 files changed:
android/alsa.mk
android/app.mk
android/app_plugin.mk
android/audio.mk
android/audioconvert.mk
android/decodebin.mk
android/decodebin2.mk
android/gdp.mk
android/interfaces.mk
android/netbuffer.mk
android/pbutils.mk
android/playbin.mk
android/queue2.mk
android/riff.mk
android/rtp.mk
android/rtsp.mk
android/sdp.mk
android/tag.mk
android/tcp.mk
android/typefindfunctions.mk
android/video.mk
configure.ac
docs/plugins/gst-plugins-base-plugins.hierarchy
docs/plugins/gst-plugins-base-plugins.interfaces
docs/plugins/gst-plugins-base-plugins.prerequisites
ext/alsa/gstalsadeviceprobe.c
ext/alsa/gstalsamixerelement.c
ext/alsa/gstalsamixertrack.c
ext/alsa/gstalsasink.c
ext/alsa/gstalsasrc.c
ext/cdparanoia/gstcdparanoiasrc.c
ext/gio/gstgiobasesink.c
ext/gio/gstgiobasesrc.c
ext/gio/gstgiosink.c
ext/gio/gstgiosrc.c
ext/gio/gstgiostreamsink.c
ext/gio/gstgiostreamsrc.c
ext/gnomevfs/gstgnomevfssink.c
ext/gnomevfs/gstgnomevfssrc.c
ext/libvisual/visual.c
ext/ogg/gstoggaviparse.c
ext/ogg/gstoggdemux.c
ext/ogg/gstoggdemux.h
ext/ogg/gstoggmux.c
ext/ogg/gstoggparse.c
ext/ogg/gstoggstream.c
ext/ogg/gstogmparse.c
ext/pango/Makefile.am
ext/pango/gstbasetextoverlay.c [new file with mode: 0644]
ext/pango/gstbasetextoverlay.h [new file with mode: 0644]
ext/pango/gstclockoverlay.c
ext/pango/gstclockoverlay.h
ext/pango/gsttextoverlay.c
ext/pango/gsttextoverlay.h
ext/pango/gsttextrender.c
ext/pango/gsttimeoverlay.c
ext/pango/gsttimeoverlay.h
ext/theora/gsttheoradec.c
ext/theora/gsttheoradec.h
ext/theora/gsttheoraenc.c
ext/theora/gsttheoraparse.c
ext/vorbis/gstvorbisdec.c
ext/vorbis/gstvorbisdeclib.h
ext/vorbis/gstvorbisenc.c
ext/vorbis/gstvorbisenc.h
ext/vorbis/gstvorbisparse.c
ext/vorbis/gstvorbistag.c
gst-libs/gst/app/Makefile.am
gst-libs/gst/app/gstappbuffer.c [deleted file]
gst-libs/gst/app/gstappbuffer.h [deleted file]
gst-libs/gst/app/gstappsink.c
gst-libs/gst/app/gstappsrc.c
gst-libs/gst/audio/audio.c
gst-libs/gst/audio/gstaudiofilter.c
gst-libs/gst/audio/gstaudiofilter.h
gst-libs/gst/audio/gstaudiosink.c
gst-libs/gst/audio/gstaudiosrc.c
gst-libs/gst/audio/gstbaseaudiosink.c
gst-libs/gst/audio/gstbaseaudiosrc.c
gst-libs/gst/audio/gstringbuffer.c
gst-libs/gst/audio/gstringbuffer.h
gst-libs/gst/cdda/gstcddabasesrc.c
gst-libs/gst/interfaces/navigation.c
gst-libs/gst/netbuffer/gstnetbuffer.c
gst-libs/gst/netbuffer/gstnetbuffer.h
gst-libs/gst/pbutils/encoding-profile.c
gst-libs/gst/pbutils/encoding-profile.h
gst-libs/gst/pbutils/encoding-target.c
gst-libs/gst/pbutils/encoding-target.h
gst-libs/gst/pbutils/gstdiscoverer-types.c
gst-libs/gst/pbutils/gstdiscoverer.c
gst-libs/gst/pbutils/gstdiscoverer.h
gst-libs/gst/pbutils/missing-plugins.c
gst-libs/gst/pbutils/pbutils-private.h
gst-libs/gst/riff/riff-media.c
gst-libs/gst/riff/riff-read.c
gst-libs/gst/rtp/gstbasertpaudiopayload.c
gst-libs/gst/rtp/gstbasertpdepayload.c
gst-libs/gst/rtp/gstbasertpdepayload.h
gst-libs/gst/rtp/gstbasertppayload.c
gst-libs/gst/rtp/gstbasertppayload.h
gst-libs/gst/rtp/gstrtcpbuffer.c
gst-libs/gst/rtp/gstrtcpbuffer.h
gst-libs/gst/rtp/gstrtpbuffer.c
gst-libs/gst/rtp/gstrtpbuffer.h
gst-libs/gst/tag/gstexiftag.c
gst-libs/gst/tag/gsttagdemux.c
gst-libs/gst/tag/gstvorbistag.c
gst-libs/gst/tag/gstxmptag.c
gst-libs/gst/tag/tag.h
gst-libs/gst/tag/tags.c
gst-libs/gst/video/Makefile.am
gst-libs/gst/video/convertframe.c
gst-libs/gst/video/gstmetavideo.c [new file with mode: 0644]
gst-libs/gst/video/gstmetavideo.h [new file with mode: 0644]
gst-libs/gst/video/gstvideofilter.c
gst-libs/gst/video/video.c
gst-libs/gst/video/video.h
gst/adder/gstadder.c
gst/adder/gstadder.h
gst/audioconvert/gstaudioconvert.c
gst/audiorate/gstaudiorate.c
gst/audiorate/gstaudiorate.h
gst/audioresample/gstaudioresample.c
gst/audiotestsrc/gstaudiotestsrc.c
gst/encoding/gstencodebin.c
gst/encoding/gstsmartencoder.c
gst/encoding/gststreamcombiner.c
gst/encoding/gststreamsplitter.c
gst/ffmpegcolorspace/gstffmpegcodecmap.c
gst/ffmpegcolorspace/gstffmpegcolorspace.c
gst/gdp/gstgdpdepay.c
gst/gdp/gstgdppay.c
gst/playback/gstdecodebin.c
gst/playback/gstdecodebin2.c
gst/playback/gstplaybasebin.c
gst/playback/gstplaybin.c
gst/playback/gstplaybin2.c
gst/playback/gstplaysink.c
gst/playback/gstplaysinkaudioconvert.c
gst/playback/gstplaysinkvideoconvert.c
gst/playback/gststreamselector.c
gst/playback/gststreamsynchronizer.c
gst/playback/gstsubtitleoverlay.c
gst/playback/gsturidecodebin.c
gst/subparse/gstssaparse.c
gst/subparse/gstsubparse.c
gst/subparse/gstsubparse.h
gst/tcp/gstmultifdsink.c
gst/tcp/gstmultifdsink.h
gst/tcp/gsttcp.c
gst/tcp/gsttcp.h
gst/tcp/gsttcpclientsink.c
gst/tcp/gsttcpclientsink.h
gst/tcp/gsttcpclientsrc.c
gst/tcp/gsttcpclientsrc.h
gst/tcp/gsttcpserversink.c
gst/tcp/gsttcpserversrc.c
gst/tcp/gsttcpserversrc.h
gst/typefind/gsttypefindfunctions.c
gst/videorate/gstvideorate.c
gst/videoscale/gstvideoscale.c
gst/videotestsrc/gstvideotestsrc.c
gst/videotestsrc/gstvideotestsrc.h
gst/volume/gstvolume.c
sys/v4l/gstv4lelement.c
sys/v4l/gstv4lmjpegsrc.c
sys/v4l/gstv4lsrc.c
sys/v4l/v4lsrc_calls.c
sys/ximage/Makefile.am
sys/ximage/ximage.c
sys/ximage/ximagepool.c [new file with mode: 0644]
sys/ximage/ximagepool.h [new file with mode: 0644]
sys/ximage/ximagesink.c
sys/ximage/ximagesink.h
sys/xvimage/Makefile.am
sys/xvimage/xvimage.c [new file with mode: 0644]
sys/xvimage/xvimagepool.c [new file with mode: 0644]
sys/xvimage/xvimagepool.h [new file with mode: 0644]
sys/xvimage/xvimagesink.c
sys/xvimage/xvimagesink.h
tests/check/elements/appsink.c
tests/check/elements/audioconvert.c
tests/check/elements/audiorate.c
tests/check/elements/audioresample.c
tests/check/elements/decodebin.c
tests/check/elements/decodebin2.c
tests/check/elements/ffmpegcolorspace.c
tests/check/elements/gdpdepay.c
tests/check/elements/gdppay.c
tests/check/elements/gnomevfssink.c
tests/check/elements/multifdsink.c
tests/check/elements/playbin.c
tests/check/elements/playbin2.c
tests/check/elements/subparse.c
tests/check/elements/textoverlay.c
tests/check/elements/videorate.c
tests/check/elements/videoscale.c
tests/check/elements/videotestsrc.c
tests/check/elements/volume.c
tests/check/elements/vorbisdec.c
tests/check/elements/vorbistag.c
tests/check/gst/typefindfunctions.c
tests/check/libs/audio.c
tests/check/libs/cddabasesrc.c
tests/check/libs/gstlibscpp.cc
tests/check/libs/libsabi.c
tests/check/libs/mixer.c
tests/check/libs/navigation.c
tests/check/libs/netbuffer.c
tests/check/libs/pbutils.c
tests/check/libs/profile.c
tests/check/libs/rtp.c
tests/check/libs/struct_i386.h
tests/check/libs/struct_x86_64.h
tests/check/libs/tag.c
tests/check/libs/video.c
tests/check/libs/xmpwriter.c
tests/check/pipelines/capsfilter-renegotiation.c
tests/check/pipelines/oggmux.c
tests/check/pipelines/streamheader.c
tests/check/pipelines/vorbisenc.c
tests/examples/app/appsink-src.c
tests/examples/app/appsrc-ra.c
tests/examples/app/appsrc-seekable.c
tests/examples/app/appsrc-stream.c
tests/examples/app/appsrc-stream2.c
tests/examples/app/appsrc_ex.c
tests/examples/encoding/encoding.c
tests/examples/gio/giosrc-mounting.c
tests/examples/seek/jsseek.c
tests/examples/seek/seek.c
tests/examples/snapshot/snapshot.c
tests/icles/playback/test.c
tests/icles/playback/test5.c
tests/icles/playback/test6.c
tests/icles/playbin-text.c
tools/gst-discoverer.c
win32/common/libgstapp.def
win32/common/libgstnetbuffer.def
win32/common/libgstrtp.def
win32/common/libgsttag.def
win32/common/libgstvideo.def

index c67a1df..b370591 100644 (file)
@@ -19,14 +19,14 @@ LOCAL_SRC_FILES:= $(addprefix ../,$(alsa_LOCAL_SRC_FILES))
 
 LOCAL_SHARED_LIBRARIES := \
        libdl                   \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0                     \
-       libgstinterfaces-0.10   \
-       libgstaudio-0.10
+       libgstinterfaces-0.11   \
+       libgstaudio-0.11
 
 LOCAL_MODULE:= libgstalsa
 
@@ -39,8 +39,8 @@ LOCAL_CFLAGS := -DHAVE_CONFIG_H       -DGSTREAMER_BUILT_FOR_ANDROID \
 #
 LOCAL_PRELINK_MODULE := false
 
-#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.10
-LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.10
+#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.11
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.11
 
 
 $(TARGET_OUT)/lib/libgstalsa.so:
index 88dfb7d..ffa9459 100644 (file)
@@ -1,7 +1,7 @@
 LOCAL_PATH:= $(call my-dir)
 #----------------------------------------
 # include 
-gst_app_COPY_HEADERS_TO := gstreamer-0.10/gst/app
+gst_app_COPY_HEADERS_TO := gstreamer-0.11/gst/app
 gst_app_COPY_HEADERS := \
        ../gst-libs/gst/app/gstappbuffer.h \
        ../gst-libs/gst/app/gstappsink.h \
@@ -20,14 +20,14 @@ app_LOCAL_SRC_FILES_BASE:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(app_LOCAL_SRC_FILES_BASE))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0 
 
-LOCAL_MODULE:= libgstapp-0.10
+LOCAL_MODULE:= libgstapp-0.11
 
 LOCAL_CFLAGS := -DHAVE_CONFIG_H         -DGSTREAMER_BUILT_FOR_ANDROID \
        $(GST_PLUGINS_BASE_CFLAGS)
index 8e067fc..179e6c8 100644 (file)
@@ -10,13 +10,13 @@ app_plugin_LOCAL_SRC_FILES:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(app_plugin_LOCAL_SRC_FILES))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0                     \
-       libgstapp-0.10
+       libgstapp-0.11
 
 LOCAL_MODULE:= libgstapp
 
@@ -27,8 +27,8 @@ LOCAL_CFLAGS := -DHAVE_CONFIG_H        -DGSTREAMER_BUILT_FOR_ANDROID \
 #
 LOCAL_PRELINK_MODULE := false
 
-#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.10
-LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.10
+#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.11
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.11
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
index fa24286..cb613a5 100644 (file)
@@ -1,7 +1,7 @@
 LOCAL_PATH:= $(call my-dir)
 #----------------------------------------
 # include 
-gst_audio_COPY_HEADERS_TO := gstreamer-0.10/gst/audio
+gst_audio_COPY_HEADERS_TO := gstreamer-0.11/gst/audio
 gst_audio_COPY_HEADERS_BASE := \
        gst-libs/gst/audio/audio.h \
        gst-libs/gst/audio/gstaudioclock.h \
@@ -39,15 +39,15 @@ audio_LOCAL_SRC_FILES_BASE:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(audio_LOCAL_SRC_FILES_BASE))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0                     \
-       libgstinterfaces-0.10
+       libgstinterfaces-0.11
 
-LOCAL_MODULE:= libgstaudio-0.10
+LOCAL_MODULE:= libgstaudio-0.11
 
 LOCAL_CFLAGS := -DHAVE_CONFIG_H        -DGSTREAMER_BUILT_FOR_ANDROID \
        $(GST_PLUGINS_BASE_CFLAGS)
index 015f39c..059b295 100644 (file)
@@ -15,14 +15,14 @@ audioconvert_LOCAL_SRC_FILES:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(audioconvert_LOCAL_SRC_FILES))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstaudio-0.10        \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstaudio-0.11        \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0                     \
-    libgstpbutils-0.10
+    libgstpbutils-0.11
 
 LOCAL_MODULE:= libgstaudioconvert
 
@@ -33,8 +33,8 @@ LOCAL_CFLAGS := -DHAVE_CONFIG_H -DGSTREAMER_BUILT_FOR_ANDROID \
 #
 LOCAL_PRELINK_MODULE := false
 
-#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.10
-LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.10
+#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.11
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.11
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
index 2d20164..3a94fee 100644 (file)
@@ -11,13 +11,13 @@ decodebin_LOCAL_SRC_FILES_BASE:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(decodebin_LOCAL_SRC_FILES_BASE))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0                     \
-       libgstpbutils-0.10
+       libgstpbutils-0.11
 
 LOCAL_MODULE:= libgstdecodebin
 
@@ -28,8 +28,8 @@ LOCAL_CFLAGS := -DHAVE_CONFIG_H       -DGSTREAMER_BUILT_FOR_ANDROID \
 #
 LOCAL_PRELINK_MODULE := false
 
-#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.10
-LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.10
+#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.11
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.11
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
index 30f0ace..c9d32f2 100644 (file)
@@ -13,13 +13,13 @@ decodebin2_LOCAL_SRC_FILES_BASE:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(decodebin2_LOCAL_SRC_FILES_BASE))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0                     \
-       libgstpbutils-0.10
+       libgstpbutils-0.11
 
 LOCAL_MODULE:= libgstdecodebin2
 
@@ -30,8 +30,8 @@ LOCAL_CFLAGS := -DHAVE_CONFIG_H        \
 #
 LOCAL_PRELINK_MODULE := false
 
-#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.10
-LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.10
+#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.11
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.11
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
index 156bf28..801ad80 100644 (file)
@@ -12,13 +12,13 @@ gdp_LOCAL_SRC_FILES:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(gdp_LOCAL_SRC_FILES))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0                     \
-       libgstdataprotocol-0.10
+       libgstdataprotocol-0.11
 
 LOCAL_MODULE:= libgstgdp
 
@@ -29,8 +29,8 @@ LOCAL_CFLAGS := -DHAVE_CONFIG_H  -DGSTREAMER_BUILT_FOR_ANDROID \
 #
 LOCAL_PRELINK_MODULE := false
 
-#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.10
-LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.10
+#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.11
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.11
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
index 61564b3..4f43a82 100644 (file)
@@ -1,7 +1,7 @@
 LOCAL_PATH:= $(call my-dir)
 #----------------------------------------
 # include 
-gst_interfaces_COPY_HEADERS_TO := gstreamer-0.10/gst/interfaces
+gst_interfaces_COPY_HEADERS_TO := gstreamer-0.11/gst/interfaces
 gst_interfaces_COPY_HEADERS_BASE := \
        gst-libs/gst/interfaces/colorbalance.h \
        gst-libs/gst/interfaces/colorbalancechannel.h \
@@ -45,15 +45,14 @@ LOCAL_SRC_FILES:= $(addprefix ../,$(interfaces_LOCAL_SRC_FILES_BASE)) \
                                  $(addprefix ../android/,$(interfaces_LOCAL_SRC_FILES_ANDROID))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0
 
-LOCAL_MODULE:= libgstinterfaces-0.10
-
+LOCAL_MODULE:= libgstinterfaces-0.11
 
 LOCAL_CFLAGS := -DHAVE_CONFIG_H        -DGSTREAMER_BUILT_FOR_ANDROID \
        $(GST_PLUGINS_BASE_CFLAGS)
index fd904bd..8b217f9 100644 (file)
@@ -1,7 +1,7 @@
 LOCAL_PATH:= $(call my-dir)
 #----------------------------------------
 # include 
-gst_netbuffer_COPY_HEADERS_TO := gstreamer-0.10/gst/netbuffer
+gst_netbuffer_COPY_HEADERS_TO := gstreamer-0.11/gst/netbuffer
 gst_netbuffer_COPY_HEADERS := \
        ../gst-libs/gst/netbuffer/gstnetbuffer.h
 
@@ -15,14 +15,14 @@ netbuffer_LOCAL_SRC_FILES:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(netbuffer_LOCAL_SRC_FILES))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0
 
-LOCAL_MODULE:= libgstnetbuffer-0.10
+LOCAL_MODULE:= libgstnetbuffer-0.11
 
 LOCAL_CFLAGS := -DHAVE_CONFIG_H        -DGSTREAMER_BUILT_FOR_ANDROID \
        $(GST_PLUGINS_BASE_CFLAGS)
index a9aebac..52ca383 100644 (file)
@@ -3,7 +3,7 @@ include $(CLEAR_VARS)
 
 GST_PBUTILS_DIR := gst-libs/gst/pbutils/
 
-gst_pbutils_COPY_HEADERS_TO := gstreamer-0.10/gst/pbutils
+gst_pbutils_COPY_HEADERS_TO := gstreamer-0.11/gst/pbutils
 gst_pbutils_COPY_HEADERS_BASE := \
        gst-libs/gst/pbutils/descriptions.h \
        gst-libs/gst/pbutils/install-plugins.h \
@@ -45,15 +45,15 @@ $(BUILT_SOURCES):
 
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstvideo-0.10        \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstvideo-0.11        \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0                     
 
-LOCAL_MODULE:= libgstpbutils-0.10
+LOCAL_MODULE:= libgstpbutils-0.11
 LOCAL_CFLAGS := -DGSTREAMER_BUILT_FOR_ANDROID \
        $(GST_PLUGINS_BASE_CFLAGS)
 #
index e792429..b81bf9e 100644 (file)
@@ -19,15 +19,15 @@ playbin_LOCAL_SRC_FILES_BASE:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(playbin_LOCAL_SRC_FILES_BASE))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0                     \
-       libgstpbutils-0.10              \
-       libgstinterfaces-0.10   \
-       libgstvideo-0.10
+       libgstpbutils-0.11              \
+       libgstinterfaces-0.11   \
+       libgstvideo-0.11
 
 LOCAL_MODULE:= libgstplaybin
 
@@ -38,8 +38,8 @@ LOCAL_CFLAGS := -DHAVE_CONFIG_H        -DGSTREAMER_BUILT_FOR_ANDROID \
 #
 LOCAL_PRELINK_MODULE := false
 
-#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.10
-LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.10
+#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.11
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.11
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
index 6c5fcd4..29b9929 100644 (file)
@@ -12,13 +12,13 @@ LOCAL_SRC_FILES:= $(addprefix ../,$(queue2_LOCAL_SRC_FILES_BASE))
 
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0                     \
-       libgstpbutils-0.10
+       libgstpbutils-0.11
 
 LOCAL_MODULE:= libgstqueue2
 
@@ -29,7 +29,7 @@ LOCAL_CFLAGS := -DHAVE_CONFIG_H       \
 #
 LOCAL_PRELINK_MODULE := false
 
-#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.10
-LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.10
+#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.11
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.11
 
 include $(BUILD_SHARED_LIBRARY)
index 759bdad..958235b 100644 (file)
@@ -1,7 +1,7 @@
 LOCAL_PATH:= $(call my-dir)
 #----------------------------------------
 # include 
-gst_riffs_COPY_HEADERS_TO := gstreamer-0.10/gst/riff
+gst_riffs_COPY_HEADERS_TO := gstreamer-0.11/gst/riff
 gst_riffs_COPY_HEADERS := \
        ../gst-libs/gst/riff/riff-ids.h \
        ../gst-libs/gst/riff/riff-media.h \
@@ -19,17 +19,17 @@ riff_LOCAL_SRC_FILES:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(riff_LOCAL_SRC_FILES))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0                     \
-       libgsttag-0.10          \
-    libgstaudio-0.10     
+       libgsttag-0.11          \
+    libgstaudio-0.11     
 
 
-LOCAL_MODULE:= libgstriff-0.10
+LOCAL_MODULE:= libgstriff-0.11
 
 LOCAL_CFLAGS := -DHAVE_CONFIG_H         -DGSTREAMER_BUILT_FOR_ANDROID \
        $(GST_PLUGINS_BASE_CFLAGS)
index 7ad0071..f39f86c 100644 (file)
@@ -1,7 +1,7 @@
 LOCAL_PATH:= $(call my-dir)
 #----------------------------------------
 # include 
-gst_rtp_COPY_HEADERS_TO := gstreamer-0.10/gst/rtp
+gst_rtp_COPY_HEADERS_TO := gstreamer-0.11/gst/rtp
 gst_rtp_COPY_HEADERS := \
        ../gst-libs/gst/rtp/gstbasertpaudiopayload.h \
        ../gst-libs/gst/rtp/gstbasertpdepayload.h \
@@ -26,14 +26,14 @@ LOCAL_SRC_FILES:= $(addprefix ../,$(rtp_LOCAL_SRC_FILES))
 
 LOCAL_SHARED_LIBRARIES := \
        libdl                   \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0             
 
-LOCAL_MODULE:= libgstrtp-0.10
+LOCAL_MODULE:= libgstrtp-0.11
 LOCAL_CFLAGS := -DHAVE_CONFIG_H        -DGSTREAMER_BUILT_FOR_ANDROID \
        $(GST_PLUGINS_BASE_CFLAGS)
 #
index fdc07b9..4f61f4e 100644 (file)
@@ -1,7 +1,7 @@
 LOCAL_PATH:= $(call my-dir)
 #----------------------------------------
 # include 
-gst_rtsp_COPY_HEADERS_TO := gstreamer-0.10/gst/rtsp
+gst_rtsp_COPY_HEADERS_TO := gstreamer-0.11/gst/rtsp
 gst_rtsp_COPY_HEADERS_BASE := \
        gst-libs/gst/rtsp/gstrtspbase64.h \
        gst-libs/gst/rtsp/gstrtspdefs.h \
@@ -34,14 +34,14 @@ rtsp_LOCAL_SRC_FILES_BASE:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(rtsp_LOCAL_SRC_FILES_BASE))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0
 
-LOCAL_MODULE:= libgstrtsp-0.10
+LOCAL_MODULE:= libgstrtsp-0.11
 
 LOCAL_CFLAGS := -DHAVE_CONFIG_H -DINET_ADDRSTRLEN=16 -DGSTREAMER_BUILT_FOR_ANDROID \
        $(GST_PLUGINS_BASE_CFLAGS)
index b83002c..7d0e7e8 100644 (file)
@@ -1,7 +1,7 @@
 LOCAL_PATH:= $(call my-dir)
 #----------------------------------------
 # include 
-gst_sdp_COPY_HEADERS_TO := gstreamer-0.10/gst/sdp
+gst_sdp_COPY_HEADERS_TO := gstreamer-0.11/gst/sdp
 gst_sdp_COPY_HEADERS := \
        ../gst-libs/gst/sdp/gstsdp.h \
        ../gst-libs/gst/sdp/gstsdpmessage.h
@@ -16,14 +16,14 @@ sdp_LOCAL_SRC_FILES:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(sdp_LOCAL_SRC_FILES))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0
 
-LOCAL_MODULE:= libgstsdp-0.10
+LOCAL_MODULE:= libgstsdp-0.11
 LOCAL_CFLAGS := -DHAVE_CONFIG_H  -DGSTREAMER_BUILT_FOR_ANDROID \
        $(GST_PLUGINS_BASE_CFLAGS)
 #
index e4eaee6..7ca9081 100644 (file)
@@ -1,7 +1,7 @@
 LOCAL_PATH:= $(call my-dir)
 #----------------------------------------
 # include 
-gst_tag_COPY_HEADERS_TO := gstreamer-0.10/gst/tag
+gst_tag_COPY_HEADERS_TO := gstreamer-0.11/gst/tag
 gst_tag_COPY_HEADERS := \
        ../gst-libs/gst/tag/gsttagdemux.h \
        ../gst-libs/gst/tag/tag.h
@@ -22,15 +22,14 @@ tag_LOCAL_SRC_FILES:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(tag_LOCAL_SRC_FILES))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0
 
-LOCAL_MODULE:= libgsttag-0.10
-
+LOCAL_MODULE:= libgsttag-0.11
 
 LOCAL_CFLAGS := -DHAVE_CONFIG_H        -DGSTREAMER_BUILT_FOR_ANDROID \
        $(GST_PLUGINS_BASE_CFLAGS)
index 28f1dca..a4d6aa8 100644 (file)
@@ -18,13 +18,13 @@ tcp_LOCAL_SRC_FILES_BASE:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(tcp_LOCAL_SRC_FILES_BASE))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0                     \
-       libgstdataprotocol-0.10
+       libgstdataprotocol-0.11
 
 LOCAL_MODULE:= libgsttcp
 
@@ -35,8 +35,8 @@ LOCAL_CFLAGS := -DHAVE_CONFIG_H  -DGSTREAMER_BUILT_FOR_ANDROID \
 #
 LOCAL_PRELINK_MODULE := false
 
-#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.10
-LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.10
+#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.11
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.11
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
index 2650e2b..c1c267c 100644 (file)
@@ -10,9 +10,9 @@ typefindfunctions_LOCAL_SRC_FILES:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(typefindfunctions_LOCAL_SRC_FILES))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
-    libgstpbutils-0.10     \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
+    libgstpbutils-0.11     \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
@@ -27,8 +27,8 @@ LOCAL_CFLAGS := -DHAVE_CONFIG_H        -DGSTREAMER_BUILT_FOR_ANDROID \
 #
 LOCAL_PRELINK_MODULE := false
 
-#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.10
-LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.10
+#It's a gstreamer plugins, and it must be installed on ..../lib/gstreamer-0.11
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/gstreamer-0.11
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
index fdfb6a2..f92949a 100644 (file)
@@ -1,7 +1,7 @@
 LOCAL_PATH:= $(call my-dir)
 #----------------------------------------
 # include 
-gst_video_COPY_HEADERS_TO := gstreamer-0.10/gst/video
+gst_video_COPY_HEADERS_TO := gstreamer-0.11/gst/video
 gst_video_COPY_HEADERS_BASE := \
        gst-libs/gst/video/gstvideofilter.h \
        gst-libs/gst/video/gstvideosink.h \
@@ -24,14 +24,14 @@ video_LOCAL_SRC_FILES_BASE:= \
 LOCAL_SRC_FILES:= $(addprefix ../,$(video_LOCAL_SRC_FILES_BASE))
 
 LOCAL_SHARED_LIBRARIES := \
-    libgstreamer-0.10       \
-    libgstbase-0.10         \
+    libgstreamer-0.11       \
+    libgstbase-0.11         \
     libglib-2.0             \
     libgthread-2.0          \
     libgmodule-2.0          \
     libgobject-2.0
 
-LOCAL_MODULE:= libgstvideo-0.10
+LOCAL_MODULE:= libgstvideo-0.11
 
 LOCAL_CFLAGS := -DHAVE_CONFIG_H        -DGSTREAMER_BUILT_FOR_ANDROID \
        $(GST_PLUGINS_BASE_CFLAGS)
index 9614618..51e3982 100644 (file)
@@ -5,7 +5,7 @@ dnl please read gstreamer/docs/random/autotools before changing this file
 dnl initialize autoconf
 dnl releases only do -Wall, git and prerelease does -Werror too
 dnl use a three digit version number for releases, and four for git/prerelease
-AC_INIT(GStreamer Base Plug-ins, 0.10.34.1,
+AC_INIT(GStreamer Base Plug-ins, 0.11.0.1,
     http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer,
     gst-plugins-base)
 
@@ -40,7 +40,7 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],
 dnl our libraries and install dirs use major.minor as a version
 GST_MAJORMINOR=$PACKAGE_VERSION_MAJOR.$PACKAGE_VERSION_MINOR
 dnl we override it here if we need to for the release candidate of new series
-GST_MAJORMINOR=0.10
+GST_MAJORMINOR=0.11
 AC_SUBST(GST_MAJORMINOR)
 
 dnl CURRENT, REVISION, AGE
@@ -60,7 +60,7 @@ AC_LIBTOOL_WIN32_DLL
 AM_PROG_LIBTOOL
 
 dnl *** required versions of GStreamer stuff ***
-GST_REQ=0.10.34.1
+GST_REQ=0.11.0
 
 dnl *** autotools stuff ****
 
@@ -439,7 +439,7 @@ AG_GST_CHECK_PLUGIN(volume)
 
 dnl check for gstreamer core features (subsystems)
 dnl FIXME: this assumes srcdir == builddir for uninstalled setups
-GST_CONFIGPATH=`$PKG_CONFIG --variable=includedir gstreamer-0.10`"/gst/gstconfig.h"
+GST_CONFIGPATH=`$PKG_CONFIG --variable=includedir gstreamer-0.11`"/gst/gstconfig.h"
 AG_GST_PARSE_SUBSYSTEM_DISABLES($GST_CONFIGPATH)
 AM_CONDITIONAL(USE_XML, test $GST_DISABLE_XML != "1")
 
@@ -1063,7 +1063,7 @@ sed \
     -e "s/.* PACKAGE_STRING$/#define PACKAGE_STRING \"$PACKAGE_STRING\"/" \
     -e 's/.* PACKAGE_TARNAME$/#define PACKAGE_TARNAME "'$PACKAGE_TARNAME'"/' \
     -e 's/.* PACKAGE_VERSION$/#define PACKAGE_VERSION "'$PACKAGE_VERSION'"/' \
-    -e 's/.* PLUGINDIR$/#ifdef _DEBUG\n#  define PLUGINDIR PREFIX "\\\\debug\\\\lib\\\\gstreamer-0.10"\n#else\n#  define PLUGINDIR PREFIX "\\\\lib\\\\gstreamer-0.10"\n#endif/' \
+    -e 's/.* PLUGINDIR$/#ifdef _DEBUG\n#  define PLUGINDIR PREFIX "\\\\debug\\\\lib\\\\gstreamer-0.11"\n#else\n#  define PLUGINDIR PREFIX "\\\\lib\\\\gstreamer-0.11"\n#endif/' \
     -e 's/.* USE_BINARY_REGISTRY$/#define USE_BINARY_REGISTRY/' \
     -e 's/.* VERSION$/#define VERSION "'$VERSION'"/' \
     -e "s/.* DEFAULT_AUDIOSINK$/#define DEFAULT_AUDIOSINK \"directsoundsink\"/" \
index 89307df..d28dd63 100644 (file)
 GObject
-  GInputStream
-  GOutputStream
-  GstColorBalanceChannel
+  GInitiallyUnowned
+    GstObject
+      GstPad
+      GstPadTemplate
+      GstPluginFeature
+        GstElementFactory
+        GstTypeFindFactory
+        GstIndexFactory
+      GstElement
+        GstBin
+          GstPipeline
+            GstPlayBaseBin
+              GstPlayBin
+            GstPlayBin2
+          GstEncodeBin
+          GstDecodeBin
+          GstPlaySink
+          GstSubtitleOverlay
+          GstDecodeBin2
+          GstURIDecodeBin
+        GstVisual
+          GstVisualjess
+          GstVisualbumpscope
+          GstVisualcorona
+          GstVisualinfinite
+          GstVisualjakdaw
+          GstVisuallv_analyzer
+          GstVisuallv_scope
+          GstVisualoinksie
+        GstBaseSrc
+          GstGnomeVFSSrc
+          GstGioBaseSrc
+            GstGioSrc
+            GstGioStreamSrc
+          GstPushSrc
+            GstCddaBaseSrc
+              GstCdParanoiaSrc
+            GstBaseAudioSrc
+              GstAudioSrc
+                GstAlsaSrc
+            GstV4lElement
+              GstV4lSrc
+            GstVideoTestSrc
+            GstTCPClientSrc
+            GstTCPServerSrc
+          GstAppSrc
+          GstAudioTestSrc
+        GstBaseSink
+          GstGnomeVFSSink
+          GstGioBaseSink
+            GstGioSink
+            GstGioStreamSink
+          GstBaseAudioSink
+            GstAudioSink
+              GstAlsaSink
+          GstVideoSink
+            GstXvImageSink
+            GstXImageSink
+          GstAppSink
+          GstTCPClientSink
+          GstMultiFdSink
+            GstTCPServerSink
+        GstTheoraDec
+        GstTheoraEnc
+        GstTheoraParse
+        GstBaseTextOverlay
+          GstTextOverlay
+          GstTimeOverlay
+          GstClockOverlay
+        GstTextRender
+        GstOggDemux
+        GstOggMux
+        GstOgmParse
+          GstOgmAudioParse
+          GstOgmVideoParse
+          GstOgmTextParse
+        GstOggParse
+        GstOggAviParse
+        GstVorbisEnc
+        GstVorbisDec
+        GstVorbisParse
+          GstVorbisTag
+        GstAlsaMixerElement
+        GstSubParse
+        GstSsaParse
+        GstBaseTransform
+          GstAudioFilter
+            GstVolume
+          GstVideoFilter
+            GstVideoScale
+            GstFFMpegCsp
+          GstAudioResample
+          GstAudioConvert
+        GstGDPDepay
+        GstGDPPay
+        GstAudioRate
+        GstAdder
+        GstVideoRate
+        GstStreamSelector
+      GstBus
+      GstTask
+      GstTaskPool
+      GstClock
+        GstSystemClock
+          GstAudioClock
+      GstPlugin
+      GstRegistry
+      GstRingBuffer
+        GstAudioSrcRingBuffer
+        GstAudioSinkRingBuffer
   GstMixerTrack
-  GstObject
-    GstBus
-    GstClock
-      GstSystemClock
-        GstAudioClock
-    GstElement
-      GstAdder
-      GstAlsaMixerElement
-      GstAudioRate
-      GstBaseSink
-        GstAppSink
-        GstBaseAudioSink
-          GstAudioSink
-            GstAlsaSink
-        GstGioBaseSink
-          GstGioSink
-          GstGioStreamSink
-        GstGnomeVFSSink
-        GstMultiFdSink
-          GstTCPServerSink
-        GstTCPClientSink
-        GstVideoSink
-          GstXImageSink
-          GstXvImageSink
-      GstBaseSrc
-        GstAppSrc
-        GstAudioTestSrc
-        GstGioBaseSrc
-          GstGioSrc
-          GstGioStreamSrc
-        GstGnomeVFSSrc
-        GstPushSrc
-          GstBaseAudioSrc
-            GstAudioSrc
-              GstAlsaSrc
-          GstCddaBaseSrc
-            GstCdParanoiaSrc
-          GstTCPClientSrc
-          GstTCPServerSrc
-          GstV4lElement
-            GstV4lSrc
-          GstVideoTestSrc
-      GstBaseTransform
-        GstAudioConvert
-        GstAudioFilter
-          GstVolume
-        GstAudioResample
-        GstVideoFilter
-          GstFFMpegCsp
-          GstVideoScale
-      GstBin
-        GstDecodeBin
-        GstDecodeBin2
-        GstEncodeBin
-        GstPipeline
-          GstPlayBaseBin
-            GstPlayBin
-          GstPlayBin2
-        GstPlaySink
-        GstSubtitleOverlay
-        GstURIDecodeBin
-      GstGDPDepay
-      GstGDPPay
-      GstOggAviParse
-      GstOggDemux
-      GstOggMux
-      GstOggParse
-      GstOgmParse
-        GstOgmAudioParse
-        GstOgmTextParse
-        GstOgmVideoParse
-      GstSsaParse
-      GstStreamSelector
-      GstSubParse
-      GstTextOverlay
-        GstClockOverlay
-        GstTimeOverlay
-      GstTextRender
-      GstTheoraDec
-      GstTheoraEnc
-      GstTheoraParse
-      GstVideoRate
-      GstVisual
-        GstVisualbumpscope
-        GstVisualcorona
-        GstVisualgforce
-        GstVisualinfinite
-        GstVisualjakdaw
-        GstVisualjess
-        GstVisuallv_scope
-        GstVisualoinksie
-      GstVorbisDec
-      GstVorbisEnc
-      GstVorbisParse
-        GstVorbisTag
-    GstPad
-    GstPadTemplate
-    GstPlugin
-    GstPluginFeature
-      GstElementFactory
-      GstIndexFactory
-      GstTypeFindFactory
-    GstRegistry
-    GstRingBuffer
-      GstAudioSinkRingBuffer
-      GstAudioSrcRingBuffer
-    GstTask
-    GstTaskPool
-  GstSignalObject
   GstStreamInfo
-  GstTunerChannel
+  GstEncodingProfile
   GstTunerNorm
-  PangoContext
+  GstTunerChannel
+  GstColorBalanceChannel
   PangoFontMap
     PangoFcFontMap
       PangoCairoFcFontMap
+  PangoContext
+  GInputStream
+  GOutputStream
 GInterface
-  GFile
   GTypePlugin
   GstChildProxy
-  GstColorBalance
+  GstURIHandler
+  GstPreset
+  GstTagSetter
   GstImplementsInterface
   GstMixer
-  GstNavigation
-  GstPreset
   GstPropertyProbe
-  GstStreamVolume
-  GstTagSetter
-  GstTuner
-  GstURIHandler
+  GstNavigation
   GstXOverlay
+  GstColorBalance
+  GstTuner
+  GstStreamVolume
   PangoCairoFontMap
+  GFile
index 8f393f4..4b602b1 100644 (file)
@@ -1,32 +1,32 @@
-GstAlsaMixerElement GstImplementsInterface GstMixer GstPropertyProbe
-GstAlsaSink GstPropertyProbe
-GstAlsaSrc GstImplementsInterface GstMixer GstPropertyProbe
-GstAppSink GstURIHandler
-GstAppSrc GstURIHandler
 GstBin GstChildProxy
-GstCdParanoiaSrc GstURIHandler
-GstCddaBaseSrc GstURIHandler
-GstDecodeBin GstChildProxy
-GstDecodeBin2 GstChildProxy
-GstEncodeBin GstChildProxy
-GstGioSink GstURIHandler
-GstGioSrc GstURIHandler
-GstGnomeVFSSink GstURIHandler
-GstGnomeVFSSrc GstURIHandler
-GstOggMux GstPreset
 GstPipeline GstChildProxy
 GstPlayBaseBin GstChildProxy
 GstPlayBin GstChildProxy
 GstPlayBin2 GstChildProxy GstStreamVolume
+GstEncodeBin GstChildProxy
+GstDecodeBin GstChildProxy
 GstPlaySink GstChildProxy
 GstSubtitleOverlay GstChildProxy
-GstTheoraEnc GstPreset
+GstDecodeBin2 GstChildProxy
 GstURIDecodeBin GstChildProxy
+GstGnomeVFSSrc GstURIHandler
+GstGioSrc GstURIHandler
+GstCddaBaseSrc GstURIHandler
+GstCdParanoiaSrc GstURIHandler
+GstAlsaSrc GstImplementsInterface GstMixer GstPropertyProbe
 GstV4lElement GstImplementsInterface GstTuner GstXOverlay GstColorBalance GstPropertyProbe
 GstV4lSrc GstImplementsInterface GstTuner GstXOverlay GstColorBalance GstPropertyProbe
-GstVolume GstImplementsInterface GstMixer GstStreamVolume
+GstAppSrc GstURIHandler
+GstGnomeVFSSink GstURIHandler
+GstGioSink GstURIHandler
+GstAlsaSink GstPropertyProbe
+GstXvImageSink GstImplementsInterface GstNavigation GstXOverlay GstColorBalance GstPropertyProbe
+GstXImageSink GstImplementsInterface GstNavigation GstXOverlay
+GstAppSink GstURIHandler
+GstTheoraEnc GstPreset
+GstOggMux GstPreset
 GstVorbisEnc GstTagSetter GstPreset
 GstVorbisTag GstTagSetter
-GstXImageSink GstImplementsInterface GstNavigation GstXOverlay
-GstXvImageSink GstImplementsInterface GstNavigation GstXOverlay GstColorBalance GstPropertyProbe
+GstAlsaMixerElement GstImplementsInterface GstMixer GstPropertyProbe
+GstVolume GstImplementsInterface GstMixer GstStreamVolume
 PangoCairoFcFontMap PangoCairoFontMap
index d111b2e..176f319 100644 (file)
@@ -1,10 +1,10 @@
-GFile GObject
 GstChildProxy GstObject
-GstColorBalance GstImplementsInterface GstElement
+GstTagSetter GstElement
 GstImplementsInterface GstElement
 GstMixer GstImplementsInterface GstElement
-GstStreamVolume GObject
-GstTagSetter GstElement
-GstTuner GstImplementsInterface GstElement
 GstXOverlay GstImplementsInterface GstElement
+GstColorBalance GstImplementsInterface GstElement
+GstTuner GstImplementsInterface GstElement
+GstStreamVolume GObject
 PangoCairoFontMap PangoFontMap
+GFile GObject
index 83596a3..97d5f5e 100644 (file)
 #include "gstalsadeviceprobe.h"
 #include "gst/interfaces/propertyprobe.h"
 
+G_LOCK_DEFINE_STATIC (probe_lock);
+
 static const GList *
 gst_alsa_device_property_probe_get_properties (GstPropertyProbe * probe)
 {
   GObjectClass *klass = G_OBJECT_GET_CLASS (probe);
   static GList *list = NULL;
 
-  /* well, not perfect, but better than no locking at all.
-   * In the worst case we leak a list node, so who cares? */
-  GST_CLASS_LOCK (GST_OBJECT_CLASS (klass));
+  G_LOCK (probe_lock);
 
   if (!list) {
     GParamSpec *pspec;
@@ -43,7 +43,7 @@ gst_alsa_device_property_probe_get_properties (GstPropertyProbe * probe)
     list = g_list_append (NULL, pspec);
   }
 
-  GST_CLASS_UNLOCK (GST_OBJECT_CLASS (klass));
+  G_UNLOCK (probe_lock);
 
   return list;
 }
index ec80039..66e9135 100644 (file)
@@ -36,9 +36,10 @@ enum
 };
 
 static void gst_alsa_mixer_element_init_interfaces (GType type);
-
-GST_BOILERPLATE_FULL (GstAlsaMixerElement, gst_alsa_mixer_element,
-    GstElement, GST_TYPE_ELEMENT, gst_alsa_mixer_element_init_interfaces);
+#define gst_alsa_mixer_element_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstAlsaMixerElement, gst_alsa_mixer_element,
+    GST_TYPE_ELEMENT,
+    gst_alsa_mixer_element_init_interfaces (g_define_type_id));
 
 /* massive macro that takes care of all the GstMixer stuff */
 GST_IMPLEMENT_ALSA_MIXER_METHODS (GstAlsaMixerElement, gst_alsa_mixer_element);
@@ -91,15 +92,6 @@ gst_alsa_mixer_element_init_interfaces (GType type)
 }
 
 static void
-gst_alsa_mixer_element_base_init (gpointer klass)
-{
-  gst_element_class_set_details_simple (GST_ELEMENT_CLASS (klass),
-      "Alsa mixer", "Generic/Audio",
-      "Control sound input and output levels with ALSA",
-      "Leif Johnson <leif@ambient.2y.net>");
-}
-
-static void
 gst_alsa_mixer_element_class_init (GstAlsaMixerElementClass * klass)
 {
   GstElementClass *element_class;
@@ -122,6 +114,11 @@ gst_alsa_mixer_element_class_init (GstAlsaMixerElementClass * klass)
           "Human-readable name of the sound device",
           DEFAULT_PROP_DEVICE_NAME, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (element_class,
+      "Alsa mixer", "Generic/Audio",
+      "Control sound input and output levels with ALSA",
+      "Leif Johnson <leif@ambient.2y.net>");
+
   element_class->change_state =
       GST_DEBUG_FUNCPTR (gst_alsa_mixer_element_change_state);
 }
@@ -137,8 +134,7 @@ gst_alsa_mixer_element_finalize (GObject * obj)
 }
 
 static void
-gst_alsa_mixer_element_init (GstAlsaMixerElement * this,
-    GstAlsaMixerElementClass * klass)
+gst_alsa_mixer_element_init (GstAlsaMixerElement * this)
 {
   this->mixer = NULL;
   this->device = g_strdup (DEFAULT_PROP_DEVICE);
index a1fdb7f..dea8ef0 100644 (file)
@@ -170,7 +170,8 @@ gst_alsa_mixer_track_new (snd_mixer_elem_t * element,
   GST_LOG ("[%s] created new mixer track %p", name, track);
 
   /* This reflects the assumptions used for GstAlsaMixerTrack */
-  if (!(!!(flags & GST_MIXER_TRACK_OUTPUT) ^ !!(flags & GST_MIXER_TRACK_INPUT))) {
+  if (!(! !(flags & GST_MIXER_TRACK_OUTPUT) ^ ! !(flags &
+              GST_MIXER_TRACK_INPUT))) {
     GST_ERROR ("Mixer track must be either output or input!");
     g_return_val_if_reached (NULL);
   }
@@ -302,7 +303,7 @@ gst_alsa_mixer_track_update (GstAlsaMixerTrack * alsa_track)
     }
   }
 
-  if (!!(audible) != !(track->flags & GST_MIXER_TRACK_MUTE)) {
+  if (! !(audible) != !(track->flags & GST_MIXER_TRACK_MUTE)) {
     if (audible) {
       track->flags &= ~GST_MIXER_TRACK_MUTE;
 
index 2fb37df..23b6d8c 100644 (file)
@@ -69,9 +69,9 @@ enum
 };
 
 static void gst_alsasink_init_interfaces (GType type);
-
-GST_BOILERPLATE_FULL (GstAlsaSink, gst_alsasink, GstAudioSink,
-    GST_TYPE_AUDIO_SINK, gst_alsasink_init_interfaces);
+#define gst_alsasink_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstAlsaSink, gst_alsasink,
+    GST_TYPE_AUDIO_SINK, gst_alsasink_init_interfaces (g_define_type_id));
 
 static void gst_alsasink_finalise (GObject * object);
 static void gst_alsasink_set_property (GObject * object,
@@ -79,7 +79,7 @@ static void gst_alsasink_set_property (GObject * object,
 static void gst_alsasink_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 
-static GstCaps *gst_alsasink_getcaps (GstBaseSink * bsink);
+static GstCaps *gst_alsasink_getcaps (GstBaseSink * bsink, GstCaps * filter);
 
 static gboolean gst_alsasink_open (GstAudioSink * asink);
 static gboolean gst_alsasink_prepare (GstAudioSink * asink,
@@ -164,26 +164,15 @@ gst_alsasink_init_interfaces (GType type)
 }
 
 static void
-gst_alsasink_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class,
-      "Audio sink (ALSA)", "Sink/Audio",
-      "Output to a sound card via ALSA", "Wim Taymans <wim@fluendo.com>");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&alsasink_sink_factory));
-}
-
-static void
 gst_alsasink_class_init (GstAlsaSinkClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseSinkClass *gstbasesink_class;
   GstAudioSinkClass *gstaudiosink_class;
 
   gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
   gstbasesink_class = (GstBaseSinkClass *) klass;
   gstaudiosink_class = (GstAudioSinkClass *) klass;
 
@@ -193,6 +182,13 @@ gst_alsasink_class_init (GstAlsaSinkClass * klass)
   gobject_class->get_property = gst_alsasink_get_property;
   gobject_class->set_property = gst_alsasink_set_property;
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "Audio sink (ALSA)", "Sink/Audio",
+      "Output to a sound card via ALSA", "Wim Taymans <wim@fluendo.com>");
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&alsasink_sink_factory));
+
   gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_alsasink_getcaps);
 
   gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_alsasink_open);
@@ -271,7 +267,7 @@ gst_alsasink_get_property (GObject * object, guint prop_id,
 }
 
 static void
-gst_alsasink_init (GstAlsaSink * alsasink, GstAlsaSinkClass * g_class)
+gst_alsasink_init (GstAlsaSink * alsasink)
 {
   GST_DEBUG_OBJECT (alsasink, "initializing alsasink");
 
@@ -295,12 +291,12 @@ if ((err = call) < 0)           \
 } G_STMT_END;
 
 static GstCaps *
-gst_alsasink_getcaps (GstBaseSink * bsink)
+gst_alsasink_getcaps (GstBaseSink * bsink, GstCaps * filter)
 {
   GstElementClass *element_class;
   GstPadTemplate *pad_template;
   GstAlsaSink *sink = GST_ALSA_SINK (bsink);
-  GstCaps *caps;
+  GstCaps *caps, *templ_caps;
 
   if (sink->handle == NULL) {
     GST_DEBUG_OBJECT (sink, "device not open, using template caps");
@@ -309,15 +305,21 @@ gst_alsasink_getcaps (GstBaseSink * bsink)
 
   if (sink->cached_caps) {
     GST_LOG_OBJECT (sink, "Returning cached caps");
-    return gst_caps_ref (sink->cached_caps);
+    if (filter)
+      return gst_caps_intersect_full (filter, sink->cached_caps,
+          GST_CAPS_INTERSECT_FIRST);
+    else
+      return gst_caps_ref (sink->cached_caps);
   }
 
   element_class = GST_ELEMENT_GET_CLASS (sink);
   pad_template = gst_element_class_get_pad_template (element_class, "sink");
   g_return_val_if_fail (pad_template != NULL, NULL);
 
+  templ_caps = gst_pad_template_get_caps (pad_template);
   caps = gst_alsa_probe_supported_formats (GST_OBJECT (sink), sink->handle,
-      gst_pad_template_get_caps (pad_template));
+      templ_caps);
+  gst_caps_unref (templ_caps);
 
   if (caps) {
     sink->cached_caps = gst_caps_ref (caps);
@@ -325,7 +327,16 @@ gst_alsasink_getcaps (GstBaseSink * bsink)
 
   GST_INFO_OBJECT (sink, "returning caps %" GST_PTR_FORMAT, caps);
 
-  return caps;
+  if (filter) {
+    GstCaps *intersection;
+
+    intersection =
+        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (caps);
+    return intersection;
+  } else {
+    return caps;
+  }
 }
 
 static int
index cce52ea..14eb95d 100644 (file)
@@ -65,9 +65,9 @@ enum
 };
 
 static void gst_alsasrc_init_interfaces (GType type);
-
-GST_BOILERPLATE_FULL (GstAlsaSrc, gst_alsasrc, GstAudioSrc,
-    GST_TYPE_AUDIO_SRC, gst_alsasrc_init_interfaces);
+#define gst_alsasrc_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstAlsaSrc, gst_alsasrc,
+    GST_TYPE_AUDIO_SRC, gst_alsasrc_init_interfaces (g_define_type_id));
 
 GST_IMPLEMENT_ALSA_MIXER_METHODS (GstAlsaSrc, gst_alsasrc_mixer);
 
@@ -77,7 +77,7 @@ static void gst_alsasrc_set_property (GObject * object,
 static void gst_alsasrc_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 
-static GstCaps *gst_alsasrc_getcaps (GstBaseSrc * bsrc);
+static GstCaps *gst_alsasrc_getcaps (GstBaseSrc * bsrc, GstCaps * filter);
 
 static gboolean gst_alsasrc_open (GstAudioSrc * asrc);
 static gboolean gst_alsasrc_prepare (GstAudioSrc * asrc,
@@ -189,19 +189,6 @@ gst_alsasrc_init_interfaces (GType type)
 }
 
 static void
-gst_alsasrc_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class,
-      "Audio source (ALSA)", "Source/Audio",
-      "Read from a sound card via ALSA", "Wim Taymans <wim@fluendo.com>");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&alsasrc_src_factory));
-}
-
-static void
 gst_alsasrc_class_init (GstAlsaSrcClass * klass)
 {
   GObjectClass *gobject_class;
@@ -218,6 +205,13 @@ gst_alsasrc_class_init (GstAlsaSrcClass * klass)
   gobject_class->get_property = gst_alsasrc_get_property;
   gobject_class->set_property = gst_alsasrc_set_property;
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "Audio source (ALSA)", "Source/Audio",
+      "Read from a sound card via ALSA", "Wim Taymans <wim@fluendo.com>");
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&alsasrc_src_factory));
+
   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_alsasrc_change_state);
 
   gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_alsasrc_getcaps);
@@ -392,7 +386,7 @@ gst_alsasrc_create (GstBaseSrc * bsrc, guint64 offset, guint length,
 }
 
 static void
-gst_alsasrc_init (GstAlsaSrc * alsasrc, GstAlsaSrcClass * g_class)
+gst_alsasrc_init (GstAlsaSrc * alsasrc)
 {
   GST_DEBUG_OBJECT (alsasrc, "initializing");
 
@@ -411,12 +405,12 @@ if ((err = call) < 0)           \
 
 
 static GstCaps *
-gst_alsasrc_getcaps (GstBaseSrc * bsrc)
+gst_alsasrc_getcaps (GstBaseSrc * bsrc, GstCaps * filter)
 {
   GstElementClass *element_class;
   GstPadTemplate *pad_template;
   GstAlsaSrc *src;
-  GstCaps *caps;
+  GstCaps *caps, *templ_caps;
 
   src = GST_ALSA_SRC (bsrc);
 
@@ -427,15 +421,21 @@ gst_alsasrc_getcaps (GstBaseSrc * bsrc)
 
   if (src->cached_caps) {
     GST_LOG_OBJECT (src, "Returning cached caps");
-    return gst_caps_ref (src->cached_caps);
+    if (filter)
+      return gst_caps_intersect_full (filter, src->cached_caps,
+          GST_CAPS_INTERSECT_FIRST);
+    else
+      return gst_caps_ref (src->cached_caps);
   }
 
   element_class = GST_ELEMENT_GET_CLASS (src);
   pad_template = gst_element_class_get_pad_template (element_class, "src");
   g_return_val_if_fail (pad_template != NULL, NULL);
 
+  templ_caps = gst_pad_template_get_caps (pad_template);
   caps = gst_alsa_probe_supported_formats (GST_OBJECT (src), src->handle,
-      gst_pad_template_get_caps (pad_template));
+      templ_caps);
+  gst_caps_unref (templ_caps);
 
   if (caps) {
     src->cached_caps = gst_caps_ref (caps);
@@ -443,7 +443,16 @@ gst_alsasrc_getcaps (GstBaseSrc * bsrc)
 
   GST_INFO_OBJECT (src, "returning caps %" GST_PTR_FORMAT, caps);
 
-  return caps;
+  if (filter) {
+    GstCaps *intersection;
+
+    intersection =
+        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (caps);
+    return intersection;
+  } else {
+    return caps;
+  }
 }
 
 static int
index 864ebc7..200f589 100644 (file)
@@ -56,8 +56,8 @@ enum
 GST_DEBUG_CATEGORY_STATIC (gst_cd_paranoia_src_debug);
 #define GST_CAT_DEFAULT gst_cd_paranoia_src_debug
 
-GST_BOILERPLATE (GstCdParanoiaSrc, gst_cd_paranoia_src, GstCddaBaseSrc,
-    GST_TYPE_CDDA_BASE_SRC);
+#define gst_cd_paranoia_src_parent_class parent_class
+G_DEFINE_TYPE (GstCdParanoiaSrc, gst_cd_paranoia_src, GST_TYPE_CDDA_BASE_SRC);
 
 static void gst_cd_paranoia_src_finalize (GObject * obj);
 static void gst_cd_paranoia_src_get_property (GObject * object, guint prop_id,
@@ -103,18 +103,7 @@ gst_cd_paranoia_mode_get_type (void)
 }
 
 static void
-gst_cd_paranoia_src_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class,
-      "CD Audio (cdda) Source, Paranoia IV", "Source/File",
-      "Read audio from CD in paranoid mode",
-      "Erik Walthinsen <omega@cse.ogi.edu>, Wim Taymans <wim@fluendo.com>");
-}
-
-static void
-gst_cd_paranoia_src_init (GstCdParanoiaSrc * src, GstCdParanoiaSrcClass * klass)
+gst_cd_paranoia_src_init (GstCdParanoiaSrc * src)
 {
   src->d = NULL;
   src->p = NULL;
@@ -131,12 +120,18 @@ static void
 gst_cd_paranoia_src_class_init (GstCdParanoiaSrcClass * klass)
 {
   GstCddaBaseSrcClass *cddabasesrc_class = GST_CDDA_BASE_SRC_CLASS (klass);
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
   gobject_class->set_property = gst_cd_paranoia_src_set_property;
   gobject_class->get_property = gst_cd_paranoia_src_get_property;
   gobject_class->finalize = gst_cd_paranoia_src_finalize;
 
+  gst_element_class_set_details_simple (element_class,
+      "CD Audio (cdda) Source, Paranoia IV", "Source/File",
+      "Read audio from CD in paranoid mode",
+      "Erik Walthinsen <omega@cse.ogi.edu>, Wim Taymans <wim@fluendo.com>");
+
   cddabasesrc_class->open = gst_cd_paranoia_src_open;
   cddabasesrc_class->close = gst_cd_paranoia_src_close;
   cddabasesrc_class->read_sector = gst_cd_paranoia_src_read_sector;
@@ -400,7 +395,7 @@ gst_cd_paranoia_src_read_sector (GstCddaBaseSrc * cddabasesrc, gint sector)
     goto read_failed;
 
   buf = gst_buffer_new_and_alloc (CD_FRAMESIZE_RAW);
-  memcpy (GST_BUFFER_DATA (buf), cdda_buf, CD_FRAMESIZE_RAW);
+  gst_buffer_fill (buf, 0, cdda_buf, CD_FRAMESIZE_RAW);
 
   /* cdda base class will take care of timestamping etc. */
   ++src->next_sector;
index 40a64eb..6f90805 100644 (file)
@@ -33,8 +33,8 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS_ANY);
 
-GST_BOILERPLATE (GstGioBaseSink, gst_gio_base_sink, GstBaseSink,
-    GST_TYPE_BASE_SINK);
+#define gst_gio_base_sink_parent_class parent_class
+G_DEFINE_TYPE (GstGioBaseSink, gst_gio_base_sink, GST_TYPE_BASE_SINK);
 
 static void gst_gio_base_sink_finalize (GObject * object);
 static gboolean gst_gio_base_sink_start (GstBaseSink * base_sink);
@@ -48,25 +48,20 @@ static GstFlowReturn gst_gio_base_sink_render (GstBaseSink * base_sink,
 static gboolean gst_gio_base_sink_query (GstPad * pad, GstQuery * query);
 
 static void
-gst_gio_base_sink_base_init (gpointer gclass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
-  GST_DEBUG_CATEGORY_INIT (gst_gio_base_sink_debug, "gio_base_sink", 0,
-      "GIO base sink");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_factory));
-}
-
-static void
 gst_gio_base_sink_class_init (GstGioBaseSinkClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstElementClass *gstelement_class = (GstElementClass *) klass;
   GstBaseSinkClass *gstbasesink_class = (GstBaseSinkClass *) klass;
 
+  GST_DEBUG_CATEGORY_INIT (gst_gio_base_sink_debug, "gio_base_sink", 0,
+      "GIO base sink");
+
   gobject_class->finalize = gst_gio_base_sink_finalize;
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sink_factory));
+
   gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_gio_base_sink_start);
   gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_gio_base_sink_stop);
   gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_gio_base_sink_unlock);
@@ -77,7 +72,7 @@ gst_gio_base_sink_class_init (GstGioBaseSinkClass * klass)
 }
 
 static void
-gst_gio_base_sink_init (GstGioBaseSink * sink, GstGioBaseSinkClass * gclass)
+gst_gio_base_sink_init (GstGioBaseSink * sink)
 {
   gst_pad_set_query_function (GST_BASE_SINK_PAD (sink),
       GST_DEBUG_FUNCPTR (gst_gio_base_sink_query));
@@ -213,25 +208,23 @@ gst_gio_base_sink_event (GstBaseSink * base_sink, GstEvent * event)
     return TRUE;
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
       if (G_IS_OUTPUT_STREAM (sink->stream)) {
-        GstFormat format;
-        gint64 offset;
+        const GstSegment *segment;
 
-        gst_event_parse_new_segment (event, NULL, NULL, &format, &offset, NULL,
-            NULL);
+        gst_event_parse_segment (event, &segment);
 
-        if (format != GST_FORMAT_BYTES) {
-          GST_WARNING_OBJECT (sink, "ignored NEWSEGMENT event in %s format",
-              gst_format_get_name (format));
+        if (segment->format != GST_FORMAT_BYTES) {
+          GST_WARNING_OBJECT (sink, "ignored SEGMENT event in %s format",
+              gst_format_get_name (segment->format));
           break;
         }
 
         if (GST_GIO_STREAM_IS_SEEKABLE (sink->stream)) {
-          ret = gst_gio_seek (sink, G_SEEKABLE (sink->stream), offset,
+          ret = gst_gio_seek (sink, G_SEEKABLE (sink->stream), segment->start,
               sink->cancel);
           if (ret == GST_FLOW_OK)
-            sink->position = offset;
+            sink->position = segment->start;
         } else {
           ret = GST_FLOW_NOT_SUPPORTED;
         }
@@ -267,26 +260,32 @@ gst_gio_base_sink_render (GstBaseSink * base_sink, GstBuffer * buffer)
 {
   GstGioBaseSink *sink = GST_GIO_BASE_SINK (base_sink);
   gssize written;
+  guint8 *data;
+  gsize size;
   gboolean success;
   GError *err = NULL;
 
   g_return_val_if_fail (G_IS_OUTPUT_STREAM (sink->stream), GST_FLOW_ERROR);
 
-  GST_LOG_OBJECT (sink, "writing %u bytes to offset %" G_GUINT64_FORMAT,
-      GST_BUFFER_SIZE (buffer), sink->position);
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+
+  GST_LOG_OBJECT (sink,
+      "writing %" G_GSIZE_FORMAT " bytes to offset %" G_GUINT64_FORMAT, size,
+      sink->position);
 
-  written = g_output_stream_write (sink->stream,
-      GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), sink->cancel, &err);
+  written =
+      g_output_stream_write (sink->stream, data, size, sink->cancel, &err);
+  gst_buffer_unmap (buffer, data, size);
 
   success = (written >= 0);
 
-  if (G_UNLIKELY (success && written < GST_BUFFER_SIZE (buffer))) {
+  if (G_UNLIKELY (success && written < size)) {
     /* FIXME: Can this happen?  Should we handle it gracefully?  gnomevfssink
      * doesn't... */
     GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
         ("Could not write to stream: (short write, only %"
-            G_GSSIZE_FORMAT " bytes of %d bytes written)",
-            written, GST_BUFFER_SIZE (buffer)));
+            G_GSSIZE_FORMAT " bytes of %" G_GSIZE_FORMAT " bytes written)",
+            written, size));
     return GST_FLOW_ERROR;
   }
 
index 133e12c..a31c054 100644 (file)
@@ -35,8 +35,8 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS_ANY);
 
-GST_BOILERPLATE (GstGioBaseSrc, gst_gio_base_src, GstBaseSrc,
-    GST_TYPE_BASE_SRC);
+#define gst_gio_base_src_parent_class parent_class
+G_DEFINE_TYPE (GstGioBaseSrc, gst_gio_base_src, GST_TYPE_BASE_SRC);
 
 static void gst_gio_base_src_finalize (GObject * object);
 
@@ -54,25 +54,20 @@ static gboolean gst_gio_base_src_query (GstBaseSrc * base_src,
     GstQuery * query);
 
 static void
-gst_gio_base_src_base_init (gpointer gclass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
-  GST_DEBUG_CATEGORY_INIT (gst_gio_base_src_debug, "gio_base_src", 0,
-      "GIO base source");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_factory));
-}
-
-static void
 gst_gio_base_src_class_init (GstGioBaseSrcClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstElementClass *gstelement_class = (GstElementClass *) klass;
   GstBaseSrcClass *gstbasesrc_class = (GstBaseSrcClass *) klass;
 
+  GST_DEBUG_CATEGORY_INIT (gst_gio_base_src_debug, "gio_base_src", 0,
+      "GIO base source");
+
   gobject_class->finalize = gst_gio_base_src_finalize;
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&src_factory));
+
   gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_gio_base_src_start);
   gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_gio_base_src_stop);
   gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_gio_base_src_get_size);
@@ -88,7 +83,7 @@ gst_gio_base_src_class_init (GstGioBaseSrcClass * klass)
 }
 
 static void
-gst_gio_base_src_init (GstGioBaseSrc * src, GstGioBaseSrcClass * gclass)
+gst_gio_base_src_init (GstGioBaseSrc * src)
 {
   src->cancel = g_cancellable_new ();
 }
@@ -327,14 +322,14 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
     GST_DEBUG_OBJECT (src, "Creating subbuffer from cached buffer: offset %"
         G_GUINT64_FORMAT " length %u", offset, size);
 
-    buf = gst_buffer_create_sub (src->cache,
+    buf = gst_buffer_copy_region (src->cache, GST_BUFFER_COPY_ALL,
         offset - GST_BUFFER_OFFSET (src->cache), size);
 
     GST_BUFFER_OFFSET (buf) = offset;
     GST_BUFFER_OFFSET_END (buf) = offset + size;
-    GST_BUFFER_SIZE (buf) = size;
   } else {
     guint cachesize = MAX (4096, size);
+    guint8 *bdata;
     gssize read, res;
     gboolean success, eos;
     GError *err = NULL;
@@ -357,7 +352,7 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
         return ret;
     }
 
-    src->cache = gst_buffer_try_new_and_alloc (cachesize);
+    src->cache = gst_buffer_new_and_alloc (cachesize);
     if (G_UNLIKELY (src->cache == NULL)) {
       GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", cachesize);
       return GST_FLOW_ERROR;
@@ -371,13 +366,14 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
      * supports reads up to 64k. So we loop here until we get at
      * at least the requested amount of bytes or a read returns
      * nothing. */
+    bdata = gst_buffer_map (src->cache, NULL, NULL, GST_MAP_WRITE);
     read = 0;
     while (size - read > 0 && (res =
             g_input_stream_read (G_INPUT_STREAM (src->stream),
-                GST_BUFFER_DATA (src->cache) + read, cachesize - read,
-                src->cancel, &err)) > 0) {
+                bdata + read, cachesize - read, src->cancel, &err)) > 0) {
       read += res;
     }
+    gst_buffer_unmap (src->cache, bdata, read);
 
     success = (read >= 0);
     eos = (cachesize > 0 && read == 0);
@@ -390,7 +386,6 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
 
     if (success && !eos) {
       src->position += read;
-      GST_BUFFER_SIZE (src->cache) = read;
 
       GST_BUFFER_OFFSET (src->cache) = offset;
       GST_BUFFER_OFFSET_END (src->cache) = offset + read;
@@ -400,11 +395,12 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
           "cached buffer: offset %" G_GUINT64_FORMAT " length %u", offset,
           size);
 
-      buf = gst_buffer_create_sub (src->cache, 0, MIN (size, read));
+      buf =
+          gst_buffer_copy_region (src->cache, GST_BUFFER_COPY_ALL, 0, MIN (size,
+              read));
 
       GST_BUFFER_OFFSET (buf) = offset;
       GST_BUFFER_OFFSET_END (buf) = offset + MIN (size, read);
-      GST_BUFFER_SIZE (buf) = MIN (size, read);
     } else {
       GST_DEBUG_OBJECT (src, "Read not successful");
       gst_buffer_unref (src->cache);
index 69e05e5..fe7a23f 100644 (file)
@@ -92,8 +92,9 @@ enum
   PROP_FILE
 };
 
-GST_BOILERPLATE_FULL (GstGioSink, gst_gio_sink, GstGioBaseSink,
-    GST_TYPE_GIO_BASE_SINK, gst_gio_uri_handler_do_init);
+#define gst_gio_sink_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstGioSink, gst_gio_sink, GST_TYPE_GIO_BASE_SINK,
+    gst_gio_uri_handler_do_init (g_define_type_id));
 
 static void gst_gio_sink_finalize (GObject * object);
 static void gst_gio_sink_set_property (GObject * object, guint prop_id,
@@ -103,25 +104,14 @@ static void gst_gio_sink_get_property (GObject * object, guint prop_id,
 static GOutputStream *gst_gio_sink_get_stream (GstGioBaseSink * base_sink);
 
 static void
-gst_gio_sink_base_init (gpointer gclass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
-  GST_DEBUG_CATEGORY_INIT (gst_gio_sink_debug, "gio_sink", 0, "GIO sink");
-
-  gst_element_class_set_details_simple (element_class, "GIO sink",
-      "Sink/File",
-      "Write to any GIO-supported location",
-      "Ren\xc3\xa9 Stadler <mail@renestadler.de>, "
-      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
-
-static void
 gst_gio_sink_class_init (GstGioSinkClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstElementClass *gstelement_class = (GstElementClass *) klass;
   GstGioBaseSinkClass *gstgiobasesink_class = (GstGioBaseSinkClass *) klass;
 
+  GST_DEBUG_CATEGORY_INIT (gst_gio_sink_debug, "gio_sink", 0, "GIO sink");
+
   gobject_class->finalize = gst_gio_sink_finalize;
   gobject_class->set_property = gst_gio_sink_set_property;
   gobject_class->get_property = gst_gio_sink_get_property;
@@ -141,13 +131,19 @@ gst_gio_sink_class_init (GstGioSinkClass * klass)
       g_param_spec_object ("file", "File", "GFile to write to",
           G_TYPE_FILE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (gstelement_class, "GIO sink",
+      "Sink/File",
+      "Write to any GIO-supported location",
+      "Ren\xc3\xa9 Stadler <mail@renestadler.de>, "
+      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
+
   gstgiobasesink_class->get_stream =
       GST_DEBUG_FUNCPTR (gst_gio_sink_get_stream);
   gstgiobasesink_class->close_on_stop = TRUE;
 }
 
 static void
-gst_gio_sink_init (GstGioSink * sink, GstGioSinkClass * gclass)
+gst_gio_sink_init (GstGioSink * sink)
 {
 }
 
index 5fd810e..62e8c2b 100644 (file)
@@ -83,8 +83,9 @@ enum
   PROP_FILE
 };
 
-GST_BOILERPLATE_FULL (GstGioSrc, gst_gio_src, GstGioBaseSrc,
-    GST_TYPE_GIO_BASE_SRC, gst_gio_uri_handler_do_init);
+#define gst_gio_src_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstGioSrc, gst_gio_src,
+    GST_TYPE_GIO_BASE_SRC, gst_gio_uri_handler_do_init (g_define_type_id));
 
 static void gst_gio_src_finalize (GObject * object);
 
@@ -98,26 +99,15 @@ static GInputStream *gst_gio_src_get_stream (GstGioBaseSrc * bsrc);
 static gboolean gst_gio_src_check_get_range (GstBaseSrc * base_src);
 
 static void
-gst_gio_src_base_init (gpointer gclass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
-  GST_DEBUG_CATEGORY_INIT (gst_gio_src_debug, "gio_src", 0, "GIO source");
-
-  gst_element_class_set_details_simple (element_class, "GIO source",
-      "Source/File",
-      "Read from any GIO-supported location",
-      "Ren\xc3\xa9 Stadler <mail@renestadler.de>, "
-      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
-
-static void
 gst_gio_src_class_init (GstGioSrcClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstElementClass *gstelement_class = (GstElementClass *) klass;
   GstBaseSrcClass *gstbasesrc_class = (GstBaseSrcClass *) klass;
   GstGioBaseSrcClass *gstgiobasesrc_class = (GstGioBaseSrcClass *) klass;
 
+  GST_DEBUG_CATEGORY_INIT (gst_gio_src_debug, "gio_src", 0, "GIO source");
+
   gobject_class->finalize = gst_gio_src_finalize;
   gobject_class->set_property = gst_gio_src_set_property;
   gobject_class->get_property = gst_gio_src_get_property;
@@ -137,6 +127,12 @@ gst_gio_src_class_init (GstGioSrcClass * klass)
       g_param_spec_object ("file", "File", "GFile to read from",
           G_TYPE_FILE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (gstelement_class, "GIO source",
+      "Source/File",
+      "Read from any GIO-supported location",
+      "Ren\xc3\xa9 Stadler <mail@renestadler.de>, "
+      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
+
   gstbasesrc_class->check_get_range =
       GST_DEBUG_FUNCPTR (gst_gio_src_check_get_range);
 
@@ -145,7 +141,7 @@ gst_gio_src_class_init (GstGioSrcClass * klass)
 }
 
 static void
-gst_gio_src_init (GstGioSrc * src, GstGioSrcClass * gclass)
+gst_gio_src_init (GstGioSrc * src)
 {
 }
 
index 02dac71..a76a1e2 100644 (file)
@@ -83,8 +83,8 @@ enum
   PROP_STREAM
 };
 
-GST_BOILERPLATE (GstGioStreamSink, gst_gio_stream_sink, GstGioBaseSink,
-    GST_TYPE_GIO_BASE_SINK);
+#define gst_gio_stream_sink_parent_class parent_class
+G_DEFINE_TYPE (GstGioStreamSink, gst_gio_stream_sink, GST_TYPE_GIO_BASE_SINK);
 
 static void gst_gio_stream_sink_finalize (GObject * object);
 static void gst_gio_stream_sink_set_property (GObject * object, guint prop_id,
@@ -94,25 +94,15 @@ static void gst_gio_stream_sink_get_property (GObject * object, guint prop_id,
 static GOutputStream *gst_gio_stream_sink_get_stream (GstGioBaseSink * bsink);
 
 static void
-gst_gio_stream_sink_base_init (gpointer gclass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
-  GST_DEBUG_CATEGORY_INIT (gst_gio_stream_sink_debug, "gio_stream_sink", 0,
-      "GIO stream sink");
-
-  gst_element_class_set_details_simple (element_class, "GIO stream sink",
-      "Sink",
-      "Write to any GIO stream",
-      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
-
-static void
 gst_gio_stream_sink_class_init (GstGioStreamSinkClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstElementClass *gstelement_class = (GstElementClass *) klass;
   GstGioBaseSinkClass *ggbsink_class = (GstGioBaseSinkClass *) klass;
 
+  GST_DEBUG_CATEGORY_INIT (gst_gio_stream_sink_debug, "gio_stream_sink", 0,
+      "GIO stream sink");
+
   gobject_class->finalize = gst_gio_stream_sink_finalize;
   gobject_class->set_property = gst_gio_stream_sink_set_property;
   gobject_class->get_property = gst_gio_stream_sink_get_property;
@@ -121,13 +111,17 @@ gst_gio_stream_sink_class_init (GstGioStreamSinkClass * klass)
       g_param_spec_object ("stream", "Stream", "Stream to write to",
           G_TYPE_OUTPUT_STREAM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (gstelement_class, "GIO stream sink",
+      "Sink",
+      "Write to any GIO stream",
+      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
+
   ggbsink_class->get_stream =
       GST_DEBUG_FUNCPTR (gst_gio_stream_sink_get_stream);
 }
 
 static void
-gst_gio_stream_sink_init (GstGioStreamSink * sink,
-    GstGioStreamSinkClass * gclass)
+gst_gio_stream_sink_init (GstGioStreamSink * sink)
 {
 }
 
index bd6c686..600f347 100644 (file)
@@ -77,8 +77,8 @@ enum
   PROP_STREAM
 };
 
-GST_BOILERPLATE (GstGioStreamSrc, gst_gio_stream_src, GstGioBaseSrc,
-    GST_TYPE_GIO_BASE_SRC);
+#define gst_gio_stream_src_parent_class parent_class
+G_DEFINE_TYPE (GstGioStreamSrc, gst_gio_stream_src, GST_TYPE_GIO_BASE_SRC);
 
 static void gst_gio_stream_src_finalize (GObject * object);
 static void gst_gio_stream_src_set_property (GObject * object, guint prop_id,
@@ -88,25 +88,15 @@ static void gst_gio_stream_src_get_property (GObject * object, guint prop_id,
 static GInputStream *gst_gio_stream_src_get_stream (GstGioBaseSrc * bsrc);
 
 static void
-gst_gio_stream_src_base_init (gpointer gclass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
-  GST_DEBUG_CATEGORY_INIT (gst_gio_stream_src_debug, "gio_stream_src", 0,
-      "GIO source");
-
-  gst_element_class_set_details_simple (element_class, "GIO stream source",
-      "Source",
-      "Read from any GIO stream",
-      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
-
-static void
 gst_gio_stream_src_class_init (GstGioStreamSrcClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstElementClass *gstelement_class = (GstElementClass *) klass;
   GstGioBaseSrcClass *gstgiobasesrc_class = (GstGioBaseSrcClass *) klass;
 
+  GST_DEBUG_CATEGORY_INIT (gst_gio_stream_src_debug, "gio_stream_src", 0,
+      "GIO source");
+
   gobject_class->finalize = gst_gio_stream_src_finalize;
   gobject_class->set_property = gst_gio_stream_src_set_property;
   gobject_class->get_property = gst_gio_stream_src_get_property;
@@ -115,12 +105,17 @@ gst_gio_stream_src_class_init (GstGioStreamSrcClass * klass)
       g_param_spec_object ("stream", "Stream", "Stream to read from",
           G_TYPE_INPUT_STREAM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (gstelement_class, "GIO stream source",
+      "Source",
+      "Read from any GIO stream",
+      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
+
   gstgiobasesrc_class->get_stream =
       GST_DEBUG_FUNCPTR (gst_gio_stream_src_get_stream);
 }
 
 static void
-gst_gio_stream_src_init (GstGioStreamSrc * src, GstGioStreamSrcClass * gclass)
+gst_gio_stream_src_init (GstGioStreamSrc * src)
 {
 }
 
index 1a5f31f..941b937 100644 (file)
@@ -123,21 +123,9 @@ gst_gnome_vfs_sink_do_init (GType type)
       "Gnome VFS sink element");
 }
 
-GST_BOILERPLATE_FULL (GstGnomeVFSSink, gst_gnome_vfs_sink, GstBaseSink,
-    GST_TYPE_BASE_SINK, gst_gnome_vfs_sink_do_init);
-
-static void
-gst_gnome_vfs_sink_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sinktemplate));
-
-  gst_element_class_set_details_simple (element_class,
-      "GnomeVFS Sink", "Sink/File",
-      "Write a stream to a GnomeVFS URI", "Bastien Nocera <hadess@hadess.net>");
-}
+#define gst_gnome_vfs_sink_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstGnomeVFSSink, gst_gnome_vfs_sink,
+    GST_TYPE_BASE_SINK, gst_gnome_vfs_sink_do_init (g_define_type_id));
 
 static gboolean
 _gst_boolean_allow_overwrite_accumulator (GSignalInvocationHint * ihint,
@@ -157,9 +145,11 @@ static void
 gst_gnome_vfs_sink_class_init (GstGnomeVFSSinkClass * klass)
 {
   GstBaseSinkClass *basesink_class;
+  GstElementClass *gstelement_class;
   GObjectClass *gobject_class;
 
   gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
   basesink_class = (GstBaseSinkClass *) klass;
 
   gobject_class->set_property = gst_gnome_vfs_sink_set_property;
@@ -195,6 +185,13 @@ gst_gnome_vfs_sink_class_init (GstGnomeVFSSinkClass * klass)
       _gst_boolean_allow_overwrite_accumulator, NULL,
       gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, GST_TYPE_GNOME_VFS_URI);
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+
+  gst_element_class_set_details_simple (gstelement_class,
+      "GnomeVFS Sink", "Sink/File",
+      "Write a stream to a GnomeVFS URI", "Bastien Nocera <hadess@hadess.net>");
+
   basesink_class->stop = GST_DEBUG_FUNCPTR (gst_gnome_vfs_sink_stop);
   basesink_class->start = GST_DEBUG_FUNCPTR (gst_gnome_vfs_sink_start);
   basesink_class->event = GST_DEBUG_FUNCPTR (gst_gnome_vfs_sink_handle_event);
@@ -221,7 +218,7 @@ gst_gnome_vfs_sink_finalize (GObject * obj)
 }
 
 static void
-gst_gnome_vfs_sink_init (GstGnomeVFSSink * sink, GstGnomeVFSSinkClass * klass)
+gst_gnome_vfs_sink_init (GstGnomeVFSSink * sink)
 {
   gst_pad_set_query_function (GST_BASE_SINK_PAD (sink),
       GST_DEBUG_FUNCPTR (gst_gnome_vfs_sink_query));
@@ -443,29 +440,29 @@ gst_gnome_vfs_sink_handle_event (GstBaseSink * basesink, GstEvent * event)
   GST_DEBUG_OBJECT (sink, "processing %s event", GST_EVENT_TYPE_NAME (event));
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_NEWSEGMENT:{
+    case GST_EVENT_SEGMENT:{
       GnomeVFSResult res;
-      GstFormat format;
-      gint64 offset;
+      const GstSegment *segment;
 
-      gst_event_parse_new_segment (event, NULL, NULL, &format, &offset,
-          NULL, NULL);
+      gst_event_parse_segment (event, &segment);
 
-      if (format != GST_FORMAT_BYTES) {
+      if (segment->format != GST_FORMAT_BYTES) {
         GST_WARNING_OBJECT (sink, "ignored NEWSEGMENT event in %s format",
-            gst_format_get_name (format));
+            gst_format_get_name (segment->format));
         break;
       }
 
-      GST_LOG_OBJECT (sink, "seeking to offset %" G_GINT64_FORMAT, offset);
-      res = gnome_vfs_seek (sink->handle, GNOME_VFS_SEEK_START, offset);
+      GST_LOG_OBJECT (sink, "seeking to offset %" G_GINT64_FORMAT,
+          segment->start);
+      res = gnome_vfs_seek (sink->handle, GNOME_VFS_SEEK_START, segment->start);
 
       if (res != GNOME_VFS_OK) {
         GST_ERROR_OBJECT (sink, "Failed to seek to offset %"
-            G_GINT64_FORMAT ": %s", offset, gnome_vfs_result_to_string (res));
+            G_GINT64_FORMAT ": %s", segment->start,
+            gnome_vfs_result_to_string (res));
         ret = FALSE;
       } else {
-        sink->current_pos = offset;
+        sink->current_pos = segment->start;
       }
 
       break;
@@ -523,6 +520,8 @@ gst_gnome_vfs_sink_render (GstBaseSink * basesink, GstBuffer * buf)
   GstGnomeVFSSink *sink;
   GnomeVFSResult result;
   GstFlowReturn ret;
+  guint8 *data;
+  gsize size;
 
   sink = GST_GNOME_VFS_SINK (basesink);
 
@@ -531,22 +530,22 @@ gst_gnome_vfs_sink_render (GstBaseSink * basesink, GstBuffer * buf)
     sink->current_pos = cur_pos;
   }
 
-  result = gnome_vfs_write (sink->handle, GST_BUFFER_DATA (buf),
-      GST_BUFFER_SIZE (buf), &written);
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  result = gnome_vfs_write (sink->handle, data, size, &written);
+  gst_buffer_unmap (buf, data, size);
 
   switch (result) {
     case GNOME_VFS_OK:{
       GST_DEBUG_OBJECT (sink, "wrote %" G_GINT64_FORMAT " bytes at %"
           G_GINT64_FORMAT, (gint64) written, (gint64) cur_pos);
 
-      if (written < GST_BUFFER_SIZE (buf)) {
+      if (written < size) {
         /* FIXME: what to do here? (tpm) */
-        g_warning ("%s: %d bytes should be written, only %"
-            G_GUINT64_FORMAT " bytes written", G_STRLOC,
-            GST_BUFFER_SIZE (buf), written);
+        g_warning ("%s: %" G_GSIZE_FORMAT " bytes should be written, only %"
+            G_GUINT64_FORMAT " bytes written", G_STRLOC, size, written);
       }
 
-      sink->current_pos += GST_BUFFER_SIZE (buf);
+      sink->current_pos += size;
       ret = GST_FLOW_OK;
       break;
     }
@@ -554,7 +553,7 @@ gst_gnome_vfs_sink_render (GstBaseSink * basesink, GstBuffer * buf)
       /* TODO: emit signal/send msg on out-of-diskspace and
        * handle this gracefully (see open bug) (tpm) */
       GST_ELEMENT_ERROR (sink, RESOURCE, NO_SPACE_LEFT, (NULL),
-          ("bufsize=%u, written=%u", GST_BUFFER_SIZE (buf), (guint) written));
+          ("bufsize=%u, written=%u", size, (guint) written));
       ret = GST_FLOW_ERROR;
       break;
     }
@@ -565,7 +564,7 @@ gst_gnome_vfs_sink_render (GstBaseSink * basesink, GstBuffer * buf)
       GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
           (_("Error while writing to file \"%s\"."), filename),
           ("%s, bufsize=%u, written=%u", gnome_vfs_result_to_string (result),
-              GST_BUFFER_SIZE (buf), (guint) written));
+              size, (guint) written));
 
       g_free (filename);
       ret = GST_FLOW_ERROR;
index 4b2507c..f6283d8 100644 (file)
@@ -116,9 +116,6 @@ enum
   ARG_IRADIO_TITLE
 };
 
-static void gst_gnome_vfs_src_base_init (gpointer g_class);
-static void gst_gnome_vfs_src_class_init (GstGnomeVFSSrcClass * klass);
-static void gst_gnome_vfs_src_init (GstGnomeVFSSrc * gnomevfssrc);
 static void gst_gnome_vfs_src_finalize (GObject * object);
 static void gst_gnome_vfs_src_uri_handler_init (gpointer g_iface,
     gpointer iface_data);
@@ -137,67 +134,24 @@ static GstFlowReturn gst_gnome_vfs_src_create (GstBaseSrc * basesrc,
     guint64 offset, guint size, GstBuffer ** buffer);
 static gboolean gst_gnome_vfs_src_query (GstBaseSrc * src, GstQuery * query);
 
-static GstElementClass *parent_class = NULL;
-
-GType
-gst_gnome_vfs_src_get_type (void)
-{
-  static GType gnomevfssrc_type = 0;
-
-  if (!gnomevfssrc_type) {
-    static const GTypeInfo gnomevfssrc_info = {
-      sizeof (GstGnomeVFSSrcClass),
-      gst_gnome_vfs_src_base_init,
-      NULL,
-      (GClassInitFunc) gst_gnome_vfs_src_class_init,
-      NULL,
-      NULL,
-      sizeof (GstGnomeVFSSrc),
-      0,
-      (GInstanceInitFunc) gst_gnome_vfs_src_init,
-    };
-    static const GInterfaceInfo urihandler_info = {
-      gst_gnome_vfs_src_uri_handler_init,
-      NULL,
-      NULL
-    };
-
-    gnomevfssrc_type =
-        g_type_register_static (GST_TYPE_BASE_SRC,
-        "GstGnomeVFSSrc", &gnomevfssrc_info, 0);
-    g_type_add_interface_static (gnomevfssrc_type, GST_TYPE_URI_HANDLER,
-        &urihandler_info);
-  }
-  return gnomevfssrc_type;
-}
-
-static void
-gst_gnome_vfs_src_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&srctemplate));
-  gst_element_class_set_details_simple (element_class,
-      "GnomeVFS Source", "Source/File",
-      "Read from any GnomeVFS-supported file",
-      "Bastien Nocera <hadess@hadess.net>, "
-      "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
-
-  GST_DEBUG_CATEGORY_INIT (gnomevfssrc_debug, "gnomevfssrc", 0,
-      "Gnome-VFS Source");
-}
+#define gst_gnome_vfs_src_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstGnomeVFSSrc, gst_gnome_vfs_src, GST_TYPE_BASE_SRC,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
+        gst_gnome_vfs_src_uri_handler_init));
 
 static void
 gst_gnome_vfs_src_class_init (GstGnomeVFSSrcClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseSrcClass *gstbasesrc_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
+  gstelement_class = GST_ELEMENT_CLASS (klass);
   gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
 
-  parent_class = g_type_class_peek_parent (klass);
+  GST_DEBUG_CATEGORY_INIT (gnomevfssrc_debug, "gnomevfssrc", 0,
+      "Gnome-VFS Source");
 
   gobject_class->finalize = gst_gnome_vfs_src_finalize;
   gobject_class->set_property = gst_gnome_vfs_src_set_property;
@@ -239,6 +193,14 @@ gst_gnome_vfs_src_class_init (GstGnomeVFSSrcClass * klass)
           "Name of currently playing song", NULL,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_set_details_simple (gstelement_class,
+      "GnomeVFS Source", "Source/File",
+      "Read from any GnomeVFS-supported file",
+      "Bastien Nocera <hadess@hadess.net>, "
+      "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
+
   gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_start);
   gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_stop);
   gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_get_size);
@@ -601,8 +563,8 @@ gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
   GnomeVFSResult res;
   GstBuffer *buf;
   GnomeVFSFileSize readbytes;
-  guint8 *data;
-  guint todo;
+  guint8 *data, *ptr;
+  gsize todo;
   GstGnomeVFSSrc *src;
 
   src = GST_GNOME_VFS_SRC (basesrc);
@@ -624,18 +586,19 @@ gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
     }
   }
 
-  buf = gst_buffer_try_new_and_alloc (size);
+  buf = gst_buffer_new_and_alloc (size);
   if (G_UNLIKELY (buf == NULL)) {
     GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", size);
     return GST_FLOW_ERROR;
   }
 
-  data = GST_BUFFER_DATA (buf);
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
 
+  ptr = data;
   todo = size;
   while (todo > 0) {
     /* this can return less that we ask for */
-    res = gnome_vfs_read (src->handle, data, todo, &readbytes);
+    res = gnome_vfs_read (src->handle, ptr, todo, &readbytes);
 
     if (G_UNLIKELY (res == GNOME_VFS_ERROR_EOF || (res == GNOME_VFS_OK
                 && readbytes == 0)))
@@ -645,13 +608,15 @@ gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
       goto read_failed;
 
     if (readbytes < todo) {
-      data = &data[readbytes];
+      ptr += readbytes;
       todo -= readbytes;
     } else {
       todo = 0;
     }
     GST_LOG ("  got size %" G_GUINT64_FORMAT, readbytes);
   }
+  gst_buffer_unmap (buf, data, size);
+
   GST_BUFFER_OFFSET (buf) = src->curoffset;
   src->curoffset += size;
 
@@ -676,6 +641,7 @@ cannot_seek:
   }
 read_failed:
   {
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
         ("Failed to read data: %s", gnome_vfs_result_to_string (res)));
@@ -683,6 +649,7 @@ read_failed:
   }
 eos:
   {
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     GST_DEBUG_OBJECT (src, "Reading data gave EOS");
     return GST_FLOW_UNEXPECTED;
index 48c1e27..618679a 100644 (file)
@@ -74,6 +74,7 @@ struct _GstVisual
   gint height;
   GstClockTime duration;
   guint outsize;
+  GstBufferPool *pool;
 
   /* samples per frame based on caps */
   guint spf;
@@ -128,7 +129,7 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
 
 static void gst_visual_class_init (gpointer g_class, gpointer class_data);
 static void gst_visual_init (GstVisual * visual);
-static void gst_visual_dispose (GObject * object);
+static void gst_visual_finalize (GObject * object);
 
 static GstStateChangeReturn gst_visual_change_state (GstElement * element,
     GstStateChange transition);
@@ -139,8 +140,7 @@ static gboolean gst_visual_src_event (GstPad * pad, GstEvent * event);
 static gboolean gst_visual_src_query (GstPad * pad, GstQuery * query);
 
 static gboolean gst_visual_sink_setcaps (GstPad * pad, GstCaps * caps);
-static gboolean gst_visual_src_setcaps (GstPad * pad, GstCaps * caps);
-static GstCaps *gst_visual_getcaps (GstPad * pad);
+static GstCaps *gst_visual_getcaps (GstPad * pad, GstCaps * filter);
 static void libvisual_log_handler (const char *message, const char *funcname,
     void *priv);
 
@@ -198,6 +198,7 @@ gst_visual_class_init (gpointer g_class, gpointer class_data)
         gst_static_pad_template_get (&src_template));
     gst_element_class_add_pad_template (element,
         gst_static_pad_template_get (&sink_template));
+
     gst_element_class_set_details_simple (element,
         longname, "Visualization",
         klass->plugin->info->about, "Benjamin Otte <otte@gnome.org>");
@@ -205,7 +206,7 @@ gst_visual_class_init (gpointer g_class, gpointer class_data)
     g_free (longname);
   }
 
-  object->dispose = gst_visual_dispose;
+  object->finalize = gst_visual_finalize;
 }
 
 static void
@@ -213,13 +214,11 @@ gst_visual_init (GstVisual * visual)
 {
   /* create the sink and src pads */
   visual->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
-  gst_pad_set_setcaps_function (visual->sinkpad, gst_visual_sink_setcaps);
   gst_pad_set_chain_function (visual->sinkpad, gst_visual_chain);
   gst_pad_set_event_function (visual->sinkpad, gst_visual_sink_event);
   gst_element_add_pad (GST_ELEMENT (visual), visual->sinkpad);
 
   visual->srcpad = gst_pad_new_from_static_template (&src_template, "src");
-  gst_pad_set_setcaps_function (visual->srcpad, gst_visual_src_setcaps);
   gst_pad_set_getcaps_function (visual->srcpad, gst_visual_getcaps);
   gst_pad_set_event_function (visual->srcpad, gst_visual_src_event);
   gst_pad_set_query_function (visual->srcpad, gst_visual_src_query);
@@ -246,17 +245,16 @@ gst_visual_clear_actors (GstVisual * visual)
 }
 
 static void
-gst_visual_dispose (GObject * object)
+gst_visual_finalize (GObject * object)
 {
   GstVisual *visual = GST_VISUAL (object);
 
-  if (visual->adapter) {
-    g_object_unref (visual->adapter);
-    visual->adapter = NULL;
-  }
+  g_object_unref (visual->adapter);
+  if (visual->pool)
+    gst_object_unref (visual->pool);
   gst_visual_clear_actors (visual);
 
-  GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
+  GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
 }
 
 static void
@@ -272,14 +270,14 @@ gst_visual_reset (GstVisual * visual)
 }
 
 static GstCaps *
-gst_visual_getcaps (GstPad * pad)
+gst_visual_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstCaps *ret;
   GstVisual *visual = GST_VISUAL (gst_pad_get_parent (pad));
   int depths;
 
   if (!visual->actor) {
-    ret = gst_caps_copy (gst_pad_get_pad_template_caps (visual->srcpad));
+    ret = gst_pad_get_pad_template_caps (visual->srcpad);
     goto beach;
   }
 
@@ -312,15 +310,23 @@ gst_visual_getcaps (GstPad * pad)
 
 beach:
 
+  if (filter) {
+    GstCaps *intersection;
+
+    intersection =
+        gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (ret);
+    ret = intersection;
+  }
+
   GST_DEBUG_OBJECT (visual, "returning caps %" GST_PTR_FORMAT, ret);
   gst_object_unref (visual);
   return ret;
 }
 
 static gboolean
-gst_visual_src_setcaps (GstPad * pad, GstCaps * caps)
+gst_visual_src_setcaps (GstVisual * visual, GstCaps * caps)
 {
-  GstVisual *visual = GST_VISUAL (gst_pad_get_parent (pad));
   GstStructure *structure;
   gint depth, pitch;
 
@@ -352,14 +358,14 @@ gst_visual_src_setcaps (GstPad * pad, GstCaps * caps)
   visual->duration =
       gst_util_uint64_scale_int (GST_SECOND, visual->fps_d, visual->fps_n);
 
-  gst_object_unref (visual);
+  gst_pad_push_event (visual->srcpad, gst_event_new_caps (caps));
+
   return TRUE;
 
   /* ERRORS */
 error:
   {
     GST_DEBUG_OBJECT (visual, "error parsing caps");
-    gst_object_unref (visual);
     return FALSE;
   }
 }
@@ -393,19 +399,22 @@ gst_vis_src_negotiate (GstVisual * visual)
   GstCaps *othercaps, *target;
   GstStructure *structure;
   GstCaps *caps;
+  GstQuery *query;
+  GstBufferPool *pool = NULL;
+  guint size, min, max, prefix, alignment;
 
-  caps = gst_pad_get_caps (visual->srcpad);
+  caps = gst_pad_get_caps (visual->srcpad, NULL);
 
   /* see what the peer can do */
-  othercaps = gst_pad_peer_get_caps (visual->srcpad);
+  othercaps = gst_pad_peer_get_caps (visual->srcpad, caps);
   if (othercaps) {
-    target = gst_caps_intersect (othercaps, caps);
-    gst_caps_unref (othercaps);
+    target = othercaps;
     gst_caps_unref (caps);
 
     if (gst_caps_is_empty (target))
       goto no_format;
 
+    target = gst_caps_make_writable (target);
     gst_caps_truncate (target);
   } else {
     /* need a copy, we'll be modifying it when fixating */
@@ -422,7 +431,42 @@ gst_vis_src_negotiate (GstVisual * visual)
   gst_structure_fixate_field_nearest_fraction (structure, "framerate",
       DEFAULT_FPS_N, DEFAULT_FPS_D);
 
-  gst_pad_set_caps (visual->srcpad, target);
+  gst_visual_src_setcaps (visual, target);
+
+  /* try to get a bufferpool now */
+  /* find a pool for the negotiated caps now */
+  query = gst_query_new_allocation (target, TRUE);
+
+  if (gst_pad_peer_query (visual->srcpad, query)) {
+    /* we got configuration from our peer, parse them */
+    gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
+        &alignment, &pool);
+  } else {
+    size = visual->outsize;
+    min = max = 0;
+    prefix = 0;
+    alignment = 1;
+  }
+
+  if (pool == NULL) {
+    GstStructure *config;
+
+    /* we did not get a pool, make one ourselves then */
+    pool = gst_buffer_pool_new ();
+
+    config = gst_buffer_pool_get_config (pool);
+    gst_buffer_pool_config_set (config, target, size, min, max, prefix, 0,
+        alignment);
+    gst_buffer_pool_set_config (pool, config);
+  }
+
+  if (visual->pool)
+    gst_object_unref (visual->pool);
+  visual->pool = pool;
+
+  /* and activate */
+  gst_buffer_pool_set_active (pool, TRUE);
+
   gst_caps_unref (target);
 
   return TRUE;
@@ -454,29 +498,27 @@ gst_visual_sink_event (GstPad * pad, GstEvent * event)
       gst_visual_reset (visual);
       res = gst_pad_push_event (visual->srcpad, event);
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_CAPS:
     {
-      GstFormat format;
-      gdouble rate, arate;
-      gint64 start, stop, time;
-      gboolean update;
+      GstCaps *caps;
 
+      gst_event_parse_caps (event, &caps);
+      res = gst_visual_sink_setcaps (pad, caps);
+      break;
+    }
+    case GST_EVENT_SEGMENT:
+    {
       /* the newsegment values are used to clip the input samples
        * and to convert the incomming timestamps to running time so
        * we can do QoS */
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-          &start, &stop, &time);
-
-      /* now configure the values */
-      gst_segment_set_newsegment_full (&visual->segment, update,
-          rate, arate, format, start, stop, time);
+      gst_event_copy_segment (event, &visual->segment);
 
       /* and forward */
       res = gst_pad_push_event (visual->srcpad, event);
       break;
     }
     default:
-      res = gst_pad_push_event (visual->srcpad, event);
+      res = gst_pad_event_default (pad, event);
       break;
   }
 
@@ -499,7 +541,7 @@ gst_visual_src_event (GstPad * pad, GstEvent * event)
       GstClockTimeDiff diff;
       GstClockTime timestamp;
 
-      gst_event_parse_qos (event, &proportion, &diff, &timestamp);
+      gst_event_parse_qos (event, NULL, &proportion, &diff, &timestamp);
 
       /* save stuff for the _chain function */
       GST_OBJECT_LOCK (visual);
@@ -516,8 +558,13 @@ gst_visual_src_event (GstPad * pad, GstEvent * event)
       res = gst_pad_push_event (visual->sinkpad, event);
       break;
     }
+    case GST_EVENT_RECONFIGURE:
+      /* dont't forward */
+      gst_event_unref (event);
+      res = TRUE;
+      break;
     default:
-      res = gst_pad_push_event (visual->sinkpad, event);
+      res = gst_pad_event_default (pad, event);
       break;
   }
 
@@ -586,31 +633,20 @@ gst_visual_src_query (GstPad * pad, GstQuery * query)
  * function will negotiate one. After calling this function, a
  * reverse negotiation could have happened. */
 static GstFlowReturn
-get_buffer (GstVisual * visual, GstBuffer ** outbuf)
+ensure_negotiated (GstVisual * visual)
 {
-  GstFlowReturn ret;
+  gboolean reconfigure;
+
+  GST_OBJECT_LOCK (visual->srcpad);
+  reconfigure = GST_PAD_NEEDS_RECONFIGURE (visual->srcpad);
+  GST_OBJECT_FLAG_UNSET (visual->srcpad, GST_PAD_NEED_RECONFIGURE);
+  GST_OBJECT_UNLOCK (visual->srcpad);
 
   /* we don't know an output format yet, pick one */
-  if (GST_PAD_CAPS (visual->srcpad) == NULL) {
+  if (reconfigure || !gst_pad_has_current_caps (visual->srcpad)) {
     if (!gst_vis_src_negotiate (visual))
       return GST_FLOW_NOT_NEGOTIATED;
   }
-
-  GST_DEBUG_OBJECT (visual, "allocating output buffer with caps %"
-      GST_PTR_FORMAT, GST_PAD_CAPS (visual->srcpad));
-
-  /* now allocate a buffer with the last negotiated format. 
-   * Downstream could renegotiate a new format, which will trigger
-   * our setcaps function on the source pad. */
-  ret =
-      gst_pad_alloc_buffer_and_set_caps (visual->srcpad,
-      GST_BUFFER_OFFSET_NONE, visual->outsize,
-      GST_PAD_CAPS (visual->srcpad), outbuf);
-
-  /* no buffer allocated, we don't care why. */
-  if (ret != GST_FLOW_OK)
-    return ret;
-
   return GST_FLOW_OK;
 }
 
@@ -625,14 +661,11 @@ gst_visual_chain (GstPad * pad, GstBuffer * buffer)
 
   GST_DEBUG_OBJECT (visual, "chain function called");
 
-  /* If we don't have an output format yet, preallocate a buffer to try and
-   * set one */
-  if (GST_PAD_CAPS (visual->srcpad) == NULL) {
-    ret = get_buffer (visual, &outbuf);
-    if (ret != GST_FLOW_OK) {
-      gst_buffer_unref (buffer);
-      goto beach;
-    }
+  /* Make sure have an output format */
+  ret = ensure_negotiated (visual);
+  if (ret != GST_FLOW_OK) {
+    gst_buffer_unref (buffer);
+    goto beach;
   }
 
   /* resync on DISCONT */
@@ -642,7 +675,8 @@ gst_visual_chain (GstPad * pad, GstBuffer * buffer)
 
   GST_DEBUG_OBJECT (visual,
       "Input buffer has %d samples, time=%" G_GUINT64_FORMAT,
-      GST_BUFFER_SIZE (buffer) / visual->bps, GST_BUFFER_TIMESTAMP (buffer));
+      gst_buffer_get_size (buffer) / visual->bps,
+      GST_BUFFER_TIMESTAMP (buffer));
 
   gst_adapter_push (visual->adapter, buffer);
 
@@ -650,6 +684,8 @@ gst_visual_chain (GstPad * pad, GstBuffer * buffer)
     gboolean need_skip;
     const guint16 *data;
     guint64 dist, timestamp;
+    guint8 *outdata;
+    gsize outsize;
 
     GST_DEBUG_OBJECT (visual, "processing buffer");
 
@@ -696,7 +732,7 @@ gst_visual_chain (GstPad * pad, GstBuffer * buffer)
 
     /* Read VISUAL_SAMPLES samples per channel */
     data =
-        (const guint16 *) gst_adapter_peek (visual->adapter,
+        (const guint16 *) gst_adapter_map (visual->adapter,
         VISUAL_SAMPLES * visual->bps);
 
 #if defined(VISUAL_API_VERSION) && VISUAL_API_VERSION >= 4000 && VISUAL_API_VERSION < 5000
@@ -780,17 +816,23 @@ gst_visual_chain (GstPad * pad, GstBuffer * buffer)
     /* alloc a buffer if we don't have one yet, this happens
      * when we pushed a buffer in this while loop before */
     if (outbuf == NULL) {
-      ret = get_buffer (visual, &outbuf);
+      GST_DEBUG_OBJECT (visual, "allocating output buffer");
+      ret = gst_buffer_pool_acquire_buffer (visual->pool, &outbuf, NULL);
       if (ret != GST_FLOW_OK) {
+        gst_adapter_unmap (visual->adapter, 0);
         goto beach;
       }
     }
-    visual_video_set_buffer (visual->video, GST_BUFFER_DATA (outbuf));
+    outdata = gst_buffer_map (outbuf, &outsize, NULL, GST_MAP_WRITE);
+    visual_video_set_buffer (visual->video, outdata);
     visual_audio_analyze (visual->audio);
     visual_actor_run (visual->actor, visual->audio);
     visual_video_set_buffer (visual->video, NULL);
+    gst_buffer_unmap (outbuf, outdata, outsize);
     GST_DEBUG_OBJECT (visual, "rendered one frame");
 
+    gst_adapter_unmap (visual->adapter, 0);
+
     GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
     GST_BUFFER_DURATION (outbuf) = visual->duration;
 
@@ -856,6 +898,11 @@ gst_visual_change_state (GstElement * element, GstStateChange transition)
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
       break;
     case GST_STATE_CHANGE_PAUSED_TO_READY:
+      if (visual->pool) {
+        gst_buffer_pool_set_active (visual->pool, FALSE);
+        gst_object_unref (visual->pool);
+        visual->pool = NULL;
+      }
       break;
     case GST_STATE_CHANGE_READY_TO_NULL:
       gst_visual_clear_actors (visual);
index 2851e52..d79a2dd 100644 (file)
@@ -196,8 +196,8 @@ gst_ogg_avi_parse_setcaps (GstPad * pad, GstCaps * caps)
   GstStructure *structure;
   const GValue *codec_data;
   GstBuffer *buffer;
-  guint8 *data;
-  guint size;
+  guint8 *data, *ptr;
+  gsize size, left;
   guint32 sizes[3];
   GstCaps *outcaps;
   gint i, offs;
@@ -221,31 +221,33 @@ gst_ogg_avi_parse_setcaps (GstPad * pad, GstCaps * caps)
   /* first 22 bytes are bits_per_sample, channel_mask, GUID
    * Then we get 3 LE guint32 with the 3 header sizes
    * then we get the bytes of the 3 headers. */
-  data = GST_BUFFER_DATA (buffer);
-  size = GST_BUFFER_SIZE (buffer);
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+
+  ptr = data;
+  left = size;
 
-  GST_LOG_OBJECT (ogg, "configuring codec_data of size %u", size);
+  GST_LOG_OBJECT (ogg, "configuring codec_data of size %u", left);
 
   /* skip headers */
-  data += 22;
-  size -= 22;
+  ptr += 22;
+  left -= 22;
 
   /* we need at least 12 bytes for the packet sizes of the 3 headers */
-  if (size < 12)
+  if (left < 12)
     goto buffer_too_small;
 
   /* read sizes of the 3 headers */
-  sizes[0] = GST_READ_UINT32_LE (data);
-  sizes[1] = GST_READ_UINT32_LE (data + 4);
-  sizes[2] = GST_READ_UINT32_LE (data + 8);
+  sizes[0] = GST_READ_UINT32_LE (ptr);
+  sizes[1] = GST_READ_UINT32_LE (ptr + 4);
+  sizes[2] = GST_READ_UINT32_LE (ptr + 8);
 
   GST_DEBUG_OBJECT (ogg, "header sizes: %u %u %u", sizes[0], sizes[1],
       sizes[2]);
 
-  size -= 12;
+  left -= 12;
 
   /* and we need at least enough data for all the headers */
-  if (size < sizes[0] + sizes[1] + sizes[2])
+  if (left < sizes[0] + sizes[1] + sizes[2])
     goto buffer_too_small;
 
   /* set caps */
@@ -258,12 +260,12 @@ gst_ogg_avi_parse_setcaps (GstPad * pad, GstCaps * caps)
     GstBuffer *out;
 
     /* now output the raw vorbis header packets */
-    out = gst_buffer_create_sub (buffer, offs, sizes[i]);
-    gst_buffer_set_caps (out, outcaps);
+    out = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, offs, sizes[i]);
     gst_pad_push (ogg->srcpad, out);
 
     offs += sizes[i];
   }
+  gst_buffer_unmap (buffer, data, size);
   gst_caps_unref (outcaps);
 
   return TRUE;
@@ -282,6 +284,7 @@ wrong_format:
 buffer_too_small:
   {
     GST_DEBUG_OBJECT (ogg, "codec_data is too small");
+    gst_buffer_unmap (buffer, data, size);
     return FALSE;
   }
 }
@@ -319,7 +322,7 @@ gst_ogg_avi_parse_push_packet (GstOggAviParse * ogg, ogg_packet * packet)
 
   /* allocate space for header and body */
   buffer = gst_buffer_new_and_alloc (packet->bytes);
-  memcpy (GST_BUFFER_DATA (buffer), packet->packet, packet->bytes);
+  gst_buffer_fill (buffer, 0, packet->packet, packet->bytes);
 
   GST_LOG_OBJECT (ogg, "created buffer %p from page", buffer);
 
@@ -340,15 +343,13 @@ gst_ogg_avi_parse_chain (GstPad * pad, GstBuffer * buffer)
 {
   GstFlowReturn result = GST_FLOW_OK;
   GstOggAviParse *ogg;
-  guint8 *data;
   guint size;
   gchar *oggbuf;
   gint ret = -1;
 
   ogg = GST_OGG_AVI_PARSE (GST_OBJECT_PARENT (pad));
 
-  data = GST_BUFFER_DATA (buffer);
-  size = GST_BUFFER_SIZE (buffer);
+  size = gst_buffer_get_size (buffer);
 
   GST_LOG_OBJECT (ogg, "Chain function received buffer of size %d", size);
 
@@ -359,7 +360,7 @@ gst_ogg_avi_parse_chain (GstPad * pad, GstBuffer * buffer)
 
   /* write data to sync layer */
   oggbuf = ogg_sync_buffer (&ogg->sync, size);
-  memcpy (oggbuf, data, size);
+  gst_buffer_extract (buffer, 0, oggbuf, size);
   ogg_sync_wrote (&ogg->sync, size);
   gst_buffer_unref (buffer);
 
index 67d2321..b2a445b 100644 (file)
@@ -114,7 +114,6 @@ static void gst_ogg_pad_finalize (GObject * object);
 static const GstQueryType *gst_ogg_pad_query_types (GstPad * pad);
 static gboolean gst_ogg_pad_src_query (GstPad * pad, GstQuery * query);
 static gboolean gst_ogg_pad_event (GstPad * pad, GstEvent * event);
-static GstCaps *gst_ogg_pad_getcaps (GstPad * pad);
 static GstOggPad *gst_ogg_chain_get_stream (GstOggChain * chain,
     glong serialno);
 
@@ -144,12 +143,11 @@ gst_ogg_pad_init (GstOggPad * pad)
 {
   gst_pad_set_event_function (GST_PAD (pad),
       GST_DEBUG_FUNCPTR (gst_ogg_pad_event));
-  gst_pad_set_getcaps_function (GST_PAD (pad),
-      GST_DEBUG_FUNCPTR (gst_ogg_pad_getcaps));
   gst_pad_set_query_type_function (GST_PAD (pad),
       GST_DEBUG_FUNCPTR (gst_ogg_pad_query_types));
   gst_pad_set_query_function (GST_PAD (pad),
       GST_DEBUG_FUNCPTR (gst_ogg_pad_src_query));
+  gst_pad_use_fixed_caps (GST_PAD (pad));
 
   pad->mode = GST_OGG_PAD_MODE_INIT;
 
@@ -158,7 +156,7 @@ gst_ogg_pad_init (GstOggPad * pad)
 
   pad->start_time = GST_CLOCK_TIME_NONE;
 
-  pad->last_stop = GST_CLOCK_TIME_NONE;
+  pad->position = GST_CLOCK_TIME_NONE;
 
   pad->have_type = FALSE;
   pad->continued = NULL;
@@ -226,12 +224,6 @@ gst_ogg_pad_query_types (GstPad * pad)
   return query_types;
 }
 
-static GstCaps *
-gst_ogg_pad_getcaps (GstPad * pad)
-{
-  return gst_caps_ref (GST_PAD_CAPS (pad));
-}
-
 static gboolean
 gst_ogg_pad_src_query (GstPad * pad, GstQuery * query)
 {
@@ -412,7 +404,7 @@ gst_ogg_pad_reset (GstOggPad * pad)
   pad->continued = NULL;
 
   pad->last_ret = GST_FLOW_OK;
-  pad->last_stop = GST_CLOCK_TIME_NONE;
+  pad->position = GST_CLOCK_TIME_NONE;
   pad->current_granule = -1;
   pad->keyframe_granule = -1;
   pad->is_eos = FALSE;
@@ -574,14 +566,14 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
     goto not_added;
 
   buf = gst_buffer_new_and_alloc (packet->bytes - offset - trim);
-  gst_buffer_set_caps (buf, GST_PAD_CAPS (pad));
 
   /* set delta flag for OGM content */
   if (delta_unit)
     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
 
   /* copy packet in buffer */
-  memcpy (buf->data, packet->packet + offset, packet->bytes - offset - trim);
+  gst_buffer_fill (buf, 0, packet->packet + offset,
+      packet->bytes - offset - trim);
 
   GST_BUFFER_TIMESTAMP (buf) = out_timestamp;
   GST_BUFFER_DURATION (buf) = out_duration;
@@ -594,7 +586,7 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
     pad->discont = FALSE;
   }
 
-  pad->last_stop = ogg->segment.last_stop;
+  pad->position = ogg->segment.position;
 
   /* don't push the header packets when we are asked to skip them */
   if (!packet->b_o_s || push_headers) {
@@ -611,7 +603,7 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
 
   /* check if valid granulepos, then we can calculate the current
    * position. We know the granule for each packet but we only want to update
-   * the last_stop when we have a valid granulepos on the packet because else
+   * the position when we have a valid granulepos on the packet because else
    * our time jumps around for the different streams. */
   if (packet->granulepos < 0)
     goto done;
@@ -631,7 +623,7 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
   }
 
   /* and store as the current position */
-  gst_segment_set_last_stop (&ogg->segment, GST_FORMAT_TIME, current_time);
+  ogg->segment.position = current_time;
 
   GST_DEBUG_OBJECT (ogg, "ogg current time %" GST_TIME_FORMAT,
       GST_TIME_ARGS (current_time));
@@ -865,6 +857,7 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
 
         if (start_time != G_MAXUINT64) {
           gint64 segment_time;
+          GstSegment segment;
 
           GST_DEBUG_OBJECT (ogg, "start_time:  %" GST_TIME_FORMAT,
               GST_TIME_ARGS (start_time));
@@ -876,8 +869,13 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
             segment_time = chain->begin_time;
 
           /* create the newsegment event we are going to send out */
-          event = gst_event_new_new_segment (FALSE, ogg->segment.rate,
-              GST_FORMAT_TIME, start_time, chain->segment_stop, segment_time);
+          gst_segment_init (&segment, GST_FORMAT_TIME);
+          segment.rate = ogg->segment.rate;
+          segment.applied_rate = ogg->segment.applied_rate;
+          segment.start = start_time;
+          segment.stop = chain->segment_stop;
+          segment.time = segment_time;
+          event = gst_event_new_segment (&segment);
 
           ogg->resync = FALSE;
         }
@@ -885,6 +883,7 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
         /* see if we have enough info to activate the chain, we have enough info
          * when all streams have a valid start time. */
         if (gst_ogg_demux_collect_chain_info (ogg, chain)) {
+          GstSegment segment;
 
           GST_DEBUG_OBJECT (ogg, "segment_start: %" GST_TIME_FORMAT,
               GST_TIME_ARGS (chain->segment_start));
@@ -894,9 +893,13 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
               GST_TIME_ARGS (chain->begin_time));
 
           /* create the newsegment event we are going to send out */
-          event = gst_event_new_new_segment (FALSE, ogg->segment.rate,
-              GST_FORMAT_TIME, chain->segment_start, chain->segment_stop,
-              chain->begin_time);
+          gst_segment_init (&segment, GST_FORMAT_TIME);
+          segment.rate = ogg->segment.rate;
+          segment.applied_rate = ogg->segment.applied_rate;
+          segment.start = chain->segment_start;
+          segment.stop = chain->segment_stop;
+          segment.time = chain->begin_time;
+          event = gst_event_new_segment (&segment);
         }
       }
 
@@ -1157,8 +1160,7 @@ gst_ogg_chain_new_stream (GstOggChain * chain, glong serialno)
 
   ret = g_object_new (GST_TYPE_OGG_PAD, NULL);
   /* we own this one */
-  gst_object_ref (ret);
-  gst_object_sink (ret);
+  gst_object_ref_sink (ret);
 
   GST_PAD_DIRECTION (ret) = GST_PAD_SRC;
   gst_ogg_pad_mark_discont (ret);
@@ -1264,29 +1266,24 @@ static gboolean gst_ogg_demux_send_event (GstOggDemux * ogg, GstEvent * event);
 
 static void gst_ogg_print (GstOggDemux * demux);
 
-GST_BOILERPLATE (GstOggDemux, gst_ogg_demux, GstElement, GST_TYPE_ELEMENT);
+#define gst_ogg_demux_parent_class parent_class
+G_DEFINE_TYPE (GstOggDemux, gst_ogg_demux, GST_TYPE_ELEMENT);
 
 static void
-gst_ogg_demux_base_init (gpointer g_class)
+gst_ogg_demux_class_init (GstOggDemuxClass * klass)
 {
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
-  gst_element_class_set_details_simple (element_class,
+  gst_element_class_set_details_simple (gstelement_class,
       "Ogg demuxer", "Codec/Demuxer",
       "demux ogg streams (info about ogg: http://xiph.org)",
       "Wim Taymans <wim@fluendo.com>");
 
-  gst_element_class_add_pad_template (element_class,
+  gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&ogg_demux_sink_template_factory));
-  gst_element_class_add_pad_template (element_class,
+  gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&ogg_demux_src_template_factory));
-}
-
-static void
-gst_ogg_demux_class_init (GstOggDemuxClass * klass)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
   gstelement_class->change_state = gst_ogg_demux_change_state;
   gstelement_class->send_event = gst_ogg_demux_receive_event;
@@ -1295,7 +1292,7 @@ gst_ogg_demux_class_init (GstOggDemuxClass * klass)
 }
 
 static void
-gst_ogg_demux_init (GstOggDemux * ogg, GstOggDemuxClass * g_class)
+gst_ogg_demux_init (GstOggDemux * ogg)
 {
   /* create the sink pad */
   ogg->sinkpad =
@@ -1373,7 +1370,7 @@ gst_ogg_demux_sink_event (GstPad * pad, GstEvent * event)
       res = gst_ogg_demux_send_event (ogg, event);
       gst_ogg_demux_reset_streams (ogg);
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
       GST_DEBUG_OBJECT (ogg, "got a new segment event");
       gst_event_unref (event);
       res = TRUE;
@@ -1401,15 +1398,14 @@ gst_ogg_demux_sink_event (GstPad * pad, GstEvent * event)
 static GstFlowReturn
 gst_ogg_demux_submit_buffer (GstOggDemux * ogg, GstBuffer * buffer)
 {
-  gint size;
+  gsize size;
   guint8 *data;
   gchar *oggbuffer;
   GstFlowReturn ret = GST_FLOW_OK;
 
-  size = GST_BUFFER_SIZE (buffer);
-  data = GST_BUFFER_DATA (buffer);
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
 
-  GST_DEBUG_OBJECT (ogg, "submitting %u bytes", size);
+  GST_DEBUG_OBJECT (ogg, "submitting %" G_GSIZE_FORMAT " bytes", size);
   if (G_UNLIKELY (size == 0))
     goto done;
 
@@ -1422,6 +1418,7 @@ gst_ogg_demux_submit_buffer (GstOggDemux * ogg, GstBuffer * buffer)
     goto write_failed;
 
 done:
+  gst_buffer_unmap (buffer, data, size);
   gst_buffer_unref (buffer);
 
   return ret;
@@ -1480,7 +1477,7 @@ gst_ogg_demux_get_data (GstOggDemux * ogg, gint64 end_offset)
   if (ret != GST_FLOW_OK)
     goto error;
 
-  ogg->read_offset += GST_BUFFER_SIZE (buffer);
+  ogg->read_offset += gst_buffer_get_size (buffer);
 
   ret = gst_ogg_demux_submit_buffer (ogg, buffer);
 
@@ -1726,7 +1723,7 @@ gst_ogg_demux_set_header_on_caps (GstOggDemux * ogg, GstCaps * caps,
     ogg_packet *op = headers->data;
     g_assert (op);
     buffer = gst_buffer_new_and_alloc (op->bytes);
-    memcpy (GST_BUFFER_DATA (buffer), op->packet, op->bytes);
+    gst_buffer_fill (buffer, 0, op->packet, op->bytes);
     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_IN_CAPS);
     g_value_init (&value, GST_TYPE_BUFFER);
     gst_value_take_buffer (&value, buffer);
@@ -1777,7 +1774,8 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain,
     gst_ogg_pad_mark_discont (pad);
     pad->last_ret = GST_FLOW_OK;
 
-    if (pad->map.is_skeleton || pad->added || GST_PAD_CAPS (pad) == NULL)
+    if (pad->map.is_skeleton || pad->added
+        || !gst_pad_has_current_caps (GST_PAD_CAST (pad)))
       continue;
 
     GST_DEBUG_OBJECT (ogg, "adding pad %" GST_PTR_FORMAT, pad);
@@ -2049,7 +2047,7 @@ gst_ogg_demux_do_seek (GstOggDemux * ogg, GstSegment * segment,
   gint i, pending, len;
   gboolean first_parsed_page = TRUE;
 
-  position = segment->last_stop;
+  position = segment->position;
 
   /* first find the chain to search in */
   total = ogg->total_time;
@@ -2203,7 +2201,7 @@ done:
   if (keyframe) {
     if (segment->rate > 0.0)
       segment->time = keytarget;
-    segment->last_stop = keytarget - begintime;
+    segment->position = keytarget - begintime;
   }
 
   *rchain = chain;
@@ -2301,28 +2299,8 @@ gst_ogg_demux_perform_seek_pull (GstOggDemux * ogg, GstEvent * event)
    * forever. */
   GST_PAD_STREAM_LOCK (ogg->sinkpad);
 
-  if (ogg->segment_running && !flush) {
-    /* create the segment event to close the current segment */
-    if ((chain = ogg->current_chain)) {
-      GstEvent *newseg;
-      gint64 chain_start = 0;
-
-      if (chain->segment_start != GST_CLOCK_TIME_NONE)
-        chain_start = chain->segment_start;
-
-      newseg = gst_event_new_new_segment (TRUE, ogg->segment.rate,
-          GST_FORMAT_TIME, ogg->segment.start + chain_start,
-          ogg->segment.last_stop + chain_start, ogg->segment.time);
-      /* set the seqnum of the running segment */
-      gst_event_set_seqnum (newseg, ogg->seqnum);
-
-      /* send segment on old chain, FIXME, must be sent from streaming thread. */
-      gst_ogg_demux_send_event (ogg, newseg);
-    }
-  }
-
   if (event) {
-    gst_segment_set_seek (&ogg->segment, rate, format, flags,
+    gst_segment_do_seek (&ogg->segment, rate, format, flags,
         cur_type, cur, stop_type, stop, &update);
   }
 
@@ -2369,7 +2347,8 @@ gst_ogg_demux_perform_seek_pull (GstOggDemux * ogg, GstEvent * event)
     GstEvent *event;
     gint64 stop;
     gint64 start;
-    gint64 last_stop, begin_time;
+    gint64 position, begin_time;
+    GstSegment segment;
 
     /* we have to send the flush to the old chain, not the new one */
     if (flush) {
@@ -2406,18 +2385,21 @@ gst_ogg_demux_perform_seek_pull (GstOggDemux * ogg, GstEvent * event)
       stop = MIN (stop, chain->segment_stop);
     }
 
-    last_stop = ogg->segment.last_stop;
+    position = ogg->segment.position;
     if (chain->segment_start != GST_CLOCK_TIME_NONE)
-      last_stop += chain->segment_start;
+      position += chain->segment_start;
 
-    /* create the segment event we are going to send out */
-    if (ogg->segment.rate >= 0.0)
-      event = gst_event_new_new_segment (FALSE, ogg->segment.rate,
-          ogg->segment.format, last_stop, stop, ogg->segment.time);
-    else
-      event = gst_event_new_new_segment (FALSE, ogg->segment.rate,
-          ogg->segment.format, start, last_stop, ogg->segment.time);
+    gst_segment_copy_into (&ogg->segment, &segment);
 
+    /* create the segment event we are going to send out */
+    if (ogg->segment.rate >= 0.0) {
+      segment.start = position;
+      segment.stop = stop;
+    } else {
+      segment.start = start;
+      segment.stop = position;
+    }
+    event = gst_event_new_segment (&segment);
     gst_event_set_seqnum (event, seqnum);
 
     if (chain != ogg->current_chain) {
@@ -2437,13 +2419,12 @@ gst_ogg_demux_perform_seek_pull (GstOggDemux * ogg, GstEvent * event)
       GstMessage *message;
 
       message = gst_message_new_segment_start (GST_OBJECT (ogg),
-          GST_FORMAT_TIME, ogg->segment.last_stop);
+          GST_FORMAT_TIME, ogg->segment.position);
       gst_message_set_seqnum (message, seqnum);
 
       gst_element_post_message (GST_ELEMENT (ogg), message);
     }
 
-    ogg->segment_running = TRUE;
     ogg->seqnum = seqnum;
     /* restart our task since it might have been stopped when we did the 
      * flush. */
@@ -2943,7 +2924,7 @@ gst_ogg_demux_collect_info (GstOggDemux * ogg)
 
     ogg->total_time += chain->total_time;
   }
-  gst_segment_set_duration (&ogg->segment, GST_FORMAT_TIME, ogg->total_time);
+  ogg->segment.duration = ogg->total_time;
 }
 
 /* find all the chains in the ogg file, this reads the first and
@@ -3066,13 +3047,17 @@ gst_ogg_demux_handle_page (GstOggDemux * ogg, ogg_page * page)
     if (chain) {
       GstEvent *event;
       gint64 start = 0;
+      GstSegment segment;
 
       if (chain->segment_start != GST_CLOCK_TIME_NONE)
         start = chain->segment_start;
 
       /* create the newsegment event we are going to send out */
-      event = gst_event_new_new_segment (FALSE, ogg->segment.rate,
-          GST_FORMAT_TIME, start, chain->segment_stop, chain->begin_time);
+      gst_segment_copy_into (&ogg->segment, &segment);
+      segment.start = start;
+      segment.stop = chain->segment_stop;
+      segment.time = chain->begin_time;
+      event = gst_event_new_segment (&segment);
       gst_event_set_seqnum (event, ogg->seqnum);
 
       GST_DEBUG_OBJECT (ogg,
@@ -3093,7 +3078,7 @@ gst_ogg_demux_handle_page (GstOggDemux * ogg, ogg_page * page)
       if (ogg->pullmode)
         goto unknown_chain;
 
-      current_time = ogg->segment.last_stop;
+      current_time = ogg->segment.position;
 
       /* time of new chain is current time */
       chain_time = current_time;
@@ -3271,7 +3256,7 @@ gst_ogg_demux_loop_forward (GstOggDemux * ogg)
     goto done;
   }
 
-  ogg->offset += GST_BUFFER_SIZE (buffer);
+  ogg->offset += gst_buffer_get_size (buffer);
 
   if (G_UNLIKELY (ogg->newsegment)) {
     gst_ogg_demux_send_event (ogg, ogg->newsegment);
@@ -3350,7 +3335,7 @@ gst_ogg_demux_sync_streams (GstOggDemux * ogg)
   guint i;
 
   chain = ogg->current_chain;
-  cur = ogg->segment.last_stop;
+  cur = ogg->segment.position;
   if (chain == NULL || cur == -1)
     return;
 
@@ -3360,18 +3345,24 @@ gst_ogg_demux_sync_streams (GstOggDemux * ogg)
     /* Theoretically, we should be doing this for all streams, but we're only
      * doing it for known-to-be-sparse streams at the moment in order not to
      * break things for wrongly-muxed streams (like we used to produce once) */
-    if (stream->map.is_sparse && stream->last_stop != GST_CLOCK_TIME_NONE) {
+    if (stream->map.is_sparse && stream->position != GST_CLOCK_TIME_NONE) {
 
       /* Does this stream lag? Random threshold of 2 seconds */
-      if (GST_CLOCK_DIFF (stream->last_stop, cur) > (2 * GST_SECOND)) {
+      if (GST_CLOCK_DIFF (stream->position, cur) > (2 * GST_SECOND)) {
         GST_DEBUG_OBJECT (stream, "synchronizing stream with others by "
             "advancing time from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
-            GST_TIME_ARGS (stream->last_stop), GST_TIME_ARGS (cur));
-        stream->last_stop = cur;
+            GST_TIME_ARGS (stream->position), GST_TIME_ARGS (cur));
+
+        stream->position = cur;
+
+#if 0
+        ogg->segment.base += cur - stream->position;
         /* advance stream time (FIXME: is this right, esp. time_pos?) */
         gst_pad_push_event (GST_PAD_CAST (stream),
             gst_event_new_new_segment (TRUE, ogg->segment.rate,
-                GST_FORMAT_TIME, stream->last_stop, -1, stream->last_stop));
+                ogg->segment.applied_rate,
+                GST_FORMAT_TIME, stream->position, -1, stream->position));
+#endif
       }
     }
   }
@@ -3449,7 +3440,6 @@ pause:
     GstEvent *event = NULL;
 
     GST_LOG_OBJECT (ogg, "pausing task, reason %s", reason);
-    ogg->segment_running = FALSE;
     gst_pad_pause_task (ogg->sinkpad);
 
     if (ret == GST_FLOW_UNEXPECTED) {
@@ -3583,7 +3573,6 @@ gst_ogg_demux_change_state (GstElement * element, GstStateChange transition)
       ogg_sync_reset (&ogg->sync);
       ogg->running = FALSE;
       ogg->bitrate = 0;
-      ogg->segment_running = FALSE;
       ogg->total_time = -1;
       gst_segment_init (&ogg->segment, GST_FORMAT_TIME);
       break;
@@ -3593,7 +3582,7 @@ gst_ogg_demux_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
-  result = parent_class->change_state (element, transition);
+  result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 
   switch (transition) {
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
@@ -3602,7 +3591,6 @@ gst_ogg_demux_change_state (GstElement * element, GstStateChange transition)
       gst_ogg_demux_clear_chains (ogg);
       GST_OBJECT_LOCK (ogg);
       ogg->running = FALSE;
-      ogg->segment_running = FALSE;
       GST_OBJECT_UNLOCK (ogg);
       break;
     case GST_STATE_CHANGE_READY_TO_NULL:
index 031627b..2a0ba2b 100644 (file)
@@ -103,7 +103,7 @@ struct _GstOggPad
   gint64 first_granule;         /* the granulepos of first page == first sample in next page */
   GstClockTime first_time;      /* the timestamp of the second page or granuletime of first page */
 
-  GstClockTime last_stop;       /* last_stop when last push occured; used to detect when we
+  GstClockTime position;        /* position when last push occured; used to detect when we
                                  * need to send a newsegment update event for sparse streams */
 
   GList *continued;
@@ -152,7 +152,6 @@ struct _GstOggDemux
 
   /* playback start/stop positions */
   GstSegment segment;
-  gboolean segment_running;
   guint32  seqnum;
 
   GstEvent *event;
index 4dda50b..500fbf4 100644 (file)
@@ -110,16 +110,13 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%d",
         "subtitle/x-kate; application/x-kate")
     );
 
-static void gst_ogg_mux_base_init (gpointer g_class);
-static void gst_ogg_mux_class_init (GstOggMuxClass * klass);
-static void gst_ogg_mux_init (GstOggMux * ogg_mux);
 static void gst_ogg_mux_finalize (GObject * object);
 
 static GstFlowReturn
 gst_ogg_mux_collected (GstCollectPads * pads, GstOggMux * ogg_mux);
 static gboolean gst_ogg_mux_handle_src_event (GstPad * pad, GstEvent * event);
 static GstPad *gst_ogg_mux_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * name);
+    GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
 static void gst_ogg_mux_release_pad (GstElement * element, GstPad * pad);
 
 static void gst_ogg_mux_set_property (GObject * object,
@@ -129,57 +126,10 @@ static void gst_ogg_mux_get_property (GObject * object,
 static GstStateChangeReturn gst_ogg_mux_change_state (GstElement * element,
     GstStateChange transition);
 
-static GstElementClass *parent_class = NULL;
-
 /*static guint gst_ogg_mux_signals[LAST_SIGNAL] = { 0 }; */
-
-GType
-gst_ogg_mux_get_type (void)
-{
-  static GType ogg_mux_type = 0;
-
-  if (G_UNLIKELY (ogg_mux_type == 0)) {
-    static const GTypeInfo ogg_mux_info = {
-      sizeof (GstOggMuxClass),
-      gst_ogg_mux_base_init,
-      NULL,
-      (GClassInitFunc) gst_ogg_mux_class_init,
-      NULL,
-      NULL,
-      sizeof (GstOggMux),
-      0,
-      (GInstanceInitFunc) gst_ogg_mux_init,
-    };
-    static const GInterfaceInfo preset_info = {
-      NULL,
-      NULL,
-      NULL
-    };
-
-    ogg_mux_type =
-        g_type_register_static (GST_TYPE_ELEMENT, "GstOggMux", &ogg_mux_info,
-        0);
-
-    g_type_add_interface_static (ogg_mux_type, GST_TYPE_PRESET, &preset_info);
-  }
-  return ogg_mux_type;
-}
-
-static void
-gst_ogg_mux_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_factory));
-
-  gst_element_class_set_details_simple (element_class,
-      "Ogg muxer", "Codec/Muxer",
-      "mux ogg streams (info about ogg: http://xiph.org)",
-      "Wim Taymans <wim@fluendo.com>");
-}
+#define gst_ogg_mux_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstOggMux, gst_ogg_mux, GST_TYPE_ELEMENT,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL));
 
 static void
 gst_ogg_mux_class_init (GstOggMuxClass * klass)
@@ -190,12 +140,20 @@ gst_ogg_mux_class_init (GstOggMuxClass * klass)
   gobject_class = (GObjectClass *) klass;
   gstelement_class = (GstElementClass *) klass;
 
-  parent_class = g_type_class_peek_parent (klass);
-
   gobject_class->finalize = gst_ogg_mux_finalize;
   gobject_class->get_property = gst_ogg_mux_get_property;
   gobject_class->set_property = gst_ogg_mux_set_property;
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&src_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sink_factory));
+
+  gst_element_class_set_details_simple (gstelement_class,
+      "Ogg muxer", "Codec/Muxer",
+      "mux ogg streams (info about ogg: http://xiph.org)",
+      "Wim Taymans <wim@fluendo.com>");
+
   gstelement_class->request_new_pad = gst_ogg_mux_request_new_pad;
   gstelement_class->release_pad = gst_ogg_mux_release_pad;
 
@@ -323,26 +281,20 @@ gst_ogg_mux_sink_event (GstPad * pad, GstEvent * event)
   GST_DEBUG_OBJECT (pad, "Got %s event", GST_EVENT_TYPE_NAME (event));
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_NEWSEGMENT:{
-      gboolean update;
-      gdouble rate;
-      gdouble applied_rate;
-      GstFormat format;
-      gint64 start, stop, position;
+    case GST_EVENT_SEGMENT:
+    {
+      const GstSegment *segment;
 
-      gst_event_parse_new_segment_full (event, &update, &rate,
-          &applied_rate, &format, &start, &stop, &position);
+      gst_event_parse_segment (event, &segment);
 
       /* We don't support non time NEWSEGMENT events */
-      if (format != GST_FORMAT_TIME) {
+      if (segment->format != GST_FORMAT_TIME) {
         gst_event_unref (event);
         event = NULL;
         break;
       }
 
-      gst_segment_set_newsegment_full (&ogg_pad->segment, update, rate,
-          applied_rate, format, start, stop, position);
-
+      gst_segment_copy_into (segment, &ogg_pad->segment);
       break;
     }
     case GST_EVENT_FLUSH_STOP:{
@@ -391,7 +343,7 @@ gst_ogg_mux_generate_serialno (GstOggMux * ogg_mux)
 
 static GstPad *
 gst_ogg_mux_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * req_name)
+    GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
 {
   GstOggMux *ogg_mux;
   GstPad *newpad;
@@ -520,9 +472,8 @@ gst_ogg_mux_buffer_from_page (GstOggMux * mux, ogg_page * page, gboolean delta)
 
   /* allocate space for header and body */
   buffer = gst_buffer_new_and_alloc (page->header_len + page->body_len);
-  memcpy (GST_BUFFER_DATA (buffer), page->header, page->header_len);
-  memcpy (GST_BUFFER_DATA (buffer) + page->header_len,
-      page->body, page->body_len);
+  gst_buffer_fill (buffer, 0, page->header, page->header_len);
+  gst_buffer_fill (buffer, page->header_len, page->body, page->body_len);
 
   /* Here we set granulepos as our OFFSET_END to give easy direct access to
    * this value later. Before we push it, we reset this to OFFSET + SIZE
@@ -542,11 +493,9 @@ static GstFlowReturn
 gst_ogg_mux_push_buffer (GstOggMux * mux, GstBuffer * buffer,
     GstOggPadData * oggpad)
 {
-  GstCaps *caps;
-
   /* fix up OFFSET and OFFSET_END again */
   GST_BUFFER_OFFSET (buffer) = mux->offset;
-  mux->offset += GST_BUFFER_SIZE (buffer);
+  mux->offset += gst_buffer_get_size (buffer);
   GST_BUFFER_OFFSET_END (buffer) = mux->offset;
 
   /* Ensure we have monotonically increasing timestamps in the output. */
@@ -558,11 +507,6 @@ gst_ogg_mux_push_buffer (GstOggMux * mux, GstBuffer * buffer,
       mux->last_ts = run_time;
   }
 
-  caps = gst_pad_get_negotiated_caps (mux->srcpad);
-  gst_buffer_set_caps (buffer, caps);
-  if (caps)
-    gst_caps_unref (caps);
-
   return gst_pad_push (mux->srcpad, buffer);
 }
 
@@ -837,9 +781,10 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux)
           /* and we have one */
           ogg_packet packet;
           gboolean is_header;
+          gsize size;
 
-          packet.packet = GST_BUFFER_DATA (buf);
-          packet.bytes = GST_BUFFER_SIZE (buf);
+          packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+          packet.bytes = size;
 
           if (GST_BUFFER_OFFSET_END_IS_VALID (buf))
             packet.granulepos = GST_BUFFER_OFFSET_END (buf);
@@ -848,13 +793,15 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux)
 
           /* if we're not yet in data mode, ensure we're setup on the first packet */
           if (!pad->have_type) {
+            GstCaps *caps;
+
             /* Use headers in caps, if any; this will allow us to be resilient
              * to starting streams on the fly, and some streams (like VP8
              * at least) do not send headers packets, as other muxers don't
              * expect/need them. */
+            caps = gst_pad_get_current_caps (GST_PAD_CAST (pad));
             pad->have_type =
-                gst_ogg_stream_setup_map_from_caps_headers (&pad->map,
-                GST_BUFFER_CAPS (buf));
+                gst_ogg_stream_setup_map_from_caps_headers (&pad->map, caps);
 
             if (!pad->have_type) {
               /* fallback on the packet */
@@ -862,11 +809,13 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux)
             }
             if (!pad->have_type) {
               GST_ERROR_OBJECT (pad, "mapper didn't recognise input stream "
-                  "(pad caps: %" GST_PTR_FORMAT ")", GST_PAD_CAPS (pad));
+                  "(pad caps: %" GST_PTR_FORMAT ")", caps);
             } else {
               GST_DEBUG_OBJECT (pad, "caps detected: %" GST_PTR_FORMAT,
                   pad->map.caps);
             }
+            if (caps)
+              gst_caps_unref (caps);
           }
 
           if (pad->have_type)
@@ -874,6 +823,8 @@ gst_ogg_mux_queue_pads (GstOggMux * ogg_mux)
           else                  /* fallback (FIXME 0.11: remove IN_CAPS hack) */
             is_header = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
 
+          gst_buffer_unmap (buf, packet.packet, size);
+
           if (is_header) {
             GST_DEBUG_OBJECT (ogg_mux,
                 "got header buffer in control state, ignoring");
@@ -1019,7 +970,8 @@ gst_ogg_mux_set_header_on_caps (GstCaps * caps, GList * buffers)
     walk = walk->next;
 
     /* mark buffer */
-    GST_LOG ("Setting IN_CAPS on buffer of length %d", GST_BUFFER_SIZE (buf));
+    GST_LOG ("Setting IN_CAPS on buffer of length %d",
+        gst_buffer_get_size (buf));
     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
 
     g_value_init (&value, GST_TYPE_BUFFER);
@@ -1087,6 +1039,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
     GstCaps *caps;
     GstStructure *structure;
     GstBuffer *hbuf;
+    gsize size;
 
     pad = (GstOggPadData *) walk->data;
     thepad = pad->collect.pad;
@@ -1118,8 +1071,8 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
     }
 
     /* create a packet from the buffer */
-    packet.packet = GST_BUFFER_DATA (buf);
-    packet.bytes = GST_BUFFER_SIZE (buf);
+    packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+    packet.bytes = size;
     packet.granulepos = GST_BUFFER_OFFSET_END (buf);
     if (packet.granulepos == -1)
       packet.granulepos = 0;
@@ -1131,6 +1084,8 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
 
     /* swap the packet in */
     ogg_stream_packetin (&pad->map.stream, &packet);
+
+    gst_buffer_unmap (buf, packet.packet, size);
     gst_buffer_unref (buf);
 
     GST_LOG_OBJECT (thepad, "flushing out BOS page");
@@ -1183,12 +1138,13 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
       GstBuffer *buf = GST_BUFFER (hwalk->data);
       ogg_packet packet;
       ogg_page page;
+      gsize size;
 
       hwalk = hwalk->next;
 
       /* create a packet from the buffer */
-      packet.packet = GST_BUFFER_DATA (buf);
-      packet.bytes = GST_BUFFER_SIZE (buf);
+      packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+      packet.bytes = size;
       packet.granulepos = GST_BUFFER_OFFSET_END (buf);
       if (packet.granulepos == -1)
         packet.granulepos = 0;
@@ -1200,6 +1156,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
 
       /* swap the packet in */
       ogg_stream_packetin (&pad->map.stream, &packet);
+      gst_buffer_unmap (buf, packet.packet, size);
       gst_buffer_unref (buf);
 
       /* if last header, flush page */
@@ -1230,7 +1187,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
   /* hbufs holds all buffers for the headers now */
 
   /* create caps with the buffers */
-  caps = gst_pad_get_caps (mux->srcpad);
+  caps = gst_pad_get_caps (mux->srcpad, NULL);
   if (caps) {
     caps = gst_ogg_mux_set_header_on_caps (caps, hbufs);
     gst_pad_set_caps (mux->srcpad, caps);
@@ -1356,6 +1313,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
     GstOggPadData *pad = ogg_mux->pulling;
     gint64 duration;
     gboolean force_flush;
+    gsize size;
 
     GST_LOG_OBJECT (ogg_mux->pulling->collect.pad, "pulling from pad");
 
@@ -1379,8 +1337,8 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
           GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
     }
     /* create a packet from the buffer */
-    packet.packet = GST_BUFFER_DATA (buf);
-    packet.bytes = GST_BUFFER_SIZE (buf);
+    packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+    packet.bytes = size;
     packet.granulepos = GST_BUFFER_OFFSET_END (buf);
     if (packet.granulepos == -1)
       packet.granulepos = 0;
@@ -1469,6 +1427,7 @@ gst_ogg_mux_process_best_pad (GstOggMux * ogg_mux, GstOggPadData * best)
       GST_DEBUG_OBJECT (pad->collect.pad, "swapping in BOS packet");
 
     ogg_stream_packetin (&pad->map.stream, &packet);
+    gst_buffer_unmap (buf, packet.packet, size);
     pad->data_pushed = TRUE;
 
     gp_time = GST_BUFFER_OFFSET (pad->buffer);
index eae0acd..27738c2 100644 (file)
@@ -286,15 +286,14 @@ gst_ogg_parse_dispose (GObject * object)
 static GstFlowReturn
 gst_ogg_parse_submit_buffer (GstOggParse * ogg, GstBuffer * buffer)
 {
-  guint size;
+  gsize size;
   guint8 *data;
   gchar *oggbuffer;
   GstFlowReturn ret = GST_FLOW_OK;
 
-  size = GST_BUFFER_SIZE (buffer);
-  data = GST_BUFFER_DATA (buffer);
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
 
-  GST_DEBUG_OBJECT (ogg, "submitting %u bytes", size);
+  GST_DEBUG_OBJECT (ogg, "submitting %" G_GSIZE_FORMAT " bytes", size);
   if (G_UNLIKELY (size == 0))
     goto done;
 
@@ -314,6 +313,7 @@ gst_ogg_parse_submit_buffer (GstOggParse * ogg, GstBuffer * buffer)
   }
 
 done:
+  gst_buffer_unmap (buffer, data, size);
   gst_buffer_unref (buffer);
 
   return ret;
@@ -368,8 +368,8 @@ gst_ogg_parse_buffer_from_page (ogg_page * page,
   int size = page->header_len + page->body_len;
   GstBuffer *buf = gst_buffer_new_and_alloc (size);
 
-  memcpy (GST_BUFFER_DATA (buf), page->header, page->header_len);
-  memcpy (GST_BUFFER_DATA (buf) + page->header_len, page->body, page->body_len);
+  gst_buffer_fill (buf, 0, page->header, page->header_len);
+  gst_buffer_fill (buf, page->header_len, page->body, page->body_len);
 
   GST_BUFFER_TIMESTAMP (buf) = timestamp;
   GST_BUFFER_OFFSET (buf) = offset;
@@ -394,8 +394,9 @@ gst_ogg_parse_chain (GstPad * pad, GstBuffer * buffer)
 
   ogg = GST_OGG_PARSE (GST_OBJECT_PARENT (pad));
 
-  GST_LOG_OBJECT (ogg, "Chain function received buffer of size %d",
-      GST_BUFFER_SIZE (buffer));
+  GST_LOG_OBJECT (ogg,
+      "Chain function received buffer of size %" G_GSIZE_FORMAT,
+      gst_buffer_get_size (buffer));
 
   gst_ogg_parse_submit_buffer (ogg, buffer);
 
@@ -581,7 +582,7 @@ gst_ogg_parse_chain (GstPad * pad, GstBuffer * buffer)
               }
             }
 
-            caps = gst_pad_get_caps (ogg->srcpad);
+            caps = gst_pad_get_caps (ogg->srcpad, NULL);
             caps = gst_caps_make_writable (caps);
 
             structure = gst_caps_get_structure (caps, 0);
@@ -603,9 +604,6 @@ gst_ogg_parse_chain (GstPad * pad, GstBuffer * buffer)
               GstOggStream *stream = (GstOggStream *) l->data;
               GstBuffer *buf = GST_BUFFER (stream->headers->data);
 
-              buf = gst_buffer_make_metadata_writable (buf);
-              gst_buffer_set_caps (buf, caps);
-
               result = gst_pad_push (ogg->srcpad, buf);
               if (result != GST_FLOW_OK)
                 return result;
@@ -618,9 +616,6 @@ gst_ogg_parse_chain (GstPad * pad, GstBuffer * buffer)
               for (j = stream->headers->next; j != NULL; j = j->next) {
                 GstBuffer *buf = GST_BUFFER (j->data);
 
-                buf = gst_buffer_make_metadata_writable (buf);
-                gst_buffer_set_caps (buf, caps);
-
                 result = gst_pad_push (ogg->srcpad, buf);
                 if (result != GST_FLOW_OK)
                   return result;
@@ -647,10 +642,8 @@ gst_ogg_parse_chain (GstPad * pad, GstBuffer * buffer)
                   g_list_length (stream->unknown_pages) + 1);
 
               for (k = stream->unknown_pages; k != NULL; k = k->next) {
-                GstBuffer *buf;
+                GstBuffer *buf = GST_BUFFER (k->data);
 
-                buf = gst_buffer_make_metadata_writable (GST_BUFFER (k->data));
-                gst_buffer_set_caps (buf, caps);
                 result = gst_pad_push (ogg->srcpad, buf);
                 if (result != GST_FLOW_OK)
                   return result;
@@ -669,8 +662,8 @@ gst_ogg_parse_chain (GstPad * pad, GstBuffer * buffer)
             while (stream->stored_buffers) {
               GstBuffer *buf = stream->stored_buffers->data;
 
-              buf = gst_buffer_make_metadata_writable (buf);
-              gst_buffer_set_caps (buf, ogg->caps);
+              buf = gst_buffer_make_writable (buf);
+
               GST_BUFFER_TIMESTAMP (buf) = buffertimestamp;
               if (!keyframe) {
                 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
@@ -687,8 +680,7 @@ gst_ogg_parse_chain (GstPad * pad, GstBuffer * buffer)
                   stream->stored_buffers);
             }
 
-            pagebuffer = gst_buffer_make_metadata_writable (pagebuffer);
-            gst_buffer_set_caps (pagebuffer, ogg->caps);
+            pagebuffer = gst_buffer_make_writable (pagebuffer);
             if (!keyframe) {
               GST_BUFFER_FLAG_SET (pagebuffer, GST_BUFFER_FLAG_DELTA_UNIT);
             } else {
index e843f48..ed746ee 100644 (file)
@@ -303,19 +303,14 @@ static gboolean
 tag_list_from_vorbiscomment_packet (ogg_packet * packet,
     const guint8 * id_data, const guint id_data_length, GstTagList ** tags)
 {
-  GstBuffer *buf = NULL;
   gchar *encoder = NULL;
   GstTagList *list;
   gboolean ret = TRUE;
 
   g_return_val_if_fail (tags != NULL, FALSE);
 
-  buf = gst_buffer_new ();
-  GST_BUFFER_DATA (buf) = (guint8 *) packet->packet;
-  GST_BUFFER_SIZE (buf) = packet->bytes;
-
-  list = gst_tag_list_from_vorbiscomment_buffer (buf, id_data, id_data_length,
-      &encoder);
+  list = gst_tag_list_from_vorbiscomment (packet->packet, packet->bytes,
+      id_data, id_data_length, &encoder);
 
   if (!list) {
     GST_WARNING ("failed to decode vorbis comments");
@@ -335,8 +330,6 @@ exit:
     gst_tag_list_free (*tags);
   *tags = list;
 
-  gst_buffer_unref (buf);
-
   return ret;
 }
 
@@ -2056,11 +2049,14 @@ gboolean
 gst_ogg_stream_setup_map_from_caps_headers (GstOggStream * pad,
     const GstCaps * caps)
 {
+  GstBuffer *buf;
   const GstStructure *structure;
-  const GstBuffer *buf;
   const GValue *streamheader;
   const GValue *first_element;
   ogg_packet packet;
+  guint8 *data;
+  gsize size;
+  gboolean ret;
 
   GST_INFO ("Checking streamheader on caps %" GST_PTR_FORMAT, caps);
 
@@ -2093,16 +2089,26 @@ gst_ogg_stream_setup_map_from_caps_headers (GstOggStream * pad,
   }
 
   buf = gst_value_get_buffer (first_element);
-  if (buf == NULL || GST_BUFFER_SIZE (buf) == 0) {
+  if (buf == NULL) {
+    GST_ERROR ("no first streamheader buffer");
+    return FALSE;
+  }
+
+  data = gst_buffer_map (buf, &size, 0, GST_MAP_READ);
+  if (data == NULL || size == 0) {
     GST_ERROR ("invalid first streamheader buffer");
     return FALSE;
   }
 
-  GST_MEMDUMP ("streamheader", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  GST_MEMDUMP ("streamheader", data, size);
 
-  packet.packet = GST_BUFFER_DATA (buf);
-  packet.bytes = GST_BUFFER_SIZE (buf);
+  packet.packet = data;
+  packet.bytes = size;
 
   GST_INFO ("Found headers on caps, using those to determine type");
-  return gst_ogg_stream_setup_map (pad, &packet);
+  ret = gst_ogg_stream_setup_map (pad, &packet);
+
+  gst_buffer_unmap (buf, data, size);
+
+  return ret;
 }
index 6b054a2..4e9a962 100644 (file)
@@ -284,6 +284,7 @@ gst_ogm_audio_parse_base_init (GstOgmParseClass * klass)
   audio_src_templ = gst_pad_template_new ("src",
       GST_PAD_SRC, GST_PAD_SOMETIMES, caps);
   gst_element_class_add_pad_template (element_class, audio_src_templ);
+  gst_caps_unref (caps);
 }
 
 static void
@@ -302,6 +303,7 @@ gst_ogm_video_parse_base_init (GstOgmParseClass * klass)
   video_src_templ = gst_pad_template_new ("src",
       GST_PAD_SRC, GST_PAD_SOMETIMES, caps);
   gst_element_class_add_pad_template (element_class, video_src_templ);
+  gst_caps_unref (caps);
 }
 
 static void
@@ -320,6 +322,7 @@ gst_ogm_text_parse_base_init (GstOgmParseClass * klass)
   text_src_templ = gst_pad_template_new ("src",
       GST_PAD_SRC, GST_PAD_SOMETIMES, caps);
   gst_element_class_add_pad_template (element_class, text_src_templ);
+  gst_caps_unref (caps);
 }
 
 static void
@@ -622,16 +625,19 @@ gst_ogm_parse_stream_header (GstOgmParse * ogm, const guint8 * data, guint size)
     goto cannot_decode;
 
   if (ogm->srcpad) {
-    GstCaps *current_caps = GST_PAD_CAPS (ogm->srcpad);
-
-    if (current_caps && caps && !gst_caps_is_equal (current_caps, caps)) {
-      GST_WARNING_OBJECT (ogm, "Already an existing pad %s:%s",
-          GST_DEBUG_PAD_NAME (ogm->srcpad));
-      gst_pad_set_active (ogm->srcpad, FALSE);
-      gst_element_remove_pad (GST_ELEMENT (ogm), ogm->srcpad);
-      ogm->srcpad = NULL;
-    } else {
-      GST_DEBUG_OBJECT (ogm, "Existing pad has the same caps, do nothing");
+    GstCaps *current_caps = gst_pad_get_current_caps (ogm->srcpad);
+
+    if (current_caps) {
+      if (caps && !gst_caps_is_equal (current_caps, caps)) {
+        GST_WARNING_OBJECT (ogm, "Already an existing pad %s:%s",
+            GST_DEBUG_PAD_NAME (ogm->srcpad));
+        gst_pad_set_active (ogm->srcpad, FALSE);
+        gst_element_remove_pad (GST_ELEMENT (ogm), ogm->srcpad);
+        ogm->srcpad = NULL;
+      } else {
+        GST_DEBUG_OBJECT (ogm, "Existing pad has the same caps, do nothing");
+      }
+      gst_caps_unref (current_caps);
     }
   }
 
@@ -640,8 +646,8 @@ gst_ogm_parse_stream_header (GstOgmParse * ogm, const guint8 * data, guint size)
 
     ogm->srcpad = gst_pad_new_from_template (ogm->srcpadtempl, "src");
     gst_pad_use_fixed_caps (ogm->srcpad);
-    gst_pad_set_caps (ogm->srcpad, caps);
     gst_pad_set_active (ogm->srcpad, TRUE);
+    gst_pad_set_caps (ogm->srcpad, caps);
     gst_element_add_pad (GST_ELEMENT (ogm), ogm->srcpad);
     GST_INFO_OBJECT (ogm, "Added pad %s:%s with caps %" GST_PTR_FORMAT,
         GST_DEBUG_PAD_NAME (ogm->srcpad), caps);
@@ -714,8 +720,6 @@ gst_ogm_parse_comment_packet (GstOgmParse * ogm, GstBuffer * buf)
     /* do not push packet downstream, just let parent unref it */
     ret = GST_FLOW_OK;
   } else {
-    buf = gst_buffer_copy (buf);
-    gst_buffer_set_caps (buf, GST_PAD_CAPS (ogm->srcpad));
     ret = gst_pad_push (ogm->srcpad, buf);
   }
 
@@ -725,32 +729,27 @@ gst_ogm_parse_comment_packet (GstOgmParse * ogm, GstBuffer * buf)
 static void
 gst_ogm_text_parse_strip_trailing_zeroes (GstOgmParse * ogm, GstBuffer * buf)
 {
-  const guint8 *data;
-  guint size;
+  guint8 *data;
+  gsize size;
 
-  g_assert (gst_buffer_is_metadata_writable (buf));
+  g_assert (gst_buffer_is_writable (buf));
 
   /* zeroes are not valid UTF-8 characters, so strip them from output */
-  data = GST_BUFFER_DATA (buf);
-  size = GST_BUFFER_SIZE (buf);
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_WRITE);
   while (size > 0 && data[size - 1] == '\0') {
     --size;
   }
-
-  GST_BUFFER_SIZE (buf) = size;
+  gst_buffer_unmap (buf, data, size);
 }
 
 static GstFlowReturn
-gst_ogm_parse_data_packet (GstOgmParse * ogm, GstBuffer * buf)
+gst_ogm_parse_data_packet (GstOgmParse * ogm, GstBuffer * buf,
+    const guint8 * data, gsize size)
 {
   GstFlowReturn ret;
-  const guint8 *data;
   GstBuffer *sbuf;
   gboolean keyframe;
-  guint size, len, n, xsize = 0;
-
-  data = GST_BUFFER_DATA (buf);
-  size = GST_BUFFER_SIZE (buf);
+  guint len, n, xsize = 0;
 
   if ((data[0] & 0x01) != 0)
     goto invalid_startcode;
@@ -769,7 +768,9 @@ gst_ogm_parse_data_packet (GstOgmParse * ogm, GstBuffer * buf)
   GST_LOG_OBJECT (ogm, "[0x%02x] samples: %d, hdrbytes: %d, datasize: %d",
       data[0], xsize, len, size - len - 1);
 
-  sbuf = gst_buffer_create_sub (buf, len + 1, size - len - 1);
+  sbuf =
+      gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, len + 1,
+      size - len - 1);
 
   if (GST_BUFFER_OFFSET_END_IS_VALID (buf))
     ogm->next_granulepos = GST_BUFFER_OFFSET_END (buf);
@@ -823,7 +824,6 @@ gst_ogm_parse_data_packet (GstOgmParse * ogm, GstBuffer * buf)
   }
 
   if (ogm->srcpad) {
-    gst_buffer_set_caps (sbuf, GST_PAD_CAPS (ogm->srcpad));
     GST_LOG_OBJECT (ogm, "Pushing buffer with ts=%" GST_TIME_FORMAT,
         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sbuf)));
     ret = gst_pad_push (ogm->srcpad, sbuf);
@@ -857,9 +857,10 @@ gst_ogm_parse_chain (GstPad * pad, GstBuffer * buf)
 {
   GstFlowReturn ret = GST_FLOW_OK;
   GstOgmParse *ogm = GST_OGM_PARSE (GST_PAD_PARENT (pad));
-  guint8 *data = GST_BUFFER_DATA (buf);
-  guint size = GST_BUFFER_SIZE (buf);
+  guint8 *data;
+  gsize size;
 
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
   if (size < 1)
     goto buffer_too_small;
 
@@ -875,11 +876,12 @@ gst_ogm_parse_chain (GstPad * pad, GstBuffer * buf)
       break;
     }
     default:{
-      ret = gst_ogm_parse_data_packet (ogm, buf);
+      ret = gst_ogm_parse_data_packet (ogm, buf, data, size);
       break;
     }
   }
 
+  gst_buffer_unmap (buf, data, size);
   gst_buffer_unref (buf);
 
   if (ret != GST_FLOW_OK) {
@@ -892,6 +894,7 @@ gst_ogm_parse_chain (GstPad * pad, GstBuffer * buf)
 buffer_too_small:
   {
     GST_ELEMENT_ERROR (ogm, STREAM, DECODE, (NULL), ("buffer too small"));
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     return GST_FLOW_ERROR;
   }
index 2ffea22..417173b 100644 (file)
@@ -1,12 +1,14 @@
 plugin_LTLIBRARIES = libgstpango.la
 
 noinst_HEADERS = \
+        gstbasetextoverlay.h \
        gstclockoverlay.h \
        gsttextoverlay.h \
        gsttextrender.h \
        gsttimeoverlay.h
 
 libgstpango_la_SOURCES = \
+       gstbasetextoverlay.c \
        gstclockoverlay.c \
        gsttextoverlay.c \
        gsttextrender.c \
diff --git a/ext/pango/gstbasetextoverlay.c b/ext/pango/gstbasetextoverlay.c
new file mode 100644 (file)
index 0000000..25f913c
--- /dev/null
@@ -0,0 +1,2754 @@
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * Copyright (C) <2003> David Schleef <ds@schleef.org>
+ * Copyright (C) <2006> Julien Moutte <julien@moutte.net>
+ * Copyright (C) <2006> Zeeshan Ali <zeeshan.ali@nokia.com>
+ * Copyright (C) <2006-2008> Tim-Philipp Müller <tim centricular net>
+ * Copyright (C) <2009> Young-Ho Cha <ganadist@gmail.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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:element-textoverlay
+ * @see_also: #GstTextRender, #GstClockOverlay, #GstTimeOverlay, #GstSubParse
+ *
+ * This plugin renders text on top of a video stream. This can be either
+ * static text or text from buffers received on the text sink pad, e.g.
+ * as produced by the subparse element. If the text sink pad is not linked,
+ * the text set via the "text" property will be rendered. If the text sink
+ * pad is linked, text will be rendered as it is received on that pad,
+ * honouring and matching the buffer timestamps of both input streams.
+ *
+ * The text can contain newline characters and text wrapping is enabled by
+ * default.
+ *
+ * <refsect2>
+ * <title>Example launch lines</title>
+ * |[
+ * gst-launch -v videotestsrc ! textoverlay text="Room A" valign=top halign=left ! xvimagesink
+ * ]| Here is a simple pipeline that displays a static text in the top left
+ * corner of the video picture
+ * |[
+ * gst-launch -v filesrc location=subtitles.srt ! subparse ! txt.   videotestsrc ! timeoverlay ! textoverlay name=txt shaded-background=yes ! xvimagesink
+ * ]| Here is another pipeline that displays subtitles from an .srt subtitle
+ * file, centered at the bottom of the picture and with a rectangular shading
+ * around the text in the background:
+ * <para>
+ * If you do not have such a subtitle file, create one looking like this
+ * in a text editor:
+ * |[
+ * 1
+ * 00:00:03,000 --> 00:00:05,000
+ * Hello? (3-5s)
+ *
+ * 2
+ * 00:00:08,000 --> 00:00:13,000
+ * Yes, this is a subtitle. Don&apos;t
+ * you like it? (8-13s)
+ *
+ * 3
+ * 00:00:18,826 --> 00:01:02,886
+ * Uh? What are you talking about?
+ * I don&apos;t understand  (18-62s)
+ * ]|
+ * </para>
+ * </refsect2>
+ */
+
+/* FIXME: alloc segment as part of instance struct */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gst/video/video.h>
+
+#include "gstbasetextoverlay.h"
+#include "gsttextoverlay.h"
+#include "gsttimeoverlay.h"
+#include "gstclockoverlay.h"
+#include "gsttextrender.h"
+#include <string.h>
+
+/* FIXME:
+ *  - use proper strides and offset for I420
+ *  - if text is wider than the video picture, it does not get
+ *    clipped properly during blitting (if wrapping is disabled)
+ *  - make 'shading_value' a property (or enum:  light/normal/dark/verydark)?
+ */
+
+GST_DEBUG_CATEGORY (pango_debug);
+#define GST_CAT_DEFAULT pango_debug
+
+#define DEFAULT_PROP_TEXT      ""
+#define DEFAULT_PROP_SHADING   FALSE
+#define DEFAULT_PROP_VALIGNMENT        GST_BASE_TEXT_OVERLAY_VALIGN_BASELINE
+#define DEFAULT_PROP_HALIGNMENT        GST_BASE_TEXT_OVERLAY_HALIGN_CENTER
+#define DEFAULT_PROP_VALIGN    "baseline"
+#define DEFAULT_PROP_HALIGN    "center"
+#define DEFAULT_PROP_XPAD      25
+#define DEFAULT_PROP_YPAD      25
+#define DEFAULT_PROP_DELTAX    0
+#define DEFAULT_PROP_DELTAY    0
+#define DEFAULT_PROP_XPOS       0.5
+#define DEFAULT_PROP_YPOS       0.5
+#define DEFAULT_PROP_WRAP_MODE  GST_BASE_TEXT_OVERLAY_WRAP_MODE_WORD_CHAR
+#define DEFAULT_PROP_FONT_DESC ""
+#define DEFAULT_PROP_SILENT    FALSE
+#define DEFAULT_PROP_LINE_ALIGNMENT GST_BASE_TEXT_OVERLAY_LINE_ALIGN_CENTER
+#define DEFAULT_PROP_WAIT_TEXT TRUE
+#define DEFAULT_PROP_AUTO_ADJUST_SIZE TRUE
+#define DEFAULT_PROP_VERTICAL_RENDER  FALSE
+#define DEFAULT_PROP_COLOR      0xffffffff
+
+/* make a property of me */
+#define DEFAULT_SHADING_VALUE    -80
+
+#define MINIMUM_OUTLINE_OFFSET 1.0
+#define DEFAULT_SCALE_BASIS    640
+
+#define COMP_Y(ret, r, g, b) \
+{ \
+   ret = (int) (((19595 * r) >> 16) + ((38470 * g) >> 16) + ((7471 * b) >> 16)); \
+   ret = CLAMP (ret, 0, 255); \
+}
+
+#define COMP_U(ret, r, g, b) \
+{ \
+   ret = (int) (-((11059 * r) >> 16) - ((21709 * g) >> 16) + ((32768 * b) >> 16) + 128); \
+   ret = CLAMP (ret, 0, 255); \
+}
+
+#define COMP_V(ret, r, g, b) \
+{ \
+   ret = (int) (((32768 * r) >> 16) - ((27439 * g) >> 16) - ((5329 * b) >> 16) + 128); \
+   ret = CLAMP (ret, 0, 255); \
+}
+
+#define BLEND(ret, alpha, v0, v1) \
+{ \
+       ret = (v0 * alpha + v1 * (255 - alpha)) / 255; \
+}
+
+#define OVER(ret, alphaA, Ca, alphaB, Cb, alphaNew)    \
+{ \
+    gint _tmp; \
+    _tmp = (Ca * alphaA + Cb * alphaB * (255 - alphaA) / 255) / alphaNew; \
+    ret = CLAMP (_tmp, 0, 255); \
+}
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+# define CAIRO_ARGB_A 3
+# define CAIRO_ARGB_R 2
+# define CAIRO_ARGB_G 1
+# define CAIRO_ARGB_B 0
+#else
+# define CAIRO_ARGB_A 0
+# define CAIRO_ARGB_R 1
+# define CAIRO_ARGB_G 2
+# define CAIRO_ARGB_B 3
+#endif
+
+enum
+{
+  PROP_0,
+  PROP_TEXT,
+  PROP_SHADING,
+  PROP_VALIGN,                  /* deprecated */
+  PROP_HALIGN,                  /* deprecated */
+  PROP_HALIGNMENT,
+  PROP_VALIGNMENT,
+  PROP_XPAD,
+  PROP_YPAD,
+  PROP_DELTAX,
+  PROP_DELTAY,
+  PROP_XPOS,
+  PROP_YPOS,
+  PROP_WRAP_MODE,
+  PROP_FONT_DESC,
+  PROP_SILENT,
+  PROP_LINE_ALIGNMENT,
+  PROP_WAIT_TEXT,
+  PROP_AUTO_ADJUST_SIZE,
+  PROP_VERTICAL_RENDER,
+  PROP_COLOR,
+  PROP_LAST
+};
+
+static GstStaticPadTemplate src_template_factory =
+    GST_STATIC_PAD_TEMPLATE ("src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";"
+        GST_VIDEO_CAPS_RGBx ";"
+        GST_VIDEO_CAPS_xRGB ";"
+        GST_VIDEO_CAPS_xBGR ";"
+        GST_VIDEO_CAPS_RGBA ";"
+        GST_VIDEO_CAPS_BGRA ";"
+        GST_VIDEO_CAPS_ARGB ";"
+        GST_VIDEO_CAPS_ABGR ";"
+        GST_VIDEO_CAPS_YUV ("{AYUV, I420, UYVY, NV12, NV21}"))
+    );
+
+static GstStaticPadTemplate video_sink_template_factory =
+    GST_STATIC_PAD_TEMPLATE ("video_sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";"
+        GST_VIDEO_CAPS_RGBx ";"
+        GST_VIDEO_CAPS_xRGB ";"
+        GST_VIDEO_CAPS_xBGR ";"
+        GST_VIDEO_CAPS_RGBA ";"
+        GST_VIDEO_CAPS_BGRA ";"
+        GST_VIDEO_CAPS_ARGB ";"
+        GST_VIDEO_CAPS_ABGR ";"
+        GST_VIDEO_CAPS_YUV ("{AYUV, I420, UYVY, NV12, NV21}"))
+    );
+
+#define GST_TYPE_BASE_TEXT_OVERLAY_VALIGN (gst_base_text_overlay_valign_get_type())
+static GType
+gst_base_text_overlay_valign_get_type (void)
+{
+  static GType base_text_overlay_valign_type = 0;
+  static const GEnumValue base_text_overlay_valign[] = {
+    {GST_BASE_TEXT_OVERLAY_VALIGN_BASELINE, "baseline", "baseline"},
+    {GST_BASE_TEXT_OVERLAY_VALIGN_BOTTOM, "bottom", "bottom"},
+    {GST_BASE_TEXT_OVERLAY_VALIGN_TOP, "top", "top"},
+    {GST_BASE_TEXT_OVERLAY_VALIGN_POS, "position", "position"},
+    {GST_BASE_TEXT_OVERLAY_VALIGN_CENTER, "center", "center"},
+    {0, NULL, NULL},
+  };
+
+  if (!base_text_overlay_valign_type) {
+    base_text_overlay_valign_type =
+        g_enum_register_static ("GstBaseTextOverlayVAlign",
+        base_text_overlay_valign);
+  }
+  return base_text_overlay_valign_type;
+}
+
+#define GST_TYPE_BASE_TEXT_OVERLAY_HALIGN (gst_base_text_overlay_halign_get_type())
+static GType
+gst_base_text_overlay_halign_get_type (void)
+{
+  static GType base_text_overlay_halign_type = 0;
+  static const GEnumValue base_text_overlay_halign[] = {
+    {GST_BASE_TEXT_OVERLAY_HALIGN_LEFT, "left", "left"},
+    {GST_BASE_TEXT_OVERLAY_HALIGN_CENTER, "center", "center"},
+    {GST_BASE_TEXT_OVERLAY_HALIGN_RIGHT, "right", "right"},
+    {GST_BASE_TEXT_OVERLAY_HALIGN_POS, "position", "position"},
+    {0, NULL, NULL},
+  };
+
+  if (!base_text_overlay_halign_type) {
+    base_text_overlay_halign_type =
+        g_enum_register_static ("GstBaseTextOverlayHAlign",
+        base_text_overlay_halign);
+  }
+  return base_text_overlay_halign_type;
+}
+
+
+#define GST_TYPE_BASE_TEXT_OVERLAY_WRAP_MODE (gst_base_text_overlay_wrap_mode_get_type())
+static GType
+gst_base_text_overlay_wrap_mode_get_type (void)
+{
+  static GType base_text_overlay_wrap_mode_type = 0;
+  static const GEnumValue base_text_overlay_wrap_mode[] = {
+    {GST_BASE_TEXT_OVERLAY_WRAP_MODE_NONE, "none", "none"},
+    {GST_BASE_TEXT_OVERLAY_WRAP_MODE_WORD, "word", "word"},
+    {GST_BASE_TEXT_OVERLAY_WRAP_MODE_CHAR, "char", "char"},
+    {GST_BASE_TEXT_OVERLAY_WRAP_MODE_WORD_CHAR, "wordchar", "wordchar"},
+    {0, NULL, NULL},
+  };
+
+  if (!base_text_overlay_wrap_mode_type) {
+    base_text_overlay_wrap_mode_type =
+        g_enum_register_static ("GstBaseTextOverlayWrapMode",
+        base_text_overlay_wrap_mode);
+  }
+  return base_text_overlay_wrap_mode_type;
+}
+
+#define GST_TYPE_BASE_TEXT_OVERLAY_LINE_ALIGN (gst_base_text_overlay_line_align_get_type())
+static GType
+gst_base_text_overlay_line_align_get_type (void)
+{
+  static GType base_text_overlay_line_align_type = 0;
+  static const GEnumValue base_text_overlay_line_align[] = {
+    {GST_BASE_TEXT_OVERLAY_LINE_ALIGN_LEFT, "left", "left"},
+    {GST_BASE_TEXT_OVERLAY_LINE_ALIGN_CENTER, "center", "center"},
+    {GST_BASE_TEXT_OVERLAY_LINE_ALIGN_RIGHT, "right", "right"},
+    {0, NULL, NULL}
+  };
+
+  if (!base_text_overlay_line_align_type) {
+    base_text_overlay_line_align_type =
+        g_enum_register_static ("GstBaseTextOverlayLineAlign",
+        base_text_overlay_line_align);
+  }
+  return base_text_overlay_line_align_type;
+}
+
+#define GST_BASE_TEXT_OVERLAY_GET_COND(ov) (((GstBaseTextOverlay *)ov)->cond)
+#define GST_BASE_TEXT_OVERLAY_WAIT(ov)     (g_cond_wait (GST_BASE_TEXT_OVERLAY_GET_COND (ov), GST_OBJECT_GET_LOCK (ov)))
+#define GST_BASE_TEXT_OVERLAY_SIGNAL(ov)   (g_cond_signal (GST_BASE_TEXT_OVERLAY_GET_COND (ov)))
+#define GST_BASE_TEXT_OVERLAY_BROADCAST(ov)(g_cond_broadcast (GST_BASE_TEXT_OVERLAY_GET_COND (ov)))
+
+static GstElementClass *parent_class = NULL;
+static void gst_base_text_overlay_base_init (gpointer g_class);
+static void gst_base_text_overlay_class_init (GstBaseTextOverlayClass * klass);
+static void gst_base_text_overlay_init (GstBaseTextOverlay * overlay,
+    GstBaseTextOverlayClass * klass);
+
+static GstStateChangeReturn gst_base_text_overlay_change_state (GstElement *
+    element, GstStateChange transition);
+
+static GstCaps *gst_base_text_overlay_getcaps (GstPad * pad, GstCaps * filter);
+static gboolean gst_base_text_overlay_setcaps (GstPad * pad, GstCaps * caps);
+static gboolean gst_base_text_overlay_setcaps_txt (GstPad * pad,
+    GstCaps * caps);
+static gboolean gst_base_text_overlay_src_event (GstPad * pad,
+    GstEvent * event);
+static gboolean gst_base_text_overlay_src_query (GstPad * pad,
+    GstQuery * query);
+
+static gboolean gst_base_text_overlay_video_event (GstPad * pad,
+    GstEvent * event);
+static GstFlowReturn gst_base_text_overlay_video_chain (GstPad * pad,
+    GstBuffer * buffer);
+
+static gboolean gst_base_text_overlay_text_event (GstPad * pad,
+    GstEvent * event);
+static GstFlowReturn gst_base_text_overlay_text_chain (GstPad * pad,
+    GstBuffer * buffer);
+static GstPadLinkReturn gst_base_text_overlay_text_pad_link (GstPad * pad,
+    GstPad * peer);
+static void gst_base_text_overlay_text_pad_unlink (GstPad * pad);
+static void gst_base_text_overlay_pop_text (GstBaseTextOverlay * overlay);
+static void gst_base_text_overlay_update_render_mode (GstBaseTextOverlay *
+    overlay);
+
+static void gst_base_text_overlay_finalize (GObject * object);
+static void gst_base_text_overlay_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_base_text_overlay_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+static void
+gst_base_text_overlay_adjust_values_with_fontdesc (GstBaseTextOverlay * overlay,
+    PangoFontDescription * desc);
+
+GType
+gst_base_text_overlay_get_type (void)
+{
+  static GType type = 0;
+
+  if (g_once_init_enter ((gsize *) & type)) {
+    static const GTypeInfo info = {
+      sizeof (GstBaseTextOverlayClass),
+      (GBaseInitFunc) gst_base_text_overlay_base_init,
+      NULL,
+      (GClassInitFunc) gst_base_text_overlay_class_init,
+      NULL,
+      NULL,
+      sizeof (GstBaseTextOverlay),
+      0,
+      (GInstanceInitFunc) gst_base_text_overlay_init,
+    };
+
+    g_once_init_leave ((gsize *) & type,
+        g_type_register_static (GST_TYPE_ELEMENT, "GstBaseTextOverlay", &info,
+            0));
+  }
+
+  return type;
+}
+
+static gchar *
+gst_base_text_overlay_get_text (GstBaseTextOverlay * overlay,
+    GstBuffer * video_frame)
+{
+  return g_strdup (overlay->default_text);
+}
+
+static void
+gst_base_text_overlay_base_init (gpointer g_class)
+{
+  GstBaseTextOverlayClass *klass = GST_BASE_TEXT_OVERLAY_CLASS (g_class);
+  PangoFontMap *fontmap;
+
+  /* Only lock for the subclasses here, the base class
+   * doesn't have this mutex yet and it's not necessary
+   * here */
+  if (klass->pango_lock)
+    g_mutex_lock (klass->pango_lock);
+  fontmap = pango_cairo_font_map_get_default ();
+  klass->pango_context =
+      pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
+  if (klass->pango_lock)
+    g_mutex_unlock (klass->pango_lock);
+}
+
+static void
+gst_base_text_overlay_class_init (GstBaseTextOverlayClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class->finalize = gst_base_text_overlay_finalize;
+  gobject_class->set_property = gst_base_text_overlay_set_property;
+  gobject_class->get_property = gst_base_text_overlay_get_property;
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&src_template_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&video_sink_template_factory));
+
+  gstelement_class->change_state =
+      GST_DEBUG_FUNCPTR (gst_base_text_overlay_change_state);
+
+  klass->pango_lock = g_mutex_new ();
+
+  klass->get_text = gst_base_text_overlay_get_text;
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TEXT,
+      g_param_spec_string ("text", "text",
+          "Text to be display.", DEFAULT_PROP_TEXT,
+          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SHADING,
+      g_param_spec_boolean ("shaded-background", "shaded background",
+          "Whether to shade the background under the text area",
+          DEFAULT_PROP_SHADING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_VALIGNMENT,
+      g_param_spec_enum ("valignment", "vertical alignment",
+          "Vertical alignment of the text", GST_TYPE_BASE_TEXT_OVERLAY_VALIGN,
+          DEFAULT_PROP_VALIGNMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_HALIGNMENT,
+      g_param_spec_enum ("halignment", "horizontal alignment",
+          "Horizontal alignment of the text", GST_TYPE_BASE_TEXT_OVERLAY_HALIGN,
+          DEFAULT_PROP_HALIGNMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_VALIGN,
+      g_param_spec_string ("valign", "vertical alignment",
+          "Vertical alignment of the text (deprecated; use valignment)",
+          DEFAULT_PROP_VALIGN, G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_HALIGN,
+      g_param_spec_string ("halign", "horizontal alignment",
+          "Horizontal alignment of the text (deprecated; use halignment)",
+          DEFAULT_PROP_HALIGN, G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_XPAD,
+      g_param_spec_int ("xpad", "horizontal paddding",
+          "Horizontal paddding when using left/right alignment", 0, G_MAXINT,
+          DEFAULT_PROP_XPAD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_YPAD,
+      g_param_spec_int ("ypad", "vertical padding",
+          "Vertical padding when using top/bottom alignment", 0, G_MAXINT,
+          DEFAULT_PROP_YPAD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DELTAX,
+      g_param_spec_int ("deltax", "X position modifier",
+          "Shift X position to the left or to the right. Unit is pixels.",
+          G_MININT, G_MAXINT, DEFAULT_PROP_DELTAX,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DELTAY,
+      g_param_spec_int ("deltay", "Y position modifier",
+          "Shift Y position up or down. Unit is pixels.", G_MININT, G_MAXINT,
+          DEFAULT_PROP_DELTAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  /**
+   * GstBaseTextOverlay:xpos
+   *
+   * Horizontal position of the rendered text when using positioned alignment.
+   *
+   * Since: 0.10.31
+   **/
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_XPOS,
+      g_param_spec_double ("xpos", "horizontal position",
+          "Horizontal position when using position alignment", 0, 1.0,
+          DEFAULT_PROP_XPOS,
+          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
+  /**
+   * GstBaseTextOverlay:ypos
+   *
+   * Vertical position of the rendered text when using positioned alignment.
+   *
+   * Since: 0.10.31
+   **/
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_YPOS,
+      g_param_spec_double ("ypos", "vertical position",
+          "Vertical position when using position alignment", 0, 1.0,
+          DEFAULT_PROP_YPOS,
+          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_WRAP_MODE,
+      g_param_spec_enum ("wrap-mode", "wrap mode",
+          "Whether to wrap the text and if so how.",
+          GST_TYPE_BASE_TEXT_OVERLAY_WRAP_MODE, DEFAULT_PROP_WRAP_MODE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FONT_DESC,
+      g_param_spec_string ("font-desc", "font description",
+          "Pango font description of font to be used for rendering. "
+          "See documentation of pango_font_description_from_string "
+          "for syntax.", DEFAULT_PROP_FONT_DESC,
+          G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+  /**
+   * GstBaseTextOverlay:color
+   *
+   * Color of the rendered text.
+   *
+   * Since: 0.10.31
+   **/
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_COLOR,
+      g_param_spec_uint ("color", "Color",
+          "Color to use for text (big-endian ARGB).", 0, G_MAXUINT32,
+          DEFAULT_PROP_COLOR,
+          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstBaseTextOverlay:line-alignment
+   *
+   * Alignment of text lines relative to each other (for multi-line text)
+   *
+   * Since: 0.10.15
+   **/
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LINE_ALIGNMENT,
+      g_param_spec_enum ("line-alignment", "line alignment",
+          "Alignment of text lines relative to each other.",
+          GST_TYPE_BASE_TEXT_OVERLAY_LINE_ALIGN, DEFAULT_PROP_LINE_ALIGNMENT,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  /**
+   * GstBaseTextOverlay:silent
+   *
+   * If set, no text is rendered. Useful to switch off text rendering
+   * temporarily without removing the textoverlay element from the pipeline.
+   *
+   * Since: 0.10.15
+   **/
+  /* FIXME 0.11: rename to "visible" or "text-visible" or "render-text" */
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SILENT,
+      g_param_spec_boolean ("silent", "silent",
+          "Whether to render the text string",
+          DEFAULT_PROP_SILENT,
+          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
+  /**
+   * GstBaseTextOverlay:wait-text
+   *
+   * If set, the video will block until a subtitle is received on the text pad.
+   * If video and subtitles are sent in sync, like from the same demuxer, this
+   * property should be set.
+   *
+   * Since: 0.10.20
+   **/
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_WAIT_TEXT,
+      g_param_spec_boolean ("wait-text", "Wait Text",
+          "Whether to wait for subtitles",
+          DEFAULT_PROP_WAIT_TEXT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass),
+      PROP_AUTO_ADJUST_SIZE, g_param_spec_boolean ("auto-resize", "auto resize",
+          "Automatically adjust font size to screen-size.",
+          DEFAULT_PROP_AUTO_ADJUST_SIZE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_VERTICAL_RENDER,
+      g_param_spec_boolean ("vertical-render", "vertical render",
+          "Vertical Render.", DEFAULT_PROP_VERTICAL_RENDER,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+}
+
+static void
+gst_base_text_overlay_finalize (GObject * object)
+{
+  GstBaseTextOverlay *overlay = GST_BASE_TEXT_OVERLAY (object);
+
+  g_free (overlay->default_text);
+
+  if (overlay->text_image) {
+    g_free (overlay->text_image);
+    overlay->text_image = NULL;
+  }
+
+  if (overlay->layout) {
+    g_object_unref (overlay->layout);
+    overlay->layout = NULL;
+  }
+
+  if (overlay->text_buffer) {
+    gst_buffer_unref (overlay->text_buffer);
+    overlay->text_buffer = NULL;
+  }
+
+  if (overlay->cond) {
+    g_cond_free (overlay->cond);
+    overlay->cond = NULL;
+  }
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_base_text_overlay_init (GstBaseTextOverlay * overlay,
+    GstBaseTextOverlayClass * klass)
+{
+  GstPadTemplate *template;
+  PangoFontDescription *desc;
+
+  /* video sink */
+  template = gst_static_pad_template_get (&video_sink_template_factory);
+  overlay->video_sinkpad = gst_pad_new_from_template (template, "video_sink");
+  gst_object_unref (template);
+  gst_pad_set_getcaps_function (overlay->video_sinkpad,
+      GST_DEBUG_FUNCPTR (gst_base_text_overlay_getcaps));
+  gst_pad_set_setcaps_function (overlay->video_sinkpad,
+      GST_DEBUG_FUNCPTR (gst_base_text_overlay_setcaps));
+  gst_pad_set_event_function (overlay->video_sinkpad,
+      GST_DEBUG_FUNCPTR (gst_base_text_overlay_video_event));
+  gst_pad_set_chain_function (overlay->video_sinkpad,
+      GST_DEBUG_FUNCPTR (gst_base_text_overlay_video_chain));
+  gst_element_add_pad (GST_ELEMENT (overlay), overlay->video_sinkpad);
+
+  template =
+      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (klass),
+      "text_sink");
+  if (template) {
+    /* text sink */
+    overlay->text_sinkpad = gst_pad_new_from_template (template, "text_sink");
+    gst_object_unref (template);
+
+    gst_pad_set_setcaps_function (overlay->text_sinkpad,
+        GST_DEBUG_FUNCPTR (gst_base_text_overlay_setcaps_txt));
+    gst_pad_set_event_function (overlay->text_sinkpad,
+        GST_DEBUG_FUNCPTR (gst_base_text_overlay_text_event));
+    gst_pad_set_chain_function (overlay->text_sinkpad,
+        GST_DEBUG_FUNCPTR (gst_base_text_overlay_text_chain));
+    gst_pad_set_link_function (overlay->text_sinkpad,
+        GST_DEBUG_FUNCPTR (gst_base_text_overlay_text_pad_link));
+    gst_pad_set_unlink_function (overlay->text_sinkpad,
+        GST_DEBUG_FUNCPTR (gst_base_text_overlay_text_pad_unlink));
+    gst_element_add_pad (GST_ELEMENT (overlay), overlay->text_sinkpad);
+  }
+
+  /* (video) source */
+  template = gst_static_pad_template_get (&src_template_factory);
+  overlay->srcpad = gst_pad_new_from_template (template, "src");
+  gst_object_unref (template);
+  gst_pad_set_getcaps_function (overlay->srcpad,
+      GST_DEBUG_FUNCPTR (gst_base_text_overlay_getcaps));
+  gst_pad_set_event_function (overlay->srcpad,
+      GST_DEBUG_FUNCPTR (gst_base_text_overlay_src_event));
+  gst_pad_set_query_function (overlay->srcpad,
+      GST_DEBUG_FUNCPTR (gst_base_text_overlay_src_query));
+  gst_element_add_pad (GST_ELEMENT (overlay), overlay->srcpad);
+
+  g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
+  overlay->line_align = DEFAULT_PROP_LINE_ALIGNMENT;
+  overlay->layout =
+      pango_layout_new (GST_BASE_TEXT_OVERLAY_GET_CLASS
+      (overlay)->pango_context);
+  desc =
+      pango_context_get_font_description (GST_BASE_TEXT_OVERLAY_GET_CLASS
+      (overlay)->pango_context);
+  gst_base_text_overlay_adjust_values_with_fontdesc (overlay, desc);
+
+  overlay->color = DEFAULT_PROP_COLOR;
+  overlay->halign = DEFAULT_PROP_HALIGNMENT;
+  overlay->valign = DEFAULT_PROP_VALIGNMENT;
+  overlay->xpad = DEFAULT_PROP_XPAD;
+  overlay->ypad = DEFAULT_PROP_YPAD;
+  overlay->deltax = DEFAULT_PROP_DELTAX;
+  overlay->deltay = DEFAULT_PROP_DELTAY;
+  overlay->xpos = DEFAULT_PROP_XPOS;
+  overlay->ypos = DEFAULT_PROP_YPOS;
+
+  overlay->wrap_mode = DEFAULT_PROP_WRAP_MODE;
+
+  overlay->want_shading = DEFAULT_PROP_SHADING;
+  overlay->shading_value = DEFAULT_SHADING_VALUE;
+  overlay->silent = DEFAULT_PROP_SILENT;
+  overlay->wait_text = DEFAULT_PROP_WAIT_TEXT;
+  overlay->auto_adjust_size = DEFAULT_PROP_AUTO_ADJUST_SIZE;
+
+  overlay->default_text = g_strdup (DEFAULT_PROP_TEXT);
+  overlay->need_render = TRUE;
+  overlay->text_image = NULL;
+  overlay->use_vertical_render = DEFAULT_PROP_VERTICAL_RENDER;
+  gst_base_text_overlay_update_render_mode (overlay);
+
+  overlay->fps_n = 0;
+  overlay->fps_d = 1;
+
+  overlay->text_buffer = NULL;
+  overlay->text_linked = FALSE;
+  overlay->cond = g_cond_new ();
+  gst_segment_init (&overlay->segment, GST_FORMAT_TIME);
+  g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
+}
+
+static void
+gst_base_text_overlay_update_wrap_mode (GstBaseTextOverlay * overlay)
+{
+  if (overlay->wrap_mode == GST_BASE_TEXT_OVERLAY_WRAP_MODE_NONE) {
+    GST_DEBUG_OBJECT (overlay, "Set wrap mode NONE");
+    pango_layout_set_width (overlay->layout, -1);
+  } else {
+    int width;
+
+    if (overlay->auto_adjust_size) {
+      width = DEFAULT_SCALE_BASIS * PANGO_SCALE;
+      if (overlay->use_vertical_render) {
+        width = width * (overlay->height - overlay->ypad * 2) / overlay->width;
+      }
+    } else {
+      width =
+          (overlay->use_vertical_render ? overlay->height : overlay->width) *
+          PANGO_SCALE;
+    }
+
+    GST_DEBUG_OBJECT (overlay, "Set layout width %d", overlay->width);
+    GST_DEBUG_OBJECT (overlay, "Set wrap mode    %d", overlay->wrap_mode);
+    pango_layout_set_width (overlay->layout, width);
+    pango_layout_set_wrap (overlay->layout, (PangoWrapMode) overlay->wrap_mode);
+  }
+}
+
+static void
+gst_base_text_overlay_update_render_mode (GstBaseTextOverlay * overlay)
+{
+  PangoMatrix matrix = PANGO_MATRIX_INIT;
+  PangoContext *context = pango_layout_get_context (overlay->layout);
+
+  if (overlay->use_vertical_render) {
+    pango_matrix_rotate (&matrix, -90);
+    pango_context_set_base_gravity (context, PANGO_GRAVITY_AUTO);
+    pango_context_set_matrix (context, &matrix);
+    pango_layout_set_alignment (overlay->layout, PANGO_ALIGN_LEFT);
+  } else {
+    pango_context_set_base_gravity (context, PANGO_GRAVITY_SOUTH);
+    pango_context_set_matrix (context, &matrix);
+    pango_layout_set_alignment (overlay->layout, overlay->line_align);
+  }
+}
+
+static gboolean
+gst_base_text_overlay_setcaps_txt (GstPad * pad, GstCaps * caps)
+{
+  GstBaseTextOverlay *overlay;
+  GstStructure *structure;
+
+  overlay = GST_BASE_TEXT_OVERLAY (gst_pad_get_parent (pad));
+
+  structure = gst_caps_get_structure (caps, 0);
+  overlay->have_pango_markup =
+      gst_structure_has_name (structure, "text/x-pango-markup");
+
+  gst_object_unref (overlay);
+
+  return TRUE;
+}
+
+/* FIXME: upstream nego (e.g. when the video window is resized) */
+
+static gboolean
+gst_base_text_overlay_setcaps (GstPad * pad, GstCaps * caps)
+{
+  GstBaseTextOverlay *overlay;
+  GstStructure *structure;
+  gboolean ret = FALSE;
+  const GValue *fps;
+
+  if (!GST_PAD_IS_SINK (pad))
+    return TRUE;
+
+  g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
+
+  overlay = GST_BASE_TEXT_OVERLAY (gst_pad_get_parent (pad));
+
+  overlay->width = 0;
+  overlay->height = 0;
+  structure = gst_caps_get_structure (caps, 0);
+  fps = gst_structure_get_value (structure, "framerate");
+
+  if (fps
+      && gst_video_format_parse_caps (caps, &overlay->format, &overlay->width,
+          &overlay->height)) {
+    ret = gst_pad_set_caps (overlay->srcpad, caps);
+  }
+
+  overlay->fps_n = gst_value_get_fraction_numerator (fps);
+  overlay->fps_d = gst_value_get_fraction_denominator (fps);
+
+  if (ret) {
+    GST_OBJECT_LOCK (overlay);
+    g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
+    gst_base_text_overlay_update_wrap_mode (overlay);
+    g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
+    GST_OBJECT_UNLOCK (overlay);
+  }
+
+  gst_object_unref (overlay);
+
+  return ret;
+}
+
+static void
+gst_base_text_overlay_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstBaseTextOverlay *overlay = GST_BASE_TEXT_OVERLAY (object);
+
+  GST_OBJECT_LOCK (overlay);
+  switch (prop_id) {
+    case PROP_TEXT:
+      g_free (overlay->default_text);
+      overlay->default_text = g_value_dup_string (value);
+      overlay->need_render = TRUE;
+      break;
+    case PROP_SHADING:
+      overlay->want_shading = g_value_get_boolean (value);
+      break;
+    case PROP_XPAD:
+      overlay->xpad = g_value_get_int (value);
+      break;
+    case PROP_YPAD:
+      overlay->ypad = g_value_get_int (value);
+      break;
+    case PROP_DELTAX:
+      overlay->deltax = g_value_get_int (value);
+      break;
+    case PROP_DELTAY:
+      overlay->deltay = g_value_get_int (value);
+      break;
+    case PROP_XPOS:
+      overlay->xpos = g_value_get_double (value);
+      break;
+    case PROP_YPOS:
+      overlay->ypos = g_value_get_double (value);
+      break;
+    case PROP_HALIGN:{
+      const gchar *s = g_value_get_string (value);
+
+      if (s && g_ascii_strcasecmp (s, "left") == 0)
+        overlay->halign = GST_BASE_TEXT_OVERLAY_HALIGN_LEFT;
+      else if (s && g_ascii_strcasecmp (s, "center") == 0)
+        overlay->halign = GST_BASE_TEXT_OVERLAY_HALIGN_CENTER;
+      else if (s && g_ascii_strcasecmp (s, "right") == 0)
+        overlay->halign = GST_BASE_TEXT_OVERLAY_HALIGN_RIGHT;
+      else
+        g_warning ("Invalid value '%s' for textoverlay property 'halign'",
+            GST_STR_NULL (s));
+      break;
+    }
+    case PROP_VALIGN:{
+      const gchar *s = g_value_get_string (value);
+
+      if (s && g_ascii_strcasecmp (s, "baseline") == 0)
+        overlay->valign = GST_BASE_TEXT_OVERLAY_VALIGN_BASELINE;
+      else if (s && g_ascii_strcasecmp (s, "bottom") == 0)
+        overlay->valign = GST_BASE_TEXT_OVERLAY_VALIGN_BOTTOM;
+      else if (s && g_ascii_strcasecmp (s, "top") == 0)
+        overlay->valign = GST_BASE_TEXT_OVERLAY_VALIGN_TOP;
+      else
+        g_warning ("Invalid value '%s' for textoverlay property 'valign'",
+            GST_STR_NULL (s));
+      break;
+    }
+    case PROP_VALIGNMENT:
+      overlay->valign = g_value_get_enum (value);
+      break;
+    case PROP_HALIGNMENT:
+      overlay->halign = g_value_get_enum (value);
+      break;
+    case PROP_WRAP_MODE:
+      overlay->wrap_mode = g_value_get_enum (value);
+      g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
+      gst_base_text_overlay_update_wrap_mode (overlay);
+      g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
+      break;
+    case PROP_FONT_DESC:
+    {
+      PangoFontDescription *desc;
+      const gchar *fontdesc_str;
+
+      fontdesc_str = g_value_get_string (value);
+      g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
+      desc = pango_font_description_from_string (fontdesc_str);
+      if (desc) {
+        GST_LOG_OBJECT (overlay, "font description set: %s", fontdesc_str);
+        pango_layout_set_font_description (overlay->layout, desc);
+        gst_base_text_overlay_adjust_values_with_fontdesc (overlay, desc);
+        pango_font_description_free (desc);
+      } else {
+        GST_WARNING_OBJECT (overlay, "font description parse failed: %s",
+            fontdesc_str);
+      }
+      g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
+      break;
+    }
+    case PROP_COLOR:
+      overlay->color = g_value_get_uint (value);
+      break;
+    case PROP_SILENT:
+      overlay->silent = g_value_get_boolean (value);
+      break;
+    case PROP_LINE_ALIGNMENT:
+      overlay->line_align = g_value_get_enum (value);
+      g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
+      pango_layout_set_alignment (overlay->layout,
+          (PangoAlignment) overlay->line_align);
+      g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
+      break;
+    case PROP_WAIT_TEXT:
+      overlay->wait_text = g_value_get_boolean (value);
+      break;
+    case PROP_AUTO_ADJUST_SIZE:
+      overlay->auto_adjust_size = g_value_get_boolean (value);
+      overlay->need_render = TRUE;
+      break;
+    case PROP_VERTICAL_RENDER:
+      overlay->use_vertical_render = g_value_get_boolean (value);
+      g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
+      gst_base_text_overlay_update_render_mode (overlay);
+      g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
+      overlay->need_render = TRUE;
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+
+  overlay->need_render = TRUE;
+  GST_OBJECT_UNLOCK (overlay);
+}
+
+static void
+gst_base_text_overlay_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstBaseTextOverlay *overlay = GST_BASE_TEXT_OVERLAY (object);
+
+  GST_OBJECT_LOCK (overlay);
+  switch (prop_id) {
+    case PROP_TEXT:
+      g_value_set_string (value, overlay->default_text);
+      break;
+    case PROP_SHADING:
+      g_value_set_boolean (value, overlay->want_shading);
+      break;
+    case PROP_XPAD:
+      g_value_set_int (value, overlay->xpad);
+      break;
+    case PROP_YPAD:
+      g_value_set_int (value, overlay->ypad);
+      break;
+    case PROP_DELTAX:
+      g_value_set_int (value, overlay->deltax);
+      break;
+    case PROP_DELTAY:
+      g_value_set_int (value, overlay->deltay);
+      break;
+    case PROP_XPOS:
+      g_value_set_double (value, overlay->xpos);
+      break;
+    case PROP_YPOS:
+      g_value_set_double (value, overlay->ypos);
+      break;
+    case PROP_VALIGNMENT:
+      g_value_set_enum (value, overlay->valign);
+      break;
+    case PROP_HALIGNMENT:
+      g_value_set_enum (value, overlay->halign);
+      break;
+    case PROP_WRAP_MODE:
+      g_value_set_enum (value, overlay->wrap_mode);
+      break;
+    case PROP_SILENT:
+      g_value_set_boolean (value, overlay->silent);
+      break;
+    case PROP_LINE_ALIGNMENT:
+      g_value_set_enum (value, overlay->line_align);
+      break;
+    case PROP_WAIT_TEXT:
+      g_value_set_boolean (value, overlay->wait_text);
+      break;
+    case PROP_AUTO_ADJUST_SIZE:
+      g_value_set_boolean (value, overlay->auto_adjust_size);
+      break;
+    case PROP_VERTICAL_RENDER:
+      g_value_set_boolean (value, overlay->use_vertical_render);
+      break;
+    case PROP_COLOR:
+      g_value_set_uint (value, overlay->color);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+
+  overlay->need_render = TRUE;
+  GST_OBJECT_UNLOCK (overlay);
+}
+
+static gboolean
+gst_base_text_overlay_src_query (GstPad * pad, GstQuery * query)
+{
+  gboolean ret = FALSE;
+  GstBaseTextOverlay *overlay = NULL;
+
+  overlay = GST_BASE_TEXT_OVERLAY (gst_pad_get_parent (pad));
+
+  ret = gst_pad_peer_query (overlay->video_sinkpad, query);
+
+  gst_object_unref (overlay);
+
+  return ret;
+}
+
+static gboolean
+gst_base_text_overlay_src_event (GstPad * pad, GstEvent * event)
+{
+  gboolean ret = FALSE;
+  GstBaseTextOverlay *overlay = NULL;
+
+  overlay = GST_BASE_TEXT_OVERLAY (gst_pad_get_parent (pad));
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_SEEK:{
+      GstSeekFlags flags;
+
+      /* We don't handle seek if we have not text pad */
+      if (!overlay->text_linked) {
+        GST_DEBUG_OBJECT (overlay, "seek received, pushing upstream");
+        ret = gst_pad_push_event (overlay->video_sinkpad, event);
+        goto beach;
+      }
+
+      GST_DEBUG_OBJECT (overlay, "seek received, driving from here");
+
+      gst_event_parse_seek (event, NULL, NULL, &flags, NULL, NULL, NULL, NULL);
+
+      /* Flush downstream, only for flushing seek */
+      if (flags & GST_SEEK_FLAG_FLUSH)
+        gst_pad_push_event (overlay->srcpad, gst_event_new_flush_start ());
+
+      /* Mark ourself as flushing, unblock chains */
+      GST_OBJECT_LOCK (overlay);
+      overlay->video_flushing = TRUE;
+      overlay->text_flushing = TRUE;
+      gst_base_text_overlay_pop_text (overlay);
+      GST_OBJECT_UNLOCK (overlay);
+
+      /* Seek on each sink pad */
+      gst_event_ref (event);
+      ret = gst_pad_push_event (overlay->video_sinkpad, event);
+      if (ret) {
+        ret = gst_pad_push_event (overlay->text_sinkpad, event);
+      } else {
+        gst_event_unref (event);
+      }
+      break;
+    }
+    default:
+      if (overlay->text_linked) {
+        gst_event_ref (event);
+        ret = gst_pad_push_event (overlay->video_sinkpad, event);
+        gst_pad_push_event (overlay->text_sinkpad, event);
+      } else {
+        ret = gst_pad_push_event (overlay->video_sinkpad, event);
+      }
+      break;
+  }
+
+beach:
+  gst_object_unref (overlay);
+
+  return ret;
+}
+
+static GstCaps *
+gst_base_text_overlay_getcaps (GstPad * pad, GstCaps * filter)
+{
+  GstBaseTextOverlay *overlay;
+  GstPad *otherpad;
+  GstCaps *caps;
+
+  overlay = GST_BASE_TEXT_OVERLAY (gst_pad_get_parent (pad));
+
+  if (pad == overlay->srcpad)
+    otherpad = overlay->video_sinkpad;
+  else
+    otherpad = overlay->srcpad;
+
+  /* we can do what the peer can */
+  caps = gst_pad_peer_get_caps (otherpad, filter);
+  if (caps) {
+    GstCaps *temp, *templ;
+
+    GST_DEBUG_OBJECT (pad, "peer caps  %" GST_PTR_FORMAT, caps);
+
+    /* filtered against our padtemplate */
+    templ = gst_pad_get_pad_template_caps (otherpad);
+    GST_DEBUG_OBJECT (pad, "our template  %" GST_PTR_FORMAT, templ);
+    temp = gst_caps_intersect_full (caps, templ, GST_CAPS_INTERSECT_FIRST);
+    GST_DEBUG_OBJECT (pad, "intersected %" GST_PTR_FORMAT, temp);
+    gst_caps_unref (caps);
+    gst_caps_unref (templ);
+    /* this is what we can do */
+    caps = temp;
+  } else {
+    /* no peer, our padtemplate is enough then */
+    caps = gst_pad_get_pad_template_caps (pad);
+    if (filter) {
+      GstCaps *intersection;
+
+      intersection =
+          gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+      gst_caps_unref (caps);
+      caps = intersection;
+    }
+  }
+
+  GST_DEBUG_OBJECT (overlay, "returning  %" GST_PTR_FORMAT, caps);
+
+  gst_object_unref (overlay);
+
+  return caps;
+}
+
+static void
+gst_base_text_overlay_adjust_values_with_fontdesc (GstBaseTextOverlay * overlay,
+    PangoFontDescription * desc)
+{
+  gint font_size = pango_font_description_get_size (desc) / PANGO_SCALE;
+  overlay->shadow_offset = (double) (font_size) / 13.0;
+  overlay->outline_offset = (double) (font_size) / 15.0;
+  if (overlay->outline_offset < MINIMUM_OUTLINE_OFFSET)
+    overlay->outline_offset = MINIMUM_OUTLINE_OFFSET;
+}
+
+#define CAIRO_UNPREMULTIPLY(a,r,g,b) G_STMT_START { \
+  b = (a > 0) ? MIN ((b * 255 + a / 2) / a, 255) : 0; \
+  g = (a > 0) ? MIN ((g * 255 + a / 2) / a, 255) : 0; \
+  r = (a > 0) ? MIN ((r * 255 + a / 2) / a, 255) : 0; \
+} G_STMT_END
+
+static inline void
+gst_base_text_overlay_blit_1 (GstBaseTextOverlay * overlay, guchar * dest,
+    gint xpos, gint ypos, guchar * text_image, guint dest_stride)
+{
+  gint i, j = 0;
+  gint x, y;
+  guchar r, g, b, a;
+  guchar *pimage;
+  guchar *py;
+  gint width = overlay->image_width;
+  gint height = overlay->image_height;
+
+  if (xpos < 0) {
+    xpos = 0;
+  }
+
+  if (xpos + width > overlay->width) {
+    width = overlay->width - xpos;
+  }
+
+  if (ypos + height > overlay->height) {
+    height = overlay->height - ypos;
+  }
+
+  dest += (ypos / 1) * dest_stride;
+
+  for (i = 0; i < height; i++) {
+    pimage = text_image + 4 * (i * overlay->image_width);
+    py = dest + i * dest_stride + xpos;
+    for (j = 0; j < width; j++) {
+      b = pimage[CAIRO_ARGB_B];
+      g = pimage[CAIRO_ARGB_G];
+      r = pimage[CAIRO_ARGB_R];
+      a = pimage[CAIRO_ARGB_A];
+      CAIRO_UNPREMULTIPLY (a, r, g, b);
+
+      pimage += 4;
+      if (a == 0) {
+        py++;
+        continue;
+      }
+      COMP_Y (y, r, g, b);
+      x = *py;
+      BLEND (*py++, a, y, x);
+    }
+  }
+}
+
+static inline void
+gst_base_text_overlay_blit_sub2x2cbcr (GstBaseTextOverlay * overlay,
+    guchar * destcb, guchar * destcr, gint xpos, gint ypos, guchar * text_image,
+    guint destcb_stride, guint destcr_stride, guint pix_stride)
+{
+  gint i, j;
+  gint x, cb, cr;
+  gushort r, g, b, a;
+  gushort r1, g1, b1, a1;
+  guchar *pimage1, *pimage2;
+  guchar *pcb, *pcr;
+  gint width = overlay->image_width - 2;
+  gint height = overlay->image_height - 2;
+
+  xpos *= pix_stride;
+
+  if (xpos < 0) {
+    xpos = 0;
+  }
+
+  if (xpos + width > overlay->width) {
+    width = overlay->width - xpos;
+  }
+
+  if (ypos + height > overlay->height) {
+    height = overlay->height - ypos;
+  }
+
+  destcb += (ypos / 2) * destcb_stride;
+  destcr += (ypos / 2) * destcr_stride;
+
+  for (i = 0; i < height; i += 2) {
+    pimage1 = text_image + 4 * (i * overlay->image_width);
+    pimage2 = pimage1 + 4 * overlay->image_width;
+    pcb = destcb + (i / 2) * destcb_stride + xpos / 2;
+    pcr = destcr + (i / 2) * destcr_stride + xpos / 2;
+    for (j = 0; j < width; j += 2) {
+      b = pimage1[CAIRO_ARGB_B];
+      g = pimage1[CAIRO_ARGB_G];
+      r = pimage1[CAIRO_ARGB_R];
+      a = pimage1[CAIRO_ARGB_A];
+      CAIRO_UNPREMULTIPLY (a, r, g, b);
+      pimage1 += 4;
+
+      b1 = pimage1[CAIRO_ARGB_B];
+      g1 = pimage1[CAIRO_ARGB_G];
+      r1 = pimage1[CAIRO_ARGB_R];
+      a1 = pimage1[CAIRO_ARGB_A];
+      CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
+      b += b1;
+      g += g1;
+      r += r1;
+      a += a1;
+      pimage1 += 4;
+
+      b1 = pimage2[CAIRO_ARGB_B];
+      g1 = pimage2[CAIRO_ARGB_G];
+      r1 = pimage2[CAIRO_ARGB_R];
+      a1 = pimage2[CAIRO_ARGB_A];
+      CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
+      b += b1;
+      g += g1;
+      r += r1;
+      a += a1;
+      pimage2 += 4;
+
+      /* + 2 for rounding */
+      b1 = pimage2[CAIRO_ARGB_B];
+      g1 = pimage2[CAIRO_ARGB_G];
+      r1 = pimage2[CAIRO_ARGB_R];
+      a1 = pimage2[CAIRO_ARGB_A];
+      CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
+      b += b1 + 2;
+      g += g1 + 2;
+      r += r1 + 2;
+      a += a1 + 2;
+      pimage2 += 4;
+
+      b /= 4;
+      g /= 4;
+      r /= 4;
+      a /= 4;
+
+      if (a == 0) {
+        pcb += pix_stride;
+        pcr += pix_stride;
+        continue;
+      }
+      COMP_U (cb, r, g, b);
+      COMP_V (cr, r, g, b);
+
+      x = *pcb;
+      BLEND (*pcb, a, cb, x);
+      x = *pcr;
+      BLEND (*pcr, a, cr, x);
+
+      pcb += pix_stride;
+      pcr += pix_stride;
+    }
+  }
+}
+
+static void
+gst_base_text_overlay_render_pangocairo (GstBaseTextOverlay * overlay,
+    const gchar * string, gint textlen)
+{
+  cairo_t *cr;
+  cairo_surface_t *surface;
+  PangoRectangle ink_rect, logical_rect;
+  cairo_matrix_t cairo_matrix;
+  int width, height;
+  double scalef = 1.0;
+  double a, r, g, b;
+
+  g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
+
+  if (overlay->auto_adjust_size) {
+    /* 640 pixel is default */
+    scalef = (double) (overlay->width) / DEFAULT_SCALE_BASIS;
+  }
+  pango_layout_set_width (overlay->layout, -1);
+  /* set text on pango layout */
+  pango_layout_set_markup (overlay->layout, string, textlen);
+
+  /* get subtitle image size */
+  pango_layout_get_pixel_extents (overlay->layout, &ink_rect, &logical_rect);
+
+  width = (logical_rect.width + overlay->shadow_offset) * scalef;
+
+  if (width + overlay->deltax >
+      (overlay->use_vertical_render ? overlay->height : overlay->width)) {
+    /*
+     * subtitle image width is larger then overlay width
+     * so rearrange overlay wrap mode.
+     */
+    gst_base_text_overlay_update_wrap_mode (overlay);
+    pango_layout_get_pixel_extents (overlay->layout, &ink_rect, &logical_rect);
+    width = overlay->width;
+  }
+
+  height =
+      (logical_rect.height + logical_rect.y + overlay->shadow_offset) * scalef;
+  if (height > overlay->height) {
+    height = overlay->height;
+  }
+  if (overlay->use_vertical_render) {
+    PangoRectangle rect;
+    PangoContext *context;
+    PangoMatrix matrix = PANGO_MATRIX_INIT;
+    int tmp;
+
+    context = pango_layout_get_context (overlay->layout);
+
+    pango_matrix_rotate (&matrix, -90);
+
+    rect.x = rect.y = 0;
+    rect.width = width;
+    rect.height = height;
+    pango_matrix_transform_pixel_rectangle (&matrix, &rect);
+    matrix.x0 = -rect.x;
+    matrix.y0 = -rect.y;
+
+    pango_context_set_matrix (context, &matrix);
+
+    cairo_matrix.xx = matrix.xx;
+    cairo_matrix.yx = matrix.yx;
+    cairo_matrix.xy = matrix.xy;
+    cairo_matrix.yy = matrix.yy;
+    cairo_matrix.x0 = matrix.x0;
+    cairo_matrix.y0 = matrix.y0;
+    cairo_matrix_scale (&cairo_matrix, scalef, scalef);
+
+    tmp = height;
+    height = width;
+    width = tmp;
+  } else {
+    cairo_matrix_init_scale (&cairo_matrix, scalef, scalef);
+  }
+
+  /* reallocate surface */
+  overlay->text_image = g_realloc (overlay->text_image, 4 * width * height);
+
+  surface = cairo_image_surface_create_for_data (overlay->text_image,
+      CAIRO_FORMAT_ARGB32, width, height, width * 4);
+  cr = cairo_create (surface);
+
+  /* clear surface */
+  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+  cairo_paint (cr);
+
+  cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+  if (overlay->want_shading)
+    cairo_paint_with_alpha (cr, overlay->shading_value);
+
+  /* apply transformations */
+  cairo_set_matrix (cr, &cairo_matrix);
+
+  /* FIXME: We use show_layout everywhere except for the surface
+   * because it's really faster and internally does all kinds of
+   * caching. Unfortunately we have to paint to a cairo path for
+   * the outline and this is slow. Once Pango supports user fonts
+   * we should use them, see
+   * https://bugzilla.gnome.org/show_bug.cgi?id=598695
+   *
+   * Idea would the be, to create a cairo user font that
+   * does shadow, outline, text painting in the
+   * render_glyph function.
+   */
+
+  /* draw shadow text */
+  cairo_save (cr);
+  cairo_translate (cr, overlay->shadow_offset, overlay->shadow_offset);
+  cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.5);
+  pango_cairo_show_layout (cr, overlay->layout);
+  cairo_restore (cr);
+
+  /* draw outline text */
+  cairo_save (cr);
+  cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+  cairo_set_line_width (cr, overlay->outline_offset);
+  pango_cairo_layout_path (cr, overlay->layout);
+  cairo_stroke (cr);
+  cairo_restore (cr);
+
+  a = (overlay->color >> 24) & 0xff;
+  r = (overlay->color >> 16) & 0xff;
+  g = (overlay->color >> 8) & 0xff;
+  b = (overlay->color >> 0) & 0xff;
+
+  /* draw text */
+  cairo_save (cr);
+  cairo_set_source_rgba (cr, r / 255.0, g / 255.0, b / 255.0, a / 255.0);
+  pango_cairo_show_layout (cr, overlay->layout);
+  cairo_restore (cr);
+
+  cairo_destroy (cr);
+  cairo_surface_destroy (surface);
+  overlay->image_width = width;
+  overlay->image_height = height;
+  overlay->baseline_y = ink_rect.y;
+  g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
+}
+
+#define BOX_XPAD         6
+#define BOX_YPAD         6
+
+static inline void
+gst_base_text_overlay_shade_planar_Y (GstBaseTextOverlay * overlay,
+    guchar * dest, gint x0, gint x1, gint y0, gint y1)
+{
+  gint i, j, dest_stride;
+
+  dest_stride = gst_video_format_get_row_stride (overlay->format, 0,
+      overlay->width);
+
+  x0 = CLAMP (x0 - BOX_XPAD, 0, overlay->width);
+  x1 = CLAMP (x1 + BOX_XPAD, 0, overlay->width);
+
+  y0 = CLAMP (y0 - BOX_YPAD, 0, overlay->height);
+  y1 = CLAMP (y1 + BOX_YPAD, 0, overlay->height);
+
+  for (i = y0; i < y1; ++i) {
+    for (j = x0; j < x1; ++j) {
+      gint y = dest[(i * dest_stride) + j] + overlay->shading_value;
+
+      dest[(i * dest_stride) + j] = CLAMP (y, 0, 255);
+    }
+  }
+}
+
+static inline void
+gst_base_text_overlay_shade_packed_Y (GstBaseTextOverlay * overlay,
+    guchar * dest, gint x0, gint x1, gint y0, gint y1)
+{
+  gint i, j;
+  guint dest_stride, pixel_stride, component_offset;
+
+  dest_stride = gst_video_format_get_row_stride (overlay->format, 0,
+      overlay->width);
+  pixel_stride = gst_video_format_get_pixel_stride (overlay->format, 0);
+  component_offset =
+      gst_video_format_get_component_offset (overlay->format, 0, overlay->width,
+      overlay->height);
+
+  x0 = CLAMP (x0 - BOX_XPAD, 0, overlay->width);
+  x1 = CLAMP (x1 + BOX_XPAD, 0, overlay->width);
+
+  y0 = CLAMP (y0 - BOX_YPAD, 0, overlay->height);
+  y1 = CLAMP (y1 + BOX_YPAD, 0, overlay->height);
+
+  if (x0 != 0)
+    x0 = gst_video_format_get_component_width (overlay->format, 0, x0);
+  if (x1 != 0)
+    x1 = gst_video_format_get_component_width (overlay->format, 0, x1);
+
+  if (y0 != 0)
+    y0 = gst_video_format_get_component_height (overlay->format, 0, y0);
+  if (y1 != 0)
+    y1 = gst_video_format_get_component_height (overlay->format, 0, y1);
+
+  for (i = y0; i < y1; i++) {
+    for (j = x0; j < x1; j++) {
+      gint y;
+      gint y_pos;
+
+      y_pos = (i * dest_stride) + j * pixel_stride + component_offset;
+      y = dest[y_pos] + overlay->shading_value;
+
+      dest[y_pos] = CLAMP (y, 0, 255);
+    }
+  }
+}
+
+#define gst_base_text_overlay_shade_BGRx gst_base_text_overlay_shade_xRGB
+#define gst_base_text_overlay_shade_RGBx gst_base_text_overlay_shade_xRGB
+#define gst_base_text_overlay_shade_xBGR gst_base_text_overlay_shade_xRGB
+static inline void
+gst_base_text_overlay_shade_xRGB (GstBaseTextOverlay * overlay, guchar * dest,
+    gint x0, gint x1, gint y0, gint y1)
+{
+  gint i, j;
+
+  x0 = CLAMP (x0 - BOX_XPAD, 0, overlay->width);
+  x1 = CLAMP (x1 + BOX_XPAD, 0, overlay->width);
+
+  y0 = CLAMP (y0 - BOX_YPAD, 0, overlay->height);
+  y1 = CLAMP (y1 + BOX_YPAD, 0, overlay->height);
+
+  for (i = y0; i < y1; i++) {
+    for (j = x0; j < x1; j++) {
+      gint y, y_pos, k;
+
+      y_pos = (i * 4 * overlay->width) + j * 4;
+      for (k = 0; k < 4; k++) {
+        y = dest[y_pos + k] + overlay->shading_value;
+        dest[y_pos + k] = CLAMP (y, 0, 255);
+      }
+    }
+  }
+}
+
+#define ARGB_SHADE_FUNCTION(name, OFFSET)      \
+static inline void \
+gst_base_text_overlay_shade_##name (GstBaseTextOverlay * overlay, guchar * dest, \
+gint x0, gint x1, gint y0, gint y1) \
+{ \
+  gint i, j;\
+  \
+  x0 = CLAMP (x0 - BOX_XPAD, 0, overlay->width);\
+  x1 = CLAMP (x1 + BOX_XPAD, 0, overlay->width);\
+  \
+  y0 = CLAMP (y0 - BOX_YPAD, 0, overlay->height);\
+  y1 = CLAMP (y1 + BOX_YPAD, 0, overlay->height);\
+  \
+  for (i = y0; i < y1; i++) {\
+    for (j = x0; j < x1; j++) {\
+      gint y, y_pos, k;\
+      y_pos = (i * 4 * overlay->width) + j * 4;\
+      for (k = OFFSET; k < 3+OFFSET; k++) {\
+        y = dest[y_pos + k] + overlay->shading_value;\
+        dest[y_pos + k] = CLAMP (y, 0, 255);\
+      }\
+    }\
+  }\
+}
+ARGB_SHADE_FUNCTION (ARGB, 1);
+ARGB_SHADE_FUNCTION (ABGR, 1);
+ARGB_SHADE_FUNCTION (RGBA, 0);
+ARGB_SHADE_FUNCTION (BGRA, 0);
+
+
+/* FIXME:
+ *  - use proper strides and offset for I420
+ *  - don't draw over the edge of the picture (try a longer
+ *    text with a huge font size)
+ */
+
+static inline void
+gst_base_text_overlay_blit_NV12_NV21 (GstBaseTextOverlay * overlay,
+    guint8 * yuv_pixels, gint xpos, gint ypos)
+{
+  int y_stride, uv_stride;
+  int u_offset, v_offset;
+  int h, w;
+
+  /* because U/V is 2x2 subsampled, we need to round, either up or down,
+   * to a boundary of integer number of U/V pixels:
+   */
+  xpos = GST_ROUND_UP_2 (xpos);
+  ypos = GST_ROUND_UP_2 (ypos);
+
+  w = overlay->width;
+  h = overlay->height;
+
+  y_stride = gst_video_format_get_row_stride (overlay->format, 0, w);
+  uv_stride = gst_video_format_get_row_stride (overlay->format, 1, w);
+  u_offset = gst_video_format_get_component_offset (overlay->format, 1, w, h);
+  v_offset = gst_video_format_get_component_offset (overlay->format, 2, w, h);
+
+  gst_base_text_overlay_blit_1 (overlay, yuv_pixels, xpos, ypos,
+      overlay->text_image, y_stride);
+  gst_base_text_overlay_blit_sub2x2cbcr (overlay, yuv_pixels + u_offset,
+      yuv_pixels + v_offset, xpos, ypos, overlay->text_image, uv_stride,
+      uv_stride, 2);
+}
+
+static inline void
+gst_base_text_overlay_blit_I420 (GstBaseTextOverlay * overlay,
+    guint8 * yuv_pixels, gint xpos, gint ypos)
+{
+  int y_stride, u_stride, v_stride;
+  int u_offset, v_offset;
+  int h, w;
+
+  /* because U/V is 2x2 subsampled, we need to round, either up or down,
+   * to a boundary of integer number of U/V pixels:
+   */
+  xpos = GST_ROUND_UP_2 (xpos);
+  ypos = GST_ROUND_UP_2 (ypos);
+
+  w = overlay->width;
+  h = overlay->height;
+
+  y_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 0, w);
+  u_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 1, w);
+  v_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 2, w);
+  u_offset =
+      gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, 1, w, h);
+  v_offset =
+      gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, 2, w, h);
+
+  gst_base_text_overlay_blit_1 (overlay, yuv_pixels, xpos, ypos,
+      overlay->text_image, y_stride);
+  gst_base_text_overlay_blit_sub2x2cbcr (overlay, yuv_pixels + u_offset,
+      yuv_pixels + v_offset, xpos, ypos, overlay->text_image, u_stride,
+      v_stride, 1);
+}
+
+static inline void
+gst_base_text_overlay_blit_UYVY (GstBaseTextOverlay * overlay,
+    guint8 * yuv_pixels, gint xpos, gint ypos)
+{
+  int a0, r0, g0, b0;
+  int a1, r1, g1, b1;
+  int y0, y1, u, v;
+  int i, j;
+  int h, w;
+  guchar *pimage, *dest;
+
+  /* because U/V is 2x horizontally subsampled, we need to round to a
+   * boundary of integer number of U/V pixels in x dimension:
+   */
+  xpos = GST_ROUND_UP_2 (xpos);
+
+  w = overlay->image_width - 2;
+  h = overlay->image_height - 2;
+
+  if (xpos < 0) {
+    xpos = 0;
+  }
+
+  if (xpos + w > overlay->width) {
+    w = overlay->width - xpos;
+  }
+
+  if (ypos + h > overlay->height) {
+    h = overlay->height - ypos;
+  }
+
+  for (i = 0; i < h; i++) {
+    pimage = overlay->text_image + i * overlay->image_width * 4;
+    dest = yuv_pixels + (i + ypos) * overlay->width * 2 + xpos * 2;
+    for (j = 0; j < w; j += 2) {
+      b0 = pimage[CAIRO_ARGB_B];
+      g0 = pimage[CAIRO_ARGB_G];
+      r0 = pimage[CAIRO_ARGB_R];
+      a0 = pimage[CAIRO_ARGB_A];
+      CAIRO_UNPREMULTIPLY (a0, r0, g0, b0);
+      pimage += 4;
+
+      b1 = pimage[CAIRO_ARGB_B];
+      g1 = pimage[CAIRO_ARGB_G];
+      r1 = pimage[CAIRO_ARGB_R];
+      a1 = pimage[CAIRO_ARGB_A];
+      CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
+      pimage += 4;
+
+      a0 += a1 + 2;
+      a0 /= 2;
+      if (a0 == 0) {
+        dest += 4;
+        continue;
+      }
+
+      COMP_Y (y0, r0, g0, b0);
+      COMP_Y (y1, r1, g1, b1);
+
+      b0 += b1 + 2;
+      g0 += g1 + 2;
+      r0 += r1 + 2;
+
+      b0 /= 2;
+      g0 /= 2;
+      r0 /= 2;
+
+      COMP_U (u, r0, g0, b0);
+      COMP_V (v, r0, g0, b0);
+
+      BLEND (*dest, a0, u, *dest);
+      dest++;
+      BLEND (*dest, a0, y0, *dest);
+      dest++;
+      BLEND (*dest, a0, v, *dest);
+      dest++;
+      BLEND (*dest, a0, y1, *dest);
+      dest++;
+    }
+  }
+}
+
+static inline void
+gst_base_text_overlay_blit_AYUV (GstBaseTextOverlay * overlay,
+    guint8 * rgb_pixels, gint xpos, gint ypos)
+{
+  int a, r, g, b, a1;
+  int y, u, v;
+  int i, j;
+  int h, w;
+  guchar *pimage, *dest;
+
+  w = overlay->image_width;
+  h = overlay->image_height;
+
+  if (xpos < 0) {
+    xpos = 0;
+  }
+
+  if (xpos + w > overlay->width) {
+    w = overlay->width - xpos;
+  }
+
+  if (ypos + h > overlay->height) {
+    h = overlay->height - ypos;
+  }
+
+  for (i = 0; i < h; i++) {
+    pimage = overlay->text_image + i * overlay->image_width * 4;
+    dest = rgb_pixels + (i + ypos) * 4 * overlay->width + xpos * 4;
+    for (j = 0; j < w; j++) {
+      a = pimage[CAIRO_ARGB_A];
+      b = pimage[CAIRO_ARGB_B];
+      g = pimage[CAIRO_ARGB_G];
+      r = pimage[CAIRO_ARGB_R];
+
+      CAIRO_UNPREMULTIPLY (a, r, g, b);
+
+      // convert background to yuv
+      COMP_Y (y, r, g, b);
+      COMP_U (u, r, g, b);
+      COMP_V (v, r, g, b);
+
+      // preform text "OVER" background alpha compositing
+      a1 = a + (dest[0] * (255 - a)) / 255 + 1; // add 1 to prevent divide by 0
+      OVER (dest[1], a, y, dest[0], dest[1], a1);
+      OVER (dest[2], a, u, dest[0], dest[2], a1);
+      OVER (dest[3], a, v, dest[0], dest[3], a1);
+      dest[0] = a1 - 1;         // remove the temporary 1 we added
+
+      pimage += 4;
+      dest += 4;
+    }
+  }
+}
+
+#define xRGB_BLIT_FUNCTION(name, R, G, B) \
+static inline void \
+gst_base_text_overlay_blit_##name (GstBaseTextOverlay * overlay, \
+    guint8 * rgb_pixels, gint xpos, gint ypos) \
+{ \
+  int a, r, g, b; \
+  int i, j; \
+  int h, w; \
+  guchar *pimage, *dest; \
+  \
+  w = overlay->image_width; \
+  h = overlay->image_height; \
+  \
+  if (xpos < 0) { \
+    xpos = 0; \
+  } \
+  \
+  if (xpos + w > overlay->width) { \
+    w = overlay->width - xpos; \
+  } \
+  \
+  if (ypos + h > overlay->height) { \
+    h = overlay->height - ypos; \
+  } \
+  \
+  for (i = 0; i < h; i++) { \
+    pimage = overlay->text_image + i * overlay->image_width * 4; \
+    dest = rgb_pixels + (i + ypos) * 4 * overlay->width + xpos * 4; \
+    for (j = 0; j < w; j++) { \
+      a = pimage[CAIRO_ARGB_A]; \
+      b = pimage[CAIRO_ARGB_B]; \
+      g = pimage[CAIRO_ARGB_G]; \
+      r = pimage[CAIRO_ARGB_R]; \
+      CAIRO_UNPREMULTIPLY (a, r, g, b); \
+      b = (b*a + dest[B] * (255-a)) / 255; \
+      g = (g*a + dest[G] * (255-a)) / 255; \
+      r = (r*a + dest[R] * (255-a)) / 255; \
+      \
+      dest[B] = b; \
+      dest[G] = g; \
+      dest[R] = r; \
+      pimage += 4; \
+      dest += 4; \
+    } \
+  } \
+}
+xRGB_BLIT_FUNCTION (xRGB, 1, 2, 3);
+xRGB_BLIT_FUNCTION (BGRx, 2, 1, 0);
+xRGB_BLIT_FUNCTION (xBGR, 3, 2, 1);
+xRGB_BLIT_FUNCTION (RGBx, 0, 1, 2);
+
+#define ARGB_BLIT_FUNCTION(name, A, R, G, B)   \
+static inline void \
+gst_base_text_overlay_blit_##name (GstBaseTextOverlay * overlay, \
+    guint8 * rgb_pixels, gint xpos, gint ypos) \
+{ \
+  int a, r, g, b, a1;                          \
+  int i, j; \
+  int h, w; \
+  guchar *pimage, *dest; \
+  \
+  w = overlay->image_width; \
+  h = overlay->image_height; \
+  \
+  if (xpos < 0) { \
+    xpos = 0; \
+  } \
+  \
+  if (xpos + w > overlay->width) { \
+    w = overlay->width - xpos; \
+  } \
+  \
+  if (ypos + h > overlay->height) { \
+    h = overlay->height - ypos; \
+  } \
+  \
+  for (i = 0; i < h; i++) { \
+    pimage = overlay->text_image + i * overlay->image_width * 4; \
+    dest = rgb_pixels + (i + ypos) * 4 * overlay->width + xpos * 4; \
+    for (j = 0; j < w; j++) { \
+      a = pimage[CAIRO_ARGB_A]; \
+      b = pimage[CAIRO_ARGB_B]; \
+      g = pimage[CAIRO_ARGB_G]; \
+      r = pimage[CAIRO_ARGB_R]; \
+      CAIRO_UNPREMULTIPLY (a, r, g, b); \
+      a1 = a + (dest[A] * (255 - a)) / 255 + 1; \
+      OVER (dest[R], a, r, dest[0], dest[R], a1); \
+      OVER (dest[G], a, g, dest[0], dest[G], a1); \
+      OVER (dest[B], a, b, dest[0], dest[B], a1); \
+      dest[A] = a1 - 1; \
+      pimage += 4; \
+      dest += 4; \
+    } \
+  } \
+}
+ARGB_BLIT_FUNCTION (RGBA, 3, 0, 1, 2);
+ARGB_BLIT_FUNCTION (BGRA, 3, 2, 1, 0);
+ARGB_BLIT_FUNCTION (ARGB, 0, 1, 2, 3);
+ARGB_BLIT_FUNCTION (ABGR, 0, 3, 2, 1);
+
+static void
+gst_base_text_overlay_render_text (GstBaseTextOverlay * overlay,
+    const gchar * text, gint textlen)
+{
+  gchar *string;
+
+  if (!overlay->need_render) {
+    GST_DEBUG ("Using previously rendered text.");
+    return;
+  }
+
+  /* -1 is the whole string */
+  if (text != NULL && textlen < 0) {
+    textlen = strlen (text);
+  }
+
+  if (text != NULL) {
+    string = g_strndup (text, textlen);
+  } else {                      /* empty string */
+    string = g_strdup (" ");
+  }
+  g_strdelimit (string, "\r\t", ' ');
+  textlen = strlen (string);
+
+  /* FIXME: should we check for UTF-8 here? */
+
+  GST_DEBUG ("Rendering '%s'", string);
+  gst_base_text_overlay_render_pangocairo (overlay, string, textlen);
+
+  g_free (string);
+
+  overlay->need_render = FALSE;
+}
+
+static GstFlowReturn
+gst_base_text_overlay_push_frame (GstBaseTextOverlay * overlay,
+    GstBuffer * video_frame)
+{
+  gint xpos, ypos;
+  gint width, height;
+  GstBaseTextOverlayVAlign valign;
+  GstBaseTextOverlayHAlign halign;
+  guint8 *data;
+  gsize size;
+
+  width = overlay->image_width;
+  height = overlay->image_height;
+
+  video_frame = gst_buffer_make_writable (video_frame);
+
+  data = gst_buffer_map (video_frame, &size, NULL, GST_MAP_WRITE);
+
+  if (overlay->use_vertical_render)
+    halign = GST_BASE_TEXT_OVERLAY_HALIGN_RIGHT;
+  else
+    halign = overlay->halign;
+
+  switch (halign) {
+    case GST_BASE_TEXT_OVERLAY_HALIGN_LEFT:
+      xpos = overlay->xpad;
+      break;
+    case GST_BASE_TEXT_OVERLAY_HALIGN_CENTER:
+      xpos = (overlay->width - width) / 2;
+      break;
+    case GST_BASE_TEXT_OVERLAY_HALIGN_RIGHT:
+      xpos = overlay->width - width - overlay->xpad;
+      break;
+    case GST_BASE_TEXT_OVERLAY_HALIGN_POS:
+      xpos = (gint) (overlay->width * overlay->xpos) - width / 2;
+      xpos = CLAMP (xpos, 0, overlay->width - width);
+      if (xpos < 0)
+        xpos = 0;
+      break;
+    default:
+      xpos = 0;
+  }
+  xpos += overlay->deltax;
+
+  if (overlay->use_vertical_render)
+    valign = GST_BASE_TEXT_OVERLAY_VALIGN_TOP;
+  else
+    valign = overlay->valign;
+
+  switch (valign) {
+    case GST_BASE_TEXT_OVERLAY_VALIGN_BOTTOM:
+      ypos = overlay->height - height - overlay->ypad;
+      break;
+    case GST_BASE_TEXT_OVERLAY_VALIGN_BASELINE:
+      ypos = overlay->height - (height + overlay->ypad);
+      break;
+    case GST_BASE_TEXT_OVERLAY_VALIGN_TOP:
+      ypos = overlay->ypad;
+      break;
+    case GST_BASE_TEXT_OVERLAY_VALIGN_POS:
+      ypos = (gint) (overlay->height * overlay->ypos) - height / 2;
+      ypos = CLAMP (ypos, 0, overlay->height - height);
+      break;
+    case GST_BASE_TEXT_OVERLAY_VALIGN_CENTER:
+      ypos = (overlay->height - height) / 2;
+      break;
+    default:
+      ypos = overlay->ypad;
+      break;
+  }
+  ypos += overlay->deltay;
+
+  /* shaded background box */
+  if (overlay->want_shading) {
+    switch (overlay->format) {
+      case GST_VIDEO_FORMAT_I420:
+      case GST_VIDEO_FORMAT_NV12:
+      case GST_VIDEO_FORMAT_NV21:
+        gst_base_text_overlay_shade_planar_Y (overlay, data,
+            xpos, xpos + overlay->image_width,
+            ypos, ypos + overlay->image_height);
+        break;
+      case GST_VIDEO_FORMAT_AYUV:
+      case GST_VIDEO_FORMAT_UYVY:
+        gst_base_text_overlay_shade_packed_Y (overlay, data,
+            xpos, xpos + overlay->image_width,
+            ypos, ypos + overlay->image_height);
+        break;
+      case GST_VIDEO_FORMAT_xRGB:
+        gst_base_text_overlay_shade_xRGB (overlay, data,
+            xpos, xpos + overlay->image_width,
+            ypos, ypos + overlay->image_height);
+        break;
+      case GST_VIDEO_FORMAT_xBGR:
+        gst_base_text_overlay_shade_xBGR (overlay, data,
+            xpos, xpos + overlay->image_width,
+            ypos, ypos + overlay->image_height);
+        break;
+      case GST_VIDEO_FORMAT_BGRx:
+        gst_base_text_overlay_shade_BGRx (overlay, data,
+            xpos, xpos + overlay->image_width,
+            ypos, ypos + overlay->image_height);
+        break;
+      case GST_VIDEO_FORMAT_RGBx:
+        gst_base_text_overlay_shade_RGBx (overlay, data,
+            xpos, xpos + overlay->image_width,
+            ypos, ypos + overlay->image_height);
+        break;
+      case GST_VIDEO_FORMAT_ARGB:
+        gst_base_text_overlay_shade_ARGB (overlay, data,
+            xpos, xpos + overlay->image_width,
+            ypos, ypos + overlay->image_height);
+        break;
+      case GST_VIDEO_FORMAT_ABGR:
+        gst_base_text_overlay_shade_ABGR (overlay, data,
+            xpos, xpos + overlay->image_width,
+            ypos, ypos + overlay->image_height);
+        break;
+      case GST_VIDEO_FORMAT_RGBA:
+        gst_base_text_overlay_shade_RGBA (overlay, data,
+            xpos, xpos + overlay->image_width,
+            ypos, ypos + overlay->image_height);
+        break;
+      case GST_VIDEO_FORMAT_BGRA:
+        gst_base_text_overlay_shade_BGRA (overlay, data,
+            xpos, xpos + overlay->image_width,
+            ypos, ypos + overlay->image_height);
+        break;
+      default:
+        g_assert_not_reached ();
+    }
+  }
+
+  if (ypos < 0)
+    ypos = 0;
+
+  if (overlay->text_image) {
+    switch (overlay->format) {
+      case GST_VIDEO_FORMAT_I420:
+        gst_base_text_overlay_blit_I420 (overlay, data, xpos, ypos);
+        break;
+      case GST_VIDEO_FORMAT_NV12:
+      case GST_VIDEO_FORMAT_NV21:
+        gst_base_text_overlay_blit_NV12_NV21 (overlay, data, xpos, ypos);
+        break;
+      case GST_VIDEO_FORMAT_UYVY:
+        gst_base_text_overlay_blit_UYVY (overlay, data, xpos, ypos);
+        break;
+      case GST_VIDEO_FORMAT_AYUV:
+        gst_base_text_overlay_blit_AYUV (overlay, data, xpos, ypos);
+        break;
+      case GST_VIDEO_FORMAT_BGRx:
+        gst_base_text_overlay_blit_BGRx (overlay, data, xpos, ypos);
+        break;
+      case GST_VIDEO_FORMAT_xRGB:
+        gst_base_text_overlay_blit_xRGB (overlay, data, xpos, ypos);
+        break;
+      case GST_VIDEO_FORMAT_RGBx:
+        gst_base_text_overlay_blit_RGBx (overlay, data, xpos, ypos);
+        break;
+      case GST_VIDEO_FORMAT_xBGR:
+        gst_base_text_overlay_blit_xBGR (overlay, data, xpos, ypos);
+        break;
+      case GST_VIDEO_FORMAT_ARGB:
+        gst_base_text_overlay_blit_ARGB (overlay, data, xpos, ypos);
+        break;
+      case GST_VIDEO_FORMAT_ABGR:
+        gst_base_text_overlay_blit_ABGR (overlay, data, xpos, ypos);
+        break;
+      case GST_VIDEO_FORMAT_RGBA:
+        gst_base_text_overlay_blit_RGBA (overlay, data, xpos, ypos);
+        break;
+      case GST_VIDEO_FORMAT_BGRA:
+        gst_base_text_overlay_blit_BGRA (overlay, data, xpos, ypos);
+        break;
+      default:
+        g_assert_not_reached ();
+    }
+  }
+  gst_buffer_unmap (video_frame, data, size);
+
+  return gst_pad_push (overlay->srcpad, video_frame);
+}
+
+static GstPadLinkReturn
+gst_base_text_overlay_text_pad_link (GstPad * pad, GstPad * peer)
+{
+  GstBaseTextOverlay *overlay;
+
+  overlay = GST_BASE_TEXT_OVERLAY (gst_pad_get_parent (pad));
+
+  GST_DEBUG_OBJECT (overlay, "Text pad linked");
+
+  overlay->text_linked = TRUE;
+
+  gst_object_unref (overlay);
+
+  return GST_PAD_LINK_OK;
+}
+
+static void
+gst_base_text_overlay_text_pad_unlink (GstPad * pad)
+{
+  GstBaseTextOverlay *overlay;
+
+  /* don't use gst_pad_get_parent() here, will deadlock */
+  overlay = GST_BASE_TEXT_OVERLAY (GST_PAD_PARENT (pad));
+
+  GST_DEBUG_OBJECT (overlay, "Text pad unlinked");
+
+  overlay->text_linked = FALSE;
+
+  gst_segment_init (&overlay->text_segment, GST_FORMAT_UNDEFINED);
+}
+
+static gboolean
+gst_base_text_overlay_text_event (GstPad * pad, GstEvent * event)
+{
+  gboolean ret = FALSE;
+  GstBaseTextOverlay *overlay = NULL;
+
+  overlay = GST_BASE_TEXT_OVERLAY (gst_pad_get_parent (pad));
+
+  GST_LOG_OBJECT (pad, "received event %s", GST_EVENT_TYPE_NAME (event));
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_SEGMENT:
+    {
+      const GstSegment *segment;
+
+      overlay->text_eos = FALSE;
+
+      gst_event_parse_segment (event, &segment);
+
+      if (segment->format == GST_FORMAT_TIME) {
+        GST_OBJECT_LOCK (overlay);
+        gst_segment_copy_into (segment, &overlay->text_segment);
+        GST_DEBUG_OBJECT (overlay, "TEXT SEGMENT now: %" GST_SEGMENT_FORMAT,
+            &overlay->text_segment);
+        GST_OBJECT_UNLOCK (overlay);
+      } else {
+        GST_ELEMENT_WARNING (overlay, STREAM, MUX, (NULL),
+            ("received non-TIME newsegment event on text input"));
+      }
+
+      gst_event_unref (event);
+      ret = TRUE;
+
+      /* wake up the video chain, it might be waiting for a text buffer or
+       * a text segment update */
+      GST_OBJECT_LOCK (overlay);
+      GST_BASE_TEXT_OVERLAY_BROADCAST (overlay);
+      GST_OBJECT_UNLOCK (overlay);
+      break;
+    }
+    case GST_EVENT_FLUSH_STOP:
+      GST_OBJECT_LOCK (overlay);
+      GST_INFO_OBJECT (overlay, "text flush stop");
+      overlay->text_flushing = FALSE;
+      overlay->text_eos = FALSE;
+      gst_base_text_overlay_pop_text (overlay);
+      gst_segment_init (&overlay->text_segment, GST_FORMAT_TIME);
+      GST_OBJECT_UNLOCK (overlay);
+      gst_event_unref (event);
+      ret = TRUE;
+      break;
+    case GST_EVENT_FLUSH_START:
+      GST_OBJECT_LOCK (overlay);
+      GST_INFO_OBJECT (overlay, "text flush start");
+      overlay->text_flushing = TRUE;
+      GST_BASE_TEXT_OVERLAY_BROADCAST (overlay);
+      GST_OBJECT_UNLOCK (overlay);
+      gst_event_unref (event);
+      ret = TRUE;
+      break;
+    case GST_EVENT_EOS:
+      GST_OBJECT_LOCK (overlay);
+      overlay->text_eos = TRUE;
+      GST_INFO_OBJECT (overlay, "text EOS");
+      /* wake up the video chain, it might be waiting for a text buffer or
+       * a text segment update */
+      GST_BASE_TEXT_OVERLAY_BROADCAST (overlay);
+      GST_OBJECT_UNLOCK (overlay);
+      gst_event_unref (event);
+      ret = TRUE;
+      break;
+    default:
+      ret = gst_pad_event_default (pad, event);
+      break;
+  }
+
+  gst_object_unref (overlay);
+
+  return ret;
+}
+
+static gboolean
+gst_base_text_overlay_video_event (GstPad * pad, GstEvent * event)
+{
+  gboolean ret = FALSE;
+  GstBaseTextOverlay *overlay = NULL;
+
+  overlay = GST_BASE_TEXT_OVERLAY (gst_pad_get_parent (pad));
+
+  GST_DEBUG_OBJECT (pad, "received event %s", GST_EVENT_TYPE_NAME (event));
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_SEGMENT:
+    {
+      const GstSegment *segment;
+
+      GST_DEBUG_OBJECT (overlay, "received new segment");
+
+      gst_event_parse_segment (event, &segment);
+
+      if (segment->format == GST_FORMAT_TIME) {
+        GST_DEBUG_OBJECT (overlay, "VIDEO SEGMENT now: %" GST_SEGMENT_FORMAT,
+            &overlay->segment);
+
+        gst_segment_copy_into (segment, &overlay->segment);
+      } else {
+        GST_ELEMENT_WARNING (overlay, STREAM, MUX, (NULL),
+            ("received non-TIME newsegment event on video input"));
+      }
+
+      ret = gst_pad_event_default (pad, event);
+      break;
+    }
+    case GST_EVENT_EOS:
+      GST_OBJECT_LOCK (overlay);
+      GST_INFO_OBJECT (overlay, "video EOS");
+      overlay->video_eos = TRUE;
+      GST_OBJECT_UNLOCK (overlay);
+      ret = gst_pad_event_default (pad, event);
+      break;
+    case GST_EVENT_FLUSH_START:
+      GST_OBJECT_LOCK (overlay);
+      GST_INFO_OBJECT (overlay, "video flush start");
+      overlay->video_flushing = TRUE;
+      GST_BASE_TEXT_OVERLAY_BROADCAST (overlay);
+      GST_OBJECT_UNLOCK (overlay);
+      ret = gst_pad_event_default (pad, event);
+      break;
+    case GST_EVENT_FLUSH_STOP:
+      GST_OBJECT_LOCK (overlay);
+      GST_INFO_OBJECT (overlay, "video flush stop");
+      overlay->video_flushing = FALSE;
+      overlay->video_eos = FALSE;
+      gst_segment_init (&overlay->segment, GST_FORMAT_TIME);
+      GST_OBJECT_UNLOCK (overlay);
+      ret = gst_pad_event_default (pad, event);
+      break;
+    default:
+      ret = gst_pad_event_default (pad, event);
+      break;
+  }
+
+  gst_object_unref (overlay);
+
+  return ret;
+}
+
+/* Called with lock held */
+static void
+gst_base_text_overlay_pop_text (GstBaseTextOverlay * overlay)
+{
+  g_return_if_fail (GST_IS_BASE_TEXT_OVERLAY (overlay));
+
+  if (overlay->text_buffer) {
+    GST_DEBUG_OBJECT (overlay, "releasing text buffer %p",
+        overlay->text_buffer);
+    gst_buffer_unref (overlay->text_buffer);
+    overlay->text_buffer = NULL;
+  }
+
+  /* Let the text task know we used that buffer */
+  GST_BASE_TEXT_OVERLAY_BROADCAST (overlay);
+}
+
+/* We receive text buffers here. If they are out of segment we just ignore them.
+   If the buffer is in our segment we keep it internally except if another one
+   is already waiting here, in that case we wait that it gets kicked out */
+static GstFlowReturn
+gst_base_text_overlay_text_chain (GstPad * pad, GstBuffer * buffer)
+{
+  GstFlowReturn ret = GST_FLOW_OK;
+  GstBaseTextOverlay *overlay = NULL;
+  gboolean in_seg = FALSE;
+  guint64 clip_start = 0, clip_stop = 0;
+
+  overlay = GST_BASE_TEXT_OVERLAY (GST_PAD_PARENT (pad));
+
+  GST_OBJECT_LOCK (overlay);
+
+  if (overlay->text_flushing) {
+    GST_OBJECT_UNLOCK (overlay);
+    ret = GST_FLOW_WRONG_STATE;
+    GST_LOG_OBJECT (overlay, "text flushing");
+    goto beach;
+  }
+
+  if (overlay->text_eos) {
+    GST_OBJECT_UNLOCK (overlay);
+    ret = GST_FLOW_UNEXPECTED;
+    GST_LOG_OBJECT (overlay, "text EOS");
+    goto beach;
+  }
+
+  GST_LOG_OBJECT (overlay, "%" GST_SEGMENT_FORMAT "  BUFFER: ts=%"
+      GST_TIME_FORMAT ", end=%" GST_TIME_FORMAT, &overlay->segment,
+      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
+      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer) +
+          GST_BUFFER_DURATION (buffer)));
+
+  if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))) {
+    GstClockTime stop;
+
+    if (G_LIKELY (GST_BUFFER_DURATION_IS_VALID (buffer)))
+      stop = GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer);
+    else
+      stop = GST_CLOCK_TIME_NONE;
+
+    in_seg = gst_segment_clip (&overlay->text_segment, GST_FORMAT_TIME,
+        GST_BUFFER_TIMESTAMP (buffer), stop, &clip_start, &clip_stop);
+  } else {
+    in_seg = TRUE;
+  }
+
+  if (in_seg) {
+    if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
+      GST_BUFFER_TIMESTAMP (buffer) = clip_start;
+    else if (GST_BUFFER_DURATION_IS_VALID (buffer))
+      GST_BUFFER_DURATION (buffer) = clip_stop - clip_start;
+
+    /* Wait for the previous buffer to go away */
+    while (overlay->text_buffer != NULL) {
+      GST_DEBUG ("Pad %s:%s has a buffer queued, waiting",
+          GST_DEBUG_PAD_NAME (pad));
+      GST_BASE_TEXT_OVERLAY_WAIT (overlay);
+      GST_DEBUG ("Pad %s:%s resuming", GST_DEBUG_PAD_NAME (pad));
+      if (overlay->text_flushing) {
+        GST_OBJECT_UNLOCK (overlay);
+        ret = GST_FLOW_WRONG_STATE;
+        goto beach;
+      }
+    }
+
+    if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
+      overlay->text_segment.position = clip_start;
+
+    overlay->text_buffer = buffer;
+    /* That's a new text buffer we need to render */
+    overlay->need_render = TRUE;
+
+    /* in case the video chain is waiting for a text buffer, wake it up */
+    GST_BASE_TEXT_OVERLAY_BROADCAST (overlay);
+  }
+
+  GST_OBJECT_UNLOCK (overlay);
+
+beach:
+
+  return ret;
+}
+
+static GstFlowReturn
+gst_base_text_overlay_video_chain (GstPad * pad, GstBuffer * buffer)
+{
+  GstBaseTextOverlayClass *klass;
+  GstBaseTextOverlay *overlay;
+  GstFlowReturn ret = GST_FLOW_OK;
+  gboolean in_seg = FALSE;
+  guint64 start, stop, clip_start = 0, clip_stop = 0;
+  gchar *text = NULL;
+
+  overlay = GST_BASE_TEXT_OVERLAY (GST_PAD_PARENT (pad));
+  klass = GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay);
+
+  if (!GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
+    goto missing_timestamp;
+
+  /* ignore buffers that are outside of the current segment */
+  start = GST_BUFFER_TIMESTAMP (buffer);
+
+  if (!GST_BUFFER_DURATION_IS_VALID (buffer)) {
+    stop = GST_CLOCK_TIME_NONE;
+  } else {
+    stop = start + GST_BUFFER_DURATION (buffer);
+  }
+
+  GST_LOG_OBJECT (overlay, "%" GST_SEGMENT_FORMAT "  BUFFER: ts=%"
+      GST_TIME_FORMAT ", end=%" GST_TIME_FORMAT, &overlay->segment,
+      GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
+
+  /* segment_clip() will adjust start unconditionally to segment_start if
+   * no stop time is provided, so handle this ourselves */
+  if (stop == GST_CLOCK_TIME_NONE && start < overlay->segment.start)
+    goto out_of_segment;
+
+  in_seg = gst_segment_clip (&overlay->segment, GST_FORMAT_TIME, start, stop,
+      &clip_start, &clip_stop);
+
+  if (!in_seg)
+    goto out_of_segment;
+
+  /* if the buffer is only partially in the segment, fix up stamps */
+  if (clip_start != start || (stop != -1 && clip_stop != stop)) {
+    GST_DEBUG_OBJECT (overlay, "clipping buffer timestamp/duration to segment");
+    buffer = gst_buffer_make_writable (buffer);
+    GST_BUFFER_TIMESTAMP (buffer) = clip_start;
+    if (stop != -1)
+      GST_BUFFER_DURATION (buffer) = clip_stop - clip_start;
+  }
+
+  /* now, after we've done the clipping, fix up end time if there's no
+   * duration (we only use those estimated values internally though, we
+   * don't want to set bogus values on the buffer itself) */
+  if (stop == -1) {
+    GstCaps *caps;
+    GstStructure *s;
+    gint fps_num, fps_denom;
+
+    /* FIXME, store this in setcaps */
+    caps = gst_pad_get_current_caps (pad);
+    s = gst_caps_get_structure (caps, 0);
+    if (gst_structure_get_fraction (s, "framerate", &fps_num, &fps_denom) &&
+        fps_num && fps_denom) {
+      GST_DEBUG_OBJECT (overlay, "estimating duration based on framerate");
+      stop = start + gst_util_uint64_scale_int (GST_SECOND, fps_denom, fps_num);
+    } else {
+      GST_WARNING_OBJECT (overlay, "no duration, assuming minimal duration");
+      stop = start + 1;         /* we need to assume some interval */
+    }
+    gst_caps_unref (caps);
+  }
+
+  gst_object_sync_values (G_OBJECT (overlay), GST_BUFFER_TIMESTAMP (buffer));
+
+wait_for_text_buf:
+
+  GST_OBJECT_LOCK (overlay);
+
+  if (overlay->video_flushing)
+    goto flushing;
+
+  if (overlay->video_eos)
+    goto have_eos;
+
+  if (overlay->silent) {
+    GST_OBJECT_UNLOCK (overlay);
+    ret = gst_pad_push (overlay->srcpad, buffer);
+
+    /* Update position */
+    overlay->segment.position = clip_start;
+
+    return ret;
+  }
+
+  /* Text pad not linked, rendering internal text */
+  if (!overlay->text_linked) {
+    if (klass->get_text) {
+      text = klass->get_text (overlay, buffer);
+    } else {
+      text = g_strdup (overlay->default_text);
+    }
+
+    GST_LOG_OBJECT (overlay, "Text pad not linked, rendering default "
+        "text: '%s'", GST_STR_NULL (text));
+
+    GST_OBJECT_UNLOCK (overlay);
+
+    if (text != NULL && *text != '\0') {
+      /* Render and push */
+      gst_base_text_overlay_render_text (overlay, text, -1);
+      ret = gst_base_text_overlay_push_frame (overlay, buffer);
+    } else {
+      /* Invalid or empty string */
+      ret = gst_pad_push (overlay->srcpad, buffer);
+    }
+  } else {
+    /* Text pad linked, check if we have a text buffer queued */
+    if (overlay->text_buffer) {
+      gboolean pop_text = FALSE, valid_text_time = TRUE;
+      GstClockTime text_start = GST_CLOCK_TIME_NONE;
+      GstClockTime text_end = GST_CLOCK_TIME_NONE;
+      GstClockTime text_running_time = GST_CLOCK_TIME_NONE;
+      GstClockTime text_running_time_end = GST_CLOCK_TIME_NONE;
+      GstClockTime vid_running_time, vid_running_time_end;
+
+      /* if the text buffer isn't stamped right, pop it off the
+       * queue and display it for the current video frame only */
+      if (!GST_BUFFER_TIMESTAMP_IS_VALID (overlay->text_buffer) ||
+          !GST_BUFFER_DURATION_IS_VALID (overlay->text_buffer)) {
+        GST_WARNING_OBJECT (overlay,
+            "Got text buffer with invalid timestamp or duration");
+        pop_text = TRUE;
+        valid_text_time = FALSE;
+      } else {
+        text_start = GST_BUFFER_TIMESTAMP (overlay->text_buffer);
+        text_end = text_start + GST_BUFFER_DURATION (overlay->text_buffer);
+      }
+
+      vid_running_time =
+          gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
+          start);
+      vid_running_time_end =
+          gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
+          stop);
+
+      /* If timestamp and duration are valid */
+      if (valid_text_time) {
+        text_running_time =
+            gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
+            text_start);
+        text_running_time_end =
+            gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
+            text_end);
+      }
+
+      GST_LOG_OBJECT (overlay, "T: %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT,
+          GST_TIME_ARGS (text_running_time),
+          GST_TIME_ARGS (text_running_time_end));
+      GST_LOG_OBJECT (overlay, "V: %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT,
+          GST_TIME_ARGS (vid_running_time),
+          GST_TIME_ARGS (vid_running_time_end));
+
+      /* Text too old or in the future */
+      if (valid_text_time && text_running_time_end <= vid_running_time) {
+        /* text buffer too old, get rid of it and do nothing  */
+        GST_LOG_OBJECT (overlay, "text buffer too old, popping");
+        pop_text = FALSE;
+        gst_base_text_overlay_pop_text (overlay);
+        GST_OBJECT_UNLOCK (overlay);
+        goto wait_for_text_buf;
+      } else if (valid_text_time && vid_running_time_end <= text_running_time) {
+        GST_LOG_OBJECT (overlay, "text in future, pushing video buf");
+        GST_OBJECT_UNLOCK (overlay);
+        /* Push the video frame */
+        ret = gst_pad_push (overlay->srcpad, buffer);
+      } else {
+        gchar *in_text, *otext;
+        gsize in_size, osize;
+
+        otext =
+            gst_buffer_map (overlay->text_buffer, &osize, NULL, GST_MAP_READ);
+        in_text = otext;
+        in_size = osize;
+
+        /* g_markup_escape_text() absolutely requires valid UTF8 input, it
+         * might crash otherwise. We don't fall back on GST_SUBTITLE_ENCODING
+         * here on purpose, this is something that needs fixing upstream */
+        if (!g_utf8_validate (in_text, in_size, NULL)) {
+          const gchar *end = NULL;
+
+          GST_WARNING_OBJECT (overlay, "received invalid UTF-8");
+          in_text = g_strndup (in_text, in_size);
+          while (!g_utf8_validate (in_text, in_size, &end) && end)
+            *((gchar *) end) = '*';
+        }
+
+        /* Get the string */
+        if (overlay->have_pango_markup) {
+          text = g_strndup (in_text, in_size);
+        } else {
+          text = g_markup_escape_text (in_text, in_size);
+        }
+
+        if (text != NULL && *text != '\0') {
+          gint text_len = strlen (text);
+
+          while (text_len > 0 && (text[text_len - 1] == '\n' ||
+                  text[text_len - 1] == '\r')) {
+            --text_len;
+          }
+          GST_DEBUG_OBJECT (overlay, "Rendering text '%*s'", text_len, text);
+          gst_base_text_overlay_render_text (overlay, text, text_len);
+        } else {
+          GST_DEBUG_OBJECT (overlay, "No text to render (empty buffer)");
+          gst_base_text_overlay_render_text (overlay, " ", 1);
+        }
+        gst_buffer_unmap (overlay->text_buffer, otext, osize);
+
+        if (in_text != otext)
+          g_free (in_text);
+
+        GST_OBJECT_UNLOCK (overlay);
+        ret = gst_base_text_overlay_push_frame (overlay, buffer);
+
+        if (valid_text_time && text_running_time_end <= vid_running_time_end) {
+          GST_LOG_OBJECT (overlay, "text buffer not needed any longer");
+          pop_text = TRUE;
+        }
+      }
+      if (pop_text) {
+        GST_OBJECT_LOCK (overlay);
+        gst_base_text_overlay_pop_text (overlay);
+        GST_OBJECT_UNLOCK (overlay);
+      }
+    } else {
+      gboolean wait_for_text_buf = TRUE;
+
+      if (overlay->text_eos)
+        wait_for_text_buf = FALSE;
+
+      if (!overlay->wait_text)
+        wait_for_text_buf = FALSE;
+
+      /* Text pad linked, but no text buffer available - what now? */
+      if (overlay->text_segment.format == GST_FORMAT_TIME) {
+        GstClockTime text_start_running_time, text_position_running_time;
+        GstClockTime vid_running_time;
+
+        vid_running_time =
+            gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
+            GST_BUFFER_TIMESTAMP (buffer));
+        text_start_running_time =
+            gst_segment_to_running_time (&overlay->text_segment,
+            GST_FORMAT_TIME, overlay->text_segment.start);
+        text_position_running_time =
+            gst_segment_to_running_time (&overlay->text_segment,
+            GST_FORMAT_TIME, overlay->text_segment.position);
+
+        if ((GST_CLOCK_TIME_IS_VALID (text_start_running_time) &&
+                vid_running_time < text_start_running_time) ||
+            (GST_CLOCK_TIME_IS_VALID (text_position_running_time) &&
+                vid_running_time < text_position_running_time)) {
+          wait_for_text_buf = FALSE;
+        }
+      }
+
+      if (wait_for_text_buf) {
+        GST_DEBUG_OBJECT (overlay, "no text buffer, need to wait for one");
+        GST_BASE_TEXT_OVERLAY_WAIT (overlay);
+        GST_DEBUG_OBJECT (overlay, "resuming");
+        GST_OBJECT_UNLOCK (overlay);
+        goto wait_for_text_buf;
+      } else {
+        GST_OBJECT_UNLOCK (overlay);
+        GST_LOG_OBJECT (overlay, "no need to wait for a text buffer");
+        ret = gst_pad_push (overlay->srcpad, buffer);
+      }
+    }
+  }
+
+  g_free (text);
+
+  /* Update position */
+  overlay->segment.position = clip_start;
+
+  return ret;
+
+missing_timestamp:
+  {
+    GST_WARNING_OBJECT (overlay, "buffer without timestamp, discarding");
+    gst_buffer_unref (buffer);
+    return GST_FLOW_OK;
+  }
+
+flushing:
+  {
+    GST_OBJECT_UNLOCK (overlay);
+    GST_DEBUG_OBJECT (overlay, "flushing, discarding buffer");
+    gst_buffer_unref (buffer);
+    return GST_FLOW_WRONG_STATE;
+  }
+have_eos:
+  {
+    GST_OBJECT_UNLOCK (overlay);
+    GST_DEBUG_OBJECT (overlay, "eos, discarding buffer");
+    gst_buffer_unref (buffer);
+    return GST_FLOW_UNEXPECTED;
+  }
+out_of_segment:
+  {
+    GST_DEBUG_OBJECT (overlay, "buffer out of segment, discarding");
+    gst_buffer_unref (buffer);
+    return GST_FLOW_OK;
+  }
+}
+
+static GstStateChangeReturn
+gst_base_text_overlay_change_state (GstElement * element,
+    GstStateChange transition)
+{
+  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+  GstBaseTextOverlay *overlay = GST_BASE_TEXT_OVERLAY (element);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      GST_OBJECT_LOCK (overlay);
+      overlay->text_flushing = TRUE;
+      overlay->video_flushing = TRUE;
+      /* pop_text will broadcast on the GCond and thus also make the video
+       * chain exit if it's waiting for a text buffer */
+      gst_base_text_overlay_pop_text (overlay);
+      GST_OBJECT_UNLOCK (overlay);
+      break;
+    default:
+      break;
+  }
+
+  ret = parent_class->change_state (element, transition);
+  if (ret == GST_STATE_CHANGE_FAILURE)
+    return ret;
+
+  switch (transition) {
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      GST_OBJECT_LOCK (overlay);
+      overlay->text_flushing = FALSE;
+      overlay->video_flushing = FALSE;
+      overlay->video_eos = FALSE;
+      overlay->text_eos = FALSE;
+      gst_segment_init (&overlay->segment, GST_FORMAT_TIME);
+      gst_segment_init (&overlay->text_segment, GST_FORMAT_TIME);
+      GST_OBJECT_UNLOCK (overlay);
+      break;
+    default:
+      break;
+  }
+
+  return ret;
+}
+
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+  gst_controller_init (NULL, NULL);
+
+  if (!gst_element_register (plugin, "textoverlay", GST_RANK_NONE,
+          GST_TYPE_TEXT_OVERLAY) ||
+      !gst_element_register (plugin, "timeoverlay", GST_RANK_NONE,
+          GST_TYPE_TIME_OVERLAY) ||
+      !gst_element_register (plugin, "clockoverlay", GST_RANK_NONE,
+          GST_TYPE_CLOCK_OVERLAY) ||
+      !gst_element_register (plugin, "textrender", GST_RANK_NONE,
+          GST_TYPE_TEXT_RENDER)) {
+    return FALSE;
+  }
+
+  /*texttestsrc_plugin_init(module, plugin); */
+
+  GST_DEBUG_CATEGORY_INIT (pango_debug, "pango", 0, "Pango elements");
+
+  return TRUE;
+}
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR,
+    "pango", "Pango-based text rendering and overlay", plugin_init,
+    VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/ext/pango/gstbasetextoverlay.h b/ext/pango/gstbasetextoverlay.h
new file mode 100644 (file)
index 0000000..4319229
--- /dev/null
@@ -0,0 +1,171 @@
+#ifndef __GST_BASE_TEXT_OVERLAY_H__
+#define __GST_BASE_TEXT_OVERLAY_H__
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/controller/gstcontroller.h>
+#include <pango/pangocairo.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_BASE_TEXT_OVERLAY            (gst_base_text_overlay_get_type())
+#define GST_BASE_TEXT_OVERLAY(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),\
+                                         GST_TYPE_BASE_TEXT_OVERLAY, GstBaseTextOverlay))
+#define GST_BASE_TEXT_OVERLAY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),\
+                                         GST_TYPE_BASE_TEXT_OVERLAY,GstBaseTextOverlayClass))
+#define GST_BASE_TEXT_OVERLAY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+                                         GST_TYPE_BASE_TEXT_OVERLAY, GstBaseTextOverlayClass))
+#define GST_IS_BASE_TEXT_OVERLAY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),\
+                                         GST_TYPE_BASE_TEXT_OVERLAY))
+#define GST_IS_BASE_TEXT_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),\
+                                         GST_TYPE_BASE_TEXT_OVERLAY))
+
+typedef struct _GstBaseTextOverlay      GstBaseTextOverlay;
+typedef struct _GstBaseTextOverlayClass GstBaseTextOverlayClass;
+
+/**
+ * GstBaseTextOverlayVAlign:
+ * @GST_BASE_TEXT_OVERLAY_VALIGN_BASELINE: draw text on the baseline
+ * @GST_BASE_TEXT_OVERLAY_VALIGN_BOTTOM: draw text on the bottom
+ * @GST_BASE_TEXT_OVERLAY_VALIGN_TOP: draw text on top
+ * @GST_BASE_TEXT_OVERLAY_VALIGN_POS: draw text according to the #GstBaseTextOverlay:ypos property
+ * @GST_BASE_TEXT_OVERLAY_VALIGN_CENTER: draw text vertically centered
+ *
+ * Vertical alignment of the text.
+ */
+typedef enum {
+    GST_BASE_TEXT_OVERLAY_VALIGN_BASELINE,
+    GST_BASE_TEXT_OVERLAY_VALIGN_BOTTOM,
+    GST_BASE_TEXT_OVERLAY_VALIGN_TOP,
+    GST_BASE_TEXT_OVERLAY_VALIGN_POS,
+    GST_BASE_TEXT_OVERLAY_VALIGN_CENTER
+} GstBaseTextOverlayVAlign;
+
+/**
+ * GstBaseTextOverlayHAlign:
+ * @GST_BASE_TEXT_OVERLAY_HALIGN_LEFT: align text left
+ * @GST_BASE_TEXT_OVERLAY_HALIGN_CENTER: align text center
+ * @GST_BASE_TEXT_OVERLAY_HALIGN_RIGHT: align text right
+ * @GST_BASE_TEXT_OVERLAY_HALIGN_POS: position text according to the #GstBaseTextOverlay:xpos property
+ *
+ * Horizontal alignment of the text.
+ */
+/* FIXME 0.11: remove GST_BASE_TEXT_OVERLAY_HALIGN_UNUSED */
+typedef enum {
+    GST_BASE_TEXT_OVERLAY_HALIGN_LEFT,
+    GST_BASE_TEXT_OVERLAY_HALIGN_CENTER,
+    GST_BASE_TEXT_OVERLAY_HALIGN_RIGHT,
+    GST_BASE_TEXT_OVERLAY_HALIGN_UNUSED,
+    GST_BASE_TEXT_OVERLAY_HALIGN_POS
+} GstBaseTextOverlayHAlign;
+
+/**
+ * GstBaseTextOverlayWrapMode:
+ * @GST_BASE_TEXT_OVERLAY_WRAP_MODE_NONE: no wrapping
+ * @GST_BASE_TEXT_OVERLAY_WRAP_MODE_WORD: do word wrapping
+ * @GST_BASE_TEXT_OVERLAY_WRAP_MODE_CHAR: do char wrapping
+ * @GST_BASE_TEXT_OVERLAY_WRAP_MODE_WORD_CHAR: do word and char wrapping
+ *
+ * Whether to wrap the text and if so how.
+ */
+typedef enum {
+    GST_BASE_TEXT_OVERLAY_WRAP_MODE_NONE = -1,
+    GST_BASE_TEXT_OVERLAY_WRAP_MODE_WORD = PANGO_WRAP_WORD,
+    GST_BASE_TEXT_OVERLAY_WRAP_MODE_CHAR = PANGO_WRAP_CHAR,
+    GST_BASE_TEXT_OVERLAY_WRAP_MODE_WORD_CHAR = PANGO_WRAP_WORD_CHAR
+} GstBaseTextOverlayWrapMode;
+
+/**
+ * GstBaseTextOverlayLineAlign:
+ * @GST_BASE_TEXT_OVERLAY_LINE_ALIGN_LEFT: lines are left-aligned
+ * @GST_BASE_TEXT_OVERLAY_LINE_ALIGN_CENTER: lines are center-aligned
+ * @GST_BASE_TEXT_OVERLAY_LINE_ALIGN_RIGHT: lines are right-aligned
+ *
+ * Alignment of text lines relative to each other
+ */
+typedef enum {
+    GST_BASE_TEXT_OVERLAY_LINE_ALIGN_LEFT = PANGO_ALIGN_LEFT,
+    GST_BASE_TEXT_OVERLAY_LINE_ALIGN_CENTER = PANGO_ALIGN_CENTER,
+    GST_BASE_TEXT_OVERLAY_LINE_ALIGN_RIGHT = PANGO_ALIGN_RIGHT
+} GstBaseTextOverlayLineAlign;
+
+/**
+ * GstBaseTextOverlay:
+ *
+ * Opaque textoverlay object structure
+ */
+struct _GstBaseTextOverlay {
+    GstElement               element;
+
+    GstPad                  *video_sinkpad;
+    GstPad                  *text_sinkpad;
+    GstPad                  *srcpad;
+
+    GstSegment               segment;
+    GstSegment               text_segment;
+    GstBuffer               *text_buffer;
+    gboolean                text_linked;
+    gboolean                video_flushing;
+    gboolean                video_eos;
+    gboolean                text_flushing;
+    gboolean                text_eos;
+
+    GCond                   *cond;  /* to signal removal of a queued text
+                                     * buffer, arrival of a text buffer,
+                                     * a text segment update, or a change
+                                     * in status (e.g. shutdown, flushing) */
+
+    gint                     width;
+    gint                     height;
+    gint                     fps_n;
+    gint                     fps_d;
+    GstVideoFormat           format;
+
+    GstBaseTextOverlayVAlign     valign;
+    GstBaseTextOverlayHAlign     halign;
+    GstBaseTextOverlayWrapMode   wrap_mode;
+    GstBaseTextOverlayLineAlign  line_align;
+
+    gint                     xpad;
+    gint                     ypad;
+    gint                     deltax;
+    gint                     deltay;
+    gdouble                  xpos;
+    gdouble                  ypos;
+    gchar                   *default_text;
+    gboolean                 want_shading;
+    gboolean                 silent;
+    gboolean                 wait_text;
+    guint                    color;
+
+    PangoLayout             *layout;
+    gdouble                  shadow_offset;
+    gdouble                  outline_offset;
+    guchar                  *text_image;
+    gint                     image_width;
+    gint                     image_height;
+    gint                     baseline_y;
+
+    gboolean                 auto_adjust_size;
+    gboolean                 need_render;
+
+    gint                     shading_value;  /* for timeoverlay subclass */
+
+    gboolean                 have_pango_markup;
+    gboolean                 use_vertical_render;
+};
+
+struct _GstBaseTextOverlayClass {
+    GstElementClass parent_class;
+
+    PangoContext *pango_context;
+    GMutex       *pango_lock;
+
+    gchar *     (*get_text) (GstBaseTextOverlay *overlay, GstBuffer *video_frame);
+};
+
+GType gst_base_text_overlay_get_type(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GST_BASE_TEXT_OVERLAY_H */
index d90cff1..6c770ce 100644 (file)
 
 /**
  * SECTION:element-clockoverlay
- * @see_also: #GstTextOverlay, #GstTimeOverlay
+ * @see_also: #GstBaseTextOverlay, #GstTimeOverlay
  *
  * This element overlays the current clock time on top of a video
  * stream. You can position the text and configure the font details
- * using the properties of the #GstTextOverlay class. By default, the
+ * using the properties of the #GstBaseTextOverlay class. By default, the
  * time is displayed in the top left corner of the picture, with some
  * padding to the left and to the top.
  *
@@ -60,20 +60,8 @@ enum
   PROP_LAST
 };
 
-GST_BOILERPLATE (GstClockOverlay, gst_clock_overlay, GstTextOverlay,
-    GST_TYPE_TEXT_OVERLAY);
-
-static void
-gst_clock_overlay_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class, "Clock overlay",
-      "Filter/Editor/Video",
-      "Overlays the current clock time on a video stream",
-      "Tim-Philipp Müller <tim@centricular.net>");
-}
-
+#define gst_clock_overlay_parent_class parent_class
+G_DEFINE_TYPE (GstClockOverlay, gst_clock_overlay, GST_TYPE_BASE_TEXT_OVERLAY);
 
 static void gst_clock_overlay_finalize (GObject * object);
 static void gst_clock_overlay_set_property (GObject * object, guint prop_id,
@@ -114,7 +102,8 @@ gst_clock_overlay_render_time (GstClockOverlay * overlay)
 
 /* Called with lock held */
 static gchar *
-gst_clock_overlay_get_text (GstTextOverlay * overlay, GstBuffer * video_frame)
+gst_clock_overlay_get_text (GstBaseTextOverlay * overlay,
+    GstBuffer * video_frame)
 {
   gchar *time_str, *txt, *ret;
   GstClockOverlay *clock_overlay = GST_CLOCK_OVERLAY (overlay);
@@ -145,17 +134,24 @@ static void
 gst_clock_overlay_class_init (GstClockOverlayClass * klass)
 {
   GObjectClass *gobject_class;
-  GstTextOverlayClass *gsttextoverlay_class;
+  GstElementClass *gstelement_class;
+  GstBaseTextOverlayClass *gsttextoverlay_class;
   PangoContext *context;
   PangoFontDescription *font_description;
 
   gobject_class = (GObjectClass *) klass;
-  gsttextoverlay_class = (GstTextOverlayClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+  gsttextoverlay_class = (GstBaseTextOverlayClass *) klass;
 
   gobject_class->finalize = gst_clock_overlay_finalize;
   gobject_class->set_property = gst_clock_overlay_set_property;
   gobject_class->get_property = gst_clock_overlay_get_property;
 
+  gst_element_class_set_details_simple (gstelement_class, "Clock overlay",
+      "Filter/Editor/Video",
+      "Overlays the current clock time on a video stream",
+      "Tim-Philipp Müller <tim@centricular.net>");
+
   gsttextoverlay_class->get_text = gst_clock_overlay_get_text;
 
   g_object_class_install_property (gobject_class, PROP_TIMEFORMAT,
@@ -163,8 +159,8 @@ gst_clock_overlay_class_init (GstClockOverlayClass * klass)
           "Format to use for time and date value, as in strftime.",
           DEFAULT_PROP_TIMEFORMAT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  g_mutex_lock (GST_TEXT_OVERLAY_CLASS (klass)->pango_lock);
-  context = GST_TEXT_OVERLAY_CLASS (klass)->pango_context;
+  g_mutex_lock (gsttextoverlay_class->pango_lock);
+  context = gsttextoverlay_class->pango_context;
 
   pango_context_set_language (context, pango_language_from_string ("en_US"));
   pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);
@@ -178,7 +174,7 @@ gst_clock_overlay_class_init (GstClockOverlayClass * klass)
   pango_font_description_set_size (font_description, 18 * PANGO_SCALE);
   pango_context_set_font_description (context, font_description);
   pango_font_description_free (font_description);
-  g_mutex_unlock (GST_TEXT_OVERLAY_CLASS (klass)->pango_lock);
+  g_mutex_unlock (gsttextoverlay_class->pango_lock);
 }
 
 
@@ -196,14 +192,14 @@ gst_clock_overlay_finalize (GObject * object)
 
 
 static void
-gst_clock_overlay_init (GstClockOverlay * overlay, GstClockOverlayClass * klass)
+gst_clock_overlay_init (GstClockOverlay * overlay)
 {
-  GstTextOverlay *textoverlay;
+  GstBaseTextOverlay *textoverlay;
 
-  textoverlay = GST_TEXT_OVERLAY (overlay);
+  textoverlay = GST_BASE_TEXT_OVERLAY (overlay);
 
-  textoverlay->valign = GST_TEXT_OVERLAY_VALIGN_TOP;
-  textoverlay->halign = GST_TEXT_OVERLAY_HALIGN_LEFT;
+  textoverlay->valign = GST_BASE_TEXT_OVERLAY_VALIGN_TOP;
+  textoverlay->halign = GST_BASE_TEXT_OVERLAY_HALIGN_LEFT;
 
   overlay->format = g_strdup (DEFAULT_PROP_TIMEFORMAT);
 }
index 15a82ed..09ca2d3 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef __GST_CLOCK_OVERLAY_H__
 #define __GST_CLOCK_OVERLAY_H__
 
-#include "gsttextoverlay.h"
+#include "gstbasetextoverlay.h"
 
 G_BEGIN_DECLS
 
@@ -46,13 +46,13 @@ typedef struct _GstClockOverlayClass GstClockOverlayClass;
  * Opaque clockoverlay data structure.
  */
 struct _GstClockOverlay {
-  GstTextOverlay textoverlay;
+  GstBaseTextOverlay textoverlay;
   gchar         *format; /* as in strftime () */
   gchar         *text;
 };
 
 struct _GstClockOverlayClass {
-  GstTextOverlayClass parent_class;
+  GstBaseTextOverlayClass parent_class;
 };
 
 GType gst_clock_overlay_get_type (void);
index d4775ca..dd8114e 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (C) <2006> Zeeshan Ali <zeeshan.ali@nokia.com>
  * Copyright (C) <2006-2008> Tim-Philipp Müller <tim centricular net>
  * Copyright (C) <2009> Young-Ho Cha <ganadist@gmail.com>
+ * Copyright (C) <2011> Sebastian Dröge <sebastian.droege@collabora.co.uk>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -24,7 +25,7 @@
 
 /**
  * SECTION:element-textoverlay
- * @see_also: #GstTextRender, #GstClockOverlay, #GstTimeOverlay, #GstSubParse
+ * @see_also: #GstTextRender, #GstTextOverlay, #GstTimeOverlay, #GstSubParse
  *
  * This plugin renders text on top of a video stream. This can be either
  * static text or text from buffers received on the text sink pad, e.g.
  * </refsect2>
  */
 
-/* FIXME: alloc segment as part of instance struct */
-
 #ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gst/video/video.h>
-
-#include "gsttextoverlay.h"
-#include "gsttimeoverlay.h"
-#include "gstclockoverlay.h"
-#include "gsttextrender.h"
-#include <string.h>
-
-/* FIXME:
- *  - use proper strides and offset for I420
- *  - if text is wider than the video picture, it does not get
- *    clipped properly during blitting (if wrapping is disabled)
- *  - make 'shading_value' a property (or enum:  light/normal/dark/verydark)?
- */
-
-GST_DEBUG_CATEGORY (pango_debug);
-#define GST_CAT_DEFAULT pango_debug
-
-#define DEFAULT_PROP_TEXT      ""
-#define DEFAULT_PROP_SHADING   FALSE
-#define DEFAULT_PROP_VALIGNMENT        GST_TEXT_OVERLAY_VALIGN_BASELINE
-#define DEFAULT_PROP_HALIGNMENT        GST_TEXT_OVERLAY_HALIGN_CENTER
-#define DEFAULT_PROP_VALIGN    "baseline"
-#define DEFAULT_PROP_HALIGN    "center"
-#define DEFAULT_PROP_XPAD      25
-#define DEFAULT_PROP_YPAD      25
-#define DEFAULT_PROP_DELTAX    0
-#define DEFAULT_PROP_DELTAY    0
-#define DEFAULT_PROP_XPOS       0.5
-#define DEFAULT_PROP_YPOS       0.5
-#define DEFAULT_PROP_WRAP_MODE  GST_TEXT_OVERLAY_WRAP_MODE_WORD_CHAR
-#define DEFAULT_PROP_FONT_DESC ""
-#define DEFAULT_PROP_SILENT    FALSE
-#define DEFAULT_PROP_LINE_ALIGNMENT GST_TEXT_OVERLAY_LINE_ALIGN_CENTER
-#define DEFAULT_PROP_WAIT_TEXT TRUE
-#define DEFAULT_PROP_AUTO_ADJUST_SIZE TRUE
-#define DEFAULT_PROP_VERTICAL_RENDER  FALSE
-#define DEFAULT_PROP_COLOR      0xffffffff
-
-/* make a property of me */
-#define DEFAULT_SHADING_VALUE    -80
-
-#define MINIMUM_OUTLINE_OFFSET 1.0
-#define DEFAULT_SCALE_BASIS    640
-
-#define COMP_Y(ret, r, g, b) \
-{ \
-   ret = (int) (((19595 * r) >> 16) + ((38470 * g) >> 16) + ((7471 * b) >> 16)); \
-   ret = CLAMP (ret, 0, 255); \
-}
-
-#define COMP_U(ret, r, g, b) \
-{ \
-   ret = (int) (-((11059 * r) >> 16) - ((21709 * g) >> 16) + ((32768 * b) >> 16) + 128); \
-   ret = CLAMP (ret, 0, 255); \
-}
-
-#define COMP_V(ret, r, g, b) \
-{ \
-   ret = (int) (((32768 * r) >> 16) - ((27439 * g) >> 16) - ((5329 * b) >> 16) + 128); \
-   ret = CLAMP (ret, 0, 255); \
-}
-
-#define BLEND(ret, alpha, v0, v1) \
-{ \
-       ret = (v0 * alpha + v1 * (255 - alpha)) / 255; \
-}
-
-#define OVER(ret, alphaA, Ca, alphaB, Cb, alphaNew)    \
-{ \
-    gint _tmp; \
-    _tmp = (Ca * alphaA + Cb * alphaB * (255 - alphaA) / 255) / alphaNew; \
-    ret = CLAMP (_tmp, 0, 255); \
-}
-
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-# define CAIRO_ARGB_A 3
-# define CAIRO_ARGB_R 2
-# define CAIRO_ARGB_G 1
-# define CAIRO_ARGB_B 0
-#else
-# define CAIRO_ARGB_A 0
-# define CAIRO_ARGB_R 1
-# define CAIRO_ARGB_G 2
-# define CAIRO_ARGB_B 3
+#include "config.h"
 #endif
 
-enum
-{
-  PROP_0,
-  PROP_TEXT,
-  PROP_SHADING,
-  PROP_VALIGN,                  /* deprecated */
-  PROP_HALIGN,                  /* deprecated */
-  PROP_HALIGNMENT,
-  PROP_VALIGNMENT,
-  PROP_XPAD,
-  PROP_YPAD,
-  PROP_DELTAX,
-  PROP_DELTAY,
-  PROP_XPOS,
-  PROP_YPOS,
-  PROP_WRAP_MODE,
-  PROP_FONT_DESC,
-  PROP_SILENT,
-  PROP_LINE_ALIGNMENT,
-  PROP_WAIT_TEXT,
-  PROP_AUTO_ADJUST_SIZE,
-  PROP_VERTICAL_RENDER,
-  PROP_COLOR,
-  PROP_LAST
-};
-
-static GstStaticPadTemplate src_template_factory =
-    GST_STATIC_PAD_TEMPLATE ("src",
-    GST_PAD_SRC,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";"
-        GST_VIDEO_CAPS_RGBx ";"
-        GST_VIDEO_CAPS_xRGB ";"
-        GST_VIDEO_CAPS_xBGR ";"
-        GST_VIDEO_CAPS_RGBA ";"
-        GST_VIDEO_CAPS_BGRA ";"
-        GST_VIDEO_CAPS_ARGB ";"
-        GST_VIDEO_CAPS_ABGR ";"
-        GST_VIDEO_CAPS_YUV ("{AYUV, I420, UYVY, NV12, NV21}"))
-    );
-
-static GstStaticPadTemplate video_sink_template_factory =
-    GST_STATIC_PAD_TEMPLATE ("video_sink",
-    GST_PAD_SINK,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";"
-        GST_VIDEO_CAPS_RGBx ";"
-        GST_VIDEO_CAPS_xRGB ";"
-        GST_VIDEO_CAPS_xBGR ";"
-        GST_VIDEO_CAPS_RGBA ";"
-        GST_VIDEO_CAPS_BGRA ";"
-        GST_VIDEO_CAPS_ARGB ";"
-        GST_VIDEO_CAPS_ABGR ";"
-        GST_VIDEO_CAPS_YUV ("{AYUV, I420, UYVY, NV12, NV21}"))
-    );
+#include <gsttextoverlay.h>
 
 static GstStaticPadTemplate text_sink_template_factory =
     GST_STATIC_PAD_TEMPLATE ("text_sink",
@@ -225,2528 +83,23 @@ static GstStaticPadTemplate text_sink_template_factory =
     GST_STATIC_CAPS ("text/x-pango-markup; text/plain")
     );
 
-#define GST_TYPE_TEXT_OVERLAY_VALIGN (gst_text_overlay_valign_get_type())
-static GType
-gst_text_overlay_valign_get_type (void)
-{
-  static GType text_overlay_valign_type = 0;
-  static const GEnumValue text_overlay_valign[] = {
-    {GST_TEXT_OVERLAY_VALIGN_BASELINE, "baseline", "baseline"},
-    {GST_TEXT_OVERLAY_VALIGN_BOTTOM, "bottom", "bottom"},
-    {GST_TEXT_OVERLAY_VALIGN_TOP, "top", "top"},
-    {GST_TEXT_OVERLAY_VALIGN_POS, "position", "position"},
-    {GST_TEXT_OVERLAY_VALIGN_CENTER, "center", "center"},
-    {0, NULL, NULL},
-  };
-
-  if (!text_overlay_valign_type) {
-    text_overlay_valign_type =
-        g_enum_register_static ("GstTextOverlayVAlign", text_overlay_valign);
-  }
-  return text_overlay_valign_type;
-}
-
-#define GST_TYPE_TEXT_OVERLAY_HALIGN (gst_text_overlay_halign_get_type())
-static GType
-gst_text_overlay_halign_get_type (void)
-{
-  static GType text_overlay_halign_type = 0;
-  static const GEnumValue text_overlay_halign[] = {
-    {GST_TEXT_OVERLAY_HALIGN_LEFT, "left", "left"},
-    {GST_TEXT_OVERLAY_HALIGN_CENTER, "center", "center"},
-    {GST_TEXT_OVERLAY_HALIGN_RIGHT, "right", "right"},
-    {GST_TEXT_OVERLAY_HALIGN_POS, "position", "position"},
-    {0, NULL, NULL},
-  };
-
-  if (!text_overlay_halign_type) {
-    text_overlay_halign_type =
-        g_enum_register_static ("GstTextOverlayHAlign", text_overlay_halign);
-  }
-  return text_overlay_halign_type;
-}
-
-
-#define GST_TYPE_TEXT_OVERLAY_WRAP_MODE (gst_text_overlay_wrap_mode_get_type())
-static GType
-gst_text_overlay_wrap_mode_get_type (void)
-{
-  static GType text_overlay_wrap_mode_type = 0;
-  static const GEnumValue text_overlay_wrap_mode[] = {
-    {GST_TEXT_OVERLAY_WRAP_MODE_NONE, "none", "none"},
-    {GST_TEXT_OVERLAY_WRAP_MODE_WORD, "word", "word"},
-    {GST_TEXT_OVERLAY_WRAP_MODE_CHAR, "char", "char"},
-    {GST_TEXT_OVERLAY_WRAP_MODE_WORD_CHAR, "wordchar", "wordchar"},
-    {0, NULL, NULL},
-  };
-
-  if (!text_overlay_wrap_mode_type) {
-    text_overlay_wrap_mode_type =
-        g_enum_register_static ("GstTextOverlayWrapMode",
-        text_overlay_wrap_mode);
-  }
-  return text_overlay_wrap_mode_type;
-}
-
-#define GST_TYPE_TEXT_OVERLAY_LINE_ALIGN (gst_text_overlay_line_align_get_type())
-static GType
-gst_text_overlay_line_align_get_type (void)
-{
-  static GType text_overlay_line_align_type = 0;
-  static const GEnumValue text_overlay_line_align[] = {
-    {GST_TEXT_OVERLAY_LINE_ALIGN_LEFT, "left", "left"},
-    {GST_TEXT_OVERLAY_LINE_ALIGN_CENTER, "center", "center"},
-    {GST_TEXT_OVERLAY_LINE_ALIGN_RIGHT, "right", "right"},
-    {0, NULL, NULL}
-  };
-
-  if (!text_overlay_line_align_type) {
-    text_overlay_line_align_type =
-        g_enum_register_static ("GstTextOverlayLineAlign",
-        text_overlay_line_align);
-  }
-  return text_overlay_line_align_type;
-}
-
-#define GST_TEXT_OVERLAY_GET_COND(ov) (((GstTextOverlay *)ov)->cond)
-#define GST_TEXT_OVERLAY_WAIT(ov)     (g_cond_wait (GST_TEXT_OVERLAY_GET_COND (ov), GST_OBJECT_GET_LOCK (ov)))
-#define GST_TEXT_OVERLAY_SIGNAL(ov)   (g_cond_signal (GST_TEXT_OVERLAY_GET_COND (ov)))
-#define GST_TEXT_OVERLAY_BROADCAST(ov)(g_cond_broadcast (GST_TEXT_OVERLAY_GET_COND (ov)))
-
-static GstStateChangeReturn gst_text_overlay_change_state (GstElement * element,
-    GstStateChange transition);
-
-static GstCaps *gst_text_overlay_getcaps (GstPad * pad);
-static gboolean gst_text_overlay_setcaps (GstPad * pad, GstCaps * caps);
-static gboolean gst_text_overlay_setcaps_txt (GstPad * pad, GstCaps * caps);
-static gboolean gst_text_overlay_src_event (GstPad * pad, GstEvent * event);
-static gboolean gst_text_overlay_src_query (GstPad * pad, GstQuery * query);
-
-static gboolean gst_text_overlay_video_event (GstPad * pad, GstEvent * event);
-static GstFlowReturn gst_text_overlay_video_chain (GstPad * pad,
-    GstBuffer * buffer);
-static GstFlowReturn gst_text_overlay_video_bufferalloc (GstPad * pad,
-    guint64 offset, guint size, GstCaps * caps, GstBuffer ** buffer);
-
-static gboolean gst_text_overlay_text_event (GstPad * pad, GstEvent * event);
-static GstFlowReturn gst_text_overlay_text_chain (GstPad * pad,
-    GstBuffer * buffer);
-static GstPadLinkReturn gst_text_overlay_text_pad_link (GstPad * pad,
-    GstPad * peer);
-static void gst_text_overlay_text_pad_unlink (GstPad * pad);
-static void gst_text_overlay_pop_text (GstTextOverlay * overlay);
-static void gst_text_overlay_update_render_mode (GstTextOverlay * overlay);
-
-static void gst_text_overlay_finalize (GObject * object);
-static void gst_text_overlay_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_text_overlay_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-static void gst_text_overlay_adjust_values_with_fontdesc (GstTextOverlay *
-    overlay, PangoFontDescription * desc);
-
-GST_BOILERPLATE (GstTextOverlay, gst_text_overlay, GstElement,
-    GST_TYPE_ELEMENT);
+G_DEFINE_TYPE (GstTextOverlay, gst_text_overlay, GST_TYPE_BASE_TEXT_OVERLAY);
 
 static void
-gst_text_overlay_base_init (gpointer g_class)
+gst_text_overlay_class_init (GstTextOverlayClass * klass)
 {
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-  GstTextOverlayClass *klass = GST_TEXT_OVERLAY_CLASS (g_class);
-  PangoFontMap *fontmap;
+  GstElementClass *element_class = (GstElementClass *) klass;
 
   gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_template_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&video_sink_template_factory));
-
-  /* ugh */
-  if (!GST_IS_TIME_OVERLAY_CLASS (g_class) &&
-      !GST_IS_CLOCK_OVERLAY_CLASS (g_class)) {
-    gst_element_class_add_pad_template (element_class,
-        gst_static_pad_template_get (&text_sink_template_factory));
-  }
+      gst_static_pad_template_get (&text_sink_template_factory));
 
   gst_element_class_set_details_simple (element_class, "Text overlay",
       "Filter/Editor/Video",
       "Adds text strings on top of a video buffer",
       "David Schleef <ds@schleef.org>, " "Zeeshan Ali <zeeshan.ali@nokia.com>");
-
-  /* Only lock for the subclasses here, the base class
-   * doesn't have this mutex yet and it's not necessary
-   * here */
-  if (klass->pango_lock)
-    g_mutex_lock (klass->pango_lock);
-  fontmap = pango_cairo_font_map_get_default ();
-  klass->pango_context =
-      pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
-  if (klass->pango_lock)
-    g_mutex_unlock (klass->pango_lock);
-}
-
-static gchar *
-gst_text_overlay_get_text (GstTextOverlay * overlay, GstBuffer * video_frame)
-{
-  return g_strdup (overlay->default_text);
 }
 
 static void
-gst_text_overlay_class_init (GstTextOverlayClass * klass)
+gst_text_overlay_init (GstTextOverlay * overlay)
 {
-  GObjectClass *gobject_class;
-  GstElementClass *gstelement_class;
-
-  gobject_class = (GObjectClass *) klass;
-  gstelement_class = (GstElementClass *) klass;
-
-  gobject_class->finalize = gst_text_overlay_finalize;
-  gobject_class->set_property = gst_text_overlay_set_property;
-  gobject_class->get_property = gst_text_overlay_get_property;
-
-  gstelement_class->change_state =
-      GST_DEBUG_FUNCPTR (gst_text_overlay_change_state);
-
-  klass->pango_lock = g_mutex_new ();
-
-  klass->get_text = gst_text_overlay_get_text;
-
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TEXT,
-      g_param_spec_string ("text", "text",
-          "Text to be display.", DEFAULT_PROP_TEXT,
-          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SHADING,
-      g_param_spec_boolean ("shaded-background", "shaded background",
-          "Whether to shade the background under the text area",
-          DEFAULT_PROP_SHADING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_VALIGNMENT,
-      g_param_spec_enum ("valignment", "vertical alignment",
-          "Vertical alignment of the text", GST_TYPE_TEXT_OVERLAY_VALIGN,
-          DEFAULT_PROP_VALIGNMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_HALIGNMENT,
-      g_param_spec_enum ("halignment", "horizontal alignment",
-          "Horizontal alignment of the text", GST_TYPE_TEXT_OVERLAY_HALIGN,
-          DEFAULT_PROP_HALIGNMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_VALIGN,
-      g_param_spec_string ("valign", "vertical alignment",
-          "Vertical alignment of the text (deprecated; use valignment)",
-          DEFAULT_PROP_VALIGN, G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_HALIGN,
-      g_param_spec_string ("halign", "horizontal alignment",
-          "Horizontal alignment of the text (deprecated; use halignment)",
-          DEFAULT_PROP_HALIGN, G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_XPAD,
-      g_param_spec_int ("xpad", "horizontal paddding",
-          "Horizontal paddding when using left/right alignment", 0, G_MAXINT,
-          DEFAULT_PROP_XPAD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_YPAD,
-      g_param_spec_int ("ypad", "vertical padding",
-          "Vertical padding when using top/bottom alignment", 0, G_MAXINT,
-          DEFAULT_PROP_YPAD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DELTAX,
-      g_param_spec_int ("deltax", "X position modifier",
-          "Shift X position to the left or to the right. Unit is pixels.",
-          G_MININT, G_MAXINT, DEFAULT_PROP_DELTAX,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DELTAY,
-      g_param_spec_int ("deltay", "Y position modifier",
-          "Shift Y position up or down. Unit is pixels.", G_MININT, G_MAXINT,
-          DEFAULT_PROP_DELTAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  /**
-   * GstTextOverlay:xpos
-   *
-   * Horizontal position of the rendered text when using positioned alignment.
-   *
-   * Since: 0.10.31
-   **/
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_XPOS,
-      g_param_spec_double ("xpos", "horizontal position",
-          "Horizontal position when using position alignment", 0, 1.0,
-          DEFAULT_PROP_XPOS,
-          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-  /**
-   * GstTextOverlay:ypos
-   *
-   * Vertical position of the rendered text when using positioned alignment.
-   *
-   * Since: 0.10.31
-   **/
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_YPOS,
-      g_param_spec_double ("ypos", "vertical position",
-          "Vertical position when using position alignment", 0, 1.0,
-          DEFAULT_PROP_YPOS,
-          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_WRAP_MODE,
-      g_param_spec_enum ("wrap-mode", "wrap mode",
-          "Whether to wrap the text and if so how.",
-          GST_TYPE_TEXT_OVERLAY_WRAP_MODE, DEFAULT_PROP_WRAP_MODE,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FONT_DESC,
-      g_param_spec_string ("font-desc", "font description",
-          "Pango font description of font to be used for rendering. "
-          "See documentation of pango_font_description_from_string "
-          "for syntax.", DEFAULT_PROP_FONT_DESC,
-          G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
-  /**
-   * GstTextOverlay:color
-   *
-   * Color of the rendered text.
-   *
-   * Since: 0.10.31
-   **/
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_COLOR,
-      g_param_spec_uint ("color", "Color",
-          "Color to use for text (big-endian ARGB).", 0, G_MAXUINT32,
-          DEFAULT_PROP_COLOR,
-          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstTextOverlay:line-alignment
-   *
-   * Alignment of text lines relative to each other (for multi-line text)
-   *
-   * Since: 0.10.15
-   **/
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LINE_ALIGNMENT,
-      g_param_spec_enum ("line-alignment", "line alignment",
-          "Alignment of text lines relative to each other.",
-          GST_TYPE_TEXT_OVERLAY_LINE_ALIGN, DEFAULT_PROP_LINE_ALIGNMENT,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  /**
-   * GstTextOverlay:silent
-   *
-   * If set, no text is rendered. Useful to switch off text rendering
-   * temporarily without removing the textoverlay element from the pipeline.
-   *
-   * Since: 0.10.15
-   **/
-  /* FIXME 0.11: rename to "visible" or "text-visible" or "render-text" */
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SILENT,
-      g_param_spec_boolean ("silent", "silent",
-          "Whether to render the text string",
-          DEFAULT_PROP_SILENT,
-          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-  /**
-   * GstTextOverlay:wait-text
-   *
-   * If set, the video will block until a subtitle is received on the text pad.
-   * If video and subtitles are sent in sync, like from the same demuxer, this
-   * property should be set.
-   *
-   * Since: 0.10.20
-   **/
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_WAIT_TEXT,
-      g_param_spec_boolean ("wait-text", "Wait Text",
-          "Whether to wait for subtitles",
-          DEFAULT_PROP_WAIT_TEXT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (G_OBJECT_CLASS (klass),
-      PROP_AUTO_ADJUST_SIZE, g_param_spec_boolean ("auto-resize", "auto resize",
-          "Automatically adjust font size to screen-size.",
-          DEFAULT_PROP_AUTO_ADJUST_SIZE,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_VERTICAL_RENDER,
-      g_param_spec_boolean ("vertical-render", "vertical render",
-          "Vertical Render.", DEFAULT_PROP_VERTICAL_RENDER,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-}
-
-static void
-gst_text_overlay_finalize (GObject * object)
-{
-  GstTextOverlay *overlay = GST_TEXT_OVERLAY (object);
-
-  g_free (overlay->default_text);
-
-  if (overlay->text_image) {
-    g_free (overlay->text_image);
-    overlay->text_image = NULL;
-  }
-
-  if (overlay->layout) {
-    g_object_unref (overlay->layout);
-    overlay->layout = NULL;
-  }
-
-  if (overlay->text_buffer) {
-    gst_buffer_unref (overlay->text_buffer);
-    overlay->text_buffer = NULL;
-  }
-
-  if (overlay->cond) {
-    g_cond_free (overlay->cond);
-    overlay->cond = NULL;
-  }
-
-  G_OBJECT_CLASS (parent_class)->finalize (object);
 }
-
-static void
-gst_text_overlay_init (GstTextOverlay * overlay, GstTextOverlayClass * klass)
-{
-  GstPadTemplate *template;
-  PangoFontDescription *desc;
-
-  /* video sink */
-  template = gst_static_pad_template_get (&video_sink_template_factory);
-  overlay->video_sinkpad = gst_pad_new_from_template (template, "video_sink");
-  gst_object_unref (template);
-  gst_pad_set_getcaps_function (overlay->video_sinkpad,
-      GST_DEBUG_FUNCPTR (gst_text_overlay_getcaps));
-  gst_pad_set_setcaps_function (overlay->video_sinkpad,
-      GST_DEBUG_FUNCPTR (gst_text_overlay_setcaps));
-  gst_pad_set_event_function (overlay->video_sinkpad,
-      GST_DEBUG_FUNCPTR (gst_text_overlay_video_event));
-  gst_pad_set_chain_function (overlay->video_sinkpad,
-      GST_DEBUG_FUNCPTR (gst_text_overlay_video_chain));
-  gst_pad_set_bufferalloc_function (overlay->video_sinkpad,
-      GST_DEBUG_FUNCPTR (gst_text_overlay_video_bufferalloc));
-  gst_element_add_pad (GST_ELEMENT (overlay), overlay->video_sinkpad);
-
-  if (!GST_IS_TIME_OVERLAY_CLASS (klass) && !GST_IS_CLOCK_OVERLAY_CLASS (klass)) {
-    /* text sink */
-    template = gst_static_pad_template_get (&text_sink_template_factory);
-    overlay->text_sinkpad = gst_pad_new_from_template (template, "text_sink");
-    gst_object_unref (template);
-    gst_pad_set_setcaps_function (overlay->text_sinkpad,
-        GST_DEBUG_FUNCPTR (gst_text_overlay_setcaps_txt));
-    gst_pad_set_event_function (overlay->text_sinkpad,
-        GST_DEBUG_FUNCPTR (gst_text_overlay_text_event));
-    gst_pad_set_chain_function (overlay->text_sinkpad,
-        GST_DEBUG_FUNCPTR (gst_text_overlay_text_chain));
-    gst_pad_set_link_function (overlay->text_sinkpad,
-        GST_DEBUG_FUNCPTR (gst_text_overlay_text_pad_link));
-    gst_pad_set_unlink_function (overlay->text_sinkpad,
-        GST_DEBUG_FUNCPTR (gst_text_overlay_text_pad_unlink));
-    gst_element_add_pad (GST_ELEMENT (overlay), overlay->text_sinkpad);
-  }
-
-  /* (video) source */
-  template = gst_static_pad_template_get (&src_template_factory);
-  overlay->srcpad = gst_pad_new_from_template (template, "src");
-  gst_object_unref (template);
-  gst_pad_set_getcaps_function (overlay->srcpad,
-      GST_DEBUG_FUNCPTR (gst_text_overlay_getcaps));
-  gst_pad_set_event_function (overlay->srcpad,
-      GST_DEBUG_FUNCPTR (gst_text_overlay_src_event));
-  gst_pad_set_query_function (overlay->srcpad,
-      GST_DEBUG_FUNCPTR (gst_text_overlay_src_query));
-  gst_element_add_pad (GST_ELEMENT (overlay), overlay->srcpad);
-
-  overlay->line_align = DEFAULT_PROP_LINE_ALIGNMENT;
-  g_mutex_lock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
-  overlay->layout =
-      pango_layout_new (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_context);
-  desc =
-      pango_context_get_font_description (GST_TEXT_OVERLAY_GET_CLASS
-      (overlay)->pango_context);
-  gst_text_overlay_adjust_values_with_fontdesc (overlay, desc);
-
-  overlay->color = DEFAULT_PROP_COLOR;
-  overlay->halign = DEFAULT_PROP_HALIGNMENT;
-  overlay->valign = DEFAULT_PROP_VALIGNMENT;
-  overlay->xpad = DEFAULT_PROP_XPAD;
-  overlay->ypad = DEFAULT_PROP_YPAD;
-  overlay->deltax = DEFAULT_PROP_DELTAX;
-  overlay->deltay = DEFAULT_PROP_DELTAY;
-  overlay->xpos = DEFAULT_PROP_XPOS;
-  overlay->ypos = DEFAULT_PROP_YPOS;
-
-  overlay->wrap_mode = DEFAULT_PROP_WRAP_MODE;
-
-  overlay->want_shading = DEFAULT_PROP_SHADING;
-  overlay->shading_value = DEFAULT_SHADING_VALUE;
-  overlay->silent = DEFAULT_PROP_SILENT;
-  overlay->wait_text = DEFAULT_PROP_WAIT_TEXT;
-  overlay->auto_adjust_size = DEFAULT_PROP_AUTO_ADJUST_SIZE;
-
-  overlay->default_text = g_strdup (DEFAULT_PROP_TEXT);
-  overlay->need_render = TRUE;
-  overlay->text_image = NULL;
-  overlay->use_vertical_render = DEFAULT_PROP_VERTICAL_RENDER;
-  gst_text_overlay_update_render_mode (overlay);
-
-  overlay->fps_n = 0;
-  overlay->fps_d = 1;
-
-  overlay->text_buffer = NULL;
-  overlay->text_linked = FALSE;
-  overlay->cond = g_cond_new ();
-  gst_segment_init (&overlay->segment, GST_FORMAT_TIME);
-  g_mutex_unlock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
-}
-
-static void
-gst_text_overlay_update_wrap_mode (GstTextOverlay * overlay)
-{
-  if (overlay->wrap_mode == GST_TEXT_OVERLAY_WRAP_MODE_NONE) {
-    GST_DEBUG_OBJECT (overlay, "Set wrap mode NONE");
-    pango_layout_set_width (overlay->layout, -1);
-  } else {
-    int width;
-
-    if (overlay->auto_adjust_size) {
-      width = DEFAULT_SCALE_BASIS * PANGO_SCALE;
-      if (overlay->use_vertical_render) {
-        width = width * (overlay->height - overlay->ypad * 2) / overlay->width;
-      }
-    } else {
-      width =
-          (overlay->use_vertical_render ? overlay->height : overlay->width) *
-          PANGO_SCALE;
-    }
-
-    GST_DEBUG_OBJECT (overlay, "Set layout width %d", overlay->width);
-    GST_DEBUG_OBJECT (overlay, "Set wrap mode    %d", overlay->wrap_mode);
-    pango_layout_set_width (overlay->layout, width);
-    pango_layout_set_wrap (overlay->layout, (PangoWrapMode) overlay->wrap_mode);
-  }
-}
-
-static void
-gst_text_overlay_update_render_mode (GstTextOverlay * overlay)
-{
-  PangoMatrix matrix = PANGO_MATRIX_INIT;
-  PangoContext *context = pango_layout_get_context (overlay->layout);
-
-  if (overlay->use_vertical_render) {
-    pango_matrix_rotate (&matrix, -90);
-    pango_context_set_base_gravity (context, PANGO_GRAVITY_AUTO);
-    pango_context_set_matrix (context, &matrix);
-    pango_layout_set_alignment (overlay->layout, PANGO_ALIGN_LEFT);
-  } else {
-    pango_context_set_base_gravity (context, PANGO_GRAVITY_SOUTH);
-    pango_context_set_matrix (context, &matrix);
-    pango_layout_set_alignment (overlay->layout, overlay->line_align);
-  }
-}
-
-static gboolean
-gst_text_overlay_setcaps_txt (GstPad * pad, GstCaps * caps)
-{
-  GstTextOverlay *overlay;
-  GstStructure *structure;
-
-  overlay = GST_TEXT_OVERLAY (gst_pad_get_parent (pad));
-
-  structure = gst_caps_get_structure (caps, 0);
-  overlay->have_pango_markup =
-      gst_structure_has_name (structure, "text/x-pango-markup");
-
-  gst_object_unref (overlay);
-
-  return TRUE;
-}
-
-/* FIXME: upstream nego (e.g. when the video window is resized) */
-
-static gboolean
-gst_text_overlay_setcaps (GstPad * pad, GstCaps * caps)
-{
-  GstTextOverlay *overlay;
-  GstStructure *structure;
-  gboolean ret = FALSE;
-  const GValue *fps;
-
-  if (!GST_PAD_IS_SINK (pad))
-    return TRUE;
-
-  g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
-
-  overlay = GST_TEXT_OVERLAY (gst_pad_get_parent (pad));
-
-  overlay->width = 0;
-  overlay->height = 0;
-  structure = gst_caps_get_structure (caps, 0);
-  fps = gst_structure_get_value (structure, "framerate");
-
-  if (fps
-      && gst_video_format_parse_caps (caps, &overlay->format, &overlay->width,
-          &overlay->height)) {
-    ret = gst_pad_set_caps (overlay->srcpad, caps);
-  }
-
-  overlay->fps_n = gst_value_get_fraction_numerator (fps);
-  overlay->fps_d = gst_value_get_fraction_denominator (fps);
-
-  if (ret) {
-    GST_OBJECT_LOCK (overlay);
-    g_mutex_lock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
-    gst_text_overlay_update_wrap_mode (overlay);
-    g_mutex_unlock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
-    GST_OBJECT_UNLOCK (overlay);
-  }
-
-  gst_object_unref (overlay);
-
-  return ret;
-}
-
-static void
-gst_text_overlay_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstTextOverlay *overlay = GST_TEXT_OVERLAY (object);
-
-  GST_OBJECT_LOCK (overlay);
-  switch (prop_id) {
-    case PROP_TEXT:
-      g_free (overlay->default_text);
-      overlay->default_text = g_value_dup_string (value);
-      overlay->need_render = TRUE;
-      break;
-    case PROP_SHADING:
-      overlay->want_shading = g_value_get_boolean (value);
-      break;
-    case PROP_XPAD:
-      overlay->xpad = g_value_get_int (value);
-      break;
-    case PROP_YPAD:
-      overlay->ypad = g_value_get_int (value);
-      break;
-    case PROP_DELTAX:
-      overlay->deltax = g_value_get_int (value);
-      break;
-    case PROP_DELTAY:
-      overlay->deltay = g_value_get_int (value);
-      break;
-    case PROP_XPOS:
-      overlay->xpos = g_value_get_double (value);
-      break;
-    case PROP_YPOS:
-      overlay->ypos = g_value_get_double (value);
-      break;
-    case PROP_HALIGN:{
-      const gchar *s = g_value_get_string (value);
-
-      if (s && g_ascii_strcasecmp (s, "left") == 0)
-        overlay->halign = GST_TEXT_OVERLAY_HALIGN_LEFT;
-      else if (s && g_ascii_strcasecmp (s, "center") == 0)
-        overlay->halign = GST_TEXT_OVERLAY_HALIGN_CENTER;
-      else if (s && g_ascii_strcasecmp (s, "right") == 0)
-        overlay->halign = GST_TEXT_OVERLAY_HALIGN_RIGHT;
-      else
-        g_warning ("Invalid value '%s' for textoverlay property 'halign'",
-            GST_STR_NULL (s));
-      break;
-    }
-    case PROP_VALIGN:{
-      const gchar *s = g_value_get_string (value);
-
-      if (s && g_ascii_strcasecmp (s, "baseline") == 0)
-        overlay->valign = GST_TEXT_OVERLAY_VALIGN_BASELINE;
-      else if (s && g_ascii_strcasecmp (s, "bottom") == 0)
-        overlay->valign = GST_TEXT_OVERLAY_VALIGN_BOTTOM;
-      else if (s && g_ascii_strcasecmp (s, "top") == 0)
-        overlay->valign = GST_TEXT_OVERLAY_VALIGN_TOP;
-      else
-        g_warning ("Invalid value '%s' for textoverlay property 'valign'",
-            GST_STR_NULL (s));
-      break;
-    }
-    case PROP_VALIGNMENT:
-      overlay->valign = g_value_get_enum (value);
-      break;
-    case PROP_HALIGNMENT:
-      overlay->halign = g_value_get_enum (value);
-      break;
-    case PROP_WRAP_MODE:
-      overlay->wrap_mode = g_value_get_enum (value);
-      g_mutex_lock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
-      gst_text_overlay_update_wrap_mode (overlay);
-      g_mutex_unlock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
-      break;
-    case PROP_FONT_DESC:
-    {
-      PangoFontDescription *desc;
-      const gchar *fontdesc_str;
-
-      fontdesc_str = g_value_get_string (value);
-      g_mutex_lock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
-      desc = pango_font_description_from_string (fontdesc_str);
-      if (desc) {
-        GST_LOG_OBJECT (overlay, "font description set: %s", fontdesc_str);
-        pango_layout_set_font_description (overlay->layout, desc);
-        gst_text_overlay_adjust_values_with_fontdesc (overlay, desc);
-        pango_font_description_free (desc);
-      } else {
-        GST_WARNING_OBJECT (overlay, "font description parse failed: %s",
-            fontdesc_str);
-      }
-      g_mutex_unlock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
-      break;
-    }
-    case PROP_COLOR:
-      overlay->color = g_value_get_uint (value);
-      break;
-    case PROP_SILENT:
-      overlay->silent = g_value_get_boolean (value);
-      break;
-    case PROP_LINE_ALIGNMENT:
-      overlay->line_align = g_value_get_enum (value);
-      g_mutex_lock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
-      pango_layout_set_alignment (overlay->layout,
-          (PangoAlignment) overlay->line_align);
-      g_mutex_unlock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
-      break;
-    case PROP_WAIT_TEXT:
-      overlay->wait_text = g_value_get_boolean (value);
-      break;
-    case PROP_AUTO_ADJUST_SIZE:
-      overlay->auto_adjust_size = g_value_get_boolean (value);
-      overlay->need_render = TRUE;
-      break;
-    case PROP_VERTICAL_RENDER:
-      overlay->use_vertical_render = g_value_get_boolean (value);
-      g_mutex_lock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
-      gst_text_overlay_update_render_mode (overlay);
-      g_mutex_unlock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
-      overlay->need_render = TRUE;
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-
-  overlay->need_render = TRUE;
-  GST_OBJECT_UNLOCK (overlay);
-}
-
-static void
-gst_text_overlay_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstTextOverlay *overlay = GST_TEXT_OVERLAY (object);
-
-  GST_OBJECT_LOCK (overlay);
-  switch (prop_id) {
-    case PROP_TEXT:
-      g_value_set_string (value, overlay->default_text);
-      break;
-    case PROP_SHADING:
-      g_value_set_boolean (value, overlay->want_shading);
-      break;
-    case PROP_XPAD:
-      g_value_set_int (value, overlay->xpad);
-      break;
-    case PROP_YPAD:
-      g_value_set_int (value, overlay->ypad);
-      break;
-    case PROP_DELTAX:
-      g_value_set_int (value, overlay->deltax);
-      break;
-    case PROP_DELTAY:
-      g_value_set_int (value, overlay->deltay);
-      break;
-    case PROP_XPOS:
-      g_value_set_double (value, overlay->xpos);
-      break;
-    case PROP_YPOS:
-      g_value_set_double (value, overlay->ypos);
-      break;
-    case PROP_VALIGNMENT:
-      g_value_set_enum (value, overlay->valign);
-      break;
-    case PROP_HALIGNMENT:
-      g_value_set_enum (value, overlay->halign);
-      break;
-    case PROP_WRAP_MODE:
-      g_value_set_enum (value, overlay->wrap_mode);
-      break;
-    case PROP_SILENT:
-      g_value_set_boolean (value, overlay->silent);
-      break;
-    case PROP_LINE_ALIGNMENT:
-      g_value_set_enum (value, overlay->line_align);
-      break;
-    case PROP_WAIT_TEXT:
-      g_value_set_boolean (value, overlay->wait_text);
-      break;
-    case PROP_AUTO_ADJUST_SIZE:
-      g_value_set_boolean (value, overlay->auto_adjust_size);
-      break;
-    case PROP_VERTICAL_RENDER:
-      g_value_set_boolean (value, overlay->use_vertical_render);
-      break;
-    case PROP_COLOR:
-      g_value_set_uint (value, overlay->color);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-
-  overlay->need_render = TRUE;
-  GST_OBJECT_UNLOCK (overlay);
-}
-
-static gboolean
-gst_text_overlay_src_query (GstPad * pad, GstQuery * query)
-{
-  gboolean ret = FALSE;
-  GstTextOverlay *overlay = NULL;
-
-  overlay = GST_TEXT_OVERLAY (gst_pad_get_parent (pad));
-
-  ret = gst_pad_peer_query (overlay->video_sinkpad, query);
-
-  gst_object_unref (overlay);
-
-  return ret;
-}
-
-static gboolean
-gst_text_overlay_src_event (GstPad * pad, GstEvent * event)
-{
-  gboolean ret = FALSE;
-  GstTextOverlay *overlay = NULL;
-
-  overlay = GST_TEXT_OVERLAY (gst_pad_get_parent (pad));
-
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_SEEK:{
-      GstSeekFlags flags;
-
-      /* We don't handle seek if we have not text pad */
-      if (!overlay->text_linked) {
-        GST_DEBUG_OBJECT (overlay, "seek received, pushing upstream");
-        ret = gst_pad_push_event (overlay->video_sinkpad, event);
-        goto beach;
-      }
-
-      GST_DEBUG_OBJECT (overlay, "seek received, driving from here");
-
-      gst_event_parse_seek (event, NULL, NULL, &flags, NULL, NULL, NULL, NULL);
-
-      /* Flush downstream, only for flushing seek */
-      if (flags & GST_SEEK_FLAG_FLUSH)
-        gst_pad_push_event (overlay->srcpad, gst_event_new_flush_start ());
-
-      /* Mark ourself as flushing, unblock chains */
-      GST_OBJECT_LOCK (overlay);
-      overlay->video_flushing = TRUE;
-      overlay->text_flushing = TRUE;
-      gst_text_overlay_pop_text (overlay);
-      GST_OBJECT_UNLOCK (overlay);
-
-      /* Seek on each sink pad */
-      gst_event_ref (event);
-      ret = gst_pad_push_event (overlay->video_sinkpad, event);
-      if (ret) {
-        ret = gst_pad_push_event (overlay->text_sinkpad, event);
-      } else {
-        gst_event_unref (event);
-      }
-      break;
-    }
-    default:
-      if (overlay->text_linked) {
-        gst_event_ref (event);
-        ret = gst_pad_push_event (overlay->video_sinkpad, event);
-        gst_pad_push_event (overlay->text_sinkpad, event);
-      } else {
-        ret = gst_pad_push_event (overlay->video_sinkpad, event);
-      }
-      break;
-  }
-
-beach:
-  gst_object_unref (overlay);
-
-  return ret;
-}
-
-static GstCaps *
-gst_text_overlay_getcaps (GstPad * pad)
-{
-  GstTextOverlay *overlay;
-  GstPad *otherpad;
-  GstCaps *caps;
-
-  overlay = GST_TEXT_OVERLAY (gst_pad_get_parent (pad));
-
-  if (pad == overlay->srcpad)
-    otherpad = overlay->video_sinkpad;
-  else
-    otherpad = overlay->srcpad;
-
-  /* we can do what the peer can */
-  caps = gst_pad_peer_get_caps (otherpad);
-  if (caps) {
-    GstCaps *temp;
-    const GstCaps *templ;
-
-    GST_DEBUG_OBJECT (pad, "peer caps  %" GST_PTR_FORMAT, caps);
-
-    /* filtered against our padtemplate */
-    templ = gst_pad_get_pad_template_caps (otherpad);
-    GST_DEBUG_OBJECT (pad, "our template  %" GST_PTR_FORMAT, templ);
-    temp = gst_caps_intersect (caps, templ);
-    GST_DEBUG_OBJECT (pad, "intersected %" GST_PTR_FORMAT, temp);
-    gst_caps_unref (caps);
-    /* this is what we can do */
-    caps = temp;
-  } else {
-    /* no peer, our padtemplate is enough then */
-    caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
-  }
-
-  GST_DEBUG_OBJECT (overlay, "returning  %" GST_PTR_FORMAT, caps);
-
-  gst_object_unref (overlay);
-
-  return caps;
-}
-
-static void
-gst_text_overlay_adjust_values_with_fontdesc (GstTextOverlay * overlay,
-    PangoFontDescription * desc)
-{
-  gint font_size = pango_font_description_get_size (desc) / PANGO_SCALE;
-  overlay->shadow_offset = (double) (font_size) / 13.0;
-  overlay->outline_offset = (double) (font_size) / 15.0;
-  if (overlay->outline_offset < MINIMUM_OUTLINE_OFFSET)
-    overlay->outline_offset = MINIMUM_OUTLINE_OFFSET;
-}
-
-#define CAIRO_UNPREMULTIPLY(a,r,g,b) G_STMT_START { \
-  b = (a > 0) ? MIN ((b * 255 + a / 2) / a, 255) : 0; \
-  g = (a > 0) ? MIN ((g * 255 + a / 2) / a, 255) : 0; \
-  r = (a > 0) ? MIN ((r * 255 + a / 2) / a, 255) : 0; \
-} G_STMT_END
-
-static inline void
-gst_text_overlay_blit_1 (GstTextOverlay * overlay, guchar * dest, gint xpos,
-    gint ypos, guchar * text_image, guint dest_stride)
-{
-  gint i, j = 0;
-  gint x, y;
-  guchar r, g, b, a;
-  guchar *pimage;
-  guchar *py;
-  gint width = overlay->image_width;
-  gint height = overlay->image_height;
-
-  if (xpos < 0) {
-    xpos = 0;
-  }
-
-  if (xpos + width > overlay->width) {
-    width = overlay->width - xpos;
-  }
-
-  if (ypos + height > overlay->height) {
-    height = overlay->height - ypos;
-  }
-
-  dest += (ypos / 1) * dest_stride;
-
-  for (i = 0; i < height; i++) {
-    pimage = text_image + 4 * (i * overlay->image_width);
-    py = dest + i * dest_stride + xpos;
-    for (j = 0; j < width; j++) {
-      b = pimage[CAIRO_ARGB_B];
-      g = pimage[CAIRO_ARGB_G];
-      r = pimage[CAIRO_ARGB_R];
-      a = pimage[CAIRO_ARGB_A];
-      CAIRO_UNPREMULTIPLY (a, r, g, b);
-
-      pimage += 4;
-      if (a == 0) {
-        py++;
-        continue;
-      }
-      COMP_Y (y, r, g, b);
-      x = *py;
-      BLEND (*py++, a, y, x);
-    }
-  }
-}
-
-static inline void
-gst_text_overlay_blit_sub2x2cbcr (GstTextOverlay * overlay,
-    guchar * destcb, guchar * destcr, gint xpos, gint ypos, guchar * text_image,
-    guint destcb_stride, guint destcr_stride, guint pix_stride)
-{
-  gint i, j;
-  gint x, cb, cr;
-  gushort r, g, b, a;
-  gushort r1, g1, b1, a1;
-  guchar *pimage1, *pimage2;
-  guchar *pcb, *pcr;
-  gint width = overlay->image_width - 2;
-  gint height = overlay->image_height - 2;
-
-  xpos *= pix_stride;
-
-  if (xpos < 0) {
-    xpos = 0;
-  }
-
-  if (xpos + width > overlay->width) {
-    width = overlay->width - xpos;
-  }
-
-  if (ypos + height > overlay->height) {
-    height = overlay->height - ypos;
-  }
-
-  destcb += (ypos / 2) * destcb_stride;
-  destcr += (ypos / 2) * destcr_stride;
-
-  for (i = 0; i < height; i += 2) {
-    pimage1 = text_image + 4 * (i * overlay->image_width);
-    pimage2 = pimage1 + 4 * overlay->image_width;
-    pcb = destcb + (i / 2) * destcb_stride + xpos / 2;
-    pcr = destcr + (i / 2) * destcr_stride + xpos / 2;
-    for (j = 0; j < width; j += 2) {
-      b = pimage1[CAIRO_ARGB_B];
-      g = pimage1[CAIRO_ARGB_G];
-      r = pimage1[CAIRO_ARGB_R];
-      a = pimage1[CAIRO_ARGB_A];
-      CAIRO_UNPREMULTIPLY (a, r, g, b);
-      pimage1 += 4;
-
-      b1 = pimage1[CAIRO_ARGB_B];
-      g1 = pimage1[CAIRO_ARGB_G];
-      r1 = pimage1[CAIRO_ARGB_R];
-      a1 = pimage1[CAIRO_ARGB_A];
-      CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
-      b += b1;
-      g += g1;
-      r += r1;
-      a += a1;
-      pimage1 += 4;
-
-      b1 = pimage2[CAIRO_ARGB_B];
-      g1 = pimage2[CAIRO_ARGB_G];
-      r1 = pimage2[CAIRO_ARGB_R];
-      a1 = pimage2[CAIRO_ARGB_A];
-      CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
-      b += b1;
-      g += g1;
-      r += r1;
-      a += a1;
-      pimage2 += 4;
-
-      /* + 2 for rounding */
-      b1 = pimage2[CAIRO_ARGB_B];
-      g1 = pimage2[CAIRO_ARGB_G];
-      r1 = pimage2[CAIRO_ARGB_R];
-      a1 = pimage2[CAIRO_ARGB_A];
-      CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
-      b += b1 + 2;
-      g += g1 + 2;
-      r += r1 + 2;
-      a += a1 + 2;
-      pimage2 += 4;
-
-      b /= 4;
-      g /= 4;
-      r /= 4;
-      a /= 4;
-
-      if (a == 0) {
-        pcb += pix_stride;
-        pcr += pix_stride;
-        continue;
-      }
-      COMP_U (cb, r, g, b);
-      COMP_V (cr, r, g, b);
-
-      x = *pcb;
-      BLEND (*pcb, a, cb, x);
-      x = *pcr;
-      BLEND (*pcr, a, cr, x);
-
-      pcb += pix_stride;
-      pcr += pix_stride;
-    }
-  }
-}
-
-static void
-gst_text_overlay_render_pangocairo (GstTextOverlay * overlay,
-    const gchar * string, gint textlen)
-{
-  cairo_t *cr;
-  cairo_surface_t *surface;
-  PangoRectangle ink_rect, logical_rect;
-  cairo_matrix_t cairo_matrix;
-  int width, height;
-  double scalef = 1.0;
-  double a, r, g, b;
-
-  g_mutex_lock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
-
-  if (overlay->auto_adjust_size) {
-    /* 640 pixel is default */
-    scalef = (double) (overlay->width) / DEFAULT_SCALE_BASIS;
-  }
-  pango_layout_set_width (overlay->layout, -1);
-  /* set text on pango layout */
-  pango_layout_set_markup (overlay->layout, string, textlen);
-
-  /* get subtitle image size */
-  pango_layout_get_pixel_extents (overlay->layout, &ink_rect, &logical_rect);
-
-  width = (logical_rect.width + overlay->shadow_offset) * scalef;
-
-  if (width + overlay->deltax >
-      (overlay->use_vertical_render ? overlay->height : overlay->width)) {
-    /*
-     * subtitle image width is larger then overlay width
-     * so rearrange overlay wrap mode.
-     */
-    gst_text_overlay_update_wrap_mode (overlay);
-    pango_layout_get_pixel_extents (overlay->layout, &ink_rect, &logical_rect);
-    width = overlay->width;
-  }
-
-  height =
-      (logical_rect.height + logical_rect.y + overlay->shadow_offset) * scalef;
-  if (height > overlay->height) {
-    height = overlay->height;
-  }
-  if (overlay->use_vertical_render) {
-    PangoRectangle rect;
-    PangoContext *context;
-    PangoMatrix matrix = PANGO_MATRIX_INIT;
-    int tmp;
-
-    context = pango_layout_get_context (overlay->layout);
-
-    pango_matrix_rotate (&matrix, -90);
-
-    rect.x = rect.y = 0;
-    rect.width = width;
-    rect.height = height;
-    pango_matrix_transform_pixel_rectangle (&matrix, &rect);
-    matrix.x0 = -rect.x;
-    matrix.y0 = -rect.y;
-
-    pango_context_set_matrix (context, &matrix);
-
-    cairo_matrix.xx = matrix.xx;
-    cairo_matrix.yx = matrix.yx;
-    cairo_matrix.xy = matrix.xy;
-    cairo_matrix.yy = matrix.yy;
-    cairo_matrix.x0 = matrix.x0;
-    cairo_matrix.y0 = matrix.y0;
-    cairo_matrix_scale (&cairo_matrix, scalef, scalef);
-
-    tmp = height;
-    height = width;
-    width = tmp;
-  } else {
-    cairo_matrix_init_scale (&cairo_matrix, scalef, scalef);
-  }
-
-  /* reallocate surface */
-  overlay->text_image = g_realloc (overlay->text_image, 4 * width * height);
-
-  surface = cairo_image_surface_create_for_data (overlay->text_image,
-      CAIRO_FORMAT_ARGB32, width, height, width * 4);
-  cr = cairo_create (surface);
-
-  /* clear surface */
-  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
-  cairo_paint (cr);
-
-  cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
-
-  if (overlay->want_shading)
-    cairo_paint_with_alpha (cr, overlay->shading_value);
-
-  /* apply transformations */
-  cairo_set_matrix (cr, &cairo_matrix);
-
-  /* FIXME: We use show_layout everywhere except for the surface
-   * because it's really faster and internally does all kinds of
-   * caching. Unfortunately we have to paint to a cairo path for
-   * the outline and this is slow. Once Pango supports user fonts
-   * we should use them, see
-   * https://bugzilla.gnome.org/show_bug.cgi?id=598695
-   *
-   * Idea would the be, to create a cairo user font that
-   * does shadow, outline, text painting in the
-   * render_glyph function.
-   */
-
-  /* draw shadow text */
-  cairo_save (cr);
-  cairo_translate (cr, overlay->shadow_offset, overlay->shadow_offset);
-  cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.5);
-  pango_cairo_show_layout (cr, overlay->layout);
-  cairo_restore (cr);
-
-  /* draw outline text */
-  cairo_save (cr);
-  cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
-  cairo_set_line_width (cr, overlay->outline_offset);
-  pango_cairo_layout_path (cr, overlay->layout);
-  cairo_stroke (cr);
-  cairo_restore (cr);
-
-  a = (overlay->color >> 24) & 0xff;
-  r = (overlay->color >> 16) & 0xff;
-  g = (overlay->color >> 8) & 0xff;
-  b = (overlay->color >> 0) & 0xff;
-
-  /* draw text */
-  cairo_save (cr);
-  cairo_set_source_rgba (cr, r / 255.0, g / 255.0, b / 255.0, a / 255.0);
-  pango_cairo_show_layout (cr, overlay->layout);
-  cairo_restore (cr);
-
-  cairo_destroy (cr);
-  cairo_surface_destroy (surface);
-  overlay->image_width = width;
-  overlay->image_height = height;
-  overlay->baseline_y = ink_rect.y;
-
-  g_mutex_unlock (GST_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
-}
-
-#define BOX_XPAD         6
-#define BOX_YPAD         6
-
-static inline void
-gst_text_overlay_shade_planar_Y (GstTextOverlay * overlay, guchar * dest,
-    gint x0, gint x1, gint y0, gint y1)
-{
-  gint i, j, dest_stride;
-
-  dest_stride = gst_video_format_get_row_stride (overlay->format, 0,
-      overlay->width);
-
-  x0 = CLAMP (x0 - BOX_XPAD, 0, overlay->width);
-  x1 = CLAMP (x1 + BOX_XPAD, 0, overlay->width);
-
-  y0 = CLAMP (y0 - BOX_YPAD, 0, overlay->height);
-  y1 = CLAMP (y1 + BOX_YPAD, 0, overlay->height);
-
-  for (i = y0; i < y1; ++i) {
-    for (j = x0; j < x1; ++j) {
-      gint y = dest[(i * dest_stride) + j] + overlay->shading_value;
-
-      dest[(i * dest_stride) + j] = CLAMP (y, 0, 255);
-    }
-  }
-}
-
-static inline void
-gst_text_overlay_shade_packed_Y (GstTextOverlay * overlay, guchar * dest,
-    gint x0, gint x1, gint y0, gint y1)
-{
-  gint i, j;
-  guint dest_stride, pixel_stride, component_offset;
-
-  dest_stride = gst_video_format_get_row_stride (overlay->format, 0,
-      overlay->width);
-  pixel_stride = gst_video_format_get_pixel_stride (overlay->format, 0);
-  component_offset =
-      gst_video_format_get_component_offset (overlay->format, 0, overlay->width,
-      overlay->height);
-
-  x0 = CLAMP (x0 - BOX_XPAD, 0, overlay->width);
-  x1 = CLAMP (x1 + BOX_XPAD, 0, overlay->width);
-
-  y0 = CLAMP (y0 - BOX_YPAD, 0, overlay->height);
-  y1 = CLAMP (y1 + BOX_YPAD, 0, overlay->height);
-
-  if (x0 != 0)
-    x0 = gst_video_format_get_component_width (overlay->format, 0, x0);
-  if (x1 != 0)
-    x1 = gst_video_format_get_component_width (overlay->format, 0, x1);
-
-  if (y0 != 0)
-    y0 = gst_video_format_get_component_height (overlay->format, 0, y0);
-  if (y1 != 0)
-    y1 = gst_video_format_get_component_height (overlay->format, 0, y1);
-
-  for (i = y0; i < y1; i++) {
-    for (j = x0; j < x1; j++) {
-      gint y;
-      gint y_pos;
-
-      y_pos = (i * dest_stride) + j * pixel_stride + component_offset;
-      y = dest[y_pos] + overlay->shading_value;
-
-      dest[y_pos] = CLAMP (y, 0, 255);
-    }
-  }
-}
-
-#define gst_text_overlay_shade_BGRx gst_text_overlay_shade_xRGB
-#define gst_text_overlay_shade_RGBx gst_text_overlay_shade_xRGB
-#define gst_text_overlay_shade_xBGR gst_text_overlay_shade_xRGB
-static inline void
-gst_text_overlay_shade_xRGB (GstTextOverlay * overlay, guchar * dest,
-    gint x0, gint x1, gint y0, gint y1)
-{
-  gint i, j;
-
-  x0 = CLAMP (x0 - BOX_XPAD, 0, overlay->width);
-  x1 = CLAMP (x1 + BOX_XPAD, 0, overlay->width);
-
-  y0 = CLAMP (y0 - BOX_YPAD, 0, overlay->height);
-  y1 = CLAMP (y1 + BOX_YPAD, 0, overlay->height);
-
-  for (i = y0; i < y1; i++) {
-    for (j = x0; j < x1; j++) {
-      gint y, y_pos, k;
-
-      y_pos = (i * 4 * overlay->width) + j * 4;
-      for (k = 0; k < 4; k++) {
-        y = dest[y_pos + k] + overlay->shading_value;
-        dest[y_pos + k] = CLAMP (y, 0, 255);
-      }
-    }
-  }
-}
-
-#define ARGB_SHADE_FUNCTION(name, OFFSET)      \
-static inline void \
-gst_text_overlay_shade_##name (GstTextOverlay * overlay, guchar * dest, \
-gint x0, gint x1, gint y0, gint y1) \
-{ \
-  gint i, j;\
-  \
-  x0 = CLAMP (x0 - BOX_XPAD, 0, overlay->width);\
-  x1 = CLAMP (x1 + BOX_XPAD, 0, overlay->width);\
-  \
-  y0 = CLAMP (y0 - BOX_YPAD, 0, overlay->height);\
-  y1 = CLAMP (y1 + BOX_YPAD, 0, overlay->height);\
-  \
-  for (i = y0; i < y1; i++) {\
-    for (j = x0; j < x1; j++) {\
-      gint y, y_pos, k;\
-      y_pos = (i * 4 * overlay->width) + j * 4;\
-      for (k = OFFSET; k < 3+OFFSET; k++) {\
-        y = dest[y_pos + k] + overlay->shading_value;\
-        dest[y_pos + k] = CLAMP (y, 0, 255);\
-      }\
-    }\
-  }\
-}
-ARGB_SHADE_FUNCTION (ARGB, 1);
-ARGB_SHADE_FUNCTION (ABGR, 1);
-ARGB_SHADE_FUNCTION (RGBA, 0);
-ARGB_SHADE_FUNCTION (BGRA, 0);
-
-
-/* FIXME:
- *  - use proper strides and offset for I420
- *  - don't draw over the edge of the picture (try a longer
- *    text with a huge font size)
- */
-
-static inline void
-gst_text_overlay_blit_NV12_NV21 (GstTextOverlay * overlay,
-    guint8 * yuv_pixels, gint xpos, gint ypos)
-{
-  int y_stride, uv_stride;
-  int u_offset, v_offset;
-  int h, w;
-
-  /* because U/V is 2x2 subsampled, we need to round, either up or down,
-   * to a boundary of integer number of U/V pixels:
-   */
-  xpos = GST_ROUND_UP_2 (xpos);
-  ypos = GST_ROUND_UP_2 (ypos);
-
-  w = overlay->width;
-  h = overlay->height;
-
-  y_stride = gst_video_format_get_row_stride (overlay->format, 0, w);
-  uv_stride = gst_video_format_get_row_stride (overlay->format, 1, w);
-  u_offset = gst_video_format_get_component_offset (overlay->format, 1, w, h);
-  v_offset = gst_video_format_get_component_offset (overlay->format, 2, w, h);
-
-  gst_text_overlay_blit_1 (overlay, yuv_pixels, xpos, ypos, overlay->text_image,
-      y_stride);
-  gst_text_overlay_blit_sub2x2cbcr (overlay, yuv_pixels + u_offset,
-      yuv_pixels + v_offset, xpos, ypos, overlay->text_image, uv_stride,
-      uv_stride, 2);
-}
-
-static inline void
-gst_text_overlay_blit_I420 (GstTextOverlay * overlay,
-    guint8 * yuv_pixels, gint xpos, gint ypos)
-{
-  int y_stride, u_stride, v_stride;
-  int u_offset, v_offset;
-  int h, w;
-
-  /* because U/V is 2x2 subsampled, we need to round, either up or down,
-   * to a boundary of integer number of U/V pixels:
-   */
-  xpos = GST_ROUND_UP_2 (xpos);
-  ypos = GST_ROUND_UP_2 (ypos);
-
-  w = overlay->width;
-  h = overlay->height;
-
-  y_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 0, w);
-  u_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 1, w);
-  v_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 2, w);
-  u_offset =
-      gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, 1, w, h);
-  v_offset =
-      gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, 2, w, h);
-
-  gst_text_overlay_blit_1 (overlay, yuv_pixels, xpos, ypos, overlay->text_image,
-      y_stride);
-  gst_text_overlay_blit_sub2x2cbcr (overlay, yuv_pixels + u_offset,
-      yuv_pixels + v_offset, xpos, ypos, overlay->text_image, u_stride,
-      v_stride, 1);
-}
-
-static inline void
-gst_text_overlay_blit_UYVY (GstTextOverlay * overlay,
-    guint8 * yuv_pixels, gint xpos, gint ypos)
-{
-  int a0, r0, g0, b0;
-  int a1, r1, g1, b1;
-  int y0, y1, u, v;
-  int i, j;
-  int h, w;
-  guchar *pimage, *dest;
-
-  /* because U/V is 2x horizontally subsampled, we need to round to a
-   * boundary of integer number of U/V pixels in x dimension:
-   */
-  xpos = GST_ROUND_UP_2 (xpos);
-
-  w = overlay->image_width - 2;
-  h = overlay->image_height - 2;
-
-  if (xpos < 0) {
-    xpos = 0;
-  }
-
-  if (xpos + w > overlay->width) {
-    w = overlay->width - xpos;
-  }
-
-  if (ypos + h > overlay->height) {
-    h = overlay->height - ypos;
-  }
-
-  for (i = 0; i < h; i++) {
-    pimage = overlay->text_image + i * overlay->image_width * 4;
-    dest = yuv_pixels + (i + ypos) * overlay->width * 2 + xpos * 2;
-    for (j = 0; j < w; j += 2) {
-      b0 = pimage[CAIRO_ARGB_B];
-      g0 = pimage[CAIRO_ARGB_G];
-      r0 = pimage[CAIRO_ARGB_R];
-      a0 = pimage[CAIRO_ARGB_A];
-      CAIRO_UNPREMULTIPLY (a0, r0, g0, b0);
-      pimage += 4;
-
-      b1 = pimage[CAIRO_ARGB_B];
-      g1 = pimage[CAIRO_ARGB_G];
-      r1 = pimage[CAIRO_ARGB_R];
-      a1 = pimage[CAIRO_ARGB_A];
-      CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
-      pimage += 4;
-
-      a0 += a1 + 2;
-      a0 /= 2;
-      if (a0 == 0) {
-        dest += 4;
-        continue;
-      }
-
-      COMP_Y (y0, r0, g0, b0);
-      COMP_Y (y1, r1, g1, b1);
-
-      b0 += b1 + 2;
-      g0 += g1 + 2;
-      r0 += r1 + 2;
-
-      b0 /= 2;
-      g0 /= 2;
-      r0 /= 2;
-
-      COMP_U (u, r0, g0, b0);
-      COMP_V (v, r0, g0, b0);
-
-      BLEND (*dest, a0, u, *dest);
-      dest++;
-      BLEND (*dest, a0, y0, *dest);
-      dest++;
-      BLEND (*dest, a0, v, *dest);
-      dest++;
-      BLEND (*dest, a0, y1, *dest);
-      dest++;
-    }
-  }
-}
-
-static inline void
-gst_text_overlay_blit_AYUV (GstTextOverlay * overlay,
-    guint8 * rgb_pixels, gint xpos, gint ypos)
-{
-  int a, r, g, b, a1;
-  int y, u, v;
-  int i, j;
-  int h, w;
-  guchar *pimage, *dest;
-
-  w = overlay->image_width;
-  h = overlay->image_height;
-
-  if (xpos < 0) {
-    xpos = 0;
-  }
-
-  if (xpos + w > overlay->width) {
-    w = overlay->width - xpos;
-  }
-
-  if (ypos + h > overlay->height) {
-    h = overlay->height - ypos;
-  }
-
-  for (i = 0; i < h; i++) {
-    pimage = overlay->text_image + i * overlay->image_width * 4;
-    dest = rgb_pixels + (i + ypos) * 4 * overlay->width + xpos * 4;
-    for (j = 0; j < w; j++) {
-      a = pimage[CAIRO_ARGB_A];
-      b = pimage[CAIRO_ARGB_B];
-      g = pimage[CAIRO_ARGB_G];
-      r = pimage[CAIRO_ARGB_R];
-
-      CAIRO_UNPREMULTIPLY (a, r, g, b);
-
-      // convert background to yuv
-      COMP_Y (y, r, g, b);
-      COMP_U (u, r, g, b);
-      COMP_V (v, r, g, b);
-
-      // preform text "OVER" background alpha compositing
-      a1 = a + (dest[0] * (255 - a)) / 255 + 1; // add 1 to prevent divide by 0
-      OVER (dest[1], a, y, dest[0], dest[1], a1);
-      OVER (dest[2], a, u, dest[0], dest[2], a1);
-      OVER (dest[3], a, v, dest[0], dest[3], a1);
-      dest[0] = a1 - 1;         // remove the temporary 1 we added
-
-      pimage += 4;
-      dest += 4;
-    }
-  }
-}
-
-#define xRGB_BLIT_FUNCTION(name, R, G, B) \
-static inline void \
-gst_text_overlay_blit_##name (GstTextOverlay * overlay, \
-    guint8 * rgb_pixels, gint xpos, gint ypos) \
-{ \
-  int a, r, g, b; \
-  int i, j; \
-  int h, w; \
-  guchar *pimage, *dest; \
-  \
-  w = overlay->image_width; \
-  h = overlay->image_height; \
-  \
-  if (xpos < 0) { \
-    xpos = 0; \
-  } \
-  \
-  if (xpos + w > overlay->width) { \
-    w = overlay->width - xpos; \
-  } \
-  \
-  if (ypos + h > overlay->height) { \
-    h = overlay->height - ypos; \
-  } \
-  \
-  for (i = 0; i < h; i++) { \
-    pimage = overlay->text_image + i * overlay->image_width * 4; \
-    dest = rgb_pixels + (i + ypos) * 4 * overlay->width + xpos * 4; \
-    for (j = 0; j < w; j++) { \
-      a = pimage[CAIRO_ARGB_A]; \
-      b = pimage[CAIRO_ARGB_B]; \
-      g = pimage[CAIRO_ARGB_G]; \
-      r = pimage[CAIRO_ARGB_R]; \
-      CAIRO_UNPREMULTIPLY (a, r, g, b); \
-      b = (b*a + dest[B] * (255-a)) / 255; \
-      g = (g*a + dest[G] * (255-a)) / 255; \
-      r = (r*a + dest[R] * (255-a)) / 255; \
-      \
-      dest[B] = b; \
-      dest[G] = g; \
-      dest[R] = r; \
-      pimage += 4; \
-      dest += 4; \
-    } \
-  } \
-}
-xRGB_BLIT_FUNCTION (xRGB, 1, 2, 3);
-xRGB_BLIT_FUNCTION (BGRx, 2, 1, 0);
-xRGB_BLIT_FUNCTION (xBGR, 3, 2, 1);
-xRGB_BLIT_FUNCTION (RGBx, 0, 1, 2);
-
-#define ARGB_BLIT_FUNCTION(name, A, R, G, B)   \
-static inline void \
-gst_text_overlay_blit_##name (GstTextOverlay * overlay, \
-    guint8 * rgb_pixels, gint xpos, gint ypos) \
-{ \
-  int a, r, g, b, a1;                          \
-  int i, j; \
-  int h, w; \
-  guchar *pimage, *dest; \
-  \
-  w = overlay->image_width; \
-  h = overlay->image_height; \
-  \
-  if (xpos < 0) { \
-    xpos = 0; \
-  } \
-  \
-  if (xpos + w > overlay->width) { \
-    w = overlay->width - xpos; \
-  } \
-  \
-  if (ypos + h > overlay->height) { \
-    h = overlay->height - ypos; \
-  } \
-  \
-  for (i = 0; i < h; i++) { \
-    pimage = overlay->text_image + i * overlay->image_width * 4; \
-    dest = rgb_pixels + (i + ypos) * 4 * overlay->width + xpos * 4; \
-    for (j = 0; j < w; j++) { \
-      a = pimage[CAIRO_ARGB_A]; \
-      b = pimage[CAIRO_ARGB_B]; \
-      g = pimage[CAIRO_ARGB_G]; \
-      r = pimage[CAIRO_ARGB_R]; \
-      CAIRO_UNPREMULTIPLY (a, r, g, b); \
-      a1 = a + (dest[A] * (255 - a)) / 255 + 1; \
-      OVER (dest[R], a, r, dest[0], dest[R], a1); \
-      OVER (dest[G], a, g, dest[0], dest[G], a1); \
-      OVER (dest[B], a, b, dest[0], dest[B], a1); \
-      dest[A] = a1 - 1; \
-      pimage += 4; \
-      dest += 4; \
-    } \
-  } \
-}
-ARGB_BLIT_FUNCTION (RGBA, 3, 0, 1, 2);
-ARGB_BLIT_FUNCTION (BGRA, 3, 2, 1, 0);
-ARGB_BLIT_FUNCTION (ARGB, 0, 1, 2, 3);
-ARGB_BLIT_FUNCTION (ABGR, 0, 3, 2, 1);
-
-static void
-gst_text_overlay_render_text (GstTextOverlay * overlay,
-    const gchar * text, gint textlen)
-{
-  gchar *string;
-
-  if (!overlay->need_render) {
-    GST_DEBUG ("Using previously rendered text.");
-    return;
-  }
-
-  /* -1 is the whole string */
-  if (text != NULL && textlen < 0) {
-    textlen = strlen (text);
-  }
-
-  if (text != NULL) {
-    string = g_strndup (text, textlen);
-  } else {                      /* empty string */
-    string = g_strdup (" ");
-  }
-  g_strdelimit (string, "\r\t", ' ');
-  textlen = strlen (string);
-
-  /* FIXME: should we check for UTF-8 here? */
-
-  GST_DEBUG ("Rendering '%s'", string);
-  gst_text_overlay_render_pangocairo (overlay, string, textlen);
-
-  g_free (string);
-
-  overlay->need_render = FALSE;
-}
-
-static GstFlowReturn
-gst_text_overlay_push_frame (GstTextOverlay * overlay, GstBuffer * video_frame)
-{
-  gint xpos, ypos;
-  gint width, height;
-  GstTextOverlayVAlign valign;
-  GstTextOverlayHAlign halign;
-
-  width = overlay->image_width;
-  height = overlay->image_height;
-
-  video_frame = gst_buffer_make_writable (video_frame);
-
-  if (overlay->use_vertical_render)
-    halign = GST_TEXT_OVERLAY_HALIGN_RIGHT;
-  else
-    halign = overlay->halign;
-
-  switch (halign) {
-    case GST_TEXT_OVERLAY_HALIGN_LEFT:
-      xpos = overlay->xpad;
-      break;
-    case GST_TEXT_OVERLAY_HALIGN_CENTER:
-      xpos = (overlay->width - width) / 2;
-      break;
-    case GST_TEXT_OVERLAY_HALIGN_RIGHT:
-      xpos = overlay->width - width - overlay->xpad;
-      break;
-    case GST_TEXT_OVERLAY_HALIGN_POS:
-      xpos = (gint) (overlay->width * overlay->xpos) - width / 2;
-      xpos = CLAMP (xpos, 0, overlay->width - width);
-      if (xpos < 0)
-        xpos = 0;
-      break;
-    default:
-      xpos = 0;
-  }
-  xpos += overlay->deltax;
-
-  if (overlay->use_vertical_render)
-    valign = GST_TEXT_OVERLAY_VALIGN_TOP;
-  else
-    valign = overlay->valign;
-
-  switch (valign) {
-    case GST_TEXT_OVERLAY_VALIGN_BOTTOM:
-      ypos = overlay->height - height - overlay->ypad;
-      break;
-    case GST_TEXT_OVERLAY_VALIGN_BASELINE:
-      ypos = overlay->height - (height + overlay->ypad);
-      break;
-    case GST_TEXT_OVERLAY_VALIGN_TOP:
-      ypos = overlay->ypad;
-      break;
-    case GST_TEXT_OVERLAY_VALIGN_POS:
-      ypos = (gint) (overlay->height * overlay->ypos) - height / 2;
-      ypos = CLAMP (ypos, 0, overlay->height - height);
-      break;
-    case GST_TEXT_OVERLAY_VALIGN_CENTER:
-      ypos = (overlay->height - height) / 2;
-      break;
-    default:
-      ypos = overlay->ypad;
-      break;
-  }
-  ypos += overlay->deltay;
-
-  /* shaded background box */
-  if (overlay->want_shading) {
-    switch (overlay->format) {
-      case GST_VIDEO_FORMAT_I420:
-      case GST_VIDEO_FORMAT_NV12:
-      case GST_VIDEO_FORMAT_NV21:
-        gst_text_overlay_shade_planar_Y (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
-            ypos, ypos + overlay->image_height);
-        break;
-      case GST_VIDEO_FORMAT_AYUV:
-      case GST_VIDEO_FORMAT_UYVY:
-        gst_text_overlay_shade_packed_Y (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
-            ypos, ypos + overlay->image_height);
-        break;
-      case GST_VIDEO_FORMAT_xRGB:
-        gst_text_overlay_shade_xRGB (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
-            ypos, ypos + overlay->image_height);
-        break;
-      case GST_VIDEO_FORMAT_xBGR:
-        gst_text_overlay_shade_xBGR (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
-            ypos, ypos + overlay->image_height);
-        break;
-      case GST_VIDEO_FORMAT_BGRx:
-        gst_text_overlay_shade_BGRx (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
-            ypos, ypos + overlay->image_height);
-        break;
-      case GST_VIDEO_FORMAT_RGBx:
-        gst_text_overlay_shade_RGBx (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
-            ypos, ypos + overlay->image_height);
-        break;
-      case GST_VIDEO_FORMAT_ARGB:
-        gst_text_overlay_shade_ARGB (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
-            ypos, ypos + overlay->image_height);
-        break;
-      case GST_VIDEO_FORMAT_ABGR:
-        gst_text_overlay_shade_ABGR (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
-            ypos, ypos + overlay->image_height);
-        break;
-      case GST_VIDEO_FORMAT_RGBA:
-        gst_text_overlay_shade_RGBA (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
-            ypos, ypos + overlay->image_height);
-        break;
-      case GST_VIDEO_FORMAT_BGRA:
-        gst_text_overlay_shade_BGRA (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, xpos + overlay->image_width,
-            ypos, ypos + overlay->image_height);
-        break;
-      default:
-        g_assert_not_reached ();
-    }
-  }
-
-  if (ypos < 0)
-    ypos = 0;
-
-  if (overlay->text_image) {
-    switch (overlay->format) {
-      case GST_VIDEO_FORMAT_I420:
-        gst_text_overlay_blit_I420 (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, ypos);
-        break;
-      case GST_VIDEO_FORMAT_NV12:
-      case GST_VIDEO_FORMAT_NV21:
-        gst_text_overlay_blit_NV12_NV21 (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, ypos);
-        break;
-      case GST_VIDEO_FORMAT_UYVY:
-        gst_text_overlay_blit_UYVY (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, ypos);
-        break;
-      case GST_VIDEO_FORMAT_AYUV:
-        gst_text_overlay_blit_AYUV (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, ypos);
-        break;
-      case GST_VIDEO_FORMAT_BGRx:
-        gst_text_overlay_blit_BGRx (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, ypos);
-        break;
-      case GST_VIDEO_FORMAT_xRGB:
-        gst_text_overlay_blit_xRGB (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, ypos);
-        break;
-      case GST_VIDEO_FORMAT_RGBx:
-        gst_text_overlay_blit_RGBx (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, ypos);
-        break;
-      case GST_VIDEO_FORMAT_xBGR:
-        gst_text_overlay_blit_xBGR (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, ypos);
-        break;
-      case GST_VIDEO_FORMAT_ARGB:
-        gst_text_overlay_blit_ARGB (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, ypos);
-        break;
-      case GST_VIDEO_FORMAT_ABGR:
-        gst_text_overlay_blit_ABGR (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, ypos);
-        break;
-      case GST_VIDEO_FORMAT_RGBA:
-        gst_text_overlay_blit_RGBA (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, ypos);
-        break;
-      case GST_VIDEO_FORMAT_BGRA:
-        gst_text_overlay_blit_BGRA (overlay,
-            GST_BUFFER_DATA (video_frame), xpos, ypos);
-        break;
-      default:
-        g_assert_not_reached ();
-    }
-  }
-  return gst_pad_push (overlay->srcpad, video_frame);
-}
-
-static GstPadLinkReturn
-gst_text_overlay_text_pad_link (GstPad * pad, GstPad * peer)
-{
-  GstTextOverlay *overlay;
-
-  overlay = GST_TEXT_OVERLAY (gst_pad_get_parent (pad));
-
-  GST_DEBUG_OBJECT (overlay, "Text pad linked");
-
-  overlay->text_linked = TRUE;
-
-  gst_object_unref (overlay);
-
-  return GST_PAD_LINK_OK;
-}
-
-static void
-gst_text_overlay_text_pad_unlink (GstPad * pad)
-{
-  GstTextOverlay *overlay;
-
-  /* don't use gst_pad_get_parent() here, will deadlock */
-  overlay = GST_TEXT_OVERLAY (GST_PAD_PARENT (pad));
-
-  GST_DEBUG_OBJECT (overlay, "Text pad unlinked");
-
-  overlay->text_linked = FALSE;
-
-  gst_segment_init (&overlay->text_segment, GST_FORMAT_UNDEFINED);
-}
-
-static gboolean
-gst_text_overlay_text_event (GstPad * pad, GstEvent * event)
-{
-  gboolean ret = FALSE;
-  GstTextOverlay *overlay = NULL;
-
-  overlay = GST_TEXT_OVERLAY (gst_pad_get_parent (pad));
-
-  GST_LOG_OBJECT (pad, "received event %s", GST_EVENT_TYPE_NAME (event));
-
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_NEWSEGMENT:{
-      GstFormat fmt;
-      gboolean update;
-      gdouble rate, applied_rate;
-      gint64 cur, stop, time;
-
-      overlay->text_eos = FALSE;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
-          &fmt, &cur, &stop, &time);
-
-      if (fmt == GST_FORMAT_TIME) {
-        GST_OBJECT_LOCK (overlay);
-        gst_segment_set_newsegment_full (&overlay->text_segment, update, rate,
-            applied_rate, GST_FORMAT_TIME, cur, stop, time);
-        GST_DEBUG_OBJECT (overlay, "TEXT SEGMENT now: %" GST_SEGMENT_FORMAT,
-            &overlay->text_segment);
-        GST_OBJECT_UNLOCK (overlay);
-      } else {
-        GST_ELEMENT_WARNING (overlay, STREAM, MUX, (NULL),
-            ("received non-TIME newsegment event on text input"));
-      }
-
-      gst_event_unref (event);
-      ret = TRUE;
-
-      /* wake up the video chain, it might be waiting for a text buffer or
-       * a text segment update */
-      GST_OBJECT_LOCK (overlay);
-      GST_TEXT_OVERLAY_BROADCAST (overlay);
-      GST_OBJECT_UNLOCK (overlay);
-      break;
-    }
-    case GST_EVENT_FLUSH_STOP:
-      GST_OBJECT_LOCK (overlay);
-      GST_INFO_OBJECT (overlay, "text flush stop");
-      overlay->text_flushing = FALSE;
-      overlay->text_eos = FALSE;
-      gst_text_overlay_pop_text (overlay);
-      gst_segment_init (&overlay->text_segment, GST_FORMAT_TIME);
-      GST_OBJECT_UNLOCK (overlay);
-      gst_event_unref (event);
-      ret = TRUE;
-      break;
-    case GST_EVENT_FLUSH_START:
-      GST_OBJECT_LOCK (overlay);
-      GST_INFO_OBJECT (overlay, "text flush start");
-      overlay->text_flushing = TRUE;
-      GST_TEXT_OVERLAY_BROADCAST (overlay);
-      GST_OBJECT_UNLOCK (overlay);
-      gst_event_unref (event);
-      ret = TRUE;
-      break;
-    case GST_EVENT_EOS:
-      GST_OBJECT_LOCK (overlay);
-      overlay->text_eos = TRUE;
-      GST_INFO_OBJECT (overlay, "text EOS");
-      /* wake up the video chain, it might be waiting for a text buffer or
-       * a text segment update */
-      GST_TEXT_OVERLAY_BROADCAST (overlay);
-      GST_OBJECT_UNLOCK (overlay);
-      gst_event_unref (event);
-      ret = TRUE;
-      break;
-    default:
-      ret = gst_pad_event_default (pad, event);
-      break;
-  }
-
-  gst_object_unref (overlay);
-
-  return ret;
-}
-
-static gboolean
-gst_text_overlay_video_event (GstPad * pad, GstEvent * event)
-{
-  gboolean ret = FALSE;
-  GstTextOverlay *overlay = NULL;
-
-  overlay = GST_TEXT_OVERLAY (gst_pad_get_parent (pad));
-
-  GST_DEBUG_OBJECT (pad, "received event %s", GST_EVENT_TYPE_NAME (event));
-
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_NEWSEGMENT:
-    {
-      GstFormat format;
-      gdouble rate;
-      gint64 start, stop, time;
-      gboolean update;
-
-      GST_DEBUG_OBJECT (overlay, "received new segment");
-
-      gst_event_parse_new_segment (event, &update, &rate, &format, &start,
-          &stop, &time);
-
-      if (format == GST_FORMAT_TIME) {
-        GST_DEBUG_OBJECT (overlay, "VIDEO SEGMENT now: %" GST_SEGMENT_FORMAT,
-            &overlay->segment);
-
-        gst_segment_set_newsegment (&overlay->segment, update, rate, format,
-            start, stop, time);
-      } else {
-        GST_ELEMENT_WARNING (overlay, STREAM, MUX, (NULL),
-            ("received non-TIME newsegment event on video input"));
-      }
-
-      ret = gst_pad_event_default (pad, event);
-      break;
-    }
-    case GST_EVENT_EOS:
-      GST_OBJECT_LOCK (overlay);
-      GST_INFO_OBJECT (overlay, "video EOS");
-      overlay->video_eos = TRUE;
-      GST_OBJECT_UNLOCK (overlay);
-      ret = gst_pad_event_default (pad, event);
-      break;
-    case GST_EVENT_FLUSH_START:
-      GST_OBJECT_LOCK (overlay);
-      GST_INFO_OBJECT (overlay, "video flush start");
-      overlay->video_flushing = TRUE;
-      GST_TEXT_OVERLAY_BROADCAST (overlay);
-      GST_OBJECT_UNLOCK (overlay);
-      ret = gst_pad_event_default (pad, event);
-      break;
-    case GST_EVENT_FLUSH_STOP:
-      GST_OBJECT_LOCK (overlay);
-      GST_INFO_OBJECT (overlay, "video flush stop");
-      overlay->video_flushing = FALSE;
-      overlay->video_eos = FALSE;
-      gst_segment_init (&overlay->segment, GST_FORMAT_TIME);
-      GST_OBJECT_UNLOCK (overlay);
-      ret = gst_pad_event_default (pad, event);
-      break;
-    default:
-      ret = gst_pad_event_default (pad, event);
-      break;
-  }
-
-  gst_object_unref (overlay);
-
-  return ret;
-}
-
-static GstFlowReturn
-gst_text_overlay_video_bufferalloc (GstPad * pad, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buffer)
-{
-  GstTextOverlay *overlay = GST_TEXT_OVERLAY (gst_pad_get_parent (pad));
-  GstFlowReturn ret = GST_FLOW_WRONG_STATE;
-  GstPad *allocpad;
-
-  GST_OBJECT_LOCK (overlay);
-  allocpad = overlay->srcpad ? gst_object_ref (overlay->srcpad) : NULL;
-  GST_OBJECT_UNLOCK (overlay);
-
-  if (allocpad) {
-    ret = gst_pad_alloc_buffer (allocpad, offset, size, caps, buffer);
-    gst_object_unref (allocpad);
-  }
-
-  gst_object_unref (overlay);
-  return ret;
-}
-
-/* Called with lock held */
-static void
-gst_text_overlay_pop_text (GstTextOverlay * overlay)
-{
-  g_return_if_fail (GST_IS_TEXT_OVERLAY (overlay));
-
-  if (overlay->text_buffer) {
-    GST_DEBUG_OBJECT (overlay, "releasing text buffer %p",
-        overlay->text_buffer);
-    gst_buffer_unref (overlay->text_buffer);
-    overlay->text_buffer = NULL;
-  }
-
-  /* Let the text task know we used that buffer */
-  GST_TEXT_OVERLAY_BROADCAST (overlay);
-}
-
-/* We receive text buffers here. If they are out of segment we just ignore them.
-   If the buffer is in our segment we keep it internally except if another one
-   is already waiting here, in that case we wait that it gets kicked out */
-static GstFlowReturn
-gst_text_overlay_text_chain (GstPad * pad, GstBuffer * buffer)
-{
-  GstFlowReturn ret = GST_FLOW_OK;
-  GstTextOverlay *overlay = NULL;
-  gboolean in_seg = FALSE;
-  gint64 clip_start = 0, clip_stop = 0;
-
-  overlay = GST_TEXT_OVERLAY (GST_PAD_PARENT (pad));
-
-  GST_OBJECT_LOCK (overlay);
-
-  if (overlay->text_flushing) {
-    GST_OBJECT_UNLOCK (overlay);
-    ret = GST_FLOW_WRONG_STATE;
-    GST_LOG_OBJECT (overlay, "text flushing");
-    goto beach;
-  }
-
-  if (overlay->text_eos) {
-    GST_OBJECT_UNLOCK (overlay);
-    ret = GST_FLOW_UNEXPECTED;
-    GST_LOG_OBJECT (overlay, "text EOS");
-    goto beach;
-  }
-
-  GST_LOG_OBJECT (overlay, "%" GST_SEGMENT_FORMAT "  BUFFER: ts=%"
-      GST_TIME_FORMAT ", end=%" GST_TIME_FORMAT, &overlay->segment,
-      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
-      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer) +
-          GST_BUFFER_DURATION (buffer)));
-
-  if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))) {
-    GstClockTime stop;
-
-    if (G_LIKELY (GST_BUFFER_DURATION_IS_VALID (buffer)))
-      stop = GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer);
-    else
-      stop = GST_CLOCK_TIME_NONE;
-
-    in_seg = gst_segment_clip (&overlay->text_segment, GST_FORMAT_TIME,
-        GST_BUFFER_TIMESTAMP (buffer), stop, &clip_start, &clip_stop);
-  } else {
-    in_seg = TRUE;
-  }
-
-  if (in_seg) {
-    if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
-      GST_BUFFER_TIMESTAMP (buffer) = clip_start;
-    else if (GST_BUFFER_DURATION_IS_VALID (buffer))
-      GST_BUFFER_DURATION (buffer) = clip_stop - clip_start;
-
-    /* Wait for the previous buffer to go away */
-    while (overlay->text_buffer != NULL) {
-      GST_DEBUG ("Pad %s:%s has a buffer queued, waiting",
-          GST_DEBUG_PAD_NAME (pad));
-      GST_TEXT_OVERLAY_WAIT (overlay);
-      GST_DEBUG ("Pad %s:%s resuming", GST_DEBUG_PAD_NAME (pad));
-      if (overlay->text_flushing) {
-        GST_OBJECT_UNLOCK (overlay);
-        ret = GST_FLOW_WRONG_STATE;
-        goto beach;
-      }
-    }
-
-    if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
-      gst_segment_set_last_stop (&overlay->text_segment, GST_FORMAT_TIME,
-          clip_start);
-
-    overlay->text_buffer = buffer;
-    /* That's a new text buffer we need to render */
-    overlay->need_render = TRUE;
-
-    /* in case the video chain is waiting for a text buffer, wake it up */
-    GST_TEXT_OVERLAY_BROADCAST (overlay);
-  }
-
-  GST_OBJECT_UNLOCK (overlay);
-
-beach:
-
-  return ret;
-}
-
-static GstFlowReturn
-gst_text_overlay_video_chain (GstPad * pad, GstBuffer * buffer)
-{
-  GstTextOverlayClass *klass;
-  GstTextOverlay *overlay;
-  GstFlowReturn ret = GST_FLOW_OK;
-  gboolean in_seg = FALSE;
-  gint64 start, stop, clip_start = 0, clip_stop = 0;
-  gchar *text = NULL;
-
-  overlay = GST_TEXT_OVERLAY (GST_PAD_PARENT (pad));
-  klass = GST_TEXT_OVERLAY_GET_CLASS (overlay);
-
-  if (!GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
-    goto missing_timestamp;
-
-  /* ignore buffers that are outside of the current segment */
-  start = GST_BUFFER_TIMESTAMP (buffer);
-
-  if (!GST_BUFFER_DURATION_IS_VALID (buffer)) {
-    stop = GST_CLOCK_TIME_NONE;
-  } else {
-    stop = start + GST_BUFFER_DURATION (buffer);
-  }
-
-  GST_LOG_OBJECT (overlay, "%" GST_SEGMENT_FORMAT "  BUFFER: ts=%"
-      GST_TIME_FORMAT ", end=%" GST_TIME_FORMAT, &overlay->segment,
-      GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
-
-  /* segment_clip() will adjust start unconditionally to segment_start if
-   * no stop time is provided, so handle this ourselves */
-  if (stop == GST_CLOCK_TIME_NONE && start < overlay->segment.start)
-    goto out_of_segment;
-
-  in_seg = gst_segment_clip (&overlay->segment, GST_FORMAT_TIME, start, stop,
-      &clip_start, &clip_stop);
-
-  if (!in_seg)
-    goto out_of_segment;
-
-  /* if the buffer is only partially in the segment, fix up stamps */
-  if (clip_start != start || (stop != -1 && clip_stop != stop)) {
-    GST_DEBUG_OBJECT (overlay, "clipping buffer timestamp/duration to segment");
-    buffer = gst_buffer_make_metadata_writable (buffer);
-    GST_BUFFER_TIMESTAMP (buffer) = clip_start;
-    if (stop != -1)
-      GST_BUFFER_DURATION (buffer) = clip_stop - clip_start;
-  }
-
-  /* now, after we've done the clipping, fix up end time if there's no
-   * duration (we only use those estimated values internally though, we
-   * don't want to set bogus values on the buffer itself) */
-  if (stop == -1) {
-    GstStructure *s;
-    gint fps_num, fps_denom;
-
-    s = gst_caps_get_structure (GST_PAD_CAPS (pad), 0);
-    if (gst_structure_get_fraction (s, "framerate", &fps_num, &fps_denom) &&
-        fps_num && fps_denom) {
-      GST_DEBUG_OBJECT (overlay, "estimating duration based on framerate");
-      stop = start + gst_util_uint64_scale_int (GST_SECOND, fps_denom, fps_num);
-    } else {
-      GST_WARNING_OBJECT (overlay, "no duration, assuming minimal duration");
-      stop = start + 1;         /* we need to assume some interval */
-    }
-  }
-
-  gst_object_sync_values (G_OBJECT (overlay), GST_BUFFER_TIMESTAMP (buffer));
-
-wait_for_text_buf:
-
-  GST_OBJECT_LOCK (overlay);
-
-  if (overlay->video_flushing)
-    goto flushing;
-
-  if (overlay->video_eos)
-    goto have_eos;
-
-  if (overlay->silent) {
-    GST_OBJECT_UNLOCK (overlay);
-    ret = gst_pad_push (overlay->srcpad, buffer);
-
-    /* Update last_stop */
-    gst_segment_set_last_stop (&overlay->segment, GST_FORMAT_TIME, clip_start);
-
-    return ret;
-  }
-
-  /* Text pad not linked, rendering internal text */
-  if (!overlay->text_linked) {
-    if (klass->get_text) {
-      text = klass->get_text (overlay, buffer);
-    } else {
-      text = g_strdup (overlay->default_text);
-    }
-
-    GST_LOG_OBJECT (overlay, "Text pad not linked, rendering default "
-        "text: '%s'", GST_STR_NULL (text));
-
-    GST_OBJECT_UNLOCK (overlay);
-
-    if (text != NULL && *text != '\0') {
-      /* Render and push */
-      gst_text_overlay_render_text (overlay, text, -1);
-      ret = gst_text_overlay_push_frame (overlay, buffer);
-    } else {
-      /* Invalid or empty string */
-      ret = gst_pad_push (overlay->srcpad, buffer);
-    }
-  } else {
-    /* Text pad linked, check if we have a text buffer queued */
-    if (overlay->text_buffer) {
-      gboolean pop_text = FALSE, valid_text_time = TRUE;
-      GstClockTime text_start = GST_CLOCK_TIME_NONE;
-      GstClockTime text_end = GST_CLOCK_TIME_NONE;
-      GstClockTime text_running_time = GST_CLOCK_TIME_NONE;
-      GstClockTime text_running_time_end = GST_CLOCK_TIME_NONE;
-      GstClockTime vid_running_time, vid_running_time_end;
-
-      /* if the text buffer isn't stamped right, pop it off the
-       * queue and display it for the current video frame only */
-      if (!GST_BUFFER_TIMESTAMP_IS_VALID (overlay->text_buffer) ||
-          !GST_BUFFER_DURATION_IS_VALID (overlay->text_buffer)) {
-        GST_WARNING_OBJECT (overlay,
-            "Got text buffer with invalid timestamp or duration");
-        pop_text = TRUE;
-        valid_text_time = FALSE;
-      } else {
-        text_start = GST_BUFFER_TIMESTAMP (overlay->text_buffer);
-        text_end = text_start + GST_BUFFER_DURATION (overlay->text_buffer);
-      }
-
-      vid_running_time =
-          gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
-          start);
-      vid_running_time_end =
-          gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
-          stop);
-
-      /* If timestamp and duration are valid */
-      if (valid_text_time) {
-        text_running_time =
-            gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
-            text_start);
-        text_running_time_end =
-            gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
-            text_end);
-      }
-
-      GST_LOG_OBJECT (overlay, "T: %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT,
-          GST_TIME_ARGS (text_running_time),
-          GST_TIME_ARGS (text_running_time_end));
-      GST_LOG_OBJECT (overlay, "V: %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT,
-          GST_TIME_ARGS (vid_running_time),
-          GST_TIME_ARGS (vid_running_time_end));
-
-      /* Text too old or in the future */
-      if (valid_text_time && text_running_time_end <= vid_running_time) {
-        /* text buffer too old, get rid of it and do nothing  */
-        GST_LOG_OBJECT (overlay, "text buffer too old, popping");
-        pop_text = FALSE;
-        gst_text_overlay_pop_text (overlay);
-        GST_OBJECT_UNLOCK (overlay);
-        goto wait_for_text_buf;
-      } else if (valid_text_time && vid_running_time_end <= text_running_time) {
-        GST_LOG_OBJECT (overlay, "text in future, pushing video buf");
-        GST_OBJECT_UNLOCK (overlay);
-        /* Push the video frame */
-        ret = gst_pad_push (overlay->srcpad, buffer);
-      } else {
-        gchar *in_text;
-        gsize in_size;
-
-        in_text = (gchar *) GST_BUFFER_DATA (overlay->text_buffer);
-        in_size = GST_BUFFER_SIZE (overlay->text_buffer);
-
-        /* g_markup_escape_text() absolutely requires valid UTF8 input, it
-         * might crash otherwise. We don't fall back on GST_SUBTITLE_ENCODING
-         * here on purpose, this is something that needs fixing upstream */
-        if (!g_utf8_validate (in_text, in_size, NULL)) {
-          const gchar *end = NULL;
-
-          GST_WARNING_OBJECT (overlay, "received invalid UTF-8");
-          in_text = g_strndup (in_text, in_size);
-          while (!g_utf8_validate (in_text, in_size, &end) && end)
-            *((gchar *) end) = '*';
-        }
-
-        /* Get the string */
-        if (overlay->have_pango_markup) {
-          text = g_strndup (in_text, in_size);
-        } else {
-          text = g_markup_escape_text (in_text, in_size);
-        }
-
-        if (text != NULL && *text != '\0') {
-          gint text_len = strlen (text);
-
-          while (text_len > 0 && (text[text_len - 1] == '\n' ||
-                  text[text_len - 1] == '\r')) {
-            --text_len;
-          }
-          GST_DEBUG_OBJECT (overlay, "Rendering text '%*s'", text_len, text);
-          gst_text_overlay_render_text (overlay, text, text_len);
-        } else {
-          GST_DEBUG_OBJECT (overlay, "No text to render (empty buffer)");
-          gst_text_overlay_render_text (overlay, " ", 1);
-        }
-
-        if (in_text != (gchar *) GST_BUFFER_DATA (overlay->text_buffer))
-          g_free (in_text);
-
-        GST_OBJECT_UNLOCK (overlay);
-        ret = gst_text_overlay_push_frame (overlay, buffer);
-
-        if (valid_text_time && text_running_time_end <= vid_running_time_end) {
-          GST_LOG_OBJECT (overlay, "text buffer not needed any longer");
-          pop_text = TRUE;
-        }
-      }
-      if (pop_text) {
-        GST_OBJECT_LOCK (overlay);
-        gst_text_overlay_pop_text (overlay);
-        GST_OBJECT_UNLOCK (overlay);
-      }
-    } else {
-      gboolean wait_for_text_buf = TRUE;
-
-      if (overlay->text_eos)
-        wait_for_text_buf = FALSE;
-
-      if (!overlay->wait_text)
-        wait_for_text_buf = FALSE;
-
-      /* Text pad linked, but no text buffer available - what now? */
-      if (overlay->text_segment.format == GST_FORMAT_TIME) {
-        GstClockTime text_start_running_time, text_last_stop_running_time;
-        GstClockTime vid_running_time;
-
-        vid_running_time =
-            gst_segment_to_running_time (&overlay->segment, GST_FORMAT_TIME,
-            GST_BUFFER_TIMESTAMP (buffer));
-        text_start_running_time =
-            gst_segment_to_running_time (&overlay->text_segment,
-            GST_FORMAT_TIME, overlay->text_segment.start);
-        text_last_stop_running_time =
-            gst_segment_to_running_time (&overlay->text_segment,
-            GST_FORMAT_TIME, overlay->text_segment.last_stop);
-
-        if ((GST_CLOCK_TIME_IS_VALID (text_start_running_time) &&
-                vid_running_time < text_start_running_time) ||
-            (GST_CLOCK_TIME_IS_VALID (text_last_stop_running_time) &&
-                vid_running_time < text_last_stop_running_time)) {
-          wait_for_text_buf = FALSE;
-        }
-      }
-
-      if (wait_for_text_buf) {
-        GST_DEBUG_OBJECT (overlay, "no text buffer, need to wait for one");
-        GST_TEXT_OVERLAY_WAIT (overlay);
-        GST_DEBUG_OBJECT (overlay, "resuming");
-        GST_OBJECT_UNLOCK (overlay);
-        goto wait_for_text_buf;
-      } else {
-        GST_OBJECT_UNLOCK (overlay);
-        GST_LOG_OBJECT (overlay, "no need to wait for a text buffer");
-        ret = gst_pad_push (overlay->srcpad, buffer);
-      }
-    }
-  }
-
-  g_free (text);
-
-  /* Update last_stop */
-  gst_segment_set_last_stop (&overlay->segment, GST_FORMAT_TIME, clip_start);
-
-  return ret;
-
-missing_timestamp:
-  {
-    GST_WARNING_OBJECT (overlay, "buffer without timestamp, discarding");
-    gst_buffer_unref (buffer);
-    return GST_FLOW_OK;
-  }
-
-flushing:
-  {
-    GST_OBJECT_UNLOCK (overlay);
-    GST_DEBUG_OBJECT (overlay, "flushing, discarding buffer");
-    gst_buffer_unref (buffer);
-    return GST_FLOW_WRONG_STATE;
-  }
-have_eos:
-  {
-    GST_OBJECT_UNLOCK (overlay);
-    GST_DEBUG_OBJECT (overlay, "eos, discarding buffer");
-    gst_buffer_unref (buffer);
-    return GST_FLOW_UNEXPECTED;
-  }
-out_of_segment:
-  {
-    GST_DEBUG_OBJECT (overlay, "buffer out of segment, discarding");
-    gst_buffer_unref (buffer);
-    return GST_FLOW_OK;
-  }
-}
-
-static GstStateChangeReturn
-gst_text_overlay_change_state (GstElement * element, GstStateChange transition)
-{
-  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
-  GstTextOverlay *overlay = GST_TEXT_OVERLAY (element);
-
-  switch (transition) {
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      GST_OBJECT_LOCK (overlay);
-      overlay->text_flushing = TRUE;
-      overlay->video_flushing = TRUE;
-      /* pop_text will broadcast on the GCond and thus also make the video
-       * chain exit if it's waiting for a text buffer */
-      gst_text_overlay_pop_text (overlay);
-      GST_OBJECT_UNLOCK (overlay);
-      break;
-    default:
-      break;
-  }
-
-  ret = parent_class->change_state (element, transition);
-  if (ret == GST_STATE_CHANGE_FAILURE)
-    return ret;
-
-  switch (transition) {
-    case GST_STATE_CHANGE_READY_TO_PAUSED:
-      GST_OBJECT_LOCK (overlay);
-      overlay->text_flushing = FALSE;
-      overlay->video_flushing = FALSE;
-      overlay->video_eos = FALSE;
-      overlay->text_eos = FALSE;
-      gst_segment_init (&overlay->segment, GST_FORMAT_TIME);
-      gst_segment_init (&overlay->text_segment, GST_FORMAT_TIME);
-      GST_OBJECT_UNLOCK (overlay);
-      break;
-    default:
-      break;
-  }
-
-  return ret;
-}
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
-  gst_controller_init (NULL, NULL);
-
-  if (!gst_element_register (plugin, "textoverlay", GST_RANK_NONE,
-          GST_TYPE_TEXT_OVERLAY) ||
-      !gst_element_register (plugin, "timeoverlay", GST_RANK_NONE,
-          GST_TYPE_TIME_OVERLAY) ||
-      !gst_element_register (plugin, "clockoverlay", GST_RANK_NONE,
-          GST_TYPE_CLOCK_OVERLAY) ||
-      !gst_element_register (plugin, "textrender", GST_RANK_NONE,
-          GST_TYPE_TEXT_RENDER)) {
-    return FALSE;
-  }
-
-  /*texttestsrc_plugin_init(module, plugin); */
-
-  GST_DEBUG_CATEGORY_INIT (pango_debug, "pango", 0, "Pango elements");
-
-  return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR,
-    "pango", "Pango-based text rendering and overlay", plugin_init,
-    VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
index 5cd4260..c1dab86 100644 (file)
+/* GStreamer
+ * Copyright (C) 2011 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
 #ifndef __GST_TEXT_OVERLAY_H__
 #define __GST_TEXT_OVERLAY_H__
 
-#include <gst/gst.h>
-#include <gst/video/video.h>
-#include <gst/controller/gstcontroller.h>
-#include <pango/pangocairo.h>
+#include "gstbasetextoverlay.h"
 
 G_BEGIN_DECLS
 
-#define GST_TYPE_TEXT_OVERLAY            (gst_text_overlay_get_type())
-#define GST_TEXT_OVERLAY(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),\
-                                         GST_TYPE_TEXT_OVERLAY, GstTextOverlay))
-#define GST_TEXT_OVERLAY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),\
-                                         GST_TYPE_TEXT_OVERLAY,GstTextOverlayClass))
-#define GST_TEXT_OVERLAY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),\
-                                         GST_TYPE_TEXT_OVERLAY, GstTextOverlayClass))
-#define GST_IS_TEXT_OVERLAY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),\
-                                         GST_TYPE_TEXT_OVERLAY))
-#define GST_IS_TEXT_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),\
-                                         GST_TYPE_TEXT_OVERLAY))
-
-typedef struct _GstTextOverlay      GstTextOverlay;
+#define GST_TYPE_TEXT_OVERLAY \
+  (gst_text_overlay_get_type())
+#define GST_TEXT_OVERLAY(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TEXT_OVERLAY,GstTextOverlay))
+#define GST_TEXT_OVERLAY_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TEXT_OVERLAY,GstTextOverlayClass))
+#define GST_IS_TEXT_OVERLAY(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TEXT_OVERLAY))
+#define GST_IS_TEXT_OVERLAY_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TEXT_OVERLAY))
+
+typedef struct _GstTextOverlay GstTextOverlay;
 typedef struct _GstTextOverlayClass GstTextOverlayClass;
 
 /**
- * GstTextOverlayVAlign:
- * @GST_TEXT_OVERLAY_VALIGN_BASELINE: draw text on the baseline
- * @GST_TEXT_OVERLAY_VALIGN_BOTTOM: draw text on the bottom
- * @GST_TEXT_OVERLAY_VALIGN_TOP: draw text on top
- * @GST_TEXT_OVERLAY_VALIGN_POS: draw text according to the #GstTextOverlay:ypos property
- * @GST_TEXT_OVERLAY_VALIGN_CENTER: draw text vertically centered
- *
- * Vertical alignment of the text.
- */
-typedef enum {
-    GST_TEXT_OVERLAY_VALIGN_BASELINE,
-    GST_TEXT_OVERLAY_VALIGN_BOTTOM,
-    GST_TEXT_OVERLAY_VALIGN_TOP,
-    GST_TEXT_OVERLAY_VALIGN_POS,
-    GST_TEXT_OVERLAY_VALIGN_CENTER
-} GstTextOverlayVAlign;
-
-/**
- * GstTextOverlayHAlign:
- * @GST_TEXT_OVERLAY_HALIGN_LEFT: align text left
- * @GST_TEXT_OVERLAY_HALIGN_CENTER: align text center
- * @GST_TEXT_OVERLAY_HALIGN_RIGHT: align text right
- * @GST_TEXT_OVERLAY_HALIGN_POS: position text according to the #GstTextOverlay:xpos property
- *
- * Horizontal alignment of the text.
- */
-/* FIXME 0.11: remove GST_TEXT_OVERLAY_HALIGN_UNUSED */
-typedef enum {
-    GST_TEXT_OVERLAY_HALIGN_LEFT,
-    GST_TEXT_OVERLAY_HALIGN_CENTER,
-    GST_TEXT_OVERLAY_HALIGN_RIGHT,
-    GST_TEXT_OVERLAY_HALIGN_UNUSED,
-    GST_TEXT_OVERLAY_HALIGN_POS
-} GstTextOverlayHAlign;
-
-/**
- * GstTextOverlayWrapMode:
- * @GST_TEXT_OVERLAY_WRAP_MODE_NONE: no wrapping
- * @GST_TEXT_OVERLAY_WRAP_MODE_WORD: do word wrapping
- * @GST_TEXT_OVERLAY_WRAP_MODE_CHAR: do char wrapping
- * @GST_TEXT_OVERLAY_WRAP_MODE_WORD_CHAR: do word and char wrapping
- *
- * Whether to wrap the text and if so how.
- */
-typedef enum {
-    GST_TEXT_OVERLAY_WRAP_MODE_NONE = -1,
-    GST_TEXT_OVERLAY_WRAP_MODE_WORD = PANGO_WRAP_WORD,
-    GST_TEXT_OVERLAY_WRAP_MODE_CHAR = PANGO_WRAP_CHAR,
-    GST_TEXT_OVERLAY_WRAP_MODE_WORD_CHAR = PANGO_WRAP_WORD_CHAR
-} GstTextOverlayWrapMode;
-
-/**
- * GstTextOverlayLineAlign:
- * @GST_TEXT_OVERLAY_LINE_ALIGN_LEFT: lines are left-aligned
- * @GST_TEXT_OVERLAY_LINE_ALIGN_CENTER: lines are center-aligned
- * @GST_TEXT_OVERLAY_LINE_ALIGN_RIGHT: lines are right-aligned
- *
- * Alignment of text lines relative to each other
- */
-typedef enum {
-    GST_TEXT_OVERLAY_LINE_ALIGN_LEFT = PANGO_ALIGN_LEFT,
-    GST_TEXT_OVERLAY_LINE_ALIGN_CENTER = PANGO_ALIGN_CENTER,
-    GST_TEXT_OVERLAY_LINE_ALIGN_RIGHT = PANGO_ALIGN_RIGHT
-} GstTextOverlayLineAlign;
-
-/**
  * GstTextOverlay:
  *
- * Opaque textoverlay object structure
+ * Opaque textoverlay data structure.
  */
 struct _GstTextOverlay {
-    GstElement               element;
-
-    GstPad                  *video_sinkpad;
-    GstPad                  *text_sinkpad;
-    GstPad                  *srcpad;
-
-    GstSegment               segment;
-    GstSegment               text_segment;
-    GstBuffer               *text_buffer;
-    gboolean                text_linked;
-    gboolean                video_flushing;
-    gboolean                video_eos;
-    gboolean                text_flushing;
-    gboolean                text_eos;
-
-    GCond                   *cond;  /* to signal removal of a queued text
-                                     * buffer, arrival of a text buffer,
-                                     * a text segment update, or a change
-                                     * in status (e.g. shutdown, flushing) */
-
-    gint                     width;
-    gint                     height;
-    gint                     fps_n;
-    gint                     fps_d;
-    GstVideoFormat           format;
-
-    GstTextOverlayVAlign     valign;
-    GstTextOverlayHAlign     halign;
-    GstTextOverlayWrapMode   wrap_mode;
-    GstTextOverlayLineAlign  line_align;
-
-    gint                     xpad;
-    gint                     ypad;
-    gint                     deltax;
-    gint                     deltay;
-    gdouble                  xpos;
-    gdouble                  ypos;
-    gchar                   *default_text;
-    gboolean                 want_shading;
-    gboolean                 silent;
-    gboolean                 wait_text;
-    guint                    color;
-
-    PangoLayout             *layout;
-    gdouble                  shadow_offset;
-    gdouble                  outline_offset;
-    guchar                  *text_image;
-    gint                     image_width;
-    gint                     image_height;
-    gint                     baseline_y;
-
-    gboolean                 auto_adjust_size;
-    gboolean                 need_render;
-
-    gint                     shading_value;  /* for timeoverlay subclass */
-
-    gboolean                 have_pango_markup;
-    gboolean                 use_vertical_render;
+  GstBaseTextOverlay parent;
 };
 
 struct _GstTextOverlayClass {
-    GstElementClass parent_class;
-
-    PangoContext *pango_context;
-    GMutex       *pango_lock;
-
-    gchar *     (*get_text) (GstTextOverlay *overlay, GstBuffer *video_frame);
+  GstBaseTextOverlayClass parent_class;
 };
 
-GType gst_text_overlay_get_type(void) G_GNUC_CONST;
+GType gst_text_overlay_get_type (void);
 
 G_END_DECLS
 
-#endif /* __GST_TEXT_OVERLAY_H */
+#endif /* __GST_TEXT_OVERLAY_H__ */
+
index c937244..31f671c 100644 (file)
@@ -162,7 +162,8 @@ gst_text_render_line_align_get_type (void)
 static void gst_text_render_adjust_values_with_fontdesc (GstTextRender *
     render, PangoFontDescription * desc);
 
-GST_BOILERPLATE (GstTextRender, gst_text_render, GstElement, GST_TYPE_ELEMENT);
+#define gst_text_render_parent_class parent_class
+G_DEFINE_TYPE (GstTextRender, gst_text_render, GST_TYPE_ELEMENT);
 
 static void gst_text_render_finalize (GObject * object);
 static void gst_text_render_set_property (GObject * object,
@@ -171,29 +172,14 @@ static void gst_text_render_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 
 static void
-gst_text_render_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_template_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_template_factory));
-
-  gst_element_class_set_details_simple (element_class, "Text renderer",
-      "Filter/Editor/Video",
-      "Renders a text string to an image bitmap",
-      "David Schleef <ds@schleef.org>, "
-      "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
-}
-
-static void
 gst_text_render_class_init (GstTextRenderClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   PangoFontMap *fontmap;
 
   gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
 
   parent_class = g_type_class_peek_parent (klass);
 
@@ -201,6 +187,17 @@ gst_text_render_class_init (GstTextRenderClass * klass)
   gobject_class->set_property = gst_text_render_set_property;
   gobject_class->get_property = gst_text_render_get_property;
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&src_template_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sink_template_factory));
+
+  gst_element_class_set_details_simple (gstelement_class, "Text renderer",
+      "Filter/Editor/Video",
+      "Renders a text string to an image bitmap",
+      "David Schleef <ds@schleef.org>, "
+      "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
+
   fontmap = pango_cairo_font_map_get_default ();
   klass->pango_context =
       pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
@@ -466,13 +463,15 @@ gst_text_render_chain (GstPad * pad, GstBuffer * inbuf)
   GstFlowReturn ret;
   GstBuffer *outbuf;
   GstCaps *caps = NULL;
-  guint8 *data = GST_BUFFER_DATA (inbuf);
-  guint size = GST_BUFFER_SIZE (inbuf);
+  guint8 *data;
+  gsize size;
   gint n;
   gint xpos, ypos;
 
   render = GST_TEXT_RENDER (gst_pad_get_parent (pad));
 
+  data = gst_buffer_map (inbuf, &size, NULL, GST_MAP_READ);
+
   /* somehow pango barfs over "\0" buffers... */
   while (size > 0 &&
       (data[size - 1] == '\r' ||
@@ -484,6 +483,7 @@ gst_text_render_chain (GstPad * pad, GstBuffer * inbuf)
   GST_DEBUG ("rendering '%*s'", size, data);
   pango_layout_set_markup (render->layout, (gchar *) data, size);
   gst_text_render_render_pangocairo (render);
+  gst_buffer_unmap (inbuf, data, size);
 
   gst_text_render_check_argb (render);
 
@@ -505,15 +505,10 @@ gst_text_render_chain (GstPad * pad, GstBuffer * inbuf)
   }
 
   GST_DEBUG ("Allocating buffer WxH = %dx%d", render->width, render->height);
-  ret =
-      gst_pad_alloc_buffer_and_set_caps (render->srcpad, GST_BUFFER_OFFSET_NONE,
-      render->width * render->height * 4, caps, &outbuf);
-
-  if (ret != GST_FLOW_OK)
-    goto done;
+  outbuf = gst_buffer_new_and_alloc (render->width * render->height * 4);
 
-  gst_buffer_copy_metadata (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS);
-  data = GST_BUFFER_DATA (outbuf);
+  gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
+  data = gst_buffer_map (outbuf, &size, NULL, GST_MAP_WRITE);
 
   if (render->use_ARGB) {
     memset (data, 0, render->width * render->height * 4);
@@ -562,6 +557,7 @@ gst_text_render_chain (GstPad * pad, GstBuffer * inbuf)
           render->width * 4);
     }
   }
+  gst_buffer_unmap (outbuf, data, size);
 
   ret = gst_pad_push (render->srcpad, outbuf);
 
@@ -587,7 +583,7 @@ gst_text_render_finalize (GObject * object)
 }
 
 static void
-gst_text_render_init (GstTextRender * render, GstTextRenderClass * klass)
+gst_text_render_init (GstTextRender * render)
 {
   GstPadTemplate *template;
 
index 27fab92..3617361 100644 (file)
 
 /**
  * SECTION:element-timeoverlay
- * @see_also: #GstTextOverlay, #GstClockOverlay
+ * @see_also: #GstBaseTextOverlay, #GstClockOverlay
  *
  * This element overlays the buffer time stamps of a video stream on
  * top of itself. You can position the text and configure the font details
- * using the properties of the #GstTextOverlay class. By default, the
+ * using the properties of the #GstBaseTextOverlay class. By default, the
  * time stamp is displayed in the top left corner of the picture, with some
  * padding to the left and to the top.
  *
 
 #include <gsttimeoverlay.h>
 
-GST_BOILERPLATE (GstTimeOverlay, gst_time_overlay, GstTextOverlay,
-    GST_TYPE_TEXT_OVERLAY);
-
-static void
-gst_time_overlay_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class, "Time overlay",
-      "Filter/Editor/Video",
-      "Overlays buffer time stamps on a video stream",
-      "Tim-Philipp Müller <tim@centricular.net>");
-}
+#define gst_time_overlay_parent_class parent_class
+G_DEFINE_TYPE (GstTimeOverlay, gst_time_overlay, GST_TYPE_BASE_TEXT_OVERLAY);
 
 static gchar *
 gst_time_overlay_render_time (GstTimeOverlay * overlay, GstClockTime time)
@@ -82,7 +71,8 @@ gst_time_overlay_render_time (GstTimeOverlay * overlay, GstClockTime time)
 
 /* Called with lock held */
 static gchar *
-gst_time_overlay_get_text (GstTextOverlay * overlay, GstBuffer * video_frame)
+gst_time_overlay_get_text (GstBaseTextOverlay * overlay,
+    GstBuffer * video_frame)
 {
   GstClockTime time = GST_BUFFER_TIMESTAMP (video_frame);
   gchar *time_str, *txt, *ret;
@@ -115,16 +105,23 @@ gst_time_overlay_get_text (GstTextOverlay * overlay, GstBuffer * video_frame)
 static void
 gst_time_overlay_class_init (GstTimeOverlayClass * klass)
 {
-  GstTextOverlayClass *gsttextoverlay_class;
+  GstElementClass *gstelement_class;
+  GstBaseTextOverlayClass *gsttextoverlay_class;
   PangoContext *context;
   PangoFontDescription *font_description;
 
-  gsttextoverlay_class = (GstTextOverlayClass *) klass;
+  gsttextoverlay_class = (GstBaseTextOverlayClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+
+  gst_element_class_set_details_simple (gstelement_class, "Time overlay",
+      "Filter/Editor/Video",
+      "Overlays buffer time stamps on a video stream",
+      "Tim-Philipp Müller <tim@centricular.net>");
 
   gsttextoverlay_class->get_text = gst_time_overlay_get_text;
 
-  g_mutex_lock (GST_TEXT_OVERLAY_CLASS (klass)->pango_lock);
-  context = GST_TEXT_OVERLAY_CLASS (klass)->pango_context;
+  g_mutex_lock (gsttextoverlay_class->pango_lock);
+  context = gsttextoverlay_class->pango_context;
 
   pango_context_set_language (context, pango_language_from_string ("en_US"));
   pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);
@@ -138,16 +135,16 @@ gst_time_overlay_class_init (GstTimeOverlayClass * klass)
   pango_font_description_set_size (font_description, 18 * PANGO_SCALE);
   pango_context_set_font_description (context, font_description);
   pango_font_description_free (font_description);
-  g_mutex_unlock (GST_TEXT_OVERLAY_CLASS (klass)->pango_lock);
+  g_mutex_unlock (gsttextoverlay_class->pango_lock);
 }
 
 static void
-gst_time_overlay_init (GstTimeOverlay * overlay, GstTimeOverlayClass * klass)
+gst_time_overlay_init (GstTimeOverlay * overlay)
 {
-  GstTextOverlay *textoverlay;
+  GstBaseTextOverlay *textoverlay;
 
-  textoverlay = GST_TEXT_OVERLAY (overlay);
+  textoverlay = GST_BASE_TEXT_OVERLAY (overlay);
 
-  textoverlay->valign = GST_TEXT_OVERLAY_VALIGN_TOP;
-  textoverlay->halign = GST_TEXT_OVERLAY_HALIGN_LEFT;
+  textoverlay->valign = GST_BASE_TEXT_OVERLAY_VALIGN_TOP;
+  textoverlay->halign = GST_BASE_TEXT_OVERLAY_HALIGN_LEFT;
 }
index 5fbfba9..dbce8ff 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef __GST_TIME_OVERLAY_H__
 #define __GST_TIME_OVERLAY_H__
 
-#include "gsttextoverlay.h"
+#include "gstbasetextoverlay.h"
 
 G_BEGIN_DECLS
 
@@ -46,11 +46,11 @@ typedef struct _GstTimeOverlayClass GstTimeOverlayClass;
  * Opaque timeoverlay data structure.
  */
 struct _GstTimeOverlay {
-  GstTextOverlay textoverlay;
+  GstBaseTextOverlay textoverlay;
 };
 
 struct _GstTimeOverlayClass {
-  GstTextOverlayClass parent_class;
+  GstBaseTextOverlayClass parent_class;
 };
 
 GType gst_time_overlay_get_type (void);
index 96e12ee..c468821 100644 (file)
@@ -81,7 +81,8 @@ GST_STATIC_PAD_TEMPLATE ("sink",
     GST_STATIC_CAPS ("video/x-theora")
     );
 
-GST_BOILERPLATE (GstTheoraDec, gst_theora_dec, GstElement, GST_TYPE_ELEMENT);
+#define gst_theora_dec_parent_class parent_class
+G_DEFINE_TYPE (GstTheoraDec, gst_theora_dec, GST_TYPE_ELEMENT);
 
 static void theora_dec_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
@@ -107,22 +108,6 @@ static const GstEventMask *theora_get_event_masks (GstPad * pad);
 #endif
 static const GstQueryType *theora_get_query_types (GstPad * pad);
 
-
-static void
-gst_theora_dec_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&theora_dec_src_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&theora_dec_sink_factory));
-  gst_element_class_set_details_simple (element_class,
-      "Theora video decoder", "Codec/Decoder/Video",
-      "decode raw theora streams to raw YUV video",
-      "Benjamin Otte <otte@gnome.org>, Wim Taymans <wim@fluendo.com>");
-}
-
 static gboolean
 gst_theora_dec_ctl_is_supported (int req)
 {
@@ -188,13 +173,22 @@ gst_theora_dec_class_init (GstTheoraDecClass * klass)
             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   }
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&theora_dec_src_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&theora_dec_sink_factory));
+  gst_element_class_set_details_simple (gstelement_class,
+      "Theora video decoder", "Codec/Decoder/Video",
+      "decode raw theora streams to raw YUV video",
+      "Benjamin Otte <otte@gnome.org>, Wim Taymans <wim@fluendo.com>");
+
   gstelement_class->change_state = theora_dec_change_state;
 
   GST_DEBUG_CATEGORY_INIT (theoradec_debug, "theoradec", 0, "Theora decoder");
 }
 
 static void
-gst_theora_dec_init (GstTheoraDec * dec, GstTheoraDecClass * g_class)
+gst_theora_dec_init (GstTheoraDec * dec)
 {
   dec->sinkpad =
       gst_pad_new_from_static_template (&theora_dec_sink_factory, "sink");
@@ -580,7 +574,7 @@ theora_dec_src_event (GstPad * pad, GstEvent * event)
       GstClockTimeDiff diff;
       GstClockTime timestamp;
 
-      gst_event_parse_qos (event, &proportion, &diff, &timestamp);
+      gst_event_parse_qos (event, NULL, &proportion, &diff, &timestamp);
 
       /* we cannot randomly skip frame decoding since we don't have
        * B frames. we can however use the timestamp and diff to not
@@ -634,29 +628,20 @@ theora_dec_sink_event (GstPad * pad, GstEvent * event)
     case GST_EVENT_EOS:
       ret = gst_pad_push_event (dec->srcpad, event);
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      gboolean update;
-      GstFormat format;
-      gdouble rate, arate;
-      gint64 start, stop, time;
+      const GstSegment *segment;
 
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-          &start, &stop, &time);
+      gst_event_parse_segment (event, &segment);
 
       /* we need TIME format */
-      if (format != GST_FORMAT_TIME)
+      if (segment->format != GST_FORMAT_TIME)
         goto newseg_wrong_format;
 
-      GST_DEBUG_OBJECT (dec,
-          "newsegment: update %d, rate %g, arate %g, start %" GST_TIME_FORMAT
-          ", stop %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT,
-          update, rate, arate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
-          GST_TIME_ARGS (time));
+      GST_DEBUG_OBJECT (dec, "segment: %" GST_SEGMENT_FORMAT, segment);
 
       /* now configure the values */
-      gst_segment_set_newsegment_full (&dec->segment, update,
-          rate, arate, format, start, stop, time);
+      gst_segment_copy_into (segment, &dec->segment);
       dec->seqnum = gst_event_get_seqnum (event);
 
       /* We don't forward this unless/until the decoder is initialised */
@@ -681,7 +666,7 @@ theora_dec_sink_event (GstPad * pad, GstEvent * event)
       break;
     }
     default:
-      ret = gst_pad_push_event (dec->srcpad, event);
+      ret = gst_pad_event_default (pad, event);
       break;
   }
 done:
@@ -716,30 +701,33 @@ theora_dec_setcaps (GstPad * pad, GstCaps * caps)
   if ((codec_data = gst_structure_get_value (s, "codec_data"))) {
     if (G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER) {
       GstBuffer *buffer;
-      guint8 *data;
-      guint size;
+      guint8 *data, *ptr;
+      gsize size, left;
       guint offset;
 
       buffer = gst_value_get_buffer (codec_data);
 
       offset = 0;
-      size = GST_BUFFER_SIZE (buffer);
-      data = GST_BUFFER_DATA (buffer);
+      data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
 
-      while (size > 2) {
+      ptr = data;
+      left = size;
+
+      while (left > 2) {
         guint psize;
         GstBuffer *buf;
 
-        psize = (data[0] << 8) | data[1];
+        psize = (ptr[0] << 8) | ptr[1];
         /* skip header */
-        data += 2;
-        size -= 2;
+        ptr += 2;
+        left -= 2;
         offset += 2;
 
         /* make sure we don't read too much */
-        psize = MIN (psize, size);
+        psize = MIN (psize, left);
 
-        buf = gst_buffer_create_sub (buffer, offset, psize);
+        buf =
+            gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, offset, psize);
 
         /* first buffer is a discont buffer */
         if (offset == 2)
@@ -749,10 +737,11 @@ theora_dec_setcaps (GstPad * pad, GstCaps * caps)
         theora_dec_chain (pad, buf);
 
         /* skip the data */
-        size -= psize;
-        data += psize;
+        left -= psize;
+        ptr += psize;
         offset += psize;
       }
+      gst_buffer_unmap (buffer, data, size);
     }
   }
 
@@ -765,20 +754,13 @@ static GstFlowReturn
 theora_handle_comment_packet (GstTheoraDec * dec, ogg_packet * packet)
 {
   gchar *encoder = NULL;
-  GstBuffer *buf;
   GstTagList *list;
 
   GST_DEBUG_OBJECT (dec, "parsing comment packet");
 
-  buf = gst_buffer_new ();
-  GST_BUFFER_SIZE (buf) = packet->bytes;
-  GST_BUFFER_DATA (buf) = packet->packet;
-
   list =
-      gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\201theora", 7,
-      &encoder);
-
-  gst_buffer_unref (buf);
+      gst_tag_list_from_vorbiscomment (packet->packet, packet->bytes,
+      (guint8 *) "\201theora", 7, &encoder);
 
   if (!list) {
     GST_ERROR_OBJECT (dec, "couldn't decode comments");
@@ -805,6 +787,54 @@ theora_handle_comment_packet (GstTheoraDec * dec, ogg_packet * packet)
 }
 
 static GstFlowReturn
+theora_negotiate_pool (GstTheoraDec * dec, GstCaps * caps)
+{
+  GstQuery *query;
+  GstBufferPool *pool = NULL;
+  guint size, min, max, prefix, alignment;
+
+  /* find a pool for the negotiated caps now */
+  query = gst_query_new_allocation (caps, TRUE);
+
+  if (gst_pad_peer_query (dec->srcpad, query)) {
+    GST_DEBUG_OBJECT (dec, "got downstream ALLOCATION hints");
+    /* we got configuration from our peer, parse them */
+    gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
+        &alignment, &pool);
+  } else {
+    GST_DEBUG_OBJECT (dec, "didn't get downstream ALLOCATION hints");
+    size = gst_video_format_get_size (dec->format, dec->width, dec->height);
+    min = max = 0;
+    prefix = 0;
+    alignment = 1;
+  }
+
+  if (pool == NULL) {
+    GstStructure *config;
+
+    /* we did not get a pool, make one ourselves then */
+    pool = gst_buffer_pool_new ();
+
+    config = gst_buffer_pool_get_config (pool);
+    gst_buffer_pool_config_set (config, caps, size, min, max, prefix, 0,
+        alignment);
+    gst_buffer_pool_set_config (pool, config);
+  }
+
+  if (dec->pool)
+    gst_object_unref (dec->pool);
+  dec->pool = pool;
+
+  /* FIXME, we can check if downstream supports clipping and/or video
+   * metadata. */
+
+  /* and activate */
+  gst_buffer_pool_set_active (pool, TRUE);
+
+  return GST_FLOW_OK;
+}
+
+static GstFlowReturn
 theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
 {
   GstCaps *caps;
@@ -846,18 +876,24 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
       dec->info.pic_width, dec->info.pic_height,
       dec->info.pic_x, dec->info.pic_y);
 
-  if (dec->info.pixel_fmt == TH_PF_420) {
-    dec->output_bpp = 12;       /* Average bits per pixel. */
-    fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
-  } else if (dec->info.pixel_fmt == TH_PF_422) {
-    dec->output_bpp = 16;
-    fourcc = GST_MAKE_FOURCC ('Y', '4', '2', 'B');
-  } else if (dec->info.pixel_fmt == TH_PF_444) {
-    dec->output_bpp = 24;
-    fourcc = GST_MAKE_FOURCC ('Y', '4', '4', '4');
-  } else {
-    GST_ERROR_OBJECT (dec, "Invalid pixel format %d", dec->info.pixel_fmt);
-    return GST_FLOW_ERROR;
+  switch (dec->info.pixel_fmt) {
+    case TH_PF_444:
+      dec->output_bpp = 24;
+      dec->format = GST_VIDEO_FORMAT_Y444;
+      fourcc = GST_MAKE_FOURCC ('Y', '4', '4', '4');
+      break;
+    case TH_PF_420:
+      dec->output_bpp = 12;     /* Average bits per pixel. */
+      dec->format = GST_VIDEO_FORMAT_I420;
+      fourcc = GST_MAKE_FOURCC ('I', '4', '2', '0');
+      break;
+    case TH_PF_422:
+      dec->output_bpp = 16;
+      dec->format = GST_VIDEO_FORMAT_Y42B;
+      fourcc = GST_MAKE_FOURCC ('Y', '4', '2', 'B');
+      break;
+    default:
+      goto invalid_format;
   }
 
   if (dec->crop) {
@@ -918,6 +954,10 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
   gst_pad_set_caps (dec->srcpad, caps);
   gst_caps_unref (caps);
 
+  /* negotiate a bufferpool */
+  if ((ret = theora_negotiate_pool (dec, caps)) != GST_FLOW_OK)
+    goto no_bufferpool;
+
   dec->have_header = TRUE;
 
   if (dec->pendingevents) {
@@ -934,6 +974,17 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
   }
 
   return ret;
+
+  /* ERRORS */
+invalid_format:
+  {
+    GST_ERROR_OBJECT (dec, "Invalid pixel format %d", dec->info.pixel_fmt);
+    return GST_FLOW_ERROR;
+  }
+no_bufferpool:
+  {
+    return ret;
+  }
 }
 
 static GstFlowReturn
@@ -981,7 +1032,7 @@ clip_buffer (GstTheoraDec * dec, GstBuffer * buf)
 {
   gboolean res = TRUE;
   GstClockTime in_ts, in_dur, stop;
-  gint64 cstart, cstop;
+  guint64 cstart, cstop;
 
   in_ts = GST_BUFFER_TIMESTAMP (buf);
   in_dur = GST_BUFFER_DURATION (buf);
@@ -1054,40 +1105,27 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf, GstBuffer ** out)
   gint width, height, stride;
   GstFlowReturn result;
   int i, plane;
-  GstVideoFormat format;
   guint8 *dest, *src;
+  gsize size;
+  guint8 *data;
 
-  switch (dec->info.pixel_fmt) {
-    case TH_PF_444:
-      format = GST_VIDEO_FORMAT_Y444;
-      break;
-    case TH_PF_420:
-      format = GST_VIDEO_FORMAT_I420;
-      break;
-    case TH_PF_422:
-      format = GST_VIDEO_FORMAT_Y42B;
-      break;
-    default:
-      g_assert_not_reached ();
-  }
+  result = gst_buffer_pool_acquire_buffer (dec->pool, out, NULL);
+  if (G_UNLIKELY (result != GST_FLOW_OK))
+    goto no_buffer;
 
-  result =
-      gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE,
-      gst_video_format_get_size (format, dec->width, dec->height),
-      GST_PAD_CAPS (dec->srcpad), out);
-  if (G_UNLIKELY (result != GST_FLOW_OK)) {
-    GST_DEBUG_OBJECT (dec, "could not get buffer, reason: %s",
-        gst_flow_get_name (result));
-    return result;
-  }
+  data = gst_buffer_map (*out, &size, NULL, GST_MAP_WRITE);
+
+  /* FIXME, we can do things slightly more efficient when we know that
+   * downstream understands clipping and video metadata */
 
   for (plane = 0; plane < 3; plane++) {
-    width = gst_video_format_get_component_width (format, plane, dec->width);
-    height = gst_video_format_get_component_height (format, plane, dec->height);
-    stride = gst_video_format_get_row_stride (format, plane, dec->width);
+    width =
+        gst_video_format_get_component_width (dec->format, plane, dec->width);
+    height =
+        gst_video_format_get_component_height (dec->format, plane, dec->height);
+    stride = gst_video_format_get_row_stride (dec->format, plane, dec->width);
 
-    dest =
-        GST_BUFFER_DATA (*out) + gst_video_format_get_component_offset (format,
+    dest = data + gst_video_format_get_component_offset (dec->format,
         plane, dec->width, dec->height);
     src = buf[plane].data;
     src += ((height == dec->height) ? dec->offset_y : dec->offset_y / 2)
@@ -1101,8 +1139,17 @@ theora_handle_image (GstTheoraDec * dec, th_ycbcr_buffer buf, GstBuffer ** out)
       src += buf[plane].stride;
     }
   }
+  gst_buffer_unmap (*out, data, size);
 
   return GST_FLOW_OK;
+
+  /* ERRORS */
+no_buffer:
+  {
+    GST_DEBUG_OBJECT (dec, "could not get buffer, reason: %s",
+        gst_flow_get_name (result));
+    return result;
+  }
 }
 
 static GstFlowReturn
@@ -1268,10 +1315,11 @@ theora_dec_decode_buffer (GstTheoraDec * dec, GstBuffer * buf)
   ogg_packet packet;
   GstFlowReturn result = GST_FLOW_OK;
   GstClockTime timestamp, duration;
+  gsize size;
 
   /* make ogg_packet out of the buffer */
-  packet.packet = GST_BUFFER_DATA (buf);
-  packet.bytes = GST_BUFFER_SIZE (buf);
+  packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  packet.bytes = size;
   packet.granulepos = -1;
   packet.packetno = 0;          /* we don't really care */
   packet.b_o_s = dec->have_header ? 0 : 1;
@@ -1299,8 +1347,9 @@ theora_dec_decode_buffer (GstTheoraDec * dec, GstBuffer * buf)
   } else {
     result = theora_handle_data_packet (dec, &packet, timestamp, duration);
   }
-
 done:
+  gst_buffer_unmap (buf, packet.packet, size);
+
   return result;
 }
 
@@ -1430,7 +1479,7 @@ theora_dec_chain_reverse (GstTheoraDec * dec, gboolean discont, GstBuffer * buf)
     GST_DEBUG_OBJECT (dec, "received discont,gathering buffers");
     while (dec->gather) {
       GstBuffer *gbuf;
-      guint8 *data;
+      guint8 data[1];
 
       gbuf = GST_BUFFER_CAST (dec->gather->data);
       /* remove from the gather list */
@@ -1439,7 +1488,7 @@ theora_dec_chain_reverse (GstTheoraDec * dec, gboolean discont, GstBuffer * buf)
       dec->decode = g_list_prepend (dec->decode, gbuf);
 
       /* if we copied a keyframe, flush and decode the decode queue */
-      data = GST_BUFFER_DATA (gbuf);
+      gst_buffer_extract (gbuf, 0, data, 1);
       if ((data[0] & 0x40) == 0) {
         GST_DEBUG_OBJECT (dec, "copied keyframe");
         res = theora_dec_flush_decode (dec);
@@ -1449,7 +1498,7 @@ theora_dec_chain_reverse (GstTheoraDec * dec, gboolean discont, GstBuffer * buf)
 
   /* add buffer to gather queue */
   GST_DEBUG_OBJECT (dec, "gathering buffer %p, size %u", buf,
-      GST_BUFFER_SIZE (buf));
+      gst_buffer_get_size (buf));
   dec->gather = g_list_prepend (dec->gather, buf);
 
   return res;
@@ -1521,7 +1570,7 @@ theora_dec_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
-  ret = parent_class->change_state (element, transition);
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 
   switch (transition) {
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
@@ -1534,6 +1583,11 @@ theora_dec_change_state (GstElement * element, GstStateChange transition)
       th_decode_free (dec->decoder);
       dec->decoder = NULL;
       gst_theora_dec_reset (dec);
+      if (dec->pool) {
+        gst_buffer_pool_set_active (dec->pool, FALSE);
+        gst_object_unref (dec->pool);
+        dec->pool = NULL;
+      }
       break;
     case GST_STATE_CHANGE_READY_TO_NULL:
       break;
index f672211..c469810 100644 (file)
@@ -27,6 +27,7 @@
 #include <gst/gst.h>
 #include <theora/theoradec.h>
 #include <string.h>
+#include <gst/video/video.h>
 
 G_BEGIN_DECLS
 
@@ -59,7 +60,6 @@ struct _GstTheoraDec
 
   /* theora decoder state */
   th_dec_ctx *decoder;
-  //theora_state state;
   th_setup_info *setup;
   th_info info;
   th_comment comment;
@@ -69,9 +69,11 @@ struct _GstTheoraDec
   GstClockTime last_timestamp;
   guint64 frame_nr;
   gboolean need_keyframe;
+  GstVideoFormat format;
   gint width, height;
   gint offset_x, offset_y;
   gint output_bpp;
+  GstBufferPool *pool;
 
   /* telemetry debuging options */
   gint telemetry_mv;
index c580675..57d76b4 100644 (file)
@@ -243,28 +243,16 @@ GST_STATIC_PAD_TEMPLATE ("src",
     GST_STATIC_CAPS ("video/x-theora")
     );
 
-static void
-_do_init (GType object_type)
-{
-  const GInterfaceInfo preset_interface_info = {
-    NULL,                       /* interface_init */
-    NULL,                       /* interface_finalize */
-    NULL                        /* interface_data */
-  };
-
-  g_type_add_interface_static (object_type, GST_TYPE_PRESET,
-      &preset_interface_info);
-}
-
-GST_BOILERPLATE_FULL (GstTheoraEnc, gst_theora_enc, GstElement,
-    GST_TYPE_ELEMENT, _do_init);
+#define gst_theora_enc_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstTheoraEnc, gst_theora_enc,
+    GST_TYPE_ELEMENT, G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL));
 
 static gboolean theora_enc_sink_event (GstPad * pad, GstEvent * event);
 static gboolean theora_enc_src_event (GstPad * pad, GstEvent * event);
 static GstFlowReturn theora_enc_chain (GstPad * pad, GstBuffer * buffer);
 static GstStateChangeReturn theora_enc_change_state (GstElement * element,
     GstStateChange transition);
-static GstCaps *theora_enc_sink_getcaps (GstPad * pad);
+static GstCaps *theora_enc_sink_getcaps (GstPad * pad, GstCaps * filter);
 static gboolean theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps);
 static void theora_enc_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
@@ -276,21 +264,6 @@ static gboolean theora_enc_write_multipass_cache (GstTheoraEnc * enc,
     gboolean begin, gboolean eos);
 
 static void
-gst_theora_enc_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&theora_enc_src_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&theora_enc_sink_factory));
-  gst_element_class_set_details_simple (element_class,
-      "Theora video encoder", "Codec/Encoder/Video",
-      "encode raw YUV video to a theora stream",
-      "Wim Taymans <wim@fluendo.com>");
-}
-
-static void
 gst_theora_enc_class_init (GstTheoraEncClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
@@ -414,11 +387,20 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass)
           THEORA_DEF_MULTIPASS_MODE,
           (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&theora_enc_src_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&theora_enc_sink_factory));
+  gst_element_class_set_details_simple (gstelement_class,
+      "Theora video encoder", "Codec/Encoder/Video",
+      "encode raw YUV video to a theora stream",
+      "Wim Taymans <wim@fluendo.com>");
+
   gstelement_class->change_state = theora_enc_change_state;
 }
 
 static void
-gst_theora_enc_init (GstTheoraEnc * enc, GstTheoraEncClass * g_class)
+gst_theora_enc_init (GstTheoraEnc * enc)
 {
   enc->sinkpad =
       gst_pad_new_from_static_template (&theora_enc_sink_factory, "sink");
@@ -596,7 +578,7 @@ theora_enc_get_supported_formats (void)
 }
 
 static GstCaps *
-theora_enc_sink_getcaps (GstPad * pad)
+theora_enc_sink_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstCaps *caps;
   char *supported_formats, *caps_string;
@@ -617,6 +599,15 @@ theora_enc_sink_getcaps (GstPad * pad)
   g_free (supported_formats);
   GST_DEBUG ("Supported caps: %" GST_PTR_FORMAT, caps);
 
+  if (filter) {
+    GstCaps *intersection;
+
+    intersection =
+        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (caps);
+    caps = intersection;
+  }
+
   return caps;
 }
 
@@ -713,8 +704,7 @@ theora_buffer_from_packet (GstTheoraEnc * enc, ogg_packet * packet,
     goto done;
   }
 
-  memcpy (GST_BUFFER_DATA (buf), packet->packet, packet->bytes);
-  gst_buffer_set_caps (buf, GST_PAD_CAPS (enc->srcpad));
+  gst_buffer_fill (buf, 0, packet->packet, packet->bytes);
   /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
    * time representation */
   GST_BUFFER_OFFSET_END (buf) =
@@ -751,7 +741,7 @@ theora_push_buffer (GstTheoraEnc * enc, GstBuffer * buffer)
 {
   GstFlowReturn ret;
 
-  enc->bytes_out += GST_BUFFER_SIZE (buffer);
+  enc->bytes_out += gst_buffer_get_size (buffer);
 
   ret = gst_pad_push (enc->srcpad, buffer);
 
@@ -839,18 +829,9 @@ theora_enc_sink_event (GstPad * pad, GstEvent * event)
   enc = GST_THEORA_ENC (GST_PAD_PARENT (pad));
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      gboolean update;
-      gdouble rate, applied_rate;
-      GstFormat format;
-      gint64 start, stop, time;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
-          &format, &start, &stop, &time);
-
-      gst_segment_set_newsegment_full (&enc->segment, update, rate,
-          applied_rate, format, start, stop, time);
+      gst_event_copy_segment (event, &enc->segment);
 
       res = gst_pad_push_event (enc->srcpad, event);
       break;
@@ -1014,17 +995,21 @@ theora_enc_read_multipass_cache (GstTheoraEnc * enc)
 
   while (!done) {
     if (gst_adapter_available (enc->multipass_cache_adapter) == 0) {
+      guint8 *data;
+      gsize size;
+
       cache_buf = gst_buffer_new_and_alloc (512);
+
+      data = gst_buffer_map (cache_buf, &size, NULL, GST_MAP_READ);
       stat = g_io_channel_read_chars (enc->multipass_cache_fd,
-          (gchar *) GST_BUFFER_DATA (cache_buf), GST_BUFFER_SIZE (cache_buf),
-          &bytes_read, NULL);
+          (gchar *) data, size, &bytes_read, NULL);
 
       if (bytes_read <= 0) {
+        gst_buffer_unmap (cache_buf, data, 0);
         gst_buffer_unref (cache_buf);
         break;
       } else {
-        GST_BUFFER_SIZE (cache_buf) = bytes_read;
-
+        gst_buffer_unmap (cache_buf, data, bytes_read);
         gst_adapter_push (enc->multipass_cache_adapter, cache_buf);
       }
     }
@@ -1034,11 +1019,13 @@ theora_enc_read_multipass_cache (GstTheoraEnc * enc)
     bytes_read =
         MIN (gst_adapter_available (enc->multipass_cache_adapter), 512);
 
-    cache_data = gst_adapter_peek (enc->multipass_cache_adapter, bytes_read);
+    cache_data = gst_adapter_map (enc->multipass_cache_adapter, bytes_read);
 
     bytes_consumed =
         th_encode_ctl (enc->encoder, TH_ENCCTL_2PASS_IN, (guint8 *) cache_data,
         bytes_read);
+    gst_adapter_unmap (enc->multipass_cache_adapter, 0);
+
     done = bytes_consumed <= 0;
     if (bytes_consumed > 0)
       gst_adapter_flush (enc->multipass_cache_adapter, bytes_consumed);
@@ -1216,13 +1203,10 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
     buffers = g_slist_reverse (buffers);
 
     /* mark buffers and put on caps */
-    caps = gst_pad_get_caps (enc->srcpad);
+    caps = gst_pad_get_caps (enc->srcpad, NULL);
     caps = theora_set_header_on_caps (caps, buffers);
     GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
     gst_pad_set_caps (enc->srcpad, caps);
-
-    g_slist_foreach (buffers, (GFunc) gst_buffer_set_caps, caps);
-
     gst_caps_unref (caps);
 
     /* push out the header buffers */
@@ -1246,8 +1230,11 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
   {
     th_ycbcr_buffer ycbcr;
     gint res;
+    guint8 *data;
+    gsize size;
 
-    theora_enc_init_buffer (ycbcr, &enc->info, GST_BUFFER_DATA (buffer));
+    data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+    theora_enc_init_buffer (ycbcr, &enc->info, data);
 
     if (theora_enc_is_discontinuous (enc, running_time, duration)) {
       theora_enc_reset (enc);
@@ -1262,6 +1249,7 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
     if (enc->multipass_cache_fd
         && enc->multipass_mode == MULTIPASS_MODE_SECOND_PASS) {
       if (!theora_enc_read_multipass_cache (enc)) {
+        gst_buffer_unmap (buffer, data, size);
         ret = GST_FLOW_ERROR;
         goto multipass_read_failed;
       }
@@ -1274,6 +1262,7 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
     if (enc->multipass_cache_fd
         && enc->multipass_mode == MULTIPASS_MODE_FIRST_PASS) {
       if (!theora_enc_write_multipass_cache (enc, FALSE, FALSE)) {
+        gst_buffer_unmap (buffer, data, size);
         ret = GST_FLOW_ERROR;
         goto multipass_write_failed;
       }
@@ -1290,9 +1279,12 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
           next_time - enc->next_ts);
 
       enc->next_ts = next_time;
-      if (ret != GST_FLOW_OK)
+      if (ret != GST_FLOW_OK) {
+        gst_buffer_unmap (buffer, data, size);
         goto data_push;
+      }
     }
+    gst_buffer_unmap (buffer, data, size);
     gst_buffer_unref (buffer);
   }
 
@@ -1384,7 +1376,7 @@ theora_enc_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
-  ret = parent_class->change_state (element, transition);
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 
   switch (transition) {
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
index 0ce68d9..25b046f 100644 (file)
@@ -85,8 +85,8 @@ enum
   PROP_SYNCHRONIZATION_POINTS
 };
 
-GST_BOILERPLATE (GstTheoraParse, gst_theora_parse, GstElement,
-    GST_TYPE_ELEMENT);
+#define gst_theora_parse_parent_class parent_class
+G_DEFINE_TYPE (GstTheoraParse, gst_theora_parse, GST_TYPE_ELEMENT);
 
 static void theora_parse_dispose (GObject * object);
 static void theora_parse_get_property (GObject * object, guint prop_id,
@@ -101,20 +101,6 @@ static gboolean theora_parse_sink_event (GstPad * pad, GstEvent * event);
 static gboolean theora_parse_src_query (GstPad * pad, GstQuery * query);
 
 static void
-gst_theora_parse_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&theora_parse_src_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&theora_parse_sink_factory));
-  gst_element_class_set_details_simple (element_class,
-      "Theora video parser", "Codec/Parser/Video",
-      "parse raw theora streams", "Andy Wingo <wingo@pobox.com>");
-}
-
-static void
 gst_theora_parse_class_init (GstTheoraParseClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
@@ -140,6 +126,15 @@ gst_theora_parse_class_init (GstTheoraParseClass * klass)
               G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&theora_parse_src_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&theora_parse_sink_factory));
+  gst_element_class_set_details_simple (gstelement_class,
+      "Theora video parser", "Codec/Parser/Video",
+      "parse raw theora streams", "Andy Wingo <wingo@pobox.com>");
+
   gstelement_class->change_state = theora_parse_change_state;
 
   GST_DEBUG_CATEGORY_INIT (theoraparse_debug, "theoraparse", 0,
@@ -147,7 +142,7 @@ gst_theora_parse_class_init (GstTheoraParseClass * klass)
 }
 
 static void
-gst_theora_parse_init (GstTheoraParse * parse, GstTheoraParseClass * g_class)
+gst_theora_parse_init (GstTheoraParse * parse)
 {
   parse->sinkpad =
       gst_pad_new_from_static_template (&theora_parse_sink_factory, "sink");
@@ -267,7 +262,7 @@ theora_parse_set_header_on_caps (GstTheoraParse * parse, GstCaps * caps)
     if (bufs[i] == NULL)
       continue;
 
-    bufs[i] = gst_buffer_make_metadata_writable (bufs[i]);
+    bufs[i] = gst_buffer_make_writable (bufs[i]);
     GST_BUFFER_FLAG_SET (bufs[i], GST_BUFFER_FLAG_IN_CAPS);
 
     g_value_init (&value, GST_TYPE_BUFFER);
@@ -292,7 +287,7 @@ theora_parse_set_streamheader (GstTheoraParse * parse)
 
   g_assert (!parse->streamheader_received);
 
-  caps = gst_caps_make_writable (gst_pad_get_caps (parse->srcpad));
+  caps = gst_caps_make_writable (gst_pad_get_caps (parse->srcpad, NULL));
   theora_parse_set_header_on_caps (parse, caps);
   GST_DEBUG_OBJECT (parse, "here are the caps: %" GST_PTR_FORMAT, caps);
   gst_pad_set_caps (parse->srcpad, caps);
@@ -302,18 +297,20 @@ theora_parse_set_streamheader (GstTheoraParse * parse)
     ogg_packet packet;
     GstBuffer *buf;
     int ret;
+    gsize size;
 
     buf = parse->streamheader[i];
     if (buf == NULL)
       continue;
 
-    packet.packet = GST_BUFFER_DATA (buf);
-    packet.bytes = GST_BUFFER_SIZE (buf);
+    packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+    packet.bytes = size;
     packet.granulepos = GST_BUFFER_OFFSET_END (buf);
     packet.packetno = i + 1;
     packet.e_o_s = 0;
     packet.b_o_s = (i == 0);
     ret = th_decode_headerin (&parse->info, &parse->comment, &setup, &packet);
+    gst_buffer_unmap (buf, packet.packet, size);
     if (ret < 0) {
       GST_WARNING_OBJECT (parse, "Failed to decode Theora header %d: %d\n",
           i + 1, ret);
@@ -367,8 +364,6 @@ theora_parse_push_headers (GstTheoraParse * parse)
     GstBuffer *buf;
 
     if ((buf = parse->streamheader[i])) {
-      buf = gst_buffer_make_metadata_writable (buf);
-      gst_buffer_set_caps (buf, GST_PAD_CAPS (parse->srcpad));
       gst_pad_push (parse->srcpad, buf);
       parse->streamheader[i] = NULL;
     }
@@ -435,11 +430,16 @@ parse_granulepos (GstTheoraParse * parse, gint64 granulepos,
 static gboolean
 is_keyframe (GstBuffer * buf)
 {
-  if (!GST_BUFFER_DATA (buf))
-    return FALSE;
-  if (!GST_BUFFER_SIZE (buf))
+  gsize size;
+  guint8 data[1];
+
+  size = gst_buffer_get_size (buf);
+  if (size == 0)
     return FALSE;
-  return ((GST_BUFFER_DATA (buf)[0] & 0x40) == 0);
+
+  gst_buffer_extract (buf, 0, data, 1);
+
+  return ((data[0] & 0x40) == 0);
 }
 
 static void
@@ -496,8 +496,6 @@ theora_parse_push_buffer (GstTheoraParse * parse, GstBuffer * buf,
   GST_BUFFER_TIMESTAMP (buf) = this_time;
   GST_BUFFER_DURATION (buf) = next_time - this_time;
 
-  gst_buffer_set_caps (buf, GST_PAD_CAPS (parse->srcpad));
-
   if (parse->times)
     theora_parse_munge_granulepos (parse, buf, keyframe, frame);
 
@@ -624,7 +622,7 @@ theora_parse_queue_buffer (GstTheoraParse * parse, GstBuffer * buf)
 {
   GstFlowReturn ret = GST_FLOW_OK;
 
-  buf = gst_buffer_make_metadata_writable (buf);
+  buf = gst_buffer_make_writable (buf);
 
   g_queue_push_tail (parse->buffer_queue, buf);
 
@@ -644,18 +642,20 @@ theora_parse_chain (GstPad * pad, GstBuffer * buffer)
 {
   GstFlowReturn ret;
   GstTheoraParse *parse;
-  guint8 *data;
-  guint size;
+  guint8 *data, header;
+  gsize size;
   gboolean have_header;
 
   parse = GST_THEORA_PARSE (gst_pad_get_parent (pad));
 
-  data = GST_BUFFER_DATA (buffer);
-  size = GST_BUFFER_SIZE (buffer);
-
   have_header = FALSE;
+
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+  header = data[0];
+  gst_buffer_unmap (buffer, data, size);
+
   if (size >= 1) {
-    if (data[0] & 0x80)
+    if (header & 0x80)
       have_header = TRUE;
   }
 
@@ -663,8 +663,8 @@ theora_parse_chain (GstPad * pad, GstBuffer * buffer)
     if (parse->send_streamheader) {
       /* we need to collect the headers still */
       /* so put it on the streamheader list and return */
-      if (data[0] >= 0x80 && data[0] <= 0x82)
-        parse->streamheader[data[0] - 0x80] = buffer;
+      if (header >= 0x80 && header <= 0x82)
+        parse->streamheader[header - 0x80] = buffer;
     }
     ret = GST_FLOW_OK;
   } else {
@@ -910,7 +910,7 @@ theora_parse_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
-  ret = parent_class->change_state (element, transition);
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 
   switch (transition) {
     case GST_STATE_CHANGE_PAUSED_TO_READY:
index ee90661..4910c3e 100644 (file)
@@ -64,8 +64,8 @@ GST_STATIC_PAD_TEMPLATE ("sink",
     GST_STATIC_CAPS ("audio/x-vorbis")
     );
 
-GST_BOILERPLATE (GST_VORBIS_DEC_GLIB_TYPE_NAME, gst_vorbis_dec, GstElement,
-    GST_TYPE_ELEMENT);
+#define gst_vorbis_dec_parent_class parent_class
+G_DEFINE_TYPE (GST_VORBIS_DEC_GLIB_TYPE_NAME, gst_vorbis_dec, GST_TYPE_ELEMENT);
 
 static void vorbis_dec_finalize (GObject * object);
 static gboolean vorbis_dec_sink_event (GstPad * pad, GstEvent * event);
@@ -86,30 +86,23 @@ static gboolean vorbis_dec_convert (GstPad * pad,
 static gboolean vorbis_dec_sink_query (GstPad * pad, GstQuery * query);
 
 static void
-gst_vorbis_dec_base_init (gpointer g_class)
+gst_vorbis_dec_class_init (GstVorbisDecClass * klass)
 {
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-  GstPadTemplate *src_template, *sink_template;
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+
+  gobject_class->finalize = vorbis_dec_finalize;
 
-  src_template = gst_static_pad_template_get (&vorbis_dec_src_factory);
-  gst_element_class_add_pad_template (element_class, src_template);
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&vorbis_dec_src_factory));
 
-  sink_template = gst_static_pad_template_get (&vorbis_dec_sink_factory);
-  gst_element_class_add_pad_template (element_class, sink_template);
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&vorbis_dec_sink_factory));
 
-  gst_element_class_set_details_simple (element_class,
+  gst_element_class_set_details_simple (gstelement_class,
       "Vorbis audio decoder", "Codec/Decoder/Audio",
       GST_VORBIS_DEC_DESCRIPTION,
       "Benjamin Otte <otte@gnome.org>, Chris Lord <chris@openedhand.com>");
-}
-
-static void
-gst_vorbis_dec_class_init (GstVorbisDecClass * klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
-
-  gobject_class->finalize = vorbis_dec_finalize;
 
   gstelement_class->change_state = GST_DEBUG_FUNCPTR (vorbis_dec_change_state);
 }
@@ -128,7 +121,7 @@ vorbis_get_query_types (GstPad * pad)
 }
 
 static void
-gst_vorbis_dec_init (GstVorbisDec * dec, GstVorbisDecClass * g_class)
+gst_vorbis_dec_init (GstVorbisDec * dec)
 {
   dec->sinkpad = gst_pad_new_from_static_template (&vorbis_dec_sink_factory,
       "sink");
@@ -493,29 +486,20 @@ vorbis_dec_sink_event (GstPad * pad, GstEvent * event)
       gst_vorbis_dec_reset (dec);
       ret = gst_pad_push_event (dec->srcpad, event);
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      GstFormat format;
-      gdouble rate, arate;
-      gint64 start, stop, time;
-      gboolean update;
+      const GstSegment *segment;
 
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-          &start, &stop, &time);
+      gst_event_parse_segment (event, &segment);
 
       /* we need time for now */
-      if (format != GST_FORMAT_TIME)
+      if (segment->format != GST_FORMAT_TIME)
         goto newseg_wrong_format;
 
-      GST_DEBUG_OBJECT (dec,
-          "newsegment: update %d, rate %g, arate %g, start %" GST_TIME_FORMAT
-          ", stop %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT,
-          update, rate, arate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
-          GST_TIME_ARGS (time));
+      GST_DEBUG_OBJECT (dec, "segment: %" GST_SEGMENT_FORMAT, segment);
 
       /* now configure the values */
-      gst_segment_set_newsegment_full (&dec->segment, update,
-          rate, arate, format, start, stop, time);
+      gst_segment_copy_into (segment, &dec->segment);
       dec->seqnum = gst_event_get_seqnum (event);
 
       if (dec->initialized)
@@ -541,7 +525,7 @@ vorbis_dec_sink_event (GstPad * pad, GstEvent * event)
       break;
     }
     default:
-      ret = gst_pad_push_event (dec->srcpad, event);
+      ret = gst_pad_event_default (pad, event);
       break;
   }
 done:
@@ -613,7 +597,7 @@ vorbis_handle_identification_packet (GstVorbisDec * vd)
    * for mono/stereo and avoid the depth switch in tremor case */
   vd->copy_samples = get_copy_sample_func (vd->vi.channels, vd->width);
 
-  caps = gst_caps_copy (gst_pad_get_pad_template_caps (vd->srcpad));
+  caps = gst_caps_make_writable (gst_pad_get_pad_template_caps (vd->srcpad));
   gst_caps_set_simple (caps, "rate", G_TYPE_INT, vd->vi.rate,
       "channels", G_TYPE_INT, vd->vi.channels,
       "width", G_TYPE_INT, width, NULL);
@@ -638,16 +622,16 @@ vorbis_handle_comment_packet (GstVorbisDec * vd, ogg_packet * packet)
   guint bitrate = 0;
   gchar *encoder = NULL;
   GstTagList *list, *old_list;
-  GstBuffer *buf;
+  guint8 *data;
+  gsize size;
 
   GST_DEBUG_OBJECT (vd, "parsing comment packet");
 
-  buf = gst_buffer_new ();
-  GST_BUFFER_DATA (buf) = gst_ogg_packet_data (packet);
-  GST_BUFFER_SIZE (buf) = gst_ogg_packet_size (packet);
+  data = gst_ogg_packet_data (packet);
+  size = gst_ogg_packet_size (packet);
 
   list =
-      gst_tag_list_from_vorbiscomment_buffer (buf, (guint8 *) "\003vorbis", 7,
+      gst_tag_list_from_vorbiscomment (data, size, (guint8 *) "\003vorbis", 7,
       &encoder);
 
   old_list = vd->taglist;
@@ -656,7 +640,6 @@ vorbis_handle_comment_packet (GstVorbisDec * vd, ogg_packet * packet)
   if (old_list)
     gst_tag_list_free (old_list);
   gst_tag_list_free (list);
-  gst_buffer_unref (buf);
 
   if (!vd->taglist) {
     GST_ERROR_OBJECT (vd, "couldn't decode comments");
@@ -881,7 +864,8 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
   guint sample_count;
   GstBuffer *out = NULL;
   GstFlowReturn result;
-  gint size;
+  guint8 *data;
+  gsize size;
 
   if (G_UNLIKELY (!vd->initialized))
     goto not_initialized;
@@ -920,11 +904,7 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
       size);
 
   /* alloc buffer for it */
-  result =
-      gst_pad_alloc_buffer_and_set_caps (vd->srcpad, GST_BUFFER_OFFSET_NONE,
-      size, GST_PAD_CAPS (vd->srcpad), &out);
-  if (G_UNLIKELY (result != GST_FLOW_OK))
-    goto done;
+  out = gst_buffer_new_and_alloc (size);
 
   /* get samples ready for reading now, should be sample_count */
 #ifdef USE_TREMOLO
@@ -938,12 +918,13 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
 
 #ifndef USE_TREMOLO
   /* copy samples in buffer */
-  vd->copy_samples ((vorbis_sample_t *) GST_BUFFER_DATA (out), pcm,
+  data = gst_buffer_map (out, NULL, NULL, GST_MAP_WRITE);
+  vd->copy_samples ((vorbis_sample_t *) data, pcm,
       sample_count, vd->vi.channels, vd->width);
 #endif
 
   GST_LOG_OBJECT (vd, "setting output size to %d", size);
-  GST_BUFFER_SIZE (out) = size;
+  gst_buffer_unmap (out, data, size);
 
   /* this should not overflow */
   if (duration == -1)
@@ -1002,11 +983,16 @@ vorbis_dec_handle_header_buffer (GstVorbisDec * vd, GstBuffer * buffer)
 {
   ogg_packet *packet;
   ogg_packet_wrapper packet_wrapper;
+  GstFlowReturn ret;
 
-  gst_ogg_packet_wrapper_from_buffer (&packet_wrapper, buffer);
+  gst_ogg_packet_wrapper_map (&packet_wrapper, buffer);
   packet = gst_ogg_packet_from_wrapper (&packet_wrapper);
 
-  return vorbis_handle_header_packet (vd, packet);
+  ret = vorbis_handle_header_packet (vd, packet);
+
+  gst_ogg_packet_wrapper_unmap (&packet_wrapper, buffer);
+
+  return ret;
 }
 
 
@@ -1015,56 +1001,71 @@ static GstFlowReturn
 vorbis_dec_handle_header_caps (GstVorbisDec * vd, GstBuffer * buffer)
 {
   GstFlowReturn result = GST_FLOW_OK;
-  GstCaps *caps = GST_PAD_CAPS (vd->sinkpad);
-  GstStructure *s = gst_caps_get_structure (caps, 0);
-  const GValue *array = gst_structure_get_value (s, "streamheader");
-
-  if (array && (gst_value_array_get_size (array) >= MIN_NUM_HEADERS)) {
-    const GValue *value = NULL;
-    GstBuffer *buf = NULL;
-
-    /* initial header */
-    value = gst_value_array_get_value (array, 0);
-    buf = gst_value_get_buffer (value);
-    if (!buf)
-      goto null_buffer;
-    result = vorbis_dec_handle_header_buffer (vd, buf);
-
-    /* comment header */
-    if (result == GST_FLOW_OK) {
-      value = gst_value_array_get_value (array, 1);
-      buf = gst_value_get_buffer (value);
-      if (!buf)
-        goto null_buffer;
-      result = vorbis_dec_handle_header_buffer (vd, buf);
-    }
+  GstCaps *caps;
+  GstStructure *s;
+  const GValue *array;
+  const GValue *value = NULL;
+  GstBuffer *buf = NULL;
 
-    /* bitstream codebook header */
-    if (result == GST_FLOW_OK) {
-      value = gst_value_array_get_value (array, 2);
-      buf = gst_value_get_buffer (value);
-      if (!buf)
-        goto null_buffer;
-      result = vorbis_dec_handle_header_buffer (vd, buf);
-    }
-  } else
+  if ((caps = gst_pad_get_current_caps (vd->sinkpad)) == NULL)
+    goto no_caps;
+
+  if ((s = gst_caps_get_structure (caps, 0)) == NULL)
+    goto no_caps;
+
+  array = gst_structure_get_value (s, "streamheader");
+
+  if (array == NULL || (gst_value_array_get_size (array) < MIN_NUM_HEADERS))
     goto array_error;
 
-done:
-  return (result != GST_FLOW_OK ? GST_FLOW_NOT_NEGOTIATED : GST_FLOW_OK);
+  /* initial header */
+  value = gst_value_array_get_value (array, 0);
+  buf = gst_value_get_buffer (value);
+  if (!buf)
+    goto null_buffer;
+  result = vorbis_dec_handle_header_buffer (vd, buf);
+  if (result != GST_FLOW_OK)
+    goto buffer_error;
+
+  /* comment header */
+  value = gst_value_array_get_value (array, 1);
+  buf = gst_value_get_buffer (value);
+  if (!buf)
+    goto null_buffer;
+  result = vorbis_dec_handle_header_buffer (vd, buf);
+  if (result != GST_FLOW_OK)
+    goto buffer_error;
+
+  /* bitstream codebook header */
+  value = gst_value_array_get_value (array, 2);
+  buf = gst_value_get_buffer (value);
+  if (!buf)
+    goto null_buffer;
+  result = vorbis_dec_handle_header_buffer (vd, buf);
+  if (result != GST_FLOW_OK)
+    goto buffer_error;
 
+  return result;
+
+no_caps:
+  {
+    GST_WARNING_OBJECT (vd, "no caps negotiated");
+    return GST_FLOW_NOT_NEGOTIATED;
+  }
 array_error:
   {
     GST_WARNING_OBJECT (vd, "streamheader array not found");
-    result = GST_FLOW_ERROR;
-    goto done;
+    return GST_FLOW_NOT_NEGOTIATED;
   }
-
 null_buffer:
   {
     GST_WARNING_OBJECT (vd, "streamheader with null buffer received");
-    result = GST_FLOW_ERROR;
-    goto done;
+    return GST_FLOW_NOT_NEGOTIATED;
+  }
+buffer_error:
+  {
+    GST_WARNING_OBJECT (vd, "error handling buffer");
+    return GST_FLOW_NOT_NEGOTIATED;
   }
 }
 
@@ -1076,7 +1077,7 @@ vorbis_dec_decode_buffer (GstVorbisDec * vd, GstBuffer * buffer)
   GstFlowReturn result = GST_FLOW_OK;
 
   /* make ogg_packet out of the buffer */
-  gst_ogg_packet_wrapper_from_buffer (&packet_wrapper, buffer);
+  gst_ogg_packet_wrapper_map (&packet_wrapper, buffer);
   packet = gst_ogg_packet_from_wrapper (&packet_wrapper);
   /* set some more stuff */
   packet->granulepos = -1;
@@ -1119,6 +1120,8 @@ vorbis_dec_decode_buffer (GstVorbisDec * vd, GstBuffer * buffer)
   }
 
 done:
+  gst_ogg_packet_wrapper_unmap (&packet_wrapper, buffer);
+
   return result;
 
 empty_buffer:
@@ -1282,7 +1285,7 @@ vorbis_dec_chain_reverse (GstVorbisDec * vd, gboolean discont, GstBuffer * buf)
   if (G_LIKELY (buf)) {
     GST_DEBUG_OBJECT (vd,
         "gathering buffer %p of size %u, time %" GST_TIME_FORMAT
-        ", dur %" GST_TIME_FORMAT, buf, GST_BUFFER_SIZE (buf),
+        ", dur %" GST_TIME_FORMAT, buf, gst_buffer_get_size (buf),
         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
         GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
 
@@ -1358,7 +1361,7 @@ vorbis_dec_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
-  res = parent_class->change_state (element, transition);
+  res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 
   switch (transition) {
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
index ca00af9..2e39422 100644 (file)
@@ -60,10 +60,18 @@ gst_ogg_packet_size (ogg_packet * p)
 }
 
 static inline void
-gst_ogg_packet_wrapper_from_buffer (ogg_packet * packet, GstBuffer * buffer)
+gst_ogg_packet_wrapper_map (ogg_packet * packet, GstBuffer * buffer)
 {
-  packet->packet = GST_BUFFER_DATA (buffer);
-  packet->bytes = GST_BUFFER_SIZE (buffer);
+  gsize size;
+
+  packet->packet = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+  packet->bytes = size;
+}
+
+static inline void
+gst_ogg_packet_wrapper_unmap (ogg_packet * packet, GstBuffer * buffer)
+{
+  gst_buffer_unmap (buffer, packet->packet, packet->bytes);
 }
 
 static inline ogg_packet *
@@ -127,14 +135,15 @@ gst_ogg_packet_size (ogg_packet * p)
 }
 
 static inline void
-gst_ogg_packet_wrapper_from_buffer (ogg_packet_wrapper * packet,
+gst_ogg_packet_wrapper_map (ogg_packet_wrapper * packet,
     GstBuffer * buffer)
 {
   ogg_reference *ref = &packet->ref;
   ogg_buffer *buf = &packet->buf;
+  gsize size;
 
-  buf->data = GST_BUFFER_DATA (buffer);
-  buf->size = GST_BUFFER_SIZE (buffer);
+  buf->data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+  buf->size = size;
   buf->refcount = 1;
   buf->ptr.owner = NULL;
   buf->ptr.next = NULL;
@@ -148,6 +157,16 @@ gst_ogg_packet_wrapper_from_buffer (ogg_packet_wrapper * packet,
   packet->packet.bytes = ref->length;
 }
 
+static inline void
+gst_ogg_packet_wrapper_unmap (ogg_packet_wrapper * packet,
+    GstBuffer * buffer)
+{
+  ogg_reference *ref = &packet->ref;
+  ogg_buffer *buf = &packet->buf;
+
+  gst_buffer_unmap (buffer, buf->data, buf->size);
+}
+
 static inline ogg_packet *
 gst_ogg_packet_from_wrapper (ogg_packet_wrapper * packet)
 {
index 9cdf484..ffa796b 100644 (file)
@@ -132,8 +132,9 @@ static GstStateChangeReturn gst_vorbis_enc_change_state (GstElement * element,
     GstStateChange transition);
 static void gst_vorbis_enc_add_interfaces (GType vorbisenc_type);
 
-GST_BOILERPLATE_FULL (GstVorbisEnc, gst_vorbis_enc, GstElement,
-    GST_TYPE_ELEMENT, gst_vorbis_enc_add_interfaces);
+#define gst_vorbis_enc_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstVorbisEnc, gst_vorbis_enc,
+    GST_TYPE_ELEMENT, gst_vorbis_enc_add_interfaces (g_define_type_id));
 
 static void
 gst_vorbis_enc_add_interfaces (GType vorbisenc_type)
@@ -147,24 +148,6 @@ gst_vorbis_enc_add_interfaces (GType vorbisenc_type)
 }
 
 static void
-gst_vorbis_enc_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-  GstPadTemplate *src_template, *sink_template;
-
-
-  src_template = gst_static_pad_template_get (&vorbis_enc_src_factory);
-  gst_element_class_add_pad_template (element_class, src_template);
-
-  sink_template = gst_static_pad_template_get (&vorbis_enc_sink_factory);
-  gst_element_class_add_pad_template (element_class, sink_template);
-  gst_element_class_set_details_simple (element_class,
-      "Vorbis audio encoder", "Codec/Encoder/Audio",
-      "Encodes audio in Vorbis format",
-      "Monty <monty@xiph.org>, " "Wim Taymans <wim@fluendo.com>");
-}
-
-static void
 gst_vorbis_enc_class_init (GstVorbisEncClass * klass)
 {
   GObjectClass *gobject_class;
@@ -208,6 +191,15 @@ gst_vorbis_enc_class_init (GstVorbisEncClass * klass)
           "The last status message", NULL,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&vorbis_enc_src_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&vorbis_enc_sink_factory));
+  gst_element_class_set_details_simple (gstelement_class,
+      "Vorbis audio encoder", "Codec/Encoder/Audio",
+      "Encodes audio in Vorbis format",
+      "Monty <monty@xiph.org>, " "Wim Taymans <wim@fluendo.com>");
+
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_vorbis_enc_change_state);
 }
@@ -277,14 +269,18 @@ gst_vorbis_enc_generate_sink_caps (void)
 }
 
 static GstCaps *
-gst_vorbis_enc_sink_getcaps (GstPad * pad)
+gst_vorbis_enc_sink_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstVorbisEnc *vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
 
   if (vorbisenc->sinkcaps == NULL)
     vorbisenc->sinkcaps = gst_vorbis_enc_generate_sink_caps ();
 
-  return gst_caps_ref (vorbisenc->sinkcaps);
+  if (filter)
+    return gst_caps_intersect_full (filter, vorbisenc->sinkcaps,
+        GST_CAPS_INTERSECT_FIRST);
+  else
+    return gst_caps_ref (vorbisenc->sinkcaps);
 }
 
 static gboolean
@@ -570,7 +566,7 @@ error:
 }
 
 static void
-gst_vorbis_enc_init (GstVorbisEnc * vorbisenc, GstVorbisEncClass * klass)
+gst_vorbis_enc_init (GstVorbisEnc * vorbisenc)
 {
   vorbisenc->sinkpad =
       gst_pad_new_from_static_template (&vorbis_enc_sink_factory, "sink");
@@ -826,7 +822,7 @@ gst_vorbis_enc_buffer_from_packet (GstVorbisEnc * vorbisenc,
   GstBuffer *outbuf;
 
   outbuf = gst_buffer_new_and_alloc (packet->bytes);
-  memcpy (GST_BUFFER_DATA (outbuf), packet->packet, packet->bytes);
+  gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
   /* see ext/ogg/README; OFFSET_END takes "our" granulepos, OFFSET its
    * time representation */
   GST_BUFFER_OFFSET_END (outbuf) = packet->granulepos +
@@ -838,8 +834,7 @@ gst_vorbis_enc_buffer_from_packet (GstVorbisEnc * vorbisenc,
   /* update the next timestamp, taking granulepos_offset and subgranule offset
    * into account */
   vorbisenc->next_ts =
-      granulepos_to_timestamp_offset (vorbisenc, packet->granulepos) +
-      vorbisenc->initial_ts;
+      granulepos_to_timestamp_offset (vorbisenc, packet->granulepos);
   GST_BUFFER_DURATION (outbuf) =
       vorbisenc->next_ts - GST_BUFFER_TIMESTAMP (outbuf);
 
@@ -848,10 +843,8 @@ gst_vorbis_enc_buffer_from_packet (GstVorbisEnc * vorbisenc,
     vorbisenc->next_discont = FALSE;
   }
 
-  gst_buffer_set_caps (outbuf, vorbisenc->srccaps);
-
   GST_LOG_OBJECT (vorbisenc, "encoded buffer of %d bytes",
-      GST_BUFFER_SIZE (outbuf));
+      gst_buffer_get_size (outbuf));
   return outbuf;
 }
 
@@ -864,16 +857,14 @@ gst_vorbis_enc_buffer_from_header_packet (GstVorbisEnc * vorbisenc,
   GstBuffer *outbuf;
 
   outbuf = gst_buffer_new_and_alloc (packet->bytes);
-  memcpy (GST_BUFFER_DATA (outbuf), packet->packet, packet->bytes);
+  gst_buffer_fill (outbuf, 0, packet->packet, packet->bytes);
   GST_BUFFER_OFFSET (outbuf) = vorbisenc->bytes_out;
   GST_BUFFER_OFFSET_END (outbuf) = 0;
   GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
   GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
 
-  gst_buffer_set_caps (outbuf, vorbisenc->srccaps);
-
   GST_DEBUG ("created header packet buffer, %d bytes",
-      GST_BUFFER_SIZE (outbuf));
+      gst_buffer_get_size (outbuf));
   return outbuf;
 }
 
@@ -881,7 +872,7 @@ gst_vorbis_enc_buffer_from_header_packet (GstVorbisEnc * vorbisenc,
 static GstFlowReturn
 gst_vorbis_enc_push_buffer (GstVorbisEnc * vorbisenc, GstBuffer * buffer)
 {
-  vorbisenc->bytes_out += GST_BUFFER_SIZE (buffer);
+  vorbisenc->bytes_out += gst_buffer_get_size (buffer);
 
   GST_DEBUG_OBJECT (vorbisenc,
       "Pushing buffer with GP %" G_GINT64_FORMAT ", ts %" GST_TIME_FORMAT,
@@ -975,23 +966,14 @@ gst_vorbis_enc_sink_event (GstPad * pad, GstEvent * event)
       }
       res = gst_pad_push_event (vorbisenc->srcpad, event);
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      gboolean update;
-      gdouble rate, applied_rate;
-      GstFormat format;
-      gint64 start, stop, position;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
-          &format, &start, &stop, &position);
-      if (format == GST_FORMAT_TIME) {
-        gst_segment_set_newsegment (&vorbisenc->segment, update, rate, format,
-            start, stop, position);
-        if (vorbisenc->initial_ts == GST_CLOCK_TIME_NONE) {
-          GST_DEBUG_OBJECT (vorbisenc, "Initial segment %" GST_SEGMENT_FORMAT,
-              &vorbisenc->segment);
-          vorbisenc->initial_ts = start;
-        }
+      const GstSegment *segment;
+
+      gst_event_parse_segment (event, &segment);
+
+      if (segment->format == GST_FORMAT_TIME) {
+        gst_segment_copy_into (segment, &vorbisenc->segment);
       }
     }
       /* fall through */
@@ -1008,6 +990,10 @@ gst_vorbis_enc_buffer_check_discontinuous (GstVorbisEnc * vorbisenc,
 {
   gboolean ret = FALSE;
 
+  GST_DEBUG_OBJECT (vorbisenc, "exp %" GST_TIME_FORMAT " time %" GST_TIME_FORMAT
+      "dur %" GST_TIME_FORMAT, GST_TIME_ARGS (vorbisenc->expected_ts),
+      GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));
+
   if (timestamp != GST_CLOCK_TIME_NONE &&
       vorbisenc->expected_ts != GST_CLOCK_TIME_NONE &&
       timestamp + duration != vorbisenc->expected_ts) {
@@ -1038,7 +1024,7 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
 {
   GstVorbisEnc *vorbisenc;
   GstFlowReturn ret = GST_FLOW_OK;
-  gfloat *data;
+  gfloat *data, *ptr;
   gulong size;
   gulong i, j;
   float **vorbis_buffer;
@@ -1046,6 +1032,7 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
   gboolean first = FALSE;
   GstClockTime timestamp = GST_CLOCK_TIME_NONE;
   GstClockTime running_time = GST_CLOCK_TIME_NONE;
+  gsize bsize;
 
   vorbisenc = GST_VORBISENC (GST_PAD_PARENT (pad));
 
@@ -1061,9 +1048,9 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
   running_time =
       gst_segment_to_running_time (&vorbisenc->segment, GST_FORMAT_TIME,
       GST_BUFFER_TIMESTAMP (buffer));
-  timestamp = running_time + vorbisenc->initial_ts;
-  GST_DEBUG_OBJECT (vorbisenc, "Initial ts is %" GST_TIME_FORMAT,
-      GST_TIME_ARGS (vorbisenc->initial_ts));
+  timestamp = running_time;
+  GST_DEBUG_OBJECT (vorbisenc, " timestamp %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (timestamp));
   if (!vorbisenc->header_sent) {
     /* Vorbis streams begin with three headers; the initial header (with
        most of the codec setup parameters) which is mandated by the Ogg
@@ -1101,10 +1088,6 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
     GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
     gst_pad_set_caps (vorbisenc->srcpad, caps);
 
-    gst_buffer_set_caps (buf1, caps);
-    gst_buffer_set_caps (buf2, caps);
-    gst_buffer_set_caps (buf3, caps);
-
     /* push out buffers */
     /* push_buffer takes the reference even for failure */
     if ((ret = gst_vorbis_enc_push_buffer (vorbisenc, buf1)) != GST_FLOW_OK)
@@ -1126,8 +1109,7 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
         (running_time, vorbisenc->frequency, GST_SECOND);
     vorbisenc->subgranule_offset = 0;
     vorbisenc->subgranule_offset =
-        (vorbisenc->next_ts - vorbisenc->initial_ts) -
-        granulepos_to_timestamp_offset (vorbisenc, 0);
+        vorbisenc->next_ts - granulepos_to_timestamp_offset (vorbisenc, 0);
 
     vorbisenc->header_sent = TRUE;
     first = TRUE;
@@ -1137,22 +1119,24 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
       timestamp < vorbisenc->expected_ts) {
     guint64 diff = vorbisenc->expected_ts - timestamp;
     guint64 diff_bytes;
+    gsize size;
 
     GST_WARNING_OBJECT (vorbisenc, "Buffer is older than previous "
         "timestamp + duration (%" GST_TIME_FORMAT "< %" GST_TIME_FORMAT
         "), cannot handle. Clipping buffer.",
         GST_TIME_ARGS (timestamp), GST_TIME_ARGS (vorbisenc->expected_ts));
 
+    size = gst_buffer_get_size (buffer);
+
     diff_bytes =
         GST_CLOCK_TIME_TO_FRAMES (diff,
         vorbisenc->frequency) * vorbisenc->channels * sizeof (gfloat);
-    if (diff_bytes >= GST_BUFFER_SIZE (buffer)) {
+    if (diff_bytes >= size) {
       gst_buffer_unref (buffer);
       return GST_FLOW_OK;
     }
-    buffer = gst_buffer_make_metadata_writable (buffer);
-    GST_BUFFER_DATA (buffer) += diff_bytes;
-    GST_BUFFER_SIZE (buffer) -= diff_bytes;
+    buffer = gst_buffer_make_writable (buffer);
+    gst_buffer_resize (buffer, diff_bytes, size - diff_bytes);
 
     GST_BUFFER_TIMESTAMP (buffer) += diff;
     if (GST_BUFFER_DURATION_IS_VALID (buffer))
@@ -1187,14 +1171,17 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
   }
 
   /* Sending zero samples to libvorbis marks EOS, so we mustn't do that */
-  if (GST_BUFFER_SIZE (buffer) == 0) {
+  data = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_WRITE);
+  if (bsize == 0) {
+    gst_buffer_unmap (buffer, data, bsize);
     gst_buffer_unref (buffer);
     return GST_FLOW_OK;
   }
 
   /* data to encode */
-  data = (gfloat *) GST_BUFFER_DATA (buffer);
-  size = GST_BUFFER_SIZE (buffer) / (vorbisenc->channels * sizeof (float));
+  size = bsize / (vorbisenc->channels * sizeof (float));
+
+  ptr = data;
 
   /* expose the buffer to submit data */
   vorbis_buffer = vorbis_analysis_buffer (&vorbisenc->vd, size);
@@ -1202,12 +1189,13 @@ gst_vorbis_enc_chain (GstPad * pad, GstBuffer * buffer)
   /* deinterleave samples, write the buffer data */
   for (i = 0; i < size; i++) {
     for (j = 0; j < vorbisenc->channels; j++) {
-      vorbis_buffer[j][i] = *data++;
+      vorbis_buffer[j][i] = *ptr++;
     }
   }
 
   /* tell the library how much we actually submitted */
   vorbis_analysis_wrote (&vorbisenc->vd, size);
+  gst_buffer_unmap (buffer, data, bsize);
 
   GST_LOG_OBJECT (vorbisenc, "wrote %lu samples to vorbis", size);
 
@@ -1392,7 +1380,6 @@ gst_vorbis_enc_change_state (GstElement * element, GstStateChange transition)
       vorbisenc->next_discont = FALSE;
       vorbisenc->header_sent = FALSE;
       gst_segment_init (&vorbisenc->segment, GST_FORMAT_TIME);
-      vorbisenc->initial_ts = GST_CLOCK_TIME_NONE;
       break;
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
       break;
index 9375a16..840f2bd 100644 (file)
@@ -81,7 +81,6 @@ struct _GstVorbisEnc {
   guint64          granulepos_offset;
   gint64           subgranule_offset;
   GstSegment       segment;
-  GstClockTime     initial_ts;
 
   GstTagList *     tags;
 
index 53fd7b1..f3fccfd 100644 (file)
@@ -72,8 +72,8 @@ GST_STATIC_PAD_TEMPLATE ("src",
     GST_STATIC_CAPS ("audio/x-vorbis")
     );
 
-GST_BOILERPLATE (GstVorbisParse, gst_vorbis_parse, GstElement,
-    GST_TYPE_ELEMENT);
+#define gst_vorbis_parse_parent_class parent_class
+G_DEFINE_TYPE (GstVorbisParse, gst_vorbis_parse, GST_TYPE_ELEMENT);
 
 static GstFlowReturn vorbis_parse_chain (GstPad * pad, GstBuffer * buffer);
 static GstStateChangeReturn vorbis_parse_change_state (GstElement * element,
@@ -87,32 +87,26 @@ static GstFlowReturn vorbis_parse_parse_packet (GstVorbisParse * parse,
     GstBuffer * buf);
 
 static void
-gst_vorbis_parse_base_init (gpointer g_class)
+gst_vorbis_parse_class_init (GstVorbisParseClass * klass)
 {
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+
+  gstelement_class->change_state = vorbis_parse_change_state;
 
-  gst_element_class_add_pad_template (element_class,
+  gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&vorbis_parse_src_factory));
-  gst_element_class_add_pad_template (element_class,
+  gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&vorbis_parse_sink_factory));
-  gst_element_class_set_details_simple (element_class,
+  gst_element_class_set_details_simple (gstelement_class,
       "VorbisParse", "Codec/Parser/Audio",
       "parse raw vorbis streams",
       "Thomas Vander Stichele <thomas at apestaart dot org>");
-}
-
-static void
-gst_vorbis_parse_class_init (GstVorbisParseClass * klass)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
-
-  gstelement_class->change_state = vorbis_parse_change_state;
 
   klass->parse_packet = GST_DEBUG_FUNCPTR (vorbis_parse_parse_packet);
 }
 
 static void
-gst_vorbis_parse_init (GstVorbisParse * parse, GstVorbisParseClass * g_class)
+gst_vorbis_parse_init (GstVorbisParse * parse)
 {
   parse->sinkpad =
       gst_pad_new_from_static_template (&vorbis_parse_sink_factory, "sink");
@@ -191,57 +185,55 @@ vorbis_parse_push_headers (GstVorbisParse * parse)
   GstCaps *caps;
   GstBuffer *outbuf, *outbuf1, *outbuf2, *outbuf3;
   ogg_packet packet;
+  gsize size;
 
   /* get the headers into the caps, passing them to vorbis as we go */
-  caps = gst_caps_make_writable (gst_pad_get_caps (parse->srcpad));
+  caps = gst_caps_make_writable (gst_pad_get_caps (parse->srcpad, NULL));
   vorbis_parse_set_header_on_caps (parse, caps);
   GST_DEBUG_OBJECT (parse, "here are the caps: %" GST_PTR_FORMAT, caps);
   gst_pad_set_caps (parse->srcpad, caps);
   gst_caps_unref (caps);
 
   outbuf = GST_BUFFER_CAST (parse->streamheader->data);
-  packet.packet = GST_BUFFER_DATA (outbuf);
-  packet.bytes = GST_BUFFER_SIZE (outbuf);
+  packet.packet = gst_buffer_map (outbuf, &size, NULL, GST_MAP_READ);
+  packet.bytes = size;
   packet.granulepos = GST_BUFFER_OFFSET_END (outbuf);
   packet.packetno = 1;
   packet.e_o_s = 0;
   packet.b_o_s = 1;
   vorbis_synthesis_headerin (&parse->vi, &parse->vc, &packet);
+  gst_buffer_unmap (outbuf, packet.packet, size);
   parse->sample_rate = parse->vi.rate;
   outbuf1 = outbuf;
 
   outbuf = GST_BUFFER_CAST (parse->streamheader->next->data);
-  packet.packet = GST_BUFFER_DATA (outbuf);
-  packet.bytes = GST_BUFFER_SIZE (outbuf);
+  packet.packet = gst_buffer_map (outbuf, &size, NULL, GST_MAP_READ);
+  packet.bytes = size;
   packet.granulepos = GST_BUFFER_OFFSET_END (outbuf);
   packet.packetno = 2;
   packet.e_o_s = 0;
   packet.b_o_s = 0;
   vorbis_synthesis_headerin (&parse->vi, &parse->vc, &packet);
+  gst_buffer_unmap (outbuf, packet.packet, size);
   outbuf2 = outbuf;
 
   outbuf = GST_BUFFER_CAST (parse->streamheader->next->next->data);
-  packet.packet = GST_BUFFER_DATA (outbuf);
-  packet.bytes = GST_BUFFER_SIZE (outbuf);
+  packet.packet = gst_buffer_map (outbuf, &size, NULL, GST_MAP_READ);
+  packet.bytes = size;
   packet.granulepos = GST_BUFFER_OFFSET_END (outbuf);
   packet.packetno = 3;
   packet.e_o_s = 0;
   packet.b_o_s = 0;
   vorbis_synthesis_headerin (&parse->vi, &parse->vc, &packet);
+  gst_buffer_unmap (outbuf, packet.packet, size);
   outbuf3 = outbuf;
 
   /* first process queued events */
   vorbis_parse_drain_event_queue (parse);
 
   /* push out buffers, ignoring return value... */
-  outbuf1 = gst_buffer_make_metadata_writable (outbuf1);
-  gst_buffer_set_caps (outbuf1, GST_PAD_CAPS (parse->srcpad));
   gst_pad_push (parse->srcpad, outbuf1);
-  outbuf2 = gst_buffer_make_metadata_writable (outbuf2);
-  gst_buffer_set_caps (outbuf2, GST_PAD_CAPS (parse->srcpad));
   gst_pad_push (parse->srcpad, outbuf2);
-  outbuf3 = gst_buffer_make_metadata_writable (outbuf3);
-  gst_buffer_set_caps (outbuf3, GST_PAD_CAPS (parse->srcpad));
   gst_pad_push (parse->srcpad, outbuf3);
 
   g_list_free (parse->streamheader);
@@ -280,8 +272,6 @@ vorbis_parse_push_buffer (GstVorbisParse * parse, GstBuffer * buf,
   GST_BUFFER_TIMESTAMP (buf) =
       GST_BUFFER_OFFSET (buf) - GST_BUFFER_DURATION (buf);
 
-  gst_buffer_set_caps (buf, GST_PAD_CAPS (parse->srcpad));
-
   return gst_pad_push (parse->srcpad, buf);
 }
 
@@ -358,16 +348,18 @@ vorbis_parse_queue_buffer (GstVorbisParse * parse, GstBuffer * buf)
   GstFlowReturn ret = GST_FLOW_OK;
   long blocksize;
   ogg_packet packet;
+  gsize size;
 
-  buf = gst_buffer_make_metadata_writable (buf);
+  buf = gst_buffer_make_writable (buf);
 
-  packet.packet = GST_BUFFER_DATA (buf);
-  packet.bytes = GST_BUFFER_SIZE (buf);
+  packet.packet = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  packet.bytes = size;
   packet.granulepos = GST_BUFFER_OFFSET_END (buf);
   packet.packetno = parse->packetno + parse->buffer_queue->length;
   packet.e_o_s = 0;
 
   blocksize = vorbis_packet_blocksize (&parse->vi, &packet);
+  gst_buffer_unmap (buf, packet.packet, size);
 
   /* temporarily store the sample count in OFFSET -- we overwrite this later */
 
@@ -391,19 +383,18 @@ vorbis_parse_parse_packet (GstVorbisParse * parse, GstBuffer * buf)
 {
   GstFlowReturn ret;
   guint8 *data;
-  guint size;
+  gsize size;
   gboolean have_header;
 
-  data = GST_BUFFER_DATA (buf);
-  size = GST_BUFFER_SIZE (buf);
-
   parse->packetno++;
 
   have_header = FALSE;
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
   if (size >= 1) {
     if (data[0] >= 0x01 && data[0] <= 0x05)
       have_header = TRUE;
   }
+  gst_buffer_unmap (buf, data, size);
 
   if (have_header) {
     if (!parse->streamheader_sent) {
@@ -650,7 +641,7 @@ vorbis_parse_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
-  ret = parent_class->change_state (element, transition);
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 
   switch (transition) {
     case GST_STATE_CHANGE_PAUSED_TO_READY:
index 8a2db41..60dc485 100644 (file)
@@ -63,41 +63,25 @@ GST_DEBUG_CATEGORY_EXTERN (vorbisparse_debug);
 static GstFlowReturn gst_vorbis_tag_parse_packet (GstVorbisParse * parse,
     GstBuffer * buffer);
 
-#define _do_init(type)                                                          \
-  G_STMT_START{                                                                 \
-    static const GInterfaceInfo tag_setter_info = {                             \
-      NULL,                                                                     \
-      NULL,                                                                     \
-      NULL                                                                      \
-    };                                                                          \
-    g_type_add_interface_static (type, GST_TYPE_TAG_SETTER,                     \
-                                 &tag_setter_info);                             \
-  }G_STMT_END
-
-GST_BOILERPLATE_FULL (GstVorbisTag, gst_vorbis_tag, GstVorbisParse,
-    GST_TYPE_VORBIS_PARSE, _do_init);
-
+#define gst_vorbis_tag_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstVorbisTag, gst_vorbis_tag,
+    GST_TYPE_VORBIS_PARSE, G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL));
 
 static void
-gst_vorbis_tag_base_init (gpointer g_class)
+gst_vorbis_tag_class_init (GstVorbisTagClass * klass)
 {
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+  GstVorbisParseClass *vorbisparse_class = GST_VORBIS_PARSE_CLASS (klass);
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
   gst_element_class_set_details_simple (element_class,
       "VorbisTag", "Formatter/Metadata",
       "Retags vorbis streams", "James Livingston <doclivingston@gmail.com>");
-}
-
-static void
-gst_vorbis_tag_class_init (GstVorbisTagClass * klass)
-{
-  GstVorbisParseClass *vorbisparse_class = GST_VORBIS_PARSE_CLASS (klass);
 
   vorbisparse_class->parse_packet = gst_vorbis_tag_parse_packet;
 }
 
 static void
-gst_vorbis_tag_init (GstVorbisTag * tagger, GstVorbisTagClass * g_class)
+gst_vorbis_tag_init (GstVorbisTag * tagger)
 {
   /* nothing to do */
 }
@@ -111,9 +95,17 @@ gst_vorbis_tag_parse_packet (GstVorbisParse * parse, GstBuffer * buffer)
   GstVorbisTag *tagger;
   gchar *encoder = NULL;
   GstBuffer *new_buf;
+  guint8 *data;
+  gsize size;
+  gboolean do_parse = FALSE;
 
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
   /* just pass everything except the comments packet */
-  if (GST_BUFFER_SIZE (buffer) >= 1 && GST_BUFFER_DATA (buffer)[0] != 0x03) {
+  if (size >= 1 && data[0] != 0x03)
+    do_parse = TRUE;
+  gst_buffer_unmap (buffer, data, size);
+
+  if (do_parse) {
     return GST_VORBIS_PARSE_CLASS (parent_class)->parse_packet (parse, buffer);
   }
 
@@ -132,7 +124,7 @@ gst_vorbis_tag_parse_packet (GstVorbisParse * parse, GstBuffer * buffer)
   new_buf =
       gst_tag_list_to_vorbiscomment_buffer (new_tags, (guint8 *) "\003vorbis",
       7, encoder);
-  gst_buffer_copy_metadata (new_buf, buffer, GST_BUFFER_COPY_TIMESTAMPS);
+  gst_buffer_copy_into (new_buf, buffer, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
 
   gst_tag_list_free (new_tags);
   g_free (encoder);
index bbd3df7..aff1470 100644 (file)
@@ -14,7 +14,7 @@ BUILT_SOURCES = $(built_sources) $(built_headers)
 nodist_libgstapp_@GST_MAJORMINOR@_la_SOURCES = \
              $(built_sources)
 
-libgstapp_@GST_MAJORMINOR@_la_SOURCES = gstappsrc.c gstappbuffer.c gstappsink.c 
+libgstapp_@GST_MAJORMINOR@_la_SOURCES = gstappsrc.c gstappsink.c 
 libgstapp_@GST_MAJORMINOR@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \
        $(GST_BASE_CFLAGS) $(GST_CFLAGS)
 libgstapp_@GST_MAJORMINOR@_la_LIBADD = $(GST_BASE_LIBS)
@@ -24,7 +24,6 @@ libgstapp_@GST_MAJORMINOR@_la_LIBTOOLFLAGS = --tag=disable-static
 libgstapp_@GST_MAJORMINOR@includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/app
 libgstapp_@GST_MAJORMINOR@include_HEADERS = \
        gstappsrc.h \
-       gstappbuffer.h \
        gstappsink.h
 
 CLEANFILES = $(BUILT_SOURCES)
diff --git a/gst-libs/gst/app/gstappbuffer.c b/gst-libs/gst/app/gstappbuffer.c
deleted file mode 100644 (file)
index 2fa72bb..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/* GStreamer
- * Copyright (C) 2007 David Schleef <ds@schleef.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gst/gst.h>
-#include <gst/base/gstpushsrc.h>
-
-#include <string.h>
-
-#include "gstappbuffer.h"
-
-static void gst_app_buffer_init (GstAppBuffer * buffer, gpointer g_class);
-static void gst_app_buffer_class_init (gpointer g_class, gpointer class_data);
-static void gst_app_buffer_finalize (GstAppBuffer * buffer);
-
-static GstBufferClass *parent_class;
-
-GType
-gst_app_buffer_get_type (void)
-{
-  static volatile gsize app_buffer_type = 0;
-
-  if (g_once_init_enter (&app_buffer_type)) {
-    static const GTypeInfo app_buffer_info = {
-      sizeof (GstBufferClass),
-      NULL,
-      NULL,
-      gst_app_buffer_class_init,
-      NULL,
-      NULL,
-      sizeof (GstAppBuffer),
-      0,
-      (GInstanceInitFunc) gst_app_buffer_init,
-      NULL
-    };
-    GType tmp = g_type_register_static (GST_TYPE_BUFFER, "GstAppBuffer",
-        &app_buffer_info, 0);
-    g_once_init_leave (&app_buffer_type, tmp);
-  }
-
-  return (GType) app_buffer_type;
-}
-
-static void
-gst_app_buffer_init (GstAppBuffer * buffer, gpointer g_class)
-{
-
-}
-
-static void
-gst_app_buffer_class_init (gpointer g_class, gpointer class_data)
-{
-  GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
-
-  mini_object_class->finalize =
-      (GstMiniObjectFinalizeFunction) gst_app_buffer_finalize;
-
-  parent_class = g_type_class_peek_parent (g_class);
-}
-
-static void
-gst_app_buffer_finalize (GstAppBuffer * buffer)
-{
-  g_return_if_fail (buffer != NULL);
-  g_return_if_fail (GST_IS_APP_BUFFER (buffer));
-
-  if (buffer->finalize) {
-    buffer->finalize (buffer->priv);
-  }
-
-  GST_MINI_OBJECT_CLASS (parent_class)->finalize (GST_MINI_OBJECT (buffer));
-}
-
-GstBuffer *
-gst_app_buffer_new (void *data, int length,
-    GstAppBufferFinalizeFunc finalize, void *priv)
-{
-  GstAppBuffer *buffer;
-
-  buffer = (GstAppBuffer *) gst_mini_object_new (GST_TYPE_APP_BUFFER);
-
-  GST_BUFFER_DATA (buffer) = data;
-  GST_BUFFER_SIZE (buffer) = length;
-
-  buffer->finalize = finalize;
-  buffer->priv = priv;
-
-  return GST_BUFFER (buffer);
-}
diff --git a/gst-libs/gst/app/gstappbuffer.h b/gst-libs/gst/app/gstappbuffer.h
deleted file mode 100644 (file)
index 532f2ae..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* GStreamer
- * Copyright (C) 2007 David Schleef <ds@schleef.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _GST_APP_BUFFER_H_
-#define _GST_APP_BUFFER_H_
-
-#include <gst/gst.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_APP_BUFFER \
-  (gst_app_buffer_get_type())
-#define GST_APP_BUFFER(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_APP_BUFFER,GstAppBuffer))
-#define GST_APP_BUFFER_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_APP_BUFFER,GstAppBufferClass))
-#define GST_IS_APP_BUFFER(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_APP_BUFFER))
-#define GST_IS_APP_BUFFER_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_APP_BUFFER))
-
-typedef struct _GstAppBuffer GstAppBuffer;
-typedef struct _GstAppBufferClass GstAppBufferClass;
-typedef void (*GstAppBufferFinalizeFunc) (void *priv);
-
-struct _GstAppBuffer
-{
-  GstBuffer buffer;
-
-  /*< private >*/
-  GstAppBufferFinalizeFunc finalize;
-  void *priv;
-};
-
-struct _GstAppBufferClass
-{
-  GstBufferClass buffer_class;
-};
-
-GType gst_app_buffer_get_type(void);
-
-GstBuffer *gst_app_buffer_new (void *data, int length,
-    GstAppBufferFinalizeFunc finalize, void *priv);
-
-G_END_DECLS
-
-#endif
-
index 39e3def..4e69069 100644 (file)
@@ -164,25 +164,15 @@ static GstFlowReturn gst_app_sink_render (GstBaseSink * psink,
     GstBuffer * buffer);
 static GstFlowReturn gst_app_sink_render_list (GstBaseSink * psink,
     GstBufferList * list);
-static GstCaps *gst_app_sink_getcaps (GstBaseSink * psink);
+static GstCaps *gst_app_sink_getcaps (GstBaseSink * psink, GstCaps * filter);
 static GstMiniObject *gst_app_sink_pull_object (GstAppSink * appsink);
 
 static guint gst_app_sink_signals[LAST_SIGNAL] = { 0 };
 
-static void
-_do_init (GType filesrc_type)
-{
-  static const GInterfaceInfo urihandler_info = {
-    gst_app_sink_uri_handler_init,
-    NULL,
-    NULL
-  };
-  g_type_add_interface_static (filesrc_type, GST_TYPE_URI_HANDLER,
-      &urihandler_info);
-}
-
-GST_BOILERPLATE_FULL (GstAppSink, gst_app_sink, GstBaseSink, GST_TYPE_BASE_SINK,
-    _do_init);
+#define gst_app_sink_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstAppSink, gst_app_sink, GST_TYPE_BASE_SINK,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
+        gst_app_sink_uri_handler_init));
 
 /* Can't use glib-genmarshal for this, as it doesn't know how to handle
  * GstMiniObject-based types, which are a new fundamental type */
@@ -219,26 +209,14 @@ gst_app_marshal_BUFFER__VOID (GClosure * closure,
 }
 
 static void
-gst_app_sink_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  GST_DEBUG_CATEGORY_INIT (app_sink_debug, "appsink", 0, "appsink element");
-
-  gst_element_class_set_details_simple (element_class, "AppSink",
-      "Generic/Sink", "Allow the application to get access to raw buffer",
-      "David Schleef <ds@schleef.org>, Wim Taymans <wim.taymans@gmail.com>");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_app_sink_template));
-}
-
-static void
 gst_app_sink_class_init (GstAppSinkClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstElementClass *element_class = (GstElementClass *) klass;
   GstBaseSinkClass *basesink_class = (GstBaseSinkClass *) klass;
 
+  GST_DEBUG_CATEGORY_INIT (app_sink_debug, "appsink", 0, "appsink element");
+
   gobject_class->dispose = gst_app_sink_dispose;
   gobject_class->finalize = gst_app_sink_finalize;
 
@@ -425,6 +403,13 @@ gst_app_sink_class_init (GstAppSinkClass * klass)
           pull_buffer_list), NULL, NULL, gst_app_marshal_BUFFER__VOID,
       GST_TYPE_BUFFER_LIST, 0, G_TYPE_NONE);
 
+  gst_element_class_set_details_simple (element_class, "AppSink",
+      "Generic/Sink", "Allow the application to get access to raw buffer",
+      "David Schleef <ds@schleef.org>, Wim Taymans <wim.taymans@gmail.com>");
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_app_sink_template));
+
   basesink_class->unlock = gst_app_sink_unlock_start;
   basesink_class->unlock_stop = gst_app_sink_unlock_stop;
   basesink_class->start = gst_app_sink_start;
@@ -443,7 +428,7 @@ gst_app_sink_class_init (GstAppSinkClass * klass)
 }
 
 static void
-gst_app_sink_init (GstAppSink * appsink, GstAppSinkClass * klass)
+gst_app_sink_init (GstAppSink * appsink)
 {
   GstAppSinkPrivate *priv;
 
@@ -817,10 +802,10 @@ gst_app_sink_render (GstBaseSink * psink, GstBuffer * buffer)
 static GstFlowReturn
 gst_app_sink_render_list (GstBaseSink * sink, GstBufferList * list)
 {
-  GstBufferListIterator *it;
   GstFlowReturn flow;
   GstAppSink *appsink;
-  GstBuffer *group;
+  GstBuffer *buffer;
+  guint i, len;
 
   appsink = GST_APP_SINK_CAST (sink);
 
@@ -831,42 +816,33 @@ gst_app_sink_render_list (GstBaseSink * sink, GstBufferList * list)
    * then and push them one-by-one */
   GST_INFO_OBJECT (sink, "chaining each group in list as a merged buffer");
 
-  it = gst_buffer_list_iterate (list);
+  len = gst_buffer_list_len (list);
 
-  if (gst_buffer_list_iterator_next_group (it)) {
-    do {
-      group = gst_buffer_list_iterator_merge_group (it);
-      if (group == NULL) {
-        group = gst_buffer_new ();
-        GST_DEBUG_OBJECT (sink, "chaining empty group");
-      } else {
-        GST_DEBUG_OBJECT (sink, "chaining group");
-      }
-      flow = gst_app_sink_render (sink, group);
-      gst_buffer_unref (group);
-    } while (flow == GST_FLOW_OK && gst_buffer_list_iterator_next_group (it));
-  } else {
-    GST_DEBUG_OBJECT (sink, "chaining empty group");
-    group = gst_buffer_new ();
-    flow = gst_app_sink_render (sink, group);
-    gst_buffer_unref (group);
+  flow = GST_FLOW_OK;
+  for (i = 0; i < len; i++) {
+    buffer = gst_buffer_list_get (list, i);
+    flow = gst_app_sink_render (sink, buffer);
+    if (flow != GST_FLOW_OK)
+      break;
   }
 
-  gst_buffer_list_iterator_free (it);
-
   return flow;
 }
 
 static GstCaps *
-gst_app_sink_getcaps (GstBaseSink * psink)
+gst_app_sink_getcaps (GstBaseSink * psink, GstCaps * filter)
 {
   GstCaps *caps;
   GstAppSink *appsink = GST_APP_SINK_CAST (psink);
   GstAppSinkPrivate *priv = appsink->priv;
 
   GST_OBJECT_LOCK (appsink);
-  if ((caps = priv->caps))
-    gst_caps_ref (caps);
+  if ((caps = priv->caps)) {
+    if (filter)
+      caps = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+    else
+      gst_caps_ref (caps);
+  }
   GST_DEBUG_OBJECT (appsink, "got caps %" GST_PTR_FORMAT, caps);
   GST_OBJECT_UNLOCK (appsink);
 
index fb72c29..7ba7020 100644 (file)
@@ -234,42 +234,19 @@ static GstFlowReturn gst_app_src_push_buffer_action (GstAppSrc * appsrc,
 
 static guint gst_app_src_signals[LAST_SIGNAL] = { 0 };
 
-static void
-_do_init (GType filesrc_type)
-{
-  static const GInterfaceInfo urihandler_info = {
-    gst_app_src_uri_handler_init,
-    NULL,
-    NULL
-  };
-  g_type_add_interface_static (filesrc_type, GST_TYPE_URI_HANDLER,
-      &urihandler_info);
-}
-
-GST_BOILERPLATE_FULL (GstAppSrc, gst_app_src, GstBaseSrc, GST_TYPE_BASE_SRC,
-    _do_init);
-
-static void
-gst_app_src_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  GST_DEBUG_CATEGORY_INIT (app_src_debug, "appsrc", 0, "appsrc element");
-
-  gst_element_class_set_details_simple (element_class, "AppSrc",
-      "Generic/Source", "Allow the application to feed buffers to a pipeline",
-      "David Schleef <ds@schleef.org>, Wim Taymans <wim.taymans@gmail.com>");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_app_src_template));
-}
+#define gst_app_src_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstAppSrc, gst_app_src, GST_TYPE_BASE_SRC,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, gst_app_src_uri_handler_init));
 
 static void
 gst_app_src_class_init (GstAppSrcClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstElementClass *element_class = (GstElementClass *) klass;
   GstBaseSrcClass *basesrc_class = (GstBaseSrcClass *) klass;
 
+  GST_DEBUG_CATEGORY_INIT (app_src_debug, "appsrc", 0, "appsrc element");
+
   gobject_class->dispose = gst_app_src_dispose;
   gobject_class->finalize = gst_app_src_finalize;
 
@@ -483,6 +460,13 @@ gst_app_src_class_init (GstAppSrcClass * klass)
           end_of_stream), NULL, NULL, __gst_app_marshal_ENUM__VOID,
       GST_TYPE_FLOW_RETURN, 0, G_TYPE_NONE);
 
+  gst_element_class_set_details_simple (element_class, "AppSrc",
+      "Generic/Source", "Allow the application to feed buffers to a pipeline",
+      "David Schleef <ds@schleef.org>, Wim Taymans <wim.taymans@gmail.com>");
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_app_src_template));
+
   basesrc_class->create = gst_app_src_create;
   basesrc_class->start = gst_app_src_start;
   basesrc_class->stop = gst_app_src_stop;
@@ -502,7 +486,7 @@ gst_app_src_class_init (GstAppSrcClass * klass)
 }
 
 static void
-gst_app_src_init (GstAppSrc * appsrc, GstAppSrcClass * klass)
+gst_app_src_init (GstAppSrc * appsrc)
 {
   GstAppSrcPrivate *priv;
 
@@ -837,7 +821,7 @@ gst_app_src_do_seek (GstBaseSrc * src, GstSegment * segment)
   gint64 desired_position;
   gboolean res = FALSE;
 
-  desired_position = segment->last_stop;
+  desired_position = segment->position;
 
   GST_DEBUG_OBJECT (appsrc, "seeking to %" G_GINT64_FORMAT ", format %s",
       desired_position, gst_format_get_name (segment->format));
@@ -935,7 +919,7 @@ gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
     GST_DEBUG_OBJECT (appsrc,
         "Size changed from %" G_GINT64_FORMAT " to %" G_GINT64_FORMAT,
         bsrc->segment.duration, priv->size);
-    gst_segment_set_duration (&bsrc->segment, GST_FORMAT_BYTES, priv->size);
+    bsrc->segment.duration = priv->size;
     GST_OBJECT_UNLOCK (appsrc);
 
     gst_element_post_message (GST_ELEMENT (appsrc),
@@ -973,7 +957,7 @@ gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
       guint buf_size;
 
       *buf = g_queue_pop_head (priv->queue);
-      buf_size = GST_BUFFER_SIZE (*buf);
+      buf_size = gst_buffer_get_size (*buf);
 
       GST_DEBUG_OBJECT (appsrc, "we have buffer %p of size %u", *buf, buf_size);
 
@@ -982,10 +966,6 @@ gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
       /* only update the offset when in random_access mode */
       if (priv->stream_type == GST_APP_STREAM_TYPE_RANDOM_ACCESS)
         priv->offset += buf_size;
-      if (caps) {
-        *buf = gst_buffer_make_metadata_writable (*buf);
-        gst_buffer_set_caps (*buf, caps);
-      }
 
       /* signal that we removed an item */
       g_cond_broadcast (priv->cond);
@@ -1477,7 +1457,7 @@ gst_app_src_push_buffer_full (GstAppSrc * appsrc, GstBuffer * buffer,
   if (!steal_ref)
     gst_buffer_ref (buffer);
   g_queue_push_tail (priv->queue, buffer);
-  priv->queued_bytes += GST_BUFFER_SIZE (buffer);
+  priv->queued_bytes += gst_buffer_get_size (buffer);
   g_cond_broadcast (priv->cond);
   g_mutex_unlock (priv->mutex);
 
index bf99a52..1088ba5 100644 (file)
@@ -49,24 +49,31 @@ gst_audio_frame_byte_size (GstPad * pad)
 
   int width = 0;
   int channels = 0;
-  const GstCaps *caps = NULL;
+  GstCaps *caps;
   GstStructure *structure;
 
   /* get caps of pad */
-  caps = GST_PAD_CAPS (pad);
+  caps = gst_pad_get_current_caps (pad);
 
-  if (caps == NULL) {
-    /* ERROR: could not get caps of pad */
-    g_warning ("gstaudio: could not get caps of pad %s:%s\n",
-        GST_DEBUG_PAD_NAME (pad));
-    return 0;
-  }
+  if (caps == NULL)
+    goto no_caps;
 
   structure = gst_caps_get_structure (caps, 0);
 
   gst_structure_get_int (structure, "width", &width);
   gst_structure_get_int (structure, "channels", &channels);
+  gst_caps_unref (caps);
+
   return (width / 8) * channels;
+
+  /* ERRORS */
+no_caps:
+  {
+    /* ERROR: could not get caps of pad */
+    g_warning ("gstaudio: could not get caps of pad %s:%s\n",
+        GST_DEBUG_PAD_NAME (pad));
+    return 0;
+  }
 }
 
 /**
@@ -93,7 +100,7 @@ gst_audio_frame_length (GstPad * pad, GstBuffer * buf)
   /* FIXME: this function assumes the buffer size to be a whole multiple
    *        of the frame byte size
    */
-  return GST_BUFFER_SIZE (buf) / frame_byte_size;
+  return gst_buffer_get_size (buf) / frame_byte_size;
 }
 
 /**
@@ -113,34 +120,38 @@ gst_audio_duration_from_pad_buffer (GstPad * pad, GstBuffer * buf)
   int width = 0;
   int channels = 0;
   int rate = 0;
-
-  GstClockTime length;
-
-  const GstCaps *caps = NULL;
+  GstCaps *caps;
   GstStructure *structure;
 
   g_assert (GST_IS_BUFFER (buf));
+
   /* get caps of pad */
-  caps = GST_PAD_CAPS (pad);
-  if (caps == NULL) {
+  caps = gst_pad_get_current_caps (pad);
+  if (caps == NULL)
+    goto no_caps;
+
+  structure = gst_caps_get_structure (caps, 0);
+  bytes = gst_buffer_get_size (buf);
+  gst_structure_get_int (structure, "width", &width);
+  gst_structure_get_int (structure, "channels", &channels);
+  gst_structure_get_int (structure, "rate", &rate);
+  gst_caps_unref (caps);
+
+  g_assert (bytes != 0);
+  g_assert (width != 0);
+  g_assert (channels != 0);
+  g_assert (rate != 0);
+
+  return (bytes * 8 * GST_SECOND) / (rate * channels * width);
+
+  /* ERRORS */
+no_caps:
+  {
     /* ERROR: could not get caps of pad */
     g_warning ("gstaudio: could not get caps of pad %s:%s\n",
         GST_DEBUG_PAD_NAME (pad));
-    length = GST_CLOCK_TIME_NONE;
-  } else {
-    structure = gst_caps_get_structure (caps, 0);
-    bytes = GST_BUFFER_SIZE (buf);
-    gst_structure_get_int (structure, "width", &width);
-    gst_structure_get_int (structure, "channels", &channels);
-    gst_structure_get_int (structure, "rate", &rate);
-
-    g_assert (bytes != 0);
-    g_assert (width != 0);
-    g_assert (channels != 0);
-    g_assert (rate != 0);
-    length = (bytes * 8 * GST_SECOND) / (rate * channels * width);
+    return GST_CLOCK_TIME_NONE;
   }
-  return length;
 }
 
 /**
@@ -155,7 +166,7 @@ gst_audio_duration_from_pad_buffer (GstPad * pad, GstBuffer * buf)
 gboolean
 gst_audio_is_buffer_framed (GstPad * pad, GstBuffer * buf)
 {
-  if (GST_BUFFER_SIZE (buf) % gst_audio_frame_byte_size (pad) == 0)
+  if (gst_buffer_get_size (buf) % gst_audio_frame_byte_size (pad) == 0)
     return TRUE;
   else
     return FALSE;
@@ -295,9 +306,7 @@ gst_audio_buffer_clip (GstBuffer * buffer, GstSegment * segment, gint rate,
   GstBuffer *ret;
   GstClockTime timestamp = GST_CLOCK_TIME_NONE, duration = GST_CLOCK_TIME_NONE;
   guint64 offset = GST_BUFFER_OFFSET_NONE, offset_end = GST_BUFFER_OFFSET_NONE;
-  guint8 *data;
-  guint size;
-
+  gsize trim, size;
   gboolean change_duration = TRUE, change_offset = TRUE, change_offset_end =
       TRUE;
 
@@ -313,10 +322,11 @@ gst_audio_buffer_clip (GstBuffer * buffer, GstSegment * segment, gint rate,
    * Calculate the missing values for the calculations,
    * they won't be changed later though. */
 
-  data = GST_BUFFER_DATA (buffer);
-  size = GST_BUFFER_SIZE (buffer);
+  trim = 0;
+  size = gst_buffer_get_size (buffer);
 
   timestamp = GST_BUFFER_TIMESTAMP (buffer);
+  GST_DEBUG ("timestamp %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp));
   if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
     duration = GST_BUFFER_DURATION (buffer);
   } else {
@@ -341,7 +351,7 @@ gst_audio_buffer_clip (GstBuffer * buffer, GstSegment * segment, gint rate,
   if (segment->format == GST_FORMAT_TIME) {
     /* Handle clipping for GST_FORMAT_TIME */
 
-    gint64 start, stop, cstart, cstop, diff;
+    guint64 start, stop, cstart, cstop, diff;
 
     start = timestamp;
     stop = timestamp + duration;
@@ -359,7 +369,7 @@ gst_audio_buffer_clip (GstBuffer * buffer, GstSegment * segment, gint rate,
         diff = gst_util_uint64_scale (diff, rate, GST_SECOND);
         if (change_offset)
           offset += diff;
-        data += diff * frame_size;
+        trim += diff * frame_size;
         size -= diff * frame_size;
       }
 
@@ -379,7 +389,7 @@ gst_audio_buffer_clip (GstBuffer * buffer, GstSegment * segment, gint rate,
     }
   } else {
     /* Handle clipping for GST_FORMAT_DEFAULT */
-    gint64 start, stop, cstart, cstop, diff;
+    guint64 start, stop, cstart, cstop, diff;
 
     g_return_val_if_fail (GST_BUFFER_OFFSET_IS_VALID (buffer), buffer);
 
@@ -398,7 +408,7 @@ gst_audio_buffer_clip (GstBuffer * buffer, GstSegment * segment, gint rate,
         if (change_duration)
           duration -= gst_util_uint64_scale (diff, GST_SECOND, rate);
 
-        data += diff * frame_size;
+        trim += diff * frame_size;
         size -= diff * frame_size;
       }
 
@@ -417,12 +427,13 @@ gst_audio_buffer_clip (GstBuffer * buffer, GstSegment * segment, gint rate,
     }
   }
 
-  /* Get a metadata writable buffer and apply all changes */
-  ret = gst_buffer_make_metadata_writable (buffer);
+  /* Get a writable buffer and apply all changes */
+  GST_DEBUG ("trim %" G_GSIZE_FORMAT " size %" G_GSIZE_FORMAT, trim, size);
+  ret = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, trim, size);
+  gst_buffer_unref (buffer);
 
+  GST_DEBUG ("timestamp %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp));
   GST_BUFFER_TIMESTAMP (ret) = timestamp;
-  GST_BUFFER_SIZE (ret) = size;
-  GST_BUFFER_DATA (ret) = data;
 
   if (change_duration)
     GST_BUFFER_DURATION (ret) = duration;
index ca928d6..fe6ad8a 100644 (file)
@@ -29,7 +29,7 @@
  * #GstAudioFilter will parse the input format for you (with error checking)
  * before calling your setup function. Also, elements deriving from
  * #GstAudioFilter may use gst_audio_filter_class_add_pad_templates() from
- * their base_init function to easily configure the set of caps/formats that
+ * their class_init function to easily configure the set of caps/formats that
  * the element is able to handle.
  *
  * Derived classes should override the #GstAudioFilterClass.setup() and
@@ -58,7 +58,7 @@ static GstStateChangeReturn gst_audio_filter_change_state (GstElement * element,
 static gboolean gst_audio_filter_set_caps (GstBaseTransform * btrans,
     GstCaps * incaps, GstCaps * outcaps);
 static gboolean gst_audio_filter_get_unit_size (GstBaseTransform * btrans,
-    GstCaps * caps, guint * size);
+    GstCaps * caps, gsize * size);
 
 #define do_init G_STMT_START { \
     GST_DEBUG_CATEGORY_INIT (audiofilter_dbg, "audiofilter", 0, "audiofilter"); \
@@ -154,7 +154,7 @@ gst_audio_filter_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
 
 static gboolean
 gst_audio_filter_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
-    guint * size)
+    gsize * size)
 {
   GstStructure *structure;
   gboolean ret = TRUE;
@@ -179,13 +179,13 @@ gst_audio_filter_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
  * Convenience function to add pad templates to this element class, with
  * @allowed_caps as the caps that can be handled.
  *
- * This function is usually used from within a GObject base_init function.
+ * This function is usually used from within a GObject class_init function.
  *
  * Since: 0.10.12
  */
 void
 gst_audio_filter_class_add_pad_templates (GstAudioFilterClass * klass,
-    const GstCaps * allowed_caps)
+    GstCaps * allowed_caps)
 {
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
   GstPadTemplate *pad_template;
@@ -194,12 +194,10 @@ gst_audio_filter_class_add_pad_templates (GstAudioFilterClass * klass,
   g_return_if_fail (GST_IS_CAPS (allowed_caps));
 
   pad_template = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
-      gst_caps_copy (allowed_caps));
+      allowed_caps);
   gst_element_class_add_pad_template (element_class, pad_template);
-  gst_object_unref (pad_template);
 
   pad_template = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
-      gst_caps_copy (allowed_caps));
+      allowed_caps);
   gst_element_class_add_pad_template (element_class, pad_template);
-  gst_object_unref (pad_template);
 }
index 2fe5da5..ed50317 100644 (file)
@@ -87,7 +87,7 @@ struct _GstAudioFilterClass {
 GType   gst_audio_filter_get_type (void);
 
 void    gst_audio_filter_class_add_pad_templates (GstAudioFilterClass * klass,
-                                                  const GstCaps       * allowed_caps);
+                                                  GstCaps             * allowed_caps);
 
 G_END_DECLS
 
index ce919af..88c6f7b 100644 (file)
@@ -394,8 +394,8 @@ gst_audioringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
   /* set latency to one more segment as we need some headroom */
   spec->seglatency = spec->segtotal + 1;
 
-  buf->data = gst_buffer_new_and_alloc (spec->segtotal * spec->segsize);
-  memset (GST_BUFFER_DATA (buf->data), 0, GST_BUFFER_SIZE (buf->data));
+  buf->size = spec->segtotal * spec->segsize;
+  buf->memory = g_malloc0 (buf->size);
 
   return TRUE;
 
@@ -468,8 +468,8 @@ gst_audioringbuffer_release (GstRingBuffer * buf)
   csink = GST_AUDIO_SINK_GET_CLASS (sink);
 
   /* free the buffer */
-  gst_buffer_unref (buf->data);
-  buf->data = NULL;
+  g_free (buf->memory);
+  buf->memory = NULL;
 
   if (csink->unprepare)
     result = csink->unprepare (sink);
@@ -574,21 +574,16 @@ enum
   ARG_0,
 };
 
-#define _do_init(bla) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (gst_audio_sink_debug, "audiosink", 0, "audiosink element");
-
-GST_BOILERPLATE_FULL (GstAudioSink, gst_audio_sink, GstBaseAudioSink,
+#define gst_audio_sink_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstAudioSink, gst_audio_sink,
     GST_TYPE_BASE_AUDIO_SINK, _do_init);
 
 static GstRingBuffer *gst_audio_sink_create_ringbuffer (GstBaseAudioSink *
     sink);
 
 static void
-gst_audio_sink_base_init (gpointer g_class)
-{
-}
-
-static void
 gst_audio_sink_class_init (GstAudioSinkClass * klass)
 {
   GstBaseAudioSinkClass *gstbaseaudiosink_class;
@@ -602,7 +597,7 @@ gst_audio_sink_class_init (GstAudioSinkClass * klass)
 }
 
 static void
-gst_audio_sink_init (GstAudioSink * audiosink, GstAudioSinkClass * g_class)
+gst_audio_sink_init (GstAudioSink * audiosink)
 {
 }
 
index d7a6b54..57864d1 100644 (file)
@@ -376,8 +376,8 @@ gst_audioringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
   if (!result)
     goto could_not_open;
 
-  buf->data = gst_buffer_new_and_alloc (spec->segtotal * spec->segsize);
-  memset (GST_BUFFER_DATA (buf->data), 0, GST_BUFFER_SIZE (buf->data));
+  buf->size = spec->segtotal * spec->segsize;
+  buf->memory = g_malloc0 (buf->size);
 
   abuf = GST_AUDIORING_BUFFER (buf);
   abuf->running = TRUE;
@@ -418,8 +418,8 @@ gst_audioringbuffer_release (GstRingBuffer * buf)
   GST_OBJECT_LOCK (buf);
 
   /* free the buffer */
-  gst_buffer_unref (buf->data);
-  buf->data = NULL;
+  g_free (buf->memory);
+  buf->memory = NULL;
 
   if (csrc->unprepare)
     result = csrc->unprepare (src);
@@ -488,20 +488,15 @@ enum
   ARG_0,
 };
 
-#define _do_init(bla) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (gst_audio_src_debug, "audiosrc", 0, "audiosrc element");
-
-GST_BOILERPLATE_FULL (GstAudioSrc, gst_audio_src, GstBaseAudioSrc,
+#define gst_audio_src_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstAudioSrc, gst_audio_src,
     GST_TYPE_BASE_AUDIO_SRC, _do_init);
 
 static GstRingBuffer *gst_audio_src_create_ringbuffer (GstBaseAudioSrc * src);
 
 static void
-gst_audio_src_base_init (gpointer g_class)
-{
-}
-
-static void
 gst_audio_src_class_init (GstAudioSrcClass * klass)
 {
   GstBaseAudioSrcClass *gstbaseaudiosrc_class;
@@ -515,7 +510,7 @@ gst_audio_src_class_init (GstAudioSrcClass * klass)
 }
 
 static void
-gst_audio_src_init (GstAudioSrc * audiosrc, GstAudioSrcClass * g_class)
+gst_audio_src_init (GstAudioSrc * audiosrc)
 {
 }
 
index fea7a8e..6d09d12 100644 (file)
@@ -57,7 +57,6 @@ struct _GstBaseAudioSinkPrivate
 
   GstClockTime eos_time;
 
-  gboolean do_time_offset;
   /* number of microseconds we alow timestamps or clock slaving to drift
    * before resyncing */
   guint64 drift_tolerance;
@@ -119,10 +118,10 @@ gst_base_audio_sink_slave_method_get_type (void)
 }
 
 
-#define _do_init(bla) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (gst_base_audio_sink_debug, "baseaudiosink", 0, "baseaudiosink element");
-
-GST_BOILERPLATE_FULL (GstBaseAudioSink, gst_base_audio_sink, GstBaseSink,
+#define gst_base_audio_sink_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstBaseAudioSink, gst_base_audio_sink,
     GST_TYPE_BASE_SINK, _do_init);
 
 static void gst_base_audio_sink_dispose (GObject * object);
@@ -132,8 +131,10 @@ static void gst_base_audio_sink_set_property (GObject * object, guint prop_id,
 static void gst_base_audio_sink_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
+#if 0
 static GstStateChangeReturn gst_base_audio_sink_async_play (GstBaseSink *
     basesink);
+#endif
 static GstStateChangeReturn gst_base_audio_sink_change_state (GstElement *
     element, GstStateChange transition);
 static gboolean gst_base_audio_sink_activate_pull (GstBaseSink * basesink,
@@ -165,11 +166,6 @@ static gboolean gst_base_audio_sink_query_pad (GstPad * pad, GstQuery * query);
 /* static guint gst_base_audio_sink_signals[LAST_SIGNAL] = { 0 }; */
 
 static void
-gst_base_audio_sink_base_init (gpointer g_class)
-{
-}
-
-static void
 gst_base_audio_sink_class_init (GstBaseAudioSinkClass * klass)
 {
   GObjectClass *gobject_class;
@@ -240,8 +236,10 @@ gst_base_audio_sink_class_init (GstBaseAudioSinkClass * klass)
       GST_DEBUG_FUNCPTR (gst_base_audio_sink_get_times);
   gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_base_audio_sink_setcaps);
   gstbasesink_class->fixate = GST_DEBUG_FUNCPTR (gst_base_audio_sink_fixate);
+#if 0
   gstbasesink_class->async_play =
       GST_DEBUG_FUNCPTR (gst_base_audio_sink_async_play);
+#endif
   gstbasesink_class->activate_pull =
       GST_DEBUG_FUNCPTR (gst_base_audio_sink_activate_pull);
 
@@ -253,10 +251,8 @@ gst_base_audio_sink_class_init (GstBaseAudioSinkClass * klass)
 }
 
 static void
-gst_base_audio_sink_init (GstBaseAudioSink * baseaudiosink,
-    GstBaseAudioSinkClass * g_class)
+gst_base_audio_sink_init (GstBaseAudioSink * baseaudiosink)
 {
-  GstPluginFeature *feature;
   GstBaseSink *basesink;
 
   baseaudiosink->priv = GST_BASE_AUDIO_SINK_GET_PRIVATE (baseaudiosink);
@@ -279,25 +275,6 @@ gst_base_audio_sink_init (GstBaseAudioSink * baseaudiosink,
   /* install some custom pad_query functions */
   gst_pad_set_query_function (GST_BASE_SINK_PAD (baseaudiosink),
       GST_DEBUG_FUNCPTR (gst_base_audio_sink_query_pad));
-
-  baseaudiosink->priv->do_time_offset = TRUE;
-
-  /* check the factory, pulsesink < 0.10.17 does the timestamp offset itself so
-   * we should not do ourselves */
-  feature =
-      GST_PLUGIN_FEATURE_CAST (GST_ELEMENT_CLASS (g_class)->elementfactory);
-  GST_DEBUG ("created from factory %p", feature);
-
-  /* HACK for old pulsesink that did the time_offset themselves */
-  if (feature) {
-    if (strcmp (gst_plugin_feature_get_name (feature), "pulsesink") == 0) {
-      if (!gst_plugin_feature_check_version (feature, 0, 10, 17)) {
-        /* we're dealing with an old pulsesink, we need to disable time corection */
-        GST_DEBUG ("disable time offset");
-        baseaudiosink->priv->do_time_offset = FALSE;
-      }
-    }
-  }
 }
 
 static void
@@ -736,7 +713,10 @@ gst_base_audio_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
 
   GST_DEBUG_OBJECT (sink, "release old ringbuffer");
 
-  /* get current time, updates the last_time */
+  /* get current time, updates the last_time. When the subclass has a clock that
+   * restarts from 0 when a new format is negotiated, it will call
+   * gst_audio_clock_reset() which will use this last_time to create an offset
+   * so that time from the clock keeps on increasing monotonically. */
   now = gst_clock_get_time (sink->provided_clock);
 
   GST_DEBUG_OBJECT (sink, "time was %" GST_TIME_FORMAT, GST_TIME_ARGS (now));
@@ -891,17 +871,6 @@ gst_base_audio_sink_event (GstBaseSink * bsink, GstEvent * event)
       /* now wait till we played everything */
       gst_base_audio_sink_drain (sink);
       break;
-    case GST_EVENT_NEWSEGMENT:
-    {
-      gdouble rate;
-
-      /* we only need the rate */
-      gst_event_parse_new_segment_full (event, NULL, &rate, NULL, NULL,
-          NULL, NULL, NULL);
-
-      GST_DEBUG_OBJECT (sink, "new segment rate of %f", rate);
-      break;
-    }
     default:
       break;
   }
@@ -1364,8 +1333,8 @@ gst_base_audio_sink_get_alignment (GstBaseAudioSink * sink,
         G_GINT64_FORMAT, align, maxdrift);
   } else {
     /* calculate sample diff in seconds for error message */
-    gint64 diff_s = gst_util_uint64_scale_int (diff, GST_SECOND,
-        ringbuf->spec.rate);
+    gint64 diff_s =
+        gst_util_uint64_scale_int (diff, GST_SECOND, ringbuf->spec.rate);
     /* timestamps drifted apart from previous samples too much, we need to
      * resync. We log this as an element warning. */
     GST_WARNING_OBJECT (sink,
@@ -1387,9 +1356,11 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
   GstBaseAudioSinkClass *bclass;
   GstBaseAudioSink *sink;
   GstRingBuffer *ringbuf;
-  gint64 diff, align, ctime, cstop;
+  gint64 diff, align;
+  guint64 ctime, cstop;
+  gsize offset;
   guint8 *data;
-  guint size;
+  gsize size;
   guint samples, written;
   gint bps;
   gint accum;
@@ -1440,7 +1411,7 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
 
   bps = ringbuf->spec.bytes_per_sample;
 
-  size = GST_BUFFER_SIZE (buf);
+  size = gst_buffer_get_size (buf);
   if (G_UNLIKELY (size % bps) != 0)
     goto wrong_size;
 
@@ -1455,7 +1426,7 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
       GST_TIME_FORMAT ", samples %u", GST_TIME_ARGS (time), in_offset,
       GST_TIME_ARGS (bsink->segment.start), samples);
 
-  data = GST_BUFFER_DATA (buf);
+  offset = 0;
 
   /* if not valid timestamp or we can't clip or sync, try to play
    * sample ASAP */
@@ -1464,7 +1435,7 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
     render_stop = render_start + samples;
     GST_DEBUG_OBJECT (sink,
         "Buffer of size %u has no time. Using render_start=%" G_GUINT64_FORMAT,
-        GST_BUFFER_SIZE (buf), render_start);
+        size, render_start);
     /* we don't have a start so we don't know stop either */
     stop = -1;
     goto no_sync;
@@ -1518,7 +1489,7 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
     GST_DEBUG_OBJECT (sink, "clipping start to %" GST_TIME_FORMAT " %"
         G_GUINT64_FORMAT " samples", GST_TIME_ARGS (ctime), diff);
     samples -= diff;
-    data += diff * bps;
+    offset += diff * bps;
     time = ctime;
   }
   diff = stop - cstop;
@@ -1599,20 +1570,18 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
       GST_TIME_ARGS (render_start), GST_TIME_ARGS (render_stop));
 
   /* bring to position in the ringbuffer */
-  if (sink->priv->do_time_offset) {
-    time_offset =
-        GST_AUDIO_CLOCK_CAST (sink->provided_clock)->abidata.ABI.time_offset;
-    GST_DEBUG_OBJECT (sink,
-        "time offset %" GST_TIME_FORMAT, GST_TIME_ARGS (time_offset));
-    if (render_start > time_offset)
-      render_start -= time_offset;
-    else
-      render_start = 0;
-    if (render_stop > time_offset)
-      render_stop -= time_offset;
-    else
-      render_stop = 0;
-  }
+  time_offset =
+      GST_AUDIO_CLOCK_CAST (sink->provided_clock)->abidata.ABI.time_offset;
+  GST_DEBUG_OBJECT (sink,
+      "time offset %" GST_TIME_FORMAT, GST_TIME_ARGS (time_offset));
+  if (render_start > time_offset)
+    render_start -= time_offset;
+  else
+    render_start = 0;
+  if (render_stop > time_offset)
+    render_stop -= time_offset;
+  else
+    render_stop = 0;
 
   /* and bring the time to the rate corrected offset in the buffer */
   render_start = gst_util_uint64_scale_int (render_start,
@@ -1676,10 +1645,11 @@ no_sync:
   /* we need to accumulate over different runs for when we get interrupted */
   accum = 0;
   align_next = TRUE;
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
   do {
     written =
-        gst_ring_buffer_commit_full (ringbuf, &sample_offset, data, samples,
-        out_samples, &accum);
+        gst_ring_buffer_commit_full (ringbuf, &sample_offset, data + offset,
+        samples, out_samples, &accum);
 
     GST_DEBUG_OBJECT (sink, "wrote %u of %u", written, samples);
     /* if we wrote all, we're done */
@@ -1703,8 +1673,9 @@ no_sync:
       break;
 
     samples -= written;
-    data += written * bps;
+    offset += written * bps;
   } while (TRUE);
+  gst_buffer_unmap (buf, data, size);
 
   if (align_next)
     sink->next_sample = sample_offset;
@@ -1764,6 +1735,7 @@ stopping:
   {
     GST_DEBUG_OBJECT (sink, "preroll got interrupted: %d (%s)", ret,
         gst_flow_get_name (ret));
+    gst_buffer_unmap (buf, data, size);
     goto done;
   }
 sync_latency_failed:
@@ -1807,6 +1779,7 @@ gst_base_audio_sink_callback (GstRingBuffer * rbuf, guint8 * data, guint len,
   GstBaseAudioSink *sink;
   GstBuffer *buf;
   GstFlowReturn ret;
+  gsize size;
 
   basesink = GST_BASE_SINK (user_data);
   sink = GST_BASE_AUDIO_SINK (user_data);
@@ -1818,7 +1791,7 @@ gst_base_audio_sink_callback (GstRingBuffer * rbuf, guint8 * data, guint len,
   GST_LOG_OBJECT (basesink, "pulling %d bytes offset %" G_GUINT64_FORMAT
       " to fill audio buffer", len, basesink->offset);
   ret =
-      gst_pad_pull_range (basesink->sinkpad, basesink->segment.last_stop, len,
+      gst_pad_pull_range (basesink->sinkpad, basesink->segment.position, len,
       &buf);
 
   if (ret != GST_FLOW_OK) {
@@ -1828,7 +1801,7 @@ gst_base_audio_sink_callback (GstRingBuffer * rbuf, guint8 * data, guint len,
       goto error;
   }
 
-  GST_PAD_PREROLL_LOCK (basesink->sinkpad);
+  GST_BASE_SINK_PREROLL_LOCK (basesink);
   if (basesink->flushing)
     goto flushing;
 
@@ -1837,17 +1810,18 @@ gst_base_audio_sink_callback (GstRingBuffer * rbuf, guint8 * data, guint len,
   if (ret != GST_FLOW_OK)
     goto preroll_error;
 
-  if (len != GST_BUFFER_SIZE (buf)) {
+  size = gst_buffer_get_size (buf);
+
+  if (len != size) {
     GST_INFO_OBJECT (basesink,
-        "got different size than requested from sink pad: %u != %u", len,
-        GST_BUFFER_SIZE (buf));
-    len = MIN (GST_BUFFER_SIZE (buf), len);
+        "got different size than requested from sink pad: %u != %u", len, size);
+    len = MIN (size, len);
   }
 
-  basesink->segment.last_stop += len;
+  basesink->segment.position += len;
 
-  memcpy (data, GST_BUFFER_DATA (buf), len);
-  GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
+  gst_buffer_extract (buf, 0, data, len);
+  GST_BASE_SINK_PREROLL_UNLOCK (basesink);
 
   GST_PAD_STREAM_UNLOCK (basesink->sinkpad);
 
@@ -1877,7 +1851,7 @@ flushing:
   {
     GST_DEBUG_OBJECT (sink, "we are flushing");
     gst_ring_buffer_pause (rbuf);
-    GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
+    GST_BASE_SINK_PREROLL_UNLOCK (basesink);
     GST_PAD_STREAM_UNLOCK (basesink->sinkpad);
     return;
   }
@@ -1885,7 +1859,7 @@ preroll_error:
   {
     GST_DEBUG_OBJECT (sink, "error %s", gst_flow_get_name (ret));
     gst_ring_buffer_pause (rbuf);
-    GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
+    GST_BASE_SINK_PREROLL_UNLOCK (basesink);
     GST_PAD_STREAM_UNLOCK (basesink->sinkpad);
     return;
   }
@@ -1913,6 +1887,7 @@ gst_base_audio_sink_activate_pull (GstBaseSink * basesink, gboolean active)
   return ret;
 }
 
+#if 0
 /* should be called with the LOCK */
 static GstStateChangeReturn
 gst_base_audio_sink_async_play (GstBaseSink * basesink)
@@ -1931,6 +1906,7 @@ gst_base_audio_sink_async_play (GstBaseSink * basesink)
 
   return GST_STATE_CHANGE_SUCCESS;
 }
+#endif
 
 static GstStateChangeReturn
 gst_base_audio_sink_change_state (GstElement * element,
index 7c7ec93..48ac2df 100644 (file)
@@ -119,8 +119,9 @@ _do_init (GType type)
 #endif /* ENABLE_NLS */
 }
 
-GST_BOILERPLATE_FULL (GstBaseAudioSrc, gst_base_audio_src, GstPushSrc,
-    GST_TYPE_PUSH_SRC, _do_init);
+#define gst_base_audio_src_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstBaseAudioSrc, gst_base_audio_src, GST_TYPE_PUSH_SRC,
+    _do_init (g_define_type_id));
 
 static void gst_base_audio_src_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
@@ -149,11 +150,6 @@ static void gst_base_audio_src_fixate (GstBaseSrc * bsrc, GstCaps * caps);
 /* static guint gst_base_audio_src_signals[LAST_SIGNAL] = { 0 }; */
 
 static void
-gst_base_audio_src_base_init (gpointer g_class)
-{
-}
-
-static void
 gst_base_audio_src_class_init (GstBaseAudioSrcClass * klass)
 {
   GObjectClass *gobject_class;
@@ -241,8 +237,7 @@ gst_base_audio_src_class_init (GstBaseAudioSrcClass * klass)
 }
 
 static void
-gst_base_audio_src_init (GstBaseAudioSrc * baseaudiosrc,
-    GstBaseAudioSrcClass * g_class)
+gst_base_audio_src_init (GstBaseAudioSrc * baseaudiosrc)
 {
   baseaudiosrc->priv = GST_BASE_AUDIO_SRC_GET_PRIVATE (baseaudiosrc);
 
@@ -561,8 +556,7 @@ gst_base_audio_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
   spec->latency_time = src->latency_time;
 
   GST_OBJECT_LOCK (src);
-  if (!gst_ring_buffer_parse_caps (spec, caps))
-  {
+  if (!gst_ring_buffer_parse_caps (spec, caps)) {
     GST_OBJECT_UNLOCK (src);
     goto parse_error;
   }
@@ -759,7 +753,7 @@ gst_base_audio_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
 {
   GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (bsrc);
   GstBuffer *buf;
-  guchar *data;
+  guchar *data, *ptr;
   guint samples, total_samples;
   guint64 sample;
   gint bps;
@@ -804,10 +798,9 @@ gst_base_audio_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
 
   /* FIXME, using a bufferpool would be nice here */
   buf = gst_buffer_new_and_alloc (length);
-  data = GST_BUFFER_DATA (buf);
-
+  data = ptr = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
   do {
-    read = gst_ring_buffer_read (ringbuffer, sample, data, samples);
+    read = gst_ring_buffer_read (ringbuffer, sample, ptr, samples);
     GST_DEBUG_OBJECT (src, "read %u of %u", read, samples);
     /* if we read all, we're done */
     if (read == samples)
@@ -823,8 +816,9 @@ gst_base_audio_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
     /* read next samples */
     sample += read;
     samples -= read;
-    data += read * bps;
+    ptr += read * bps;
   } while (TRUE);
+  gst_buffer_unmap (buf, data, length);
 
   /* mark discontinuity if needed */
   if (G_UNLIKELY (sample != src->next_sample) && src->next_sample != -1) {
index 87df45b..ca97813 100644 (file)
@@ -1643,10 +1643,10 @@ default_commit (GstRingBuffer * buf, guint64 * sample,
   gint inr, outr;
   gboolean reverse;
 
-  g_return_val_if_fail (buf->data != NULL, -1);
+  g_return_val_if_fail (buf->memory != NULL, -1);
   g_return_val_if_fail (data != NULL, -1);
 
-  dest = GST_BUFFER_DATA (buf->data);
+  dest = buf->memory;
   segsize = buf->spec.segsize;
   segtotal = buf->spec.segtotal;
   bps = buf->spec.bytes_per_sample;
@@ -1872,10 +1872,10 @@ gst_ring_buffer_read (GstRingBuffer * buf, guint64 sample, guchar * data,
   guint to_read;
 
   g_return_val_if_fail (GST_IS_RING_BUFFER (buf), -1);
-  g_return_val_if_fail (buf->data != NULL, -1);
+  g_return_val_if_fail (buf->memory != NULL, -1);
   g_return_val_if_fail (data != NULL, -1);
 
-  dest = GST_BUFFER_DATA (buf->data);
+  dest = buf->memory;
   segsize = buf->spec.segsize;
   segtotal = buf->spec.segtotal;
   bps = buf->spec.bytes_per_sample;
@@ -1982,12 +1982,12 @@ gst_ring_buffer_prepare_read (GstRingBuffer * buf, gint * segment,
       return FALSE;
   }
 
-  g_return_val_if_fail (buf->data != NULL, FALSE);
+  g_return_val_if_fail (buf->memory != NULL, FALSE);
   g_return_val_if_fail (segment != NULL, FALSE);
   g_return_val_if_fail (readptr != NULL, FALSE);
   g_return_val_if_fail (len != NULL, FALSE);
 
-  data = GST_BUFFER_DATA (buf->data);
+  data = buf->memory;
 
   /* get the position of the pointer */
   segdone = g_atomic_int_get (&buf->segdone);
@@ -2054,7 +2054,7 @@ gst_ring_buffer_clear (GstRingBuffer * buf, gint segment)
   g_return_if_fail (GST_IS_RING_BUFFER (buf));
 
   /* no data means it's already cleared */
-  if (G_UNLIKELY (buf->data == NULL))
+  if (G_UNLIKELY (buf->memory == NULL))
     return;
 
   /* no empty_seg means it's not opened */
@@ -2063,7 +2063,7 @@ gst_ring_buffer_clear (GstRingBuffer * buf, gint segment)
 
   segment %= buf->spec.segtotal;
 
-  data = GST_BUFFER_DATA (buf->data);
+  data = buf->memory;
   data += segment * buf->spec.segsize;
 
   GST_LOG ("clear segment %d @%p", segment, data);
index b09863c..bfa7241 100644 (file)
@@ -310,7 +310,8 @@ struct _GstRingBuffer {
   GCond                 *cond;
   gboolean               open;
   gboolean               acquired;
-  GstBuffer             *data;
+  guint8                *memory;
+  gsize                  size;
   GstRingBufferSpec      spec;
   GstRingBufferSegState *segstate;
   gint                   samples_per_seg;
index e753a56..fec1ebd 100644 (file)
@@ -114,6 +114,8 @@ enum
   ARG_TOC_BIAS
 };
 
+static void gst_cdda_base_src_uri_handler_init (gpointer g_iface,
+    gpointer iface_data);
 static void gst_cdda_base_src_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 static void gst_cdda_base_src_set_property (GObject * object, guint prop_id,
@@ -125,7 +127,6 @@ static gboolean gst_cdda_base_src_handle_event (GstBaseSrc * basesrc,
     GstEvent * event);
 static gboolean gst_cdda_base_src_do_seek (GstBaseSrc * basesrc,
     GstSegment * segment);
-static void gst_cdda_base_src_setup_interfaces (GType type);
 static gboolean gst_cdda_base_src_start (GstBaseSrc * basesrc);
 static gboolean gst_cdda_base_src_stop (GstBaseSrc * basesrc);
 static GstFlowReturn gst_cdda_base_src_create (GstPushSrc * pushsrc,
@@ -135,8 +136,10 @@ static void gst_cdda_base_src_update_duration (GstCddaBaseSrc * src);
 static void gst_cdda_base_src_set_index (GstElement * src, GstIndex * index);
 static GstIndex *gst_cdda_base_src_get_index (GstElement * src);
 
-GST_BOILERPLATE_FULL (GstCddaBaseSrc, gst_cdda_base_src, GstPushSrc,
-    GST_TYPE_PUSH_SRC, gst_cdda_base_src_setup_interfaces);
+#define gst_cdda_base_src_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstCddaBaseSrc, gst_cdda_base_src, GST_TYPE_PUSH_SRC,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
+        gst_cdda_base_src_uri_handler_init));
 
 #define SRC_CAPS \
   "audio/x-raw-int, "               \
@@ -177,12 +180,20 @@ gst_cdda_base_src_mode_get_type (void)
 }
 
 static void
-gst_cdda_base_src_base_init (gpointer g_class)
+gst_cdda_base_src_class_init (GstCddaBaseSrcClass * klass)
 {
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+  GstElementClass *element_class;
+  GstPushSrcClass *pushsrc_class;
+  GstBaseSrcClass *basesrc_class;
+  GObjectClass *gobject_class;
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_cdda_base_src_src_template));
+  gobject_class = (GObjectClass *) klass;
+  element_class = (GstElementClass *) klass;
+  basesrc_class = (GstBaseSrcClass *) klass;
+  pushsrc_class = (GstPushSrcClass *) klass;
+
+  GST_DEBUG_CATEGORY_INIT (gst_cdda_base_src_debug, "cddabasesrc", 0,
+      "CDDA Base Source");
 
   /* our very own formats */
   track_format = gst_format_register ("track", "CD track");
@@ -196,23 +207,6 @@ gst_cdda_base_src_base_init (gpointer g_class)
   gst_tag_register (GST_TAG_CDDA_TRACK_TAGS, GST_TAG_FLAG_META, GST_TYPE_TAG_LIST, "track-tags", "CDDA taglist for one track", gst_tag_merge_use_first);        ///////////// FIXME: right function??? ///////
 #endif
 
-  GST_DEBUG_CATEGORY_INIT (gst_cdda_base_src_debug, "cddabasesrc", 0,
-      "CDDA Base Source");
-}
-
-static void
-gst_cdda_base_src_class_init (GstCddaBaseSrcClass * klass)
-{
-  GstElementClass *element_class;
-  GstPushSrcClass *pushsrc_class;
-  GstBaseSrcClass *basesrc_class;
-  GObjectClass *gobject_class;
-
-  gobject_class = (GObjectClass *) klass;
-  element_class = (GstElementClass *) klass;
-  basesrc_class = (GstBaseSrcClass *) klass;
-  pushsrc_class = (GstPushSrcClass *) klass;
-
   gobject_class->set_property = gst_cdda_base_src_set_property;
   gobject_class->get_property = gst_cdda_base_src_get_property;
   gobject_class->finalize = gst_cdda_base_src_finalize;
@@ -247,6 +241,9 @@ gst_cdda_base_src_class_init (GstCddaBaseSrcClass * klass)
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 #endif
 
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_cdda_base_src_src_template));
+
   element_class->set_index = GST_DEBUG_FUNCPTR (gst_cdda_base_src_set_index);
   element_class->get_index = GST_DEBUG_FUNCPTR (gst_cdda_base_src_get_index);
 
@@ -262,7 +259,7 @@ gst_cdda_base_src_class_init (GstCddaBaseSrcClass * klass)
 }
 
 static void
-gst_cdda_base_src_init (GstCddaBaseSrc * src, GstCddaBaseSrcClass * klass)
+gst_cdda_base_src_init (GstCddaBaseSrc * src)
 {
   gst_pad_set_query_type_function (GST_BASE_SRC_PAD (src),
       GST_DEBUG_FUNCPTR (gst_cdda_base_src_get_query_types));
@@ -1035,18 +1032,6 @@ gst_cdda_base_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
   iface->get_protocols = gst_cdda_base_src_uri_get_protocols;
 }
 
-static void
-gst_cdda_base_src_setup_interfaces (GType type)
-{
-  static const GInterfaceInfo urihandler_info = {
-    gst_cdda_base_src_uri_handler_init,
-    NULL,
-    NULL,
-  };
-
-  g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info);
-}
-
 /**
  * gst_cdda_base_src_add_track:
  * @src: a #GstCddaBaseSrc
@@ -1101,12 +1086,10 @@ gst_cdda_base_src_update_duration (GstCddaBaseSrc * src)
   basesrc = GST_BASE_SRC (src);
 
   format = GST_FORMAT_TIME;
-  if (gst_pad_query_duration (GST_BASE_SRC_PAD (src), &format, &duration)) {
-    gst_segment_set_duration (&basesrc->segment, GST_FORMAT_TIME, duration);
-  } else {
-    gst_segment_set_duration (&basesrc->segment, GST_FORMAT_TIME, -1);
+  if (!gst_pad_query_duration (GST_BASE_SRC_PAD (src), &format, &duration)) {
     duration = GST_CLOCK_TIME_NONE;
   }
+  basesrc->segment.duration = duration;
 
   gst_element_post_message (GST_ELEMENT (src),
       gst_message_new_duration (GST_OBJECT (src), GST_FORMAT_TIME, -1));
@@ -1628,10 +1611,6 @@ gst_cdda_base_src_create (GstPushSrc * pushsrc, GstBuffer ** buffer)
     return GST_FLOW_ERROR;
   }
 
-  if (GST_BUFFER_CAPS (buf) == NULL) {
-    gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (src)));
-  }
-
   format = GST_FORMAT_TIME;
   if (gst_pad_query_position (GST_BASE_SRC_PAD (src), &format, &qry_position)) {
     gint64 next_ts = 0;
@@ -1647,7 +1626,7 @@ gst_cdda_base_src_create (GstPushSrc * pushsrc, GstBuffer ** buffer)
 
   /* fallback duration: 4 bytes per sample, 44100 samples per second */
   if (duration == GST_CLOCK_TIME_NONE) {
-    duration = gst_util_uint64_scale_int (GST_BUFFER_SIZE (buf) >> 2,
+    duration = gst_util_uint64_scale_int (gst_buffer_get_size (buf) >> 2,
         GST_SECOND, 44100);
   }
 
index 7203ce8..619c8eb 100644 (file)
@@ -237,7 +237,7 @@ gst_navigation_query_new_commands (void)
 
   structure = gst_structure_new (GST_NAVIGATION_QUERY_NAME,
       "type", G_TYPE_STRING, "commands", NULL);
-  query = gst_query_new_application (GST_QUERY_CUSTOM, structure);
+  query = gst_query_new_custom (GST_QUERY_CUSTOM, structure);
 
   return query;
 }
@@ -283,7 +283,7 @@ gst_navigation_query_set_commands (GstQuery * query, gint n_cmds, ...)
   }
   va_end (ap);
 
-  structure = gst_query_get_structure (query);
+  structure = gst_query_writable_structure (query);
   gst_structure_set_value (structure, "commands", &list);
 
   g_value_unset (&list);
@@ -314,7 +314,7 @@ gst_navigation_query_set_commandsv (GstQuery * query, gint n_cmds,
   for (i = 0; i < n_cmds; i++) {
     gst_query_list_add_command (&list, cmds[i]);
   }
-  structure = gst_query_get_structure (query);
+  structure = gst_query_writable_structure (query);
   gst_structure_set_value (structure, "commands", &list);
 
   g_value_unset (&list);
@@ -333,7 +333,7 @@ gst_navigation_query_set_commandsv (GstQuery * query, gint n_cmds,
 gboolean
 gst_navigation_query_parse_commands_length (GstQuery * query, guint * n_cmds)
 {
-  GstStructure *structure;
+  const GstStructure *structure;
   const GValue *list;
 
   g_return_val_if_fail (GST_NAVIGATION_QUERY_HAS_TYPE (query, COMMANDS), FALSE);
@@ -368,7 +368,7 @@ gboolean
 gst_navigation_query_parse_commands_nth (GstQuery * query, guint nth,
     GstNavigationCommand * cmd)
 {
-  GstStructure *structure;
+  const GstStructure *structure;
   const GValue *list;
 
   g_return_val_if_fail (GST_NAVIGATION_QUERY_HAS_TYPE (query, COMMANDS), FALSE);
@@ -409,7 +409,7 @@ gst_navigation_query_new_angles (void)
 
   structure = gst_structure_new (GST_NAVIGATION_QUERY_NAME,
       "type", G_TYPE_STRING, "angles", NULL);
-  query = gst_query_new_application (GST_QUERY_CUSTOM, structure);
+  query = gst_query_new_custom (GST_QUERY_CUSTOM, structure);
 
   return query;
 }
@@ -432,7 +432,7 @@ gst_navigation_query_set_angles (GstQuery * query, guint cur_angle,
 
   g_return_if_fail (GST_NAVIGATION_QUERY_HAS_TYPE (query, ANGLES));
 
-  structure = gst_query_get_structure (query);
+  structure = gst_query_writable_structure (query);
   gst_structure_set (structure,
       "angle", G_TYPE_UINT, cur_angle, "angles", G_TYPE_UINT, n_angles, NULL);
 }
@@ -456,7 +456,7 @@ gboolean
 gst_navigation_query_parse_angles (GstQuery * query, guint * cur_angle,
     guint * n_angles)
 {
-  GstStructure *structure;
+  const GstStructure *structure;
   gboolean ret = TRUE;
 
   g_return_val_if_fail (GST_NAVIGATION_QUERY_HAS_TYPE (query, ANGLES), FALSE);
index 6328a76..aaea75a 100644 (file)
 
 #include "gstnetbuffer.h"
 
-static void gst_netbuffer_finalize (GstNetBuffer * nbuf);
-static GstNetBuffer *gst_netbuffer_copy (GstNetBuffer * nbuf);
-
-static GstBufferClass *parent_class;
-
-G_DEFINE_TYPE (GstNetBuffer, gst_netbuffer, GST_TYPE_BUFFER);
-
-static void
-gst_netbuffer_class_init (GstNetBufferClass * netbuffer_class)
-{
-  GstMiniObjectClass *mo_class = GST_MINI_OBJECT_CLASS (netbuffer_class);
-
-  parent_class = g_type_class_peek_parent (netbuffer_class);
-
-  mo_class->copy = (GstMiniObjectCopyFunction) gst_netbuffer_copy;
-  mo_class->finalize = (GstMiniObjectFinalizeFunction) gst_netbuffer_finalize;
-}
-
 static void
-gst_netbuffer_init (GstNetBuffer * instance)
+meta_net_address_copy (GstBuffer * copybuf, GstMetaNetAddress * meta,
+    GstBuffer * buffer, gsize offset, gsize size)
 {
-}
+  GstMetaNetAddress *naddr;
 
-static void
-gst_netbuffer_finalize (GstNetBuffer * nbuf)
-{
-  GST_MINI_OBJECT_CLASS (parent_class)->finalize (GST_MINI_OBJECT (nbuf));
+  naddr = gst_buffer_add_meta_net_address (copybuf);
+  memcpy (&naddr->naddr, &meta->naddr, sizeof (meta->naddr));
 }
 
-static GstNetBuffer *
-gst_netbuffer_copy (GstNetBuffer * nbuf)
+const GstMetaInfo *
+gst_meta_net_address_get_info (void)
 {
-  GstNetBuffer *copy;
-
-  copy = gst_netbuffer_new ();
-
-  /* we simply copy everything from our parent */
-  GST_BUFFER_DATA (copy) =
-      g_memdup (GST_BUFFER_DATA (nbuf), GST_BUFFER_SIZE (nbuf));
-  /* make sure it gets freed (even if the parent is subclassed, we return a
-     normal buffer) */
-  GST_BUFFER_MALLOCDATA (copy) = GST_BUFFER_DATA (copy);
-  GST_BUFFER_SIZE (copy) = GST_BUFFER_SIZE (nbuf);
-
-  memcpy (&copy->to, &nbuf->to, sizeof (nbuf->to));
-  memcpy (&copy->from, &nbuf->from, sizeof (nbuf->from));
-
-  /* copy metadata */
-  gst_buffer_copy_metadata (GST_BUFFER_CAST (copy),
-      GST_BUFFER_CAST (nbuf), GST_BUFFER_COPY_ALL);
-
-  return copy;
-}
-
-/**
- * gst_netbuffer_new:
- *
- * Create a new network buffer.
- *
- * Returns: a new #GstNetBuffer.
- */
-GstNetBuffer *
-gst_netbuffer_new (void)
-{
-  GstNetBuffer *buf;
-
-  buf = (GstNetBuffer *) gst_mini_object_new (GST_TYPE_NETBUFFER);
-
-  return buf;
+  static const GstMetaInfo *meta_info = NULL;
+
+  if (meta_info == NULL) {
+    meta_info = gst_meta_register ("GstMetaNetAddress", "GstMetaNetAddress",
+        sizeof (GstMetaNetAddress),
+        (GstMetaInitFunction) NULL,
+        (GstMetaFreeFunction) NULL,
+        (GstMetaCopyFunction) meta_net_address_copy,
+        (GstMetaTransformFunction) NULL);
+  }
+  return meta_info;
 }
 
 /**
index 91770e4..368490a 100644 (file)
 
 G_BEGIN_DECLS
 
+#if 0
 typedef struct _GstNetBuffer GstNetBuffer;
 typedef struct _GstNetBufferClass GstNetBufferClass;
+#endif
 typedef struct _GstNetAddress GstNetAddress;
 
+#if 0
 #define GST_TYPE_NETBUFFER            (gst_netbuffer_get_type())
 #define GST_IS_NETBUFFER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_NETBUFFER))
 #define GST_IS_NETBUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_NETBUFFER))
 #define GST_NETBUFFER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_NETBUFFER, GstNetBufferClass))
 #define GST_NETBUFFER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_NETBUFFER, GstNetBuffer))
 #define GST_NETBUFFER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_NETBUFFER, GstNetBufferClass))
+#endif
 
 /**
  * GstNetType:
@@ -62,7 +66,7 @@ typedef enum {
 /**
  * GstNetAddress:
  *
- * An opaque network address as used in #GstNetBuffer.
+ * An opaque network address as used in #GstMetaNetAddress.
  */
 struct _GstNetAddress {
   /*< private >*/
@@ -76,36 +80,26 @@ struct _GstNetAddress {
   gpointer _gst_reserved[GST_PADDING];
 };
 
+typedef struct _GstMetaNetAddress GstMetaNetAddress;
+
 /**
- * GstNetBuffer:
- * @buffer: the parent #GstBuffer
- * @from: the address where this buffer came from.
- * @to: the address where this buffer should go to.
+ * GstMetaNetAddress:
  *
- * buffer for use in network sources and sinks.
- * It contains the source or destination address of the buffer.
+ * Buffer metadata for network addresses.
  */
-struct _GstNetBuffer {
-  GstBuffer buffer;
-
-  GstNetAddress from;
-  GstNetAddress to;
+struct _GstMetaNetAddress {
+  GstMeta       meta;
 
-  /*< private >*/
-  gpointer _gst_reserved[GST_PADDING];
-};
-
-struct _GstNetBufferClass {
-  GstBufferClass  buffer_class;
-
-  /*< private >*/
-  gpointer _gst_reserved[GST_PADDING];
+  GstNetAddress naddr;
 };
 
-/* creating buffers */
-GType           gst_netbuffer_get_type           (void);
+const GstMetaInfo *gst_meta_net_address_get_info (void);
+#define GST_META_NET_ADDRESS_INFO (gst_meta_net_address_get_info())
 
-GstNetBuffer*   gst_netbuffer_new                (void);
+#define gst_buffer_get_meta_net_address(b) \
+  ((GstMetaNetAddress*)gst_buffer_get_meta((b),GST_META_NET_ADDRESS_INFO))
+#define gst_buffer_add_meta_net_address(b) \
+  ((GstMetaNetAddress*)gst_buffer_add_meta((b),GST_META_NET_ADDRESS_INFO,NULL))
 
 /* address operations */
 void            gst_netaddress_set_ip4_address   (GstNetAddress *naddr, guint32 address, guint16 port);
index eaa7507..710e5bc 100644 (file)
 
 struct _GstEncodingProfile
 {
-  GstMiniObject parent;
+  GObject parent;
 
   /*< public > */
   gchar *name;
@@ -165,8 +165,7 @@ gst_encoding_profile_get_type (void)
   static volatile gsize g_define_type_id__volatile = 0;
 
   if (g_once_init_enter (&g_define_type_id__volatile)) {
-    GType g_define_type_id =
-        g_type_register_static_simple (GST_TYPE_MINI_OBJECT,
+    GType g_define_type_id = g_type_register_static_simple (G_TYPE_OBJECT,
         g_intern_static_string ("GstEncodingProfile"),
         sizeof (GstEncodingProfileClass),
         (GClassInitFunc) gst_encoding_profile_class_intern_init,
@@ -194,8 +193,9 @@ gst_encoding_profile_get_type (void)
 }
 
 static void
-gst_encoding_profile_finalize (GstEncodingProfile * prof)
+gst_encoding_profile_finalize (GObject * object)
 {
+  GstEncodingProfile *prof = (GstEncodingProfile *) object;
   if (prof->name)
     g_free (prof->name);
   if (prof->format)
@@ -209,10 +209,9 @@ gst_encoding_profile_finalize (GstEncodingProfile * prof)
 }
 
 static void
-gst_encoding_profile_class_init (GstMiniObjectClass * klass)
+gst_encoding_profile_class_init (GObjectClass * klass)
 {
-  klass->finalize =
-      (GstMiniObjectFinalizeFunction) gst_encoding_profile_finalize;
+  klass->finalize = gst_encoding_profile_finalize;
 }
 
 /**
@@ -249,12 +248,13 @@ gst_encoding_profile_get_description (GstEncodingProfile * profile)
  *
  * Since: 0.10.32
  *
- * Returns: the #GstCaps corresponding to the media format used in the profile.
+ * Returns: (transfer full): the #GstCaps corresponding to the media format used
+ * in the profile. Unref after usage.
  */
-const GstCaps *
+GstCaps *
 gst_encoding_profile_get_format (GstEncodingProfile * profile)
 {
-  return profile->format;
+  return (profile->format ? gst_caps_ref (profile->format) : NULL);
 }
 
 /**
@@ -292,17 +292,17 @@ gst_encoding_profile_get_presence (GstEncodingProfile * profile)
  *
  * Since: 0.10.32
  *
- * Returns: The restriction #GstCaps to apply before the encoder
+ * Returns: (transfer full): The restriction #GstCaps to apply before the encoder
  * that will be used in the profile. The fields present in restriction caps are
  * properties of the raw stream (that is before encoding), such as height and
  * width for video and depth and sampling rate for audio. Does not apply to
  * #GstEncodingContainerProfile (since there is no corresponding raw stream).
- * Can be %NULL.
+ * Can be %NULL. Unref after usage.
  */
-const GstCaps *
+GstCaps *
 gst_encoding_profile_get_restriction (GstEncodingProfile * profile)
 {
-  return profile->restriction;
+  return (profile->restriction ? gst_caps_ref (profile->restriction) : NULL);
 }
 
 /**
@@ -432,20 +432,21 @@ gst_encoding_container_profile_init (GstEncodingContainerProfile * prof)
 }
 
 static void
-gst_encoding_container_profile_finalize (GstEncodingContainerProfile * prof)
+gst_encoding_container_profile_finalize (GObject * object)
 {
-  g_list_foreach (prof->encodingprofiles, (GFunc) gst_mini_object_unref, NULL);
+  GstEncodingContainerProfile *prof = (GstEncodingContainerProfile *) object;
+
+  g_list_foreach (prof->encodingprofiles, (GFunc) g_object_unref, NULL);
   g_list_free (prof->encodingprofiles);
 
-  GST_MINI_OBJECT_CLASS (gst_encoding_container_profile_parent_class)->finalize
-      ((GstMiniObject *) prof);
+  G_OBJECT_CLASS (gst_encoding_container_profile_parent_class)->finalize
+      ((GObject *) prof);
 }
 
 static void
-gst_encoding_container_profile_class_init (GstMiniObjectClass * klass)
+gst_encoding_container_profile_class_init (GObjectClass * klass)
 {
-  klass->finalize =
-      (GstMiniObjectFinalizeFunction) gst_encoding_container_profile_finalize;
+  klass->finalize = gst_encoding_container_profile_finalize;
 }
 
 const GList *
@@ -475,7 +476,7 @@ gst_encoding_video_profile_init (GstEncodingVideoProfile * prof)
 }
 
 static void
-gst_encoding_video_profile_class_init (GstMiniObjectClass * klass)
+gst_encoding_video_profile_class_init (GObjectClass * klass)
 {
 }
 
@@ -562,7 +563,7 @@ gst_encoding_audio_profile_init (GstEncodingAudioProfile * prof)
 }
 
 static void
-gst_encoding_audio_profile_class_init (GstMiniObjectClass * klass)
+gst_encoding_audio_profile_class_init (GObjectClass * klass)
 {
 }
 
@@ -688,7 +689,7 @@ common_creation (GType objtype, GstCaps * format, const gchar * preset,
 {
   GstEncodingProfile *prof;
 
-  prof = (GstEncodingProfile *) gst_mini_object_new (objtype);
+  prof = (GstEncodingProfile *) g_object_new (objtype, NULL);
 
   if (name)
     prof->name = g_strdup (name);
@@ -816,8 +817,8 @@ gst_encoding_profile_is_equal (GstEncodingProfile * a, GstEncodingProfile * b)
  *
  * Since: 0.10.32
  *
- * Returns: The full caps the given @profile can consume. Call gst_caps_unref()
- * when you are done with the caps.
+ * Returns: (transfer full): The full caps the given @profile can consume. Call
+ * gst_caps_unref() when you are done with the caps.
  */
 GstCaps *
 gst_encoding_profile_get_input_caps (GstEncodingProfile * profile)
@@ -827,7 +828,7 @@ gst_encoding_profile_get_input_caps (GstEncodingProfile * profile)
   GstStructure *st, *outst;
   GQuark out_name;
   guint i, len;
-  const GstCaps *fcaps;
+  GstCaps *fcaps;
 
   if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) {
     GstCaps *res = gst_caps_new_empty ();
@@ -844,7 +845,7 @@ gst_encoding_profile_get_input_caps (GstEncodingProfile * profile)
 
   /* fast-path */
   if ((profile->restriction == NULL) || gst_caps_is_any (profile->restriction))
-    return gst_caps_copy (fcaps);
+    return gst_caps_ref (fcaps);
 
   /* Combine the format with the restriction caps */
   outst = gst_caps_get_structure (fcaps, 0);
@@ -947,7 +948,7 @@ string_to_profile_transform (const GValue * src_value, GValue * dest_value)
   profile = combo_search (profilename);
 
   if (profile)
-    gst_value_take_mini_object (dest_value, (GstMiniObject *) profile);
+    g_value_take_object (dest_value, (GObject *) profile);
 }
 
 static gboolean
@@ -958,7 +959,7 @@ gst_encoding_profile_deserialize_valfunc (GValue * value, const gchar * s)
   profile = combo_search (s);
 
   if (profile) {
-    gst_value_take_mini_object (value, (GstMiniObject *) profile);
+    g_value_take_object (value, (GObject *) profile);
     return TRUE;
   }
 
index 86becca..6645436 100644 (file)
@@ -43,7 +43,7 @@ G_BEGIN_DECLS
 #define GST_IS_ENCODING_PROFILE(obj)                   \
   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ENCODING_PROFILE))
 typedef struct _GstEncodingProfile GstEncodingProfile;
-typedef GstMiniObjectClass GstEncodingProfileClass;
+typedef GObjectClass GstEncodingProfileClass;
 GType gst_encoding_profile_get_type (void);
 
 
@@ -115,7 +115,7 @@ GType gst_encoding_audio_profile_get_type (void);
  *
  * Since: 0.10.32
  */
-#define gst_encoding_profile_unref(profile) (gst_mini_object_unref ((GstMiniObject*) profile))
+#define gst_encoding_profile_unref(profile) (g_object_unref ((GObject*) profile))
 
 /**
  * gst_encoding_profile_ref:
@@ -125,14 +125,14 @@ GType gst_encoding_audio_profile_get_type (void);
  *
  * Since: 0.10.32
  */
-#define gst_encoding_profile_ref(profile) (gst_mini_object_ref ((GstMiniObject*) profile))
+#define gst_encoding_profile_ref(profile) (g_object_ref ((GObject*) profile))
 
 const gchar *  gst_encoding_profile_get_name(GstEncodingProfile *profile);
 const gchar *  gst_encoding_profile_get_description(GstEncodingProfile *profile);
-const GstCaps *        gst_encoding_profile_get_format(GstEncodingProfile *profile);
+GstCaps *      gst_encoding_profile_get_format(GstEncodingProfile *profile);
 const gchar *  gst_encoding_profile_get_preset(GstEncodingProfile *profile);
 guint  gst_encoding_profile_get_presence(GstEncodingProfile *profile);
-const GstCaps *        gst_encoding_profile_get_restriction(GstEncodingProfile *profile);
+GstCaps *      gst_encoding_profile_get_restriction(GstEncodingProfile *profile);
 
 void   gst_encoding_profile_set_name(GstEncodingProfile *profile, const gchar *name);
 void   gst_encoding_profile_set_description(GstEncodingProfile *profile, const gchar *description);
index 29e67d0..142e4a5 100644 (file)
@@ -74,7 +74,7 @@
 
 struct _GstEncodingTarget
 {
-  GstMiniObject parent;
+  GObject parent;
 
   gchar *name;
   gchar *category;
@@ -85,7 +85,7 @@ struct _GstEncodingTarget
   gchar *keyfile;
 };
 
-G_DEFINE_TYPE (GstEncodingTarget, gst_encoding_target, GST_TYPE_MINI_OBJECT);
+G_DEFINE_TYPE (GstEncodingTarget, gst_encoding_target, G_TYPE_OBJECT);
 
 static void
 gst_encoding_target_init (GstEncodingTarget * target)
@@ -94,8 +94,10 @@ gst_encoding_target_init (GstEncodingTarget * target)
 }
 
 static void
-gst_encoding_target_finalize (GstEncodingTarget * target)
+gst_encoding_target_finalize (GObject * object)
 {
+  GstEncodingTarget *target = (GstEncodingTarget *) object;
+
   GST_DEBUG ("Finalizing");
 
   if (target->name)
@@ -105,15 +107,14 @@ gst_encoding_target_finalize (GstEncodingTarget * target)
   if (target->description)
     g_free (target->description);
 
-  g_list_foreach (target->profiles, (GFunc) gst_mini_object_unref, NULL);
+  g_list_foreach (target->profiles, (GFunc) g_object_unref, NULL);
   g_list_free (target->profiles);
 }
 
 static void
-gst_encoding_target_class_init (GstMiniObjectClass * klass)
+gst_encoding_target_class_init (GObjectClass * klass)
 {
-  klass->finalize =
-      (GstMiniObjectFinalizeFunction) gst_encoding_target_finalize;
+  klass->finalize = gst_encoding_target_finalize;
 }
 
 /**
@@ -281,7 +282,7 @@ gst_encoding_target_new (const gchar * name, const gchar * category,
   if (!validate_name (category))
     goto invalid_category;
 
-  res = (GstEncodingTarget *) gst_mini_object_new (GST_TYPE_ENCODING_TARGET);
+  res = (GstEncodingTarget *) g_object_new (GST_TYPE_ENCODING_TARGET, NULL);
   res->name = g_strdup (name);
   res->category = g_strdup (category);
   res->description = g_strdup (description);
@@ -882,7 +883,7 @@ gst_encoding_target_load (const gchar * name, const gchar * category,
 
   /* Try from local profiles */
   tldir =
-      g_build_filename (g_get_home_dir (), ".gstreamer-" GST_MAJORMINOR,
+      g_build_filename (g_get_user_data_dir (), "gstreamer-" GST_MAJORMINOR,
       GST_ENCODING_TARGET_DIRECTORY, NULL);
   target = gst_encoding_target_subload (tldir, category, lfilename, error);
   g_free (tldir);
@@ -1005,7 +1006,7 @@ gst_encoding_target_save (GstEncodingTarget * target, GError ** error)
 
   lfilename = g_strdup_printf ("%s" GST_ENCODING_TARGET_SUFFIX, target->name);
   filename =
-      g_build_filename (g_get_home_dir (), ".gstreamer-" GST_MAJORMINOR,
+      g_build_filename (g_get_user_data_dir (), "gstreamer-" GST_MAJORMINOR,
       GST_ENCODING_TARGET_DIRECTORY, target->category, lfilename, NULL);
   g_free (lfilename);
 
@@ -1058,7 +1059,8 @@ gst_encoding_list_available_categories (void)
   gchar *topdir;
 
   /* First try user-local categories */
-  topdir = g_build_filename (g_get_home_dir (), ".gstreamer-" GST_MAJORMINOR,
+  topdir =
+      g_build_filename (g_get_user_data_dir (), "gstreamer-" GST_MAJORMINOR,
       GST_ENCODING_TARGET_DIRECTORY, NULL);
   res = get_categories (topdir);
   g_free (topdir);
@@ -1174,7 +1176,8 @@ gst_encoding_list_all_targets (const gchar * categoryname)
   gchar *topdir;
 
   /* Get user-locals */
-  topdir = g_build_filename (g_get_home_dir (), ".gstreamer-" GST_MAJORMINOR,
+  topdir =
+      g_build_filename (g_get_user_data_dir (), "gstreamer-" GST_MAJORMINOR,
       GST_ENCODING_TARGET_DIRECTORY, NULL);
   res = get_all_targets (topdir, categoryname);
   g_free (topdir);
index 70c049d..4dcf598 100644 (file)
@@ -89,7 +89,7 @@ G_BEGIN_DECLS
   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ENCODING_TARGET))
 
 typedef struct _GstEncodingTarget GstEncodingTarget;
-typedef GstMiniObjectClass GstEncodingTargetClass;
+typedef GObjectClass GstEncodingTargetClass;
 
 GType gst_encoding_target_get_type (void);
 
@@ -102,7 +102,7 @@ GType gst_encoding_target_get_type (void);
  * Since: 0.10.32
  */
 #define gst_encoding_target_unref(target) \
-  (gst_mini_object_unref ((GstMiniObject*) target))
+  (g_object_unref ((GObject*) target))
 
 /**
  * gst_encoding_target_ref:
@@ -113,7 +113,7 @@ GType gst_encoding_target_get_type (void);
  * Since: 0.10.32
  */
 #define gst_encoding_target_ref(target) \
-  (gst_mini_object_ref ((GstMiniObject*) target))
+  (g_object_ref ((GObject*) target))
 
 GstEncodingTarget *
 gst_encoding_target_new (const gchar *name, const gchar *category,
index 2edf8e9..124328e 100644 (file)
@@ -42,7 +42,7 @@ static GstDiscovererVideoInfo
 /* Per-stream information */
 
 G_DEFINE_TYPE (GstDiscovererStreamInfo, gst_discoverer_stream_info,
-    GST_TYPE_MINI_OBJECT);
+    G_TYPE_OBJECT);
 
 static void
 gst_discoverer_stream_info_init (GstDiscovererStreamInfo * info)
@@ -51,10 +51,12 @@ gst_discoverer_stream_info_init (GstDiscovererStreamInfo * info)
 }
 
 static void
-gst_discoverer_stream_info_finalize (GstDiscovererStreamInfo * info)
+gst_discoverer_stream_info_finalize (GObject * object)
 {
+  GstDiscovererStreamInfo *info = (GstDiscovererStreamInfo *) object;
+
   if (info->next)
-    gst_mini_object_unref ((GstMiniObject *) info->next);
+    g_object_unref ((GObject *) info->next);
 
   if (info->caps)
     gst_caps_unref (info->caps);
@@ -66,25 +68,17 @@ gst_discoverer_stream_info_finalize (GstDiscovererStreamInfo * info)
     gst_structure_free (info->misc);
 }
 
-static GstDiscovererStreamInfo *
-gst_discoverer_stream_info_copy (GstDiscovererStreamInfo * info)
-{
-  return gst_discoverer_info_copy_int (info, NULL);
-}
-
 static void
-gst_discoverer_stream_info_class_init (GstMiniObjectClass * klass)
+gst_discoverer_stream_info_class_init (GObjectClass * klass)
 {
-  klass->finalize =
-      (GstMiniObjectFinalizeFunction) gst_discoverer_stream_info_finalize;
-  klass->copy = (GstMiniObjectCopyFunction) gst_discoverer_stream_info_copy;
+  klass->finalize = gst_discoverer_stream_info_finalize;
 }
 
 static GstDiscovererStreamInfo *
 gst_discoverer_stream_info_new (void)
 {
   return (GstDiscovererStreamInfo *)
-      gst_mini_object_new (GST_TYPE_DISCOVERER_STREAM_INFO);
+      g_object_new (GST_TYPE_DISCOVERER_STREAM_INFO, NULL);
 }
 
 static GstDiscovererStreamInfo *
@@ -147,28 +141,28 @@ static GstDiscovererContainerInfo *
 gst_discoverer_container_info_new (void)
 {
   return (GstDiscovererContainerInfo *)
-      gst_mini_object_new (GST_TYPE_DISCOVERER_CONTAINER_INFO);
+      g_object_new (GST_TYPE_DISCOVERER_CONTAINER_INFO, NULL);
 }
 
 static void
-gst_discoverer_container_info_finalize (GstDiscovererContainerInfo * info)
+gst_discoverer_container_info_finalize (GObject * object)
 {
+  GstDiscovererContainerInfo *info = (GstDiscovererContainerInfo *) object;
   GList *tmp;
 
   for (tmp = ((GstDiscovererContainerInfo *) info)->streams; tmp;
       tmp = tmp->next)
-    gst_mini_object_unref ((GstMiniObject *) tmp->data);
+    g_object_unref ((GObject *) tmp->data);
 
   gst_discoverer_stream_info_list_free (info->streams);
 
-  gst_discoverer_stream_info_finalize ((GstDiscovererStreamInfo *) info);
+  gst_discoverer_stream_info_finalize ((GObject *) info);
 }
 
 static void
-gst_discoverer_container_info_class_init (GstMiniObjectClass * klass)
+gst_discoverer_container_info_class_init (GObjectClass * klass)
 {
-  klass->finalize =
-      (GstMiniObjectFinalizeFunction) gst_discoverer_container_info_finalize;
+  klass->finalize = gst_discoverer_container_info_finalize;
 }
 
 static GstDiscovererContainerInfo *
@@ -214,7 +208,7 @@ static GstDiscovererAudioInfo *
 gst_discoverer_audio_info_new (void)
 {
   return (GstDiscovererAudioInfo *)
-      gst_mini_object_new (GST_TYPE_DISCOVERER_AUDIO_INFO);
+      g_object_new (GST_TYPE_DISCOVERER_AUDIO_INFO, NULL);
 }
 
 static GstDiscovererAudioInfo *
@@ -238,7 +232,7 @@ G_DEFINE_TYPE (GstDiscovererVideoInfo, gst_discoverer_video_info,
     GST_TYPE_DISCOVERER_STREAM_INFO);
 
 static void
-gst_discoverer_video_info_class_init (GstMiniObjectClass * klass)
+gst_discoverer_video_info_class_init (GObjectClass * klass)
 {
   /* Nothing to initialize */
 }
@@ -253,7 +247,7 @@ static GstDiscovererVideoInfo *
 gst_discoverer_video_info_new (void)
 {
   return (GstDiscovererVideoInfo *)
-      gst_mini_object_new (GST_TYPE_DISCOVERER_VIDEO_INFO);
+      g_object_new (GST_TYPE_DISCOVERER_VIDEO_INFO, NULL);
 }
 
 static GstDiscovererVideoInfo *
@@ -279,7 +273,7 @@ gst_discoverer_video_info_copy_int (GstDiscovererVideoInfo * ptr)
 }
 
 /* Global stream information */
-G_DEFINE_TYPE (GstDiscovererInfo, gst_discoverer_info, GST_TYPE_MINI_OBJECT);
+G_DEFINE_TYPE (GstDiscovererInfo, gst_discoverer_info, G_TYPE_OBJECT);
 
 static void
 gst_discoverer_info_init (GstDiscovererInfo * info)
@@ -288,12 +282,13 @@ gst_discoverer_info_init (GstDiscovererInfo * info)
 }
 
 static void
-gst_discoverer_info_finalize (GstDiscovererInfo * info)
+gst_discoverer_info_finalize (GObject * object)
 {
+  GstDiscovererInfo *info = (GstDiscovererInfo *) object;
   g_free (info->uri);
 
   if (info->stream_info)
-    gst_mini_object_unref ((GstMiniObject *) info->stream_info);
+    g_object_unref ((GObject *) info->stream_info);
 
   if (info->misc)
     gst_structure_free (info->misc);
@@ -307,7 +302,7 @@ gst_discoverer_info_finalize (GstDiscovererInfo * info)
 static GstDiscovererInfo *
 gst_discoverer_info_new (void)
 {
-  return (GstDiscovererInfo *) gst_mini_object_new (GST_TYPE_DISCOVERER_INFO);
+  return (GstDiscovererInfo *) g_object_new (GST_TYPE_DISCOVERER_INFO, NULL);
 }
 
 GstDiscovererInfo *
@@ -350,11 +345,9 @@ gst_discoverer_info_copy (GstDiscovererInfo * ptr)
 }
 
 static void
-gst_discoverer_info_class_init (GstMiniObjectClass * klass)
+gst_discoverer_info_class_init (GObjectClass * klass)
 {
-  klass->finalize =
-      (GstMiniObjectFinalizeFunction) gst_discoverer_info_finalize;
-  klass->copy = (GstMiniObjectCopyFunction) gst_discoverer_info_copy;
+  klass->finalize = gst_discoverer_info_finalize;
 }
 
 /**
index 58d3e52..3a72eed 100644 (file)
@@ -468,7 +468,7 @@ uridecodebin_pad_added_cb (GstElement * uridecodebin, GstPad * pad,
   g_object_set (ps->sink, "silent", TRUE, NULL);
   g_object_set (ps->queue, "max-size-buffers", 1, "silent", TRUE, NULL);
 
-  caps = gst_pad_get_caps_reffed (pad);
+  caps = gst_pad_get_caps (pad, NULL);
 
   if (gst_caps_can_intersect (caps, subs_caps)) {
     /* Subtitle streams are sparse and don't provide any information - don't
@@ -582,7 +582,7 @@ collect_stream_information (GstDiscoverer * dc, PrivateStream * ps, guint idx)
   if (!caps) {
     GST_WARNING ("Couldn't get negotiated caps from %s:%s",
         GST_DEBUG_PAD_NAME (ps->pad));
-    caps = gst_pad_get_caps (ps->pad);
+    caps = gst_pad_get_caps (ps->pad, NULL);
   }
   if (caps) {
     GST_DEBUG ("Got caps %" GST_PTR_FORMAT, caps);
@@ -616,7 +616,7 @@ collect_information (GstDiscoverer * dc, const GstStructure * st,
       return parent;
     else
       return (GstDiscovererStreamInfo *)
-          gst_mini_object_new (GST_TYPE_DISCOVERER_STREAM_INFO);
+          g_object_new (GST_TYPE_DISCOVERER_STREAM_INFO, NULL);
   }
 
   gst_structure_id_get (st, _CAPS_QUARK, GST_TYPE_CAPS, &caps, NULL);
@@ -630,7 +630,7 @@ collect_information (GstDiscoverer * dc, const GstStructure * st,
       info = (GstDiscovererAudioInfo *) parent;
     else {
       info = (GstDiscovererAudioInfo *)
-          gst_mini_object_new (GST_TYPE_DISCOVERER_AUDIO_INFO);
+          g_object_new (GST_TYPE_DISCOVERER_AUDIO_INFO, NULL);
       info->parent.caps = caps;
     }
 
@@ -671,7 +671,7 @@ collect_information (GstDiscoverer * dc, const GstStructure * st,
       info = (GstDiscovererVideoInfo *) parent;
     else {
       info = (GstDiscovererVideoInfo *)
-          gst_mini_object_new (GST_TYPE_DISCOVERER_VIDEO_INFO);
+          g_object_new (GST_TYPE_DISCOVERER_VIDEO_INFO, NULL);
       info->parent.caps = caps;
     }
 
@@ -722,7 +722,7 @@ collect_information (GstDiscoverer * dc, const GstStructure * st,
       info = parent;
     else {
       info = (GstDiscovererStreamInfo *)
-          gst_mini_object_new (GST_TYPE_DISCOVERER_STREAM_INFO);
+          g_object_new (GST_TYPE_DISCOVERER_STREAM_INFO, NULL);
       info->caps = caps;
     }
 
@@ -885,7 +885,7 @@ parse_stream_topology (GstDiscoverer * dc, const GstStructure * topology,
     GST_DEBUG ("next is a list of %d entries", len);
 
     cont = (GstDiscovererContainerInfo *)
-        gst_mini_object_new (GST_TYPE_DISCOVERER_CONTAINER_INFO);
+        g_object_new (GST_TYPE_DISCOVERER_CONTAINER_INFO, NULL);
     cont->parent.caps = caps;
     res = (GstDiscovererStreamInfo *) cont;
 
@@ -1079,16 +1079,20 @@ handle_message (GstDiscoverer * dc, GstMessage * msg)
 
     case GST_MESSAGE_ELEMENT:
     {
-      GQuark sttype = gst_structure_get_name_id (msg->structure);
+      GQuark sttype;
+      const GstStructure *structure;
+
+      structure = gst_message_get_structure (msg);
+      sttype = gst_structure_get_name_id (structure);
       GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg),
-          "structure %" GST_PTR_FORMAT, msg->structure);
+          "structure %" GST_PTR_FORMAT, structure);
       if (sttype == _MISSING_PLUGIN_QUARK) {
         GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg),
             "Setting result to MISSING_PLUGINS");
         dc->priv->current_info->result = GST_DISCOVERER_MISSING_PLUGINS;
-        dc->priv->current_info->misc = gst_structure_copy (msg->structure);
+        dc->priv->current_info->misc = gst_structure_copy (structure);
       } else if (sttype == _STREAM_TOPOLOGY_QUARK) {
-        dc->priv->current_topology = gst_structure_copy (msg->structure);
+        dc->priv->current_topology = gst_structure_copy (structure);
       }
     }
       break;
@@ -1162,7 +1166,7 @@ _setup_locked (GstDiscoverer * dc)
 
   /* Pop URI off the pending URI list */
   dc->priv->current_info =
-      (GstDiscovererInfo *) gst_mini_object_new (GST_TYPE_DISCOVERER_INFO);
+      (GstDiscovererInfo *) g_object_new (GST_TYPE_DISCOVERER_INFO, NULL);
   dc->priv->current_info->uri = (gchar *) dc->priv->pending_uris->data;
   dc->priv->pending_uris =
       g_list_delete_link (dc->priv->pending_uris, dc->priv->pending_uris);
index 671dbaa..5225738 100644 (file)
@@ -32,7 +32,7 @@ G_BEGIN_DECLS
 #define GST_IS_DISCOVERER_STREAM_INFO(obj) \
   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DISCOVERER_STREAM_INFO))
 typedef struct _GstDiscovererStreamInfo GstDiscovererStreamInfo;
-typedef GstMiniObjectClass GstDiscovererStreamInfoClass;
+typedef GObjectClass GstDiscovererStreamInfoClass;
 GType gst_discoverer_stream_info_get_type (void);
 
 /**
@@ -56,8 +56,8 @@ GType gst_discoverer_stream_info_get_type (void);
  *
  * Since: 0.10.31
  */
-#define gst_discoverer_stream_info_ref(info) ((GstDiscovererStreamInfo*) gst_mini_object_ref((GstMiniObject*) info))
-#define gst_discoverer_stream_info_unref(info) (gst_mini_object_unref((GstMiniObject*) info))
+#define gst_discoverer_stream_info_ref(info) ((GstDiscovererStreamInfo*) g_object_ref((GObject*) info))
+#define gst_discoverer_stream_info_unref(info) (g_object_unref((GObject*) info))
 
 GstDiscovererStreamInfo* gst_discoverer_stream_info_get_previous(GstDiscovererStreamInfo* info);
 GstDiscovererStreamInfo* gst_discoverer_stream_info_get_next(GstDiscovererStreamInfo* info);
@@ -80,7 +80,7 @@ const gchar *            gst_discoverer_stream_info_get_stream_type_nick(GstDisc
 #define GST_IS_DISCOVERER_CONTAINER_INFO(obj) \
   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DISCOVERER_CONTAINER_INFO))
 typedef struct _GstDiscovererContainerInfo GstDiscovererContainerInfo;
-typedef GstMiniObjectClass GstDiscovererContainerInfoClass;
+typedef GObjectClass GstDiscovererContainerInfoClass;
 
 GType gst_discoverer_container_info_get_type (void);
 
@@ -101,7 +101,7 @@ GList *gst_discoverer_container_info_get_streams(GstDiscovererContainerInfo *inf
 #define GST_IS_DISCOVERER_AUDIO_INFO(obj) \
   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DISCOVERER_AUDIO_INFO))
 typedef struct _GstDiscovererAudioInfo GstDiscovererAudioInfo;
-typedef GstMiniObjectClass GstDiscovererAudioInfoClass;
+typedef GObjectClass GstDiscovererAudioInfoClass;
 
 GType gst_discoverer_audio_info_get_type (void);
 
@@ -125,7 +125,7 @@ guint gst_discoverer_audio_info_get_max_bitrate(const GstDiscovererAudioInfo* in
 #define GST_IS_DISCOVERER_VIDEO_INFO(obj) \
   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DISCOVERER_VIDEO_INFO))
 typedef struct _GstDiscovererVideoInfo GstDiscovererVideoInfo;
-typedef GstMiniObjectClass GstDiscovererVideoInfoClass;
+typedef GObjectClass GstDiscovererVideoInfoClass;
 GType gst_discoverer_video_info_get_type (void);
 
 guint           gst_discoverer_video_info_get_width(const GstDiscovererVideoInfo* info);
@@ -178,11 +178,11 @@ typedef struct _GstDiscovererInfo GstDiscovererInfo;
   (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DISCOVERER_INFO, GstDiscovererInfo))
 #define GST_IS_DISCOVERER_INFO(obj) \
   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DISCOVERER_INFO))
-typedef GstMiniObjectClass GstDiscovererInfoClass;
+typedef GObjectClass GstDiscovererInfoClass;
 GType gst_discoverer_info_get_type (void);
 
-#define gst_discoverer_info_unref(info) (gst_mini_object_unref((GstMiniObject*)info))
-#define gst_discoverer_info_ref(info) (gst_mini_object_ref((GstMiniObject*)info))
+#define gst_discoverer_info_unref(info) (g_object_unref((GObject*)info))
+#define gst_discoverer_info_ref(info) (g_object_ref((Gbject*)info))
 
 GstDiscovererInfo*        gst_discoverer_info_copy (GstDiscovererInfo * ptr);
 
index 1b6d44b..896d28d 100644 (file)
@@ -406,18 +406,20 @@ gst_missing_plugin_message_get_installer_detail (GstMessage * msg)
   GString *str = NULL;
   gchar *detail = NULL;
   gchar *desc;
+  const GstStructure *structure;
 
   g_return_val_if_fail (gst_is_missing_plugin_message (msg), NULL);
 
-  GST_LOG ("Parsing missing-plugin message: %" GST_PTR_FORMAT, msg->structure);
+  structure = gst_message_get_structure (msg);
+  GST_LOG ("Parsing missing-plugin message: %" GST_PTR_FORMAT, structure);
 
-  missing_type = missing_structure_get_type (msg->structure);
+  missing_type = missing_structure_get_type (structure);
   if (missing_type == GST_MISSING_TYPE_UNKNOWN) {
     GST_WARNING ("couldn't parse 'type' field");
     goto error;
   }
 
-  type = gst_structure_get_string (msg->structure, "type");
+  type = gst_structure_get_string (structure, "type");
   g_assert (type != NULL);      /* validity already checked above */
 
   /* FIXME: use gst_installer_detail_new() here too */
@@ -444,14 +446,14 @@ gst_missing_plugin_message_get_installer_detail (GstMessage * msg)
     case GST_MISSING_TYPE_URISOURCE:
     case GST_MISSING_TYPE_URISINK:
     case GST_MISSING_TYPE_ELEMENT:
-      if (!missing_structure_get_string_detail (msg->structure, &detail))
+      if (!missing_structure_get_string_detail (structure, &detail))
         goto error;
       break;
     case GST_MISSING_TYPE_DECODER:
     case GST_MISSING_TYPE_ENCODER:{
       GstCaps *caps = NULL;
 
-      if (!missing_structure_get_caps_detail (msg->structure, &caps))
+      if (!missing_structure_get_caps_detail (structure, &caps))
         goto error;
 
       detail = gst_caps_to_string (caps);
@@ -498,19 +500,21 @@ gst_missing_plugin_message_get_description (GstMessage * msg)
   GstMissingType missing_type;
   const gchar *desc;
   gchar *ret = NULL;
+  const GstStructure *structure;
 
   g_return_val_if_fail (gst_is_missing_plugin_message (msg), NULL);
 
-  GST_LOG ("Parsing missing-plugin message: %" GST_PTR_FORMAT, msg->structure);
+  structure = gst_message_get_structure (msg);
+  GST_LOG ("Parsing missing-plugin message: %" GST_PTR_FORMAT, structure);
 
-  desc = gst_structure_get_string (msg->structure, "name");
+  desc = gst_structure_get_string (structure, "name");
   if (desc != NULL && *desc != '\0') {
     ret = g_strdup (desc);
     goto done;
   }
 
   /* fallback #1 */
-  missing_type = missing_structure_get_type (msg->structure);
+  missing_type = missing_structure_get_type (structure);
 
   switch (missing_type) {
     case GST_MISSING_TYPE_URISOURCE:
@@ -518,7 +522,7 @@ gst_missing_plugin_message_get_description (GstMessage * msg)
     case GST_MISSING_TYPE_ELEMENT:{
       gchar *detail = NULL;
 
-      if (missing_structure_get_string_detail (msg->structure, &detail)) {
+      if (missing_structure_get_string_detail (structure, &detail)) {
         if (missing_type == GST_MISSING_TYPE_URISOURCE)
           ret = gst_pb_utils_get_source_description (detail);
         else if (missing_type == GST_MISSING_TYPE_URISINK)
@@ -533,7 +537,7 @@ gst_missing_plugin_message_get_description (GstMessage * msg)
     case GST_MISSING_TYPE_ENCODER:{
       GstCaps *caps = NULL;
 
-      if (missing_structure_get_caps_detail (msg->structure, &caps)) {
+      if (missing_structure_get_caps_detail (structure, &caps)) {
         if (missing_type == GST_MISSING_TYPE_DECODER)
           ret = gst_pb_utils_get_decoder_description (caps);
         else
@@ -591,13 +595,16 @@ done:
 gboolean
 gst_is_missing_plugin_message (GstMessage * msg)
 {
+  const GstStructure *structure;
+
   g_return_val_if_fail (msg != NULL, FALSE);
   g_return_val_if_fail (GST_IS_MESSAGE (msg), FALSE);
 
-  if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ELEMENT || msg->structure == NULL)
+  structure = gst_message_get_structure (msg);
+  if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ELEMENT || structure == NULL)
     return FALSE;
 
-  return gst_structure_has_name (msg->structure, "missing-plugin");
+  return gst_structure_has_name (structure, "missing-plugin");
 }
 
 /* takes ownership of the description */
index 5031df0..2d7fcd8 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 struct _GstDiscovererStreamInfo {
-  GstMiniObject          parent;
+  GObject                parent;
 
   GstDiscovererStreamInfo *previous;  /* NULL for starting points */
   GstDiscovererStreamInfo *next; /* NULL for containers */
@@ -65,7 +65,7 @@ struct _GstDiscovererVideoInfo {
 };
 
 struct _GstDiscovererInfo {
-  GstMiniObject parent;
+  GObject parent;
 
   gchar *uri;
   GstDiscovererResult result;
index 40b2bf6..7d4c148 100644 (file)
@@ -908,18 +908,19 @@ gst_riff_create_video_caps (guint32 codec_fcc,
   if (palette) {
     GstBuffer *copy;
     guint num_colors;
+    gsize size;
 
     if (strf != NULL)
       num_colors = strf->num_colors;
     else
       num_colors = 256;
 
-    if (GST_BUFFER_SIZE (palette) >= (num_colors * 4)) {
+    size = gst_buffer_get_size (palette);
+
+    if (size >= (num_colors * 4)) {
       /* palette is always at least 256*4 bytes */
-      copy =
-          gst_buffer_new_and_alloc (MAX (GST_BUFFER_SIZE (palette), 256 * 4));
-      memcpy (GST_BUFFER_DATA (copy), GST_BUFFER_DATA (palette),
-          GST_BUFFER_SIZE (palette));
+      copy = gst_buffer_new_and_alloc (MAX (size, 256 * 4));
+      gst_buffer_copy_into (copy, palette, GST_BUFFER_COPY_MEMORY, 0, size);
 
 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
       {
@@ -1466,25 +1467,28 @@ gst_riff_create_audio_caps (guint16 codec_id,
       guint16 valid_bits_per_sample;
       guint32 channel_mask;
       guint32 subformat_guid[4];
-      const guint8 *data;
+      guint8 *data;
+      gsize size;
 
       channels_max = 8;
 
       /* should be at least 22 bytes */
-      if (strf_data == NULL || GST_BUFFER_SIZE (strf_data) < 22) {
+      size = gst_buffer_get_size (strf_data);
+
+      if (strf_data == NULL || size < 22) {
         GST_WARNING ("WAVE_FORMAT_EXTENSIBLE data size is %d (expected: 22)",
-            (strf_data) ? GST_BUFFER_SIZE (strf_data) : -1);
+            (strf_data) ? size : -1);
         return NULL;
       }
 
-      data = GST_BUFFER_DATA (strf_data);
-
+      data = gst_buffer_map (strf_data, &size, NULL, GST_MAP_READ);
       valid_bits_per_sample = GST_READ_UINT16_LE (data);
       channel_mask = GST_READ_UINT32_LE (data + 2);
       subformat_guid[0] = GST_READ_UINT32_LE (data + 6);
       subformat_guid[1] = GST_READ_UINT32_LE (data + 10);
       subformat_guid[2] = GST_READ_UINT32_LE (data + 14);
       subformat_guid[3] = GST_READ_UINT32_LE (data + 18);
+      gst_buffer_unmap (strf_data, data, size);
 
       GST_DEBUG ("valid bps    = %u", valid_bits_per_sample);
       GST_DEBUG ("channel mask = 0x%08x", channel_mask);
index e5983be..c422f04 100644 (file)
@@ -52,8 +52,10 @@ gst_riff_read_chunk (GstElement * element,
 {
   GstBuffer *buf;
   GstFlowReturn res;
+  guint8 *data;
   guint size;
   guint64 offset = *_offset;
+  gsize bsize;
 
   g_return_val_if_fail (element != NULL, GST_FLOW_ERROR);
   g_return_val_if_fail (pad != NULL, GST_FLOW_ERROR);
@@ -65,11 +67,13 @@ skip_junk:
   size = 8;
   if ((res = gst_pad_pull_range (pad, offset, size, &buf)) != GST_FLOW_OK)
     return res;
-  else if (GST_BUFFER_SIZE (buf) < size)
+  else if (gst_buffer_get_size (buf) < size)
     goto too_small;
 
-  *tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
-  size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
+  data = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+  *tag = GST_READ_UINT32_LE (data);
+  size = GST_READ_UINT32_LE (data + 4);
+  gst_buffer_unmap (buf, data, bsize);
   gst_buffer_unref (buf);
 
   GST_DEBUG_OBJECT (element, "fourcc=%" GST_FOURCC_FORMAT ", size=%u",
@@ -86,7 +90,7 @@ skip_junk:
 
   if ((res = gst_pad_pull_range (pad, offset + 8, size, &buf)) != GST_FLOW_OK)
     return res;
-  else if (GST_BUFFER_SIZE (buf) < size)
+  else if (gst_buffer_get_size (buf) < size)
     goto too_small;
 
   *_chunk_data = buf;
@@ -99,7 +103,7 @@ too_small:
   {
     /* short read, we return UNEXPECTED to mark the EOS case */
     GST_DEBUG_OBJECT (element, "not enough data (available=%u, needed=%u)",
-        GST_BUFFER_SIZE (buf), size);
+        gst_buffer_get_size (buf), size);
     gst_buffer_unref (buf);
     return GST_FLOW_UNEXPECTED;
   }
@@ -125,7 +129,8 @@ gst_riff_parse_chunk (GstElement * element, GstBuffer * buf,
 {
   guint size, bufsize;
   guint32 fourcc;
-  guint8 *data;
+  guint8 *data, *ptr;
+  gsize bsize;
   guint offset = *_offset;
 
   g_return_val_if_fail (element != NULL, FALSE);
@@ -137,7 +142,7 @@ gst_riff_parse_chunk (GstElement * element, GstBuffer * buf,
   *chunk_data = NULL;
   *_fourcc = 0;
 
-  bufsize = GST_BUFFER_SIZE (buf);
+  bufsize = gst_buffer_get_size (buf);
 
   if (bufsize == offset)
     goto end_offset;
@@ -146,9 +151,11 @@ gst_riff_parse_chunk (GstElement * element, GstBuffer * buf,
     goto too_small;
 
   /* read header */
-  data = GST_BUFFER_DATA (buf) + offset;
-  fourcc = GST_READ_UINT32_LE (data);
-  size = GST_READ_UINT32_LE (data + 4);
+  data = ptr = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+  ptr += offset;
+  fourcc = GST_READ_UINT32_LE (ptr);
+  size = GST_READ_UINT32_LE (ptr + 4);
+  gst_buffer_unmap (buf, data, bsize);
 
   GST_DEBUG_OBJECT (element, "fourcc=%" GST_FOURCC_FORMAT ", size=%u",
       GST_FOURCC_ARGS (fourcc), size);
@@ -165,7 +172,8 @@ gst_riff_parse_chunk (GstElement * element, GstBuffer * buf,
   }
 
   if (size)
-    *chunk_data = gst_buffer_create_sub (buf, offset + 8, size);
+    *chunk_data =
+        gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, offset + 8, size);
   else
     *chunk_data = NULL;
 
@@ -217,19 +225,21 @@ gst_riff_parse_file_header (GstElement * element,
 {
   guint8 *data;
   guint32 tag;
+  gsize size;
 
   g_return_val_if_fail (buf != NULL, FALSE);
   g_return_val_if_fail (doctype != NULL, FALSE);
 
-  if (GST_BUFFER_SIZE (buf) < 12)
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  if (size < 12)
     goto too_small;
 
-  data = GST_BUFFER_DATA (buf);
   tag = GST_READ_UINT32_LE (data);
   if (tag != GST_RIFF_TAG_RIFF && tag != GST_RIFF_TAG_AVF0)
     goto not_riff;
 
   *doctype = GST_READ_UINT32_LE (data + 8);
+  gst_buffer_unmap (buf, data, size);
 
   gst_buffer_unref (buf);
 
@@ -240,7 +250,8 @@ too_small:
   {
     GST_ELEMENT_ERROR (element, STREAM, WRONG_TYPE, (NULL),
         ("Not enough data to parse RIFF header (%d available, %d needed)",
-            GST_BUFFER_SIZE (buf), 12));
+            size, 12));
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -249,6 +260,7 @@ not_riff:
     GST_ELEMENT_ERROR (element, STREAM, WRONG_TYPE, (NULL),
         ("Stream is no RIFF stream: %" GST_FOURCC_FORMAT,
             GST_FOURCC_ARGS (tag)));
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -272,14 +284,19 @@ gst_riff_parse_strh (GstElement * element,
     GstBuffer * buf, gst_riff_strh ** _strh)
 {
   gst_riff_strh *strh;
+  guint8 *data;
+  gsize size;
 
   g_return_val_if_fail (buf != NULL, FALSE);
   g_return_val_if_fail (_strh != NULL, FALSE);
 
-  if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strh))
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  if (size < sizeof (gst_riff_strh))
     goto too_small;
 
-  strh = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  strh = g_memdup (data, size);
+  gst_buffer_unmap (buf, data, size);
+
   gst_buffer_unref (buf);
 
 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
@@ -329,7 +346,8 @@ too_small:
   {
     GST_ERROR_OBJECT (element,
         "Too small strh (%d available, %d needed)",
-        GST_BUFFER_SIZE (buf), (int) sizeof (gst_riff_strh));
+        size, (int) sizeof (gst_riff_strh));
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -357,15 +375,19 @@ gst_riff_parse_strf_vids (GstElement * element,
     GstBuffer * buf, gst_riff_strf_vids ** _strf, GstBuffer ** data)
 {
   gst_riff_strf_vids *strf;
+  guint8 *bdata;
+  gsize size;
 
   g_return_val_if_fail (buf != NULL, FALSE);
   g_return_val_if_fail (_strf != NULL, FALSE);
   g_return_val_if_fail (data != NULL, FALSE);
 
-  if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strf_vids))
+  bdata = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  if (size < sizeof (gst_riff_strf_vids))
     goto too_small;
 
-  strf = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  strf = g_memdup (bdata, size);
+  gst_buffer_unmap (buf, bdata, size);
 
 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
   strf->size = GUINT32_FROM_LE (strf->size);
@@ -383,16 +405,18 @@ gst_riff_parse_strf_vids (GstElement * element,
 
   /* size checking */
   *data = NULL;
-  if (strf->size > GST_BUFFER_SIZE (buf)) {
+  if (strf->size > size) {
     GST_WARNING_OBJECT (element,
         "strf_vids header gave %d bytes data, only %d available",
-        strf->size, GST_BUFFER_SIZE (buf));
-    strf->size = GST_BUFFER_SIZE (buf);
+        strf->size, size);
+    strf->size = size;
   }
-  if (sizeof (gst_riff_strf_vids) < GST_BUFFER_SIZE (buf)) {
-    *data = gst_buffer_create_sub (buf, sizeof (gst_riff_strf_vids),
-        GST_BUFFER_SIZE (buf) - sizeof (gst_riff_strf_vids));
+  if (sizeof (gst_riff_strf_vids) < size) {
+    *data =
+        gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
+        sizeof (gst_riff_strf_vids), size - sizeof (gst_riff_strf_vids));
   }
+  gst_buffer_unref (buf);
 
   /* debug */
   GST_INFO_OBJECT (element, "strf tag found in context vids:");
@@ -409,9 +433,8 @@ gst_riff_parse_strf_vids (GstElement * element,
   GST_INFO_OBJECT (element, " num_colors  %d", strf->num_colors);
   GST_INFO_OBJECT (element, " imp_colors  %d", strf->imp_colors);
   if (*data)
-    GST_INFO_OBJECT (element, " %d bytes extradata", GST_BUFFER_SIZE (*data));
-
-  gst_buffer_unref (buf);
+    GST_INFO_OBJECT (element, " %d bytes extradata",
+        gst_buffer_get_size (*data));
 
   *_strf = strf;
 
@@ -422,7 +445,8 @@ too_small:
   {
     GST_ERROR_OBJECT (element,
         "Too small strf_vids (%d available, %d needed)",
-        GST_BUFFER_SIZE (buf), (int) sizeof (gst_riff_strf_vids));
+        size, (int) sizeof (gst_riff_strf_vids));
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -450,18 +474,18 @@ gst_riff_parse_strf_auds (GstElement * element,
     GstBuffer * buf, gst_riff_strf_auds ** _strf, GstBuffer ** data)
 {
   gst_riff_strf_auds *strf;
-  guint bufsize;
+  gsize bsize;
+  guint8 *bdata;
 
   g_return_val_if_fail (buf != NULL, FALSE);
   g_return_val_if_fail (_strf != NULL, FALSE);
   g_return_val_if_fail (data != NULL, FALSE);
 
-  bufsize = GST_BUFFER_SIZE (buf);
-
-  if (bufsize < sizeof (gst_riff_strf_auds))
+  bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+  if (bsize < sizeof (gst_riff_strf_auds))
     goto too_small;
 
-  strf = g_memdup (GST_BUFFER_DATA (buf), bufsize);
+  strf = g_memdup (bdata, bsize);
 
 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
   strf->format = GUINT16_FROM_LE (strf->format);
@@ -474,18 +498,19 @@ gst_riff_parse_strf_auds (GstElement * element,
 
   /* size checking */
   *data = NULL;
-  if (bufsize > sizeof (gst_riff_strf_auds) + 2) {
+  if (bsize > sizeof (gst_riff_strf_auds) + 2) {
     gint len;
 
-    len = GST_READ_UINT16_LE (&GST_BUFFER_DATA (buf)[16]);
-    if (len + 2 + sizeof (gst_riff_strf_auds) > bufsize) {
+    len = GST_READ_UINT16_LE (&data[16]);
+    if (len + 2 + sizeof (gst_riff_strf_auds) > bsize) {
       GST_WARNING_OBJECT (element,
           "Extradata indicated %d bytes, but only %" G_GSSIZE_FORMAT
-          " available", len, bufsize - 2 - sizeof (gst_riff_strf_auds));
-      len = bufsize - 2 - sizeof (gst_riff_strf_auds);
+          " available", len, bsize - 2 - sizeof (gst_riff_strf_auds));
+      len = bsize - 2 - sizeof (gst_riff_strf_auds);
     }
     if (len)
-      *data = gst_buffer_create_sub (buf, sizeof (gst_riff_strf_auds) + 2, len);
+      *data = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
+          sizeof (gst_riff_strf_auds) + 2, len);
   }
 
   /* debug */
@@ -497,8 +522,10 @@ gst_riff_parse_strf_auds (GstElement * element,
   GST_INFO_OBJECT (element, " blockalign  %d", strf->blockalign);
   GST_INFO_OBJECT (element, " size        %d", strf->size);
   if (*data)
-    GST_INFO_OBJECT (element, " %d bytes extradata", GST_BUFFER_SIZE (*data));
+    GST_INFO_OBJECT (element, " %d bytes extradata",
+        gst_buffer_get_size (*data));
 
+  gst_buffer_unmap (buf, bdata, bsize);
   gst_buffer_unref (buf);
 
   *_strf = strf;
@@ -510,7 +537,8 @@ too_small:
   {
     GST_ERROR_OBJECT (element,
         "Too small strf_auds (%d available, %" G_GSSIZE_FORMAT " needed)",
-        bufsize, sizeof (gst_riff_strf_auds));
+        bsize, sizeof (gst_riff_strf_auds));
+    gst_buffer_unmap (buf, bdata, bsize);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -538,15 +566,20 @@ gst_riff_parse_strf_iavs (GstElement * element,
     GstBuffer * buf, gst_riff_strf_iavs ** _strf, GstBuffer ** data)
 {
   gst_riff_strf_iavs *strf;
+  gsize bsize;
+  guint8 *bdata;
 
   g_return_val_if_fail (buf != NULL, FALSE);
   g_return_val_if_fail (_strf != NULL, FALSE);
   g_return_val_if_fail (data != NULL, FALSE);
 
-  if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_strf_iavs))
+  bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+  if (bsize < sizeof (gst_riff_strf_iavs))
     goto too_small;
 
-  strf = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  strf = g_memdup (bdata, bsize);
+  gst_buffer_unmap (buf, bdata, bsize);
+
   gst_buffer_unref (buf);
 
 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
@@ -581,7 +614,8 @@ too_small:
   {
     GST_ERROR_OBJECT (element,
         "Too small strf_iavs (%d available, %" G_GSSIZE_FORMAT " needed)",
-        GST_BUFFER_SIZE (buf), sizeof (gst_riff_strf_iavs));
+        bsize, sizeof (gst_riff_strf_iavs));
+    gst_buffer_unmap (buf, bdata, bsize);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -601,8 +635,9 @@ void
 gst_riff_parse_info (GstElement * element,
     GstBuffer * buf, GstTagList ** _taglist)
 {
-  guint8 *data;
-  guint size, tsize;
+  guint8 *data, *ptr;
+  gsize size, left;
+  guint tsize;
   guint32 tag;
   const gchar *type;
   GstTagList *taglist;
@@ -614,23 +649,26 @@ gst_riff_parse_info (GstElement * element,
     *_taglist = NULL;
     return;
   }
-  data = GST_BUFFER_DATA (buf);
-  size = GST_BUFFER_SIZE (buf);
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+
   taglist = gst_tag_list_new ();
 
-  while (size > 8) {
-    tag = GST_READ_UINT32_LE (data);
-    tsize = GST_READ_UINT32_LE (data + 4);
-    size -= 8;
-    data += 8;
+  ptr = data;
+  left = size;
+
+  while (left > 8) {
+    tag = GST_READ_UINT32_LE (ptr);
+    tsize = GST_READ_UINT32_LE (ptr + 4);
+    left -= 8;
+    ptr += 8;
 
     GST_DEBUG ("tag %" GST_FOURCC_FORMAT ", size %u",
         GST_FOURCC_ARGS (tag), tsize);
 
-    if (tsize > size) {
+    if (tsize > left) {
       GST_WARNING_OBJECT (element,
-          "Tagsize %d is larger than available data %d", tsize, size);
-      tsize = size;
+          "Tagsize %d is larger than available data %d", tsize, left);
+      tsize = left;
     }
 
     /* find out the type of metadata */
@@ -712,13 +750,13 @@ gst_riff_parse_info (GstElement * element,
         break;
     }
 
-    if (type != NULL && data[0] != '\0') {
+    if (type != NULL && ptr[0] != '\0') {
       static const gchar *env_vars[] = { "GST_AVI_TAG_ENCODING",
         "GST_RIFF_TAG_ENCODING", "GST_TAG_ENCODING", NULL
       };
       gchar *val;
 
-      val = gst_tag_freeform_string_to_utf8 ((gchar *) data, tsize, env_vars);
+      val = gst_tag_freeform_string_to_utf8 ((gchar *) ptr, tsize, env_vars);
 
       if (val) {
         gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, type, val, NULL);
@@ -730,12 +768,12 @@ gst_riff_parse_info (GstElement * element,
 
     if (tsize & 1) {
       tsize++;
-      if (tsize > size)
-        tsize = size;
+      if (tsize > left)
+        tsize = left;
     }
 
-    data += tsize;
-    size -= tsize;
+    ptr += tsize;
+    left -= tsize;
   }
 
   if (!gst_tag_list_is_empty (taglist)) {
@@ -744,6 +782,7 @@ gst_riff_parse_info (GstElement * element,
     *_taglist = NULL;
     gst_tag_list_free (taglist);
   }
+  gst_buffer_unmap (buf, data, size);
 
   return;
 }
index d1a43a9..b8b78d5 100644 (file)
@@ -159,13 +159,9 @@ static GstStateChangeReturn gst_base_rtp_payload_audio_change_state (GstElement
 static gboolean gst_base_rtp_payload_audio_handle_event (GstPad * pad,
     GstEvent * event);
 
-GST_BOILERPLATE (GstBaseRTPAudioPayload, gst_base_rtp_audio_payload,
-    GstBaseRTPPayload, GST_TYPE_BASE_RTP_PAYLOAD);
-
-static void
-gst_base_rtp_audio_payload_base_init (gpointer klass)
-{
-}
+#define gst_base_rtp_audio_payload_parent_class parent_class
+G_DEFINE_TYPE (GstBaseRTPAudioPayload, gst_base_rtp_audio_payload,
+    GST_TYPE_BASE_RTP_PAYLOAD);
 
 static void
 gst_base_rtp_audio_payload_class_init (GstBaseRTPAudioPayloadClass * klass)
@@ -202,8 +198,7 @@ gst_base_rtp_audio_payload_class_init (GstBaseRTPAudioPayloadClass * klass)
 }
 
 static void
-gst_base_rtp_audio_payload_init (GstBaseRTPAudioPayload * payload,
-    GstBaseRTPAudioPayloadClass * klass)
+gst_base_rtp_audio_payload_init (GstBaseRTPAudioPayload * payload)
 {
   payload->priv = GST_BASE_RTP_AUDIO_PAYLOAD_GET_PRIVATE (payload);
 
@@ -404,19 +399,23 @@ gst_base_rtp_audio_payload_set_meta (GstBaseRTPAudioPayload * payload,
 {
   GstBaseRTPPayload *basepayload;
   GstBaseRTPAudioPayloadPrivate *priv;
+  GstRTPBuffer rtp;
 
   basepayload = GST_BASE_RTP_PAYLOAD_CAST (payload);
   priv = payload->priv;
 
   /* set payload type */
-  gst_rtp_buffer_set_payload_type (buffer, basepayload->pt);
+  gst_rtp_buffer_map (buffer, GST_MAP_WRITE, &rtp);
+  gst_rtp_buffer_set_payload_type (&rtp, basepayload->pt);
   /* set marker bit for disconts */
   if (priv->discont) {
     GST_DEBUG_OBJECT (payload, "Setting marker and DISCONT");
-    gst_rtp_buffer_set_marker (buffer, TRUE);
+    gst_rtp_buffer_set_marker (&rtp, TRUE);
     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
     priv->discont = FALSE;
   }
+  gst_rtp_buffer_unmap (&rtp);
+
   GST_BUFFER_TIMESTAMP (buffer) = timestamp;
 
   /* get the offset in RTP time */
@@ -456,6 +455,7 @@ gst_base_rtp_audio_payload_push (GstBaseRTPAudioPayload * baseaudiopayload,
   GstBuffer *outbuf;
   guint8 *payload;
   GstFlowReturn ret;
+  GstRTPBuffer rtp;
 
   basepayload = GST_BASE_RTP_PAYLOAD (baseaudiopayload);
 
@@ -466,8 +466,10 @@ gst_base_rtp_audio_payload_push (GstBaseRTPAudioPayload * baseaudiopayload,
   outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
 
   /* copy payload */
-  payload = gst_rtp_buffer_get_payload (outbuf);
+  gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
+  payload = gst_rtp_buffer_get_payload (&rtp);
   memcpy (payload, data, payload_len);
+  gst_rtp_buffer_unmap (&rtp);
 
   /* set metadata */
   gst_base_rtp_audio_payload_set_meta (baseaudiopayload, outbuf, payload_len,
@@ -492,7 +494,7 @@ gst_base_rtp_audio_payload_push_buffer (GstBaseRTPAudioPayload *
   priv = baseaudiopayload->priv;
   basepayload = GST_BASE_RTP_PAYLOAD (baseaudiopayload);
 
-  payload_len = GST_BUFFER_SIZE (buffer);
+  payload_len = gst_buffer_get_size (buffer);
 
   GST_DEBUG_OBJECT (baseaudiopayload, "Pushing %d bytes ts %" GST_TIME_FORMAT,
       payload_len, GST_TIME_ARGS (timestamp));
@@ -511,24 +513,29 @@ gst_base_rtp_audio_payload_push_buffer (GstBaseRTPAudioPayload *
 
   if (priv->buffer_list) {
     GstBufferList *list;
-    GstBufferListIterator *it;
+    guint i, len;
 
     list = gst_buffer_list_new ();
-    it = gst_buffer_list_iterate (list);
+    len = gst_buffer_list_len (list);
 
-    /* add both buffers to the buffer list */
-    gst_buffer_list_iterator_add_group (it);
-    gst_buffer_list_iterator_add (it, outbuf);
-    gst_buffer_list_iterator_add (it, buffer);
-
-    gst_buffer_list_iterator_free (it);
+    for (i = 0; i < len; i++) {
+      /* FIXME */
+      g_warning ("bufferlist not implemented");
+      gst_buffer_list_add (list, outbuf);
+      gst_buffer_list_add (list, buffer);
+    }
 
     GST_DEBUG_OBJECT (baseaudiopayload, "Pushing list %p", list);
     ret = gst_basertppayload_push_list (basepayload, list);
   } else {
+    GstRTPBuffer rtp;
+
     /* copy payload */
-    payload = gst_rtp_buffer_get_payload (outbuf);
-    memcpy (payload, GST_BUFFER_DATA (buffer), payload_len);
+    gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
+    payload = gst_rtp_buffer_get_payload (&rtp);
+    gst_buffer_extract (buffer, 0, payload, payload_len);
+    gst_rtp_buffer_unmap (&rtp);
+
     gst_buffer_unref (buffer);
 
     GST_DEBUG_OBJECT (baseaudiopayload, "Pushing buffer %p", outbuf);
@@ -607,13 +614,17 @@ gst_base_rtp_audio_payload_flush (GstBaseRTPAudioPayload * baseaudiopayload,
         gst_base_rtp_audio_payload_push_buffer (baseaudiopayload, buffer,
         timestamp);
   } else {
+    GstRTPBuffer rtp;
+
     /* create buffer to hold the payload */
     outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
 
     /* copy payload */
-    payload = gst_rtp_buffer_get_payload (outbuf);
+    gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
+    payload = gst_rtp_buffer_get_payload (&rtp);
     gst_adapter_copy (adapter, payload, 0, payload_len);
     gst_adapter_flush (adapter, payload_len);
+    gst_rtp_buffer_unmap (&rtp);
 
     /* set metadata */
     gst_base_rtp_audio_payload_set_meta (baseaudiopayload, outbuf, payload_len,
@@ -861,7 +872,7 @@ gst_base_rtp_audio_payload_handle_buffer (GstBaseRTPPayload *
       "Calculated min_payload_len %u and max_payload_len %u",
       min_payload_len, max_payload_len);
 
-  size = GST_BUFFER_SIZE (buffer);
+  size = gst_buffer_get_size (buffer);
 
   /* shortcut, we don't need to use the adapter when the packet can be pushed
    * through directly. */
index 9c33413..c8be565 100644 (file)
 
 #include "gstbasertpdepayload.h"
 
-#ifdef GST_DISABLE_DEPRECATED
-#define QUEUE_LOCK_INIT(base)   (g_static_rec_mutex_init(&base->queuelock))
-#define QUEUE_LOCK_FREE(base)   (g_static_rec_mutex_free(&base->queuelock))
-#define QUEUE_LOCK(base)        (g_static_rec_mutex_lock(&base->queuelock))
-#define QUEUE_UNLOCK(base)      (g_static_rec_mutex_unlock(&base->queuelock))
-#else
-/* otherwise it's already been defined in the header (FIXME 0.11)*/
-#endif
-
 GST_DEBUG_CATEGORY_STATIC (basertpdepayload_debug);
 #define GST_CAT_DEFAULT (basertpdepayload_debug)
 
@@ -65,12 +56,9 @@ enum
   LAST_SIGNAL
 };
 
-#define DEFAULT_QUEUE_DELAY    0
-
 enum
 {
   PROP_0,
-  PROP_QUEUE_DELAY,
   PROP_LAST
 };
 
@@ -96,13 +84,35 @@ static gboolean gst_base_rtp_depayload_packet_lost (GstBaseRTPDepayload *
 static gboolean gst_base_rtp_depayload_handle_event (GstBaseRTPDepayload *
     filter, GstEvent * event);
 
-GST_BOILERPLATE (GstBaseRTPDepayload, gst_base_rtp_depayload, GstElement,
-    GST_TYPE_ELEMENT);
+static GstElementClass *parent_class = NULL;
+static void gst_base_rtp_depayload_class_init (GstBaseRTPDepayloadClass *
+    klass);
+static void gst_base_rtp_depayload_init (GstBaseRTPDepayload * basertppayload,
+    GstBaseRTPDepayloadClass * klass);
 
-static void
-gst_base_rtp_depayload_base_init (gpointer klass)
+GType
+gst_base_rtp_depayload_get_type (void)
 {
-  /*GstElementClass *element_class = GST_ELEMENT_CLASS (klass); */
+  static GType base_rtp_depayload_type = 0;
+
+  if (g_once_init_enter ((gsize *) & base_rtp_depayload_type)) {
+    static const GTypeInfo base_rtp_depayload_info = {
+      sizeof (GstBaseRTPDepayloadClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) gst_base_rtp_depayload_class_init,
+      NULL,
+      NULL,
+      sizeof (GstBaseRTPDepayload),
+      0,
+      (GInstanceInitFunc) gst_base_rtp_depayload_init,
+    };
+
+    g_once_init_leave ((gsize *) & base_rtp_depayload_type,
+        g_type_register_static (GST_TYPE_ELEMENT, "GstBaseRTPDepayload",
+            &base_rtp_depayload_info, G_TYPE_FLAG_ABSTRACT));
+  }
+  return base_rtp_depayload_type;
 }
 
 static void
@@ -121,21 +131,6 @@ gst_base_rtp_depayload_class_init (GstBaseRTPDepayloadClass * klass)
   gobject_class->set_property = gst_base_rtp_depayload_set_property;
   gobject_class->get_property = gst_base_rtp_depayload_get_property;
 
-  /**
-   * GstBaseRTPDepayload::queue-delay
-   *
-   * Control the amount of packets to buffer.
-   *
-   * Deprecated: Use a jitterbuffer or RTP session manager to delay packet
-   * playback. This property has no effect anymore since 0.10.15.
-   */
-#ifndef GST_REMOVE_DEPRECATED
-  g_object_class_install_property (gobject_class, PROP_QUEUE_DELAY,
-      g_param_spec_uint ("queue-delay", "Queue Delay",
-          "Amount of ms to queue/buffer, deprecated", 0, G_MAXUINT,
-          DEFAULT_QUEUE_DELAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-#endif
-
   gstelement_class->change_state = gst_base_rtp_depayload_change_state;
 
   klass->set_gst_timestamp = gst_base_rtp_depayload_set_gst_timestamp;
@@ -176,19 +171,12 @@ gst_base_rtp_depayload_init (GstBaseRTPDepayload * filter,
   gst_pad_use_fixed_caps (filter->srcpad);
   gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
 
-  filter->queue = g_queue_new ();
-  filter->queue_delay = DEFAULT_QUEUE_DELAY;
-
   gst_segment_init (&filter->segment, GST_FORMAT_UNDEFINED);
 }
 
 static void
 gst_base_rtp_depayload_finalize (GObject * object)
 {
-  GstBaseRTPDepayload *filter = GST_BASE_RTP_DEPAYLOAD (object);
-
-  g_queue_free (filter->queue);
-
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -269,6 +257,7 @@ gst_base_rtp_depayload_chain (GstPad * pad, GstBuffer * in)
   guint32 rtptime;
   gboolean discont;
   gint gap;
+  GstRTPBuffer rtp;
 
   filter = GST_BASE_RTP_DEPAYLOAD (GST_OBJECT_PARENT (pad));
   priv = filter->priv;
@@ -293,8 +282,11 @@ gst_base_rtp_depayload_chain (GstPad * pad, GstBuffer * in)
   priv->timestamp = timestamp;
   priv->duration = GST_BUFFER_DURATION (in);
 
-  seqnum = gst_rtp_buffer_get_seq (in);
-  rtptime = gst_rtp_buffer_get_timestamp (in);
+  gst_rtp_buffer_map (in, GST_MAP_READ, &rtp);
+  seqnum = gst_rtp_buffer_get_seq (&rtp);
+  rtptime = gst_rtp_buffer_get_timestamp (&rtp);
+  gst_rtp_buffer_unmap (&rtp);
+
   discont = FALSE;
 
   GST_LOG_OBJECT (filter, "discont %d, seqnum %u, rtptime %u, timestamp %"
@@ -337,7 +329,7 @@ gst_base_rtp_depayload_chain (GstPad * pad, GstBuffer * in)
     /* we detected a seqnum discont but the buffer was not flagged with a discont,
      * set the discont flag so that the subclass can throw away old data. */
     priv->discont = TRUE;
-    in = gst_buffer_make_metadata_writable (in);
+    in = gst_buffer_make_writable (in);
     GST_BUFFER_FLAG_SET (in, GST_BUFFER_FLAG_DISCONT);
   }
 
@@ -361,22 +353,14 @@ gst_base_rtp_depayload_chain (GstPad * pad, GstBuffer * in)
 not_negotiated:
   {
     /* this is not fatal but should be filtered earlier */
-    if (GST_BUFFER_CAPS (in) == NULL) {
-      GST_ELEMENT_ERROR (filter, CORE, NEGOTIATION,
-          ("No RTP format was negotiated."),
-          ("Input buffers need to have RTP caps set on them. This is usually "
-              "achieved by setting the 'caps' property of the upstream source "
-              "element (often udpsrc or appsrc), or by putting a capsfilter "
-              "element before the depayloader and setting the 'caps' property "
-              "on that. Also see http://cgit.freedesktop.org/gstreamer/"
-              "gst-plugins-good/tree/gst/rtp/README"));
-    } else {
-      GST_ELEMENT_ERROR (filter, CORE, NEGOTIATION,
-          ("No RTP format was negotiated."),
-          ("RTP caps on input buffer were rejected, most likely because they "
-              "were incomplete or contained wrong values. Check the debug log "
-              "for more information."));
-    }
+    GST_ELEMENT_ERROR (filter, CORE, NEGOTIATION,
+        ("No RTP format was negotiated."),
+        ("Input buffers need to have RTP caps set on them. This is usually "
+            "achieved by setting the 'caps' property of the upstream source "
+            "element (often udpsrc or appsrc), or by putting a capsfilter "
+            "element before the depayloader and setting the 'caps' property "
+            "on that. Also see http://cgit.freedesktop.org/gstreamer/"
+            "gst-plugins-good/tree/gst/rtp/README"));
     gst_buffer_unref (in);
     return GST_FLOW_NOT_NEGOTIATED;
   }
@@ -417,19 +401,9 @@ gst_base_rtp_depayload_handle_event (GstBaseRTPDepayload * filter,
       filter->need_newsegment = TRUE;
       filter->priv->next_seqnum = -1;
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      gboolean update;
-      gdouble rate;
-      GstFormat fmt;
-      gint64 start, stop, position;
-
-      gst_event_parse_new_segment (event, &update, &rate, &fmt, &start, &stop,
-          &position);
-
-      gst_segment_set_newsegment (&filter->segment, update, rate, fmt,
-          start, stop, position);
-
+      gst_event_copy_segment (event, &filter->segment);
       /* don't pass the event downstream, we generate our own segment including
        * the NTP time and other things we receive in caps */
       forward = FALSE;
@@ -500,6 +474,7 @@ create_segment_event (GstBaseRTPDepayload * filter, gboolean update,
   GstEvent *event;
   GstClockTime stop;
   GstBaseRTPDepayloadPrivate *priv;
+  GstSegment segment;
 
   priv = filter->priv;
 
@@ -508,9 +483,15 @@ create_segment_event (GstBaseRTPDepayload * filter, gboolean update,
   else
     stop = -1;
 
-  event = gst_event_new_new_segment_full (update, priv->play_speed,
-      priv->play_scale, GST_FORMAT_TIME, position, stop,
-      position + priv->npt_start);
+  gst_segment_init (&segment, GST_FORMAT_TIME);
+  segment.rate = priv->play_speed;
+  segment.applied_rate = priv->play_scale;
+  segment.start = 0;
+  segment.stop = stop;
+  segment.time = priv->npt_start;
+  segment.position = position;
+
+  event = gst_event_new_segment (&segment);
 
   return event;
 }
@@ -519,18 +500,16 @@ typedef struct
 {
   GstBaseRTPDepayload *depayload;
   GstBaseRTPDepayloadClass *bclass;
-  GstCaps *caps;
   gboolean do_ts;
   gboolean rtptime;
 } HeaderData;
 
-static GstBufferListItem
-set_headers (GstBuffer ** buffer, guint group, guint idx, HeaderData * data)
+static gboolean
+set_headers (GstBuffer ** buffer, guint idx, HeaderData * data)
 {
   GstBaseRTPDepayload *depayload = data->depayload;
 
-  *buffer = gst_buffer_make_metadata_writable (*buffer);
-  gst_buffer_set_caps (*buffer, data->caps);
+  *buffer = gst_buffer_make_writable (*buffer);
 
   /* set the timestamp if we must and can */
   if (data->bclass->set_gst_timestamp && data->do_ts)
@@ -542,7 +521,7 @@ set_headers (GstBuffer ** buffer, guint group, guint idx, HeaderData * data)
     depayload->priv->discont = FALSE;
   }
 
-  return GST_BUFFER_LIST_SKIP_GROUP;
+  return TRUE;
 }
 
 static GstFlowReturn
@@ -552,7 +531,6 @@ gst_base_rtp_depayload_prepare_push (GstBaseRTPDepayload * filter,
   HeaderData data;
 
   data.depayload = filter;
-  data.caps = GST_PAD_CAPS (filter->srcpad);
   data.rtptime = rtptime;
   data.do_ts = do_ts;
   data.bclass = GST_BASE_RTP_DEPAYLOAD_GET_CLASS (filter);
@@ -562,7 +540,7 @@ gst_base_rtp_depayload_prepare_push (GstBaseRTPDepayload * filter,
     gst_buffer_list_foreach (*blist, (GstBufferListFunc) set_headers, &data);
   } else {
     GstBuffer **buf = obj;
-    set_headers (buf, 0, 0, &data);
+    set_headers (buf, 0, &data);
   }
 
   /* if this is the first buffer send a NEWSEGMENT */
@@ -774,9 +752,6 @@ gst_base_rtp_depayload_set_property (GObject * object, guint prop_id,
   filter = GST_BASE_RTP_DEPAYLOAD (object);
 
   switch (prop_id) {
-    case PROP_QUEUE_DELAY:
-      filter->queue_delay = g_value_get_uint (value);
-      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -792,9 +767,6 @@ gst_base_rtp_depayload_get_property (GObject * object, guint prop_id,
   filter = GST_BASE_RTP_DEPAYLOAD (object);
 
   switch (prop_id) {
-    case PROP_QUEUE_DELAY:
-      g_value_set_uint (value, filter->queue_delay);
-      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index d0326a4..68f178d 100644 (file)
@@ -40,15 +40,6 @@ G_BEGIN_DECLS
 #define GST_BASE_RTP_DEPAYLOAD_SINKPAD(depayload) (GST_BASE_RTP_DEPAYLOAD (depayload)->sinkpad)
 #define GST_BASE_RTP_DEPAYLOAD_SRCPAD(depayload)  (GST_BASE_RTP_DEPAYLOAD (depayload)->srcpad)
 
-#ifndef GST_DISABLE_DEPRECATED
-/* this was presumably never meant to be public API, or should at least
- * have been prefixed if it was. Don't use. (FIXME: remove in 0.11) */
-#define QUEUE_LOCK_INIT(base)   (g_static_rec_mutex_init(&base->queuelock))
-#define QUEUE_LOCK_FREE(base)   (g_static_rec_mutex_free(&base->queuelock))
-#define QUEUE_LOCK(base)        (g_static_rec_mutex_lock(&base->queuelock))
-#define QUEUE_UNLOCK(base)      (g_static_rec_mutex_unlock(&base->queuelock))
-#endif
-
 typedef struct _GstBaseRTPDepayload      GstBaseRTPDepayload;
 typedef struct _GstBaseRTPDepayloadClass GstBaseRTPDepayloadClass;
 typedef struct _GstBaseRTPDepayloadPrivate GstBaseRTPDepayloadPrivate;
@@ -59,30 +50,9 @@ struct _GstBaseRTPDepayload
 
   GstPad *sinkpad, *srcpad;
 
-#ifndef GST_REMOVE_DEPRECATED
-  /* lock to protect the queue, deprecated */
-  GStaticRecMutex queuelock;
-
-  /* deprecated */
-  gboolean thread_running;
-  /* the releaser thread, deprecated */
-  GThread *thread;
-#endif
-
   /* this attribute must be set by the child */
   guint clock_rate;
 
-#ifndef GST_REMOVE_DEPRECATED
-  /* this value can be modified by the child if needed, deprecated */
-  guint queue_delay;
-#endif
-
-  /* we will queue up to RTP_QUEUEDELAY ms of packets,
-   * reordering them if necessary
-   * dropping any packets that are more than
-   * RTP_QUEUEDELAY ms late, deprecated */
-  GQueue *queue;
-
   GstSegment segment;
   gboolean need_newsegment;
 
@@ -111,10 +81,6 @@ struct _GstBaseRTPDepayloadClass
   /* virtuals, inform the subclass of the caps. */
   gboolean (*set_caps) (GstBaseRTPDepayload *filter, GstCaps *caps);
 
-  /* non-pure function, default implementation in base class
-   * this does buffering, reordering and dropping, deprecated */
-  GstFlowReturn (*add_to_queue) (GstBaseRTPDepayload *filter, GstBuffer *in);
-
   /* pure virtual function, child must use this to process incoming
    * rtp packets. If the child returns a buffer without a valid timestamp,
    * the timestamp of @in will be applied to the result buffer and the
index e27d97a..33e6a90 100644 (file)
@@ -95,7 +95,8 @@ static void gst_basertppayload_init (GstBaseRTPPayload * basertppayload,
 static void gst_basertppayload_finalize (GObject * object);
 
 static gboolean gst_basertppayload_sink_setcaps (GstPad * pad, GstCaps * caps);
-static GstCaps *gst_basertppayload_sink_getcaps (GstPad * pad);
+static GstCaps *gst_basertppayload_sink_getcaps (GstPad * pad,
+    GstCaps * filter);
 static gboolean gst_basertppayload_event (GstPad * pad, GstEvent * event);
 static GstFlowReturn gst_basertppayload_chain (GstPad * pad,
     GstBuffer * buffer);
@@ -117,7 +118,7 @@ gst_basertppayload_get_type (void)
 {
   static GType basertppayload_type = 0;
 
-  if (!basertppayload_type) {
+  if (g_once_init_enter ((gsize *) & basertppayload_type)) {
     static const GTypeInfo basertppayload_info = {
       sizeof (GstBaseRTPPayloadClass),
       (GBaseInitFunc) gst_basertppayload_base_init,
@@ -130,9 +131,9 @@ gst_basertppayload_get_type (void)
       (GInstanceInitFunc) gst_basertppayload_init,
     };
 
-    basertppayload_type =
+    g_once_init_leave ((gsize *) & basertppayload_type,
         g_type_register_static (GST_TYPE_ELEMENT, "GstBaseRTPPayload",
-        &basertppayload_info, G_TYPE_FLAG_ABSTRACT);
+            &basertppayload_info, G_TYPE_FLAG_ABSTRACT));
   }
   return basertppayload_type;
 }
@@ -343,7 +344,7 @@ gst_basertppayload_sink_setcaps (GstPad * pad, GstCaps * caps)
 }
 
 static GstCaps *
-gst_basertppayload_sink_getcaps (GstPad * pad)
+gst_basertppayload_sink_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstBaseRTPPayload *basertppayload;
   GstBaseRTPPayloadClass *basertppayload_class;
@@ -355,7 +356,7 @@ gst_basertppayload_sink_getcaps (GstPad * pad)
   basertppayload_class = GST_BASE_RTP_PAYLOAD_GET_CLASS (basertppayload);
 
   if (basertppayload_class->get_caps)
-    caps = basertppayload_class->get_caps (basertppayload, pad);
+    caps = basertppayload_class->get_caps (basertppayload, pad, filter);
 
   if (!caps) {
     caps = GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad));
@@ -363,7 +364,10 @@ gst_basertppayload_sink_getcaps (GstPad * pad)
         "using pad template %p with caps %p %" GST_PTR_FORMAT,
         GST_PAD_PAD_TEMPLATE (pad), caps, caps);
 
-    caps = gst_caps_ref (caps);
+    if (filter)
+      caps = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+    else
+      caps = gst_caps_ref (caps);
   }
 
   gst_object_unref (basertppayload);
@@ -399,28 +403,15 @@ gst_basertppayload_event (GstPad * pad, GstEvent * event)
       res = gst_pad_event_default (pad, event);
       gst_segment_init (&basertppayload->segment, GST_FORMAT_UNDEFINED);
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      gboolean update;
-      gdouble rate, arate;
-      GstFormat fmt;
-      gint64 start, stop, position;
       GstSegment *segment;
 
       segment = &basertppayload->segment;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &fmt,
-          &start, &stop, &position);
-      gst_segment_set_newsegment_full (segment, update, rate, arate, fmt, start,
-          stop, position);
+      gst_event_copy_segment (event, segment);
 
       GST_DEBUG_OBJECT (basertppayload,
-          "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, "
-          "format %d, "
-          "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
-          G_GINT64_FORMAT ", accum %" G_GINT64_FORMAT, update, rate, arate,
-          segment->format, segment->start, segment->stop, segment->time,
-          segment->accum);
+          "configured SEGMENT %" GST_SEGMENT_FORMAT, segment);
       /* fallthrough */
     }
     default:
@@ -560,7 +551,7 @@ gst_basertppayload_set_outcaps (GstBaseRTPPayload * payload,
   payload->abidata.ABI.ptime = 0;
 
   /* the peer caps can override some of the defaults */
-  peercaps = gst_pad_peer_get_caps (payload->srcpad);
+  peercaps = gst_pad_peer_get_caps (payload->srcpad, srccaps);
   if (peercaps == NULL) {
     /* no peer caps, just add the other properties */
     gst_caps_set_simple (srccaps,
@@ -577,11 +568,10 @@ gst_basertppayload_set_outcaps (GstBaseRTPPayload * payload,
     gint pt;
     guint max_ptime, ptime;
 
-    /* peer provides caps we can use to fixate, intersect. This always returns a
-     * writable caps. */
-    temp = gst_caps_intersect (srccaps, peercaps);
+    /* peer provides caps we can use to fixate. They are already intersected
+     * with our srccaps, just make them writable */
+    temp = gst_caps_make_writable (peercaps);
     gst_caps_unref (srccaps);
-    gst_caps_unref (peercaps);
 
     if (gst_caps_is_empty (temp)) {
       gst_caps_unref (temp);
@@ -704,14 +694,13 @@ typedef struct
   guint32 ssrc;
   guint16 seqnum;
   guint8 pt;
-  GstCaps *caps;
   GstClockTime timestamp;
   guint64 offset;
   guint32 rtptime;
 } HeaderData;
 
-static GstBufferListItem
-find_timestamp (GstBuffer ** buffer, guint group, guint idx, HeaderData * data)
+static gboolean
+find_timestamp (GstBuffer ** buffer, guint idx, HeaderData * data)
 {
   data->timestamp = GST_BUFFER_TIMESTAMP (*buffer);
   data->offset = GST_BUFFER_OFFSET (*buffer);
@@ -719,23 +708,27 @@ find_timestamp (GstBuffer ** buffer, guint group, guint idx, HeaderData * data)
   /* stop when we find a timestamp. We take whatever offset is associated with
    * the timestamp (if any) to do perfect timestamps when we need to. */
   if (data->timestamp != -1)
-    return GST_BUFFER_LIST_END;
+    return FALSE;
   else
-    return GST_BUFFER_LIST_CONTINUE;
+    return TRUE;
 }
 
-static GstBufferListItem
+static gboolean
 set_headers (GstBuffer ** buffer, guint group, guint idx, HeaderData * data)
 {
-  gst_rtp_buffer_set_ssrc (*buffer, data->ssrc);
-  gst_rtp_buffer_set_payload_type (*buffer, data->pt);
-  gst_rtp_buffer_set_seq (*buffer, data->seqnum);
-  gst_rtp_buffer_set_timestamp (*buffer, data->rtptime);
-  gst_buffer_set_caps (*buffer, data->caps);
+  GstRTPBuffer rtp;
+
+  gst_rtp_buffer_map (*buffer, GST_MAP_WRITE, &rtp);
+  gst_rtp_buffer_set_ssrc (&rtp, data->ssrc);
+  gst_rtp_buffer_set_payload_type (&rtp, data->pt);
+  gst_rtp_buffer_set_seq (&rtp, data->seqnum);
+  gst_rtp_buffer_set_timestamp (&rtp, data->rtptime);
+  gst_rtp_buffer_unmap (&rtp);
+
   /* increment the seqnum for each buffer */
   data->seqnum++;
 
-  return GST_BUFFER_LIST_SKIP_GROUP;
+  return TRUE;
 }
 
 /* Updates the SSRC, payload type, seqnum and timestamp of the RTP buffer
@@ -761,7 +754,6 @@ gst_basertppayload_prepare_push (GstBaseRTPPayload * payload,
   data.seqnum = payload->seqnum;
   data.ssrc = payload->current_ssrc;
   data.pt = payload->pt;
-  data.caps = GST_PAD_CAPS (payload->srcpad);
 
   /* find the first buffer with a timestamp */
   if (is_list) {
@@ -821,7 +813,7 @@ gst_basertppayload_prepare_push (GstBaseRTPPayload * payload,
   GST_LOG_OBJECT (payload,
       "Preparing to push packet with size %d, seq=%d, rtptime=%u, timestamp %"
       GST_TIME_FORMAT, (is_list) ? -1 :
-      GST_BUFFER_SIZE (GST_BUFFER (obj)), payload->seqnum, data.rtptime,
+      gst_buffer_get_size (GST_BUFFER (obj)), payload->seqnum, data.rtptime,
       GST_TIME_ARGS (data.timestamp));
 
   if (g_atomic_int_compare_and_exchange (&payload->
index 86a5721..2987b3c 100644 (file)
@@ -141,7 +141,7 @@ struct _GstBaseRTPPayloadClass
   GstFlowReturn (*handle_buffer)        (GstBaseRTPPayload *payload,
                                          GstBuffer *buffer);
   gboolean      (*handle_event)         (GstPad * pad, GstEvent * event);
-  GstCaps *     (*get_caps)             (GstBaseRTPPayload *payload, GstPad * pad);
+  GstCaps *     (*get_caps)             (GstBaseRTPPayload *payload, GstPad * pad, GstCaps * filter);
 
   /*< private >*/
   gpointer _gst_reserved[GST_PADDING-2];
index 3b37c6f..57bc81a 100644 (file)
@@ -70,10 +70,8 @@ gst_rtcp_buffer_new_take_data (gpointer data, guint len)
   g_return_val_if_fail (len > 0, NULL);
 
   result = gst_buffer_new ();
-
-  GST_BUFFER_MALLOCDATA (result) = data;
-  GST_BUFFER_DATA (result) = data;
-  GST_BUFFER_SIZE (result) = len;
+  gst_buffer_take_memory (result,
+      gst_memory_new_wrapped (0, data, g_free, len, 0, len));
 
   return result;
 }
@@ -205,15 +203,17 @@ wrong_padding:
 gboolean
 gst_rtcp_buffer_validate (GstBuffer * buffer)
 {
+  gboolean res;
   guint8 *data;
-  guint len;
+  gsize len;
 
   g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
 
-  data = GST_BUFFER_DATA (buffer);
-  len = GST_BUFFER_SIZE (buffer);
+  data = gst_buffer_map (buffer, &len, NULL, GST_MAP_READ);
+  res = gst_rtcp_buffer_validate_data (data, len);
+  gst_buffer_unmap (buffer, data, len);
 
-  return gst_rtcp_buffer_validate_data (data, len);
+  return res;
 }
 
 /**
@@ -233,36 +233,64 @@ gst_rtcp_buffer_new (guint mtu)
   g_return_val_if_fail (mtu > 0, NULL);
 
   result = gst_buffer_new ();
-  GST_BUFFER_MALLOCDATA (result) = g_malloc0 (mtu);
-  GST_BUFFER_DATA (result) = GST_BUFFER_MALLOCDATA (result);
-  GST_BUFFER_SIZE (result) = mtu;
+  gst_buffer_take_memory (result,
+      gst_memory_new_wrapped (0, g_malloc0 (mtu), g_free, mtu, 0, mtu));
 
   return result;
 }
 
 /**
- * gst_rtcp_buffer_end:
+ * gst_rtcp_buffer_map:
  * @buffer: a buffer with an RTCP packet
+ * @flags: flags for the mapping
+ * @rtcp: resulting #GstRTCPBuffer
  *
- * Finish @buffer after being constructured. This function is usually called
- * after gst_rtcp_buffer_new() and after adding the RTCP items to the new buffer. 
+ * Open @buffer for reading or writing, depending on @flags. The resulting RTCP
+ * buffer state is stored in @rtcp.
+ */
+gboolean
+gst_rtcp_buffer_map (GstBuffer * buffer, GstMapFlags flags,
+    GstRTCPBuffer * rtcp)
+{
+  g_return_val_if_fail (rtcp != NULL, FALSE);
+  g_return_val_if_fail (rtcp->buffer == NULL, FALSE);
+  g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+
+  rtcp->buffer = buffer;
+  rtcp->flags = flags;
+  rtcp->data = gst_buffer_map (buffer, &rtcp->size, &rtcp->maxsize, flags);
+
+  return TRUE;
+}
+
+/**
+ * gst_rtcp_buffer_unmap:
+ * @buffer: a buffer with an RTCP packet
+ *
+ * Finish @rtcp after being constructured. This function is usually called
+ * after gst_rtcp_buffer_map() and after adding the RTCP items to the new buffer.
  *
  * The function adjusts the size of @buffer with the total length of all the
  * added packets.
  */
-void
-gst_rtcp_buffer_end (GstBuffer * buffer)
+gboolean
+gst_rtcp_buffer_unmap (GstRTCPBuffer * rtcp)
 {
+  gboolean res;
   GstRTCPPacket packet;
 
-  g_return_if_fail (GST_IS_BUFFER (buffer));
+  g_return_val_if_fail (rtcp != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_BUFFER (rtcp->buffer), FALSE);
 
   /* move to the first free space */
-  if (gst_rtcp_buffer_get_first_packet (buffer, &packet))
+  if (gst_rtcp_buffer_get_first_packet (rtcp, &packet))
     while (gst_rtcp_packet_move_to_next (&packet));
 
   /* shrink size */
-  GST_BUFFER_SIZE (buffer) = packet.offset;
+  res = gst_buffer_unmap (rtcp->buffer, rtcp->data, packet.offset);
+  rtcp->buffer = NULL;
+
+  return res;
 }
 
 /**
@@ -274,15 +302,16 @@ gst_rtcp_buffer_end (GstBuffer * buffer)
  * Returns: the number of RTCP packets in @buffer.
  */
 guint
-gst_rtcp_buffer_get_packet_count (GstBuffer * buffer)
+gst_rtcp_buffer_get_packet_count (GstRTCPBuffer * rtcp)
 {
   GstRTCPPacket packet;
   guint count;
 
-  g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
+  g_return_val_if_fail (rtcp != NULL, 0);
+  g_return_val_if_fail (GST_IS_BUFFER (rtcp->buffer), 0);
 
   count = 0;
-  if (gst_rtcp_buffer_get_first_packet (buffer, &packet)) {
+  if (gst_rtcp_buffer_get_first_packet (rtcp, &packet)) {
     do {
       count++;
     } while (gst_rtcp_packet_move_to_next (&packet));
@@ -307,10 +336,9 @@ read_packet_header (GstRTCPPacket * packet)
   guint offset;
 
   g_return_val_if_fail (packet != NULL, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
-  data = GST_BUFFER_DATA (packet->buffer);
-  size = GST_BUFFER_SIZE (packet->buffer);
+  data = packet->rtcp->data;
+  size = packet->rtcp->size;
 
   offset = packet->offset;
 
@@ -345,13 +373,14 @@ read_packet_header (GstRTCPPacket * packet)
  * Returns: TRUE if the packet existed in @buffer.
  */
 gboolean
-gst_rtcp_buffer_get_first_packet (GstBuffer * buffer, GstRTCPPacket * packet)
+gst_rtcp_buffer_get_first_packet (GstRTCPBuffer * rtcp, GstRTCPPacket * packet)
 {
-  g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+  g_return_val_if_fail (rtcp != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_BUFFER (rtcp->buffer), FALSE);
   g_return_val_if_fail (packet != NULL, FALSE);
 
   /* init to 0 */
-  packet->buffer = buffer;
+  packet->rtcp = rtcp;
   packet->offset = 0;
   packet->type = GST_RTCP_TYPE_INVALID;
 
@@ -376,7 +405,6 @@ gst_rtcp_packet_move_to_next (GstRTCPPacket * packet)
 {
   g_return_val_if_fail (packet != NULL, FALSE);
   g_return_val_if_fail (packet->type != GST_RTCP_TYPE_INVALID, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
   /* if we have a padding or invalid packet, it must be the last, 
    * return FALSE */
@@ -413,22 +441,23 @@ end:
  * if the max mtu is exceeded for the buffer.
  */
 gboolean
-gst_rtcp_buffer_add_packet (GstBuffer * buffer, GstRTCPType type,
+gst_rtcp_buffer_add_packet (GstRTCPBuffer * rtcp, GstRTCPType type,
     GstRTCPPacket * packet)
 {
   guint len, size;
   guint8 *data;
   gboolean result;
 
-  g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+  g_return_val_if_fail (rtcp != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_BUFFER (rtcp->buffer), FALSE);
   g_return_val_if_fail (type != GST_RTCP_TYPE_INVALID, FALSE);
   g_return_val_if_fail (packet != NULL, FALSE);
 
   /* find free space */
-  if (gst_rtcp_buffer_get_first_packet (buffer, packet))
+  if (gst_rtcp_buffer_get_first_packet (rtcp, packet))
     while (gst_rtcp_packet_move_to_next (packet));
 
-  size = GST_BUFFER_SIZE (buffer);
+  size = rtcp->size;
 
   /* packet->offset is now pointing to the next free offset in the buffer to
    * start a compount packet. Next we figure out if we have enough free space in
@@ -461,7 +490,7 @@ gst_rtcp_buffer_add_packet (GstBuffer * buffer, GstRTCPType type,
   if (packet->offset + len >= size)
     goto no_space;
 
-  data = GST_BUFFER_DATA (buffer) + packet->offset;
+  data = rtcp->data + packet->offset;
 
   data[0] = (GST_RTCP_VERSION << 6);
   data[1] = type;
@@ -510,9 +539,8 @@ gst_rtcp_packet_remove (GstRTCPPacket * packet)
   offset = packet->offset + (packet->length << 2) + 4;
 
   /* Overwrite this packet with the rest of the data */
-  memmove (GST_BUFFER_DATA (packet->buffer) + packet->offset,
-      GST_BUFFER_DATA (packet->buffer) + offset,
-      GST_BUFFER_SIZE (packet->buffer) - offset);
+  memmove (packet->rtcp->data + packet->offset,
+      packet->rtcp->data + offset, packet->rtcp->size - offset);
 
   /* try to read next header */
   ret = read_packet_header (packet);
@@ -612,9 +640,8 @@ gst_rtcp_packet_sr_get_sender_info (GstRTCPPacket * packet, guint32 * ssrc,
 
   g_return_if_fail (packet != NULL);
   g_return_if_fail (packet->type == GST_RTCP_TYPE_SR);
-  g_return_if_fail (GST_IS_BUFFER (packet->buffer));
 
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
 
   /* skip header */
   data += packet->offset + 4;
@@ -653,9 +680,8 @@ gst_rtcp_packet_sr_set_sender_info (GstRTCPPacket * packet, guint32 ssrc,
 
   g_return_if_fail (packet != NULL);
   g_return_if_fail (packet->type == GST_RTCP_TYPE_SR);
-  g_return_if_fail (GST_IS_BUFFER (packet->buffer));
 
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
 
   /* skip header */
   data += packet->offset + 4;
@@ -686,9 +712,8 @@ gst_rtcp_packet_rr_get_ssrc (GstRTCPPacket * packet)
 
   g_return_val_if_fail (packet != NULL, 0);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR, 0);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
 
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
 
   /* skip header */
   data += packet->offset + 4;
@@ -711,9 +736,8 @@ gst_rtcp_packet_rr_set_ssrc (GstRTCPPacket * packet, guint32 ssrc)
 
   g_return_if_fail (packet != NULL);
   g_return_if_fail (packet->type == GST_RTCP_TYPE_RR);
-  g_return_if_fail (GST_IS_BUFFER (packet->buffer));
 
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
 
   /* skip header */
   data += packet->offset + 4;
@@ -734,7 +758,6 @@ gst_rtcp_packet_get_rb_count (GstRTCPPacket * packet)
   g_return_val_if_fail (packet != NULL, 0);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR ||
       packet->type == GST_RTCP_TYPE_SR, 0);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
 
   return packet->count;
 }
@@ -765,9 +788,8 @@ gst_rtcp_packet_get_rb (GstRTCPPacket * packet, guint nth, guint32 * ssrc,
   g_return_if_fail (packet != NULL);
   g_return_if_fail (packet->type == GST_RTCP_TYPE_RR ||
       packet->type == GST_RTCP_TYPE_SR);
-  g_return_if_fail (GST_IS_BUFFER (packet->buffer));
 
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
 
   /* skip header */
   data += packet->offset + 4;
@@ -835,13 +857,12 @@ gst_rtcp_packet_add_rb (GstRTCPPacket * packet, guint32 ssrc,
   g_return_val_if_fail (packet != NULL, FALSE);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR ||
       packet->type == GST_RTCP_TYPE_SR, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
   if (packet->count >= GST_RTCP_MAX_RB_COUNT)
     goto no_space;
 
-  data = GST_BUFFER_DATA (packet->buffer);
-  size = GST_BUFFER_SIZE (packet->buffer);
+  data = packet->rtcp->data;
+  size = packet->rtcp->size;
 
   /* skip header */
   offset = packet->offset + 4;
@@ -911,7 +932,6 @@ gst_rtcp_packet_set_rb (GstRTCPPacket * packet, guint nth, guint32 ssrc,
   g_return_if_fail (packet != NULL);
   g_return_if_fail (packet->type == GST_RTCP_TYPE_RR ||
       packet->type == GST_RTCP_TYPE_SR);
-  g_return_if_fail (GST_IS_BUFFER (packet->buffer));
 
   g_warning ("not implemented");
 }
@@ -930,7 +950,6 @@ gst_rtcp_packet_sdes_get_item_count (GstRTCPPacket * packet)
 {
   g_return_val_if_fail (packet != NULL, 0);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, 0);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
 
   return packet->count;
 }
@@ -948,7 +967,6 @@ gst_rtcp_packet_sdes_first_item (GstRTCPPacket * packet)
 {
   g_return_val_if_fail (packet != NULL, FALSE);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
   packet->item_offset = 4;
   packet->item_count = 0;
@@ -977,14 +995,13 @@ gst_rtcp_packet_sdes_next_item (GstRTCPPacket * packet)
 
   g_return_val_if_fail (packet != NULL, FALSE);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
   /* if we are at the last item, we are done */
   if (packet->item_count == packet->count)
     return FALSE;
 
   /* move to SDES */
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
   data += packet->offset;
   /* move to item */
   offset = packet->item_offset;
@@ -1028,10 +1045,9 @@ gst_rtcp_packet_sdes_get_ssrc (GstRTCPPacket * packet)
 
   g_return_val_if_fail (packet != NULL, 0);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, 0);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
 
   /* move to SDES */
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
   data += packet->offset;
   /* move to item */
   data += packet->item_offset;
@@ -1057,10 +1073,9 @@ gst_rtcp_packet_sdes_first_entry (GstRTCPPacket * packet)
 
   g_return_val_if_fail (packet != NULL, FALSE);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
   /* move to SDES */
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
   data += packet->offset;
   /* move to item */
   offset = packet->item_offset;
@@ -1096,10 +1111,9 @@ gst_rtcp_packet_sdes_next_entry (GstRTCPPacket * packet)
 
   g_return_val_if_fail (packet != NULL, FALSE);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
   /* move to SDES */
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
   data += packet->offset;
   /* move to item */
   offset = packet->item_offset;
@@ -1150,10 +1164,9 @@ gst_rtcp_packet_sdes_get_entry (GstRTCPPacket * packet,
 
   g_return_val_if_fail (packet != NULL, FALSE);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
   /* move to SDES */
-  bdata = GST_BUFFER_DATA (packet->buffer);
+  bdata = packet->rtcp->data;
   bdata += packet->offset;
   /* move to item */
   offset = packet->item_offset;
@@ -1194,7 +1207,6 @@ gst_rtcp_packet_sdes_copy_entry (GstRTCPPacket * packet,
 
   g_return_val_if_fail (packet != NULL, FALSE);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
   if (!gst_rtcp_packet_sdes_get_entry (packet, type, &tlen, &tdata))
     return FALSE;
@@ -1225,7 +1237,6 @@ gst_rtcp_packet_sdes_add_item (GstRTCPPacket * packet, guint32 ssrc)
 
   g_return_val_if_fail (packet != NULL, FALSE);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
   /* increment item count when possible */
   if (packet->count >= GST_RTCP_MAX_SDES_ITEM_COUNT)
@@ -1238,8 +1249,8 @@ gst_rtcp_packet_sdes_add_item (GstRTCPPacket * packet, guint32 ssrc)
   gst_rtcp_packet_sdes_next_item (packet);
 
   /* move to SDES */
-  data = GST_BUFFER_DATA (packet->buffer);
-  size = GST_BUFFER_SIZE (packet->buffer);
+  data = packet->rtcp->data;
+  size = packet->rtcp->size;
   data += packet->offset;
   /* move to current item */
   offset = packet->item_offset;
@@ -1295,11 +1306,10 @@ gst_rtcp_packet_sdes_add_entry (GstRTCPPacket * packet, GstRTCPSDESType type,
 
   g_return_val_if_fail (packet != NULL, FALSE);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
   /* move to SDES */
-  bdata = GST_BUFFER_DATA (packet->buffer);
-  size = GST_BUFFER_SIZE (packet->buffer);
+  bdata = packet->rtcp->data;
+  size = packet->rtcp->size;
   bdata += packet->offset;
   /* move to item */
   offset = packet->item_offset;
@@ -1371,7 +1381,6 @@ gst_rtcp_packet_bye_get_nth_ssrc (GstRTCPPacket * packet, guint nth)
 
   g_return_val_if_fail (packet != NULL, 0);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, 0);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
 
   /* get amount of sources and check that we don't read too much */
   sc = packet->count;
@@ -1389,10 +1398,10 @@ gst_rtcp_packet_bye_get_nth_ssrc (GstRTCPPacket * packet, guint nth)
   offset += packet->offset;
 
   /* check if the packet is valid */
-  if (offset + 4 > GST_BUFFER_SIZE (packet->buffer))
+  if (offset + 4 > packet->rtcp->size)
     return 0;
 
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
   data += offset;
 
   ssrc = GST_READ_UINT32_BE (data);
@@ -1419,13 +1428,12 @@ gst_rtcp_packet_bye_add_ssrc (GstRTCPPacket * packet, guint32 ssrc)
 
   g_return_val_if_fail (packet != NULL, FALSE);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
   if (packet->count >= GST_RTCP_MAX_BYE_SSRC_COUNT)
     goto no_space;
 
-  data = GST_BUFFER_DATA (packet->buffer);
-  size = GST_BUFFER_SIZE (packet->buffer);
+  data = packet->rtcp->data;
+  size = packet->rtcp->size;
 
   /* skip header */
   offset = packet->offset + 4;
@@ -1477,7 +1485,6 @@ gst_rtcp_packet_bye_add_ssrcs (GstRTCPPacket * packet, guint32 * ssrc,
 
   g_return_val_if_fail (packet != NULL, FALSE);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
   res = TRUE;
   for (i = 0; i < len && res; i++) {
@@ -1504,7 +1511,7 @@ get_reason_offset (GstRTCPPacket * packet)
   offset += packet->offset;
 
   /* check if the packet is valid */
-  if (offset + 1 > GST_BUFFER_SIZE (packet->buffer))
+  if (offset + 1 > packet->rtcp->size)
     return 0;
 
   return offset;
@@ -1527,13 +1534,12 @@ gst_rtcp_packet_bye_get_reason_len (GstRTCPPacket * packet)
 
   g_return_val_if_fail (packet != NULL, 0);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, 0);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
 
   roffset = get_reason_offset (packet);
   if (roffset == 0)
     return 0;
 
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
 
   return data[roffset];
 }
@@ -1556,13 +1562,12 @@ gst_rtcp_packet_bye_get_reason (GstRTCPPacket * packet)
 
   g_return_val_if_fail (packet != NULL, NULL);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, NULL);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), NULL);
 
   roffset = get_reason_offset (packet);
   if (roffset == 0)
     return NULL;
 
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
 
   /* get length of reason string */
   len = data[roffset];
@@ -1573,7 +1578,7 @@ gst_rtcp_packet_bye_get_reason (GstRTCPPacket * packet)
   roffset += 1;
 
   /* check if enough data to copy */
-  if (roffset + len > GST_BUFFER_SIZE (packet->buffer))
+  if (roffset + len > packet->rtcp->size)
     return NULL;
 
   return g_strndup ((gconstpointer) (data + roffset), len);
@@ -1597,7 +1602,6 @@ gst_rtcp_packet_bye_set_reason (GstRTCPPacket * packet, const gchar * reason)
 
   g_return_val_if_fail (packet != NULL, FALSE);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
   if (reason == NULL)
     return TRUE;
@@ -1613,8 +1617,8 @@ gst_rtcp_packet_bye_set_reason (GstRTCPPacket * packet, const gchar * reason)
   if (roffset == 0)
     goto no_space;
 
-  data = GST_BUFFER_DATA (packet->buffer);
-  size = GST_BUFFER_SIZE (packet->buffer);
+  data = packet->rtcp->data;
+  size = packet->rtcp->size;
 
   /* we have 1 byte length and we need to pad to 4 bytes */
   padded = ((len + 1) + 3) & ~3;
@@ -1660,9 +1664,8 @@ gst_rtcp_packet_fb_get_sender_ssrc (GstRTCPPacket * packet)
   g_return_val_if_fail (packet != NULL, 0);
   g_return_val_if_fail ((packet->type == GST_RTCP_TYPE_RTPFB ||
           packet->type == GST_RTCP_TYPE_PSFB), 0);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
 
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
 
   /* skip header */
   data += packet->offset + 4;
@@ -1688,9 +1691,8 @@ gst_rtcp_packet_fb_set_sender_ssrc (GstRTCPPacket * packet, guint32 ssrc)
   g_return_if_fail (packet != NULL);
   g_return_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
       packet->type == GST_RTCP_TYPE_PSFB);
-  g_return_if_fail (GST_IS_BUFFER (packet->buffer));
 
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
 
   /* skip header */
   data += packet->offset + 4;
@@ -1716,9 +1718,8 @@ gst_rtcp_packet_fb_get_media_ssrc (GstRTCPPacket * packet)
   g_return_val_if_fail (packet != NULL, 0);
   g_return_val_if_fail ((packet->type == GST_RTCP_TYPE_RTPFB ||
           packet->type == GST_RTCP_TYPE_PSFB), 0);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
 
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
 
   /* skip header and sender ssrc */
   data += packet->offset + 8;
@@ -1744,9 +1745,8 @@ gst_rtcp_packet_fb_set_media_ssrc (GstRTCPPacket * packet, guint32 ssrc)
   g_return_if_fail (packet != NULL);
   g_return_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
       packet->type == GST_RTCP_TYPE_PSFB);
-  g_return_if_fail (GST_IS_BUFFER (packet->buffer));
 
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
 
   /* skip header and sender ssrc */
   data += packet->offset + 8;
@@ -1790,9 +1790,8 @@ gst_rtcp_packet_fb_set_type (GstRTCPPacket * packet, GstRTCPFBType type)
   g_return_if_fail (packet != NULL);
   g_return_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
       packet->type == GST_RTCP_TYPE_PSFB);
-  g_return_if_fail (GST_IS_BUFFER (packet->buffer));
 
-  data = GST_BUFFER_DATA (packet->buffer);
+  data = packet->rtcp->data;
 
   data[packet->offset] = (data[packet->offset] & 0xe0) | type;
   packet->count = type;
@@ -1963,9 +1962,8 @@ gst_rtcp_packet_fb_get_fci_length (GstRTCPPacket * packet)
   g_return_val_if_fail (packet != NULL, 0);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
       packet->type == GST_RTCP_TYPE_PSFB, 0);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 0);
 
-  data = GST_BUFFER_DATA (packet->buffer) + packet->offset + 2;
+  data = packet->rtcp->data + packet->offset + 2;
 
   return GST_READ_UINT16_BE (data) - 2;
 }
@@ -1990,12 +1988,11 @@ gst_rtcp_packet_fb_set_fci_length (GstRTCPPacket * packet, guint16 wordlen)
   g_return_val_if_fail (packet != NULL, FALSE);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
       packet->type == GST_RTCP_TYPE_PSFB, FALSE);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
 
-  if (GST_BUFFER_SIZE (packet->buffer) < packet->offset + ((wordlen + 3) * 4))
+  if (packet->rtcp->size < packet->offset + ((wordlen + 3) * 4))
     return FALSE;
 
-  data = GST_BUFFER_DATA (packet->buffer) + packet->offset + 2;
+  data = packet->rtcp->data + packet->offset + 2;
   wordlen += 2;
   GST_WRITE_UINT16_BE (data, wordlen);
 
@@ -2020,9 +2017,8 @@ gst_rtcp_packet_fb_get_fci (GstRTCPPacket * packet)
   g_return_val_if_fail (packet != NULL, NULL);
   g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
       packet->type == GST_RTCP_TYPE_PSFB, NULL);
-  g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), NULL);
 
-  data = GST_BUFFER_DATA (packet->buffer) + packet->offset;
+  data = packet->rtcp->data + packet->offset;
 
   if (GST_READ_UINT16_BE (data + 2) <= 2)
     return NULL;
index 6f57fad..a9a547d 100644 (file)
@@ -156,8 +156,19 @@ typedef enum
  */
 #define GST_RTCP_VALID_VALUE ((GST_RTCP_VERSION << 14) | GST_RTCP_TYPE_SR)
 
+typedef struct _GstRTCPBuffer GstRTCPBuffer;
 typedef struct _GstRTCPPacket GstRTCPPacket;
 
+struct _GstRTCPBuffer
+{
+  GstBuffer   *buffer;
+
+  GstMapFlags  flags;
+  guint8      *data;
+  gsize        size;
+  gsize        maxsize;
+};
+
 /**
  * GstRTCPPacket:
  * @buffer: pointer to RTCP buffer
@@ -168,8 +179,8 @@ typedef struct _GstRTCPPacket GstRTCPPacket;
  */
 struct _GstRTCPPacket
 { 
-  GstBuffer   *buffer;
-  guint        offset;
+  GstRTCPBuffer *rtcp;
+  guint         offset;
   
   /*< private >*/
   gboolean     padding;      /* padding field of current packet */
@@ -190,14 +201,16 @@ gboolean        gst_rtcp_buffer_validate_data     (guint8 *data, guint len);
 gboolean        gst_rtcp_buffer_validate          (GstBuffer *buffer);
 
 GstBuffer*      gst_rtcp_buffer_new               (guint mtu);
-void            gst_rtcp_buffer_end               (GstBuffer *buffer);
+
+gboolean        gst_rtcp_buffer_map               (GstBuffer *buffer, GstMapFlags flags, GstRTCPBuffer *rtcp);
+gboolean        gst_rtcp_buffer_unmap             (GstRTCPBuffer *rtcp);
 
 /* adding/retrieving packets */
-guint           gst_rtcp_buffer_get_packet_count  (GstBuffer *buffer);
-gboolean        gst_rtcp_buffer_get_first_packet  (GstBuffer *buffer, GstRTCPPacket *packet);
+guint           gst_rtcp_buffer_get_packet_count  (GstRTCPBuffer *rtcp);
+gboolean        gst_rtcp_buffer_get_first_packet  (GstRTCPBuffer *rtcp, GstRTCPPacket *packet);
 gboolean        gst_rtcp_packet_move_to_next      (GstRTCPPacket *packet);
 
-gboolean        gst_rtcp_buffer_add_packet        (GstBuffer *buffer, GstRTCPType type,
+gboolean        gst_rtcp_buffer_add_packet        (GstRTCPBuffer *rtcp, GstRTCPType type,
                                                   GstRTCPPacket *packet);
 gboolean        gst_rtcp_packet_remove            (GstRTCPPacket *packet);
 
index 141b072..7e5de64 100644 (file)
@@ -101,6 +101,7 @@ gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len,
 {
   guint len;
   guint8 *data;
+  GstMemory *mem;
 
   g_return_if_fail (csrc_count <= 15);
   g_return_if_fail (GST_IS_BUFFER (buffer));
@@ -108,11 +109,9 @@ gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len,
   len = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32)
       + payload_len + pad_len;
 
-  data = g_malloc (len);
-  GST_BUFFER_MALLOCDATA (buffer) = data;
-  GST_BUFFER_DATA (buffer) = data;
-  GST_BUFFER_SIZE (buffer) = len;
+  mem = gst_memory_new_alloc (len, 0);
 
+  data = gst_memory_map (mem, NULL, NULL, GST_MAP_WRITE);
   /* fill in defaults */
   GST_RTP_HEADER_VERSION (data) = GST_RTP_VERSION;
   GST_RTP_HEADER_PADDING (data) = FALSE;
@@ -125,6 +124,9 @@ gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len,
   GST_RTP_HEADER_SEQ (data) = 0;
   GST_RTP_HEADER_TIMESTAMP (data) = 0;
   GST_RTP_HEADER_SSRC (data) = 0;
+  gst_memory_unmap (mem, data, len);
+
+  gst_buffer_take_memory (buffer, mem);
 }
 
 /**
@@ -139,7 +141,7 @@ gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len,
  * Returns: A newly allocated buffer with @data and of size @len.
  */
 GstBuffer *
-gst_rtp_buffer_new_take_data (gpointer data, guint len)
+gst_rtp_buffer_new_take_data (gpointer data, gsize len)
 {
   GstBuffer *result;
 
@@ -147,10 +149,8 @@ gst_rtp_buffer_new_take_data (gpointer data, guint len)
   g_return_val_if_fail (len > 0, NULL);
 
   result = gst_buffer_new ();
-
-  GST_BUFFER_MALLOCDATA (result) = data;
-  GST_BUFFER_DATA (result) = data;
-  GST_BUFFER_SIZE (result) = len;
+  gst_buffer_take_memory (result,
+      gst_memory_new_wrapped (0, data, g_free, len, 0, len));
 
   return result;
 }
@@ -167,7 +167,7 @@ gst_rtp_buffer_new_take_data (gpointer data, guint len)
  * Returns: A newly allocated buffer with a copy of @data and of size @len.
  */
 GstBuffer *
-gst_rtp_buffer_new_copy_data (gpointer data, guint len)
+gst_rtp_buffer_new_copy_data (gpointer data, gsize len)
 {
   return gst_rtp_buffer_new_take_data (g_memdup (data, len), len);
 }
@@ -201,7 +201,7 @@ gst_rtp_buffer_new_allocate (guint payload_len, guint8 pad_len,
 
 /**
  * gst_rtp_buffer_new_allocate_len:
- * @packet_len: the total length of the packet
+ * @rtp_len: the total length of the packet
  * @pad_len: the amount of padding
  * @csrc_count: the number of CSRC entries
  *
@@ -391,7 +391,7 @@ dump_packet:
  * Returns: TRUE if the data points to a valid RTP packet.
  */
 gboolean
-gst_rtp_buffer_validate_data (guint8 * data, guint len)
+gst_rtp_buffer_validate_data (guint8 * data, gsize len)
 {
   return validate_data (data, len, NULL, 0);
 }
@@ -410,133 +410,80 @@ gst_rtp_buffer_validate_data (guint8 * data, guint len)
 gboolean
 gst_rtp_buffer_validate (GstBuffer * buffer)
 {
+  gboolean res;
   guint8 *data;
-  guint len;
+  gsize len;
 
   g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
 
-  data = GST_BUFFER_DATA (buffer);
-  len = GST_BUFFER_SIZE (buffer);
+  data = gst_buffer_map (buffer, &len, NULL, GST_MAP_READ);
+  res = validate_data (data, len, NULL, 0);
+  gst_buffer_unmap (buffer, data, len);
 
-  return validate_data (data, len, NULL, 0);
+  return res;
 }
 
-/**
- * gst_rtp_buffer_list_validate:
- * @list: the buffer list to validate
- *
- * Check if all RTP packets in the @list are valid using validate_data().
- * Use this function to validate an list before using the other functions in
- * this module.
- *
- * Returns: TRUE if @list consists only of valid RTP packets.
- *
- * Since: 0.10.24
- */
 gboolean
-gst_rtp_buffer_list_validate (GstBufferList * list)
+gst_rtp_buffer_map (GstBuffer * buffer, GstMapFlags flags, GstRTPBuffer * rtp)
 {
-  guint16 prev_seqnum = 0;
-  GstBufferListIterator *it;
-  guint i = 0;
-
-  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), FALSE);
-
-  it = gst_buffer_list_iterate (list);
-  g_return_val_if_fail (it != NULL, FALSE);
-
-  /* iterate through all the RTP packets in the list */
-  while (gst_buffer_list_iterator_next_group (it)) {
-    GstBuffer *rtpbuf;
-    GstBuffer *paybuf;
-    guint8 *packet_header;
-    guint8 *packet_payload;
-    guint payload_size;
-    guint packet_size;
-    guint j, n_buffers;
-
-    /* each group should consists of at least 1 buffer: The first buffer always
-     * contains the complete RTP header. Next buffers contain the payload */
-    n_buffers = gst_buffer_list_iterator_n_buffers (it);
-    if (n_buffers < 1)
-      goto invalid_list;
-
-    /* get the RTP header (and if n_buffers == 1 also the payload) */
-    rtpbuf = gst_buffer_list_iterator_next (it);
-    packet_header = GST_BUFFER_DATA (rtpbuf);
-    if (packet_header == NULL)
-      goto invalid_list;
-
-    /* check the sequence number */
-    if (G_UNLIKELY (i == 0)) {
-      prev_seqnum = g_ntohs (GST_RTP_HEADER_SEQ (packet_header));
-      i++;
-    } else {
-      if (++prev_seqnum != g_ntohs (GST_RTP_HEADER_SEQ (packet_header)))
-        goto invalid_list;
-    }
+  guint8 *data;
+  gsize size, maxsize;
 
-    packet_size = GST_BUFFER_SIZE (rtpbuf);
-    packet_payload = NULL;
-    payload_size = 0;
+  g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+  g_return_val_if_fail (rtp != NULL, FALSE);
+  g_return_val_if_fail (rtp->buffer == NULL, FALSE);
 
-    /* get the payload buffers */
-    for (j = 1; j < n_buffers; j++) {
-      /* get the payload */
-      paybuf = gst_buffer_list_iterator_next (it);
+  data = gst_buffer_map (buffer, &size, &maxsize, flags);
+  if (data == NULL)
+    return FALSE;
 
-      if ((packet_payload = GST_BUFFER_DATA (paybuf)) == NULL)
-        goto invalid_list;
+  rtp->buffer = buffer;
+  rtp->flags = flags;
+  rtp->data = data;
+  rtp->size = size;
+  rtp->maxsize = maxsize;
 
-      if ((payload_size = GST_BUFFER_SIZE (paybuf)) == 0)
-        goto invalid_list;
+  return TRUE;
+}
 
-      /* the size of the RTP packet within the current group */
-      packet_size += payload_size;
-    }
+gboolean
+gst_rtp_buffer_unmap (GstRTPBuffer * rtp)
+{
+  g_return_val_if_fail (rtp != NULL, FALSE);
+  g_return_val_if_fail (rtp->buffer != NULL, FALSE);
 
-    /* validate packet */
-    if (!validate_data (packet_header, packet_size, packet_payload,
-            payload_size)) {
-      goto invalid_list;
-    }
-  }
+  gst_buffer_unmap (rtp->buffer, rtp->data, rtp->size);
 
-  gst_buffer_list_iterator_free (it);
+  rtp->buffer = NULL;
 
   return TRUE;
-
-  /* ERRORS */
-invalid_list:
-  {
-    gst_buffer_list_iterator_free (it);
-    return FALSE;
-  }
 }
 
+
 /**
  * gst_rtp_buffer_set_packet_len:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @len: the new packet length
  *
- * Set the total @buffer size to @len. The data in the buffer will be made
- * larger if needed. Any padding will be removed from the packet. 
+ * Set the total @rtp size to @len. The data in the buffer will be made
+ * larger if needed. Any padding will be removed from the packet.
  */
 void
-gst_rtp_buffer_set_packet_len (GstBuffer * buffer, guint len)
+gst_rtp_buffer_set_packet_len (GstRTPBuffer * rtp, guint len)
 {
   guint oldlen;
   guint8 *data;
 
-  oldlen = GST_BUFFER_SIZE (buffer);
-  data = GST_BUFFER_DATA (buffer);
+  oldlen = rtp->size;
+  data = rtp->data;
 
-  if (oldlen < len) {
-    data = g_realloc (GST_BUFFER_MALLOCDATA (buffer), len);
-    GST_BUFFER_MALLOCDATA (buffer) = data;
-    GST_BUFFER_DATA (buffer) = data;
+  if (rtp->maxsize <= len) {
+    /* FIXME, realloc bigger space */
+    g_warning ("not implemented");
   }
-  GST_BUFFER_SIZE (buffer) = len;
+
+  gst_buffer_set_size (rtp->buffer, len);
+  rtp->size = len;
 
   /* remove any padding */
   GST_RTP_HEADER_PADDING (data) = FALSE;
@@ -544,21 +491,21 @@ gst_rtp_buffer_set_packet_len (GstBuffer * buffer, guint len)
 
 /**
  * gst_rtp_buffer_get_packet_len:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  *
  * Return the total length of the packet in @buffer.
  *
  * Returns: The total length of the packet in @buffer.
  */
 guint
-gst_rtp_buffer_get_packet_len (GstBuffer * buffer)
+gst_rtp_buffer_get_packet_len (GstRTPBuffer * rtp)
 {
-  return GST_BUFFER_SIZE (buffer);
+  return gst_buffer_get_size (rtp->buffer);
 }
 
 /**
  * gst_rtp_buffer_get_header_len:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  *
  * Return the total length of the header in @buffer. This include the length of
  * the fixed header, the CSRC list and the extension header.
@@ -566,12 +513,12 @@ gst_rtp_buffer_get_packet_len (GstBuffer * buffer)
  * Returns: The total length of the header in @buffer.
  */
 guint
-gst_rtp_buffer_get_header_len (GstBuffer * buffer)
+gst_rtp_buffer_get_header_len (GstRTPBuffer * rtp)
 {
   guint len;
   guint8 *data;
 
-  data = GST_BUFFER_DATA (buffer);
+  data = rtp->data;
 
   len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data);
   if (GST_RTP_HEADER_EXTENSION (data))
@@ -582,45 +529,45 @@ gst_rtp_buffer_get_header_len (GstBuffer * buffer)
 
 /**
  * gst_rtp_buffer_get_version:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  *
  * Get the version number of the RTP packet in @buffer.
  *
  * Returns: The version of @buffer.
  */
 guint8
-gst_rtp_buffer_get_version (GstBuffer * buffer)
+gst_rtp_buffer_get_version (GstRTPBuffer * rtp)
 {
-  return GST_RTP_HEADER_VERSION (GST_BUFFER_DATA (buffer));
+  return GST_RTP_HEADER_VERSION (rtp->data);
 }
 
 /**
  * gst_rtp_buffer_set_version:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @version: the new version
  *
  * Set the version of the RTP packet in @buffer to @version.
  */
 void
-gst_rtp_buffer_set_version (GstBuffer * buffer, guint8 version)
+gst_rtp_buffer_set_version (GstRTPBuffer * rtp, guint8 version)
 {
   g_return_if_fail (version < 0x04);
 
-  GST_RTP_HEADER_VERSION (GST_BUFFER_DATA (buffer)) = version;
+  GST_RTP_HEADER_VERSION (rtp->data) = version;
 }
 
 /**
  * gst_rtp_buffer_get_padding:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  *
  * Check if the padding bit is set on the RTP packet in @buffer.
  *
  * Returns: TRUE if @buffer has the padding bit set.
  */
 gboolean
-gst_rtp_buffer_get_padding (GstBuffer * buffer)
+gst_rtp_buffer_get_padding (GstRTPBuffer * rtp)
 {
-  return GST_RTP_HEADER_PADDING (GST_BUFFER_DATA (buffer));
+  return GST_RTP_HEADER_PADDING (rtp->data);
 }
 
 /**
@@ -631,14 +578,14 @@ gst_rtp_buffer_get_padding (GstBuffer * buffer)
  * Set the padding bit on the RTP packet in @buffer to @padding.
  */
 void
-gst_rtp_buffer_set_padding (GstBuffer * buffer, gboolean padding)
+gst_rtp_buffer_set_padding (GstRTPBuffer * rtp, gboolean padding)
 {
-  GST_RTP_HEADER_PADDING (GST_BUFFER_DATA (buffer)) = padding;
+  GST_RTP_HEADER_PADDING (rtp->data) = padding;
 }
 
 /**
  * gst_rtp_buffer_pad_to:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @len: the new amount of padding
  *
  * Set the amount of padding in the RTP packet in @buffer to
@@ -647,11 +594,11 @@ gst_rtp_buffer_set_padding (GstBuffer * buffer, gboolean padding)
  * NOTE: This function does not work correctly.
  */
 void
-gst_rtp_buffer_pad_to (GstBuffer * buffer, guint len)
+gst_rtp_buffer_pad_to (GstRTPBuffer * rtp, guint len)
 {
   guint8 *data;
 
-  data = GST_BUFFER_DATA (buffer);
+  data = rtp->data;
 
   if (len > 0)
     GST_RTP_HEADER_PADDING (data) = TRUE;
@@ -663,34 +610,34 @@ gst_rtp_buffer_pad_to (GstBuffer * buffer, guint len)
 
 /**
  * gst_rtp_buffer_get_extension:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  *
  * Check if the extension bit is set on the RTP packet in @buffer.
  * 
  * Returns: TRUE if @buffer has the extension bit set.
  */
 gboolean
-gst_rtp_buffer_get_extension (GstBuffer * buffer)
+gst_rtp_buffer_get_extension (GstRTPBuffer * rtp)
 {
-  return GST_RTP_HEADER_EXTENSION (GST_BUFFER_DATA (buffer));
+  return GST_RTP_HEADER_EXTENSION (rtp->data);
 }
 
 /**
  * gst_rtp_buffer_set_extension:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @extension: the new extension
  *
  * Set the extension bit on the RTP packet in @buffer to @extension.
  */
 void
-gst_rtp_buffer_set_extension (GstBuffer * buffer, gboolean extension)
+gst_rtp_buffer_set_extension (GstRTPBuffer * rtp, gboolean extension)
 {
-  GST_RTP_HEADER_EXTENSION (GST_BUFFER_DATA (buffer)) = extension;
+  GST_RTP_HEADER_EXTENSION (rtp->data) = extension;
 }
 
 /**
  * gst_rtp_buffer_get_extension_data:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @bits: location for result bits
  * @data: location for data
  * @wordlen: location for length of @data in 32 bits words
@@ -707,13 +654,13 @@ gst_rtp_buffer_set_extension (GstBuffer * buffer, gboolean extension)
  * Since: 0.10.15
  */
 gboolean
-gst_rtp_buffer_get_extension_data (GstBuffer * buffer, guint16 * bits,
+gst_rtp_buffer_get_extension_data (GstRTPBuffer * rtp, guint16 * bits,
     gpointer * data, guint * wordlen)
 {
   guint len;
   guint8 *pdata;
 
-  pdata = GST_BUFFER_DATA (buffer);
+  pdata = rtp->data;
 
   if (!GST_RTP_HEADER_EXTENSION (pdata))
     return FALSE;
@@ -734,7 +681,7 @@ gst_rtp_buffer_get_extension_data (GstBuffer * buffer, guint16 * bits,
 
 /**
  * gst_rtp_buffer_set_extension_data:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @bits: the bits specific for the extension
  * @length: the length that counts the number of 32-bit words in
  * the extension, excluding the extension header ( therefore zero is a valid length)
@@ -748,23 +695,23 @@ gst_rtp_buffer_get_extension_data (GstBuffer * buffer, guint16 * bits,
  * Since: 0.10.18
  */
 gboolean
-gst_rtp_buffer_set_extension_data (GstBuffer * buffer, guint16 bits,
+gst_rtp_buffer_set_extension_data (GstRTPBuffer * rtp, guint16 bits,
     guint16 length)
 {
   guint32 min_size = 0;
   guint8 *data;
 
-  data = GST_BUFFER_DATA (buffer);
+  data = rtp->data;
 
   /* check if the buffer is big enough to hold the extension */
   min_size =
       GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data) + 4 +
       length * sizeof (guint32);
-  if (G_UNLIKELY (min_size > GST_BUFFER_SIZE (buffer)))
+  if (G_UNLIKELY (min_size > rtp->size))
     goto too_small;
 
   /* now we can set the extension bit */
-  gst_rtp_buffer_set_extension (buffer, TRUE);
+  GST_RTP_HEADER_EXTENSION (rtp->data) = TRUE;
 
   data += GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data);
   GST_WRITE_UINT16_BE (data, bits);
@@ -776,100 +723,56 @@ gst_rtp_buffer_set_extension_data (GstBuffer * buffer, guint16 bits,
 too_small:
   {
     g_warning
-        ("rtp buffer too small: need more than %d bytes but only have %d bytes",
-        min_size, GST_BUFFER_SIZE (buffer));
+        ("rtp buffer too small: need more than %d bytes but only have %"
+        G_GSIZE_FORMAT " bytes", min_size, rtp->size);
     return FALSE;
   }
 }
 
 /**
  * gst_rtp_buffer_get_ssrc:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  *
  * Get the SSRC of the RTP packet in @buffer.
  * 
  * Returns: the SSRC of @buffer in host order.
  */
 guint32
-gst_rtp_buffer_get_ssrc (GstBuffer * buffer)
-{
-  return g_ntohl (GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer)));
-}
-
-/**
- * gst_rtp_buffer_list_get_ssrc:
- * @list: the buffer list
- *
- * Get the SSRC of the first RTP packet in @list.
- * All RTP packets within @list have the same SSRC.
- *
- * Returns: the SSRC of @list in host order.
- *
- * Since: 0.10.24
- */
-guint32
-gst_rtp_buffer_list_get_ssrc (GstBufferList * list)
+gst_rtp_buffer_get_ssrc (GstRTPBuffer * rtp)
 {
-  GstBuffer *buffer;
-
-  buffer = gst_buffer_list_get (list, 0, 0);
-  g_return_val_if_fail (buffer != NULL, 0);
-
-  return g_ntohl (GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer)));
+  return g_ntohl (GST_RTP_HEADER_SSRC (rtp->data));
 }
 
 /**
  * gst_rtp_buffer_set_ssrc:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @ssrc: the new SSRC
  *
  * Set the SSRC on the RTP packet in @buffer to @ssrc.
  */
 void
-gst_rtp_buffer_set_ssrc (GstBuffer * buffer, guint32 ssrc)
-{
-  GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer)) = g_htonl (ssrc);
-}
-
-static GstBufferListItem
-set_ssrc_header (GstBuffer ** buffer, guint group, guint idx, guint32 * ssrc)
-{
-  GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (*buffer)) = g_htonl (*ssrc);
-  return GST_BUFFER_LIST_SKIP_GROUP;
-}
-
-/**
- * gst_rtp_buffer_list_set_ssrc:
- * @list: the buffer list
- * @ssrc: the new SSRC
- *
- * Set the SSRC on each RTP packet in @list to @ssrc.
- *
- * Since: 0.10.24
- */
-void
-gst_rtp_buffer_list_set_ssrc (GstBufferList * list, guint32 ssrc)
+gst_rtp_buffer_set_ssrc (GstRTPBuffer * rtp, guint32 ssrc)
 {
-  gst_buffer_list_foreach (list, (GstBufferListFunc) set_ssrc_header, &ssrc);
+  GST_RTP_HEADER_SSRC (rtp->data) = g_htonl (ssrc);
 }
 
 /**
  * gst_rtp_buffer_get_csrc_count:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  *
  * Get the CSRC count of the RTP packet in @buffer.
  * 
  * Returns: the CSRC count of @buffer.
  */
 guint8
-gst_rtp_buffer_get_csrc_count (GstBuffer * buffer)
+gst_rtp_buffer_get_csrc_count (GstRTPBuffer * rtp)
 {
-  return GST_RTP_HEADER_CSRC_COUNT (GST_BUFFER_DATA (buffer));
+  return GST_RTP_HEADER_CSRC_COUNT (rtp->data);
 }
 
 /**
  * gst_rtp_buffer_get_csrc:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @idx: the index of the CSRC to get
  *
  * Get the CSRC at index @idx in @buffer.
@@ -877,11 +780,11 @@ gst_rtp_buffer_get_csrc_count (GstBuffer * buffer)
  * Returns: the CSRC at index @idx in host order.
  */
 guint32
-gst_rtp_buffer_get_csrc (GstBuffer * buffer, guint8 idx)
+gst_rtp_buffer_get_csrc (GstRTPBuffer * rtp, guint8 idx)
 {
   guint8 *data;
 
-  data = GST_BUFFER_DATA (buffer);
+  data = rtp->data;
 
   g_return_val_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data), 0);
 
@@ -890,18 +793,18 @@ gst_rtp_buffer_get_csrc (GstBuffer * buffer, guint8 idx)
 
 /**
  * gst_rtp_buffer_set_csrc:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @idx: the CSRC index to set
  * @csrc: the CSRC in host order to set at @idx
  *
  * Modify the CSRC at index @idx in @buffer to @csrc.
  */
 void
-gst_rtp_buffer_set_csrc (GstBuffer * buffer, guint8 idx, guint32 csrc)
+gst_rtp_buffer_set_csrc (GstRTPBuffer * rtp, guint8 idx, guint32 csrc)
 {
   guint8 *data;
 
-  data = GST_BUFFER_DATA (buffer);
+  data = rtp->data;
 
   g_return_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data));
 
@@ -910,260 +813,118 @@ gst_rtp_buffer_set_csrc (GstBuffer * buffer, guint8 idx, guint32 csrc)
 
 /**
  * gst_rtp_buffer_get_marker:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  *
  * Check if the marker bit is set on the RTP packet in @buffer.
  *
  * Returns: TRUE if @buffer has the marker bit set.
  */
 gboolean
-gst_rtp_buffer_get_marker (GstBuffer * buffer)
+gst_rtp_buffer_get_marker (GstRTPBuffer * rtp)
 {
-  return GST_RTP_HEADER_MARKER (GST_BUFFER_DATA (buffer));
+  return GST_RTP_HEADER_MARKER (rtp->data);
 }
 
 /**
  * gst_rtp_buffer_set_marker:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @marker: the new marker
  *
  * Set the marker bit on the RTP packet in @buffer to @marker.
  */
 void
-gst_rtp_buffer_set_marker (GstBuffer * buffer, gboolean marker)
+gst_rtp_buffer_set_marker (GstRTPBuffer * rtp, gboolean marker)
 {
-  GST_RTP_HEADER_MARKER (GST_BUFFER_DATA (buffer)) = marker;
+  GST_RTP_HEADER_MARKER (rtp->data) = marker;
 }
 
 /**
  * gst_rtp_buffer_get_payload_type:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  *
  * Get the payload type of the RTP packet in @buffer.
  *
  * Returns: The payload type.
  */
 guint8
-gst_rtp_buffer_get_payload_type (GstBuffer * buffer)
-{
-  return GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer));
-}
-
-/**
- * gst_rtp_buffer_list_get_payload_type:
- * @list: the buffer list
- *
- * Get the payload type of the first RTP packet in @list.
- * All packets in @list should have the same payload type.
- *
- * Returns: The payload type.
- *
- * Since: 0.10.24
- */
-guint8
-gst_rtp_buffer_list_get_payload_type (GstBufferList * list)
+gst_rtp_buffer_get_payload_type (GstRTPBuffer * rtp)
 {
-  GstBuffer *buffer;
-
-  buffer = gst_buffer_list_get (list, 0, 0);
-  g_return_val_if_fail (buffer != NULL, 0);
-
-  return GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer));
+  return GST_RTP_HEADER_PAYLOAD_TYPE (rtp->data);
 }
 
 /**
  * gst_rtp_buffer_set_payload_type:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @payload_type: the new type
  *
  * Set the payload type of the RTP packet in @buffer to @payload_type.
  */
 void
-gst_rtp_buffer_set_payload_type (GstBuffer * buffer, guint8 payload_type)
+gst_rtp_buffer_set_payload_type (GstRTPBuffer * rtp, guint8 payload_type)
 {
   g_return_if_fail (payload_type < 0x80);
 
-  GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer)) = payload_type;
-}
-
-static GstBufferListItem
-set_pt_header (GstBuffer ** buffer, guint group, guint idx, guint8 * pt)
-{
-  GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (*buffer)) = *pt;
-  return GST_BUFFER_LIST_SKIP_GROUP;
-}
-
-/**
- * gst_rtp_buffer_list_set_payload_type:
- * @list: the buffer list
- * @payload_type: the new type
- *
- * Set the payload type of each RTP packet in @list to @payload_type.
- *
- * Since: 0.10.24
- */
-void
-gst_rtp_buffer_list_set_payload_type (GstBufferList * list, guint8 payload_type)
-{
-  g_return_if_fail (payload_type < 0x80);
-
-  gst_buffer_list_foreach (list, (GstBufferListFunc) set_pt_header,
-      &payload_type);
+  GST_RTP_HEADER_PAYLOAD_TYPE (rtp->data) = payload_type;
 }
 
 /**
  * gst_rtp_buffer_get_seq:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  *
  * Get the sequence number of the RTP packet in @buffer.
  *
  * Returns: The sequence number in host order.
  */
 guint16
-gst_rtp_buffer_get_seq (GstBuffer * buffer)
+gst_rtp_buffer_get_seq (GstRTPBuffer * rtp)
 {
-  return g_ntohs (GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)));
+  return g_ntohs (GST_RTP_HEADER_SEQ (rtp->data));
 }
 
 /**
  * gst_rtp_buffer_set_seq:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @seq: the new sequence number
  *
  * Set the sequence number of the RTP packet in @buffer to @seq.
  */
 void
-gst_rtp_buffer_set_seq (GstBuffer * buffer, guint16 seq)
+gst_rtp_buffer_set_seq (GstRTPBuffer * rtp, guint16 seq)
 {
-  GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)) = g_htons (seq);
-}
-
-static GstBufferListItem
-set_seq_header (GstBuffer ** buffer, guint group, guint idx, guint16 * seq)
-{
-  GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (*buffer)) = g_htons (*seq);
-  (*seq)++;
-  return GST_BUFFER_LIST_SKIP_GROUP;
-}
-
-/**
- * gst_rtp_buffer_list_set_seq:
- * @list: the buffer list
- * @seq: the new sequence number
- *
- * Set the sequence number of each RTP packet in @list to @seq.
- *
- * Returns: The seq number of the last packet in the list + 1.
- *
- * Since: 0.10.24
- */
-guint16
-gst_rtp_buffer_list_set_seq (GstBufferList * list, guint16 seq)
-{
-  gst_buffer_list_foreach (list, (GstBufferListFunc) set_seq_header, &seq);
-  return seq;
+  GST_RTP_HEADER_SEQ (rtp->data) = g_htons (seq);
 }
 
 /**
- * gst_rtp_buffer_list_get_seq:
- * @list: the buffer list
- *
- * Get the sequence number of the first RTP packet in @list.
- * All packets within @list have the same sequence number.
- *
- * Returns: The seq number
- *
- * Since: 0.10.24
- */
-guint16
-gst_rtp_buffer_list_get_seq (GstBufferList * list)
-{
-  GstBuffer *buffer;
-
-  buffer = gst_buffer_list_get (list, 0, 0);
-  g_return_val_if_fail (buffer != NULL, 0);
-
-  return g_ntohl (GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)));
-}
-
-
-/**
  * gst_rtp_buffer_get_timestamp:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  *
  * Get the timestamp of the RTP packet in @buffer.
  *
  * Returns: The timestamp in host order.
  */
 guint32
-gst_rtp_buffer_get_timestamp (GstBuffer * buffer)
-{
-  return g_ntohl (GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer)));
-}
-
-/**
- * gst_rtp_buffer_list_get_timestamp:
- * @list: the buffer list
- *
- * Get the timestamp of the first RTP packet in @list.
- * All packets within @list have the same timestamp.
- *
- * Returns: The timestamp in host order.
- *
- * Since: 0.10.24
- */
-guint32
-gst_rtp_buffer_list_get_timestamp (GstBufferList * list)
+gst_rtp_buffer_get_timestamp (GstRTPBuffer * rtp)
 {
-  GstBuffer *buffer;
-
-  buffer = gst_buffer_list_get (list, 0, 0);
-  g_return_val_if_fail (buffer != NULL, 0);
-
-  return g_ntohl (GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer)));
+  return g_ntohl (GST_RTP_HEADER_TIMESTAMP (rtp->data));
 }
 
 /**
  * gst_rtp_buffer_set_timestamp:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @timestamp: the new timestamp
  *
  * Set the timestamp of the RTP packet in @buffer to @timestamp.
  */
 void
-gst_rtp_buffer_set_timestamp (GstBuffer * buffer, guint32 timestamp)
-{
-  GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer)) = g_htonl (timestamp);
-}
-
-
-static GstBufferListItem
-set_timestamp_header (GstBuffer ** buffer, guint group, guint idx,
-    guint32 * timestamp)
+gst_rtp_buffer_set_timestamp (GstRTPBuffer * rtp, guint32 timestamp)
 {
-  GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (*buffer)) = g_htonl (*timestamp);
-  return GST_BUFFER_LIST_SKIP_GROUP;
+  GST_RTP_HEADER_TIMESTAMP (rtp->data) = g_htonl (timestamp);
 }
 
-/**
- * gst_rtp_buffer_list_set_timestamp:
- * @list: the buffer list
- * @timestamp: the new timestamp
- *
- * Set the timestamp of each RTP packet in @list to @timestamp.
- *
- * Since: 0.10.24
- */
-void
-gst_rtp_buffer_list_set_timestamp (GstBufferList * list, guint32 timestamp)
-{
-  gst_buffer_list_foreach (list, (GstBufferListFunc) set_timestamp_header,
-      &timestamp);
-}
 
 /**
  * gst_rtp_buffer_get_payload_subbuffer:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @offset: the offset in the payload
  * @len: the length in the payload
  *
@@ -1176,25 +937,26 @@ gst_rtp_buffer_list_set_timestamp (GstBufferList * list, guint32 timestamp)
  * Since: 0.10.10
  */
 GstBuffer *
-gst_rtp_buffer_get_payload_subbuffer (GstBuffer * buffer, guint offset,
+gst_rtp_buffer_get_payload_subbuffer (GstRTPBuffer * rtp, guint offset,
     guint len)
 {
   guint poffset, plen;
 
-  plen = gst_rtp_buffer_get_payload_len (buffer);
+  plen = gst_rtp_buffer_get_payload_len (rtp);
   /* we can't go past the length */
   if (G_UNLIKELY (offset >= plen))
     goto wrong_offset;
 
   /* apply offset */
-  poffset = gst_rtp_buffer_get_header_len (buffer) + offset;
+  poffset = gst_rtp_buffer_get_header_len (rtp) + offset;
   plen -= offset;
 
   /* see if we need to shrink the buffer based on @len */
   if (len != -1 && len < plen)
     plen = len;
 
-  return gst_buffer_create_sub (buffer, poffset, plen);
+  return gst_buffer_copy_region (rtp->buffer, GST_BUFFER_COPY_ALL, poffset,
+      plen);
 
   /* ERRORS */
 wrong_offset:
@@ -1206,7 +968,7 @@ wrong_offset:
 
 /**
  * gst_rtp_buffer_get_payload_buffer:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  *
  * Create a buffer of the payload of the RTP packet in @buffer. This function
  * will internally create a subbuffer of @buffer so that a memcpy can be
@@ -1215,29 +977,29 @@ wrong_offset:
  * Returns: A new buffer with the data of the payload.
  */
 GstBuffer *
-gst_rtp_buffer_get_payload_buffer (GstBuffer * buffer)
+gst_rtp_buffer_get_payload_buffer (GstRTPBuffer * rtp)
 {
-  return gst_rtp_buffer_get_payload_subbuffer (buffer, 0, -1);
+  return gst_rtp_buffer_get_payload_subbuffer (rtp, 0, -1);
 }
 
 /**
  * gst_rtp_buffer_get_payload_len:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  *
  * Get the length of the payload of the RTP packet in @buffer.
  *
  * Returns: The length of the payload in @buffer.
  */
 guint
-gst_rtp_buffer_get_payload_len (GstBuffer * buffer)
+gst_rtp_buffer_get_payload_len (GstRTPBuffer * rtp)
 {
   guint len, size;
   guint8 *data;
 
-  size = GST_BUFFER_SIZE (buffer);
-  data = GST_BUFFER_DATA (buffer);
+  size = rtp->size;
+  data = rtp->data;
 
-  len = size - gst_rtp_buffer_get_header_len (buffer);
+  len = size - gst_rtp_buffer_get_header_len (rtp);
 
   if (GST_RTP_HEADER_PADDING (data))
     len -= data[size - 1];
@@ -1246,46 +1008,8 @@ gst_rtp_buffer_get_payload_len (GstBuffer * buffer)
 }
 
 /**
- * gst_rtp_buffer_list_get_payload_len:
- * @list: the buffer list
- *
- * Get the length of the payload of the RTP packet in @list.
- *
- * Returns: The length of the payload in @list.
- *
- * Since: 0.10.24
- */
-guint
-gst_rtp_buffer_list_get_payload_len (GstBufferList * list)
-{
-  guint len;
-  GstBufferListIterator *it;
-
-  it = gst_buffer_list_iterate (list);
-  len = 0;
-
-  while (gst_buffer_list_iterator_next_group (it)) {
-    guint i;
-    GstBuffer *buf;
-
-    i = 0;
-    while ((buf = gst_buffer_list_iterator_next (it))) {
-      /* skip the RTP header */
-      if (!i++)
-        continue;
-      /* take the size of the current buffer */
-      len += GST_BUFFER_SIZE (buf);
-    }
-  }
-
-  gst_buffer_list_iterator_free (it);
-
-  return len;
-}
-
-/**
  * gst_rtp_buffer_get_payload:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  *
  * Get a pointer to the payload data in @buffer. This pointer is valid as long
  * as a reference to @buffer is held.
@@ -1293,9 +1017,9 @@ gst_rtp_buffer_list_get_payload_len (GstBufferList * list)
  * Returns: A pointer to the payload data in @buffer.
  */
 gpointer
-gst_rtp_buffer_get_payload (GstBuffer * buffer)
+gst_rtp_buffer_get_payload (GstRTPBuffer * rtp)
 {
-  return GST_BUFFER_DATA (buffer) + gst_rtp_buffer_get_header_len (buffer);
+  return rtp->data + gst_rtp_buffer_get_header_len (rtp);
 }
 
 /**
@@ -1395,7 +1119,7 @@ gst_rtp_buffer_ext_timestamp (guint64 * exttimestamp, guint32 timestamp)
 
 /**
  * gst_rtp_buffer_get_extension_onebyte_header:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @id: The ID of the header extension to be read (between 1 and 14).
  * @nth: Read the nth extension packet with the requested ID
  * @data: location for data
@@ -1410,7 +1134,7 @@ gst_rtp_buffer_ext_timestamp (guint64 * exttimestamp, guint32 timestamp)
  */
 
 gboolean
-gst_rtp_buffer_get_extension_onebyte_header (GstBuffer * buffer, guint8 id,
+gst_rtp_buffer_get_extension_onebyte_header (GstRTPBuffer * rtp, guint8 id,
     guint nth, gpointer * data, guint * size)
 {
   guint16 bits;
@@ -1421,7 +1145,7 @@ gst_rtp_buffer_get_extension_onebyte_header (GstBuffer * buffer, guint8 id,
 
   g_return_val_if_fail (id > 0 && id < 15, FALSE);
 
-  if (!gst_rtp_buffer_get_extension_data (buffer, &bits, (gpointer) & pdata,
+  if (!gst_rtp_buffer_get_extension_data (rtp, &bits, (gpointer) & pdata,
           &wordlen))
     return FALSE;
 
@@ -1474,7 +1198,7 @@ gst_rtp_buffer_get_extension_onebyte_header (GstBuffer * buffer, guint8 id,
 
 /**
  * gst_rtp_buffer_get_extension_twobytes_header:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @appbits: Application specific bits
  * @id: The ID of the header extension to be read (between 1 and 14).
  * @nth: Read the nth extension packet with the requested ID
@@ -1490,7 +1214,7 @@ gst_rtp_buffer_get_extension_onebyte_header (GstBuffer * buffer, guint8 id,
  */
 
 gboolean
-gst_rtp_buffer_get_extension_twobytes_header (GstBuffer * buffer,
+gst_rtp_buffer_get_extension_twobytes_header (GstRTPBuffer * rtp,
     guint8 * appbits, guint8 id, guint nth, gpointer * data, guint * size)
 {
   guint16 bits;
@@ -1500,7 +1224,7 @@ gst_rtp_buffer_get_extension_twobytes_header (GstBuffer * buffer,
   gulong offset = 0;
   guint count = 0;
 
-  if (!gst_rtp_buffer_get_extension_data (buffer, &bits, (gpointer) & pdata,
+  if (!gst_rtp_buffer_get_extension_data (rtp, &bits, (gpointer) & pdata,
           &wordlen))
     return FALSE;
 
@@ -1588,7 +1312,7 @@ get_onebyte_header_end_offset (guint8 * pdata, guint wordlen)
 
 /**
  * gst_rtp_buffer_add_extension_onebyte_header:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @id: The ID of the header extension (between 1 and 14).
  * @data: location for data
  * @size: the size of the data in bytes
@@ -1607,7 +1331,7 @@ get_onebyte_header_end_offset (guint8 * pdata, guint wordlen)
  */
 
 gboolean
-gst_rtp_buffer_add_extension_onebyte_header (GstBuffer * buffer, guint8 id,
+gst_rtp_buffer_add_extension_onebyte_header (GstRTPBuffer * rtp, guint8 id,
     gpointer data, guint size)
 {
   guint16 bits;
@@ -1617,9 +1341,9 @@ gst_rtp_buffer_add_extension_onebyte_header (GstBuffer * buffer, guint8 id,
 
   g_return_val_if_fail (id > 0 && id < 15, FALSE);
   g_return_val_if_fail (size >= 1 && size <= 16, FALSE);
-  g_return_val_if_fail (gst_buffer_is_writable (buffer), FALSE);
+  g_return_val_if_fail (gst_buffer_is_writable (rtp->buffer), FALSE);
 
-  has_bit = gst_rtp_buffer_get_extension_data (buffer, &bits,
+  has_bit = gst_rtp_buffer_get_extension_data (rtp, &bits,
       (gpointer) & pdata, &wordlen);
 
   if (has_bit) {
@@ -1635,10 +1359,10 @@ gst_rtp_buffer_add_extension_onebyte_header (GstBuffer * buffer, guint8 id,
       return FALSE;
 
     nextext = pdata + offset;
-    offset = nextext - GST_BUFFER_DATA (buffer);
+    offset = nextext - rtp->data;
 
     /* Don't add extra header if there isn't enough space */
-    if (GST_BUFFER_SIZE (buffer) < offset + size + 1)
+    if (rtp->size < offset + size + 1)
       return FALSE;
 
     nextext[0] = (id << 4) | (0x0F & (size - 1));
@@ -1652,13 +1376,13 @@ gst_rtp_buffer_add_extension_onebyte_header (GstBuffer * buffer, guint8 id,
       wordlen = extlen / 4;
     }
 
-    gst_rtp_buffer_set_extension_data (buffer, 0xBEDE, wordlen);
+    gst_rtp_buffer_set_extension_data (rtp, 0xBEDE, wordlen);
   } else {
     wordlen = (size + 1) / 4 + (((size + 1) % 4) ? 1 : 0);
 
-    gst_rtp_buffer_set_extension_data (buffer, 0xBEDE, wordlen);
+    gst_rtp_buffer_set_extension_data (rtp, 0xBEDE, wordlen);
 
-    gst_rtp_buffer_get_extension_data (buffer, &bits,
+    gst_rtp_buffer_get_extension_data (rtp, &bits,
         (gpointer) & pdata, &wordlen);
 
     pdata[0] = (id << 4) | (0x0F & (size - 1));
@@ -1708,7 +1432,7 @@ get_twobytes_header_end_offset (guint8 * pdata, guint wordlen)
 
 /**
  * gst_rtp_buffer_add_extension_twobytes_header:
- * @buffer: the buffer
+ * @rtp: the RTP packet
  * @appbits: Application specific bits
  * @id: The ID of the header extension
  * @data: location for data
@@ -1728,7 +1452,7 @@ get_twobytes_header_end_offset (guint8 * pdata, guint wordlen)
  */
 
 gboolean
-gst_rtp_buffer_add_extension_twobytes_header (GstBuffer * buffer,
+gst_rtp_buffer_add_extension_twobytes_header (GstRTPBuffer * rtp,
     guint8 appbits, guint8 id, gpointer data, guint size)
 {
   guint16 bits;
@@ -1738,9 +1462,9 @@ gst_rtp_buffer_add_extension_twobytes_header (GstBuffer * buffer,
 
   g_return_val_if_fail ((appbits & 0xF0) == 0, FALSE);
   g_return_val_if_fail (size < 256, FALSE);
-  g_return_val_if_fail (gst_buffer_is_writable (buffer), FALSE);
+  g_return_val_if_fail (gst_buffer_is_writable (rtp->buffer), FALSE);
 
-  has_bit = gst_rtp_buffer_get_extension_data (buffer, &bits,
+  has_bit = gst_rtp_buffer_get_extension_data (rtp, &bits,
       (gpointer) & pdata, &wordlen);
 
   if (has_bit) {
@@ -1755,10 +1479,10 @@ gst_rtp_buffer_add_extension_twobytes_header (GstBuffer * buffer,
 
     nextext = pdata + offset;
 
-    offset = nextext - GST_BUFFER_DATA (buffer);
+    offset = nextext - rtp->data;
 
     /* Don't add extra header if there isn't enough space */
-    if (GST_BUFFER_SIZE (buffer) < offset + size + 2)
+    if (rtp->size < offset + size + 2)
       return FALSE;
 
     nextext[0] = id;
@@ -1773,15 +1497,15 @@ gst_rtp_buffer_add_extension_twobytes_header (GstBuffer * buffer,
       wordlen = extlen / 4;
     }
 
-    gst_rtp_buffer_set_extension_data (buffer, (0x100 << 4) | (appbits & 0x0F),
+    gst_rtp_buffer_set_extension_data (rtp, (0x100 << 4) | (appbits & 0x0F),
         wordlen);
   } else {
     wordlen = (size + 2) / 4 + (((size + 2) % 4) ? 1 : 0);
 
-    gst_rtp_buffer_set_extension_data (buffer, (0x100 << 4) | (appbits & 0x0F),
+    gst_rtp_buffer_set_extension_data (rtp, (0x100 << 4) | (appbits & 0x0F),
         wordlen);
 
-    gst_rtp_buffer_get_extension_data (buffer, &bits,
+    gst_rtp_buffer_get_extension_data (rtp, &bits,
         (gpointer) & pdata, &wordlen);
 
     pdata[0] = id;
@@ -1793,267 +1517,3 @@ gst_rtp_buffer_add_extension_twobytes_header (GstBuffer * buffer,
 
   return TRUE;
 }
-
-/**
- * gst_rtp_buffer_list_get_extension_onebyte_header:
- * @bufferlist: the bufferlist
- * @group_idx: The index of the group in the #GstBufferList
- * @id: The ID of the header extension to be read (between 1 and 14).
- * @nth: Read the nth extension packet with the requested ID
- * @data: location for data
- * @size: the size of the data in bytes
- *
- * Parses RFC 5285 style header extensions with a one byte header. It will
- * return the nth extension with the requested id.
- *
- * Returns: TRUE if @buffer had the requested header extension
- *
- * Since: 0.10.31
- */
-
-gboolean
-gst_rtp_buffer_list_get_extension_onebyte_header (GstBufferList * bufferlist,
-    guint group_idx, guint8 id, guint nth, gpointer * data, guint * size)
-{
-  GstBuffer *buffer;
-
-  buffer = gst_buffer_list_get (bufferlist, group_idx, 0);
-
-  if (!buffer)
-    return FALSE;
-
-  return gst_rtp_buffer_get_extension_onebyte_header (buffer, id, nth, data,
-      size);
-}
-
-
-/**
- * gst_rtp_buffer_list_get_extension_twobytes_header:
- * @bufferlist: the bufferlist
- * @group_idx: The index of the group in the #GstBufferList
- * @appbits: Application specific bits
- * @id: The ID of the header extension to be read (between 1 and 14).
- * @nth: Read the nth extension packet with the requested ID
- * @data: location for data
- * @size: the size of the data in bytes
- *
- * Parses RFC 5285 style header extensions with a two bytes header. It will
- * return the nth extension with the requested id.
- *
- * Returns: TRUE if @buffer had the requested header extension
- *
- * Since: 0.10.31
- */
-
-gboolean
-gst_rtp_buffer_list_get_extension_twobytes_header (GstBufferList * bufferlist,
-    guint group_idx, guint8 * appbits, guint8 id, guint nth,
-    gpointer * data, guint * size)
-{
-  GstBuffer *buffer;
-
-  buffer = gst_buffer_list_get (bufferlist, group_idx, 0);
-
-  if (!buffer)
-    return FALSE;
-
-  return gst_rtp_buffer_get_extension_twobytes_header (buffer, appbits, id,
-      nth, data, size);
-}
-
-/**
- * gst_rtp_buffer_list_add_extension_onebyte_header:
- * @it: a #GstBufferListIterator pointing right after the #GstBuffer where
- * the header extension should be added
- * @id: The ID of the header extension (between 1 and 14).
- * @data: location for data
- * @size: the size of the data in bytes
- *
- * Adds a RFC 5285 header extension with a one byte header to the end of the
- * RTP header. If there is already a RFC 5285 header extension with a one byte
- * header, the new extension will be appended.
- * It will not work if there is already a header extension that does not follow
- * the mecanism described in RFC 5285 or if there is a header extension with
- * a two bytes header as described in RFC 5285. In that case, use
- * gst_rtp_buffer_list_add_extension_twobytes_header()
- *
- * This function will not modify the data section of the RTP buffer, only
- * the header.
- *
- * Returns: %TRUE if header extension could be added
- *
- * Since: 0.10.31
- */
-
-gboolean
-gst_rtp_buffer_list_add_extension_onebyte_header (GstBufferListIterator * it,
-    guint8 id, gpointer data, guint size)
-{
-  GstBuffer *buffer;
-  guint16 bits;
-  guint8 *pdata;
-  guint wordlen;
-  gboolean retval;
-  guint endoffset = 0;
-
-  g_return_val_if_fail (gst_buffer_list_iterator_n_buffers (it) == 1, FALSE);
-  g_return_val_if_fail (id > 0 && id < 15, FALSE);
-  g_return_val_if_fail (size >= 1 && size <= 16, FALSE);
-
-  buffer = gst_buffer_list_iterator_steal (it);
-
-  if (GST_RTP_HEADER_EXTENSION (GST_BUFFER_DATA (buffer))) {
-    gst_rtp_buffer_get_extension_data (buffer, &bits, (gpointer) & pdata,
-        &wordlen);
-
-    if (bits != 0xBEDE)
-      return FALSE;
-
-    endoffset = get_onebyte_header_end_offset (pdata, wordlen);
-    if (endoffset == 0)
-      return FALSE;
-    endoffset += pdata - GST_BUFFER_DATA (buffer);
-  } else {
-    endoffset = GST_BUFFER_SIZE (buffer) + 4;
-  }
-
-  if (endoffset + size + 1 > GST_BUFFER_SIZE (buffer)) {
-    guint newsize;
-    GstBuffer *newbuffer;
-
-    newsize = endoffset + size + 1;
-    if (newsize % 4)
-      newsize += 4 - (newsize % 4);
-    newbuffer = gst_buffer_new_and_alloc (newsize);
-    memcpy (GST_BUFFER_DATA (newbuffer), GST_BUFFER_DATA (buffer),
-        GST_BUFFER_SIZE (buffer));
-    gst_buffer_copy_metadata (newbuffer, buffer, GST_BUFFER_COPY_ALL);
-    gst_buffer_unref (buffer);
-    buffer = newbuffer;
-  } else {
-    buffer = gst_buffer_make_writable (buffer);
-  }
-
-  retval = gst_rtp_buffer_add_extension_onebyte_header (buffer, id, data, size);
-
-  gst_buffer_list_iterator_take (it, buffer);
-
-  return retval;
-}
-
-/**
- * gst_rtp_buffer_list_add_extension_twobytes_header:
- * @it: a #GstBufferListIterator pointing right after the #GstBuffer where
- * the header extension should be added
- * @appbits: Application specific bits
- * @id: The ID of the header extension
- * @data: location for data
- * @size: the size of the data in bytes
- *
- * Adds a RFC 5285 header extension with a two bytes header to the end of the
- * RTP header. If there is already a RFC 5285 header extension with a two bytes
- * header, the new extension will be appended.
- * It will not work if there is already a header extension that does not follow
- * the mecanism described in RFC 5285 or if there is a header extension with
- * a one byte header as described in RFC 5285. In that case, use
- * gst_rtp_buffer_add_extension_onebyte_header()
- *
- * This function will not modify the data section of the RTP buffer, only
- * the header.
- *
- * Returns: %TRUE if header extension could be added
- *
- * Since: 0.10.31
- */
-
-gboolean
-gst_rtp_buffer_list_add_extension_twobytes_header (GstBufferListIterator * it,
-    guint8 appbits, guint8 id, gpointer data, guint size)
-{
-  GstBuffer *buffer;
-  guint16 bits;
-  guint8 *pdata;
-  guint wordlen;
-  gboolean retval;
-  guint endoffset;
-
-  g_return_val_if_fail ((appbits & 0xF0) == 0, FALSE);
-  g_return_val_if_fail (size < 256, FALSE);
-  g_return_val_if_fail (gst_buffer_list_iterator_n_buffers (it) == 1, FALSE);
-
-  buffer = gst_buffer_list_iterator_steal (it);
-
-  if (GST_RTP_HEADER_EXTENSION (GST_BUFFER_DATA (buffer))) {
-    gst_rtp_buffer_get_extension_data (buffer, &bits, (gpointer) & pdata,
-        &wordlen);
-
-    if (bits != ((0x100 << 4) | (appbits & 0x0f)))
-      return FALSE;
-
-    endoffset = get_twobytes_header_end_offset (pdata, wordlen);
-    if (endoffset == 0)
-      return FALSE;
-    endoffset += pdata - GST_BUFFER_DATA (buffer);
-  } else {
-    endoffset = GST_BUFFER_SIZE (buffer) + 4;
-  }
-
-  if (endoffset + size + 2 > GST_BUFFER_SIZE (buffer)) {
-    guint newsize;
-    GstBuffer *newbuffer;
-
-    newsize = endoffset + size + 2;
-    if (newsize % 4)
-      newsize += 4 - newsize % 4;
-    newbuffer = gst_buffer_new_and_alloc (newsize);
-    memcpy (GST_BUFFER_DATA (newbuffer), GST_BUFFER_DATA (buffer),
-        GST_BUFFER_SIZE (buffer));
-    gst_buffer_copy_metadata (newbuffer, buffer, GST_BUFFER_COPY_ALL);
-    gst_buffer_unref (buffer);
-    buffer = newbuffer;
-  } else {
-    buffer = gst_buffer_make_writable (buffer);
-  }
-
-  retval = gst_rtp_buffer_add_extension_twobytes_header (buffer, appbits, id,
-      data, size);
-
-  gst_buffer_list_iterator_take (it, buffer);
-
-  return retval;
-}
-
-/**
- * gst_rtp_buffer_list_from_buffer:
- * @buffer: a #GstBuffer containing a RTP packet
- *
- * Splits a #GstBuffer into a #GstBufferList containing separate
- * buffers for the header and data sections.
- *
- * Returns: a #GstBufferList
- */
-
-GstBufferList *
-gst_rtp_buffer_list_from_buffer (GstBuffer * buffer)
-{
-  GstBufferList *bufferlist;
-  GstBuffer *sub;
-  GstBufferListIterator *it;
-  guint8 *payload;
-
-  bufferlist = gst_buffer_list_new ();
-
-  it = gst_buffer_list_iterate (bufferlist);
-  gst_buffer_list_iterator_add_group (it);
-
-  payload = gst_rtp_buffer_get_payload (buffer);
-  sub = gst_buffer_create_sub (buffer, 0, payload - GST_BUFFER_DATA (buffer));
-  gst_buffer_list_iterator_add (it, sub);
-
-  sub = gst_rtp_buffer_get_payload_buffer (buffer);
-  gst_buffer_list_iterator_add (it, sub);
-
-  gst_buffer_list_iterator_free (it);
-
-  return bufferlist;
-}
index c82fd71..b40e714 100644 (file)
@@ -36,129 +36,115 @@ G_BEGIN_DECLS
  */
 #define GST_RTP_VERSION 2
 
+
+typedef struct _GstRTPBuffer GstRTPBuffer;
+
+/**
+ * GstRTPBuffer:
+ * @buffer: pointer to RTP buffer
+ *
+ * Data structure that points to an RTP packet.
+ * The size of the structure is made public to allow stack allocations.
+ */
+struct _GstRTPBuffer
+{
+  GstBuffer   *buffer;
+  GstMapFlags  flags;
+  guint8      *data;
+  gsize        size;
+  gsize        maxsize;
+};
+
 /* creating buffers */
-void            gst_rtp_buffer_allocate_data         (GstBuffer *buffer, guint payload_len, 
+void            gst_rtp_buffer_allocate_data         (GstBuffer *buffer, guint payload_len,
                                                       guint8 pad_len, guint8 csrc_count);
 
-GstBuffer*      gst_rtp_buffer_new_take_data         (gpointer data, guint len);
-GstBuffer*      gst_rtp_buffer_new_copy_data         (gpointer data, guint len);
+GstBuffer*      gst_rtp_buffer_new_take_data         (gpointer data, gsize len);
+GstBuffer*      gst_rtp_buffer_new_copy_data         (gpointer data, gsize len);
 GstBuffer*      gst_rtp_buffer_new_allocate          (guint payload_len, guint8 pad_len, guint8 csrc_count);
 GstBuffer*      gst_rtp_buffer_new_allocate_len      (guint packet_len, guint8 pad_len, guint8 csrc_count);
 
-GstBufferList*  gst_rtp_buffer_list_from_buffer      (GstBuffer * buffer);
-
-
 guint           gst_rtp_buffer_calc_header_len       (guint8 csrc_count);
 guint           gst_rtp_buffer_calc_packet_len       (guint payload_len, guint8 pad_len, guint8 csrc_count);
 guint           gst_rtp_buffer_calc_payload_len      (guint packet_len, guint8 pad_len, guint8 csrc_count);
 
-gboolean        gst_rtp_buffer_validate_data         (guint8 *data, guint len);
+gboolean        gst_rtp_buffer_validate_data         (guint8 *data, gsize len);
 gboolean        gst_rtp_buffer_validate              (GstBuffer *buffer);
-gboolean        gst_rtp_buffer_list_validate         (GstBufferList *list);
 
-void            gst_rtp_buffer_set_packet_len        (GstBuffer *buffer, guint len);
-guint           gst_rtp_buffer_get_packet_len        (GstBuffer *buffer);
 
-guint           gst_rtp_buffer_get_header_len        (GstBuffer *buffer);
+gboolean        gst_rtp_buffer_map                   (GstBuffer *buffer, GstMapFlags flags, GstRTPBuffer *rtp);
+gboolean        gst_rtp_buffer_unmap                 (GstRTPBuffer *rtp);
+
+void            gst_rtp_buffer_set_packet_len        (GstRTPBuffer *rtp, guint len);
+guint           gst_rtp_buffer_get_packet_len        (GstRTPBuffer *rtp);
+
+guint           gst_rtp_buffer_get_header_len        (GstRTPBuffer *rtp);
 
-guint8          gst_rtp_buffer_get_version           (GstBuffer *buffer);
-void            gst_rtp_buffer_set_version           (GstBuffer *buffer, guint8 version);
+guint8          gst_rtp_buffer_get_version           (GstRTPBuffer *rtp);
+void            gst_rtp_buffer_set_version           (GstRTPBuffer *rtp, guint8 version);
 
-gboolean        gst_rtp_buffer_get_padding           (GstBuffer *buffer);
-void            gst_rtp_buffer_set_padding           (GstBuffer *buffer, gboolean padding);
-void            gst_rtp_buffer_pad_to                (GstBuffer *buffer, guint len);
+gboolean        gst_rtp_buffer_get_padding           (GstRTPBuffer *rtp);
+void            gst_rtp_buffer_set_padding           (GstRTPBuffer *rtp, gboolean padding);
+void            gst_rtp_buffer_pad_to                (GstRTPBuffer *rtp, guint len);
 
-gboolean        gst_rtp_buffer_get_extension         (GstBuffer *buffer);
-void            gst_rtp_buffer_set_extension         (GstBuffer *buffer, gboolean extension);
-gboolean        gst_rtp_buffer_get_extension_data    (GstBuffer *buffer, guint16 *bits,
+gboolean        gst_rtp_buffer_get_extension         (GstRTPBuffer *rtp);
+void            gst_rtp_buffer_set_extension         (GstRTPBuffer *rtp, gboolean extension);
+gboolean        gst_rtp_buffer_get_extension_data    (GstRTPBuffer *rtp, guint16 *bits,
                                                       gpointer *data, guint *wordlen);
-gboolean        gst_rtp_buffer_set_extension_data    (GstBuffer *buffer, guint16 bits, guint16 length);
+gboolean        gst_rtp_buffer_set_extension_data    (GstRTPBuffer *rtp, guint16 bits, guint16 length);
 
-guint32         gst_rtp_buffer_get_ssrc              (GstBuffer *buffer);
-guint32         gst_rtp_buffer_list_get_ssrc         (GstBufferList *list);
-void            gst_rtp_buffer_set_ssrc              (GstBuffer *buffer, guint32 ssrc);
-void            gst_rtp_buffer_list_set_ssrc         (GstBufferList *list, guint32 ssrc);
+guint32         gst_rtp_buffer_get_ssrc              (GstRTPBuffer *rtp);
+void            gst_rtp_buffer_set_ssrc              (GstRTPBuffer *rtp, guint32 ssrc);
 
-guint8          gst_rtp_buffer_get_csrc_count        (GstBuffer *buffer);
-guint32         gst_rtp_buffer_get_csrc              (GstBuffer *buffer, guint8 idx);
-void            gst_rtp_buffer_set_csrc              (GstBuffer *buffer, guint8 idx, guint32 csrc);
+guint8          gst_rtp_buffer_get_csrc_count        (GstRTPBuffer *rtp);
+guint32         gst_rtp_buffer_get_csrc              (GstRTPBuffer *rtp, guint8 idx);
+void            gst_rtp_buffer_set_csrc              (GstRTPBuffer *rtp, guint8 idx, guint32 csrc);
 
-gboolean        gst_rtp_buffer_get_marker            (GstBuffer *buffer);
-void            gst_rtp_buffer_set_marker            (GstBuffer *buffer, gboolean marker);
+gboolean        gst_rtp_buffer_get_marker            (GstRTPBuffer *rtp);
+void            gst_rtp_buffer_set_marker            (GstRTPBuffer *rtp, gboolean marker);
 
-guint8          gst_rtp_buffer_get_payload_type      (GstBuffer *buffer);
-guint8          gst_rtp_buffer_list_get_payload_type (GstBufferList *list);
-void            gst_rtp_buffer_set_payload_type      (GstBuffer *buffer, guint8 payload_type);
-void            gst_rtp_buffer_list_set_payload_type (GstBufferList *list, guint8 payload_type);
+guint8          gst_rtp_buffer_get_payload_type      (GstRTPBuffer *rtp);
+void            gst_rtp_buffer_set_payload_type      (GstRTPBuffer *rtp, guint8 payload_type);
 
-guint16         gst_rtp_buffer_get_seq               (GstBuffer *buffer);
-guint16         gst_rtp_buffer_list_get_seq          (GstBufferList *list);
-void            gst_rtp_buffer_set_seq               (GstBuffer *buffer, guint16 seq);
-guint16         gst_rtp_buffer_list_set_seq          (GstBufferList *list, guint16 seq);
+guint16         gst_rtp_buffer_get_seq               (GstRTPBuffer *rtp);
+void            gst_rtp_buffer_set_seq               (GstRTPBuffer *rtp, guint16 seq);
 
-guint32         gst_rtp_buffer_get_timestamp         (GstBuffer *buffer);
-guint32         gst_rtp_buffer_list_get_timestamp    (GstBufferList *list);
-void            gst_rtp_buffer_set_timestamp         (GstBuffer *buffer, guint32 timestamp);
-void            gst_rtp_buffer_list_set_timestamp    (GstBufferList *list, guint32 timestamp);
+guint32         gst_rtp_buffer_get_timestamp         (GstRTPBuffer *rtp);
+void            gst_rtp_buffer_set_timestamp         (GstRTPBuffer *rtp, guint32 timestamp);
 
-GstBuffer*     gst_rtp_buffer_get_payload_buffer    (GstBuffer *buffer);
-GstBuffer*     gst_rtp_buffer_get_payload_subbuffer (GstBuffer *buffer, guint offset, guint len);
+GstBuffer*     gst_rtp_buffer_get_payload_buffer    (GstRTPBuffer *rtp);
+GstBuffer*     gst_rtp_buffer_get_payload_subbuffer (GstRTPBuffer *rtp, guint offset, guint len);
 
-guint           gst_rtp_buffer_get_payload_len       (GstBuffer *buffer);
-guint           gst_rtp_buffer_list_get_payload_len  (GstBufferList *list);
-gpointer        gst_rtp_buffer_get_payload           (GstBuffer *buffer);
+guint           gst_rtp_buffer_get_payload_len       (GstRTPBuffer *rtp);
+gpointer        gst_rtp_buffer_get_payload           (GstRTPBuffer *rtp);
 
 /* some helpers */
 guint32         gst_rtp_buffer_default_clock_rate    (guint8 payload_type);
 gint            gst_rtp_buffer_compare_seqnum        (guint16 seqnum1, guint16 seqnum2);
 guint64         gst_rtp_buffer_ext_timestamp         (guint64 *exttimestamp, guint32 timestamp);
 
-gboolean        gst_rtp_buffer_get_extension_onebyte_header (GstBuffer * buffer,
-                                                             guint8 id,
-                                                             guint nth,
-                                                             gpointer * data,
-                                                             guint * size);
-gboolean        gst_rtp_buffer_get_extension_twobytes_header (GstBuffer * buffer,
+gboolean        gst_rtp_buffer_get_extension_onebyte_header  (GstRTPBuffer *rtp,
+                                                              guint8 id,
+                                                              guint nth,
+                                                              gpointer * data,
+                                                              guint * size);
+gboolean        gst_rtp_buffer_get_extension_twobytes_header (GstRTPBuffer *rtp,
                                                               guint8 * appbits,
                                                               guint8 id,
                                                               guint nth,
                                                               gpointer * data,
                                                               guint * size);
 
-gboolean       gst_rtp_buffer_add_extension_onebyte_header (GstBuffer * buffer,
-                                                            guint8 id,
-                                                            gpointer data,
-                                                            guint size);
-gboolean       gst_rtp_buffer_add_extension_twobytes_header (GstBuffer * buffer,
+gboolean       gst_rtp_buffer_add_extension_onebyte_header  (GstRTPBuffer *rtp,
+                                                             guint8 id,
+                                                             gpointer data,
+                                                             guint size);
+gboolean       gst_rtp_buffer_add_extension_twobytes_header (GstRTPBuffer *rtp,
                                                              guint8 appbits,
                                                              guint8 id,
                                                              gpointer data,
                                                              guint size);
 
-gboolean       gst_rtp_buffer_list_get_extension_onebyte_header (GstBufferList * bufferlist,
-                                                                 guint group_idx,
-                                                                 guint8 id,
-                                                                 guint nth,
-                                                                 gpointer * data,
-                                                                 guint * size);
-gboolean       gst_rtp_buffer_list_get_extension_twobytes_header (GstBufferList * bufferlist,
-                                                                  guint group_idx,
-                                                                  guint8 * appbits,
-                                                                  guint8 id,
-                                                                  guint nth,
-                                                                  gpointer * data,
-                                                                  guint * size);
-
-gboolean       gst_rtp_buffer_list_add_extension_onebyte_header (GstBufferListIterator * it,
-                                                                  guint8 id,
-                                                                  gpointer data,
-                                                                  guint size);
-gboolean       gst_rtp_buffer_list_add_extension_twobytes_header (GstBufferListIterator * it,
-                                                                  guint8 appbits,
-                                                                  guint8 id,
-                                                                  gpointer data,
-                                                                  guint size);
-
 
 G_END_DECLS
 
index c97901c..7dc9ac6 100644 (file)
@@ -231,7 +231,7 @@ struct _GstExifWriter
 struct _GstExifReader
 {
   GstTagList *taglist;
-  const GstBuffer *buffer;
+  GstBuffer *buffer;
   guint32 base_offset;
   gint byte_order;
 
@@ -454,7 +454,7 @@ static const GstExifTagMatch tag_map_gps[] = {
 /* GstExifReader functions */
 static void
 gst_exif_reader_init (GstExifReader * reader, gint byte_order,
-    const GstBuffer * buf, guint32 base_offset)
+    GstBuffer * buf, guint32 base_offset)
 {
   ensure_exif_tags ();
 
@@ -856,9 +856,10 @@ write_exif_undefined_tag_from_taglist (GstExifWriter * writer,
     const GstTagList * taglist, const GstExifTagMatch * exiftag)
 {
   const GValue *value;
-  const guint8 *data = NULL;
-  gint size = 0;
+  guint8 *data = NULL;
+  gsize size = 0;
   gint tag_size = gst_tag_list_get_tag_size (taglist, exiftag->gst_tag);
+  GstBuffer *buf = NULL;
 
   if (tag_size != 1) {
     GST_WARNING ("Only the first item in the taglist will be serialized");
@@ -875,10 +876,8 @@ write_exif_undefined_tag_from_taglist (GstExifWriter * writer,
       break;
     default:
       if (G_VALUE_TYPE (value) == GST_TYPE_BUFFER) {
-        GstBuffer *buf = gst_value_get_buffer (value);
-
-        data = GST_BUFFER_DATA (buf);
-        size = GST_BUFFER_SIZE (buf);
+        buf = gst_value_get_buffer (value);
+        data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
       } else {
         GST_WARNING ("Conversion from %s to raw data not supported",
             G_VALUE_TYPE_NAME (value));
@@ -886,10 +885,11 @@ write_exif_undefined_tag_from_taglist (GstExifWriter * writer,
       break;
   }
 
-  if (size == 0)
-    return;
+  if (size > 0)
+    write_exif_undefined_tag (writer, exiftag->exif_tag, data, size);
 
-  write_exif_undefined_tag (writer, exiftag->exif_tag, data, size);
+  if (buf)
+    gst_buffer_unmap (buf, data, size);
 }
 
 static void
@@ -1167,6 +1167,9 @@ parse_exif_ascii_tag (GstExifReader * reader, const GstExifTagMatch * tag,
   guint32 real_offset;
 
   if (count > 4) {
+    guint8 *data;
+    gsize size;
+
     if (offset < reader->base_offset) {
       GST_WARNING ("Offset is smaller (%u) than base offset (%u)", offset,
           reader->base_offset);
@@ -1174,15 +1177,17 @@ parse_exif_ascii_tag (GstExifReader * reader, const GstExifTagMatch * tag,
     }
 
     real_offset = offset - reader->base_offset;
-    if (real_offset >= GST_BUFFER_SIZE (reader->buffer)) {
+
+    data = gst_buffer_map (reader->buffer, &size, NULL, GST_MAP_READ);
+    if (real_offset >= size) {
       GST_WARNING ("Invalid offset %u for buffer of size %u, not adding tag %s",
-          real_offset, GST_BUFFER_SIZE (reader->buffer), tag->gst_tag);
+          real_offset, size, tag->gst_tag);
+      gst_buffer_unmap (reader->buffer, data, size);
       return;
     }
 
-    str =
-        g_strndup ((gchar *) (GST_BUFFER_DATA (reader->buffer) + real_offset),
-        count);
+    str = g_strndup ((gchar *) (data + real_offset), count);
+    gst_buffer_unmap (reader->buffer, data, size);
   } else {
     str = g_strndup ((gchar *) offset_as_data, count);
   }
@@ -1243,6 +1248,9 @@ parse_exif_undefined_tag (GstExifReader * reader, const GstExifTagMatch * tag,
   guint32 real_offset;
 
   if (count > 4) {
+    guint8 *bdata;
+    gsize bsize;
+
     if (offset < reader->base_offset) {
       GST_WARNING ("Offset is smaller (%u) than base offset (%u)", offset,
           reader->base_offset);
@@ -1250,16 +1258,22 @@ parse_exif_undefined_tag (GstExifReader * reader, const GstExifTagMatch * tag,
     }
 
     real_offset = offset - reader->base_offset;
-    if (real_offset >= GST_BUFFER_SIZE (reader->buffer)) {
+
+    bdata = gst_buffer_map (reader->buffer, &bsize, NULL, GST_MAP_READ);
+
+    if (real_offset >= bsize) {
       GST_WARNING ("Invalid offset %u for buffer of size %u, not adding tag %s",
-          real_offset, GST_BUFFER_SIZE (reader->buffer), tag->gst_tag);
+          real_offset, bsize, tag->gst_tag);
+      gst_buffer_unmap (reader->buffer, bdata, bsize);
       return;
     }
 
     /* +1 because it could be a string without the \0 */
     data = malloc (sizeof (guint8) * count + 1);
-    memcpy (data, GST_BUFFER_DATA (reader->buffer) + real_offset, count);
+    memcpy (data, bdata + real_offset, count);
     data[count] = 0;
+
+    gst_buffer_unmap (reader->buffer, bdata, bsize);
   } else {
     data = malloc (sizeof (guint8) * count + 1);
     memcpy (data, (guint8 *) offset_as_data, count);
@@ -1271,9 +1285,8 @@ parse_exif_undefined_tag (GstExifReader * reader, const GstExifTagMatch * tag,
     GstBuffer *buf;
 
     buf = gst_buffer_new ();
-    GST_BUFFER_DATA (buf) = data;
-    GST_BUFFER_MALLOCDATA (buf) = data;
-    GST_BUFFER_SIZE (buf) = count;
+    gst_buffer_take_memory (buf,
+        gst_memory_new_wrapped (0, data, g_free, count, 0, count));
     data = NULL;
 
     gst_tag_list_add (reader->taglist, GST_TAG_MERGE_APPEND, tag->gst_tag,
@@ -1299,6 +1312,8 @@ exif_reader_read_rational_tag (GstExifReader * exif_reader,
   guint32 real_offset;
   gint32 frac_n = 0;
   gint32 frac_d = 0;
+  guint8 *data;
+  gsize size;
 
   if (count > 1) {
     GST_WARNING ("Rationals with multiple entries are not supported");
@@ -1310,13 +1325,15 @@ exif_reader_read_rational_tag (GstExifReader * exif_reader,
   }
 
   real_offset = offset - exif_reader->base_offset;
-  if (real_offset >= GST_BUFFER_SIZE (exif_reader->buffer)) {
-    GST_WARNING ("Invalid offset %u for buffer of size %u",
-        real_offset, GST_BUFFER_SIZE (exif_reader->buffer));
-    return FALSE;
+
+  data = gst_buffer_map (exif_reader->buffer, &size, NULL, GST_MAP_READ);
+
+  if (real_offset >= size) {
+    GST_WARNING ("Invalid offset %u for buffer of size %u", real_offset, size);
+    goto reader_fail;
   }
 
-  gst_byte_reader_init_from_buffer (&data_reader, exif_reader->buffer);
+  gst_byte_reader_init (&data_reader, data, size);
   if (!gst_byte_reader_set_pos (&data_reader, real_offset))
     goto reader_fail;
 
@@ -1350,10 +1367,13 @@ exif_reader_read_rational_tag (GstExifReader * exif_reader,
   if (_frac_d)
     *_frac_d = frac_d;
 
+  gst_buffer_unmap (exif_reader->buffer, data, size);
+
   return TRUE;
 
 reader_fail:
   GST_WARNING ("Failed to read from byte reader. (Buffer too short?)");
+  gst_buffer_unmap (exif_reader->buffer, data, size);
   return FALSE;
 }
 
@@ -1453,12 +1473,17 @@ write_exif_ifd (const GstTagList * taglist, gboolean byte_order,
       }
 
       if (inner_ifd) {
+        guint8 *data;
+        gsize size;
+
         GST_DEBUG ("Adding inner ifd: %x", tag_map[i].exif_tag);
         gst_exif_writer_write_tag_header (&writer, tag_map[i].exif_tag,
             EXIF_TYPE_LONG, 1,
             gst_byte_writer_get_size (&writer.datawriter), FALSE);
-        gst_byte_writer_put_data (&writer.datawriter,
-            GST_BUFFER_DATA (inner_ifd), GST_BUFFER_SIZE (inner_ifd));
+
+        data = gst_buffer_map (inner_ifd, &size, NULL, GST_MAP_READ);
+        gst_byte_writer_put_data (&writer.datawriter, data, size);
+        gst_buffer_unmap (inner_ifd, data, size);
         gst_buffer_unref (inner_ifd);
       }
       continue;
@@ -1528,15 +1553,17 @@ parse_exif_ifd (GstExifReader * exif_reader, gint buf_offset,
   GstByteReader reader;
   guint16 entries = 0;
   guint16 i;
+  guint8 *data;
+  gsize size;
 
   g_return_val_if_fail (exif_reader->byte_order == G_LITTLE_ENDIAN
       || exif_reader->byte_order == G_BIG_ENDIAN, FALSE);
 
-  gst_byte_reader_init_from_buffer (&reader, exif_reader->buffer);
-  if (!gst_byte_reader_set_pos (&reader, buf_offset)) {
-    GST_WARNING ("Buffer offset invalid when parsing exif ifd");
-    return FALSE;
-  }
+  data = gst_buffer_map (exif_reader->buffer, &size, NULL, GST_MAP_READ);
+
+  gst_byte_reader_init (&reader, data, size);
+  if (!gst_byte_reader_set_pos (&reader, buf_offset))
+    goto invalid_offset;
 
   /* read the IFD entries number */
   if (exif_reader->byte_order == G_LITTLE_ENDIAN) {
@@ -1646,12 +1673,20 @@ parse_exif_ifd (GstExifReader * exif_reader, gint buf_offset,
       }
     }
   }
+  gst_buffer_unmap (exif_reader->buffer, data, size);
 
   return TRUE;
 
+invalid_offset:
+  {
+    GST_WARNING ("Buffer offset invalid when parsing exif ifd");
+    gst_buffer_unmap (exif_reader->buffer, data, size);
+    return FALSE;
+  }
 read_error:
   {
     GST_WARNING ("Failed to parse the exif ifd");
+    gst_buffer_unmap (exif_reader->buffer, data, size);
     return FALSE;
   }
 }
@@ -1692,14 +1727,18 @@ gst_tag_list_to_exif_buffer_with_tiff_header (const GstTagList * taglist)
 {
   GstBuffer *ifd;
   GstByteWriter writer;
-  guint size;
+  gsize size;
+  guint8 *data;
 
   ifd = gst_tag_list_to_exif_buffer (taglist, G_BYTE_ORDER, 8);
   if (ifd == NULL) {
     GST_WARNING ("Failed to create exif buffer");
     return NULL;
   }
-  size = TIFF_HEADER_SIZE + GST_BUFFER_SIZE (ifd);
+
+  data = gst_buffer_map (ifd, &size, NULL, GST_MAP_READ);
+
+  size += TIFF_HEADER_SIZE;
 
   /* TODO what is the correct endianness here? */
   gst_byte_writer_init_with_size (&writer, size, FALSE);
@@ -1713,17 +1752,19 @@ gst_tag_list_to_exif_buffer_with_tiff_header (const GstTagList * taglist)
     gst_byte_writer_put_uint16_be (&writer, 42);
     gst_byte_writer_put_uint32_be (&writer, 8);
   }
-  if (!gst_byte_writer_put_data (&writer, GST_BUFFER_DATA (ifd),
-          GST_BUFFER_SIZE (ifd))) {
+  if (!gst_byte_writer_put_data (&writer, data, size)) {
     GST_WARNING ("Byte writer size mismatch");
     /* reaching here is a programming error because we should have a buffer
      * large enough */
     g_assert_not_reached ();
+    gst_buffer_unmap (ifd, data, size);
     gst_buffer_unref (ifd);
     gst_byte_writer_reset (&writer);
     return NULL;
   }
+  gst_buffer_unmap (ifd, data, size);
   gst_buffer_unref (ifd);
+
   return gst_byte_writer_reset_and_get_buffer (&writer);
 }
 
@@ -1743,7 +1784,7 @@ gst_tag_list_to_exif_buffer_with_tiff_header (const GstTagList * taglist)
  * Since: 0.10.30
  */
 GstTagList *
-gst_tag_list_from_exif_buffer (const GstBuffer * buffer, gint byte_order,
+gst_tag_list_from_exif_buffer (GstBuffer * buffer, gint byte_order,
     guint32 base_offset)
 {
   GstExifReader reader;
@@ -1776,7 +1817,7 @@ read_error:
  * Since: 0.10.30
  */
 GstTagList *
-gst_tag_list_from_exif_buffer_with_tiff_header (const GstBuffer * buffer)
+gst_tag_list_from_exif_buffer_with_tiff_header (GstBuffer * buffer)
 {
   GstByteReader reader;
   guint16 fortytwo = 42;
@@ -1784,11 +1825,14 @@ gst_tag_list_from_exif_buffer_with_tiff_header (const GstBuffer * buffer)
   guint32 offset;
   GstTagList *taglist = NULL;
   GstBuffer *subbuffer;
+  guint8 *data, *sdata;
+  gsize size, ssize;
+
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
 
-  GST_LOG ("Parsing exif tags with tiff header of size %u",
-      GST_BUFFER_SIZE (buffer));
+  GST_LOG ("Parsing exif tags with tiff header of size %u", size);
 
-  gst_byte_reader_init_from_buffer (&reader, buffer);
+  gst_byte_reader_init (&reader, data, size);
 
   GST_LOG ("Parsing the tiff header");
   if (!gst_byte_reader_get_uint16_be (&reader, &endianness)) {
@@ -1803,32 +1847,42 @@ gst_tag_list_from_exif_buffer_with_tiff_header (const GstBuffer * buffer)
     if (!gst_byte_reader_get_uint16_be (&reader, &fortytwo) ||
         !gst_byte_reader_get_uint32_be (&reader, &offset))
       goto byte_reader_fail;
-  } else {
-    GST_WARNING ("Invalid endianness number %u", endianness);
-    return NULL;
-  }
+  } else
+    goto invalid_endianness;
 
-  if (fortytwo != 42) {
-    GST_WARNING ("Invalid magic number %u, should be 42", fortytwo);
-    return NULL;
-  }
+  if (fortytwo != 42)
+    goto invalid_magic;
 
-  subbuffer = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buffer) -
-      (TIFF_HEADER_SIZE - 2));
-  memcpy (GST_BUFFER_DATA (subbuffer),
-      GST_BUFFER_DATA (buffer) + TIFF_HEADER_SIZE,
-      GST_BUFFER_SIZE (buffer) - TIFF_HEADER_SIZE);
+  subbuffer = gst_buffer_new_and_alloc (size - (TIFF_HEADER_SIZE - 2));
+
+  sdata = gst_buffer_map (subbuffer, &ssize, NULL, GST_MAP_WRITE);
+  memcpy (sdata, data + TIFF_HEADER_SIZE, size - TIFF_HEADER_SIZE);
+  gst_buffer_unmap (subbuffer, sdata, ssize);
 
   taglist = gst_tag_list_from_exif_buffer (subbuffer,
       endianness == TIFF_LITTLE_ENDIAN ? G_LITTLE_ENDIAN : G_BIG_ENDIAN, 8);
 
   gst_buffer_unref (subbuffer);
+
+done:
+  gst_buffer_unmap (buffer, data, size);
+
   return taglist;
 
 byte_reader_fail:
   {
     GST_WARNING ("Failed to read values from buffer");
-    return NULL;
+    goto done;
+  }
+invalid_endianness:
+  {
+    GST_WARNING ("Invalid endianness number %u", endianness);
+    goto done;
+  }
+invalid_magic:
+  {
+    GST_WARNING ("Invalid magic number %u, should be 42", fortytwo);
+    goto done;
   }
 }
 
@@ -1928,6 +1982,8 @@ deserialize_geo_coordinate (GstExifReader * exif_reader,
   gdouble degrees;
   gdouble minutes;
   gdouble seconds;
+  guint8 *data = NULL;
+  gsize size = 0;
 
   GST_LOG ("Starting to parse %s tag in exif 0x%x", exiftag->gst_tag,
       exiftag->exif_tag);
@@ -1984,8 +2040,11 @@ deserialize_geo_coordinate (GstExifReader * exif_reader,
     return ret;
   }
 
+  data = gst_buffer_map (exif_reader->buffer, &size, NULL, GST_MAP_READ);
+
   /* now parse the fractions */
-  gst_byte_reader_init_from_buffer (&fractions_reader, exif_reader->buffer);
+  gst_byte_reader_init (&fractions_reader, data, size);
+
   if (!gst_byte_reader_set_pos (&fractions_reader,
           next_tagdata.offset - exif_reader->base_offset))
     goto reader_fail;
@@ -2007,6 +2066,7 @@ deserialize_geo_coordinate (GstExifReader * exif_reader,
         !gst_byte_reader_get_uint32_be (&fractions_reader, &seconds_d))
       goto reader_fail;
   }
+  gst_buffer_unmap (exif_reader->buffer, data, size);
 
   GST_DEBUG ("Read degrees fraction for tag %s: %u/%u %u/%u %u/%u",
       exiftag->gst_tag, degrees_n, degrees_d, minutes_n, minutes_d,
@@ -2028,6 +2088,8 @@ deserialize_geo_coordinate (GstExifReader * exif_reader,
 
 reader_fail:
   GST_WARNING ("Failed to read fields from buffer (too short?)");
+  if (data)
+    gst_buffer_unmap (exif_reader->buffer, data, size);
   return ret;
 }
 
index 8bb3314..baa9eae 100644 (file)
@@ -102,6 +102,7 @@ struct _GstTagDemuxPrivate
 
   GstTagDemuxState state;
   GstBuffer *collect;
+  gsize collect_size;
   GstCaps *src_caps;
 
   GstTagList *event_tags;
@@ -110,7 +111,6 @@ struct _GstTagDemuxPrivate
 
   GstSegment segment;
   gboolean need_newseg;
-  gboolean newseg_update;
 
   GList *pending_events;
 };
@@ -254,6 +254,7 @@ gst_tag_demux_reset (GstTagDemux * tagdemux)
   tagdemux->priv->send_tag_event = FALSE;
 
   gst_buffer_replace (buffer_p, NULL);
+  tagdemux->priv->collect_size = 0;
   gst_caps_replace (caps_p, NULL);
 
   gst_tag_demux_remove_srcpad (tagdemux);
@@ -269,7 +270,6 @@ gst_tag_demux_reset (GstTagDemux * tagdemux)
 
   gst_segment_init (&tagdemux->priv->segment, GST_FORMAT_UNDEFINED);
   tagdemux->priv->need_newseg = TRUE;
-  tagdemux->priv->newseg_update = FALSE;
 
   g_list_foreach (tagdemux->priv->pending_events,
       (GFunc) gst_mini_object_unref, NULL);
@@ -388,18 +388,23 @@ gst_tag_demux_remove_srcpad (GstTagDemux * demux)
  * also return TRUE and set *buf_ref to NULL if the buffer was before
  * the start of the data */
 static gboolean
-gst_tag_demux_trim_buffer (GstTagDemux * tagdemux, GstBuffer ** buf_ref)
+gst_tag_demux_trim_buffer (GstTagDemux * tagdemux, GstBuffer ** buf_ref,
+    gsize * buf_size)
 {
   GstBuffer *buf = *buf_ref;
 
   guint trim_start = 0;
-  guint out_size = GST_BUFFER_SIZE (buf);
-  guint64 out_offset = GST_BUFFER_OFFSET (buf);
+  guint out_size, bsize;
+  guint64 out_offset, boffset;
   gboolean need_sub = FALSE;
 
+  bsize = out_size = gst_buffer_get_size (buf);
+  boffset = out_offset = GST_BUFFER_OFFSET (buf);
+
   /* Adjust offset and length */
   if (!GST_BUFFER_OFFSET_IS_VALID (buf)) {
     /* Can't change anything without an offset */
+    *buf_size = bsize;
     return TRUE;
   }
 
@@ -439,26 +444,28 @@ gst_tag_demux_trim_buffer (GstTagDemux * tagdemux, GstBuffer ** buf_ref)
   }
 
   if (need_sub == TRUE) {
-    if (out_size != GST_BUFFER_SIZE (buf) || !gst_buffer_is_writable (buf)) {
+    if (out_size != bsize || !gst_buffer_is_writable (buf)) {
       GstBuffer *sub;
 
       GST_DEBUG_OBJECT (tagdemux, "Sub-buffering to trim size %d offset %"
           G_GINT64_FORMAT " to %d offset %" G_GINT64_FORMAT,
-          GST_BUFFER_SIZE (buf), GST_BUFFER_OFFSET (buf), out_size, out_offset);
+          bsize, boffset, out_size, out_offset);
 
-      sub = gst_buffer_create_sub (buf, trim_start, out_size);
+      sub =
+          gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, trim_start,
+          out_size);
       g_return_val_if_fail (sub != NULL, FALSE);
       gst_buffer_unref (buf);
       *buf_ref = buf = sub;
+      *buf_size = out_size;
     } else {
       GST_DEBUG_OBJECT (tagdemux, "Adjusting buffer from size %d offset %"
           G_GINT64_FORMAT " to %d offset %" G_GINT64_FORMAT,
-          GST_BUFFER_SIZE (buf), GST_BUFFER_OFFSET (buf), out_size, out_offset);
+          bsize, boffset, out_size, out_offset);
     }
 
     GST_BUFFER_OFFSET (buf) = out_offset;
     GST_BUFFER_OFFSET_END (buf) = out_offset + out_size;
-    gst_buffer_set_caps (buf, tagdemux->priv->src_caps);
   }
 
   return TRUE;
@@ -485,7 +492,7 @@ gst_tag_demux_chain_parse_tag (GstTagDemux * demux, GstBuffer * collect)
   guint tagsize = 0;
   guint available;
 
-  g_assert (gst_buffer_is_metadata_writable (collect));
+  g_assert (gst_buffer_is_writable (collect));
 
   klass = GST_TAG_DEMUX_CLASS (G_OBJECT_GET_CLASS (demux));
 
@@ -501,7 +508,7 @@ gst_tag_demux_chain_parse_tag (GstTagDemux * demux, GstBuffer * collect)
   g_assert (klass->identify_tag != NULL);
   g_assert (klass->parse_tag != NULL);
 
-  available = GST_BUFFER_SIZE (collect);
+  available = gst_buffer_get_size (collect);
 
   if (available < klass->min_start_size) {
     GST_DEBUG_OBJECT (demux, "Only %u bytes available, but %u needed "
@@ -535,13 +542,13 @@ gst_tag_demux_chain_parse_tag (GstTagDemux * demux, GstBuffer * collect)
       return;                   /* wait for more data */
     }
 
-    saved_size = GST_BUFFER_SIZE (collect);
-    GST_BUFFER_SIZE (collect) = tagsize;
+    saved_size = gst_buffer_get_size (collect);
+    gst_buffer_set_size (collect, tagsize);
     newsize = tagsize;
 
     parse_ret = klass->parse_tag (demux, collect, TRUE, &newsize, &tags);
 
-    GST_BUFFER_SIZE (collect) = saved_size;
+    gst_buffer_set_size (collect, saved_size);
 
     switch (parse_ret) {
       case GST_TAG_DEMUX_RESULT_OK:
@@ -572,19 +579,22 @@ static GstFlowReturn
 gst_tag_demux_chain (GstPad * pad, GstBuffer * buf)
 {
   GstTagDemux *demux;
+  gsize size;
 
   demux = GST_TAG_DEMUX (GST_PAD_PARENT (pad));
 
-  /* Update our segment last_stop info */
+  size = gst_buffer_get_size (buf);
+
+  /* Update our segment position info */
   if (demux->priv->segment.format == GST_FORMAT_BYTES) {
     if (GST_BUFFER_OFFSET_IS_VALID (buf))
-      demux->priv->segment.last_stop = GST_BUFFER_OFFSET (buf);
-    demux->priv->segment.last_stop += GST_BUFFER_SIZE (buf);
+      demux->priv->segment.position = GST_BUFFER_OFFSET (buf);
+    demux->priv->segment.position += size;
   } else if (demux->priv->segment.format == GST_FORMAT_TIME) {
     if (GST_BUFFER_TIMESTAMP_IS_VALID (buf))
-      demux->priv->segment.last_stop = GST_BUFFER_TIMESTAMP (buf);
+      demux->priv->segment.position = GST_BUFFER_TIMESTAMP (buf);
     if (GST_BUFFER_DURATION_IS_VALID (buf))
-      demux->priv->segment.last_stop += GST_BUFFER_DURATION (buf);
+      demux->priv->segment.position += GST_BUFFER_DURATION (buf);
   }
 
   if (demux->priv->collect == NULL) {
@@ -592,12 +602,12 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf)
   } else {
     demux->priv->collect = gst_buffer_join (demux->priv->collect, buf);
   }
+  demux->priv->collect_size += size;
   buf = NULL;
 
   switch (demux->priv->state) {
     case GST_TAG_DEMUX_READ_START_TAG:
-      demux->priv->collect =
-          gst_buffer_make_metadata_writable (demux->priv->collect);
+      demux->priv->collect = gst_buffer_make_writable (demux->priv->collect);
       gst_tag_demux_chain_parse_tag (demux, demux->priv->collect);
       if (demux->priv->state != GST_TAG_DEMUX_TYPEFINDING)
         break;
@@ -605,19 +615,20 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf)
     case GST_TAG_DEMUX_TYPEFINDING:{
       GstTypeFindProbability probability = 0;
       GstBuffer *typefind_buf = NULL;
+      gsize typefind_size;
       GstCaps *caps;
 
-      if (GST_BUFFER_SIZE (demux->priv->collect) <
+      if (demux->priv->collect_size <
           TYPE_FIND_MIN_SIZE + demux->priv->strip_start)
         break;                  /* Go get more data first */
 
       GST_DEBUG_OBJECT (demux, "Typefinding with size %d",
-          GST_BUFFER_SIZE (demux->priv->collect));
+          demux->priv->collect_size);
 
       /* Trim the buffer and adjust offset for typefinding */
       typefind_buf = demux->priv->collect;
       gst_buffer_ref (typefind_buf);
-      if (!gst_tag_demux_trim_buffer (demux, &typefind_buf))
+      if (!gst_tag_demux_trim_buffer (demux, &typefind_buf, &typefind_size))
         return GST_FLOW_UNEXPECTED;
 
       if (typefind_buf == NULL)
@@ -627,7 +638,7 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf)
           typefind_buf, &probability);
 
       if (caps == NULL) {
-        if (GST_BUFFER_SIZE (typefind_buf) < TYPE_FIND_MAX_SIZE) {
+        if (typefind_size < TYPE_FIND_MAX_SIZE) {
           /* Just break for more data */
           gst_buffer_unref (typefind_buf);
           return GST_FLOW_OK;
@@ -639,6 +650,7 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf)
         gst_buffer_unref (typefind_buf);
         gst_buffer_unref (demux->priv->collect);
         demux->priv->collect = NULL;
+        demux->priv->collect_size = 0;
         return GST_FLOW_ERROR;
       }
       gst_buffer_unref (typefind_buf);
@@ -660,12 +672,14 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf)
     }
     case GST_TAG_DEMUX_STREAMING:{
       GstBuffer *outbuf = NULL;
+      gsize outbuf_size;
 
       /* Trim the buffer and adjust offset */
       if (demux->priv->collect) {
         outbuf = demux->priv->collect;
         demux->priv->collect = NULL;
-        if (!gst_tag_demux_trim_buffer (demux, &outbuf))
+        demux->priv->collect_size = 0;
+        if (!gst_tag_demux_trim_buffer (demux, &outbuf, &outbuf_size))
           return GST_FLOW_UNEXPECTED;
       }
       if (outbuf) {
@@ -692,10 +706,6 @@ gst_tag_demux_chain (GstPad * pad, GstBuffer * buf)
           demux->priv->send_tag_event = FALSE;
         }
 
-        /* Ensure the caps are set correctly */
-        outbuf = gst_buffer_make_metadata_writable (outbuf);
-        gst_buffer_set_caps (outbuf, GST_PAD_CAPS (demux->priv->srcpad));
-
         GST_LOG_OBJECT (demux, "Pushing buffer %p", outbuf);
 
         return gst_pad_push (demux->priv->srcpad, outbuf);
@@ -726,18 +736,10 @@ gst_tag_demux_sink_event (GstPad * pad, GstEvent * event)
       }
       ret = gst_pad_event_default (pad, event);
       break;
-    case GST_EVENT_NEWSEGMENT:{
-      gboolean update;
-      gdouble rate, arate;
-      GstFormat format;
-      gint64 start, stop, position;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate,
-          &format, &start, &stop, &position);
+    case GST_EVENT_SEGMENT:
+    {
+      gst_event_copy_segment (event, &demux->priv->segment);
 
-      gst_segment_set_newsegment_full (&demux->priv->segment, update, rate,
-          arate, format, start, stop, position);
-      demux->priv->newseg_update = update;
       demux->priv->need_newseg = TRUE;
       gst_event_unref (event);
       ret = TRUE;
@@ -885,6 +887,7 @@ gst_tag_demux_pull_end_tag (GstTagDemux * demux, GstTagList ** tags)
   gboolean res = FALSE;
   guint64 offset;
   guint tagsize;
+  gsize bsize;
 
   klass = GST_TAG_DEMUX_CLASS (G_OBJECT_GET_CLASS (demux));
 
@@ -913,9 +916,11 @@ gst_tag_demux_pull_end_tag (GstTagDemux * demux, GstTagList ** tags)
     goto done;
   }
 
-  if (GST_BUFFER_SIZE (buffer) < klass->min_end_size) {
+  bsize = gst_buffer_get_size (buffer);
+
+  if (bsize < klass->min_end_size) {
     GST_DEBUG_OBJECT (demux, "Only managed to read %u bytes from file "
-        "(required: %u bytes)", GST_BUFFER_SIZE (buffer), klass->min_end_size);
+        "(required: %u bytes)", bsize, klass->min_end_size);
     goto done;
   }
 
@@ -937,7 +942,7 @@ gst_tag_demux_pull_end_tag (GstTagDemux * demux, GstTagList ** tags)
     g_assert (tagsize >= klass->min_end_size);
 
     /* Get buffer that's exactly the requested size */
-    if (GST_BUFFER_SIZE (buffer) != tagsize) {
+    if (bsize != tagsize) {
       gst_buffer_unref (buffer);
       buffer = NULL;
 
@@ -953,22 +958,24 @@ gst_tag_demux_pull_end_tag (GstTagDemux * demux, GstTagList ** tags)
         goto done;
       }
 
-      if (GST_BUFFER_SIZE (buffer) < tagsize) {
+      bsize = gst_buffer_get_size (buffer);
+
+      if (bsize < tagsize) {
         GST_DEBUG_OBJECT (demux, "Only managed to read %u bytes from file",
-            GST_BUFFER_SIZE (buffer));
+            bsize);
         goto done;
       }
     }
 
     GST_BUFFER_OFFSET (buffer) = offset;
 
-    saved_size = GST_BUFFER_SIZE (buffer);
-    GST_BUFFER_SIZE (buffer) = tagsize;
+    saved_size = bsize;
+    gst_buffer_set_size (buffer, tagsize);
     newsize = tagsize;
 
     parse_ret = klass->parse_tag (demux, buffer, FALSE, &newsize, &new_tags);
 
-    GST_BUFFER_SIZE (buffer) = saved_size;
+    gst_buffer_set_size (buffer, saved_size);
 
     switch (parse_ret) {
       case GST_TAG_DEMUX_RESULT_OK:
@@ -1015,6 +1022,7 @@ gst_tag_demux_pull_start_tag (GstTagDemux * demux, GstTagList ** tags)
   gboolean have_tag;
   gboolean res = FALSE;
   guint req, tagsize;
+  gsize bsize;
 
   klass = GST_TAG_DEMUX_CLASS (G_OBJECT_GET_CLASS (demux));
 
@@ -1037,9 +1045,11 @@ gst_tag_demux_pull_start_tag (GstTagDemux * demux, GstTagList ** tags)
     goto done;
   }
 
-  if (GST_BUFFER_SIZE (buffer) < klass->min_start_size) {
+  bsize = gst_buffer_get_size (buffer);
+
+  if (bsize < klass->min_start_size) {
     GST_DEBUG_OBJECT (demux, "Only managed to read %u bytes from file - "
-        "no tag in this file", GST_BUFFER_SIZE (buffer));
+        "no tag in this file", bsize);
     goto done;
   }
 
@@ -1061,7 +1071,7 @@ gst_tag_demux_pull_start_tag (GstTagDemux * demux, GstTagList ** tags)
     /* Now pull the entire tag */
     g_assert (tagsize >= klass->min_start_size);
 
-    if (GST_BUFFER_SIZE (buffer) < tagsize) {
+    if (bsize < tagsize) {
       gst_buffer_unref (buffer);
       buffer = NULL;
 
@@ -1072,21 +1082,23 @@ gst_tag_demux_pull_start_tag (GstTagDemux * demux, GstTagList ** tags)
         goto done;
       }
 
-      if (GST_BUFFER_SIZE (buffer) < tagsize) {
+      bsize = gst_buffer_get_size (buffer);
+
+      if (bsize < tagsize) {
         GST_DEBUG_OBJECT (demux, "Only managed to read %u bytes from file",
-            GST_BUFFER_SIZE (buffer));
+            bsize);
         GST_ELEMENT_ERROR (demux, STREAM, DECODE,
             (_("Failed to read tag: not enough data")), (NULL));
         goto done;
       }
     }
 
-    saved_size = GST_BUFFER_SIZE (buffer);
-    GST_BUFFER_SIZE (buffer) = tagsize;
+    saved_size = bsize;
+    gst_buffer_set_size (buffer, tagsize);
     newsize = tagsize;
     parse_ret = klass->parse_tag (demux, buffer, TRUE, &newsize, &new_tags);
 
-    GST_BUFFER_SIZE (buffer) = saved_size;
+    gst_buffer_set_size (buffer, saved_size);
 
     switch (parse_ret) {
       case GST_TAG_DEMUX_RESULT_OK:
@@ -1272,6 +1284,7 @@ gst_tag_demux_read_range (GstTagDemux * demux,
   GstFlowReturn ret;
   guint64 in_offset;
   guint in_length;
+  gsize size;
 
   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
 
@@ -1294,13 +1307,11 @@ gst_tag_demux_read_range (GstTagDemux * demux,
   ret = gst_pad_pull_range (demux->priv->sinkpad, in_offset, in_length, buffer);
 
   if (ret == GST_FLOW_OK && *buffer) {
-    if (!gst_tag_demux_trim_buffer (demux, buffer))
+    if (!gst_tag_demux_trim_buffer (demux, buffer, &size))
       goto read_beyond_end;
 
     /* this should only happen in streaming mode */
     g_assert (*buffer != NULL);
-
-    gst_buffer_set_caps (*buffer, demux->priv->src_caps);
   }
 
   return ret;
@@ -1460,20 +1471,19 @@ gst_tag_demux_send_new_segment (GstTagDemux * tagdemux)
   GstEvent *event;
   gint64 start, stop, position;
   GstSegment *seg = &tagdemux->priv->segment;
+  GstSegment newseg;
 
   if (seg->format == GST_FORMAT_UNDEFINED) {
     GST_LOG_OBJECT (tagdemux,
         "No new segment received before first buffer. Using default");
-    gst_segment_set_newsegment (seg, FALSE, 1.0,
-        GST_FORMAT_BYTES, tagdemux->priv->strip_start, -1,
-        tagdemux->priv->strip_start);
+    gst_segment_init (seg, GST_FORMAT_BYTES);
+    seg->start = tagdemux->priv->strip_start;
+    seg->time = tagdemux->priv->strip_start;
   }
 
   /* Can't adjust segments in non-BYTES formats */
   if (tagdemux->priv->segment.format != GST_FORMAT_BYTES) {
-    event = gst_event_new_new_segment_full (tagdemux->priv->newseg_update,
-        seg->rate, seg->applied_rate, seg->format, seg->start,
-        seg->stop, seg->time);
+    event = gst_event_new_segment (seg);
     return gst_pad_push_event (tagdemux->priv->srcpad, event);
   }
 
@@ -1523,13 +1533,13 @@ gst_tag_demux_send_new_segment (GstTagDemux * tagdemux)
     }
   }
 
-  GST_DEBUG_OBJECT (tagdemux,
-      "Sending new segment update %d, rate %g, format %d, "
-      "start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT ", position %"
-      G_GINT64_FORMAT, tagdemux->priv->newseg_update, seg->rate, seg->format,
-      start, stop, position);
+  GST_DEBUG_OBJECT (tagdemux, "Sending segment %" GST_SEGMENT_FORMAT, seg);
+
+  gst_segment_copy_into (seg, &newseg);
+  newseg.start = start;
+  newseg.stop = stop;
+  newseg.position = position;
+  event = gst_event_new_segment (&newseg);
 
-  event = gst_event_new_new_segment_full (tagdemux->priv->newseg_update,
-      seg->rate, seg->applied_rate, seg->format, start, stop, position);
   return gst_pad_push_event (tagdemux->priv->srcpad, event);
 }
index 400118b..603ffe9 100644 (file)
@@ -417,8 +417,9 @@ decode_failed:
 }
 
 /**
- * gst_tag_list_from_vorbiscomment_buffer:
- * @buffer: buffer to convert
+ * gst_tag_list_from_vorbiscomment:
+ * @data: data to convert
+ * @size: size of @data
  * @id_data: identification data at start of stream
  * @id_data_length: length of identification data
  * @vendor_string: pointer to a string that should take the vendor string
@@ -431,7 +432,7 @@ decode_failed:
  *          given vorbiscomment buffer or NULL on error.
  */
 GstTagList *
-gst_tag_list_from_vorbiscomment_buffer (const GstBuffer * buffer,
+gst_tag_list_from_vorbiscomment (const guint8 * data, gsize size,
     const guint8 * id_data, const guint id_data_length, gchar ** vendor_string)
 {
 #define ADVANCE(x) G_STMT_START{                                                \
@@ -447,15 +448,12 @@ gst_tag_list_from_vorbiscomment_buffer (const GstBuffer * buffer,
   gchar *cur, *value;
   guint cur_size;
   guint iterations;
-  guint8 *data;
-  guint size, value_len;
+  guint value_len;
   GstTagList *list;
 
-  g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
+  g_return_val_if_fail (data != NULL, NULL);
   g_return_val_if_fail (id_data != NULL || id_data_length == 0, NULL);
 
-  data = GST_BUFFER_DATA (buffer);
-  size = GST_BUFFER_SIZE (buffer);
   list = gst_tag_list_new ();
 
   if (size < 11 || size <= id_data_length + 4)
@@ -510,6 +508,37 @@ error:
 #undef ADVANCE
 }
 
+/**
+ * gst_tag_list_from_vorbiscomment_buffer:
+ * @buffer: buffer to convert
+ * @id_data: identification data at start of stream
+ * @id_data_length: length of identification data
+ * @vendor_string: pointer to a string that should take the vendor string
+ *                 of this vorbis comment or NULL if you don't need it.
+ *
+ * Creates a new tag list that contains the information parsed out of a
+ * vorbiscomment packet.
+ *
+ * Returns: A new #GstTagList with all tags that could be extracted from the
+ *          given vorbiscomment buffer or NULL on error.
+ */
+GstTagList *
+gst_tag_list_from_vorbiscomment_buffer (GstBuffer * buffer,
+    const guint8 * id_data, const guint id_data_length, gchar ** vendor_string)
+{
+  GstTagList *res;
+  guint8 *data;
+  gsize size;
+
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+  res =
+      gst_tag_list_from_vorbiscomment (data, size, id_data, id_data_length,
+      vendor_string);
+  gst_buffer_unmap (buffer, data, size);
+
+  return res;
+}
+
 typedef struct
 {
   guint count;
@@ -522,20 +551,30 @@ static GList *
 gst_tag_to_metadata_block_picture (const gchar * tag,
     const GValue * image_value)
 {
+#if 0
   gchar *comment_data, *data_result;
   const gchar *mime_type;
   guint mime_type_len;
   GstStructure *mime_struct;
   GstBuffer *buffer;
+#endif
   GList *l = NULL;
+#if 0
+  guint8 *data;
+  gsize size;
   GstByteWriter writer;
   GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
   gint width = 0, height = 0;
   guint8 *metadata_block;
   guint metadata_block_len;
+#endif
 
   g_return_val_if_fail (image_value != NULL, NULL);
 
+  /* FIXME, no more buffer caps */
+  g_assert_not_reached ();
+
+#if 0
   buffer = gst_value_get_buffer (image_value);
   g_return_val_if_fail (gst_caps_is_fixed (buffer->caps), NULL);
   mime_struct = gst_caps_get_structure (buffer->caps, 0);
@@ -549,7 +588,7 @@ gst_tag_to_metadata_block_picture (const gchar * tag,
       &image_type, "width", G_TYPE_INT, &width, "height", G_TYPE_INT, &height,
       NULL);
 
-  metadata_block_len = 32 + mime_type_len + GST_BUFFER_SIZE (buffer);
+  metadata_block_len = 32 + mime_type_len + gst_buffer_get_size (buffer);
   gst_byte_writer_init_with_size (&writer, metadata_block_len, TRUE);
 
   if (image_type == GST_TAG_IMAGE_TYPE_NONE
@@ -575,9 +614,12 @@ gst_tag_to_metadata_block_picture (const gchar * tag,
   gst_byte_writer_put_uint32_be_unchecked (&writer, 0);
   /* for indexed formats the number of colors */
   gst_byte_writer_put_uint32_be_unchecked (&writer, 0);
-  gst_byte_writer_put_uint32_be_unchecked (&writer, GST_BUFFER_SIZE (buffer));
-  gst_byte_writer_put_data_unchecked (&writer, GST_BUFFER_DATA (buffer),
-      GST_BUFFER_SIZE (buffer));
+
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+  gst_byte_writer_put_uint32_be_unchecked (&writer, size);
+  gst_byte_writer_put_data_unchecked (&writer, data, size);
+  gst_buffer_unmap (buffer, data, size);
+
   g_assert (gst_byte_writer_get_pos (&writer) == metadata_block_len);
 
   metadata_block = gst_byte_writer_reset_and_get_data (&writer);
@@ -587,6 +629,7 @@ gst_tag_to_metadata_block_picture (const gchar * tag,
   g_free (comment_data);
 
   l = g_list_append (l, data_result);
+#endif
 
   return l;
 }
@@ -743,7 +786,7 @@ gst_tag_list_to_vorbiscomment_buffer (const GstTagList * list,
     const gchar * vendor_string)
 {
   GstBuffer *buffer;
-  guint8 *data;
+  guint8 *data, *odata;
   guint i;
   GList *l;
   MyForEach my_data = { 0, 0, NULL };
@@ -759,8 +802,9 @@ gst_tag_list_to_vorbiscomment_buffer (const GstTagList * list,
   required_size = id_data_length + 4 + vendor_len + 4 + 1;
   gst_tag_list_foreach ((GstTagList *) list, write_one_tag, &my_data);
   required_size += 4 * my_data.count + my_data.data_count;
+
   buffer = gst_buffer_new_and_alloc (required_size);
-  data = GST_BUFFER_DATA (buffer);
+  odata = data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE);
   if (id_data_length > 0) {
     memcpy (data, id_data, id_data_length);
     data += id_data_length;
@@ -788,6 +832,7 @@ gst_tag_list_to_vorbiscomment_buffer (const GstTagList * list,
   g_list_foreach (my_data.entries, (GFunc) g_free, NULL);
   g_list_free (my_data.entries);
   *data = 1;
+  gst_buffer_unmap (buffer, odata, required_size);
 
   return buffer;
 }
index 920007e..55529be 100644 (file)
@@ -1250,11 +1250,11 @@ read_one_tag (GstTagList * list, XmpTag * xmptag,
  * Since: 0.10.29
  */
 GstTagList *
-gst_tag_list_from_xmp_buffer (const GstBuffer * buffer)
+gst_tag_list_from_xmp_buffer (GstBuffer * buffer)
 {
   GstTagList *list = NULL;
-  const gchar *xps, *xp1, *xp2, *xpe, *ns, *ne;
-  guint len, max_ft_len;
+  gchar *xps, *xp1, *xp2, *xpe, *ns, *ne;
+  gsize len, max_ft_len;
   gboolean in_tag;
   gchar *part, *pp;
   guint i;
@@ -1265,25 +1265,32 @@ gst_tag_list_from_xmp_buffer (const GstBuffer * buffer)
   XmpTag *context_tag = NULL;
 
   GstXmpNamespaceMap ns_map[] = {
-    {"dc", NULL},
-    {"exif", NULL},
-    {"tiff", NULL},
-    {"xap", NULL},
-    {"photoshop", NULL},
-    {"Iptc4xmpCore", NULL},
-    {"Iptc4xmpExt", NULL},
+    {"dc", NULL}
+    ,
+    {"exif", NULL}
+    ,
+    {"tiff", NULL}
+    ,
+    {"xap", NULL}
+    ,
+    {"photoshop", NULL}
+    ,
+    {"Iptc4xmpCore", NULL}
+    ,
+    {"Iptc4xmpExt", NULL}
+    ,
     {NULL, NULL}
   };
 
   xmp_tags_initialize ();
 
   g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
-  g_return_val_if_fail (GST_BUFFER_SIZE (buffer) > 0, NULL);
 
   GST_LOG ("Starting xmp parsing");
 
-  xps = (const gchar *) GST_BUFFER_DATA (buffer);
-  len = GST_BUFFER_SIZE (buffer);
+  xps = gst_buffer_map (buffer, &len, NULL, GST_MAP_READ);
+  g_return_val_if_fail (len > 0, NULL);
+
   xpe = &xps[len + 1];
 
   /* check header and footer */
@@ -1545,6 +1552,8 @@ gst_tag_list_from_xmp_buffer (const GstBuffer * buffer)
   }
   g_free (part);
 
+  gst_buffer_unmap (buffer, xps, len);
+
   return list;
 
   /* Errors */
@@ -1743,6 +1752,8 @@ gst_tag_list_to_xmp_buffer_full (const GstTagList * list, gboolean read_only,
   XmpSerializationData serialization_data;
   GString *data;
   guint i;
+  gsize bsize;
+  gpointer bdata;
 
   serialization_data.data = g_string_sized_new (4096);
   serialization_data.schemas = schemas;
@@ -1807,10 +1818,12 @@ gst_tag_list_to_xmp_buffer_full (const GstTagList * list, gboolean read_only,
   g_string_append_printf (data, "<?xpacket end=\"%c\"?>\n",
       (read_only ? 'r' : 'w'));
 
+  bsize = data->len + 1;
+  bdata = g_string_free (data, FALSE);
+
   buffer = gst_buffer_new ();
-  GST_BUFFER_SIZE (buffer) = data->len + 1;
-  GST_BUFFER_DATA (buffer) = (guint8 *) g_string_free (data, FALSE);
-  GST_BUFFER_MALLOCDATA (buffer) = GST_BUFFER_DATA (buffer);
+  gst_buffer_take_memory (buffer,
+      gst_memory_new_wrapped (0, bdata, g_free, bsize, 0, bsize));
 
   return buffer;
 }
index 219fe85..fcd977d 100644 (file)
@@ -454,7 +454,12 @@ GList *                 gst_tag_to_vorbis_comments              (const GstTagLis
                                                                  const gchar *          tag);
 
 /* functions to convert GstBuffers with vorbiscomment contents to GstTagLists and back */
-GstTagList *            gst_tag_list_from_vorbiscomment_buffer  (const GstBuffer *      buffer,
+GstTagList *            gst_tag_list_from_vorbiscomment         (const guint8 *         data,
+                                                                 gsize                  size,
+                                                                 const guint8 *         id_data,
+                                                                 const guint            id_data_length,
+                                                                 gchar **               vendor_string);
+GstTagList *            gst_tag_list_from_vorbiscomment_buffer  (GstBuffer *            buffer,
                                                                  const guint8 *         id_data,
                                                                  const guint            id_data_length,
                                                                  gchar **               vendor_string);
@@ -480,7 +485,7 @@ gboolean                gst_tag_list_add_id3_image (GstTagList   * tag_list,
                                                     guint          id3_picture_type);
 
 /* functions to  convert GstBuffers with xmp packets contents to GstTagLists and back */
-GstTagList *            gst_tag_list_from_xmp_buffer  (const GstBuffer *  buffer);
+GstTagList *            gst_tag_list_from_xmp_buffer  (GstBuffer *  buffer);
 GstBuffer *             gst_tag_list_to_xmp_buffer    (const GstTagList * list,
                                                        gboolean           read_only);
 GstBuffer *            gst_tag_list_to_xmp_buffer_full (const GstTagList * list,
@@ -494,12 +499,12 @@ GstBuffer *             gst_tag_list_to_exif_buffer (const GstTagList * taglist,
 
 GstBuffer *             gst_tag_list_to_exif_buffer_with_tiff_header (const GstTagList * taglist);
 
-GstTagList *            gst_tag_list_from_exif_buffer (const GstBuffer * buffer,
+GstTagList *            gst_tag_list_from_exif_buffer (GstBuffer * buffer,
                                                        gint byte_order,
                                                        guint32 base_offset);
 
 GstTagList *            gst_tag_list_from_exif_buffer_with_tiff_header (
-                                                      const GstBuffer * buffer);
+                                                      GstBuffer * buffer);
 
 /* other tag-related functions */
 
index 51f3bc7..b536239 100644 (file)
@@ -561,10 +561,9 @@ gst_tag_image_data_to_image_buffer (const guint8 * image_data,
     guint image_data_len, GstTagImageType image_type)
 {
   const gchar *name;
-
   GstBuffer *image;
-
   GstCaps *caps;
+  guint8 *data;
 
   g_return_val_if_fail (image_data != NULL, NULL);
   g_return_val_if_fail (image_data_len > 0, NULL);
@@ -573,14 +572,14 @@ gst_tag_image_data_to_image_buffer (const guint8 * image_data,
   GST_DEBUG ("image data len: %u bytes", image_data_len);
 
   /* allocate space for a NUL terminator for an uri too */
-  image = gst_buffer_try_new_and_alloc (image_data_len + 1);
-  if (image == NULL) {
-    GST_WARNING ("failed to allocate buffer of %d for image", image_data_len);
-    return NULL;
-  }
+  image = gst_buffer_new_and_alloc (image_data_len + 1);
+  if (image == NULL)
+    goto alloc_failed;
 
-  memcpy (GST_BUFFER_DATA (image), image_data, image_data_len);
-  GST_BUFFER_DATA (image)[image_data_len] = '\0';
+  data = gst_buffer_map (image, NULL, NULL, GST_MAP_WRITE);
+  memcpy (data, image_data, image_data_len);
+  data[image_data_len] = '\0';
+  gst_buffer_unmap (image, data, image_data_len + 1);
 
   /* Find GStreamer media type, can't trust declared type */
   caps = gst_type_find_helper_for_buffer (NULL, image, NULL);
@@ -604,7 +603,7 @@ gst_tag_image_data_to_image_buffer (const guint8 * image_data,
    * to keep the original size of the image
    */
   if (!g_str_equal (name, "text/uri-list"))
-    GST_BUFFER_SIZE (image) = image_data_len;
+    gst_buffer_set_size (image, image_data_len);
 
   if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
     GST_LOG ("Setting image type: %d", image_type);
@@ -613,8 +612,9 @@ gst_tag_image_data_to_image_buffer (const guint8 * image_data,
         image_type, NULL);
   }
 
-  gst_buffer_set_caps (image, caps);
+  g_warning ("extra image data can't be set");
   gst_caps_unref (caps);
+
   return image;
 
 /* ERRORS */
@@ -631,4 +631,11 @@ error:
       gst_caps_unref (caps);
     return NULL;
   }
+alloc_failed:
+  {
+    GST_WARNING ("failed to allocate buffer of %d for image", image_data_len);
+    gst_buffer_unref (image);
+    return NULL;
+  }
+
 }
index 21ce6e4..18cc49d 100644 (file)
@@ -13,12 +13,12 @@ lib_LTLIBRARIES = libgstvideo-@GST_MAJORMINOR@.la
 CLEANFILES = $(BUILT_SOURCES)
 
 libgstvideo_@GST_MAJORMINOR@_la_SOURCES = \
-       video.c gstvideosink.c gstvideofilter.c convertframe.c
+       video.c gstvideosink.c gstvideofilter.c convertframe.c gstmetavideo.c
 nodist_libgstvideo_@GST_MAJORMINOR@_la_SOURCES = $(BUILT_SOURCES)
 
 libgstvideo_@GST_MAJORMINOR@includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/video
 libgstvideo_@GST_MAJORMINOR@include_HEADERS = \
-       video.h gstvideosink.h gstvideofilter.h
+       video.h gstvideosink.h gstvideofilter.h gstmetavideo.h
 nodist_libgstvideo_@GST_MAJORMINOR@include_HEADERS = $(built_headers)
 
 libgstvideo_@GST_MAJORMINOR@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
index 58dc426..3d71675 100644 (file)
@@ -233,6 +233,7 @@ link_failed:
 /**
  * gst_video_convert_frame:
  * @buf: a #GstBuffer
+ * @from_caps: the #GstCaps to convert from
  * @to_caps: the #GstCaps to convert to
  * @timeout: the maximum amount of time allowed for the processing.
  * @error: pointer to a #GError. Can be %NULL.
@@ -250,23 +251,21 @@ link_failed:
  *
  */
 GstBuffer *
-gst_video_convert_frame (GstBuffer * buf, const GstCaps * to_caps,
-    GstClockTime timeout, GError ** error)
+gst_video_convert_frame (GstBuffer * buf, GstCaps * from_caps,
+    const GstCaps * to_caps, GstClockTime timeout, GError ** err)
 {
   GstMessage *msg;
   GstBuffer *result = NULL;
   GError *err = NULL;
   GstBus *bus;
-  GstCaps *from_caps, *to_caps_copy = NULL;
+  GstCaps *to_caps_copy = NULL;
   GstFlowReturn ret;
   GstElement *pipeline, *src, *sink;
   guint i, n;
 
   g_return_val_if_fail (buf != NULL, NULL);
   g_return_val_if_fail (to_caps != NULL, NULL);
-  g_return_val_if_fail (GST_BUFFER_CAPS (buf) != NULL, NULL);
-
-  from_caps = GST_BUFFER_CAPS (buf);
+  g_return_val_if_fail (from_caps != NULL, NULL);
 
   to_caps_copy = gst_caps_new_empty ();
   n = gst_caps_get_size (to_caps);
@@ -291,7 +290,7 @@ gst_video_convert_frame (GstBuffer * buf, const GstCaps * to_caps,
 
   /* feed buffer in appsrc */
   GST_DEBUG ("feeding buffer %p, size %u, caps %" GST_PTR_FORMAT,
-      buf, GST_BUFFER_SIZE (buf), from_caps);
+      buf, gst_buffer_get_size (buf), from_caps);
   g_signal_emit_by_name (src, "push-buffer", buf, &ret);
 
   /* now see what happens. We either got an error somewhere or the pipeline
@@ -597,14 +596,15 @@ done:
  *
  */
 void
-gst_video_convert_frame_async (GstBuffer * buf, const GstCaps * to_caps,
-    GstClockTime timeout, GstVideoConvertFrameCallback callback,
-    gpointer user_data, GDestroyNotify destroy_notify)
+gst_video_convert_frame_async (GstBuffer * buf, GstCaps * from_caps,
+    const GstCaps * to_caps, GstClockTime timeout,
+    GstVideoConvertFrameCallback callback, gpointer user_data,
+    GDestroyNotify destroy_notify)
 {
   GMainContext *context = NULL;
   GError *error = NULL;
   GstBus *bus;
-  GstCaps *from_caps, *to_caps_copy = NULL;
+  GstCaps *to_caps_copy = NULL;
   GstElement *pipeline, *src, *sink;
   guint i, n;
   GSource *source;
@@ -612,7 +612,7 @@ gst_video_convert_frame_async (GstBuffer * buf, const GstCaps * to_caps,
 
   g_return_if_fail (buf != NULL);
   g_return_if_fail (to_caps != NULL);
-  g_return_if_fail (GST_BUFFER_CAPS (buf) != NULL);
+  g_return_if_fail (from_caps != NULL);
   g_return_if_fail (callback != NULL);
 
   context = g_main_context_get_thread_default ();
@@ -620,8 +620,6 @@ gst_video_convert_frame_async (GstBuffer * buf, const GstCaps * to_caps,
   if (!context)
     context = g_main_context_default ();
 
-  from_caps = GST_BUFFER_CAPS (buf);
-
   to_caps_copy = gst_caps_new_empty ();
   n = gst_caps_get_size (to_caps);
   for (i = 0; i < n; i++) {
diff --git a/gst-libs/gst/video/gstmetavideo.c b/gst-libs/gst/video/gstmetavideo.c
new file mode 100644 (file)
index 0000000..a1be58b
--- /dev/null
@@ -0,0 +1,164 @@
+/* GStreamer
+ * Copyright (C) <2011> Wim Taymans <wim.taymans@gmail.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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gstmetavideo.h"
+
+/* video metadata */
+const GstMetaInfo *
+gst_meta_video_get_info (void)
+{
+  static const GstMetaInfo *meta_video_info = NULL;
+
+  if (meta_video_info == NULL) {
+    meta_video_info = gst_meta_register (GST_META_API_VIDEO, "GstMetaVideo",
+        sizeof (GstMetaVideo),
+        (GstMetaInitFunction) NULL,
+        (GstMetaFreeFunction) NULL,
+        (GstMetaCopyFunction) NULL, (GstMetaTransformFunction) NULL);
+  }
+  return meta_video_info;
+}
+
+
+GstMetaVideo *
+gst_buffer_add_meta_video (GstBuffer * buffer, GstMetaVideoFlags flags,
+    GstVideoFormat format, guint width, guint height)
+{
+  GstMetaVideo *meta;
+  guint i;
+  GstMetaVideoPlane plane[GST_VIDEO_MAX_PLANES];
+
+  for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
+    gint offset;
+
+    offset = gst_video_format_get_component_offset (format, i, width, height);
+    /* end when the offset is 0 for something else that the first component */
+    if (i > 0 && offset == 0)
+      break;
+
+    plane[i].offset = offset;
+    plane[i].stride = gst_video_format_get_row_stride (format, i, width);
+  }
+
+  meta = gst_buffer_add_meta_video_full (buffer, flags, format, width, height,
+      i, plane);
+
+  return meta;
+}
+
+GstMetaVideo *
+gst_buffer_add_meta_video_full (GstBuffer * buffer, GstMetaVideoFlags flags,
+    GstVideoFormat format, guint width, guint height,
+    guint n_planes, GstMetaVideoPlane plane[GST_VIDEO_MAX_PLANES])
+{
+  GstMetaVideo *meta;
+  guint i;
+
+  meta =
+      (GstMetaVideo *) gst_buffer_add_meta (buffer, GST_META_INFO_VIDEO, NULL);
+
+  meta->flags = flags;
+  meta->format = format;
+  meta->width = width;
+  meta->height = height;
+
+  meta->n_planes = n_planes;
+  for (i = 0; i < n_planes; i++)
+    meta->plane[i] = plane[i];
+
+  return meta;
+}
+
+static GstMemory *
+find_mem_for_offset (GstBuffer * buffer, guint * offset, GstMapFlags flags)
+{
+  guint n, i;
+  GstMemory *res = NULL;
+
+  n = gst_buffer_n_memory (buffer);
+  for (i = 0; i < n; i++) {
+    GstMemory *mem = NULL;
+    gsize size;
+
+    mem = gst_buffer_peek_memory (buffer, i, flags);
+    size = gst_memory_get_sizes (mem, NULL);
+
+    if (*offset < size) {
+      res = mem;
+      break;
+    }
+    *offset -= size;
+  }
+  return res;
+}
+
+gpointer
+gst_meta_video_map (GstMetaVideo * meta, guint plane, gint * stride,
+    GstMapFlags flags)
+{
+  guint offset;
+  gboolean write;
+  GstBuffer *buffer;
+  GstMemory *mem;
+  guint8 *base;
+
+  g_return_val_if_fail (meta != NULL, NULL);
+  g_return_val_if_fail (plane < meta->n_planes, NULL);
+  g_return_val_if_fail (stride != NULL, NULL);
+
+  buffer = meta->buffer;
+  g_return_val_if_fail (buffer != NULL, NULL);
+
+  write = (flags & GST_MAP_WRITE) != 0;
+  g_return_val_if_fail (write && !gst_buffer_is_writable (buffer), NULL);
+
+  offset = meta->plane[plane].offset;
+  *stride = meta->plane[plane].stride;
+  /* find the memory block for this plane, this is the memory block containing
+   * the plane offset */
+  mem = find_mem_for_offset (buffer, &offset, flags);
+
+  /* move to the right offset inside the block */
+  base = gst_memory_map (mem, NULL, NULL, flags);
+
+  return base + offset;
+}
+
+gboolean
+gst_meta_video_unmap (GstMetaVideo * meta, guint plane, gpointer data)
+{
+  guint offset;
+  GstBuffer *buffer;
+  GstMemory *mem;
+  guint8 *base;
+
+  g_return_val_if_fail (meta != NULL, FALSE);
+  g_return_val_if_fail (plane < meta->n_planes, FALSE);
+
+  buffer = meta->buffer;
+  g_return_val_if_fail (buffer != NULL, FALSE);
+
+  offset = meta->plane[plane].offset;
+  mem = find_mem_for_offset (buffer, &offset, GST_MAP_READ);
+  base = data;
+
+  gst_memory_unmap (mem, base - offset, -1);
+
+  return TRUE;
+}
diff --git a/gst-libs/gst/video/gstmetavideo.h b/gst-libs/gst/video/gstmetavideo.h
new file mode 100644 (file)
index 0000000..30549e7
--- /dev/null
@@ -0,0 +1,118 @@
+/* GStreamer
+ * Copyright (C) <2011> Wim Taymans <wim.taymans@gmail.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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_META_VIDEO_H__
+#define __GST_META_VIDEO_H__
+
+#include <gst/gst.h>
+
+#include <gst/video/video.h>
+
+G_BEGIN_DECLS
+
+#define GST_META_API_VIDEO   "GstMetaVideo"
+#define GST_META_INFO_VIDEO  (gst_meta_video_get_info())
+
+#define GST_VIDEO_MAX_PLANES 4
+
+typedef struct _GstMetaVideo GstMetaVideo;
+typedef struct _GstMetaVideoPlane GstMetaVideoPlane;
+
+/**
+ * GstMetaVideoFlags:
+ * @GST_META_VIDEO_FLAG_NONE: no flags
+ * @GST_META_VIDEO_FLAG_INTERLACED:
+ * @GST_META_VIDEO_FLAG_TTF:
+ * @GST_META_VIDEO_FLAG_RFF:
+ * @GST_META_VIDEO_FLAG_ONEFIELD:
+ * @GST_META_VIDEO_FLAG_TELECINE:
+ * @GST_META_VIDEO_FLAG_PROGRESSIVE:
+ *
+ * Extra video flags
+ */
+typedef enum {
+  GST_META_VIDEO_FLAG_NONE        = 0,
+  GST_META_VIDEO_FLAG_INTERLACED  = (1 << 0),
+  GST_META_VIDEO_FLAG_TTF         = (1 << 1),
+  GST_META_VIDEO_FLAG_RFF         = (1 << 2),
+  GST_META_VIDEO_FLAG_ONEFIELD    = (1 << 3),
+  GST_META_VIDEO_FLAG_TELECINE    = (1 << 4),
+  GST_META_VIDEO_FLAG_PROGRESSIVE = (1 << 5)
+} GstMetaVideoFlags;
+
+/**
+ * GstMetaVideoPlane:
+ * @offset: offset of the first pixel in the buffer memory region
+ * @stride: stride of the image lines. Can be negative when the image is
+ *    upside-down
+ *
+ * Information for one video plane.
+ */
+struct _GstMetaVideoPlane {
+  gsize           offset;
+  gint            stride;
+};
+
+/**
+ * GstMetaVideo:
+ * @meta: parent #GstMeta
+ * @flags: additional video flags
+ * @n_planes: the number of planes in the image
+ * @plane: array of #GstMetaVideoPlane
+ * @map: map the memory of a plane
+ * @unmap: unmap the memory of a plane
+ *
+ * Extra buffer metadata describing image properties
+ */
+struct _GstMetaVideo {
+  GstMeta       meta;
+
+  GstMetaVideoFlags  flags;
+
+  GstBuffer         *buffer;
+
+  GstVideoFormat     format;
+  guint              width;
+  guint              height;
+
+  guint              n_planes;
+  GstMetaVideoPlane  plane[GST_VIDEO_MAX_PLANES];
+
+  gpointer (*map)    (GstMetaVideo *meta, guint plane, gint *stride,
+                      GstMapFlags flags);
+  gboolean (*unmap)  (GstMetaVideo *meta, guint plane, gpointer data);
+};
+
+const GstMetaInfo * gst_meta_video_get_info (void);
+
+#define gst_buffer_get_meta_video(b) ((GstMetaVideo*)gst_buffer_get_meta((b),GST_META_INFO_VIDEO))
+GstMetaVideo * gst_buffer_add_meta_video       (GstBuffer *buffer, GstMetaVideoFlags flags,
+                                                GstVideoFormat format, guint width, guint height);
+GstMetaVideo * gst_buffer_add_meta_video_full  (GstBuffer *buffer, GstMetaVideoFlags flags,
+                                                GstVideoFormat format, guint width, guint height,
+                                                guint n_planes, GstMetaVideoPlane plane[GST_VIDEO_MAX_PLANES]);
+
+gpointer       gst_meta_video_map        (GstMetaVideo *meta, guint plane, gint *stride,
+                                          GstMapFlags flags);
+gboolean       gst_meta_video_unmap      (GstMetaVideo *meta, guint plane, gpointer data);
+
+
+G_END_DECLS
+
+#endif /* __GST_META_VIDEO_H__ */
index 2d08a60..0f09b82 100644 (file)
@@ -75,7 +75,7 @@ gst_video_filter_get_type (void)
 
 static gboolean
 gst_video_filter_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
-    guint * size)
+    gsize * size)
 {
   GstVideoFormat fmt;
   gint width, height;
index 4b64cfc..3b28bba 100644 (file)
@@ -65,37 +65,52 @@ gst_video_frame_rate (GstPad * pad)
 {
   const GValue *fps;
   gchar *fps_string;
-
-  const GstCaps *caps = NULL;
+  GstCaps *caps = NULL;
   GstStructure *structure;
 
   /* get pad caps */
-  caps = GST_PAD_CAPS (pad);
-  if (caps == NULL) {
+  caps = gst_pad_get_current_caps (pad);
+  if (caps == NULL)
+    goto no_caps;
+
+  structure = gst_caps_get_structure (caps, 0);
+  if ((fps = gst_structure_get_value (structure, "framerate")) == NULL)
+    goto no_framerate;
+
+  if (!GST_VALUE_HOLDS_FRACTION (fps))
+    goto no_fraction;
+
+  fps_string = gst_value_serialize (fps);
+  GST_DEBUG ("Framerate request on pad %s:%s: %s",
+      GST_DEBUG_PAD_NAME (pad), fps_string);
+  g_free (fps_string);
+
+  gst_caps_unref (caps);
+
+  return fps;
+
+  /* ERRORS */
+no_caps:
+  {
     g_warning ("gstvideo: failed to get caps of pad %s:%s",
         GST_DEBUG_PAD_NAME (pad));
     return NULL;
   }
-
-  structure = gst_caps_get_structure (caps, 0);
-  if ((fps = gst_structure_get_value (structure, "framerate")) == NULL) {
+no_framerate:
+  {
     g_warning ("gstvideo: failed to get framerate property of pad %s:%s",
         GST_DEBUG_PAD_NAME (pad));
+    gst_caps_unref (caps);
     return NULL;
   }
-  if (!GST_VALUE_HOLDS_FRACTION (fps)) {
+no_fraction:
+  {
     g_warning
         ("gstvideo: framerate property of pad %s:%s is not of type Fraction",
         GST_DEBUG_PAD_NAME (pad));
+    gst_caps_unref (caps);
     return NULL;
   }
-
-  fps_string = gst_value_serialize (fps);
-  GST_DEBUG ("Framerate request on pad %s:%s: %s",
-      GST_DEBUG_PAD_NAME (pad), fps_string);
-  g_free (fps_string);
-
-  return fps;
 }
 
 /**
@@ -115,7 +130,7 @@ gst_video_frame_rate (GstPad * pad)
 gboolean
 gst_video_get_size (GstPad * pad, gint * width, gint * height)
 {
-  const GstCaps *caps = NULL;
+  GstCaps *caps = NULL;
   GstStructure *structure;
   gboolean ret;
 
@@ -123,28 +138,36 @@ gst_video_get_size (GstPad * pad, gint * width, gint * height)
   g_return_val_if_fail (width != NULL, FALSE);
   g_return_val_if_fail (height != NULL, FALSE);
 
-  caps = GST_PAD_CAPS (pad);
-
-  if (caps == NULL) {
-    g_warning ("gstvideo: failed to get caps of pad %s:%s",
-        GST_DEBUG_PAD_NAME (pad));
-    return FALSE;
-  }
+  caps = gst_pad_get_current_caps (pad);
+  if (caps == NULL)
+    goto no_caps;
 
   structure = gst_caps_get_structure (caps, 0);
   ret = gst_structure_get_int (structure, "width", width);
   ret &= gst_structure_get_int (structure, "height", height);
+  gst_caps_unref (caps);
 
-  if (!ret) {
-    g_warning ("gstvideo: failed to get size properties on pad %s:%s",
-        GST_DEBUG_PAD_NAME (pad));
-    return FALSE;
-  }
+  if (!ret)
+    goto no_size;
 
   GST_DEBUG ("size request on pad %s:%s: %dx%d",
       GST_DEBUG_PAD_NAME (pad), width ? *width : -1, height ? *height : -1);
 
   return TRUE;
+
+  /* ERROR */
+no_caps:
+  {
+    g_warning ("gstvideo: failed to get caps of pad %s:%s",
+        GST_DEBUG_PAD_NAME (pad));
+    return FALSE;
+  }
+no_size:
+  {
+    g_warning ("gstvideo: failed to get size properties on pad %s:%s",
+        GST_DEBUG_PAD_NAME (pad));
+    return FALSE;
+  }
 }
 
 /**
index 66dad1f..60d73f4 100644 (file)
@@ -489,11 +489,11 @@ gboolean gst_video_format_convert (GstVideoFormat format, int width, int height,
 GstEvent *gst_video_event_new_still_frame (gboolean in_still);
 gboolean gst_video_event_parse_still_frame (GstEvent *event, gboolean *in_still);
 
-GstBuffer *gst_video_convert_frame(GstBuffer *buf, const GstCaps *to_caps,
+GstBuffer *gst_video_convert_frame(GstBuffer *buf, GstCaps *from_caps, const GstCaps *to_caps,
                                   GstClockTime timeout, GError **error);
 
 typedef void (*GstVideoConvertFrameCallback) (GstBuffer *buf, GError *error, gpointer user_data);
-void gst_video_convert_frame_async(GstBuffer *buf, const GstCaps *to_caps,
+void gst_video_convert_frame_async(GstBuffer *buf, GstCaps *from_caps, const GstCaps *to_caps,
                                   GstClockTime timeout, GstVideoConvertFrameCallback callback,
                                    gpointer user_data, GDestroyNotify destroy_notify);
 
index fca3eb2..c004c41 100644 (file)
@@ -116,7 +116,8 @@ GST_STATIC_PAD_TEMPLATE ("sink%d",
     GST_STATIC_CAPS (CAPS)
     );
 
-GST_BOILERPLATE (GstAdder, gst_adder, GstElement, GST_TYPE_ELEMENT);
+#define gst_adder_parent_class parent_class
+G_DEFINE_TYPE (GstAdder, gst_adder, GST_TYPE_ELEMENT);
 
 static void gst_adder_dispose (GObject * object);
 static void gst_adder_set_property (GObject * object, guint prop_id,
@@ -130,7 +131,7 @@ static gboolean gst_adder_src_event (GstPad * pad, GstEvent * event);
 static gboolean gst_adder_sink_event (GstPad * pad, GstEvent * event);
 
 static GstPad *gst_adder_request_new_pad (GstElement * element,
-    GstPadTemplate * temp, const gchar * unused);
+    GstPadTemplate * temp, const gchar * unused, const GstCaps * caps);
 static void gst_adder_release_pad (GstElement * element, GstPad * pad);
 
 static GstStateChangeReturn gst_adder_change_state (GstElement * element,
@@ -157,7 +158,7 @@ MAKE_FUNC_NC (add_float64, gdouble)
  * if we have filtercaps set, use those to constrain the target caps.
  */
 static GstCaps *
-gst_adder_sink_getcaps (GstPad * pad)
+gst_adder_sink_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstAdder *adder;
   GstCaps *result, *peercaps, *sinkcaps, *filter_caps;
@@ -166,27 +167,39 @@ gst_adder_sink_getcaps (GstPad * pad)
 
   GST_OBJECT_LOCK (adder);
   /* take filter */
-  if ((filter_caps = adder->filter_caps))
-    gst_caps_ref (filter_caps);
+  if ((filter_caps = adder->filter_caps)) {
+    if (filter)
+      filter_caps =
+          gst_caps_intersect_full (filter, filter_caps,
+          GST_CAPS_INTERSECT_FIRST);
+    else
+      gst_caps_ref (filter_caps);
+  } else {
+    filter_caps = gst_caps_ref (filter);
+  }
   GST_OBJECT_UNLOCK (adder);
 
+  if (filter_caps && gst_caps_is_empty (filter_caps)) {
+    GST_WARNING_OBJECT (pad, "Empty filter caps");
+    return filter_caps;
+  }
+
   /* get the downstream possible caps */
-  peercaps = gst_pad_peer_get_caps (adder->srcpad);
+  peercaps = gst_pad_peer_get_caps (adder->srcpad, filter_caps);
+
+  /* get the allowed caps on this sinkpad */
+  sinkcaps = gst_pad_get_current_caps (pad);
+  if (sinkcaps == NULL) {
+    sinkcaps = gst_pad_get_pad_template_caps (pad);
+    if (!sinkcaps)
+      sinkcaps = gst_caps_new_any ();
+  }
 
-  /* get the allowed caps on this sinkpad, we use the fixed caps function so
-   * that it does not call recursively in this function. */
-  sinkcaps = gst_pad_get_fixed_caps_func (pad);
   if (peercaps) {
-    /* restrict with filter-caps if any */
-    if (filter_caps) {
-      GST_DEBUG_OBJECT (adder, "filtering peer caps");
-      result = gst_caps_intersect (peercaps, filter_caps);
-      gst_caps_unref (peercaps);
-      peercaps = result;
-    }
     /* if the peer has caps, intersect */
     GST_DEBUG_OBJECT (adder, "intersecting peer and template caps");
-    result = gst_caps_intersect (peercaps, sinkcaps);
+    result =
+        gst_caps_intersect_full (peercaps, sinkcaps, GST_CAPS_INTERSECT_FIRST);
     gst_caps_unref (peercaps);
     gst_caps_unref (sinkcaps);
   } else {
@@ -195,7 +208,9 @@ gst_adder_sink_getcaps (GstPad * pad)
     /* restrict with filter-caps if any */
     if (filter_caps) {
       GST_DEBUG_OBJECT (adder, "no peer caps, using filtered sinkcaps");
-      result = gst_caps_intersect (sinkcaps, filter_caps);
+      result =
+          gst_caps_intersect_full (filter_caps, sinkcaps,
+          GST_CAPS_INTERSECT_FIRST);
       gst_caps_unref (sinkcaps);
     } else {
       GST_DEBUG_OBJECT (adder, "no peer caps, using sinkcaps");
@@ -212,6 +227,21 @@ gst_adder_sink_getcaps (GstPad * pad)
   return result;
 }
 
+typedef struct
+{
+  GstPad *pad;
+  GstCaps *caps;
+} IterData;
+
+static void
+setcapsfunc (const GValue * item, IterData * data)
+{
+  GstPad *otherpad = g_value_get_object (item);
+
+  if (otherpad != data->pad)
+    gst_pad_set_caps (data->pad, data->caps);
+}
+
 /* the first caps we receive on any of the sinkpads will define the caps for all
  * the other sinkpads because we can only mix streams with the same caps.
  */
@@ -219,28 +249,39 @@ static gboolean
 gst_adder_setcaps (GstPad * pad, GstCaps * caps)
 {
   GstAdder *adder;
-  GList *pads;
   GstStructure *structure;
   const char *media_type;
+  GstIterator *it;
+  GstIteratorResult ires;
+  IterData idata;
+  gboolean done;
 
   adder = GST_ADDER (GST_PAD_PARENT (pad));
 
   GST_LOG_OBJECT (adder, "setting caps on pad %p,%s to %" GST_PTR_FORMAT, pad,
       GST_PAD_NAME (pad), caps);
 
+  it = gst_element_iterate_pads (GST_ELEMENT_CAST (adder));
+
   /* FIXME, see if the other pads can accept the format. Also lock the
    * format on the other pads to this new format. */
-  GST_OBJECT_LOCK (adder);
-  pads = GST_ELEMENT (adder)->pads;
-  while (pads) {
-    GstPad *otherpad = GST_PAD (pads->data);
+  idata.caps = caps;
+  idata.pad = pad;
 
-    if (otherpad != pad) {
-      gst_caps_replace (&GST_PAD_CAPS (otherpad), caps);
+  done = FALSE;
+  while (!done) {
+    ires = gst_iterator_foreach (it, (GstIteratorForeachFunction) setcapsfunc,
+        &idata);
+
+    switch (ires) {
+      case GST_ITERATOR_RESYNC:
+        gst_iterator_resync (it);
+        break;
+      default:
+        done = TRUE;
+        break;
     }
-    pads = g_list_next (pads);
   }
-  GST_OBJECT_UNLOCK (adder);
 
   /* parse caps now */
   structure = gst_caps_get_structure (caps, 0);
@@ -343,6 +384,7 @@ gst_adder_query_duration (GstAdder * adder, GstQuery * query)
   GstFormat format;
   GstIterator *it;
   gboolean done;
+  GValue item = { 0, };
 
   /* parse format */
   gst_query_parse_duration (query, &format, NULL);
@@ -355,8 +397,6 @@ gst_adder_query_duration (GstAdder * adder, GstQuery * query)
   while (!done) {
     GstIteratorResult ires;
 
-    gpointer item;
-
     ires = gst_iterator_next (it, &item);
     switch (ires) {
       case GST_ITERATOR_DONE:
@@ -364,8 +404,7 @@ gst_adder_query_duration (GstAdder * adder, GstQuery * query)
         break;
       case GST_ITERATOR_OK:
       {
-        GstPad *pad = GST_PAD_CAST (item);
-
+        GstPad *pad = g_value_get_object (&item);
         gint64 duration;
 
         /* ask sink peer for duration */
@@ -381,7 +420,7 @@ gst_adder_query_duration (GstAdder * adder, GstQuery * query)
           else if (duration > max)
             max = duration;
         }
-        gst_object_unref (pad);
+        g_value_reset (&item);
         break;
       }
       case GST_ITERATOR_RESYNC:
@@ -395,6 +434,7 @@ gst_adder_query_duration (GstAdder * adder, GstQuery * query)
         break;
     }
   }
+  g_value_unset (&item);
   gst_iterator_free (it);
 
   if (res) {
@@ -415,6 +455,7 @@ gst_adder_query_latency (GstAdder * adder, GstQuery * query)
   gboolean res;
   GstIterator *it;
   gboolean done;
+  GValue item = { 0, };
 
   res = TRUE;
   done = FALSE;
@@ -428,8 +469,6 @@ gst_adder_query_latency (GstAdder * adder, GstQuery * query)
   while (!done) {
     GstIteratorResult ires;
 
-    gpointer item;
-
     ires = gst_iterator_next (it, &item);
     switch (ires) {
       case GST_ITERATOR_DONE:
@@ -437,7 +476,7 @@ gst_adder_query_latency (GstAdder * adder, GstQuery * query)
         break;
       case GST_ITERATOR_OK:
       {
-        GstPad *pad = GST_PAD_CAST (item);
+        GstPad *pad = g_value_get_object (&item);
         GstQuery *peerquery;
         GstClockTime min_cur, max_cur;
         gboolean live_cur;
@@ -463,7 +502,7 @@ gst_adder_query_latency (GstAdder * adder, GstQuery * query)
         }
 
         gst_query_unref (peerquery);
-        gst_object_unref (pad);
+        g_value_reset (&item);
         break;
       }
       case GST_ITERATOR_RESYNC:
@@ -479,6 +518,7 @@ gst_adder_query_latency (GstAdder * adder, GstQuery * query)
         break;
     }
   }
+  g_value_unset (&item);
   gst_iterator_free (it);
 
   if (res) {
@@ -508,7 +548,7 @@ gst_adder_query (GstPad * pad, GstQuery * query)
       switch (format) {
         case GST_FORMAT_TIME:
           /* FIXME, bring to stream time, might be tricky */
-          gst_query_set_position (query, format, adder->timestamp);
+          gst_query_set_position (query, format, adder->segment.position);
           res = TRUE;
           break;
         case GST_FORMAT_DEFAULT:
@@ -544,8 +584,9 @@ typedef struct
 } EventData;
 
 static gboolean
-forward_event_func (GstPad * pad, GValue * ret, EventData * data)
+forward_event_func (const GValue * val, GValue * ret, EventData * data)
 {
+  GstPad *pad = g_value_get_object (val);
   GstEvent *event = data->event;
 
   gst_event_ref (event);
@@ -562,7 +603,6 @@ forward_event_func (GstPad * pad, GValue * ret, EventData * data)
     GST_LOG_OBJECT (pad, "Sent event  %p (%s).",
         event, GST_EVENT_TYPE_NAME (event));
   }
-  gst_object_unref (pad);
 
   /* continue on other pads, even if one failed */
   return TRUE;
@@ -593,7 +633,8 @@ forward_event (GstAdder * adder, GstEvent * event, gboolean flush)
   g_value_set_boolean (&vret, FALSE);
   it = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (adder));
   while (TRUE) {
-    ires = gst_iterator_fold (it, (GstIteratorFoldFunction) forward_event_func,
+    ires =
+        gst_iterator_fold (it, (GstIteratorFoldFunction) forward_event_func,
         &vret, &data);
     switch (ires) {
       case GST_ITERATOR_RESYNC:
@@ -631,12 +672,13 @@ gst_adder_src_event (GstPad * pad, GstEvent * event)
     case GST_EVENT_SEEK:
     {
       GstSeekFlags flags;
+      gdouble rate;
       GstSeekType curtype, endtype;
       gint64 cur, end;
       gboolean flush;
 
       /* parse the seek parameters */
-      gst_event_parse_seek (event, &adder->segment_rate, NULL, &flags, &curtype,
+      gst_event_parse_seek (event, &rate, NULL, &flags, &curtype,
           &cur, &endtype, &end);
 
       if ((curtype != GST_SEEK_TYPE_NONE) && (curtype != GST_SEEK_TYPE_SET)) {
@@ -677,14 +719,15 @@ gst_adder_src_event (GstPad * pad, GstEvent * event)
        * segment. After we have the lock, no collect function is running and no
        * new collect function will be called for as long as we're flushing. */
       GST_OBJECT_LOCK (adder->collect);
+      adder->segment.rate = rate;
       if (curtype == GST_SEEK_TYPE_SET)
-        adder->segment_start = cur;
+        adder->segment.start = cur;
       else
-        adder->segment_start = 0;
+        adder->segment.start = 0;
       if (endtype == GST_SEEK_TYPE_SET)
-        adder->segment_end = end;
+        adder->segment.stop = end;
       else
-        adder->segment_end = GST_CLOCK_TIME_NONE;
+        adder->segment.stop = GST_CLOCK_TIME_NONE;
       /* make sure we push a new segment, to inform about new basetime
        * see FIXME in gst_adder_collected() */
       adder->segment_pending = TRUE;
@@ -781,21 +824,6 @@ beach:
 }
 
 static void
-gst_adder_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_adder_src_template));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_adder_sink_template));
-  gst_element_class_set_details_simple (gstelement_class, "Adder",
-      "Generic/Audio",
-      "Add N audio channels together",
-      "Thomas Vander Stichele <thomas at apestaart dot org>");
-}
-
-static void
 gst_adder_class_init (GstAdderClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
@@ -817,6 +845,15 @@ gst_adder_class_init (GstAdderClass * klass)
           "object.", GST_TYPE_CAPS,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_adder_src_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_adder_sink_template));
+  gst_element_class_set_details_simple (gstelement_class, "Adder",
+      "Generic/Audio",
+      "Add N audio channels together",
+      "Thomas Vander Stichele <thomas at apestaart dot org>");
+
   gstelement_class->request_new_pad =
       GST_DEBUG_FUNCPTR (gst_adder_request_new_pad);
   gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_adder_release_pad);
@@ -824,7 +861,7 @@ gst_adder_class_init (GstAdderClass * klass)
 }
 
 static void
-gst_adder_init (GstAdder * adder, GstAdderClass * klass)
+gst_adder_init (GstAdder * adder)
 {
   GstPadTemplate *template;
 
@@ -930,7 +967,7 @@ gst_adder_get_property (GObject * object, guint prop_id, GValue * value,
 
 static GstPad *
 gst_adder_request_new_pad (GstElement * element, GstPadTemplate * templ,
-    const gchar * unused)
+    const gchar * unused, const GstCaps * caps)
 {
   gchar *name;
   GstAdder *adder;
@@ -1098,20 +1135,15 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
 
       GST_LOG_OBJECT (adder, "channel %p: preparing output buffer of %d bytes",
           collect_data, outsize);
-      /* make data and metadata writable, can simply return the inbuf when we
-       * are the only one referencing this buffer. If this is the last (and
-       * only) GAP buffer, it will automatically copy the GAP flag. */
-      outbuf = gst_buffer_make_writable (inbuf);
-      outdata = GST_BUFFER_DATA (outbuf);
-      gst_buffer_set_caps (outbuf, GST_PAD_CAPS (adder->srcpad));
+
+      outdata = gst_buffer_map (outbuf, NULL, NULL, GST_MAP_WRITE);
     } else {
       if (!is_gap) {
         /* we had a previous output buffer, mix this non-GAP buffer */
         guint8 *indata;
-        guint insize;
+        gsize insize;
 
-        indata = GST_BUFFER_DATA (inbuf);
-        insize = GST_BUFFER_SIZE (inbuf);
+        indata = gst_buffer_map (inbuf, &insize, NULL, GST_MAP_READ);
 
         /* all buffers should have outsize, there are no short buffers because we
          * asked for the max size above */
@@ -1123,6 +1155,7 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
         /* further buffers, need to add them */
         adder->func ((gpointer) outdata, (gpointer) indata,
             insize / adder->sample_size);
+        gst_buffer_unmap (inbuf, indata, insize);
       } else {
         /* skip gap buffer */
         GST_LOG_OBJECT (adder, "channel %p: skipping GAP buffer", collect_data);
@@ -1130,6 +1163,8 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
       gst_buffer_unref (inbuf);
     }
   }
+  if (outbuf)
+    gst_buffer_unmap (outbuf, outdata, outsize);
 
   if (outbuf == NULL) {
     /* no output buffer, reuse one of the GAP buffers then if we have one */
@@ -1153,20 +1188,19 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
      * event. We also adjust offset & timestamp acordingly.
      * This basically ignores all newsegments sent by upstream.
      */
-    event = gst_event_new_new_segment_full (FALSE, adder->segment_rate,
-        1.0, GST_FORMAT_TIME, adder->segment_start, adder->segment_end,
-        adder->segment_start);
-    if (adder->segment_rate > 0.0) {
-      adder->timestamp = adder->segment_start;
+    event = gst_event_new_segment (&adder->segment);
+
+    if (adder->segment.rate > 0.0) {
+      adder->segment.position = adder->segment.start;
     } else {
-      adder->timestamp = adder->segment_end;
+      adder->segment.position = adder->segment.stop;
     }
-    adder->offset = gst_util_uint64_scale (adder->timestamp,
+    adder->offset = gst_util_uint64_scale (adder->segment.position,
         adder->rate, GST_SECOND);
     GST_INFO_OBJECT (adder, "seg_start %" G_GUINT64_FORMAT ", seg_end %"
-        G_GUINT64_FORMAT, adder->segment_start, adder->segment_end);
+        G_GUINT64_FORMAT, adder->segment.start, adder->segment.stop);
     GST_INFO_OBJECT (adder, "timestamp %" G_GINT64_FORMAT ",new offset %"
-        G_GINT64_FORMAT, adder->timestamp, adder->offset);
+        G_GINT64_FORMAT, adder->segment.position, adder->offset);
 
     if (event) {
       if (!gst_pad_push_event (adder->srcpad, event)) {
@@ -1177,7 +1211,7 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
     } else {
       GST_WARNING_OBJECT (adder->srcpad, "Creating new segment event for "
           "start:%" G_GINT64_FORMAT "  end:%" G_GINT64_FORMAT " failed",
-          adder->segment_start, adder->segment_end);
+          adder->segment.start, adder->segment.stop);
     }
   }
 
@@ -1196,7 +1230,7 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
 
   /* for the next timestamp, use the sample counter, which will
    * never accumulate rounding errors */
-  if (adder->segment_rate > 0.0) {
+  if (adder->segment.rate > 0.0) {
     next_offset = adder->offset + outsize / adder->bps;
   } else {
     next_offset = adder->offset - outsize / adder->bps;
@@ -1205,20 +1239,20 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
 
 
   /* set timestamps on the output buffer */
-  if (adder->segment_rate > 0.0) {
-    GST_BUFFER_TIMESTAMP (outbuf) = adder->timestamp;
+  if (adder->segment.rate > 0.0) {
+    GST_BUFFER_TIMESTAMP (outbuf) = adder->segment.position;
     GST_BUFFER_OFFSET (outbuf) = adder->offset;
     GST_BUFFER_OFFSET_END (outbuf) = next_offset;
-    GST_BUFFER_DURATION (outbuf) = next_timestamp - adder->timestamp;
+    GST_BUFFER_DURATION (outbuf) = next_timestamp - adder->segment.position;
   } else {
     GST_BUFFER_TIMESTAMP (outbuf) = next_timestamp;
     GST_BUFFER_OFFSET (outbuf) = next_offset;
     GST_BUFFER_OFFSET_END (outbuf) = adder->offset;
-    GST_BUFFER_DURATION (outbuf) = adder->timestamp - next_timestamp;
+    GST_BUFFER_DURATION (outbuf) = adder->segment.position - next_timestamp;
   }
 
   adder->offset = next_offset;
-  adder->timestamp = next_timestamp;
+  adder->segment.position = next_timestamp;
 
   /* send it out */
   GST_LOG_OBJECT (adder, "pushing outbuf %p, timestamp %" GST_TIME_FORMAT
@@ -1258,14 +1292,11 @@ gst_adder_change_state (GstElement * element, GstStateChange transition)
     case GST_STATE_CHANGE_NULL_TO_READY:
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
-      adder->timestamp = 0;
+      adder->segment.position = 0;
       adder->offset = 0;
       adder->flush_stop_pending = FALSE;
       adder->segment_pending = TRUE;
-      adder->segment_start = 0;
-      adder->segment_end = GST_CLOCK_TIME_NONE;
-      adder->segment_rate = 1.0;
-      gst_segment_init (&adder->segment, GST_FORMAT_UNDEFINED);
+      gst_segment_init (&adder->segment, GST_FORMAT_TIME);
       gst_collect_pads_start (adder->collect);
       break;
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
index f0151b4..d72c162 100644 (file)
@@ -79,15 +79,12 @@ struct _GstAdder {
   GstAdderFunction func;
 
   /* counters to keep track of timestamps */
-  gint64          timestamp;
   gint64          offset;
 
   /* sink event handling */
   GstPadEventFunction  collect_event;
   GstSegment      segment;
   gboolean        segment_pending;
-  guint64         segment_start, segment_end;
-  gdouble         segment_rate;
   /* src event handling */
   gboolean        flush_stop_pending;
   
index 188c191..3c7084d 100644 (file)
@@ -76,9 +76,9 @@ static void gst_audio_convert_dispose (GObject * obj);
 
 /* gstreamer functions */
 static gboolean gst_audio_convert_get_unit_size (GstBaseTransform * base,
-    GstCaps * caps, guint * size);
+    GstCaps * caps, gsize * size);
 static GstCaps *gst_audio_convert_transform_caps (GstBaseTransform * base,
-    GstPadDirection direction, GstCaps * caps);
+    GstPadDirection direction, GstCaps * caps, GstCaps * filter);
 static void gst_audio_convert_fixate_caps (GstBaseTransform * base,
     GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
 static gboolean gst_audio_convert_set_caps (GstBaseTransform * base,
@@ -108,11 +108,11 @@ enum
   ARG_NOISE_SHAPING,
 };
 
-#define DEBUG_INIT(bla) \
+#define DEBUG_INIT \
   GST_DEBUG_CATEGORY_INIT (audio_convert_debug, "audioconvert", 0, "audio conversion element"); \
   GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
-
-GST_BOILERPLATE_FULL (GstAudioConvert, gst_audio_convert, GstBaseTransform,
+#define gst_audio_convert_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstAudioConvert, gst_audio_convert,
     GST_TYPE_BASE_TRANSFORM, DEBUG_INIT);
 
 /*** GSTREAMER PROTOTYPES *****************************************************/
@@ -215,25 +215,11 @@ gst_audio_convert_ns_get_type (void)
 
 
 /*** TYPE FUNCTIONS ***********************************************************/
-
-static void
-gst_audio_convert_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_audio_convert_src_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_audio_convert_sink_template));
-  gst_element_class_set_details_simple (element_class,
-      "Audio converter", "Filter/Converter/Audio",
-      "Convert audio to different formats", "Benjamin Otte <otte@gnome.org>");
-}
-
 static void
 gst_audio_convert_class_init (GstAudioConvertClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
   GstBaseTransformClass *basetransform_class = GST_BASE_TRANSFORM_CLASS (klass);
 
   gobject_class->dispose = gst_audio_convert_dispose;
@@ -252,6 +238,14 @@ gst_audio_convert_class_init (GstAudioConvertClass * klass)
           GST_TYPE_AUDIO_CONVERT_NOISE_SHAPING, NOISE_SHAPING_NONE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_audio_convert_src_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_audio_convert_sink_template));
+  gst_element_class_set_details_simple (element_class,
+      "Audio converter", "Filter/Converter/Audio",
+      "Convert audio to different formats", "Benjamin Otte <otte@gnome.org>");
+
   basetransform_class->get_unit_size =
       GST_DEBUG_FUNCPTR (gst_audio_convert_get_unit_size);
   basetransform_class->transform_caps =
@@ -269,7 +263,7 @@ gst_audio_convert_class_init (GstAudioConvertClass * klass)
 }
 
 static void
-gst_audio_convert_init (GstAudioConvert * this, GstAudioConvertClass * g_class)
+gst_audio_convert_init (GstAudioConvert * this)
 {
   this->dither = DITHER_TPDF;
   this->ns = NOISE_SHAPING_NONE;
@@ -361,7 +355,7 @@ not_allowed:
 /* BaseTransform vmethods */
 static gboolean
 gst_audio_convert_get_unit_size (GstBaseTransform * base, GstCaps * caps,
-    guint * size)
+    gsize * size)
 {
   AudioConvertFmt fmt = { 0 };
 
@@ -563,7 +557,7 @@ structure_has_fixed_channel_positions (GstStructure * s,
  */
 static GstCaps *
 gst_audio_convert_transform_caps (GstBaseTransform * base,
-    GstPadDirection direction, GstCaps * caps)
+    GstPadDirection direction, GstCaps * caps, GstCaps * filter)
 {
   GstCaps *ret;
   GstStructure *s, *structure;
@@ -704,6 +698,17 @@ gst_audio_convert_transform_caps (GstBaseTransform * base,
 
   GST_DEBUG_OBJECT (base, "Caps transformed to %" GST_PTR_FORMAT, ret);
 
+  if (filter) {
+    GstCaps *intersection;
+
+    GST_DEBUG_OBJECT (base, "Using filter caps %" GST_PTR_FORMAT, filter);
+    intersection =
+        gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (ret);
+    ret = intersection;
+    GST_DEBUG_OBJECT (base, "Intersection %" GST_PTR_FORMAT, ret);
+  }
+
   return ret;
 }
 
@@ -1069,17 +1074,15 @@ static GstFlowReturn
 gst_audio_convert_transform (GstBaseTransform * base, GstBuffer * inbuf,
     GstBuffer * outbuf)
 {
+  GstFlowReturn ret;
   GstAudioConvert *this = GST_AUDIO_CONVERT (base);
+  gsize srcsize, dstsize;
   gint insize, outsize;
   gint samples;
   gpointer src, dst;
 
-  GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, base, "converting audio from %"
-      GST_PTR_FORMAT " to %" GST_PTR_FORMAT, GST_BUFFER_CAPS (inbuf),
-      GST_BUFFER_CAPS (outbuf));
-
   /* get amount of samples to convert. */
-  samples = GST_BUFFER_SIZE (inbuf) / this->ctx.in.unit_size;
+  samples = gst_buffer_get_size (inbuf) / this->ctx.in.unit_size;
 
   /* get in/output sizes, to see if the buffers we got are of correct
    * sizes */
@@ -1089,16 +1092,16 @@ gst_audio_convert_transform (GstBaseTransform * base, GstBuffer * inbuf,
   if (insize == 0 || outsize == 0)
     return GST_FLOW_OK;
 
+  /* get src and dst data */
+  src = gst_buffer_map (inbuf, &srcsize, NULL, GST_MAP_READ);
+  dst = gst_buffer_map (outbuf, &dstsize, NULL, GST_MAP_WRITE);
+
   /* check in and outsize */
-  if (GST_BUFFER_SIZE (inbuf) < insize)
+  if (srcsize < insize)
     goto wrong_size;
-  if (GST_BUFFER_SIZE (outbuf) < outsize)
+  if (dstsize < outsize)
     goto wrong_size;
 
-  /* get src and dst data */
-  src = GST_BUFFER_DATA (inbuf);
-  dst = GST_BUFFER_DATA (outbuf);
-
   /* and convert the samples */
   if (!GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP)) {
     if (!audio_convert_convert (&this->ctx, src, dst,
@@ -1108,10 +1111,13 @@ gst_audio_convert_transform (GstBaseTransform * base, GstBuffer * inbuf,
     /* Create silence buffer */
     gst_audio_convert_create_silence_buffer (this, dst, outsize);
   }
+  ret = GST_FLOW_OK;
 
-  GST_BUFFER_SIZE (outbuf) = outsize;
+done:
+  gst_buffer_unmap (outbuf, dst, outsize);
+  gst_buffer_unmap (inbuf, src, srcsize);
 
-  return GST_FLOW_OK;
+  return ret;
 
   /* ERRORS */
 error:
@@ -1125,15 +1131,16 @@ wrong_size:
     GST_ELEMENT_ERROR (this, STREAM, FORMAT,
         (NULL),
         ("input/output buffers are of wrong size in: %d < %d or out: %d < %d",
-            GST_BUFFER_SIZE (inbuf), insize, GST_BUFFER_SIZE (outbuf),
-            outsize));
-    return GST_FLOW_ERROR;
+            srcsize, insize, dstsize, outsize));
+    ret = GST_FLOW_ERROR;
+    goto done;
   }
 convert_error:
   {
     GST_ELEMENT_ERROR (this, STREAM, FORMAT,
         (NULL), ("error while converting"));
-    return GST_FLOW_ERROR;
+    ret = GST_FLOW_ERROR;
+    goto done;
   }
 }
 
index 40d3467..79ac544 100644 (file)
@@ -108,9 +108,6 @@ static GstStaticPadTemplate gst_audio_rate_sink_template =
         GST_AUDIO_FLOAT_PAD_TEMPLATE_CAPS)
     );
 
-static void gst_audio_rate_base_init (gpointer g_class);
-static void gst_audio_rate_class_init (GstAudioRateClass * klass);
-static void gst_audio_rate_init (GstAudioRate * audiorate);
 static gboolean gst_audio_rate_sink_event (GstPad * pad, GstEvent * event);
 static gboolean gst_audio_rate_src_event (GstPad * pad, GstEvent * event);
 static GstFlowReturn gst_audio_rate_chain (GstPad * pad, GstBuffer * buf);
@@ -123,53 +120,13 @@ static void gst_audio_rate_get_property (GObject * object,
 static GstStateChangeReturn gst_audio_rate_change_state (GstElement * element,
     GstStateChange transition);
 
-static GstElementClass *parent_class = NULL;
-
 /*static guint gst_audio_rate_signals[LAST_SIGNAL] = { 0 }; */
 
 static GParamSpec *pspec_drop = NULL;
 static GParamSpec *pspec_add = NULL;
 
-static GType
-gst_audio_rate_get_type (void)
-{
-  static GType audio_rate_type = 0;
-
-  if (!audio_rate_type) {
-    static const GTypeInfo audio_rate_info = {
-      sizeof (GstAudioRateClass),
-      gst_audio_rate_base_init,
-      NULL,
-      (GClassInitFunc) gst_audio_rate_class_init,
-      NULL,
-      NULL,
-      sizeof (GstAudioRate),
-      0,
-      (GInstanceInitFunc) gst_audio_rate_init,
-    };
-
-    audio_rate_type = g_type_register_static (GST_TYPE_ELEMENT,
-        "GstAudioRate", &audio_rate_info, 0);
-  }
-
-  return audio_rate_type;
-}
-
-static void
-gst_audio_rate_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class,
-      "Audio rate adjuster", "Filter/Effect/Audio",
-      "Drops/duplicates/adjusts timestamps on audio samples to make a perfect stream",
-      "Wim Taymans <wim@fluendo.com>");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_audio_rate_sink_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_audio_rate_src_template));
-}
+#define gst_audio_rate_parent_class parent_class
+G_DEFINE_TYPE (GstAudioRate, gst_audio_rate, GST_TYPE_ELEMENT);
 
 static void
 gst_audio_rate_class_init (GstAudioRateClass * klass)
@@ -177,8 +134,6 @@ gst_audio_rate_class_init (GstAudioRateClass * klass)
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
-  parent_class = g_type_class_peek_parent (klass);
-
   object_class->set_property = gst_audio_rate_set_property;
   object_class->get_property = gst_audio_rate_get_property;
 
@@ -225,6 +180,16 @@ gst_audio_rate_class_init (GstAudioRateClass * klass)
           "Don't produce buffers before the first one we receive",
           DEFAULT_SKIP_TO_FIRST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (element_class,
+      "Audio rate adjuster", "Filter/Effect/Audio",
+      "Drops/duplicates/adjusts timestamps on audio samples to make a perfect stream",
+      "Wim Taymans <wim@fluendo.com>");
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_audio_rate_sink_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_audio_rate_src_template));
+
   element_class->change_state = gst_audio_rate_change_state;
 }
 
@@ -349,41 +314,35 @@ gst_audio_rate_sink_event (GstPad * pad, GstEvent * event)
       gst_audio_rate_reset (audiorate);
       res = gst_pad_push_event (audiorate->srcpad, event);
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      GstFormat format;
-      gdouble rate, arate;
-      gint64 start, stop, time;
-      gboolean update;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-          &start, &stop, &time);
+      gst_event_copy_segment (event, &audiorate->sink_segment);
 
       GST_DEBUG_OBJECT (audiorate, "handle NEWSEGMENT");
+#if 0
       /* FIXME: bad things will likely happen if rate < 0 ... */
       if (!update) {
         /* a new segment starts. We need to figure out what will be the next
          * sample offset. We mark the offsets as invalid so that the _chain
          * function will perform this calculation. */
         gst_audio_rate_fill_to_time (audiorate, audiorate->src_segment.stop);
+#endif
         audiorate->next_offset = -1;
         audiorate->next_ts = -1;
+#if 0
       } else {
         gst_audio_rate_fill_to_time (audiorate, audiorate->src_segment.start);
       }
-
-      /* we accept all formats */
-      gst_segment_set_newsegment_full (&audiorate->sink_segment, update, rate,
-          arate, format, start, stop, time);
+#endif
 
       GST_DEBUG_OBJECT (audiorate, "updated segment: %" GST_SEGMENT_FORMAT,
           &audiorate->sink_segment);
 
-      if (format == GST_FORMAT_TIME) {
+      if (audiorate->sink_segment.format == GST_FORMAT_TIME) {
         /* TIME formats can be copied to src and forwarded */
         res = gst_pad_push_event (audiorate->srcpad, event);
-        memcpy (&audiorate->src_segment, &audiorate->sink_segment,
-            sizeof (GstSegment));
+        gst_segment_copy_into (&audiorate->sink_segment,
+            &audiorate->src_segment);
       } else {
         /* other formats will be handled in the _chain function */
         gst_event_unref (event);
@@ -428,7 +387,7 @@ gst_audio_rate_src_event (GstPad * pad, GstEvent * event)
 
 static gboolean
 gst_audio_rate_convert (GstAudioRate * audiorate,
-    GstFormat src_fmt, gint64 src_val, GstFormat dest_fmt, gint64 * dest_val)
+    GstFormat src_fmt, guint64 src_val, GstFormat dest_fmt, guint64 * dest_val)
 {
   if (src_fmt == dest_fmt) {
     *dest_val = src_val;
@@ -496,14 +455,13 @@ gst_audio_rate_convert_segments (GstAudioRate * audiorate)
                dst_fmt, &audiorate->src_segment.field);
 
   audiorate->sink_segment.rate = audiorate->src_segment.rate;
-  audiorate->sink_segment.abs_rate = audiorate->src_segment.abs_rate;
   audiorate->sink_segment.flags = audiorate->src_segment.flags;
   audiorate->sink_segment.applied_rate = audiorate->src_segment.applied_rate;
   CONVERT_VAL (start);
   CONVERT_VAL (stop);
   CONVERT_VAL (time);
-  CONVERT_VAL (accum);
-  CONVERT_VAL (last_stop);
+  CONVERT_VAL (base);
+  CONVERT_VAL (position);
 #undef CONVERT_VAL
 
   return TRUE;
@@ -589,7 +547,7 @@ gst_audio_rate_chain (GstPad * pad, GstBuffer * buf)
     in_time = audiorate->next_ts;
   }
 
-  in_size = GST_BUFFER_SIZE (buf);
+  in_size = gst_buffer_get_size (buf);
   in_samples = in_size / audiorate->bytes_per_sample;
 
   /* calculate the buffer offset */
@@ -633,13 +591,17 @@ gst_audio_rate_chain (GstPad * pad, GstBuffer * buf)
 
     while (fillsamples > 0) {
       guint64 cursamples = MIN (fillsamples, audiorate->rate);
+      guint8 *data;
 
       fillsamples -= cursamples;
       fillsize = cursamples * audiorate->bytes_per_sample;
 
       fill = gst_buffer_new_and_alloc (fillsize);
+
+      data = gst_buffer_map (fill, NULL, NULL, GST_MAP_WRITE);
       /* FIXME, 0 might not be the silence byte for the negotiated format. */
-      memset (GST_BUFFER_DATA (fill), 0, fillsize);
+      memset (data, 0, fillsize);
+      gst_buffer_unmap (fill, data, fillsize);
 
       GST_DEBUG_OBJECT (audiorate, "inserting %" G_GUINT64_FORMAT " samples",
           cursamples);
@@ -665,7 +627,6 @@ gst_audio_rate_chain (GstPad * pad, GstBuffer * buf)
         GST_BUFFER_FLAG_SET (fill, GST_BUFFER_FLAG_DISCONT);
         audiorate->discont = FALSE;
       }
-      gst_buffer_set_caps (fill, GST_PAD_CAPS (audiorate->srcpad));
 
       ret = gst_pad_push (audiorate->srcpad, fill);
       if (ret != GST_FLOW_OK)
@@ -705,13 +666,13 @@ gst_audio_rate_chain (GstPad * pad, GstBuffer * buf)
       truncsize = truncsamples * audiorate->bytes_per_sample;
       leftsize = in_size - truncsize;
 
-      trunc = gst_buffer_create_sub (buf, truncsize, leftsize);
+      trunc =
+          gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, truncsize,
+          leftsize);
 
       gst_buffer_unref (buf);
       buf = trunc;
 
-      gst_buffer_set_caps (buf, GST_PAD_CAPS (audiorate->srcpad));
-
       audiorate->drop += truncsamples;
       GST_DEBUG_OBJECT (audiorate, "truncating %" G_GUINT64_FORMAT " samples",
           truncsamples);
@@ -722,7 +683,7 @@ gst_audio_rate_chain (GstPad * pad, GstBuffer * buf)
   }
 
 send:
-  if (GST_BUFFER_SIZE (buf) == 0)
+  if (gst_buffer_get_size (buf) == 0)
     goto beach;
 
   /* Now calculate parameters for whichever buffer (either the original
@@ -738,20 +699,20 @@ send:
   if (audiorate->discont) {
     /* we need to output a discont buffer, do so now */
     GST_DEBUG_OBJECT (audiorate, "marking DISCONT on output buffer");
-    buf = gst_buffer_make_metadata_writable (buf);
+    buf = gst_buffer_make_writable (buf);
     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
     audiorate->discont = FALSE;
   } else if (GST_BUFFER_IS_DISCONT (buf)) {
     /* else we make everything continuous so we can safely remove the DISCONT
      * flag from the buffer if there was one */
     GST_DEBUG_OBJECT (audiorate, "removing DISCONT from buffer");
-    buf = gst_buffer_make_metadata_writable (buf);
+    buf = gst_buffer_make_writable (buf);
     GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
   }
 
   /* set last_stop on segment */
-  gst_segment_set_last_stop (&audiorate->src_segment, GST_FORMAT_TIME,
-      GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf));
+  audiorate->src_segment.position =
+      GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
 
   ret = gst_pad_push (audiorate->srcpad, buf);
   buf = NULL;
@@ -854,10 +815,7 @@ gst_audio_rate_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
-  if (parent_class->change_state)
-    return parent_class->change_state (element, transition);
-
-  return GST_STATE_CHANGE_SUCCESS;
+  return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 }
 
 static gboolean
index e55bbcf..f2eafcf 100644 (file)
@@ -78,6 +78,8 @@ struct _GstAudioRateClass
   GstElementClass parent_class;
 };
 
+GType gst_audio_rate_get_type (void);
+
 G_END_DECLS
 
 #endif /* __GST_AUDIO_RATE_H__ */
index 9364a86..6839c4d 100644 (file)
@@ -62,8 +62,7 @@ GST_DEBUG_CATEGORY (audio_resample_debug);
 enum
 {
   PROP_0,
-  PROP_QUALITY,
-  PROP_FILTER_LENGTH
+  PROP_QUALITY
 };
 
 #define SUPPORTED_CAPS \
@@ -127,14 +126,14 @@ static void gst_audio_resample_get_property (GObject * object,
 
 /* vmethods */
 static gboolean gst_audio_resample_get_unit_size (GstBaseTransform * base,
-    GstCaps * caps, guint * size);
+    GstCaps * caps, gsize * size);
 static GstCaps *gst_audio_resample_transform_caps (GstBaseTransform * base,
-    GstPadDirection direction, GstCaps * caps);
+    GstPadDirection direction, GstCaps * caps, GstCaps * filter);
 static void gst_audio_resample_fixate_caps (GstBaseTransform * base,
     GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
 static gboolean gst_audio_resample_transform_size (GstBaseTransform * trans,
-    GstPadDirection direction, GstCaps * incaps, guint insize,
-    GstCaps * outcaps, guint * outsize);
+    GstPadDirection direction, GstCaps * incaps, gsize insize,
+    GstCaps * outcaps, gsize * outsize);
 static gboolean gst_audio_resample_set_caps (GstBaseTransform * base,
     GstCaps * incaps, GstCaps * outcaps);
 static GstFlowReturn gst_audio_resample_transform (GstBaseTransform * base,
@@ -146,28 +145,14 @@ static gboolean gst_audio_resample_stop (GstBaseTransform * base);
 static gboolean gst_audio_resample_query (GstPad * pad, GstQuery * query);
 static const GstQueryType *gst_audio_resample_query_type (GstPad * pad);
 
-GST_BOILERPLATE (GstAudioResample, gst_audio_resample, GstBaseTransform,
-    GST_TYPE_BASE_TRANSFORM);
-
-static void
-gst_audio_resample_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_audio_resample_src_template));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_audio_resample_sink_template));
-
-  gst_element_class_set_details_simple (gstelement_class, "Audio resampler",
-      "Filter/Converter/Audio", "Resamples audio",
-      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
+#define gst_audio_resample_parent_class parent_class
+G_DEFINE_TYPE (GstAudioResample, gst_audio_resample, GST_TYPE_BASE_TRANSFORM);
 
 static void
 gst_audio_resample_class_init (GstAudioResampleClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstElementClass *gstelement_class = (GstElementClass *) klass;
 
   gobject_class->set_property = gst_audio_resample_set_property;
   gobject_class->get_property = gst_audio_resample_get_property;
@@ -179,20 +164,14 @@ gst_audio_resample_class_init (GstAudioResampleClass * klass)
           SPEEX_RESAMPLER_QUALITY_DEFAULT,
           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
 
-  /* FIXME 0.11: Remove this property, it's just for compatibility
-   * with old audioresample
-   */
-  /**
-   * GstAudioResample:filter-length:
-   *
-   * Length of the resample filter
-   *
-   * Deprectated: Use #GstAudioResample:quality property instead
-   */
-  g_object_class_install_property (gobject_class, PROP_FILTER_LENGTH,
-      g_param_spec_int ("filter-length", "Filter length",
-          "Length of the resample filter", 0, G_MAXINT, 64,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_audio_resample_src_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_audio_resample_sink_template));
+
+  gst_element_class_set_details_simple (gstelement_class, "Audio resampler",
+      "Filter/Converter/Audio", "Resamples audio",
+      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
 
   GST_BASE_TRANSFORM_CLASS (klass)->start =
       GST_DEBUG_FUNCPTR (gst_audio_resample_start);
@@ -217,8 +196,7 @@ gst_audio_resample_class_init (GstAudioResampleClass * klass)
 }
 
 static void
-gst_audio_resample_init (GstAudioResample * resample,
-    GstAudioResampleClass * klass)
+gst_audio_resample_init (GstAudioResample * resample)
 {
   GstBaseTransform *trans = GST_BASE_TRANSFORM (resample);
 
@@ -282,7 +260,7 @@ gst_audio_resample_stop (GstBaseTransform * base)
 
 static gboolean
 gst_audio_resample_get_unit_size (GstBaseTransform * base, GstCaps * caps,
-    guint * size)
+    gsize * size)
 {
   gint width, channels;
   GstStructure *structure;
@@ -305,7 +283,7 @@ gst_audio_resample_get_unit_size (GstBaseTransform * base, GstCaps * caps,
 
 static GstCaps *
 gst_audio_resample_transform_caps (GstBaseTransform * base,
-    GstPadDirection direction, GstCaps * caps)
+    GstPadDirection direction, GstCaps * caps, GstCaps * filter)
 {
   const GValue *val;
   GstStructure *s;
@@ -336,6 +314,15 @@ gst_audio_resample_transform_caps (GstBaseTransform * base,
     gst_caps_append_structure (res, s);
   }
 
+  if (filter) {
+    GstCaps *intersection;
+
+    intersection =
+        gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (res);
+    res = intersection;
+  }
+
   return res;
 }
 
@@ -530,8 +517,8 @@ _gcd (gint a, gint b)
 
 static gboolean
 gst_audio_resample_transform_size (GstBaseTransform * base,
-    GstPadDirection direction, GstCaps * caps, guint size, GstCaps * othercaps,
-    guint * othersize)
+    GstPadDirection direction, GstCaps * caps, gsize size, GstCaps * othercaps,
+    gsize * othersize)
 {
   gboolean ret = TRUE;
   guint32 ratio_den, ratio_num;
@@ -824,6 +811,7 @@ gst_audio_resample_push_drain (GstAudioResample * resample, guint history_len)
   guint out_len, out_processed;
   gint err;
   guint num, den;
+  guint8 *data;
 
   g_assert (resample->state != NULL);
 
@@ -841,15 +829,9 @@ gst_audio_resample_push_drain (GstAudioResample * resample, guint history_len)
   if (out_len == 0)
     return;
 
-  res =
-      gst_pad_alloc_buffer_and_set_caps (GST_BASE_TRANSFORM_SRC_PAD (resample),
-      GST_BUFFER_OFFSET_NONE, outsize,
-      GST_PAD_CAPS (GST_BASE_TRANSFORM_SRC_PAD (resample)), &outbuf);
-  if (G_UNLIKELY (res != GST_FLOW_OK)) {
-    GST_WARNING_OBJECT (resample, "failed allocating buffer of %d bytes",
-        outsize);
-    return;
-  }
+  outbuf = gst_buffer_new_and_alloc (outsize);
+
+  data = gst_buffer_map (outbuf, NULL, NULL, GST_MAP_WRITE);
 
   if (resample->funcs->width != resample->width) {
     /* need to convert data format;  allocate workspace */
@@ -866,17 +848,20 @@ gst_audio_resample_push_drain (GstAudioResample * resample, guint history_len)
 
     /* convert output format */
     gst_audio_resample_convert_buffer (resample, resample->tmp_out,
-        GST_BUFFER_DATA (outbuf), out_processed, TRUE);
+        data, out_processed, TRUE);
   } else {
     /* don't need to convert data format;  process */
     err = resample->funcs->process (resample->state, NULL, &in_processed,
-        GST_BUFFER_DATA (outbuf), &out_processed);
+        data, &out_processed);
   }
 
   /* If we wrote more than allocated something is really wrong now
    * and we should better abort immediately */
   g_assert (out_len >= out_processed);
 
+  outsize = out_processed * resample->channels * (resample->width / 8);
+  gst_buffer_unmap (outbuf, data, outsize);
+
   if (G_UNLIKELY (err != RESAMPLER_ERR_SUCCESS)) {
     GST_WARNING_OBJECT (resample, "Failed to process drain: %s",
         resample->funcs->strerror (err));
@@ -914,13 +899,10 @@ gst_audio_resample_push_drain (GstAudioResample * resample, guint history_len)
     return;
   }
 
-  GST_BUFFER_SIZE (outbuf) =
-      out_processed * resample->channels * (resample->width / 8);
-
   GST_LOG_OBJECT (resample,
       "Pushing drain buffer of %u bytes with timestamp %" GST_TIME_FORMAT
       " duration %" GST_TIME_FORMAT " offset %" G_GUINT64_FORMAT " offset_end %"
-      G_GUINT64_FORMAT, GST_BUFFER_SIZE (outbuf),
+      G_GUINT64_FORMAT, outsize,
       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
       GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)), GST_BUFFER_OFFSET (outbuf),
       GST_BUFFER_OFFSET_END (outbuf));
@@ -953,7 +935,7 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event)
       resample->samples_out = 0;
       resample->need_discont = TRUE;
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
       if (resample->state) {
         guint latency = resample->funcs->get_input_latency (resample->state);
         gst_audio_resample_push_drain (resample, latency);
@@ -981,7 +963,7 @@ gst_audio_resample_event (GstBaseTransform * base, GstEvent * event)
       break;
   }
 
-  return parent_class->event (base, event);
+  return GST_BASE_TRANSFORM_CLASS (parent_class)->event (base, event);
 }
 
 static gboolean
@@ -1025,12 +1007,17 @@ static GstFlowReturn
 gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf,
     GstBuffer * outbuf)
 {
+  gsize in_size, out_size;
+  guint8 *in_data, *out_data;
   guint32 in_len, in_processed;
   guint32 out_len, out_processed;
   guint filt_len = resample->funcs->get_filt_len (resample->state);
 
-  in_len = GST_BUFFER_SIZE (inbuf) / resample->channels;
-  out_len = GST_BUFFER_SIZE (outbuf) / resample->channels;
+  in_data = gst_buffer_map (inbuf, &in_size, NULL, GST_MAP_READ);
+  out_data = gst_buffer_map (outbuf, &out_size, NULL, GST_MAP_WRITE);
+
+  in_len = in_size / resample->channels;
+  out_len = out_size / resample->channels;
 
   in_len /= (resample->width / 8);
   out_len /= (resample->width / 8);
@@ -1062,7 +1049,7 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf,
       else
         out_processed = 0;
 
-      memset (GST_BUFFER_DATA (outbuf), 0, GST_BUFFER_SIZE (outbuf));
+      memset (out_data, 0, out_size);
       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
       resample->num_gap_samples += in_len;
       in_processed = in_len;
@@ -1095,11 +1082,13 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf,
               &resample->tmp_out_size, out_len * resample->channels *
               (resample->funcs->width / 8))) {
         GST_ERROR_OBJECT (resample, "failed to allocate workspace");
+        gst_buffer_unmap (inbuf, in_data, in_size);
+        gst_buffer_unmap (outbuf, out_data, out_size);
         return GST_FLOW_ERROR;
       }
 
       /* convert input */
-      gst_audio_resample_convert_buffer (resample, GST_BUFFER_DATA (inbuf),
+      gst_audio_resample_convert_buffer (resample, in_data,
           resample->tmp_in, in_len, FALSE);
 
       /* process */
@@ -1108,17 +1097,18 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf,
 
       /* convert output */
       gst_audio_resample_convert_buffer (resample, resample->tmp_out,
-          GST_BUFFER_DATA (outbuf), out_processed, TRUE);
+          out_data, out_processed, TRUE);
     } else {
       /* no format conversion required;  process */
       err = resample->funcs->process (resample->state,
-          GST_BUFFER_DATA (inbuf), &in_processed,
-          GST_BUFFER_DATA (outbuf), &out_processed);
+          in_data, &in_processed, out_data, &out_processed);
     }
 
     if (G_UNLIKELY (err != RESAMPLER_ERR_SUCCESS)) {
       GST_ERROR_OBJECT (resample, "Failed to convert data: %s",
           resample->funcs->strerror (err));
+      gst_buffer_unmap (inbuf, in_data, in_size);
+      gst_buffer_unmap (outbuf, out_data, out_size);
       return GST_FLOW_ERROR;
     }
   }
@@ -1156,14 +1146,15 @@ gst_audio_resample_process (GstAudioResample * resample, GstBuffer * inbuf,
   resample->samples_out += out_processed;
   resample->samples_in += in_len;
 
-  GST_BUFFER_SIZE (outbuf) =
-      out_processed * resample->channels * (resample->width / 8);
+  out_size = out_processed * resample->channels * (resample->width / 8);
+  gst_buffer_unmap (inbuf, in_data, in_size);
+  gst_buffer_unmap (outbuf, out_data, out_size);
 
   GST_LOG_OBJECT (resample,
       "Converted to buffer of %" G_GUINT32_FORMAT
       " samples (%u bytes) with timestamp %" GST_TIME_FORMAT ", duration %"
       GST_TIME_FORMAT ", offset %" G_GUINT64_FORMAT ", offset_end %"
-      G_GUINT64_FORMAT, out_processed, GST_BUFFER_SIZE (outbuf),
+      G_GUINT64_FORMAT, out_processed, out_size,
       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
       GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)),
       GST_BUFFER_OFFSET (outbuf), GST_BUFFER_OFFSET_END (outbuf));
@@ -1180,7 +1171,6 @@ gst_audio_resample_transform (GstBaseTransform * base, GstBuffer * inbuf,
     GstBuffer * outbuf)
 {
   GstAudioResample *resample = GST_AUDIO_RESAMPLE (base);
-  gulong size;
   GstFlowReturn ret;
 
   if (resample->state == NULL) {
@@ -1194,12 +1184,10 @@ gst_audio_resample_transform (GstBaseTransform * base, GstBuffer * inbuf,
         gst_audio_resample_get_funcs (resample->width, resample->fp);
   }
 
-  size = GST_BUFFER_SIZE (inbuf);
-
   GST_LOG_OBJECT (resample, "transforming buffer of %ld bytes, ts %"
       GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT ", offset %"
       G_GINT64_FORMAT ", offset_end %" G_GINT64_FORMAT,
-      size, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (inbuf)),
+      gst_buffer_get_size (inbuf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (inbuf)),
       GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)),
       GST_BUFFER_OFFSET (inbuf), GST_BUFFER_OFFSET_END (inbuf));
 
@@ -1360,41 +1348,6 @@ gst_audio_resample_set_property (GObject * object, guint prop_id,
           resample->quality, resample->fp);
       GST_BASE_TRANSFORM_UNLOCK (resample);
       break;
-    case PROP_FILTER_LENGTH:{
-      gint filter_length = g_value_get_int (value);
-
-      GST_BASE_TRANSFORM_LOCK (resample);
-      if (filter_length <= 8)
-        resample->quality = 0;
-      else if (filter_length <= 16)
-        resample->quality = 1;
-      else if (filter_length <= 32)
-        resample->quality = 2;
-      else if (filter_length <= 48)
-        resample->quality = 3;
-      else if (filter_length <= 64)
-        resample->quality = 4;
-      else if (filter_length <= 80)
-        resample->quality = 5;
-      else if (filter_length <= 96)
-        resample->quality = 6;
-      else if (filter_length <= 128)
-        resample->quality = 7;
-      else if (filter_length <= 160)
-        resample->quality = 8;
-      else if (filter_length <= 192)
-        resample->quality = 9;
-      else
-        resample->quality = 10;
-
-      GST_DEBUG_OBJECT (resample, "new quality %d", resample->quality);
-
-      gst_audio_resample_update_state (resample, resample->width,
-          resample->channels, resample->inrate, resample->outrate,
-          resample->quality, resample->fp);
-      GST_BASE_TRANSFORM_UNLOCK (resample);
-      break;
-    }
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1413,43 +1366,6 @@ gst_audio_resample_get_property (GObject * object, guint prop_id,
     case PROP_QUALITY:
       g_value_set_int (value, resample->quality);
       break;
-    case PROP_FILTER_LENGTH:
-      switch (resample->quality) {
-        case 0:
-          g_value_set_int (value, 8);
-          break;
-        case 1:
-          g_value_set_int (value, 16);
-          break;
-        case 2:
-          g_value_set_int (value, 32);
-          break;
-        case 3:
-          g_value_set_int (value, 48);
-          break;
-        case 4:
-          g_value_set_int (value, 64);
-          break;
-        case 5:
-          g_value_set_int (value, 80);
-          break;
-        case 6:
-          g_value_set_int (value, 96);
-          break;
-        case 7:
-          g_value_set_int (value, 128);
-          break;
-        case 8:
-          g_value_set_int (value, 160);
-          break;
-        case 9:
-          g_value_set_int (value, 192);
-          break;
-        case 10:
-          g_value_set_int (value, 256);
-          break;
-      }
-      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index ecbb2fb..5b1127a 100644 (file)
@@ -109,9 +109,8 @@ static GstStaticPadTemplate gst_audio_test_src_src_template =
         "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]")
     );
 
-
-GST_BOILERPLATE (GstAudioTestSrc, gst_audio_test_src, GstBaseSrc,
-    GST_TYPE_BASE_SRC);
+#define gst_audio_test_src_parent_class parent_class
+G_DEFINE_TYPE (GstAudioTestSrc, gst_audio_test_src, GST_TYPE_BASE_SRC);
 
 #define GST_TYPE_AUDIO_TEST_SRC_WAVE (gst_audiostestsrc_wave_get_type())
 static GType
@@ -167,27 +166,15 @@ static gboolean gst_audio_test_src_stop (GstBaseSrc * basesrc);
 static GstFlowReturn gst_audio_test_src_create (GstBaseSrc * basesrc,
     guint64 offset, guint length, GstBuffer ** buffer);
 
-
-static void
-gst_audio_test_src_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_audio_test_src_src_template));
-  gst_element_class_set_details_simple (element_class,
-      "Audio test source", "Source/Audio",
-      "Creates audio test signals of given frequency and volume",
-      "Stefan Kost <ensonic@users.sf.net>");
-}
-
 static void
 gst_audio_test_src_class_init (GstAudioTestSrcClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseSrcClass *gstbasesrc_class;
 
   gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
   gstbasesrc_class = (GstBaseSrcClass *) klass;
 
   gobject_class->set_property = gst_audio_test_src_set_property;
@@ -230,6 +217,13 @@ gst_audio_test_src_class_init (GstAudioTestSrcClass * klass)
           "Can activate in pull mode", DEFAULT_CAN_ACTIVATE_PULL,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_audio_test_src_src_template));
+  gst_element_class_set_details_simple (gstelement_class,
+      "Audio test source", "Source/Audio",
+      "Creates audio test signals of given frequency and volume",
+      "Stefan Kost <ensonic@users.sf.net>");
+
   gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_audio_test_src_setcaps);
   gstbasesrc_class->is_seekable =
       GST_DEBUG_FUNCPTR (gst_audio_test_src_is_seekable);
@@ -245,7 +239,7 @@ gst_audio_test_src_class_init (GstAudioTestSrcClass * klass)
 }
 
 static void
-gst_audio_test_src_init (GstAudioTestSrc * src, GstAudioTestSrcClass * g_class)
+gst_audio_test_src_init (GstAudioTestSrc * src)
 {
   GstPad *pad = GST_BASE_SRC_PAD (src);
 
@@ -966,7 +960,7 @@ gst_audio_test_src_do_seek (GstBaseSrc * basesrc, GstSegment * segment)
 
   GST_DEBUG_OBJECT (src, "seeking %" GST_SEGMENT_FORMAT, segment);
 
-  time = segment->last_stop;
+  time = segment->position;
   src->reverse = (segment->rate < 0.0);
 
   /* now move to the time indicated */
@@ -1027,13 +1021,13 @@ static GstFlowReturn
 gst_audio_test_src_create (GstBaseSrc * basesrc, guint64 offset,
     guint length, GstBuffer ** buffer)
 {
-  GstFlowReturn res;
   GstAudioTestSrc *src;
   GstBuffer *buf;
   GstClockTime next_time;
   gint64 next_sample, next_byte;
   gint bytes, samples;
   GstElementClass *eclass;
+  guint8 *data;
 
   src = GST_AUDIO_TEST_SRC (basesrc);
 
@@ -1097,10 +1091,7 @@ gst_audio_test_src_create (GstBaseSrc * basesrc, guint64 offset,
 
   bytes = src->generate_samples_per_buffer * src->sample_size * src->channels;
 
-  if ((res = gst_pad_alloc_buffer (basesrc->srcpad, src->next_sample,
-              bytes, GST_PAD_CAPS (basesrc->srcpad), &buf)) != GST_FLOW_OK) {
-    return res;
-  }
+  buf = gst_buffer_new_and_alloc (bytes);
 
   next_byte = src->next_byte + (src->reverse ? (-bytes) : bytes);
   next_time = gst_util_uint64_scale_int (next_sample, GST_SECOND,
@@ -1130,7 +1121,9 @@ gst_audio_test_src_create (GstBaseSrc * basesrc, guint64 offset,
       src->generate_samples_per_buffer,
       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
 
-  src->process (src, GST_BUFFER_DATA (buf));
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+  src->process (src, data);
+  gst_buffer_unmap (buf, data, bytes);
 
   if (G_UNLIKELY ((src->wave == GST_AUDIO_TEST_SRC_WAVE_SILENCE)
           || (src->volume == 0.0))) {
index d90e745..1631857 100644 (file)
@@ -306,7 +306,7 @@ gst_encode_bin_class_init (GstEncodeBinClass * klass)
    * to %GST_STATE_PAUSED or higher.
    */
   g_object_class_install_property (gobject_klass, PROP_PROFILE,
-      gst_param_spec_mini_object ("profile", "Profile",
+      g_param_spec_object ("profile", "Profile",
           "The GstEncodingProfile to use", GST_TYPE_ENCODING_PROFILE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
@@ -373,7 +373,7 @@ gst_encode_bin_class_init (GstEncodeBinClass * klass)
 
   gstelement_klass->change_state =
       GST_DEBUG_FUNCPTR (gst_encode_bin_change_state);
-  gstelement_klass->request_new_pad_full =
+  gstelement_klass->request_new_pad =
       GST_DEBUG_FUNCPTR (gst_encode_bin_request_new_pad);
   gstelement_klass->release_pad =
       GST_DEBUG_FUNCPTR (gst_encode_bin_release_pad);
@@ -463,7 +463,7 @@ gst_encode_bin_set_property (GObject * object, guint prop_id,
   switch (prop_id) {
     case PROP_PROFILE:
       gst_encode_bin_set_profile (ebin,
-          (GstEncodingProfile *) gst_value_get_mini_object (value));
+          (GstEncodingProfile *) g_value_get_object (value));
       break;
     case PROP_QUEUE_BUFFERS_MAX:
       ebin->queue_buffers_max = g_value_get_uint (value);
@@ -494,7 +494,7 @@ gst_encode_bin_get_property (GObject * object, guint prop_id,
 
   switch (prop_id) {
     case PROP_PROFILE:
-      gst_value_set_mini_object (value, (GstMiniObject *) ebin->profile);
+      g_value_set_object (value, (GObject *) ebin->profile);
       break;
     case PROP_QUEUE_BUFFERS_MAX:
       g_value_set_uint (value, ebin->queue_buffers_max);
@@ -827,7 +827,7 @@ beach:
 
 static GstPad *
 local_element_request_pad (GstElement * element, GstPadTemplate * templ,
-    const gchar * name)
+    const gchar * name, const GstCaps * caps)
 {
   GstPad *newpad = NULL;
   GstElementClass *oclass;
@@ -835,7 +835,7 @@ local_element_request_pad (GstElement * element, GstPadTemplate * templ,
   oclass = GST_ELEMENT_GET_CLASS (element);
 
   if (oclass->request_new_pad)
-    newpad = (oclass->request_new_pad) (element, templ, name);
+    newpad = (oclass->request_new_pad) (element, templ, name, caps);
 
   if (newpad)
     gst_object_ref (newpad);
@@ -876,7 +876,7 @@ gst_element_get_pad_from_template (GstElement * element, GstPadTemplate * templ)
 /* FIXME : Improve algorithm for finding compatible muxer sink pad */
 static inline GstPad *
 get_compatible_muxer_sink_pad (GstEncodeBin * ebin, GstElement * encoder,
-    const GstCaps * sinkcaps)
+    GstCaps * sinkcaps)
 {
   GstPad *sinkpad;
   GstPadTemplate *srctempl = NULL;
@@ -894,10 +894,11 @@ get_compatible_muxer_sink_pad (GstEncodeBin * ebin, GstElement * encoder,
 
     gst_object_unref (srcpad);
     sinktempl = gst_element_get_compatible_pad_template (ebin->muxer, srctempl);
+    gst_object_unref (srctempl);
   } else {
     srctempl =
         gst_pad_template_new ("whatever", GST_PAD_SRC, GST_PAD_ALWAYS,
-        gst_caps_copy (sinkcaps));
+        sinkcaps);
     g_assert (srctempl != NULL);
     sinktempl = gst_element_get_compatible_pad_template (ebin->muxer, srctempl);
     g_object_unref (srctempl);
@@ -921,10 +922,12 @@ static gboolean
 _has_class (GstElement * element, const gchar * classname)
 {
   GstElementClass *klass;
+  const gchar *value;
 
   klass = GST_ELEMENT_GET_CLASS (element);
+  value = gst_element_class_get_metadata (klass, GST_ELEMENT_METADATA_KLASS);
 
-  return strstr (klass->details.klass, classname) != NULL;
+  return strstr (value, classname) != NULL;
 }
 
 /* FIXME : Add handling of streams that don't need encoding  */
@@ -943,8 +946,7 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
   /* Element we will link to the encoder */
   GstElement *last = NULL;
   GList *tmp, *tosync = NULL;
-  const GstCaps *format;
-  const GstCaps *restriction;
+  GstCaps *format, *restriction;
   const gchar *missing_element_name;
 
   format = gst_encoding_profile_get_format (sprof);
@@ -1134,7 +1136,8 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
 
   /* Path 1 : Already-encoded data */
   sinkpad =
-      local_element_request_pad (sgroup->combiner, NULL, "passthroughsink");
+      local_element_request_pad (sgroup->combiner, NULL, "passthroughsink",
+      NULL);
   if (G_UNLIKELY (sinkpad == NULL))
     goto no_combiner_sinkpad;
 
@@ -1146,7 +1149,7 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
 
     /* Check if stream format is compatible */
     srcpad = gst_element_get_static_pad (sgroup->smartencoder, "src");
-    tmpcaps = gst_pad_get_caps (srcpad);
+    tmpcaps = gst_pad_get_caps (srcpad, NULL);
     if (!gst_caps_can_intersect (tmpcaps, format)) {
       GST_DEBUG ("We don't have a smart encoder for the stream format");
       gst_object_unref (sgroup->smartencoder);
@@ -1161,7 +1164,9 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
     g_object_unref (srcpad);
   }
 
-  srcpad = local_element_request_pad (sgroup->splitter, NULL, "passthroughsrc");
+  srcpad =
+      local_element_request_pad (sgroup->splitter, NULL, "passthroughsrc",
+      NULL);
   if (G_UNLIKELY (srcpad == NULL))
     goto no_splitter_srcpad;
 
@@ -1180,7 +1185,8 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
   gst_bin_add ((GstBin *) ebin, sgroup->encoder);
   tosync = g_list_append (tosync, sgroup->encoder);
 
-  sinkpad = local_element_request_pad (sgroup->combiner, NULL, "encodingsink");
+  sinkpad =
+      local_element_request_pad (sgroup->combiner, NULL, "encodingsink", NULL);
   if (G_UNLIKELY (sinkpad == NULL))
     goto no_combiner_sinkpad;
   srcpad = gst_element_get_static_pad (sgroup->encoder, "src");
@@ -1300,7 +1306,8 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
 
   /* Link to stream splitter */
   sinkpad = gst_element_get_static_pad (last, "sink");
-  srcpad = local_element_request_pad (sgroup->splitter, NULL, "encodingsrc");
+  srcpad =
+      local_element_request_pad (sgroup->splitter, NULL, "encodingsrc", NULL);
   if (G_UNLIKELY (srcpad == NULL))
     goto no_splitter_srcpad;
   if (G_UNLIKELY (fast_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK))
@@ -1327,6 +1334,11 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
 
   ebin->streams = g_list_prepend (ebin->streams, sgroup);
 
+  if (format)
+    gst_caps_unref (format);
+  if (restriction)
+    gst_caps_unref (restriction);
+
   return sgroup;
 
 splitter_encoding_failure:
@@ -1406,6 +1418,10 @@ converter_link_failure:
 
 cleanup:
   /* FIXME : Actually properly cleanup everything */
+  if (format)
+    gst_caps_unref (format);
+  if (restriction)
+    gst_caps_unref (restriction);
   g_slice_free (StreamGroup, sgroup);
   return NULL;
 }
@@ -1635,8 +1651,9 @@ stream_error:
 }
 
 static void
-release_pads (GstPad * pad, GstElement * elt)
+release_pads (const GValue * item, GstElement * elt)
 {
+  GstPad *pad = g_value_get_object (item);
   GstPad *peer = NULL;
 
   GST_DEBUG_OBJECT (elt, "Releasing pad %s:%s", GST_DEBUG_PAD_NAME (pad));
@@ -1652,9 +1669,6 @@ release_pads (GstPad * pad, GstElement * elt)
 
   /* Release it from the object */
   gst_element_release_request_pad (elt, pad);
-
-  /* And remove the reference added by the iterator */
-  gst_object_unref (pad);
 }
 
 static void inline
@@ -1736,7 +1750,9 @@ stream_group_free (GstEncodeBin * ebin, StreamGroup * sgroup)
     GstIteratorResult itret = GST_ITERATOR_OK;
 
     while (itret == GST_ITERATOR_OK || itret == GST_ITERATOR_RESYNC) {
-      itret = gst_iterator_foreach (it, (GFunc) release_pads, sgroup->combiner);
+      itret =
+          gst_iterator_foreach (it, (GstIteratorForeachFunction) release_pads,
+          sgroup->combiner);
       gst_iterator_resync (it);
     }
     gst_iterator_free (it);
@@ -1748,7 +1764,9 @@ stream_group_free (GstEncodeBin * ebin, StreamGroup * sgroup)
     GstIterator *it = gst_element_iterate_src_pads (sgroup->splitter);
     GstIteratorResult itret = GST_ITERATOR_OK;
     while (itret == GST_ITERATOR_OK || itret == GST_ITERATOR_RESYNC) {
-      itret = gst_iterator_foreach (it, (GFunc) release_pads, sgroup->splitter);
+      itret =
+          gst_iterator_foreach (it, (GstIteratorForeachFunction) release_pads,
+          sgroup->splitter);
       gst_iterator_resync (it);
     }
     gst_iterator_free (it);
index ed0e42b..0f9ab49 100644 (file)
@@ -80,7 +80,7 @@ static gboolean setup_recoder_pipeline (GstSmartEncoder * smart_encoder);
 
 static GstFlowReturn gst_smart_encoder_chain (GstPad * pad, GstBuffer * buf);
 static gboolean smart_encoder_sink_event (GstPad * pad, GstEvent * event);
-static GstCaps *smart_encoder_sink_getcaps (GstPad * pad);
+static GstCaps *smart_encoder_sink_getcaps (GstPad * pad, GstCaps * filter);
 static GstStateChangeReturn
 gst_smart_encoder_change_state (GstElement * element,
     GstStateChange transition);
@@ -242,7 +242,7 @@ gst_smart_encoder_reencode_gop (GstSmartEncoder * smart_encoder)
 static GstFlowReturn
 gst_smart_encoder_push_pending_gop (GstSmartEncoder * smart_encoder)
 {
-  gint64 cstart, cstop;
+  guint64 cstart, cstop;
   GList *tmp;
   GstFlowReturn res = GST_FLOW_OK;
 
@@ -350,28 +350,16 @@ smart_encoder_sink_event (GstPad * pad, GstEvent * event)
     case GST_EVENT_FLUSH_STOP:
       smart_encoder_reset (smart_encoder);
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      GstFormat format;
-      gdouble rate, arate;
-      gint64 start, stop, time;
-      gboolean update;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-          &start, &stop, &time);
-      GST_DEBUG_OBJECT (smart_encoder,
-          "newsegment: update %d, rate %g, arate %g, start %" GST_TIME_FORMAT
-          ", stop %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT,
-          update, rate, arate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
-          GST_TIME_ARGS (time));
-      if (format != GST_FORMAT_TIME)
+      gst_event_copy_segment (event, smart_encoder->segment);
+
+      GST_DEBUG_OBJECT (smart_encoder, "segment: %" GST_SEGMENT_FORMAT,
+          smart_encoder->segment);
+      if (smart_encoder->segment->format != GST_FORMAT_TIME)
         GST_ERROR
             ("smart_encoder can not handle streams not specified in GST_FORMAT_TIME");
 
-      /* now configure the values */
-      gst_segment_set_newsegment_full (smart_encoder->segment, update,
-          rate, arate, format, start, stop, time);
-
       /* And keep a copy for further usage */
       if (smart_encoder->newsegment)
         gst_event_unref (smart_encoder->newsegment);
@@ -393,25 +381,24 @@ smart_encoder_sink_event (GstPad * pad, GstEvent * event)
 }
 
 static GstCaps *
-smart_encoder_sink_getcaps (GstPad * pad)
+smart_encoder_sink_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstCaps *peer, *tmpl, *res;
   GstSmartEncoder *smart_encoder = GST_SMART_ENCODER (gst_pad_get_parent (pad));
 
-  /* Try getting it from downstream */
-  peer = gst_pad_peer_get_caps_reffed (smart_encoder->srcpad);
-
   /* Use computed caps */
   if (smart_encoder->available_caps)
     tmpl = gst_caps_ref (smart_encoder->available_caps);
   else
     tmpl = gst_static_pad_template_get_caps (&src_template);
 
+  /* Try getting it from downstream */
+  peer = gst_pad_peer_get_caps (smart_encoder->srcpad, tmpl);
+
   if (peer == NULL) {
     res = tmpl;
   } else {
-    res = gst_caps_intersect (peer, tmpl);
-    gst_caps_unref (peer);
+    res = peer;
     gst_caps_unref (tmpl);
   }
 
@@ -510,6 +497,7 @@ static gboolean
 setup_recoder_pipeline (GstSmartEncoder * smart_encoder)
 {
   GstPad *tmppad;
+  GstCaps *caps;
 
   /* Fast path */
   if (G_UNLIKELY (smart_encoder->encoder))
@@ -518,14 +506,18 @@ setup_recoder_pipeline (GstSmartEncoder * smart_encoder)
   GST_DEBUG ("Creating internal decoder and encoder");
 
   /* Create decoder/encoder */
-  smart_encoder->decoder = get_decoder (GST_PAD_CAPS (smart_encoder->sinkpad));
+  caps = gst_pad_get_current_caps (smart_encoder->sinkpad);
+  smart_encoder->decoder = get_decoder (caps);
   if (G_UNLIKELY (smart_encoder->decoder == NULL))
     goto no_decoder;
+  gst_caps_unref (caps);
   gst_element_set_bus (smart_encoder->decoder, GST_ELEMENT_BUS (smart_encoder));
 
-  smart_encoder->encoder = get_encoder (GST_PAD_CAPS (smart_encoder->sinkpad));
+  caps = gst_pad_get_current_caps (smart_encoder->sinkpad);
+  smart_encoder->encoder = get_encoder (caps);
   if (G_UNLIKELY (smart_encoder->encoder == NULL))
     goto no_encoder;
+  gst_caps_unref (caps);
   gst_element_set_bus (smart_encoder->encoder, GST_ELEMENT_BUS (smart_encoder));
 
   GST_DEBUG ("Creating internal pads");
@@ -536,8 +528,6 @@ setup_recoder_pipeline (GstSmartEncoder * smart_encoder)
   smart_encoder->internal_srcpad = gst_pad_new ("internal_src", GST_PAD_SRC);
   g_object_set_qdata ((GObject *) smart_encoder->internal_srcpad,
       INTERNAL_ELEMENT, smart_encoder);
-  gst_pad_set_caps (smart_encoder->internal_srcpad,
-      GST_PAD_CAPS (smart_encoder->sinkpad));
   gst_pad_set_active (smart_encoder->internal_srcpad, TRUE);
 
   /* Sink pad which will get the buffers from the encoder.
@@ -546,8 +536,6 @@ setup_recoder_pipeline (GstSmartEncoder * smart_encoder)
   smart_encoder->internal_sinkpad = gst_pad_new ("internal_sink", GST_PAD_SINK);
   g_object_set_qdata ((GObject *) smart_encoder->internal_sinkpad,
       INTERNAL_ELEMENT, smart_encoder);
-  gst_pad_set_caps (smart_encoder->internal_sinkpad,
-      GST_PAD_CAPS (smart_encoder->sinkpad));
   gst_pad_set_chain_function (smart_encoder->internal_sinkpad, internal_chain);
   gst_pad_set_active (smart_encoder->internal_sinkpad, TRUE);
 
@@ -575,15 +563,15 @@ setup_recoder_pipeline (GstSmartEncoder * smart_encoder)
 
 no_decoder:
   {
-    GST_WARNING ("Couldn't find a decoder for %" GST_PTR_FORMAT,
-        GST_PAD_CAPS (smart_encoder->sinkpad));
+    GST_WARNING ("Couldn't find a decoder for %" GST_PTR_FORMAT, caps);
+    gst_caps_unref (caps);
     return FALSE;
   }
 
 no_encoder:
   {
-    GST_WARNING ("Couldn't find an encoder for %" GST_PTR_FORMAT,
-        GST_PAD_CAPS (smart_encoder->sinkpad));
+    GST_WARNING ("Couldn't find an encoder for %" GST_PTR_FORMAT, caps);
+    gst_caps_unref (caps);
     return FALSE;
   }
 
index 72d40fe..e93cab4 100644 (file)
@@ -44,7 +44,7 @@ G_DEFINE_TYPE (GstStreamCombiner, gst_stream_combiner, GST_TYPE_ELEMENT);
 static void gst_stream_combiner_dispose (GObject * object);
 
 static GstPad *gst_stream_combiner_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * name);
+    GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
 static void gst_stream_combiner_release_pad (GstElement * element,
     GstPad * pad);
 
@@ -132,12 +132,12 @@ gst_stream_combiner_sink_event (GstPad * pad, GstEvent * event)
 }
 
 static GstCaps *
-gst_stream_combiner_sink_getcaps (GstPad * pad)
+gst_stream_combiner_sink_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstStreamCombiner *stream_combiner =
       (GstStreamCombiner *) GST_PAD_PARENT (pad);
 
-  return gst_pad_peer_get_caps_reffed (stream_combiner->srcpad);
+  return gst_pad_peer_get_caps (stream_combiner->srcpad, filter);
 }
 
 static gboolean
@@ -217,7 +217,7 @@ gst_stream_combiner_init (GstStreamCombiner * stream_combiner)
 
 static GstPad *
 gst_stream_combiner_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * name)
+    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
 {
   GstStreamCombiner *stream_combiner = (GstStreamCombiner *) element;
   GstPad *sinkpad;
index c473386..531a8f5 100644 (file)
@@ -44,7 +44,7 @@ G_DEFINE_TYPE (GstStreamSplitter, gst_stream_splitter, GST_TYPE_ELEMENT);
 static void gst_stream_splitter_dispose (GObject * object);
 
 static GstPad *gst_stream_splitter_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * name);
+    GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
 static void gst_stream_splitter_release_pad (GstElement * element,
     GstPad * pad);
 
@@ -242,7 +242,7 @@ beach:
 }
 
 static GstCaps *
-gst_stream_splitter_sink_getcaps (GstPad * pad)
+gst_stream_splitter_sink_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstStreamSplitter *stream_splitter =
       (GstStreamSplitter *) GST_PAD_PARENT (pad);
@@ -256,7 +256,7 @@ gst_stream_splitter_sink_getcaps (GstPad * pad)
 
 resync:
   if (G_UNLIKELY (stream_splitter->srcpads == NULL)) {
-    res = gst_caps_new_any ();
+    res = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
     goto beach;
   }
 
@@ -269,9 +269,9 @@ resync:
 
     STREAMS_UNLOCK (stream_splitter);
     if (res)
-      gst_caps_merge (res, gst_pad_peer_get_caps_reffed (srcpad));
+      gst_caps_merge (res, gst_pad_peer_get_caps (srcpad, filter));
     else
-      res = gst_pad_peer_get_caps (srcpad);
+      res = gst_pad_peer_get_caps (srcpad, filter);
     STREAMS_LOCK (stream_splitter);
 
     if (G_UNLIKELY (cookie != stream_splitter->cookie)) {
@@ -316,7 +316,7 @@ resync:
     GstCaps *peercaps;
 
     STREAMS_UNLOCK (stream_splitter);
-    peercaps = gst_pad_peer_get_caps_reffed (srcpad);
+    peercaps = gst_pad_peer_get_caps (srcpad, NULL);
     if (peercaps) {
       res = gst_caps_can_intersect (caps, peercaps);
       gst_caps_unref (peercaps);
@@ -387,7 +387,7 @@ gst_stream_splitter_init (GstStreamSplitter * stream_splitter)
 
 static GstPad *
 gst_stream_splitter_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * name)
+    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
 {
   GstStreamSplitter *stream_splitter = (GstStreamSplitter *) element;
   GstPad *srcpad;
index 318a90e..2e73027 100644 (file)
@@ -43,7 +43,6 @@ gst_ff_vid_caps_new (AVCodecContext * context,
 /*
  * Read a palette from a caps.
  */
-
      static void
          gst_ffmpeg_get_palette (const GstCaps * caps, AVCodecContext * context)
 {
@@ -52,15 +51,15 @@ gst_ff_vid_caps_new (AVCodecContext * context,
 
   /* do we have a palette? */
   if ((palette_v = gst_structure_get_value (str, "palette_data")) && context) {
-    const GstBuffer *palette;
+    GstBuffer *palette;
 
     palette = gst_value_get_buffer (palette_v);
-    if (palette && GST_BUFFER_SIZE (palette) >= 256 * 4) {
+    if (palette && gst_buffer_get_size (palette) >= 256 * 4) {
       if (context->palctrl)
         av_free (context->palctrl);
       context->palctrl = av_malloc (sizeof (AVPaletteControl));
       context->palctrl->palette_changed = 1;
-      memcpy (context->palctrl->palette, GST_BUFFER_DATA (palette),
+      gst_buffer_extract (palette, 0, context->palctrl->palette,
           AVPALETTE_SIZE);
     }
   }
@@ -71,9 +70,13 @@ gst_ffmpeg_set_palette (GstCaps * caps, AVCodecContext * context)
 {
   if (context->palctrl) {
     GstBuffer *palette = gst_buffer_new_and_alloc (256 * 4);
+    guint8 *data;
+    gsize size;
+
+    data = gst_buffer_map (palette, &size, NULL, GST_MAP_WRITE);
+    memcpy (data, context->palctrl->palette, AVPALETTE_SIZE);
+    gst_buffer_unmap (palette, data, size);
 
-    memcpy (GST_BUFFER_DATA (palette), context->palctrl->palette,
-        AVPALETTE_SIZE);
     gst_caps_set_simple (caps, "palette_data", GST_TYPE_BUFFER, palette, NULL);
     gst_buffer_unref (palette);
   }
index 4ba0204..8aecc4f 100644 (file)
@@ -87,7 +87,7 @@ GType gst_ffmpegcsp_get_type (void);
 static gboolean gst_ffmpegcsp_set_caps (GstBaseTransform * btrans,
     GstCaps * incaps, GstCaps * outcaps);
 static gboolean gst_ffmpegcsp_get_unit_size (GstBaseTransform * btrans,
-    GstCaps * caps, guint * size);
+    GstCaps * caps, gsize * size);
 static GstFlowReturn gst_ffmpegcsp_transform (GstBaseTransform * btrans,
     GstBuffer * inbuf, GstBuffer * outbuf);
 
@@ -124,40 +124,16 @@ gst_ffmpegcsp_caps_remove_format_info (GstCaps * caps)
   return caps;
 }
 
-
-static gboolean
-gst_ffmpegcsp_structure_is_alpha (GstStructure * s)
-{
-  GQuark name;
-
-  name = gst_structure_get_name_id (s);
-
-  if (name == _QRAWRGB) {
-    return gst_structure_id_has_field (s, _QALPHAMASK);
-  } else if (name == _QRAWYUV) {
-    guint32 fourcc;
-
-    if (!gst_structure_get_fourcc (s, "format", &fourcc))
-      return FALSE;
-
-    return (fourcc == GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'));
-  }
-
-  return FALSE;
-}
-
 /* The caps can be transformed into any other caps with format info removed.
  * However, we should prefer passthrough, so if passthrough is possible,
  * put it first in the list. */
 static GstCaps *
 gst_ffmpegcsp_transform_caps (GstBaseTransform * btrans,
-    GstPadDirection direction, GstCaps * caps)
+    GstPadDirection direction, GstCaps * caps, GstCaps * filter)
 {
   GstCaps *template;
   GstCaps *tmp, *tmp2;
   GstCaps *result;
-  GstStructure *s;
-  GstCaps *alpha, *non_alpha;
 
   template = gst_static_pad_template_get_caps (&gst_ffmpegcsp_src_template);
   result = gst_caps_copy (caps);
@@ -168,31 +144,12 @@ gst_ffmpegcsp_transform_caps (GstBaseTransform * btrans,
   gst_caps_unref (tmp);
   tmp = tmp2;
 
-  /* Now move alpha formats to the beginning if caps is an alpha format
-   * or at the end if caps is no alpha format */
-  alpha = gst_caps_new_empty ();
-  non_alpha = gst_caps_new_empty ();
-
-  while ((s = gst_caps_steal_structure (tmp, 0))) {
-    if (gst_ffmpegcsp_structure_is_alpha (s))
-      gst_caps_append_structure (alpha, s);
-    else
-      gst_caps_append_structure (non_alpha, s);
-  }
-
-  s = gst_caps_get_structure (caps, 0);
-  gst_caps_unref (tmp);
-
-  if (gst_ffmpegcsp_structure_is_alpha (s)) {
-    gst_caps_append (alpha, non_alpha);
-    tmp = alpha;
-  } else {
-    gst_caps_append (non_alpha, alpha);
-    tmp = non_alpha;
+  if (filter) {
+    tmp2 = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (tmp);
+    tmp = tmp2;
   }
 
-  gst_caps_append (result, tmp);
-
   GST_DEBUG_OBJECT (btrans, "transformed %" GST_PTR_FORMAT " into %"
       GST_PTR_FORMAT, caps, result);
 
@@ -333,28 +290,8 @@ invalid_out_caps:
   }
 }
 
-GST_BOILERPLATE (GstFFMpegCsp, gst_ffmpegcsp, GstVideoFilter,
-    GST_TYPE_VIDEO_FILTER);
-
-static void
-gst_ffmpegcsp_base_init (gpointer klass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_ffmpegcsp_src_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_ffmpegcsp_sink_template));
-
-  gst_element_class_set_details_simple (element_class,
-      "FFMPEG Colorspace converter", "Filter/Converter/Video",
-      "Converts video from one colorspace to another",
-      "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
-
-  _QRAWRGB = g_quark_from_string ("video/x-raw-rgb");
-  _QRAWYUV = g_quark_from_string ("video/x-raw-yuv");
-  _QALPHAMASK = g_quark_from_string ("alpha_mask");
-}
+#define gst_ffmpegcsp_parent_class parent_class
+G_DEFINE_TYPE (GstFFMpegCsp, gst_ffmpegcsp, GST_TYPE_VIDEO_FILTER);
 
 static void
 gst_ffmpegcsp_finalize (GObject * obj)
@@ -371,11 +308,26 @@ static void
 gst_ffmpegcsp_class_init (GstFFMpegCspClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstElementClass *gstelement_class = (GstElementClass *) klass;
   GstBaseTransformClass *gstbasetransform_class =
       (GstBaseTransformClass *) klass;
 
+  _QRAWRGB = g_quark_from_string ("video/x-raw-rgb");
+  _QRAWYUV = g_quark_from_string ("video/x-raw-yuv");
+  _QALPHAMASK = g_quark_from_string ("alpha_mask");
+
   gobject_class->finalize = gst_ffmpegcsp_finalize;
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_ffmpegcsp_src_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_ffmpegcsp_sink_template));
+
+  gst_element_class_set_details_simple (gstelement_class,
+      "FFMPEG Colorspace converter", "Filter/Converter/Video",
+      "Converts video from one colorspace to another",
+      "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
+
   gstbasetransform_class->transform_caps =
       GST_DEBUG_FUNCPTR (gst_ffmpegcsp_transform_caps);
   gstbasetransform_class->set_caps = GST_DEBUG_FUNCPTR (gst_ffmpegcsp_set_caps);
@@ -388,7 +340,7 @@ gst_ffmpegcsp_class_init (GstFFMpegCspClass * klass)
 }
 
 static void
-gst_ffmpegcsp_init (GstFFMpegCsp * space, GstFFMpegCspClass * klass)
+gst_ffmpegcsp_init (GstFFMpegCsp * space)
 {
   space->from_pixfmt = space->to_pixfmt = PIX_FMT_NB;
   space->palette = NULL;
@@ -396,7 +348,7 @@ gst_ffmpegcsp_init (GstFFMpegCsp * space, GstFFMpegCspClass * klass)
 
 static gboolean
 gst_ffmpegcsp_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
-    guint * size)
+    gsize * size)
 {
   GstStructure *structure = NULL;
   AVCodecContext *ctx = NULL;
@@ -448,6 +400,8 @@ gst_ffmpegcsp_transform (GstBaseTransform * btrans, GstBuffer * inbuf,
 {
   GstFFMpegCsp *space;
   gint result;
+  guint8 *indata, *outdata;
+  gsize insize, outsize;
 
   space = GST_FFMPEGCSP (btrans);
 
@@ -458,8 +412,9 @@ gst_ffmpegcsp_transform (GstBaseTransform * btrans, GstBuffer * inbuf,
     goto unknown_format;
 
   /* fill from with source data */
+  indata = gst_buffer_map (inbuf, &insize, NULL, GST_MAP_READ);
   gst_ffmpegcsp_avpicture_fill (&space->from_frame,
-      GST_BUFFER_DATA (inbuf), space->from_pixfmt, space->width, space->height,
+      indata, space->from_pixfmt, space->width, space->height,
       space->interlaced);
 
   /* fill optional palette */
@@ -467,13 +422,17 @@ gst_ffmpegcsp_transform (GstBaseTransform * btrans, GstBuffer * inbuf,
     space->from_frame.data[1] = (uint8_t *) space->palette->palette;
 
   /* fill target frame */
+  outdata = gst_buffer_map (outbuf, &outsize, NULL, GST_MAP_WRITE);
   gst_ffmpegcsp_avpicture_fill (&space->to_frame,
-      GST_BUFFER_DATA (outbuf), space->to_pixfmt, space->width, space->height,
+      outdata, space->to_pixfmt, space->width, space->height,
       space->interlaced);
 
   /* and convert */
   result = img_convert (&space->to_frame, space->to_pixfmt,
       &space->from_frame, space->from_pixfmt, space->width, space->height);
+  gst_buffer_unmap (outbuf, outdata, outsize);
+  gst_buffer_unmap (inbuf, indata, insize);
+
   if (result == -1)
     goto not_supported;
 
index 702e63f..b608977 100644 (file)
@@ -62,11 +62,11 @@ GST_STATIC_PAD_TEMPLATE ("src",
 GST_DEBUG_CATEGORY_STATIC (gst_gdp_depay_debug);
 #define GST_CAT_DEFAULT gst_gdp_depay_debug
 
-#define _do_init(x) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (gst_gdp_depay_debug, "gdpdepay", 0, \
     "GDP depayloader");
-
-GST_BOILERPLATE_FULL (GstGDPDepay, gst_gdp_depay, GstElement,
+#define gst_gdp_depay_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstGDPDepay, gst_gdp_depay,
     GST_TYPE_ELEMENT, _do_init);
 
 static gboolean gst_gdp_depay_sink_event (GstPad * pad, GstEvent * event);
@@ -80,29 +80,23 @@ static GstStateChangeReturn gst_gdp_depay_change_state (GstElement *
 static void gst_gdp_depay_finalize (GObject * object);
 
 static void
-gst_gdp_depay_base_init (gpointer g_class)
+gst_gdp_depay_class_init (GstGDPDepayClass * klass)
 {
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
 
-  gst_element_class_set_details_simple (element_class,
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+
+  gst_element_class_set_details_simple (gstelement_class,
       "GDP Depayloader", "GDP/Depayloader",
       "Depayloads GStreamer Data Protocol buffers",
       "Thomas Vander Stichele <thomas at apestaart dot org>");
 
-  gst_element_class_add_pad_template (element_class,
+  gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&gdp_depay_sink_template));
-  gst_element_class_add_pad_template (element_class,
+  gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&gdp_depay_src_template));
-}
-
-static void
-gst_gdp_depay_class_init (GstGDPDepayClass * klass)
-{
-  GObjectClass *gobject_class;
-  GstElementClass *gstelement_class;
-
-  gobject_class = (GObjectClass *) klass;
-  gstelement_class = (GstElementClass *) klass;
 
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_gdp_depay_change_state);
@@ -110,7 +104,7 @@ gst_gdp_depay_class_init (GstGDPDepayClass * klass)
 }
 
 static void
-gst_gdp_depay_init (GstGDPDepay * gdpdepay, GstGDPDepayClass * g_class)
+gst_gdp_depay_init (GstGDPDepay * gdpdepay)
 {
   gdpdepay->sinkpad =
       gst_pad_new_from_static_template (&gdp_depay_sink_template, "sink");
@@ -169,7 +163,7 @@ gst_gdp_depay_sink_event (GstPad * pad, GstEvent * event)
       /* after EOS, we don't expect to output anything anymore */
       res = gst_pad_push_event (this->srcpad, event);
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     case GST_EVENT_TAG:
     case GST_EVENT_BUFFERSIZE:
     default:
@@ -285,17 +279,23 @@ gst_gdp_depay_chain (GstPad * pad, GstBuffer * buffer)
           goto wrong_type;
         }
 
-        if (this->payload_length
-            && (!gst_dp_validate_payload (GST_DP_HEADER_LENGTH, this->header,
-                    gst_adapter_peek (this->adapter, this->payload_length)))) {
-          goto payload_validate_error;
+        if (this->payload_length) {
+          const guint8 *data;
+          gboolean res;
+
+          data = gst_adapter_map (this->adapter, this->payload_length);
+          res = gst_dp_validate_payload (GST_DP_HEADER_LENGTH, this->header,
+              data);
+          gst_adapter_unmap (this->adapter, 0);
+
+          if (!res)
+            goto payload_validate_error;
         }
 
         break;
       }
       case GST_GDP_DEPAY_STATE_BUFFER:
       {
-
         /* if we receive a buffer without caps first, we error out */
         if (!this->caps)
           goto no_caps;
@@ -309,22 +309,23 @@ gst_gdp_depay_chain (GstPad * pad, GstBuffer * buffer)
         if (this->payload_length > 0) {
           guint8 *payload;
 
-          payload = gst_adapter_take (this->adapter, this->payload_length);
-          memcpy (GST_BUFFER_DATA (buf), payload, this->payload_length);
-          g_free (payload);
+          payload = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+          gst_adapter_copy (this->adapter, payload, 0, this->payload_length);
+          gst_buffer_unmap (buf, payload, this->payload_length);
+
+          gst_adapter_flush (this->adapter, this->payload_length);
         }
 
         /* set caps and push */
-        gst_buffer_set_caps (buf, this->caps);
         GST_LOG_OBJECT (this, "deserialized buffer %p, pushing, timestamp %"
             GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT
             ", offset %" G_GINT64_FORMAT ", offset_end %" G_GINT64_FORMAT
-            ", size %d, flags 0x%x",
+            ", size %" G_GSIZE_FORMAT ", flags 0x%x",
             buf,
             GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
             GST_TIME_ARGS (GST_BUFFER_DURATION (buf)),
             GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
-            GST_BUFFER_SIZE (buf), GST_BUFFER_FLAGS (buf));
+            gst_buffer_get_size (buf), GST_BUFFER_FLAGS (buf));
         ret = gst_pad_push (this->srcpad, buf);
         if (ret != GST_FLOW_OK)
           goto push_error;
index 6da4967..56c567e 100644 (file)
@@ -67,19 +67,16 @@ enum
   PROP_VERSION,
 };
 
-#define _do_init(x) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (gst_gdp_pay_debug, "gdppay", 0, \
     "GDP payloader");
-
-GST_BOILERPLATE_FULL (GstGDPPay, gst_gdp_pay, GstElement,
-    GST_TYPE_ELEMENT, _do_init);
+#define gst_gdp_pay_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstGDPPay, gst_gdp_pay, GST_TYPE_ELEMENT, _do_init);
 
 static void gst_gdp_pay_reset (GstGDPPay * this);
 
 static GstFlowReturn gst_gdp_pay_chain (GstPad * pad, GstBuffer * buffer);
-
 static gboolean gst_gdp_pay_src_event (GstPad * pad, GstEvent * event);
-
 static gboolean gst_gdp_pay_sink_event (GstPad * pad, GstEvent * event);
 
 static GstStateChangeReturn gst_gdp_pay_change_state (GstElement *
@@ -93,26 +90,9 @@ static void gst_gdp_pay_get_property (GObject * object, guint prop_id,
 static void gst_gdp_pay_finalize (GObject * gobject);
 
 static void
-gst_gdp_pay_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class,
-      "GDP Payloader", "GDP/Payloader",
-      "Payloads GStreamer Data Protocol buffers",
-      "Thomas Vander Stichele <thomas at apestaart dot org>");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gdp_pay_sink_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gdp_pay_src_template));
-}
-
-static void
 gst_gdp_pay_class_init (GstGDPPayClass * klass)
 {
   GObjectClass *gobject_class;
-
   GstElementClass *gstelement_class;
 
   gobject_class = (GObjectClass *) klass;
@@ -136,11 +116,21 @@ gst_gdp_pay_class_init (GstGDPPayClass * klass)
           GST_TYPE_DP_VERSION, DEFAULT_VERSION,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "GDP Payloader", "GDP/Payloader",
+      "Payloads GStreamer Data Protocol buffers",
+      "Thomas Vander Stichele <thomas at apestaart dot org>");
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gdp_pay_sink_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gdp_pay_src_template));
+
   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_gdp_pay_change_state);
 }
 
 static void
-gst_gdp_pay_init (GstGDPPay * gdppay, GstGDPPayClass * g_class)
+gst_gdp_pay_init (GstGDPPay * gdppay)
 {
   gdppay->sinkpad =
       gst_pad_new_from_static_template (&gdp_pay_sink_template, "sink");
@@ -216,20 +206,18 @@ static void
 gst_gdp_stamp_buffer (GstGDPPay * this, GstBuffer * buffer)
 {
   GST_BUFFER_OFFSET (buffer) = this->offset;
-  GST_BUFFER_OFFSET_END (buffer) = this->offset + GST_BUFFER_SIZE (buffer);
+  GST_BUFFER_OFFSET_END (buffer) = this->offset + gst_buffer_get_size (buffer);
   this->offset = GST_BUFFER_OFFSET_END (buffer);
 }
 
+#if 0
 static GstBuffer *
 gst_gdp_buffer_from_caps (GstGDPPay * this, GstCaps * caps)
 {
   GstBuffer *headerbuf;
-
   GstBuffer *payloadbuf;
-
   guint8 *header, *payload;
-
-  guint len;
+  guint len, plen;
 
   if (!this->packetizer->packet_from_caps (caps, this->header_flag, &len,
           &header, &payload))
@@ -237,13 +225,13 @@ gst_gdp_buffer_from_caps (GstGDPPay * this, GstCaps * caps)
 
   GST_LOG_OBJECT (this, "creating GDP header and payload buffer from caps");
   headerbuf = gst_buffer_new ();
-  gst_buffer_set_data (headerbuf, header, len);
-  GST_BUFFER_MALLOCDATA (headerbuf) = header;
+  gst_buffer_take_memory (headerbuf,
+      gst_memory_new_wrapped (0, header, g_free, len, 0, len));
 
   payloadbuf = gst_buffer_new ();
-  gst_buffer_set_data (payloadbuf, payload,
-      gst_dp_header_payload_length (header));
-  GST_BUFFER_MALLOCDATA (payloadbuf) = payload;
+  plen = gst_dp_header_payload_length (header);
+  gst_buffer_take_memory (payloadbuf,
+      gst_memory_new_wrapped (0, payload, g_free, plen, 0, plen));
 
   return gst_buffer_join (headerbuf, payloadbuf);
 
@@ -254,14 +242,13 @@ packet_failed:
     return NULL;
   }
 }
+#endif
 
 static GstBuffer *
 gst_gdp_pay_buffer_from_buffer (GstGDPPay * this, GstBuffer * buffer)
 {
   GstBuffer *headerbuf;
-
   guint8 *header;
-
   guint len;
 
   if (!this->packetizer->header_from_buffer (buffer, this->header_flag, &len,
@@ -270,8 +257,8 @@ gst_gdp_pay_buffer_from_buffer (GstGDPPay * this, GstBuffer * buffer)
 
   GST_LOG_OBJECT (this, "creating GDP header and payload buffer from buffer");
   headerbuf = gst_buffer_new ();
-  gst_buffer_set_data (headerbuf, header, len);
-  GST_BUFFER_MALLOCDATA (headerbuf) = header;
+  gst_buffer_take_memory (headerbuf,
+      gst_memory_new_wrapped (0, header, g_free, len, 0, len));
 
   /* we do not want to lose the ref on the incoming buffer */
   gst_buffer_ref (buffer);
@@ -290,13 +277,9 @@ static GstBuffer *
 gst_gdp_buffer_from_event (GstGDPPay * this, GstEvent * event)
 {
   GstBuffer *headerbuf;
-
   GstBuffer *payloadbuf;
-
   guint8 *header, *payload;
-
-  guint len;
-
+  guint len, plen;
   gboolean ret;
 
   ret =
@@ -307,13 +290,15 @@ gst_gdp_buffer_from_event (GstGDPPay * this, GstEvent * event)
 
   GST_LOG_OBJECT (this, "creating GDP header and payload buffer from event");
   headerbuf = gst_buffer_new ();
-  gst_buffer_set_data (headerbuf, header, len);
-  GST_BUFFER_MALLOCDATA (headerbuf) = header;
+  gst_buffer_take_memory (headerbuf,
+      gst_memory_new_wrapped (0, header, g_free, len, 0, len));
 
   payloadbuf = gst_buffer_new ();
-  gst_buffer_set_data (payloadbuf, payload,
-      gst_dp_header_payload_length (header));
-  GST_BUFFER_MALLOCDATA (payloadbuf) = payload;
+  plen = gst_dp_header_payload_length (header);
+  if (plen && payload != NULL) {
+    gst_buffer_take_memory (payloadbuf,
+        gst_memory_new_wrapped (0, payload, g_free, plen, 0, plen));
+  }
 
   return gst_buffer_join (headerbuf, payloadbuf);
 
@@ -333,14 +318,10 @@ static GstFlowReturn
 gst_gdp_pay_reset_streamheader (GstGDPPay * this)
 {
   GstCaps *caps;
-
   /* We use copies of these to avoid circular refcounts */
   GstBuffer *new_segment_buf, *caps_buf, *tag_buf;
-
   GstStructure *structure;
-
   GstFlowReturn r = GST_FLOW_OK;
-
   gboolean version_one_zero = TRUE;
 
   GValue array = { 0 };
@@ -373,7 +354,6 @@ gst_gdp_pay_reset_streamheader (GstGDPPay * this)
     GST_DEBUG_OBJECT (this, "1.0, appending copy of new segment buffer %p",
         this->new_segment_buf);
     new_segment_buf = gst_buffer_copy (this->new_segment_buf);
-    gst_buffer_set_caps (new_segment_buf, NULL);
     g_value_init (&value, GST_TYPE_BUFFER);
     gst_value_set_buffer (&value, new_segment_buf);
     gst_value_array_append_value (&array, &value);
@@ -387,7 +367,6 @@ gst_gdp_pay_reset_streamheader (GstGDPPay * this)
       tag_buf = this->tag_buf;
       this->tag_buf = NULL;
 
-      gst_buffer_set_caps (tag_buf, NULL);
       g_value_init (&value, GST_TYPE_BUFFER);
       gst_value_set_buffer (&value, tag_buf);
       gst_value_array_append_value (&array, &value);
@@ -399,7 +378,6 @@ gst_gdp_pay_reset_streamheader (GstGDPPay * this)
   gst_gdp_stamp_buffer (this, this->caps_buf);
   GST_DEBUG_OBJECT (this, "appending copy of caps buffer %p", this->caps_buf);
   caps_buf = gst_buffer_copy (this->caps_buf);
-  gst_buffer_set_caps (caps_buf, NULL);
   g_value_init (&value, GST_TYPE_BUFFER);
   gst_value_set_buffer (&value, caps_buf);
   gst_value_array_append_value (&array, &value);
@@ -474,16 +452,15 @@ gst_gdp_pay_reset_streamheader (GstGDPPay * this)
 
   GST_DEBUG_OBJECT (this, "Setting caps on src pad %" GST_PTR_FORMAT, caps);
   gst_pad_set_caps (this->srcpad, caps);
-  this->caps_buf = gst_buffer_make_metadata_writable (this->caps_buf);
-  gst_buffer_set_caps (this->caps_buf, caps);
-  this->new_segment_buf =
-      gst_buffer_make_metadata_writable (this->new_segment_buf);
-  gst_buffer_set_caps (this->new_segment_buf, caps);
 
   /* if these are our first ever buffers, send out new_segment first */
   if (!this->sent_streamheader) {
-    GstEvent *event =
-        gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_BYTES, 0, -1, 0);
+    GstEvent *event;
+    GstSegment segment;
+
+    gst_segment_init (&segment, GST_FORMAT_BYTES);
+    event = gst_event_new_segment (&segment);
+
     GST_DEBUG_OBJECT (this, "Sending out new_segment event %p", event);
     if (!gst_pad_push_event (this->srcpad, event)) {
       GST_WARNING_OBJECT (this, "pushing new segment failed");
@@ -504,7 +481,6 @@ gst_gdp_pay_reset_streamheader (GstGDPPay * this)
     goto done;
   }
   if (this->tag_buf) {
-    gst_buffer_set_caps (this->tag_buf, caps);
     GST_DEBUG_OBJECT (this, "Pushing GDP tag buffer %p", this->tag_buf);
     /* we stored these bufs with refcount 1, so make sure we keep a ref */
     r = gst_pad_push (this->srcpad, gst_buffer_ref (this->tag_buf));
@@ -532,7 +508,6 @@ gst_gdp_pay_reset_streamheader (GstGDPPay * this)
     this->queue = g_list_delete_link (this->queue, this->queue);
 
     /* set caps and push */
-    gst_buffer_set_caps (buffer, caps);
     r = gst_pad_push (this->srcpad, buffer);
     if (r != GST_FLOW_OK) {
       GST_WARNING_OBJECT (this, "pushing queued GDP buffer returned %d", r);
@@ -562,7 +537,6 @@ gst_gdp_queue_buffer (GstGDPPay * this, GstBuffer * buffer)
   if (this->sent_streamheader) {
     GST_LOG_OBJECT (this, "Pushing GDP buffer %p, caps %" GST_PTR_FORMAT,
         buffer, this->caps);
-    gst_buffer_set_caps (buffer, GST_PAD_CAPS (this->srcpad));
     return gst_pad_push (this->srcpad, buffer);
   }
 
@@ -579,11 +553,10 @@ static GstFlowReturn
 gst_gdp_pay_chain (GstPad * pad, GstBuffer * buffer)
 {
   GstGDPPay *this;
-
+#if 0
   GstCaps *caps;
-
+#endif
   GstBuffer *outbuffer;
-
   GstFlowReturn ret;
 
   this = GST_GDP_PAY (gst_pad_get_parent (pad));
@@ -592,10 +565,12 @@ gst_gdp_pay_chain (GstPad * pad, GstBuffer * buffer)
    * fake one in that case */
   if (!this->new_segment_buf) {
     GstEvent *event;
+    GstSegment segment;
 
     GST_WARNING_OBJECT (this,
         "did not receive new-segment before first buffer");
-    event = gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_BYTES, 0, -1, 0);
+    gst_segment_init (&segment, GST_FORMAT_BYTES);
+    event = gst_event_new_segment (&segment);
     outbuffer = gst_gdp_buffer_from_event (this, event);
     gst_event_unref (event);
 
@@ -612,7 +587,7 @@ gst_gdp_pay_chain (GstPad * pad, GstBuffer * buffer)
       this->new_segment_buf = outbuffer;
     }
   }
-
+#if 0
   /* make sure we've received caps before */
   caps = gst_buffer_get_caps (buffer);
   if (!this->caps && !caps)
@@ -638,6 +613,7 @@ gst_gdp_pay_chain (GstPad * pad, GstBuffer * buffer)
 
   if (caps)
     gst_caps_unref (caps);
+#endif
 
   /* create a GDP header packet,
    * then create a GST buffer of the header packet and the buffer contents */
@@ -666,6 +642,7 @@ done:
   return ret;
 
   /* ERRORS */
+#if 0
 no_caps:
   {
     /* when returning a fatal error as a GstFlowReturn we must post an error
@@ -685,6 +662,7 @@ no_caps_buffer:
     ret = GST_FLOW_ERROR;
     goto done;
   }
+#endif
 no_buffer:
   {
     GST_ELEMENT_ERROR (this, STREAM, ENCODE, (NULL),
@@ -698,11 +676,8 @@ static gboolean
 gst_gdp_pay_sink_event (GstPad * pad, GstEvent * event)
 {
   GstBuffer *outbuffer;
-
   GstGDPPay *this = GST_GDP_PAY (gst_pad_get_parent (pad));
-
   GstFlowReturn flowret;
-
   gboolean ret = TRUE;
 
   GST_DEBUG_OBJECT (this, "received event %p of type %s (%d)",
@@ -719,7 +694,7 @@ gst_gdp_pay_sink_event (GstPad * pad, GstEvent * event)
   /* if we got a new segment or tag event, we should put it on our streamheader,
    * and not send it on */
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
       GST_DEBUG_OBJECT (this, "Storing in caps buffer %p as new_segment_buf",
           outbuffer);
 
@@ -784,7 +759,6 @@ static gboolean
 gst_gdp_pay_src_event (GstPad * pad, GstEvent * event)
 {
   GstGDPPay *this;
-
   gboolean res = TRUE;
 
   this = GST_GDP_PAY (gst_pad_get_parent (pad));
@@ -865,7 +839,6 @@ static GstStateChangeReturn
 gst_gdp_pay_change_state (GstElement * element, GstStateChange transition)
 {
   GstStateChangeReturn ret;
-
   GstGDPPay *this = GST_GDP_PAY (element);
 
   switch (transition) {
index 854a28d..95a65d5 100644 (file)
@@ -1236,6 +1236,7 @@ static GstPad *
 get_our_ghost_pad (GstDecodeBin * decode_bin, GstPad * pad)
 {
   GstIterator *pad_it = NULL;
+  GValue item = { 0, };
   GstPad *db_pad = NULL;
   gboolean done = FALSE;
 
@@ -1248,8 +1249,9 @@ get_our_ghost_pad (GstDecodeBin * decode_bin, GstPad * pad)
   pad_it = gst_element_iterate_src_pads (GST_ELEMENT (decode_bin));
   while (!done) {
     db_pad = NULL;
-    switch (gst_iterator_next (pad_it, (gpointer) & db_pad)) {
-      case GST_ITERATOR_OK:
+    switch (gst_iterator_next (pad_it, &item)) {
+      case GST_ITERATOR_OK:{
+        db_pad = g_value_get_object (&item);
         GST_DEBUG_OBJECT (decode_bin, "looking at pad %s:%s",
             GST_DEBUG_PAD_NAME (db_pad));
         if (GST_IS_GHOST_PAD (db_pad)) {
@@ -1268,8 +1270,9 @@ get_our_ghost_pad (GstDecodeBin * decode_bin, GstPad * pad)
           }
         }
         /* Not the right one */
-        gst_object_unref (db_pad);
+        g_value_reset (&item);
         break;
+      }
       case GST_ITERATOR_RESYNC:
         gst_iterator_resync (pad_it);
         break;
@@ -1281,6 +1284,7 @@ get_our_ghost_pad (GstDecodeBin * decode_bin, GstPad * pad)
         break;
     }
   }
+  g_value_unset (&item);
   gst_iterator_free (pad_it);
 
   return db_pad;
@@ -1295,7 +1299,7 @@ remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
 {
   GstIterator *iter;
   gboolean done = FALSE;
-  gpointer item;
+  GValue item = { 0, };
   GstElement *elem = GST_ELEMENT (GST_OBJECT_PARENT (pad));
 
   while (GST_OBJECT_PARENT (elem) &&
@@ -1322,7 +1326,7 @@ remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
         GstPad *ghostpad;
         GstPad *peer;
 
-        pad = GST_PAD (item);
+        pad = g_value_get_object (&item);
         GST_DEBUG_OBJECT (decode_bin, "inspecting internal pad %s:%s",
             GST_DEBUG_PAD_NAME (pad));
 
@@ -1336,6 +1340,7 @@ remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
 
           gst_element_remove_pad (GST_ELEMENT (decode_bin), ghostpad);
           gst_object_unref (ghostpad);
+          g_value_reset (&item);
           continue;
         } else {
           GST_DEBUG_OBJECT (decode_bin, "not one of our ghostpads");
@@ -1368,7 +1373,7 @@ remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
           }
           gst_object_unref (peer);
         }
-        gst_object_unref (item);
+        g_value_reset (&item);
       }
         break;
       case GST_ITERATOR_RESYNC:
@@ -1384,7 +1389,7 @@ remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
     }
   }
   GST_DEBUG_OBJECT (decode_bin, "removing %s", GST_ELEMENT_NAME (elem));
-
+  g_value_unset (&item);
   gst_iterator_free (iter);
 
 no_iter:
@@ -1508,7 +1513,7 @@ new_pad (GstElement * element, GstPad * pad, GstDynamic * dynamic)
   /* see if any more pending dynamic connections exist */
   more = gst_decode_bin_is_dynamic (decode_bin);
 
-  caps = gst_pad_get_caps (pad);
+  caps = gst_pad_get_caps (pad, NULL);
   close_pad_link (element, pad, caps, decode_bin, more);
   if (caps)
     gst_caps_unref (caps);
@@ -1777,7 +1782,7 @@ close_link (GstElement * element, GstDecodeBin * decode_bin)
         GST_OBJECT_NAME (pad));
 
     /* continue autoplugging on the pads */
-    caps = gst_pad_get_caps (pad);
+    caps = gst_pad_get_caps (pad, NULL);
     close_pad_link (element, pad, caps, decode_bin, more);
     if (caps)
       gst_caps_unref (caps);
@@ -1860,16 +1865,17 @@ disconnect_unlinked_signals (GstDecodeBin * decode_bin, GstElement * element)
 {
   GstIterator *pad_it = NULL;
   gboolean done = FALSE;
+  GstPad *pad = NULL;
+  GValue item = { 0, };
 
   pad_it = gst_element_iterate_src_pads (element);
   while (!done) {
-    GstPad *pad = NULL;
-
-    switch (gst_iterator_next (pad_it, (gpointer) & pad)) {
+    switch (gst_iterator_next (pad_it, &item)) {
       case GST_ITERATOR_OK:
+        pad = g_value_get_object (&item);
         g_signal_handlers_disconnect_by_func (pad, (gpointer) unlinked,
             decode_bin);
-        gst_object_unref (pad);
+        g_value_reset (&item);
         break;
       case GST_ITERATOR_RESYNC:
         gst_iterator_resync (pad_it);
@@ -1879,6 +1885,7 @@ disconnect_unlinked_signals (GstDecodeBin * decode_bin, GstElement * element)
         break;
     }
   }
+  g_value_unset (&item);
   gst_iterator_free (pad_it);
 }
 
@@ -1889,6 +1896,9 @@ cleanup_decodebin (GstDecodeBin * decode_bin)
   GstIterator *elem_it = NULL, *gpad_it = NULL;
   GstPad *typefind_pad = NULL;
   gboolean done = FALSE;
+  GstElement *element = NULL;
+  GstPad *pad = NULL;
+  GValue item = { 0, };
 
   g_return_if_fail (GST_IS_DECODE_BIN (decode_bin));
 
@@ -1902,17 +1912,16 @@ cleanup_decodebin (GstDecodeBin * decode_bin)
 
   elem_it = gst_bin_iterate_elements (GST_BIN (decode_bin));
   while (!done) {
-    GstElement *element = NULL;
-
-    switch (gst_iterator_next (elem_it, (gpointer) & element)) {
+    switch (gst_iterator_next (elem_it, &item)) {
       case GST_ITERATOR_OK:
+        element = g_value_get_object (&item);
         if (element != decode_bin->typefind && element != decode_bin->fakesink) {
           GST_DEBUG_OBJECT (element, "removing autoplugged element");
           disconnect_unlinked_signals (decode_bin, element);
           gst_element_set_state (element, GST_STATE_NULL);
           gst_bin_remove (GST_BIN (decode_bin), element);
         }
-        gst_object_unref (element);
+        g_value_reset (&item);
         break;
       case GST_ITERATOR_RESYNC:
         gst_iterator_resync (elem_it);
@@ -1925,22 +1934,22 @@ cleanup_decodebin (GstDecodeBin * decode_bin)
         break;
     }
   }
+  g_value_unset (&item);
   gst_iterator_free (elem_it);
 
   done = FALSE;
   gpad_it = gst_element_iterate_pads (GST_ELEMENT (decode_bin));
   while (!done) {
-    GstPad *pad = NULL;
-
-    switch (gst_iterator_next (gpad_it, (gpointer) & pad)) {
+    switch (gst_iterator_next (gpad_it, &item)) {
       case GST_ITERATOR_OK:
+        pad = g_value_get_object (&item);
         GST_DEBUG_OBJECT (pad, "inspecting pad %s:%s",
             GST_DEBUG_PAD_NAME (pad));
         if (GST_IS_GHOST_PAD (pad) && GST_PAD_IS_SRC (pad)) {
           GST_DEBUG_OBJECT (pad, "removing ghost pad");
           gst_element_remove_pad (GST_ELEMENT (decode_bin), pad);
         }
-        gst_object_unref (pad);
+        g_value_reset (&item);
         break;
       case GST_ITERATOR_RESYNC:
         gst_iterator_resync (gpad_it);
@@ -1953,6 +1962,7 @@ cleanup_decodebin (GstDecodeBin * decode_bin)
         break;
     }
   }
+  g_value_unset (&item);
   gst_iterator_free (gpad_it);
 
   if (GST_IS_PAD (typefind_pad)) {
index 0e8c040..140d8e6 100644 (file)
@@ -1888,16 +1888,13 @@ get_pad_caps (GstPad * pad)
 
   /* first check the pad caps, if this is set, we are positively sure it is
    * fixed and exactly what the element will produce. */
-  GST_OBJECT_LOCK (pad);
-  if ((caps = GST_PAD_CAPS (pad)))
-    gst_caps_ref (caps);
-  GST_OBJECT_UNLOCK (pad);
+  caps = gst_pad_get_current_caps (pad);
 
   /* then use the getcaps function if we don't have caps. These caps might not
    * be fixed in some cases, in which case analyze_new_pad will set up a
    * notify::caps signal to continue autoplugging. */
   if (caps == NULL)
-    caps = gst_pad_get_caps_reffed (pad);
+    caps = gst_pad_get_caps (pad, NULL);
 
   return caps;
 }
@@ -2790,6 +2787,7 @@ gst_decode_group_control_demuxer_pad (GstDecodeGroup * group, GstPad * pad)
   GstDecodeBin *dbin;
   GstPad *srcpad, *sinkpad;
   GstIterator *it = NULL;
+  GValue item = { 0, };
 
   dbin = group->dbin;
 
@@ -2812,19 +2810,19 @@ gst_decode_group_control_demuxer_pad (GstDecodeGroup * group, GstPad * pad)
 
   it = gst_pad_iterate_internal_links (sinkpad);
 
-  if (!it || (gst_iterator_next (it, (gpointer) & srcpad)) != GST_ITERATOR_OK
-      || srcpad == NULL) {
+  if (!it || (gst_iterator_next (it, &item)) != GST_ITERATOR_OK
+      || ((srcpad = g_value_dup_object (&item)) == NULL)) {
     GST_ERROR_OBJECT (dbin,
         "Couldn't get srcpad from multiqueue for sinkpad %" GST_PTR_FORMAT,
         sinkpad);
     goto error;
   }
-
   CHAIN_MUTEX_LOCK (group->parent);
   group->reqpads = g_list_prepend (group->reqpads, gst_object_ref (sinkpad));
   CHAIN_MUTEX_UNLOCK (group->parent);
 
 beach:
+  g_value_unset (&item);
   if (it)
     gst_iterator_free (it);
   gst_object_unref (sinkpad);
@@ -3115,11 +3113,13 @@ _gst_element_get_linked_caps (GstElement * src, GstElement * sink)
   GstPad *pad, *peer;
   gboolean done = FALSE;
   GstCaps *caps = NULL;
+  GValue item = { 0, };
 
   it = gst_element_iterate_src_pads (src);
   while (!done) {
-    switch (gst_iterator_next (it, (gpointer) & pad)) {
+    switch (gst_iterator_next (it, &item)) {
       case GST_ITERATOR_OK:
+        pad = g_value_get_object (&item);
         peer = gst_pad_get_peer (pad);
         if (peer) {
           parent = gst_pad_get_parent_element (peer);
@@ -3132,7 +3132,7 @@ _gst_element_get_linked_caps (GstElement * src, GstElement * sink)
             gst_object_unref (parent);
           gst_object_unref (peer);
         }
-        gst_object_unref (pad);
+        g_value_reset (&item);
         break;
       case GST_ITERATOR_RESYNC:
         gst_iterator_resync (it);
@@ -3143,7 +3143,7 @@ _gst_element_get_linked_caps (GstElement * src, GstElement * sink)
         break;
     }
   }
-
+  g_value_unset (&item);
   gst_iterator_free (it);
 
   return caps;
@@ -3451,8 +3451,7 @@ gst_decode_pad_init (GstDecodePad * pad)
   pad->blocked = FALSE;
   pad->exposed = FALSE;
   pad->drained = FALSE;
-  gst_object_ref (pad);
-  gst_object_sink (pad);
+  gst_object_ref_sink (pad);
 }
 
 static void
@@ -3643,13 +3642,13 @@ find_sink_pad (GstElement * element)
 {
   GstIterator *it;
   GstPad *pad = NULL;
-  gpointer point;
+  GValue item = { 0, };
 
   it = gst_element_iterate_sink_pads (element);
 
-  if ((gst_iterator_next (it, &point)) == GST_ITERATOR_OK)
-    pad = (GstPad *) point;
-
+  if ((gst_iterator_next (it, &item)) == GST_ITERATOR_OK)
+    pad = g_value_dup_object (&item);
+  g_value_unset (&item);
   gst_iterator_free (it);
 
   return pad;
index 847e12f..3591f89 100644 (file)
@@ -1333,7 +1333,7 @@ new_decoded_pad_full (GstElement * element, GstPad * pad, gboolean last,
   GST_DEBUG ("play base: new decoded pad. Last: %d", last);
 
   /* first see if this pad has interesting caps */
-  caps = gst_pad_get_caps (pad);
+  caps = gst_pad_get_caps (pad, NULL);
   if (caps == NULL || gst_caps_is_empty (caps) || gst_caps_is_any (caps))
     goto no_type;
 
@@ -1815,7 +1815,7 @@ has_all_raw_caps (GstPad * pad, gboolean * all_raw)
   guint i, num_raw = 0;
   gboolean res = FALSE;
 
-  caps = gst_pad_get_caps (pad);
+  caps = gst_pad_get_caps (pad, NULL);
   if (caps == NULL)
     return FALSE;
 
@@ -1871,6 +1871,7 @@ analyse_source (GstPlayBaseBin * play_base_bin, gboolean * is_raw,
   GstIterator *pads_iter;
   gboolean done = FALSE;
   gboolean res = TRUE;
+  GValue item = { 0, };
 
   *have_out = FALSE;
   *is_raw = FALSE;
@@ -1880,7 +1881,7 @@ analyse_source (GstPlayBaseBin * play_base_bin, gboolean * is_raw,
   while (!done) {
     GstPad *pad = NULL;
 
-    switch (gst_iterator_next (pads_iter, (gpointer) & pad)) {
+    switch (gst_iterator_next (pads_iter, &item)) {
       case GST_ITERATOR_ERROR:
         res = FALSE;
         /* FALLTROUGH */
@@ -1895,12 +1896,13 @@ analyse_source (GstPlayBaseBin * play_base_bin, gboolean * is_raw,
         gst_iterator_resync (pads_iter);
         break;
       case GST_ITERATOR_OK:
+        pad = g_value_get_object (&item);
         /* we now officially have an ouput pad */
         *have_out = TRUE;
 
         /* if FALSE, this pad has no caps and we continue with the next pad. */
         if (!has_all_raw_caps (pad, is_raw)) {
-          gst_object_unref (pad);
+          g_value_reset (&item);
           break;
         }
 
@@ -1910,10 +1912,11 @@ analyse_source (GstPlayBaseBin * play_base_bin, gboolean * is_raw,
               play_base_bin, FALSE);
         }
 
-        gst_object_unref (pad);
+        g_value_reset (&item);
         break;
     }
   }
+  g_value_unset (&item);
   gst_iterator_free (pads_iter);
 
   if (!*have_out) {
index 57b5dbe..2a56156 100644 (file)
@@ -408,7 +408,7 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
           0.0, VOLUME_MAX_DOUBLE, 1.0,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_klass, ARG_FRAME,
-      gst_param_spec_mini_object ("frame", "Frame",
+      g_param_spec_boxed ("frame", "Frame",
           "The last frame (NULL = no video available)", GST_TYPE_BUFFER,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_klass, ARG_FONT_DESC,
@@ -638,8 +638,7 @@ gst_play_bin_set_property (GObject * object, guint prop_id,
       }
       play_bin->video_sink = g_value_get_object (value);
       if (play_bin->video_sink != NULL) {
-        gst_object_ref (play_bin->video_sink);
-        gst_object_sink (GST_OBJECT_CAST (play_bin->video_sink));
+        gst_object_ref_sink (play_bin->video_sink);
       }
       /* when changing the videosink, we just remove the
        * video pipeline from the cache so that it will be
@@ -656,8 +655,7 @@ gst_play_bin_set_property (GObject * object, guint prop_id,
       }
       play_bin->audio_sink = g_value_get_object (value);
       if (play_bin->audio_sink != NULL) {
-        gst_object_ref (play_bin->audio_sink);
-        gst_object_sink (GST_OBJECT_CAST (play_bin->audio_sink));
+        gst_object_ref_sink (play_bin->audio_sink);
       }
       g_hash_table_remove (play_bin->cache, "abin");
       break;
@@ -668,8 +666,7 @@ gst_play_bin_set_property (GObject * object, guint prop_id,
 
       /* Take ownership */
       if (pending_visualisation) {
-        gst_object_ref (pending_visualisation);
-        gst_object_sink (pending_visualisation);
+        gst_object_ref_sink (pending_visualisation);
       }
 
       /* Do we already have a visualisation change pending ? */
@@ -787,6 +784,7 @@ handoff (GstElement * identity, GstBuffer * frame, gpointer data)
 {
   GstPlayBin *play_bin = GST_PLAY_BIN (data);
 
+#if 0
   /* applications need to know the buffer caps,
    * make sure they are always set on the frame */
   if (GST_BUFFER_CAPS (frame) == NULL) {
@@ -797,6 +795,7 @@ handoff (GstElement * identity, GstBuffer * frame, gpointer data)
       gst_object_unref (pad);
     }
   }
+#endif
 
   gst_buffer_replace (&play_bin->frame, frame);
 }
@@ -1539,7 +1538,7 @@ link_failed:
     GstCaps *caps;
 
     /* could not link this stream */
-    caps = gst_pad_get_caps (srcpad);
+    caps = gst_pad_get_caps (srcpad, NULL);
     capsstr = gst_caps_to_string (caps);
     g_warning ("could not link %s: %d", capsstr, linkres);
     GST_DEBUG_OBJECT (play_bin,
@@ -1556,7 +1555,7 @@ subtitle_failed:
     GstCaps *caps;
 
     /* could not link this stream */
-    caps = gst_pad_get_caps (subtitle_pad);
+    caps = gst_pad_get_caps (subtitle_pad, NULL);
     GST_WARNING_OBJECT (play_bin, "subtitle link failed when adding sink, "
         "caps = %" GST_PTR_FORMAT ", reason %d", caps, linkres);
     gst_caps_unref (caps);
@@ -1860,14 +1859,16 @@ gst_play_bin_handle_redirect_message (GstPlayBin * playbin, GstMessage * msg)
   guint size, i;
   GstPlayBaseBin *playbasebin = GST_PLAY_BASE_BIN (playbin);
   guint connection_speed = playbasebin->connection_speed;
+  const GstStructure *structure;
 
   GST_DEBUG_OBJECT (playbin, "redirect message: %" GST_PTR_FORMAT, msg);
   GST_DEBUG_OBJECT (playbin, "connection speed: %u", connection_speed);
 
-  if (connection_speed == 0 || msg->structure == NULL)
+  structure = gst_message_get_structure (msg);
+  if (connection_speed == 0 || structure == NULL)
     return msg;
 
-  locations_list = gst_structure_get_value (msg->structure, "locations");
+  locations_list = gst_structure_get_value (structure, "locations");
   if (locations_list == NULL)
     return msg;
 
@@ -1919,8 +1920,11 @@ gst_play_bin_handle_redirect_message (GstPlayBin * playbin, GstMessage * msg)
 static void
 gst_play_bin_handle_message (GstBin * bin, GstMessage * msg)
 {
-  if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ELEMENT && msg->structure != NULL
-      && gst_structure_has_name (msg->structure, "redirect")) {
+  const GstStructure *structure;
+
+  structure = gst_message_get_structure (msg);
+  if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ELEMENT && structure != NULL
+      && gst_structure_has_name (structure, "redirect")) {
     msg = gst_play_bin_handle_redirect_message (GST_PLAY_BIN (bin), msg);
   }
 
index c46f110..e738cf2 100644 (file)
@@ -763,7 +763,7 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
    * The #GstCaps on the buffer will describe the format of the buffer.
    */
   g_object_class_install_property (gobject_klass, PROP_FRAME,
-      gst_param_spec_mini_object ("frame", "Frame",
+      g_param_spec_boxed ("frame", "Frame",
           "The last frame (NULL = no video available)",
           GST_TYPE_BUFFER, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_klass, PROP_FONT_DESC,
@@ -1594,9 +1594,10 @@ gst_play_bin_suburidecodebin_seek_to_start (GstElement * suburidecodebin)
 {
   GstIterator *it = gst_element_iterate_src_pads (suburidecodebin);
   GstPad *sinkpad;
+  GValue item = { 0, };
 
-  if (it && gst_iterator_next (it, (gpointer) & sinkpad) == GST_ITERATOR_OK
-      && sinkpad) {
+  if (it && gst_iterator_next (it, &item) == GST_ITERATOR_OK
+      && ((sinkpad = g_value_get_object (&item)) != NULL)) {
     GstEvent *event;
 
     event =
@@ -1610,7 +1611,7 @@ gst_play_bin_suburidecodebin_seek_to_start (GstElement * suburidecodebin)
         GST_DEBUG_OBJECT (suburidecodebin, "Seeking to the beginning failed!");
     }
 
-    gst_object_unref (sinkpad);
+    g_value_unset (&item);
   }
 
   if (it)
@@ -1623,6 +1624,7 @@ gst_play_bin_suburidecodebin_block (GstElement * suburidecodebin,
 {
   GstIterator *it = gst_element_iterate_src_pads (suburidecodebin);
   gboolean done = FALSE;
+  GValue item = { 0, };
 
   GST_DEBUG_OBJECT (suburidecodebin, "Blocking suburidecodebin: %d", block);
 
@@ -1631,11 +1633,12 @@ gst_play_bin_suburidecodebin_block (GstElement * suburidecodebin,
   while (!done) {
     GstPad *sinkpad;
 
-    switch (gst_iterator_next (it, (gpointer) & sinkpad)) {
+    switch (gst_iterator_next (it, &item)) {
       case GST_ITERATOR_OK:
+        sinkpad = g_value_get_object (&item);
         gst_pad_set_blocked_async (sinkpad, block, _suburidecodebin_blocked_cb,
             NULL);
-        gst_object_unref (sinkpad);
+        g_value_reset (&item);
         break;
       case GST_ITERATOR_DONE:
         done = TRUE;
@@ -1648,6 +1651,7 @@ gst_play_bin_suburidecodebin_block (GstElement * suburidecodebin,
         break;
     }
   }
+  g_value_unset (&item);
   gst_iterator_free (it);
 }
 
@@ -2253,6 +2257,7 @@ gst_play_bin_handle_message (GstBin * bin, GstMessage * msg)
         GstMessage *new_msg;
         GstIterator *it;
         gboolean done = FALSE;
+        GValue item = { 0, };
 
         gst_message_parse_error (msg, &err, &debug);
         new_msg = gst_message_new_warning (msg->src, err, debug);
@@ -2272,15 +2277,16 @@ gst_play_bin_handle_message (GstBin * bin, GstMessage * msg)
           GstPad *p = NULL;
           GstIteratorResult res;
 
-          res = gst_iterator_next (it, (gpointer) & p);
+          res = gst_iterator_next (it, &item);
 
           switch (res) {
             case GST_ITERATOR_DONE:
               done = TRUE;
               break;
             case GST_ITERATOR_OK:
+              p = g_value_get_object (&item);
               pad_removed_cb (NULL, p, group);
-              gst_object_unref (p);
+              g_value_reset (&item);
               break;
 
             case GST_ITERATOR_RESYNC:
@@ -2291,6 +2297,7 @@ gst_play_bin_handle_message (GstBin * bin, GstMessage * msg)
               break;
           }
         }
+        g_value_unset (&item);
         if (it)
           gst_iterator_free (it);
 
@@ -2388,7 +2395,7 @@ stream_changed_data_probe (GstPad * pad, GstMiniObject * object, gpointer data)
   }
 
   if (GST_IS_EVENT (object)
-      && GST_EVENT_TYPE (GST_EVENT_CAST (object)) == GST_EVENT_NEWSEGMENT) {
+      && GST_EVENT_TYPE (GST_EVENT_CAST (object)) == GST_EVENT_SEGMENT) {
     /* push the event first, then send the delayed one */
     gst_event_ref (GST_EVENT_CAST (object));
     gst_pad_send_event (pad, GST_EVENT_CAST (object));
@@ -2471,7 +2478,7 @@ pad_added_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
 
   playbin = group->playbin;
 
-  caps = gst_pad_get_caps_reffed (pad);
+  caps = gst_pad_get_caps (pad, NULL);
   s = gst_caps_get_structure (caps, 0);
   name = gst_structure_get_name (s);
 
@@ -2985,7 +2992,7 @@ autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps,
     if (GST_STATE (sink) < GST_STATE_READY)
       gst_element_set_state (sink, GST_STATE_READY);
 
-    sinkcaps = gst_pad_get_caps_reffed (sinkpad);
+    sinkcaps = gst_pad_get_caps (sinkpad, NULL);
     if (!gst_caps_is_any (sinkcaps))
       ret = !gst_pad_accept_caps (sinkpad, caps);
     gst_caps_unref (sinkcaps);
@@ -3017,7 +3024,7 @@ autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps,
       if (GST_STATE (sink) < GST_STATE_READY)
         gst_element_set_state (sink, GST_STATE_READY);
 
-      sinkcaps = gst_pad_get_caps_reffed (sinkpad);
+      sinkcaps = gst_pad_get_caps (sinkpad, NULL);
       if (!gst_caps_is_any (sinkcaps))
         ret = !gst_pad_accept_caps (sinkpad, caps);
       gst_caps_unref (sinkcaps);
@@ -3038,7 +3045,7 @@ autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps,
       if (GST_STATE (sink) < GST_STATE_READY)
         gst_element_set_state (sink, GST_STATE_READY);
 
-      sinkcaps = gst_pad_get_caps_reffed (sinkpad);
+      sinkcaps = gst_pad_get_caps (sinkpad, NULL);
       if (!gst_caps_is_any (sinkcaps))
         ret = !gst_pad_accept_caps (sinkpad, caps);
       gst_caps_unref (sinkcaps);
index b36ab1b..141e0ae 100644 (file)
@@ -253,7 +253,7 @@ static void gst_play_sink_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * spec);
 
 static GstPad *gst_play_sink_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * name);
+    GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
 static void gst_play_sink_release_request_pad (GstElement * element,
     GstPad * pad);
 static gboolean gst_play_sink_send_event (GstElement * element,
@@ -373,7 +373,7 @@ gst_play_sink_class_init (GstPlaySinkClass * klass)
    * Since: 0.10.30
    */
   g_object_class_install_property (gobject_klass, PROP_FRAME,
-      gst_param_spec_mini_object ("frame", "Frame",
+      g_param_spec_boxed ("frame", "Frame",
           "The last frame (NULL = no video available)",
           GST_TYPE_BUFFER, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   /**
@@ -962,15 +962,14 @@ typedef struct
 } FindPropertyHelper;
 
 static gint
-find_property (GstElement * element, FindPropertyHelper * helper)
+find_property (const GValue * item, FindPropertyHelper * helper)
 {
+  GstElement *element = g_value_get_object (item);
   if (helper->need_sink && !element_is_sink (element)) {
-    gst_object_unref (element);
     return 1;
   }
 
   if (!element_has_property (element, helper->prop_name, helper->prop_type)) {
-    gst_object_unref (element);
     return 1;
   }
 
@@ -993,15 +992,18 @@ gst_play_sink_find_property_sinks (GstPlaySink * playsink, GstElement * obj,
   if (element_has_property (obj, name, expected_type)) {
     result = obj;
   } else if (GST_IS_BIN (obj)) {
+    gboolean found;
+    GValue item = { 0, };
     FindPropertyHelper helper = { name, expected_type, TRUE };
 
     it = gst_bin_iterate_recurse (GST_BIN_CAST (obj));
-    result = gst_iterator_find_custom (it,
-        (GCompareFunc) find_property, &helper);
+    found = gst_iterator_find_custom (it,
+        (GCompareFunc) find_property, &item, &helper);
     gst_iterator_free (it);
+    if (found)
+      result = g_value_get_object (&item);
     /* we don't need the extra ref */
-    if (result)
-      gst_object_unref (result);
+    g_value_unset (&item);
   }
   return result;
 }
@@ -1015,12 +1017,17 @@ gst_play_sink_find_property (GstPlaySink * playsink, GstElement * obj,
   GstIterator *it;
 
   if (GST_IS_BIN (obj)) {
+    gboolean found;
+    GValue item = { 0, };
     FindPropertyHelper helper = { name, expected_type, FALSE };
 
     it = gst_bin_iterate_recurse (GST_BIN_CAST (obj));
-    result = gst_iterator_find_custom (it,
-        (GCompareFunc) find_property, &helper);
+    found = gst_iterator_find_custom (it,
+        (GCompareFunc) find_property, &item, &helper);
     gst_iterator_free (it);
+    if (found)
+      result = g_value_dup_object (&item);
+    g_value_unset (&item);
   } else {
     if (element_has_property (obj, name, expected_type)) {
       result = obj;
@@ -2197,6 +2204,7 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
       goto no_chain;
 
     if (!playsink->video_sinkpad_stream_synchronizer) {
+      GValue item = { 0, };
       GstIterator *it;
 
       playsink->video_sinkpad_stream_synchronizer =
@@ -2205,8 +2213,9 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
       it = gst_pad_iterate_internal_links
           (playsink->video_sinkpad_stream_synchronizer);
       g_assert (it);
-      gst_iterator_next (it,
-          (gpointer *) & playsink->video_srcpad_stream_synchronizer);
+      gst_iterator_next (it, &item);
+      playsink->video_srcpad_stream_synchronizer = g_value_dup_object (&item);
+      g_value_unset (&item);
       g_assert (playsink->video_srcpad_stream_synchronizer);
       gst_iterator_free (it);
     }
@@ -2353,6 +2362,7 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
     }
 
     if (!playsink->audio_sinkpad_stream_synchronizer) {
+      GValue item = { 0, };
       GstIterator *it;
 
       playsink->audio_sinkpad_stream_synchronizer =
@@ -2361,8 +2371,9 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
       it = gst_pad_iterate_internal_links
           (playsink->audio_sinkpad_stream_synchronizer);
       g_assert (it);
-      gst_iterator_next (it,
-          (gpointer *) & playsink->audio_srcpad_stream_synchronizer);
+      gst_iterator_next (it, &item);
+      playsink->audio_srcpad_stream_synchronizer = g_value_dup_object (&item);
+      g_value_unset (&item);
       g_assert (playsink->audio_srcpad_stream_synchronizer);
       gst_iterator_free (it);
     }
@@ -2472,14 +2483,17 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
       add_chain (GST_PLAY_CHAIN (playsink->textchain), TRUE);
 
       if (!playsink->text_sinkpad_stream_synchronizer) {
+        GValue item = { 0, };
+
         playsink->text_sinkpad_stream_synchronizer =
             gst_element_get_request_pad (GST_ELEMENT_CAST
             (playsink->stream_synchronizer), "sink_%d");
         it = gst_pad_iterate_internal_links
             (playsink->text_sinkpad_stream_synchronizer);
         g_assert (it);
-        gst_iterator_next (it,
-            (gpointer *) & playsink->text_srcpad_stream_synchronizer);
+        gst_iterator_next (it, &item);
+        playsink->text_srcpad_stream_synchronizer = g_value_dup_object (&item);
+        g_value_unset (&item);
         g_assert (playsink->text_srcpad_stream_synchronizer);
         gst_iterator_free (it);
 
@@ -2792,7 +2806,8 @@ gst_play_sink_convert_frame (GstPlaySink * playsink, GstCaps * caps)
     GstBuffer *temp;
     GError *err = NULL;
 
-    temp = gst_video_convert_frame (result, caps, 25 * GST_SECOND, &err);
+    /* FIXME, need to get the input buffer caps */
+    temp = gst_video_convert_frame (result, NULL, caps, 25 * GST_SECOND, &err);
     gst_buffer_unref (result);
     if (temp == NULL && err) {
       /* I'm really uncertain whether we should make playsink post an error
@@ -2832,7 +2847,7 @@ is_raw_pad (GstPad * pad)
   if (!caps) {
     guint i, n;
 
-    caps = gst_pad_get_caps_reffed (peer);
+    caps = gst_pad_get_caps (peer, NULL);
 
     n = gst_caps_get_size (caps);
     for (i = 0; i < n; i++) {
@@ -3115,7 +3130,7 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type)
 
 static GstPad *
 gst_play_sink_request_new_pad (GstElement * element, GstPadTemplate * templ,
-    const gchar * name)
+    const gchar * name, const GstCaps * caps)
 {
   GstPlaySink *psink;
   GstPad *pad;
index a179e73..be4e1ec 100644 (file)
@@ -73,28 +73,6 @@ post_missing_element_message (GstPlaySinkAudioConvert * self,
 }
 
 static void
-distribute_running_time (GstElement * element, const GstSegment * segment)
-{
-  GstEvent *event;
-  GstPad *pad;
-
-  pad = gst_element_get_static_pad (element, "sink");
-
-  if (segment->accum) {
-    event = gst_event_new_new_segment_full (FALSE, segment->rate,
-        segment->applied_rate, segment->format, 0, segment->accum, 0);
-    gst_pad_push_event (pad, event);
-  }
-
-  event = gst_event_new_new_segment_full (FALSE, segment->rate,
-      segment->applied_rate, segment->format,
-      segment->start, segment->stop, segment->time);
-  gst_pad_push_event (pad, event);
-
-  gst_object_unref (pad);
-}
-
-static void
 pad_blocked_cb (GstPad * pad, gboolean blocked, GstPlaySinkAudioConvert * self)
 {
   GstPad *peer;
@@ -111,7 +89,7 @@ pad_blocked_cb (GstPad * pad, gboolean blocked, GstPlaySinkAudioConvert * self)
   peer = gst_pad_get_peer (self->sinkpad);
   caps = gst_pad_get_negotiated_caps (peer);
   if (!caps)
-    caps = gst_pad_get_caps_reffed (peer);
+    caps = gst_pad_get_caps (peer, NULL);
   gst_object_unref (peer);
 
   raw = is_raw_caps (caps);
@@ -142,7 +120,6 @@ pad_blocked_cb (GstPad * pad, gboolean blocked, GstPlaySinkAudioConvert * self)
       } else {
         gst_bin_add (bin, self->conv);
         gst_element_sync_state_with_parent (self->conv);
-        distribute_running_time (self->conv, &self->segment);
         prev = head = self->conv;
       }
 
@@ -155,7 +132,6 @@ pad_blocked_cb (GstPad * pad, gboolean blocked, GstPlaySinkAudioConvert * self)
       } else {
         gst_bin_add (bin, self->resample);
         gst_element_sync_state_with_parent (self->resample);
-        distribute_running_time (self->resample, &self->segment);
         if (prev) {
           if (!gst_element_link_pads_full (prev, "src", self->resample, "sink",
                   GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
@@ -170,7 +146,6 @@ pad_blocked_cb (GstPad * pad, gboolean blocked, GstPlaySinkAudioConvert * self)
     if (self->use_volume && self->volume) {
       gst_bin_add (bin, gst_object_ref (self->volume));
       gst_element_sync_state_with_parent (self->volume);
-      distribute_running_time (self->volume, &self->segment);
       if (prev) {
         if (!gst_element_link_pads_full (prev, "src", self->volume, "sink",
                 GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
@@ -261,20 +236,11 @@ gst_play_sink_audio_convert_sink_event (GstPad * pad, GstEvent * event)
 
   ret = gst_proxy_pad_event_default (pad, gst_event_ref (event));
 
-  if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
-    gboolean update;
-    gdouble rate, applied_rate;
-    GstFormat format;
-    gint64 start, stop, position;
-
+  if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
     GST_PLAY_SINK_AUDIO_CONVERT_LOCK (self);
-    gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
-        &format, &start, &stop, &position);
-
     GST_DEBUG_OBJECT (self, "Segment before %" GST_SEGMENT_FORMAT,
         &self->segment);
-    gst_segment_set_newsegment_full (&self->segment, update, rate, applied_rate,
-        format, start, stop, position);
+    gst_event_copy_segment (event, &self->segment);
     GST_DEBUG_OBJECT (self, "Segment after %" GST_SEGMENT_FORMAT,
         &self->segment);
     GST_PLAY_SINK_AUDIO_CONVERT_UNLOCK (self);
@@ -341,7 +307,7 @@ gst_play_sink_audio_convert_sink_setcaps (GstPad * pad, GstCaps * caps)
 }
 
 static GstCaps *
-gst_play_sink_audio_convert_getcaps (GstPad * pad)
+gst_play_sink_audio_convert_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstPlaySinkAudioConvert *self =
       GST_PLAY_SINK_AUDIO_CONVERT (gst_pad_get_parent (pad));
@@ -357,10 +323,10 @@ gst_play_sink_audio_convert_getcaps (GstPad * pad)
 
   peer = gst_pad_get_peer (otherpad);
   if (peer) {
-    ret = gst_pad_get_caps_reffed (peer);
+    ret = gst_pad_get_caps (peer, filter);
     gst_object_unref (peer);
   } else {
-    ret = gst_caps_new_any ();
+    ret = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
   }
 
   gst_object_unref (otherpad);
index 692da0f..75352f3 100644 (file)
@@ -73,28 +73,6 @@ post_missing_element_message (GstPlaySinkVideoConvert * self,
 }
 
 static void
-distribute_running_time (GstElement * element, const GstSegment * segment)
-{
-  GstEvent *event;
-  GstPad *pad;
-
-  pad = gst_element_get_static_pad (element, "sink");
-
-  if (segment->accum) {
-    event = gst_event_new_new_segment_full (FALSE, segment->rate,
-        segment->applied_rate, segment->format, 0, segment->accum, 0);
-    gst_pad_push_event (pad, event);
-  }
-
-  event = gst_event_new_new_segment_full (FALSE, segment->rate,
-      segment->applied_rate, segment->format,
-      segment->start, segment->stop, segment->time);
-  gst_pad_push_event (pad, event);
-
-  gst_object_unref (pad);
-}
-
-static void
 pad_blocked_cb (GstPad * pad, gboolean blocked, GstPlaySinkVideoConvert * self)
 {
   GstPad *peer;
@@ -111,7 +89,7 @@ pad_blocked_cb (GstPad * pad, gboolean blocked, GstPlaySinkVideoConvert * self)
   peer = gst_pad_get_peer (self->sinkpad);
   caps = gst_pad_get_negotiated_caps (peer);
   if (!caps)
-    caps = gst_pad_get_caps_reffed (peer);
+    caps = gst_pad_get_caps (peer, NULL);
   gst_object_unref (peer);
 
   raw = is_raw_caps (caps);
@@ -141,7 +119,6 @@ pad_blocked_cb (GstPad * pad, gboolean blocked, GstPlaySinkVideoConvert * self)
     } else {
       gst_bin_add (bin, self->conv);
       gst_element_sync_state_with_parent (self->conv);
-      distribute_running_time (self->conv, &self->segment);
       prev = head = self->conv;
     }
 
@@ -156,7 +133,6 @@ pad_blocked_cb (GstPad * pad, gboolean blocked, GstPlaySinkVideoConvert * self)
       g_object_set (self->scale, "add-borders", TRUE, NULL);
       gst_bin_add (bin, self->scale);
       gst_element_sync_state_with_parent (self->scale);
-      distribute_running_time (self->scale, &self->segment);
       if (prev) {
         if (!gst_element_link_pads_full (prev, "src", self->scale, "sink",
                 GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
@@ -241,20 +217,12 @@ gst_play_sink_video_convert_sink_event (GstPad * pad, GstEvent * event)
 
   ret = gst_proxy_pad_event_default (pad, gst_event_ref (event));
 
-  if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
-    gboolean update;
-    gdouble rate, applied_rate;
-    GstFormat format;
-    gint64 start, stop, position;
+  if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
 
     GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self);
-    gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
-        &format, &start, &stop, &position);
-
     GST_DEBUG_OBJECT (self, "Segment before %" GST_SEGMENT_FORMAT,
         &self->segment);
-    gst_segment_set_newsegment_full (&self->segment, update, rate, applied_rate,
-        format, start, stop, position);
+    gst_event_copy_segment (event, &self->segment);
     GST_DEBUG_OBJECT (self, "Segment after %" GST_SEGMENT_FORMAT,
         &self->segment);
     GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self);
@@ -321,7 +289,7 @@ gst_play_sink_video_convert_sink_setcaps (GstPad * pad, GstCaps * caps)
 }
 
 static GstCaps *
-gst_play_sink_video_convert_getcaps (GstPad * pad)
+gst_play_sink_video_convert_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstPlaySinkVideoConvert *self =
       GST_PLAY_SINK_VIDEO_CONVERT (gst_pad_get_parent (pad));
@@ -337,10 +305,10 @@ gst_play_sink_video_convert_getcaps (GstPad * pad)
 
   peer = gst_pad_get_peer (otherpad);
   if (peer) {
-    ret = gst_pad_get_caps_reffed (peer);
+    ret = gst_pad_get_caps (peer, filter);
     gst_object_unref (peer);
   } else {
-    ret = gst_caps_new_any ();
+    ret = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
   }
 
   gst_object_unref (otherpad);
index 294eac4..24f0031 100644 (file)
@@ -101,10 +101,8 @@ static GstPadClass *selector_pad_parent_class = NULL;
 
 static void gst_selector_pad_reset (GstSelectorPad * pad);
 static gboolean gst_selector_pad_event (GstPad * pad, GstEvent * event);
-static GstCaps *gst_selector_pad_getcaps (GstPad * pad);
+static GstCaps *gst_selector_pad_getcaps (GstPad * pad, GstCaps * filter);
 static GstFlowReturn gst_selector_pad_chain (GstPad * pad, GstBuffer * buf);
-static GstFlowReturn gst_selector_pad_bufferalloc (GstPad * pad,
-    guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
 
 enum
 {
@@ -239,24 +237,12 @@ gst_selector_pad_event (GstPad * pad, GstEvent * event)
     case GST_EVENT_FLUSH_STOP:
       gst_selector_pad_reset (selpad);
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      gboolean update;
-      GstFormat format;
-      gdouble rate, arate;
-      gint64 start, stop, time;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-          &start, &stop, &time);
-
-      GST_DEBUG_OBJECT (selpad,
-          "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, "
-          "format %d, "
-          "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
-          G_GINT64_FORMAT, update, rate, arate, format, start, stop, time);
-
-      gst_segment_set_newsegment_full (&selpad->segment, update,
-          rate, arate, format, start, stop, time);
+      gst_event_copy_segment (event, &selpad->segment);
+
+      GST_DEBUG_OBJECT (selpad, "configured SEGMENT %" GST_SEGMENT_FORMAT,
+          &selpad->segment);
       /* if we are not going to forward the segment, mark the segment as
        * pending */
       if (!forward)
@@ -295,7 +281,7 @@ gst_selector_pad_event (GstPad * pad, GstEvent * event)
 }
 
 static GstCaps *
-gst_selector_pad_getcaps (GstPad * pad)
+gst_selector_pad_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstStreamSelector *sel;
   GstCaps *caps;
@@ -303,9 +289,9 @@ gst_selector_pad_getcaps (GstPad * pad)
   sel = GST_STREAM_SELECTOR (gst_pad_get_parent (pad));
 
   GST_DEBUG_OBJECT (sel, "Getting caps of srcpad peer");
-  caps = gst_pad_peer_get_caps (sel->srcpad);
+  caps = gst_pad_peer_get_caps (sel->srcpad, filter);
   if (caps == NULL)
-    caps = gst_caps_new_any ();
+    caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
 
   gst_object_unref (sel);
 
@@ -313,48 +299,6 @@ gst_selector_pad_getcaps (GstPad * pad)
 }
 
 static GstFlowReturn
-gst_selector_pad_bufferalloc (GstPad * pad, guint64 offset,
-    guint size, GstCaps * caps, GstBuffer ** buf)
-{
-  GstStreamSelector *sel;
-  GstFlowReturn result;
-  GstPad *active_sinkpad;
-
-  sel = GST_STREAM_SELECTOR (gst_pad_get_parent (pad));
-
-  active_sinkpad = gst_stream_selector_activate_sinkpad (sel, pad);
-
-  /* Fallback allocation for buffers from pads except the selected one */
-  if (pad != active_sinkpad) {
-    GST_DEBUG_OBJECT (sel,
-        "Pad %s:%s is not selected. Performing fallback allocation",
-        GST_DEBUG_PAD_NAME (pad));
-
-    *buf = NULL;
-    result = GST_FLOW_OK;
-  } else {
-    result = gst_pad_alloc_buffer (sel->srcpad, offset, size, caps, buf);
-
-    /* FIXME: HACK. If buffer alloc returns not-linked, perform a fallback
-     * allocation.  This should NOT be necessary, because playbin should
-     * properly block the source pad from running until it's finished hooking 
-     * everything up, but playbin needs refactoring first. */
-    if (result == GST_FLOW_NOT_LINKED) {
-      GST_DEBUG_OBJECT (sel,
-          "No peer pad yet - performing fallback allocation for pad %s:%s",
-          GST_DEBUG_PAD_NAME (pad));
-
-      *buf = NULL;
-      result = GST_FLOW_OK;
-    }
-  }
-
-  gst_object_unref (sel);
-
-  return result;
-}
-
-static GstFlowReturn
 gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
 {
   GstStreamSelector *sel;
@@ -374,7 +318,7 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
   if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
     GST_DEBUG_OBJECT (sel, "received timestamp %" GST_TIME_FORMAT,
         GST_TIME_ARGS (timestamp));
-    gst_segment_set_last_stop (seg, seg->format, timestamp);
+    seg->position = timestamp;
   }
 
   /* Ignore buffers from pads except the selected one */
@@ -383,10 +327,7 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
 
   /* if we have a pending segment, push it out now */
   if (selpad->segment_pending) {
-    gst_pad_push_event (sel->srcpad, gst_event_new_new_segment_full (FALSE,
-            seg->rate, seg->applied_rate, seg->format, seg->start, seg->stop,
-            seg->time));
-
+    gst_pad_push_event (sel->srcpad, gst_event_new_segment (seg));
     selpad->segment_pending = FALSE;
   }
 
@@ -420,11 +361,11 @@ static void gst_stream_selector_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 
 static GstPad *gst_stream_selector_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * unused);
+    GstPadTemplate * templ, const gchar * unused, const GstCaps * caps);
 static void gst_stream_selector_release_pad (GstElement * element,
     GstPad * pad);
 static GstIterator *gst_stream_selector_pad_iterate_linked_pads (GstPad * pad);
-static GstCaps *gst_stream_selector_getcaps (GstPad * pad);
+static GstCaps *gst_stream_selector_getcaps (GstPad * pad, GstCaps * filter);
 
 static GstElementClass *parent_class = NULL;
 
@@ -611,7 +552,7 @@ gst_stream_selector_get_linked_pad (GstPad * pad, gboolean strict)
 }
 
 static GstCaps *
-gst_stream_selector_getcaps (GstPad * pad)
+gst_stream_selector_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstPad *otherpad;
   GstObject *parent;
@@ -622,15 +563,15 @@ gst_stream_selector_getcaps (GstPad * pad)
   if (!otherpad) {
     GST_DEBUG_OBJECT (parent,
         "Pad %s:%s not linked, returning ANY", GST_DEBUG_PAD_NAME (pad));
-    caps = gst_caps_new_any ();
+    caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
   } else {
     GST_DEBUG_OBJECT (parent,
         "Pad %s:%s is linked (to %s:%s), returning peer caps",
         GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (otherpad));
     /* if the peer has caps, use those. If the pad is not linked, this function
      * returns NULL and we return ANY */
-    if (!(caps = gst_pad_peer_get_caps (otherpad)))
-      caps = gst_caps_new_any ();
+    if (!(caps = gst_pad_peer_get_caps (otherpad, filter)))
+      caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
     gst_object_unref (otherpad);
   }
 
@@ -677,16 +618,18 @@ static GstIterator *
 gst_stream_selector_pad_iterate_linked_pads (GstPad * pad)
 {
   GstStreamSelector *sel = GST_STREAM_SELECTOR (gst_pad_get_parent (pad));
+  GValue value = { 0, };
   GstPad *otherpad;
-  GstIterator *ret;
+  GstIterator *ret = NULL;
 
   otherpad = gst_stream_selector_get_linked_pad (pad, TRUE);
-  ret =
-      gst_iterator_new_single (GST_TYPE_PAD, otherpad,
-      (GstCopyFunction) gst_object_ref, (GFreeFunc) gst_object_unref);
-
-  if (otherpad)
+  if (otherpad) {
+    g_value_init (&value, GST_TYPE_PAD);
+    g_value_set_object (&value, otherpad);
+    ret = gst_iterator_new_single (GST_TYPE_PAD, &value);
+    g_value_unset (&value);
     gst_object_unref (otherpad);
+  }
   gst_object_unref (sel);
 
   return ret;
@@ -694,7 +637,7 @@ gst_stream_selector_pad_iterate_linked_pads (GstPad * pad)
 
 static GstPad *
 gst_stream_selector_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * unused)
+    GstPadTemplate * templ, const gchar * unused, const GstCaps * caps)
 {
   GstStreamSelector *sel;
   gchar *name = NULL;
@@ -719,8 +662,6 @@ gst_stream_selector_request_new_pad (GstElement * element,
       GST_DEBUG_FUNCPTR (gst_selector_pad_chain));
   gst_pad_set_iterate_internal_links_function (sinkpad,
       GST_DEBUG_FUNCPTR (gst_stream_selector_pad_iterate_linked_pads));
-  gst_pad_set_bufferalloc_function (sinkpad,
-      GST_DEBUG_FUNCPTR (gst_selector_pad_bufferalloc));
 
   gst_pad_set_active (sinkpad, TRUE);
   gst_element_add_pad (GST_ELEMENT (sel), sinkpad);
index 9a48ab0..34f371a 100644 (file)
@@ -54,8 +54,9 @@ static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink_%d",
 
 static const gboolean passthrough = TRUE;
 
-GST_BOILERPLATE (GstStreamSynchronizer, gst_stream_synchronizer,
-    GstElement, GST_TYPE_ELEMENT);
+#define gst_stream_synchronizer_parent_class parent_class
+G_DEFINE_TYPE (GstStreamSynchronizer, gst_stream_synchronizer,
+    GST_TYPE_ELEMENT);
 
 typedef struct
 {
@@ -120,8 +121,12 @@ gst_stream_synchronizer_iterate_internal_links (GstPad * pad)
 
   opad = gst_stream_get_other_pad_from_pad (pad);
   if (opad) {
-    it = gst_iterator_new_single (GST_TYPE_PAD, opad,
-        (GstCopyFunction) gst_object_ref, (GFreeFunc) gst_object_unref);
+    GValue value = { 0, };
+
+    g_value_init (&value, GST_TYPE_PAD);
+    g_value_set_object (&value, opad);
+    it = gst_iterator_new_single (GST_TYPE_PAD, &value);
+    g_value_unset (&value);
     gst_object_unref (opad);
   }
 
@@ -146,19 +151,19 @@ gst_stream_synchronizer_query (GstPad * pad, GstQuery * query)
 }
 
 static GstCaps *
-gst_stream_synchronizer_getcaps (GstPad * pad)
+gst_stream_synchronizer_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstPad *opad;
   GstCaps *ret = NULL;
 
   opad = gst_stream_get_other_pad_from_pad (pad);
   if (opad) {
-    ret = gst_pad_peer_get_caps (opad);
+    ret = gst_pad_peer_get_caps (opad, filter);
     gst_object_unref (opad);
   }
 
   if (ret == NULL)
-    ret = gst_caps_new_any ();
+    ret = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
 
   GST_LOG_OBJECT (pad, "Returning caps: %" GST_PTR_FORMAT, ret);
 
@@ -196,7 +201,7 @@ gst_stream_synchronizer_src_event (GstPad * pad, GstEvent * event)
     goto skip_adjustments;
 
   GST_LOG_OBJECT (pad, "Handling event %s: %" GST_PTR_FORMAT,
-      GST_EVENT_TYPE_NAME (event), event->structure);
+      GST_EVENT_TYPE_NAME (event), event);
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_QOS:{
@@ -206,7 +211,7 @@ gst_stream_synchronizer_src_event (GstPad * pad, GstEvent * event)
       gint64 running_time_diff;
       GstStream *stream;
 
-      gst_event_parse_qos (event, &proportion, &diff, &timestamp);
+      gst_event_parse_qos (event, NULL, &proportion, &diff, &timestamp);
       gst_event_unref (event);
 
       GST_STREAM_SYNCHRONIZER_LOCK (self);
@@ -240,7 +245,9 @@ gst_stream_synchronizer_src_event (GstPad * pad, GstEvent * event)
         goto out;
       }
 
-      event = gst_event_new_qos (proportion, diff, timestamp);
+      event =
+          gst_event_new_qos (GST_QOS_TYPE_UNDERFLOW, proportion, diff,
+          timestamp);
       break;
     }
     default:
@@ -274,16 +281,14 @@ gst_stream_synchronizer_sink_event (GstPad * pad, GstEvent * event)
     goto skip_adjustments;
 
   GST_LOG_OBJECT (pad, "Handling event %s: %" GST_PTR_FORMAT,
-      GST_EVENT_TYPE_NAME (event), event->structure);
+      GST_EVENT_TYPE_NAME (event), event);
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_SINK_MESSAGE:{
       GstMessage *message;
 
       gst_event_parse_sink_message (event, &message);
-      if (message->structure
-          && gst_structure_has_name (message->structure,
-              "playbin2-stream-changed")) {
+      if (gst_message_has_name (message, "playbin2-stream-changed")) {
         GstStream *stream;
 
         GST_STREAM_SYNCHRONIZER_LOCK (self);
@@ -306,29 +311,29 @@ gst_stream_synchronizer_sink_event (GstPad * pad, GstEvent * event)
               break;
           }
           if (all_wait) {
-            gint64 last_stop = 0;
+            gint64 position = 0;
 
             GST_DEBUG_OBJECT (self, "All streams have changed -- unblocking");
 
             for (l = self->streams; l; l = l->next) {
               GstStream *ostream = l->data;
               gint64 stop_running_time;
-              gint64 last_stop_running_time;
+              gint64 position_running_time;
 
               ostream->wait = FALSE;
 
               stop_running_time =
                   gst_segment_to_running_time (&ostream->segment,
                   GST_FORMAT_TIME, ostream->segment.stop);
-              last_stop_running_time =
+              position_running_time =
                   gst_segment_to_running_time (&ostream->segment,
-                  GST_FORMAT_TIME, ostream->segment.last_stop);
-              last_stop =
-                  MAX (last_stop, MAX (stop_running_time,
-                      last_stop_running_time));
+                  GST_FORMAT_TIME, ostream->segment.position);
+              position =
+                  MAX (position, MAX (stop_running_time,
+                      position_running_time));
             }
-            last_stop = MAX (0, last_stop);
-            self->group_start_time = MAX (self->group_start_time, last_stop);
+            position = MAX (0, position);
+            self->group_start_time = MAX (self->group_start_time, position);
 
             GST_DEBUG_OBJECT (self, "New group start time: %" GST_TIME_FORMAT,
                 GST_TIME_ARGS (self->group_start_time));
@@ -341,15 +346,11 @@ gst_stream_synchronizer_sink_event (GstPad * pad, GstEvent * event)
       gst_message_unref (message);
       break;
     }
-    case GST_EVENT_NEWSEGMENT:{
+    case GST_EVENT_SEGMENT:{
       GstStream *stream;
-      gboolean update;
-      gdouble rate, applied_rate;
-      GstFormat format;
-      gint64 start, stop, position;
+      GstSegment segment;
 
-      gst_event_parse_new_segment_full (event,
-          &update, &rate, &applied_rate, &format, &start, &stop, &position);
+      gst_event_copy_segment (event, &segment);
 
       GST_STREAM_SYNCHRONIZER_LOCK (self);
       stream = gst_pad_get_element_private (pad);
@@ -369,41 +370,35 @@ gst_stream_synchronizer_sink_event (GstPad * pad, GstEvent * event)
         goto done;
       }
 
-      if (stream && format == GST_FORMAT_TIME) {
+      if (stream && segment.format == GST_FORMAT_TIME) {
         if (stream->new_stream) {
-          gint64 last_stop_running_time = 0;
+          gint64 position_running_time = 0;
           gint64 stop_running_time = 0;
 
           if (stream->segment.format == GST_FORMAT_TIME) {
-            last_stop_running_time =
+            position_running_time =
                 gst_segment_to_running_time (&stream->segment, GST_FORMAT_TIME,
-                stream->segment.last_stop);
-            last_stop_running_time = MAX (last_stop_running_time, 0);
+                stream->segment.position);
+            position_running_time = MAX (position_running_time, 0);
             stop_running_time =
                 gst_segment_to_running_time (&stream->segment, GST_FORMAT_TIME,
                 stream->segment.stop);
-            stop_running_time = MAX (last_stop_running_time, 0);
+            stop_running_time = MAX (position_running_time, 0);
 
-            if (stop_running_time != last_stop_running_time) {
+            if (stop_running_time != position_running_time) {
               GST_WARNING_OBJECT (pad,
-                  "Gap between last_stop and segment stop: %" GST_TIME_FORMAT
+                  "Gap between position and segment stop: %" GST_TIME_FORMAT
                   " != %" GST_TIME_FORMAT, GST_TIME_ARGS (stop_running_time),
-                  GST_TIME_ARGS (last_stop_running_time));
+                  GST_TIME_ARGS (position_running_time));
             }
 
-            if (stop_running_time < last_stop_running_time) {
+            if (stop_running_time < position_running_time) {
               GST_DEBUG_OBJECT (pad, "Updating stop position");
+              stream->segment.stop = stream->segment.position;
               gst_pad_push_event (stream->srcpad,
-                  gst_event_new_new_segment_full (TRUE, stream->segment.rate,
-                      stream->segment.applied_rate, GST_FORMAT_TIME,
-                      stream->segment.start, stream->segment.last_stop,
-                      stream->segment.time));
-              gst_segment_set_newsegment_full (&stream->segment, TRUE,
-                  stream->segment.rate, stream->segment.applied_rate,
-                  GST_FORMAT_TIME, stream->segment.start,
-                  stream->segment.last_stop, stream->segment.time);
+                  gst_event_new_segment (&stream->segment));
             }
-            stop_running_time = MAX (stop_running_time, last_stop_running_time);
+            stop_running_time = MAX (stop_running_time, position_running_time);
             GST_DEBUG_OBJECT (pad,
                 "Stop running time of last group: %" GST_TIME_FORMAT,
                 GST_TIME_ARGS (stop_running_time));
@@ -417,27 +412,23 @@ gst_stream_synchronizer_sink_event (GstPad * pad, GstEvent * event)
             GST_DEBUG_OBJECT (pad,
                 "Advancing running time for other streams by: %"
                 GST_TIME_FORMAT, GST_TIME_ARGS (diff));
-            gst_pad_push_event (stream->srcpad,
-                gst_event_new_new_segment_full (FALSE, 1.0, 1.0,
-                    GST_FORMAT_TIME, 0, diff, 0));
-            gst_segment_set_newsegment_full (&stream->segment, FALSE, 1.0, 1.0,
-                GST_FORMAT_TIME, 0, diff, 0);
+
+            segment.base += diff;
           }
         }
 
         GST_DEBUG_OBJECT (pad, "Segment was: %" GST_SEGMENT_FORMAT,
             &stream->segment);
-        gst_segment_set_newsegment_full (&stream->segment, update, rate,
-            applied_rate, format, start, stop, position);
+        gst_segment_copy_into (&segment, &stream->segment);
         GST_DEBUG_OBJECT (pad, "Segment now is: %" GST_SEGMENT_FORMAT,
             &stream->segment);
 
         GST_DEBUG_OBJECT (pad, "Stream start running time: %" GST_TIME_FORMAT,
-            GST_TIME_ARGS (stream->segment.accum));
-        stream->running_time_diff = stream->segment.accum;
+            GST_TIME_ARGS (stream->segment.base));
+        stream->running_time_diff = stream->segment.base;
       } else if (stream) {
         GST_WARNING_OBJECT (pad, "Non-TIME segment: %s",
-            gst_format_get_name (format));
+            gst_format_get_name (segment.format));
         gst_segment_init (&stream->segment, GST_FORMAT_UNDEFINED);
       }
       GST_STREAM_SYNCHRONIZER_UNLOCK (self);
@@ -550,26 +541,6 @@ done:
 }
 
 static GstFlowReturn
-gst_stream_synchronizer_sink_bufferalloc (GstPad * pad, guint64 offset,
-    guint size, GstCaps * caps, GstBuffer ** buf)
-{
-  GstPad *opad;
-  GstFlowReturn ret = GST_FLOW_ERROR;
-
-  GST_LOG_OBJECT (pad, "Allocating buffer: size=%u", size);
-
-  opad = gst_stream_get_other_pad_from_pad (pad);
-  if (opad) {
-    ret = gst_pad_alloc_buffer (opad, offset, size, caps, buf);
-    gst_object_unref (opad);
-  }
-
-  GST_LOG_OBJECT (pad, "Allocation: %s", gst_flow_get_name (ret));
-
-  return ret;
-}
-
-static GstFlowReturn
 gst_stream_synchronizer_sink_chain (GstPad * pad, GstBuffer * buffer)
 {
   GstStreamSynchronizer *self =
@@ -592,7 +563,7 @@ gst_stream_synchronizer_sink_chain (GstPad * pad, GstBuffer * buffer)
   GST_LOG_OBJECT (pad, "Handling buffer %p: size=%u, timestamp=%"
       GST_TIME_FORMAT " duration=%" GST_TIME_FORMAT
       " offset=%" G_GUINT64_FORMAT " offset_end=%" G_GUINT64_FORMAT,
-      buffer, GST_BUFFER_SIZE (buffer),
+      buffer, gst_buffer_get_size (buffer),
       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
       GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)),
       GST_BUFFER_OFFSET (buffer), GST_BUFFER_OFFSET_END (buffer));
@@ -607,7 +578,7 @@ gst_stream_synchronizer_sink_chain (GstPad * pad, GstBuffer * buffer)
 
   stream->seen_data = TRUE;
   if (stream && stream->drop_discont) {
-    buffer = gst_buffer_make_metadata_writable (buffer);
+    buffer = gst_buffer_make_writable (buffer);
     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DISCONT);
     stream->drop_discont = FALSE;
   }
@@ -616,8 +587,8 @@ gst_stream_synchronizer_sink_chain (GstPad * pad, GstBuffer * buffer)
       && GST_CLOCK_TIME_IS_VALID (timestamp)) {
     GST_LOG_OBJECT (pad,
         "Updating last-stop from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (stream->segment.last_stop), GST_TIME_ARGS (timestamp));
-    gst_segment_set_last_stop (&stream->segment, GST_FORMAT_TIME, timestamp);
+        GST_TIME_ARGS (stream->segment.position), GST_TIME_ARGS (timestamp));
+    stream->segment.position = timestamp;
   }
   GST_STREAM_SYNCHRONIZER_UNLOCK (self);
 
@@ -637,28 +608,27 @@ gst_stream_synchronizer_sink_chain (GstPad * pad, GstBuffer * buffer)
         && GST_CLOCK_TIME_IS_VALID (timestamp_end)) {
       GST_LOG_OBJECT (pad,
           "Updating last-stop from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
-          GST_TIME_ARGS (stream->segment.last_stop),
+          GST_TIME_ARGS (stream->segment.position),
           GST_TIME_ARGS (timestamp_end));
-      gst_segment_set_last_stop (&stream->segment, GST_FORMAT_TIME,
-          timestamp_end);
+      stream->segment.position = timestamp_end;
     }
 
     /* Advance EOS streams if necessary. For non-EOS
      * streams the demuxers should already do this! */
     for (l = self->streams; l; l = l->next) {
       GstStream *ostream = l->data;
-      gint64 last_stop;
+      gint64 position;
 
       if (!ostream->is_eos || ostream->segment.format != GST_FORMAT_TIME)
         continue;
 
-      if (ostream->segment.last_stop != -1)
-        last_stop = ostream->segment.last_stop;
+      if (ostream->segment.position != -1)
+        position = ostream->segment.position;
       else
-        last_stop = ostream->segment.start;
+        position = ostream->segment.start;
 
       /* Is there a 1 second lag? */
-      if (last_stop != -1 && last_stop + GST_SECOND < timestamp_end) {
+      if (position != -1 && position + GST_SECOND < timestamp_end) {
         gint64 new_start, new_stop;
 
         new_start = timestamp_end - GST_SECOND;
@@ -669,18 +639,16 @@ gst_stream_synchronizer_sink_chain (GstPad * pad, GstBuffer * buffer)
 
         GST_DEBUG_OBJECT (ostream->sinkpad,
             "Advancing stream %u from %" GST_TIME_FORMAT " to %"
-            GST_TIME_FORMAT, ostream->stream_number, GST_TIME_ARGS (last_stop),
+            GST_TIME_FORMAT, ostream->stream_number, GST_TIME_ARGS (position),
             GST_TIME_ARGS (new_start));
 
+        ostream->segment.start = new_start;
+        ostream->segment.stop = new_stop;
+        ostream->segment.time = new_start;
+        ostream->segment.position = new_start;
+
         gst_pad_push_event (ostream->srcpad,
-            gst_event_new_new_segment_full (TRUE, ostream->segment.rate,
-                ostream->segment.applied_rate, ostream->segment.format,
-                new_start, new_stop, new_start));
-        gst_segment_set_newsegment_full (&ostream->segment, TRUE,
-            ostream->segment.rate, ostream->segment.applied_rate,
-            ostream->segment.format, new_start, new_stop, new_start);
-        gst_segment_set_last_stop (&ostream->segment, GST_FORMAT_TIME,
-            new_start);
+            gst_event_new_segment (&ostream->segment));
       }
     }
     GST_STREAM_SYNCHRONIZER_UNLOCK (self);
@@ -696,7 +664,7 @@ done:
 /* GstElement vfuncs */
 static GstPad *
 gst_stream_synchronizer_request_new_pad (GstElement * element,
-    GstPadTemplate * temp, const gchar * name)
+    GstPadTemplate * temp, const gchar * name, const GstCaps * caps)
 {
   GstStreamSynchronizer *self = GST_STREAM_SYNCHRONIZER (element);
   GstStream *stream;
@@ -726,8 +694,6 @@ gst_stream_synchronizer_request_new_pad (GstElement * element,
       GST_DEBUG_FUNCPTR (gst_stream_synchronizer_sink_event));
   gst_pad_set_chain_function (stream->sinkpad,
       GST_DEBUG_FUNCPTR (gst_stream_synchronizer_sink_chain));
-  gst_pad_set_bufferalloc_function (stream->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_stream_synchronizer_sink_bufferalloc));
 
   tmp = g_strdup_printf ("src_%d", self->current_stream_number);
   stream->srcpad = gst_pad_new_from_static_template (&srctemplate, tmp);
@@ -794,15 +760,15 @@ gst_stream_synchronizer_release_stream (GstStreamSynchronizer * self,
 
   if (stream->segment.format == GST_FORMAT_TIME) {
     gint64 stop_running_time;
-    gint64 last_stop_running_time;
+    gint64 position_running_time;
 
     stop_running_time =
         gst_segment_to_running_time (&stream->segment, GST_FORMAT_TIME,
         stream->segment.stop);
-    last_stop_running_time =
+    position_running_time =
         gst_segment_to_running_time (&stream->segment, GST_FORMAT_TIME,
-        stream->segment.last_stop);
-    stop_running_time = MAX (stop_running_time, last_stop_running_time);
+        stream->segment.position);
+    stop_running_time = MAX (stop_running_time, position_running_time);
 
     GST_DEBUG_OBJECT (stream->sinkpad,
         "Stop running time was: %" GST_TIME_FORMAT,
@@ -943,30 +909,13 @@ gst_stream_synchronizer_finalize (GObject * object)
 
 /* GObject type initialization */
 static void
-gst_stream_synchronizer_init (GstStreamSynchronizer * self,
-    GstStreamSynchronizerClass * klass)
+gst_stream_synchronizer_init (GstStreamSynchronizer * self)
 {
   self->lock = g_mutex_new ();
   self->stream_finish_cond = g_cond_new ();
 }
 
 static void
-gst_stream_synchronizer_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "Stream Synchronizer", "Generic",
-      "Synchronizes a group of streams to have equal durations and starting points",
-      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
-
-static void
 gst_stream_synchronizer_class_init (GstStreamSynchronizerClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
@@ -977,6 +926,16 @@ gst_stream_synchronizer_class_init (GstStreamSynchronizerClass * klass)
 
   gobject_class->finalize = gst_stream_synchronizer_finalize;
 
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&sinktemplate));
+
+  gst_element_class_set_details_simple (element_class,
+      "Stream Synchronizer", "Generic",
+      "Synchronizes a group of streams to have equal durations and starting points",
+      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
+
   element_class->change_state =
       GST_DEBUG_FUNCPTR (gst_stream_synchronizer_change_state);
   element_class->request_new_pad =
index 0ec7ee5..692d3b2 100644 (file)
@@ -79,8 +79,8 @@ enum
   PROP_SUBTITLE_ENCODING
 };
 
-GST_BOILERPLATE (GstSubtitleOverlay, gst_subtitle_overlay, GstBin,
-    GST_TYPE_BIN);
+#define gst_subtitle_overlay_parent_class parent_class
+G_DEFINE_TYPE (GstSubtitleOverlay, gst_subtitle_overlay, GST_TYPE_BIN);
 
 static void _pad_blocked_cb (GstPad * pad, gboolean blocked,
     gpointer user_data);
@@ -95,7 +95,7 @@ do_async_start (GstSubtitleOverlay * self)
         gst_message_new_async_start (GST_OBJECT_CAST (self), FALSE);
 
     GST_DEBUG_OBJECT (self, "Posting async-start");
-    parent_class->handle_message (GST_BIN_CAST (self), msg);
+    GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (self), msg);
     self->do_async = TRUE;
   }
 }
@@ -107,7 +107,7 @@ do_async_done (GstSubtitleOverlay * self)
     GstMessage *msg = gst_message_new_async_done (GST_OBJECT_CAST (self));
 
     GST_DEBUG_OBJECT (self, "Posting async-done");
-    parent_class->handle_message (GST_BIN_CAST (self), msg);
+    GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (self), msg);
     self->do_async = FALSE;
   }
 }
@@ -495,26 +495,16 @@ _remove_element (GstSubtitleOverlay * self, GstElement ** element)
 }
 
 static void
-_generate_update_newsegment_event (GstSegment * segment, GstEvent ** event1,
-    GstEvent ** event2)
+_generate_update_segment_event (GstSegment * segment, GstEvent ** event1)
 {
   GstEvent *event;
+  GstStructure *structure;
 
-  *event1 = NULL;
-  *event2 = NULL;
-
-  event = gst_event_new_new_segment_full (FALSE, segment->rate,
-      segment->applied_rate, segment->format, 0, segment->accum, 0);
-  gst_structure_id_set (event->structure, _subtitle_overlay_event_marker_id,
+  event = gst_event_new_segment (segment);
+  structure = gst_event_writable_structure (event);
+  gst_structure_id_set (structure, _subtitle_overlay_event_marker_id,
       G_TYPE_BOOLEAN, TRUE, NULL);
   *event1 = event;
-
-  event = gst_event_new_new_segment_full (FALSE, segment->rate,
-      segment->applied_rate, segment->format,
-      segment->start, segment->stop, segment->time);
-  gst_structure_id_set (event->structure, _subtitle_overlay_event_marker_id,
-      G_TYPE_BOOLEAN, TRUE, NULL);
-  *event2 = event;
 }
 
 static gboolean
@@ -578,17 +568,12 @@ _setup_passthrough (GstSubtitleOverlay * self)
   /* Send segment to the identity. This is dropped because identity
    * is not linked downstream yet */
   if (self->video_segment.format != GST_FORMAT_UNDEFINED) {
-    GstEvent *event1, *event2;
+    GstEvent *event1;
 
-    _generate_update_newsegment_event (&self->video_segment, &event1, &event2);
+    _generate_update_segment_event (&self->video_segment, &event1);
     GST_DEBUG_OBJECT (self,
-        "Pushing video accumulate newsegment event: %" GST_PTR_FORMAT,
-        event1->structure);
-    GST_DEBUG_OBJECT (self,
-        "Pushing video update newsegment event: %" GST_PTR_FORMAT,
-        event2->structure);
+        "Pushing video segment event: %" GST_PTR_FORMAT, event1);
     gst_pad_send_event (sink, event1);
-    gst_pad_send_event (sink, event2);
   }
 
   /* Link sink ghostpads to identity */
@@ -714,7 +699,7 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
     if (peer) {
       subcaps = gst_pad_get_negotiated_caps (peer);
       if (!subcaps) {
-        subcaps = gst_pad_get_caps_reffed (peer);
+        subcaps = gst_pad_get_caps (peer, NULL);
         if (!gst_caps_is_fixed (subcaps)) {
           gst_caps_unref (subcaps);
           subcaps = NULL;
@@ -855,7 +840,7 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
 
         video_caps = gst_pad_get_negotiated_caps (video_peer);
         if (!video_caps) {
-          video_caps = gst_pad_get_caps_reffed (video_peer);
+          video_caps = gst_pad_get_caps (video_peer, NULL);
           if (!gst_caps_is_fixed (video_caps)) {
             gst_caps_unref (video_caps);
             video_caps = NULL;
@@ -990,7 +975,7 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
       /* Send segments to the parser/overlay if necessary. These are not sent
        * outside this element because of the proxy pad event function */
       if (self->video_segment.format != GST_FORMAT_UNDEFINED) {
-        GstEvent *event1, *event2;
+        GstEvent *event1;
 
         sink = gst_element_get_static_pad (self->pre_colorspace, "sink");
         if (G_UNLIKELY (!sink)) {
@@ -998,22 +983,16 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
           continue;
         }
 
-        _generate_update_newsegment_event (&self->video_segment, &event1,
-            &event2);
-        GST_DEBUG_OBJECT (self,
-            "Pushing video accumulate newsegment event: %" GST_PTR_FORMAT,
-            event1->structure);
+        _generate_update_segment_event (&self->video_segment, &event1);
         GST_DEBUG_OBJECT (self,
-            "Pushing video update newsegment event: %" GST_PTR_FORMAT,
-            event2->structure);
+            "Pushing video segment event: %" GST_PTR_FORMAT, event1);
         gst_pad_send_event (sink, event1);
-        gst_pad_send_event (sink, event2);
 
         gst_object_unref (sink);
       }
 
       if (self->subtitle_segment.format != GST_FORMAT_UNDEFINED) {
-        GstEvent *event1, *event2;
+        GstEvent *event1;
 
         sink = gst_element_get_static_pad (element, "sink");
         if (G_UNLIKELY (!sink)) {
@@ -1021,16 +1000,10 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
           continue;
         }
 
-        _generate_update_newsegment_event (&self->subtitle_segment, &event1,
-            &event2);
-        GST_DEBUG_OBJECT (self,
-            "Pushing subtitle accumulate newsegment event: %" GST_PTR_FORMAT,
-            event1->structure);
+        _generate_update_segment_event (&self->subtitle_segment, &event1);
         GST_DEBUG_OBJECT (self,
-            "Pushing subtitle update newsegment event: %" GST_PTR_FORMAT,
-            event2->structure);
+            "Pushing subtitle segment event: %" GST_PTR_FORMAT, event1);
         gst_pad_send_event (sink, event1);
-        gst_pad_send_event (sink, event2);
 
         gst_object_unref (sink);
       }
@@ -1159,7 +1132,7 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
       /* Send segments to the renderer if necessary. These are not sent
        * outside this element because of the proxy pad event handler */
       if (self->video_segment.format != GST_FORMAT_UNDEFINED) {
-        GstEvent *event1, *event2;
+        GstEvent *event1;
 
         sink = gst_element_get_static_pad (self->pre_colorspace, "sink");
         if (G_UNLIKELY (!sink)) {
@@ -1167,21 +1140,15 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
           continue;
         }
 
-        _generate_update_newsegment_event (&self->video_segment, &event1,
-            &event2);
+        _generate_update_segment_event (&self->video_segment, &event1);
         GST_DEBUG_OBJECT (self,
-            "Pushing video accumulate newsegment event: %" GST_PTR_FORMAT,
-            event1->structure);
-        GST_DEBUG_OBJECT (self,
-            "Pushing video update newsegment event: %" GST_PTR_FORMAT,
-            event2->structure);
+            "Pushing video segment event: %" GST_PTR_FORMAT, event1);
         gst_pad_send_event (sink, event1);
-        gst_pad_send_event (sink, event2);
         gst_object_unref (sink);
       }
 
       if (self->subtitle_segment.format != GST_FORMAT_UNDEFINED) {
-        GstEvent *event1, *event2;
+        GstEvent *event1;
 
         sink = _get_sub_pad (element);
         if (G_UNLIKELY (!sink)) {
@@ -1189,16 +1156,10 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
           continue;
         }
 
-        _generate_update_newsegment_event (&self->subtitle_segment, &event1,
-            &event2);
-        GST_DEBUG_OBJECT (self,
-            "Pushing subtitle accumulate newsegment event: %" GST_PTR_FORMAT,
-            event1->structure);
+        _generate_update_segment_event (&self->subtitle_segment, &event1);
         GST_DEBUG_OBJECT (self,
-            "Pushing subtitle update newsegment event: %" GST_PTR_FORMAT,
-            event2->structure);
+            "Pushing subtitle segment event: %" GST_PTR_FORMAT, event1);
         gst_pad_send_event (sink, event1);
-        gst_pad_send_event (sink, event2);
         gst_object_unref (sink);
       }
 
@@ -1513,25 +1474,6 @@ gst_subtitle_overlay_set_property (GObject * object, guint prop_id,
 }
 
 static void
-gst_subtitle_overlay_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
-
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&video_sinktemplate));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&subtitle_sinktemplate));
-
-  gst_element_class_set_details_simple (gstelement_class, "Subtitle Overlay",
-      "Video/Overlay/Subtitle",
-      "Overlays a video stream with subtitles",
-      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
-
-static void
 gst_subtitle_overlay_class_init (GstSubtitleOverlayClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
@@ -1563,6 +1505,19 @@ gst_subtitle_overlay_class_init (GstSubtitleOverlayClass * klass)
           "ISO-8859-15 will be assumed.", NULL,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&srctemplate));
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&video_sinktemplate));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&subtitle_sinktemplate));
+
+  gst_element_class_set_details_simple (element_class, "Subtitle Overlay",
+      "Video/Overlay/Subtitle",
+      "Overlays a video stream with subtitles",
+      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
+
   element_class->change_state =
       GST_DEBUG_FUNCPTR (gst_subtitle_overlay_change_state);
 
@@ -1621,7 +1576,7 @@ gst_subtitle_overlay_src_proxy_event (GstPad * proxypad, GstEvent * event)
   s = gst_event_get_structure (event);
   if (s && gst_structure_id_has_field (s, _subtitle_overlay_event_marker_id)) {
     GST_DEBUG_OBJECT (ghostpad, "Dropping event with marker: %" GST_PTR_FORMAT,
-        event->structure);
+        event);
     gst_event_unref (event);
     event = NULL;
     ret = TRUE;
@@ -1686,31 +1641,18 @@ gst_subtitle_overlay_video_sink_event (GstPad * pad, GstEvent * event)
 
   ret = gst_proxy_pad_event_default (pad, gst_event_ref (event));
 
-  if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
-    gboolean update;
-    gdouble rate, applied_rate;
-    GstFormat format;
-    gint64 start, stop, position;
+  if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
 
-    GST_DEBUG_OBJECT (pad, "Newsegment event: %" GST_PTR_FORMAT,
-        event->structure);
-    gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
-        &format, &start, &stop, &position);
+    GST_DEBUG_OBJECT (pad, "segment event: %" GST_PTR_FORMAT, event);
+    gst_event_copy_segment (event, &self->video_segment);
 
-    if (format != GST_FORMAT_TIME) {
+    if (self->video_segment.format != GST_FORMAT_TIME) {
       GST_ERROR_OBJECT (pad, "Newsegment event in non-time format: %s",
-          gst_format_get_name (format));
+          gst_format_get_name (self->video_segment.format));
       gst_object_unref (event);
       gst_object_unref (self);
       return FALSE;
     }
-
-    GST_DEBUG_OBJECT (pad, "Old video segment: %" GST_SEGMENT_FORMAT,
-        &self->video_segment);
-    gst_segment_set_newsegment_full (&self->video_segment, update, rate,
-        applied_rate, format, start, stop, position);
-    GST_DEBUG_OBJECT (pad, "New video segment: %" GST_SEGMENT_FORMAT,
-        &self->video_segment);
   }
 
   gst_event_unref (event);
@@ -1779,7 +1721,7 @@ gst_subtitle_overlay_subtitle_sink_chain (GstPad * pad, GstBuffer * buffer)
 }
 
 static GstCaps *
-gst_subtitle_overlay_subtitle_sink_getcaps (GstPad * pad)
+gst_subtitle_overlay_subtitle_sink_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY (gst_pad_get_parent (pad));
   GstCaps *ret;
@@ -1787,6 +1729,10 @@ gst_subtitle_overlay_subtitle_sink_getcaps (GstPad * pad)
   g_mutex_lock (self->factories_lock);
   if (G_UNLIKELY (!gst_subtitle_overlay_update_factory_list (self)))
     ret = GST_CAPS_NONE;
+  else if (filter)
+    ret =
+        gst_caps_intersect_full (filter, self->factory_caps,
+        GST_CAPS_INTERSECT_FIRST);
   else
     ret = gst_caps_ref (self->factory_caps);
   g_mutex_unlock (self->factories_lock);
@@ -1801,7 +1747,7 @@ gst_subtitle_overlay_subtitle_sink_getcaps (GstPad * pad)
 static gboolean
 gst_subtitle_overlay_subtitle_sink_acceptcaps (GstPad * pad, GstCaps * caps)
 {
-  GstCaps *othercaps = gst_subtitle_overlay_subtitle_sink_getcaps (pad);
+  GstCaps *othercaps = gst_subtitle_overlay_subtitle_sink_getcaps (pad, NULL);
   gboolean ret = gst_caps_can_intersect (caps, othercaps);
 
   gst_caps_unref (othercaps);
@@ -1862,7 +1808,7 @@ gst_subtitle_overlay_subtitle_sink_link (GstPad * pad, GstPad * peer)
 
   caps = gst_pad_get_negotiated_caps (peer);
   if (!caps) {
-    caps = gst_pad_get_caps_reffed (peer);
+    caps = gst_pad_get_caps (peer, NULL);
     if (!gst_caps_is_fixed (caps)) {
       gst_caps_unref (caps);
       caps = NULL;
@@ -1930,12 +1876,9 @@ gst_subtitle_overlay_subtitle_sink_event (GstPad * pad, GstEvent * event)
 {
   GstSubtitleOverlay *self = GST_SUBTITLE_OVERLAY (gst_pad_get_parent (pad));
   gboolean ret;
-  GstFormat format;
 
   if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM_OOB &&
-      event->structure
-      && strcmp (gst_structure_get_name (event->structure),
-          "subtitleoverlay-flush-subtitle") == 0) {
+      gst_event_has_name (event, "subtitleoverlay-flush-subtitle")) {
     GST_DEBUG_OBJECT (pad, "Custom subtitle flush event");
     GST_SUBTITLE_OVERLAY_LOCK (self);
     self->subtitle_flush = TRUE;
@@ -1954,16 +1897,6 @@ gst_subtitle_overlay_subtitle_sink_event (GstPad * pad, GstEvent * event)
     event = NULL;
     ret = TRUE;
     goto out;
-  } else if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
-    gst_event_parse_new_segment_full (event, NULL, NULL, NULL,
-        &format, NULL, NULL, NULL);
-    if (self->subtitle_segment.format != GST_FORMAT_UNDEFINED &&
-        self->subtitle_segment.format != format) {
-      GST_DEBUG_OBJECT (pad, "Subtitle segment format changed: %s -> %s",
-          gst_format_get_name (self->subtitle_segment.format),
-          gst_format_get_name (format));
-      gst_segment_init (&self->subtitle_segment, GST_FORMAT_UNDEFINED);
-    }
   }
 
   switch (GST_EVENT_TYPE (event)) {
@@ -1973,49 +1906,29 @@ gst_subtitle_overlay_subtitle_sink_event (GstPad * pad, GstEvent * event)
       gst_segment_init (&self->subtitle_segment, GST_FORMAT_UNDEFINED);
       /* fall through */
     case GST_EVENT_FLUSH_START:
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     case GST_EVENT_EOS:
+    {
+      GstStructure *structure;
+
       /* Add our event marker to make sure no events from here go ever outside
        * the element, they're only interesting for our internal elements */
-      event =
-          GST_EVENT_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST
-              (event)));
-      if (!event->structure) {
-        event->structure =
-            gst_structure_id_empty_new (_subtitle_overlay_event_marker_id);
-        gst_structure_set_parent_refcount (event->structure,
-            &event->mini_object.refcount);
-      }
-      gst_structure_id_set (event->structure, _subtitle_overlay_event_marker_id,
+      event = GST_EVENT_CAST (gst_event_make_writable (event));
+      structure = gst_event_writable_structure (event);
+
+      gst_structure_id_set (structure, _subtitle_overlay_event_marker_id,
           G_TYPE_BOOLEAN, TRUE, NULL);
       break;
+    }
     default:
       break;
   }
 
   ret = gst_proxy_pad_event_default (pad, gst_event_ref (event));
 
-  if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
-    gboolean update;
-    gdouble rate, applied_rate;
-    gint64 start, stop, position;
-
-    GST_DEBUG_OBJECT (pad, "Newsegment event: %" GST_PTR_FORMAT,
-        event->structure);
-    gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
-        &format, &start, &stop, &position);
-
-    GST_DEBUG_OBJECT (pad, "Old subtitle segment: %" GST_SEGMENT_FORMAT,
-        &self->subtitle_segment);
-    if (self->subtitle_segment.format != format) {
-      GST_DEBUG_OBJECT (pad, "Subtitle segment format changed: %s -> %s",
-          gst_format_get_name (self->subtitle_segment.format),
-          gst_format_get_name (format));
-      gst_segment_init (&self->subtitle_segment, format);
-    }
-
-    gst_segment_set_newsegment_full (&self->subtitle_segment, update, rate,
-        applied_rate, format, start, stop, position);
+  if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
+    GST_DEBUG_OBJECT (pad, "segment event: %" GST_PTR_FORMAT, event);
+    gst_event_copy_segment (event, &self->subtitle_segment);
     GST_DEBUG_OBJECT (pad, "New subtitle segment: %" GST_SEGMENT_FORMAT,
         &self->subtitle_segment);
   }
@@ -2027,8 +1940,7 @@ out:
 }
 
 static void
-gst_subtitle_overlay_init (GstSubtitleOverlay * self,
-    GstSubtitleOverlayClass * klass)
+gst_subtitle_overlay_init (GstSubtitleOverlay * self)
 {
   GstPadTemplate *templ;
   GstPad *proxypad = NULL;
@@ -2063,6 +1975,7 @@ gst_subtitle_overlay_init (GstSubtitleOverlay * self,
       GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD
           (self->video_sinkpad)));
   self->video_block_pad = proxypad;
+
   gst_element_add_pad (GST_ELEMENT_CAST (self), self->video_sinkpad);
 
   templ = gst_static_pad_template_get (&subtitle_sinktemplate);
@@ -2082,7 +1995,6 @@ gst_subtitle_overlay_init (GstSubtitleOverlay * self,
       GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_getcaps));
   gst_pad_set_acceptcaps_function (self->subtitle_sinkpad,
       GST_DEBUG_FUNCPTR (gst_subtitle_overlay_subtitle_sink_acceptcaps));
-  gst_pad_set_bufferalloc_function (self->subtitle_sinkpad, NULL);
 
   proxypad =
       GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD
index 2404242..01fe8c2 100644 (file)
@@ -192,7 +192,8 @@ enum
 static guint gst_uri_decode_bin_signals[LAST_SIGNAL] = { 0 };
 
 GType gst_uri_decode_bin_get_type (void);
-GST_BOILERPLATE (GstURIDecodeBin, gst_uri_decode_bin, GstBin, GST_TYPE_BIN);
+#define gst_uri_decode_bin_parent_class parent_class
+G_DEFINE_TYPE (GstURIDecodeBin, gst_uri_decode_bin, GST_TYPE_BIN);
 
 static void remove_decoders (GstURIDecodeBin * bin, gboolean force);
 static void gst_uri_decode_bin_set_property (GObject * object, guint prop_id,
@@ -208,19 +209,6 @@ static gboolean gst_uri_decode_bin_query (GstElement * element,
 static GstStateChangeReturn gst_uri_decode_bin_change_state (GstElement *
     element, GstStateChange transition);
 
-static void
-gst_uri_decode_bin_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
-  gst_element_class_set_details_simple (gstelement_class,
-      "URI Decoder", "Generic/Bin/Decoder",
-      "Autoplug and decode an URI to raw media",
-      "Wim Taymans <wim.taymans@gmail.com>");
-}
-
 static gboolean
 _gst_boolean_accumulator (GSignalInvocationHint * ihint,
     GValue * return_accu, const GValue * handler_return, gpointer dummy)
@@ -643,6 +631,13 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass)
       G_SIGNAL_RUN_LAST, 0, NULL, NULL,
       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_set_details_simple (gstelement_class,
+      "URI Decoder", "Generic/Bin/Decoder",
+      "Autoplug and decode an URI to raw media",
+      "Wim Taymans <wim.taymans@gmail.com>");
+
   gstelement_class->query = GST_DEBUG_FUNCPTR (gst_uri_decode_bin_query);
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_uri_decode_bin_change_state);
@@ -659,7 +654,7 @@ gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass)
 }
 
 static void
-gst_uri_decode_bin_init (GstURIDecodeBin * dec, GstURIDecodeBinClass * klass)
+gst_uri_decode_bin_init (GstURIDecodeBin * dec)
 {
   /* first filter out the interesting element factories */
   dec->factories_lock = g_mutex_new ();
@@ -841,7 +836,7 @@ do_async_start (GstURIDecodeBin * dbin)
   dbin->async_pending = TRUE;
 
   message = gst_message_new_async_start (GST_OBJECT_CAST (dbin), FALSE);
-  parent_class->handle_message (GST_BIN_CAST (dbin), message);
+  GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (dbin), message);
 }
 
 static void
@@ -852,7 +847,7 @@ do_async_done (GstURIDecodeBin * dbin)
   if (dbin->async_pending) {
     GST_DEBUG_OBJECT (dbin, "posting ASYNC_DONE");
     message = gst_message_new_async_done (GST_OBJECT_CAST (dbin));
-    parent_class->handle_message (GST_BIN_CAST (dbin), message);
+    GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (dbin), message);
 
     dbin->async_pending = FALSE;
   }
@@ -1307,7 +1302,7 @@ has_all_raw_caps (GstPad * pad, GstCaps * rawcaps, gboolean * all_raw)
   gint capssize;
   gboolean res = FALSE;
 
-  caps = gst_pad_get_caps_reffed (pad);
+  caps = gst_pad_get_caps (pad, NULL);
   if (caps == NULL)
     return FALSE;
 
@@ -1373,6 +1368,7 @@ analyse_source (GstURIDecodeBin * decoder, gboolean * is_raw,
   gboolean res = TRUE;
   GstCaps *rawcaps;
   GstPad *pad;
+  GValue item = { 0, };
 
   *have_out = FALSE;
   *is_raw = FALSE;
@@ -1384,7 +1380,7 @@ analyse_source (GstURIDecodeBin * decoder, gboolean * is_raw,
 
   pads_iter = gst_element_iterate_src_pads (decoder->source);
   while (!done) {
-    switch (gst_iterator_next (pads_iter, (gpointer) & pad)) {
+    switch (gst_iterator_next (pads_iter, &item)) {
       case GST_ITERATOR_ERROR:
         res = FALSE;
         /* FALLTROUGH */
@@ -1399,12 +1395,13 @@ analyse_source (GstURIDecodeBin * decoder, gboolean * is_raw,
         gst_iterator_resync (pads_iter);
         break;
       case GST_ITERATOR_OK:
+        pad = g_value_get_object (&item);
         /* we now officially have an ouput pad */
         *have_out = TRUE;
 
         /* if FALSE, this pad has no caps and we continue with the next pad. */
         if (!has_all_raw_caps (pad, rawcaps, is_raw)) {
-          gst_object_unref (pad);
+          g_value_reset (&item);
           break;
         }
 
@@ -1437,10 +1434,11 @@ analyse_source (GstURIDecodeBin * decoder, gboolean * is_raw,
           }
           expose_decoded_pad (outelem, pad, decoder);
         }
-        gst_object_unref (pad);
+        g_value_reset (&item);
         break;
     }
   }
+  g_value_unset (&item);
   gst_iterator_free (pads_iter);
   gst_caps_unref (rawcaps);
 
@@ -1471,7 +1469,7 @@ no_queue2:
   {
     post_missing_plugin_error (GST_ELEMENT_CAST (decoder), "queue2");
 
-    gst_object_unref (pad);
+    g_value_unset (&item);
     gst_iterator_free (pads_iter);
     gst_caps_unref (rawcaps);
 
@@ -2139,14 +2137,16 @@ handle_redirect_message (GstURIDecodeBin * dec, GstMessage * msg)
   GList *l_good = NULL, *l_neutral = NULL, *l_bad = NULL;
   GValue new_list = { 0, };
   guint size, i;
+  const GstStructure *structure;
 
   GST_DEBUG_OBJECT (dec, "redirect message: %" GST_PTR_FORMAT, msg);
   GST_DEBUG_OBJECT (dec, "connection speed: %u", dec->connection_speed);
 
-  if (dec->connection_speed == 0 || msg->structure == NULL)
+  structure = gst_message_get_structure (msg);
+  if (dec->connection_speed == 0 || structure == NULL)
     return msg;
 
-  locations_list = gst_structure_get_value (msg->structure, "locations");
+  locations_list = gst_structure_get_value (structure, "locations");
   if (locations_list == NULL)
     return msg;
 
@@ -2198,8 +2198,8 @@ handle_redirect_message (GstURIDecodeBin * dec, GstMessage * msg)
 static void
 handle_message (GstBin * bin, GstMessage * msg)
 {
-  if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ELEMENT && msg->structure != NULL
-      && gst_structure_has_name (msg->structure, "redirect")) {
+  if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ELEMENT
+      && gst_message_has_name (msg, "redirect")) {
     /* sort redirect messages based on the connection speed. This simplifies
      * the user of this element as it can in most cases just pick the first item
      * of the sorted list as a good redirection candidate. It can of course
@@ -2236,9 +2236,12 @@ decoder_query_init (GstURIDecodeBin * dec, QueryFold * fold)
 }
 
 static gboolean
-decoder_query_duration_fold (GstPad * item, GValue * ret, QueryFold * fold)
+decoder_query_duration_fold (const GValue * item, GValue * ret,
+    QueryFold * fold)
 {
-  if (gst_pad_query (item, fold->query)) {
+  GstPad *pad = g_value_get_object (item);
+
+  if (gst_pad_query (pad, fold->query)) {
     gint64 duration;
 
     g_value_set_boolean (ret, TRUE);
@@ -2250,7 +2253,6 @@ decoder_query_duration_fold (GstPad * item, GValue * ret, QueryFold * fold)
     if (duration > fold->max)
       fold->max = duration;
   }
-  gst_object_unref (item);
   return TRUE;
 }
 
@@ -2267,9 +2269,12 @@ decoder_query_duration_done (GstURIDecodeBin * dec, QueryFold * fold)
 }
 
 static gboolean
-decoder_query_position_fold (GstPad * item, GValue * ret, QueryFold * fold)
+decoder_query_position_fold (const GValue * item, GValue * ret,
+    QueryFold * fold)
 {
-  if (gst_pad_query (item, fold->query)) {
+  GstPad *pad = g_value_get_object (item);
+
+  if (gst_pad_query (pad, fold->query)) {
     gint64 position;
 
     g_value_set_boolean (ret, TRUE);
@@ -2282,7 +2287,6 @@ decoder_query_position_fold (GstPad * item, GValue * ret, QueryFold * fold)
       fold->max = position;
   }
 
-  gst_object_unref (item);
   return TRUE;
 }
 
@@ -2299,9 +2303,11 @@ decoder_query_position_done (GstURIDecodeBin * dec, QueryFold * fold)
 }
 
 static gboolean
-decoder_query_latency_fold (GstPad * item, GValue * ret, QueryFold * fold)
+decoder_query_latency_fold (const GValue * item, GValue * ret, QueryFold * fold)
 {
-  if (gst_pad_query (item, fold->query)) {
+  GstPad *pad = g_value_get_object (item);
+
+  if (gst_pad_query (pad, fold->query)) {
     GstClockTime min, max;
     gboolean live;
 
@@ -2325,7 +2331,6 @@ decoder_query_latency_fold (GstPad * item, GValue * ret, QueryFold * fold)
       fold->live = live;
   }
 
-  gst_object_unref (item);
   return TRUE;
 }
 
@@ -2343,9 +2348,11 @@ decoder_query_latency_done (GstURIDecodeBin * dec, QueryFold * fold)
 
 /* we are seekable if all srcpads are seekable */
 static gboolean
-decoder_query_seeking_fold (GstPad * item, GValue * ret, QueryFold * fold)
+decoder_query_seeking_fold (const GValue * item, GValue * ret, QueryFold * fold)
 {
-  if (gst_pad_query (item, fold->query)) {
+  GstPad *pad = g_value_get_object (item);
+
+  if (gst_pad_query (pad, fold->query)) {
     gboolean seekable;
 
     g_value_set_boolean (ret, TRUE);
@@ -2356,7 +2363,6 @@ decoder_query_seeking_fold (GstPad * item, GValue * ret, QueryFold * fold)
     if (fold->seekable == TRUE)
       fold->seekable = seekable;
   }
-  gst_object_unref (item);
 
   return TRUE;
 }
@@ -2374,17 +2380,16 @@ decoder_query_seeking_done (GstURIDecodeBin * dec, QueryFold * fold)
 
 /* generic fold, return first valid result */
 static gboolean
-decoder_query_generic_fold (GstPad * item, GValue * ret, QueryFold * fold)
+decoder_query_generic_fold (const GValue * item, GValue * ret, QueryFold * fold)
 {
+  GstPad *pad = g_value_get_object (item);
   gboolean res;
 
-  if ((res = gst_pad_query (item, fold->query))) {
+  if ((res = gst_pad_query (pad, fold->query))) {
     g_value_set_boolean (ret, TRUE);
     GST_DEBUG_OBJECT (item, "answered query %p", fold->query);
   }
 
-  gst_object_unref (item);
-
   /* and stop as soon as we have a valid result */
   return !res;
 }
index 5aa68e3..946fdda 100644 (file)
@@ -44,7 +44,8 @@ static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
     GST_STATIC_CAPS ("text/x-pango-markup")
     );
 
-GST_BOILERPLATE (GstSsaParse, gst_ssa_parse, GstElement, GST_TYPE_ELEMENT);
+#define gst_ssa_parse_parent_class parent_class
+G_DEFINE_TYPE (GstSsaParse, gst_ssa_parse, GST_TYPE_ELEMENT);
 
 static GstStateChangeReturn gst_ssa_parse_change_state (GstElement *
     element, GstStateChange transition);
@@ -54,24 +55,6 @@ static gboolean gst_ssa_parse_sink_event (GstPad * pad, GstEvent * event);
 static GstFlowReturn gst_ssa_parse_chain (GstPad * sinkpad, GstBuffer * buf);
 
 static void
-gst_ssa_parse_base_init (gpointer klass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
-  gst_element_class_set_details_simple (element_class,
-      "SSA Subtitle Parser", "Codec/Parser/Subtitle",
-      "Parses SSA subtitle streams",
-      "Tim-Philipp Müller <tim centricular net>");
-
-  GST_DEBUG_CATEGORY_INIT (ssa_parse_debug, "ssaparse", 0,
-      "SSA subtitle parser");
-}
-
-static void
 gst_ssa_parse_dispose (GObject * object)
 {
   GstSsaParse *parse = GST_SSA_PARSE (object);
@@ -83,7 +66,7 @@ gst_ssa_parse_dispose (GObject * object)
 }
 
 static void
-gst_ssa_parse_init (GstSsaParse * parse, GstSsaParseClass * klass)
+gst_ssa_parse_init (GstSsaParse * parse)
 {
   parse->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
   gst_pad_set_setcaps_function (parse->sinkpad,
@@ -115,6 +98,18 @@ gst_ssa_parse_class_init (GstSsaParseClass * klass)
 
   object_class->dispose = gst_ssa_parse_dispose;
 
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&sink_templ));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&src_templ));
+  gst_element_class_set_details_simple (element_class,
+      "SSA Subtitle Parser", "Codec/Parser/Subtitle",
+      "Parses SSA subtitle streams",
+      "Tim-Philipp Müller <tim centricular net>");
+
+  GST_DEBUG_CATEGORY_INIT (ssa_parse_debug, "ssaparse", 0,
+      "SSA subtitle parser");
+
   element_class->change_state = GST_DEBUG_FUNCPTR (gst_ssa_parse_change_state);
 }
 
@@ -138,8 +133,8 @@ gst_ssa_parse_setcaps (GstPad * sinkpad, GstCaps * caps)
   GstStructure *s;
   const guchar bom_utf8[] = { 0xEF, 0xBB, 0xBF };
   GstBuffer *priv;
-  gchar *data;
-  guint size;
+  gchar *data, *ptr;
+  gsize size, left;
 
   s = gst_caps_get_structure (caps, 0);
   val = gst_structure_get_value (s, "codec_data");
@@ -152,17 +147,20 @@ gst_ssa_parse_setcaps (GstPad * sinkpad, GstCaps * caps)
   parse->framed = TRUE;
   parse->send_tags = TRUE;
 
-  priv = (GstBuffer *) gst_value_get_mini_object (val);
+  priv = (GstBuffer *) g_value_get_boxed (val);
   g_return_val_if_fail (priv != NULL, FALSE);
 
   gst_buffer_ref (priv);
 
-  data = (gchar *) GST_BUFFER_DATA (priv);
-  size = GST_BUFFER_SIZE (priv);
+  data = gst_buffer_map (priv, &size, NULL, GST_MAP_READ);
+
+  ptr = data;
+  left = size;
+
   /* skip UTF-8 BOM */
-  if (size >= 3 && memcmp (data, bom_utf8, 3) == 0) {
-    data += 3;
-    size -= 3;
+  if (left >= 3 && memcmp (ptr, bom_utf8, 3) == 0) {
+    ptr += 3;
+    left -= 3;
   }
 
   if (!strstr (data, "[Script Info]")) {
@@ -171,16 +169,17 @@ gst_ssa_parse_setcaps (GstPad * sinkpad, GstCaps * caps)
     return FALSE;
   }
 
-  if (!g_utf8_validate (data, size, NULL)) {
+  if (!g_utf8_validate (ptr, left, NULL)) {
     GST_WARNING_OBJECT (parse, "Init section is not valid UTF-8");
     gst_buffer_unref (priv);
     return FALSE;
   }
 
   /* FIXME: parse initial section */
-  parse->ini = g_strndup (data, size);
+  parse->ini = g_strndup (ptr, left);
   GST_LOG_OBJECT (parse, "Init section:\n%s", parse->ini);
 
+  gst_buffer_unmap (priv, data, size);
   gst_buffer_unref (priv);
 
   return TRUE;
@@ -269,15 +268,13 @@ gst_ssa_parse_push_line (GstSsaParse * parse, gchar * txt,
 
   /* allocate enough for a terminating NUL, but don't include it in buf size */
   buf = gst_buffer_new_and_alloc (len + 1);
-  memcpy (GST_BUFFER_DATA (buf), escaped, len + 1);
-  GST_BUFFER_SIZE (buf) = len;
+  gst_buffer_fill (buf, 0, escaped, len + 1);
+  gst_buffer_set_size (buf, len);
   g_free (escaped);
 
   GST_BUFFER_TIMESTAMP (buf) = start;
   GST_BUFFER_DURATION (buf) = duration;
 
-  gst_buffer_set_caps (buf, GST_PAD_CAPS (parse->srcpad));
-
   GST_LOG_OBJECT (parse, "Pushing buffer with timestamp %" GST_TIME_FORMAT
       " and duration %" GST_TIME_FORMAT, GST_TIME_ARGS (start),
       GST_TIME_ARGS (duration));
@@ -299,6 +296,8 @@ gst_ssa_parse_chain (GstPad * sinkpad, GstBuffer * buf)
   GstSsaParse *parse = GST_SSA_PARSE (GST_PAD_PARENT (sinkpad));
   GstClockTime ts;
   gchar *txt;
+  gchar *data;
+  gsize size;
 
   if (G_UNLIKELY (!parse->framed))
     goto not_framed;
@@ -314,7 +313,10 @@ gst_ssa_parse_chain (GstPad * sinkpad, GstBuffer * buf)
   }
 
   /* make double-sure it's 0-terminated and all */
-  txt = g_strndup ((gchar *) GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  txt = g_strndup (data, size);
+  gst_buffer_unmap (buf, data, size);
+
   if (txt == NULL)
     goto empty_text;
 
@@ -322,9 +324,13 @@ gst_ssa_parse_chain (GstPad * sinkpad, GstBuffer * buf)
   ret = gst_ssa_parse_push_line (parse, txt, ts, GST_BUFFER_DURATION (buf));
 
   if (ret != GST_FLOW_OK && GST_CLOCK_TIME_IS_VALID (ts)) {
+    GstSegment segment;
+
     /* just advance time without sending anything */
-    gst_pad_push_event (parse->srcpad,
-        gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, ts, -1, ts));
+    gst_segment_init (&segment, GST_FORMAT_TIME);
+    segment.start = ts;
+    segment.time = ts;
+    gst_pad_push_event (parse->srcpad, gst_event_new_segment (&segment));
     ret = GST_FLOW_OK;
   }
 
@@ -363,7 +369,7 @@ gst_ssa_parse_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
-  ret = parent_class->change_state (element, transition);
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
   if (ret == GST_STATE_CHANGE_FAILURE)
     return ret;
 
index eaf03c3..b4bbb5f 100644 (file)
@@ -79,9 +79,6 @@ static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
     GST_STATIC_CAPS ("text/plain; text/x-pango-markup")
     );
 
-static void gst_sub_parse_base_init (GstSubParseClass * klass);
-static void gst_sub_parse_class_init (GstSubParseClass * klass);
-static void gst_sub_parse_init (GstSubParse * subparse);
 
 static gboolean gst_sub_parse_src_event (GstPad * pad, GstEvent * event);
 static gboolean gst_sub_parse_src_query (GstPad * pad, GstQuery * query);
@@ -92,48 +89,8 @@ static GstStateChangeReturn gst_sub_parse_change_state (GstElement * element,
 
 static GstFlowReturn gst_sub_parse_chain (GstPad * sinkpad, GstBuffer * buf);
 
-static GstElementClass *parent_class = NULL;
-
-GType
-gst_sub_parse_get_type (void)
-{
-  static GType sub_parse_type = 0;
-
-  if (!sub_parse_type) {
-    static const GTypeInfo sub_parse_info = {
-      sizeof (GstSubParseClass),
-      (GBaseInitFunc) gst_sub_parse_base_init,
-      NULL,
-      (GClassInitFunc) gst_sub_parse_class_init,
-      NULL,
-      NULL,
-      sizeof (GstSubParse),
-      0,
-      (GInstanceInitFunc) gst_sub_parse_init,
-    };
-
-    sub_parse_type = g_type_register_static (GST_TYPE_ELEMENT,
-        "GstSubParse", &sub_parse_info, 0);
-  }
-
-  return sub_parse_type;
-}
-
-static void
-gst_sub_parse_base_init (GstSubParseClass * klass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
-  gst_element_class_set_details_simple (element_class,
-      "Subtitle parser", "Codec/Parser/Subtitle",
-      "Parses subtitle (.sub) files into text streams",
-      "Gustavo J. A. M. Carneiro <gjc@inescporto.pt>, "
-      "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
-}
+#define gst_sub_parse_parent_class parent_class
+G_DEFINE_TYPE (GstSubParse, gst_sub_parse, GST_TYPE_ELEMENT);
 
 static void
 gst_sub_parse_dispose (GObject * object)
@@ -184,12 +141,20 @@ gst_sub_parse_class_init (GstSubParseClass * klass)
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
-  parent_class = g_type_class_peek_parent (klass);
-
   object_class->dispose = gst_sub_parse_dispose;
   object_class->set_property = gst_sub_parse_set_property;
   object_class->get_property = gst_sub_parse_get_property;
 
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&sink_templ));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&src_templ));
+  gst_element_class_set_details_simple (element_class,
+      "Subtitle parser", "Codec/Parser/Subtitle",
+      "Parses subtitle (.sub) files into text streams",
+      "Gustavo J. A. M. Carneiro <gjc@inescporto.pt>, "
+      "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
+
   element_class->change_state = gst_sub_parse_change_state;
 
   g_object_class_install_property (object_class, PROP_ENCODING,
@@ -260,8 +225,7 @@ gst_sub_parse_src_query (GstPad * pad, GstQuery * query)
         ret = gst_pad_peer_query (self->sinkpad, query);
       } else {
         ret = TRUE;
-        gst_query_set_position (query, GST_FORMAT_TIME,
-            self->segment.last_stop);
+        gst_query_set_position (query, GST_FORMAT_TIME, self->segment.position);
       }
     }
     case GST_QUERY_SEEKING:
@@ -307,12 +271,13 @@ gst_sub_parse_src_event (GstPad * pad, GstEvent * event)
     case GST_EVENT_SEEK:
     {
       GstFormat format;
+      GstSeekFlags flags;
       GstSeekType start_type, stop_type;
       gint64 start, stop;
       gdouble rate;
       gboolean update;
 
-      gst_event_parse_seek (event, &rate, &format, &self->segment_flags,
+      gst_event_parse_seek (event, &rate, &format, &flags,
           &start_type, &start, &stop_type, &stop);
 
       if (format != GST_FORMAT_TIME) {
@@ -324,12 +289,12 @@ gst_sub_parse_src_event (GstPad * pad, GstEvent * event)
       /* Convert that seek to a seeking in bytes at position 0,
          FIXME: could use an index */
       ret = gst_pad_push_event (self->sinkpad,
-          gst_event_new_seek (rate, GST_FORMAT_BYTES, self->segment_flags,
+          gst_event_new_seek (rate, GST_FORMAT_BYTES, flags,
               GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, 0));
 
       if (ret) {
         /* Apply the seek to our segment */
-        gst_segment_set_seek (&self->segment, rate, format, self->segment_flags,
+        gst_segment_do_seek (&self->segment, rate, format, flags,
             start_type, start, stop_type, stop, &update);
 
         GST_DEBUG_OBJECT (self, "segment after seek: %" GST_SEGMENT_FORMAT,
@@ -588,7 +553,7 @@ parse_mdvdsub (ParserState * state, const gchar * line)
   const gchar *line_split;
   gchar *line_chunk;
   guint start_frame, end_frame;
-  gint64 clip_start = 0, clip_stop = 0;
+  guint64 clip_start = 0, clip_stop = 0;
   gboolean in_seg = FALSE;
   GString *markup;
   gchar *ret;
@@ -941,7 +906,7 @@ parse_subrip (ParserState * state, const gchar * line)
     case 2:
     {
       /* No need to parse that text if it's out of segment */
-      gint64 clip_start = 0, clip_stop = 0;
+      guint64 clip_start = 0, clip_stop = 0;
       gboolean in_seg = FALSE;
 
       /* Check our segment start/stop */
@@ -1030,7 +995,7 @@ parse_subviewer (ParserState * state, const gchar * line)
     case 1:
     {
       /* No need to parse that text if it's out of segment */
-      gint64 clip_start = 0, clip_stop = 0;
+      guint64 clip_start = 0, clip_stop = 0;
       gboolean in_seg = FALSE;
 
       /* Check our segment start/stop */
@@ -1082,7 +1047,7 @@ parse_mpsub (ParserState * state, const gchar * line)
       return NULL;
     case 1:
     {                           /* No need to parse that text if it's out of segment */
-      gint64 clip_start = 0, clip_stop = 0;
+      guint64 clip_start = 0, clip_stop = 0;
       gboolean in_seg = FALSE;
 
       /* Check our segment start/stop */
@@ -1146,7 +1111,7 @@ parse_dks (ParserState * state, const gchar * line)
       return NULL;
     case 1:
     {
-      gint64 clip_start = 0, clip_stop = 0;
+      guint64 clip_start = 0, clip_stop = 0;
       gboolean in_seg;
       gchar *ret;
 
@@ -1419,6 +1384,8 @@ feed_textbuf (GstSubParse * self, GstBuffer * buf)
   gboolean discont;
   gsize consumed;
   gchar *input = NULL;
+  const guint8 *data;
+  gsize avail;
 
   discont = GST_BUFFER_IS_DISCONT (buf);
 
@@ -1443,19 +1410,20 @@ feed_textbuf (GstSubParse * self, GstBuffer * buf)
      * subtitles which are discontinuous by nature. */
   }
 
-  self->offset = GST_BUFFER_OFFSET (buf) + GST_BUFFER_SIZE (buf);
+  self->offset = GST_BUFFER_OFFSET (buf) + gst_buffer_get_size (buf);
   self->next_offset = self->offset;
 
   gst_adapter_push (self->adapter, buf);
 
-  input =
-      convert_encoding (self, (const gchar *) gst_adapter_peek (self->adapter,
-          gst_adapter_available (self->adapter)),
-      (gsize) gst_adapter_available (self->adapter), &consumed);
+  avail = gst_adapter_available (self->adapter);
+  data = gst_adapter_map (self->adapter, avail),
+      input = convert_encoding (self, (const gchar *) data, avail, &consumed);
 
   if (input && consumed > 0) {
     self->textbuf = g_string_append (self->textbuf, input);
-    gst_adapter_flush (self->adapter, consumed);
+    gst_adapter_unmap (self->adapter, consumed);
+  } else {
+    gst_adapter_unmap (self->adapter, 0);
   }
 
   g_free (input);
@@ -1466,12 +1434,13 @@ handle_buffer (GstSubParse * self, GstBuffer * buf)
 {
   GstFlowReturn ret = GST_FLOW_OK;
   GstCaps *caps = NULL;
-  gchar *line, *subtitle;
+  gchar *line, *subtitle, *data;
+  gsize size;
 
   if (self->first_buffer) {
-    self->detected_encoding =
-        detect_encoding ((gchar *) GST_BUFFER_DATA (buf),
-        GST_BUFFER_SIZE (buf));
+    data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+    self->detected_encoding = detect_encoding (data, size);
+    gst_buffer_unmap (buf, data, size);
     self->first_buffer = FALSE;
     self->state.fps_n = self->fps_n;
     self->state.fps_d = self->fps_d;
@@ -1515,36 +1484,32 @@ handle_buffer (GstSubParse * self, GstBuffer * buf)
       guint subtitle_len = strlen (subtitle);
 
       /* +1 for terminating NUL character */
-      ret = gst_pad_alloc_buffer_and_set_caps (self->srcpad,
-          GST_BUFFER_OFFSET_NONE, subtitle_len + 1,
-          GST_PAD_CAPS (self->srcpad), &buf);
-
-      if (ret == GST_FLOW_OK) {
-        /* copy terminating NUL character as well */
-        memcpy (GST_BUFFER_DATA (buf), subtitle, subtitle_len + 1);
-        GST_BUFFER_SIZE (buf) = subtitle_len;
-        GST_BUFFER_TIMESTAMP (buf) = self->state.start_time;
-        GST_BUFFER_DURATION (buf) = self->state.duration;
-
-        /* in some cases (e.g. tmplayer) we can only determine the duration
-         * of a text chunk from the timestamp of the next text chunk; in those
-         * cases, we probably want to limit the duration to something
-         * reasonable, so we don't end up showing some text for e.g. 40 seconds
-         * just because nothing else is being said during that time */
-        if (self->state.max_duration > 0 && GST_BUFFER_DURATION_IS_VALID (buf)) {
-          if (GST_BUFFER_DURATION (buf) > self->state.max_duration)
-            GST_BUFFER_DURATION (buf) = self->state.max_duration;
-        }
+      buf = gst_buffer_new_and_alloc (subtitle_len + 1);
+
+      /* copy terminating NUL character as well */
+      gst_buffer_fill (buf, 0, subtitle, subtitle_len + 1);
+      gst_buffer_set_size (buf, subtitle_len);
+
+      GST_BUFFER_TIMESTAMP (buf) = self->state.start_time;
+      GST_BUFFER_DURATION (buf) = self->state.duration;
+
+      /* in some cases (e.g. tmplayer) we can only determine the duration
+       * of a text chunk from the timestamp of the next text chunk; in those
+       * cases, we probably want to limit the duration to something
+       * reasonable, so we don't end up showing some text for e.g. 40 seconds
+       * just because nothing else is being said during that time */
+      if (self->state.max_duration > 0 && GST_BUFFER_DURATION_IS_VALID (buf)) {
+        if (GST_BUFFER_DURATION (buf) > self->state.max_duration)
+          GST_BUFFER_DURATION (buf) = self->state.max_duration;
+      }
 
-        gst_segment_set_last_stop (&self->segment, GST_FORMAT_TIME,
-            self->state.start_time);
+      self->segment.position = self->state.start_time;
 
-        GST_DEBUG_OBJECT (self, "Sending text '%s', %" GST_TIME_FORMAT " + %"
-            GST_TIME_FORMAT, subtitle, GST_TIME_ARGS (self->state.start_time),
-            GST_TIME_ARGS (self->state.duration));
+      GST_DEBUG_OBJECT (self, "Sending text '%s', %" GST_TIME_FORMAT " + %"
+          GST_TIME_FORMAT, subtitle, GST_TIME_ARGS (self->state.start_time),
+          GST_TIME_ARGS (self->state.duration));
 
-        ret = gst_pad_push (self->srcpad, buf);
-      }
+      ret = gst_pad_push (self->srcpad, buf);
 
       /* move this forward (the tmplayer parser needs this) */
       if (self->state.duration != GST_CLOCK_TIME_NONE)
@@ -1576,9 +1541,7 @@ gst_sub_parse_chain (GstPad * sinkpad, GstBuffer * buf)
     GST_LOG_OBJECT (self, "pushing newsegment event with %" GST_SEGMENT_FORMAT,
         &self->segment);
 
-    gst_pad_push_event (self->srcpad, gst_event_new_new_segment (FALSE,
-            self->segment.rate, self->segment.format,
-            self->segment.last_stop, self->segment.stop, self->segment.time));
+    gst_pad_push_event (self->srcpad, gst_event_new_segment (&self->segment));
     self->need_segment = FALSE;
   }
 
@@ -1603,45 +1566,33 @@ gst_sub_parse_sink_event (GstPad * pad, GstEvent * event)
           self->parser_type == GST_SUB_PARSE_FORMAT_TMPLAYER ||
           self->parser_type == GST_SUB_PARSE_FORMAT_MPL2 ||
           self->parser_type == GST_SUB_PARSE_FORMAT_QTTEXT) {
+        gchar term_chars[] = { '\n', '\n', '\0' };
         GstBuffer *buf = gst_buffer_new_and_alloc (2 + 1);
 
         GST_DEBUG ("EOS. Pushing remaining text (if any)");
-        GST_BUFFER_DATA (buf)[0] = '\n';
-        GST_BUFFER_DATA (buf)[1] = '\n';
-        GST_BUFFER_DATA (buf)[2] = '\0';        /* play it safe */
-        GST_BUFFER_SIZE (buf) = 2;
+        gst_buffer_fill (buf, 0, term_chars, 3);
+        gst_buffer_set_size (buf, 2);
+
         GST_BUFFER_OFFSET (buf) = self->offset;
         gst_sub_parse_chain (pad, buf);
       }
       ret = gst_pad_event_default (pad, event);
       break;
     }
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      GstFormat format;
-      gdouble rate;
-      gint64 start, stop, time;
-      gboolean update;
-
-      gst_event_parse_new_segment (event, &update, &rate, &format, &start,
-          &stop, &time);
-
-      GST_DEBUG_OBJECT (self, "newsegment (%s)", gst_format_get_name (format));
-
-      if (format == GST_FORMAT_TIME) {
-        gst_segment_set_newsegment (&self->segment, update, rate, format,
-            start, stop, time);
-      } else {
-        /* if not time format, we'll either start with a 0 timestamp anyway or
-         * it's following a seek in which case we'll have saved the requested
-         * seek segment and don't want to overwrite it (remember that on a seek
-         * we always just seek back to the start in BYTES format and just throw
-         * away all text that's before the requested position; if the subtitles
-         * come from an upstream demuxer, it won't be able to handle our BYTES
-         * seek request and instead send us a newsegment from the seek request
-         * it received via its video pads instead, so all is fine then too) */
-      }
-
+      gst_event_copy_segment (event, &self->segment);
+      GST_DEBUG_OBJECT (self, "newsegment (%s)",
+          gst_format_get_name (self->segment.format));
+
+      /* if not time format, we'll either start with a 0 timestamp anyway or
+       * it's following a seek in which case we'll have saved the requested
+       * seek segment and don't want to overwrite it (remember that on a seek
+       * we always just seek back to the start in BYTES format and just throw
+       * away all text that's before the requested position; if the subtitles
+       * come from an upstream demuxer, it won't be able to handle our BYTES
+       * seek request and instead send us a newsegment from the seek request
+       * it received via its video pads instead, so all is fine then too) */
       ret = TRUE;
       gst_event_unref (event);
       break;
@@ -1694,7 +1645,7 @@ gst_sub_parse_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
-  ret = parent_class->change_state (element, transition);
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
   if (ret == GST_STATE_CHANGE_FAILURE)
     return ret;
 
index 5731d91..93c1968 100644 (file)
@@ -95,7 +95,6 @@ struct _GstSubParse {
   
   /* Segment */
   GstSegment    segment;
-  GstSeekFlags  segment_flags;
   gboolean      need_segment;
   
   gboolean flushing;
index 98c62d7..7f40e35 100644 (file)
@@ -153,7 +153,6 @@ enum
 
 
 /* this is really arbitrarily chosen */
-#define DEFAULT_PROTOCOL                GST_TCP_PROTOCOL_NONE
 #define DEFAULT_MODE                    1
 #define DEFAULT_BUFFERS_MAX             -1
 #define DEFAULT_BUFFERS_SOFT_MAX        -1
@@ -178,7 +177,6 @@ enum
 enum
 {
   PROP_0,
-  PROP_PROTOCOL,
   PROP_MODE,
   PROP_BUFFERS_QUEUED,
   PROP_BYTES_QUEUED,
@@ -345,27 +343,12 @@ static void gst_multi_fd_sink_set_property (GObject * object, guint prop_id,
 static void gst_multi_fd_sink_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-GST_BOILERPLATE (GstMultiFdSink, gst_multi_fd_sink, GstBaseSink,
-    GST_TYPE_BASE_SINK);
+#define gst_multi_fd_sink_parent_class parent_class
+G_DEFINE_TYPE (GstMultiFdSink, gst_multi_fd_sink, GST_TYPE_BASE_SINK);
 
 static guint gst_multi_fd_sink_signals[LAST_SIGNAL] = { 0 };
 
 static void
-gst_multi_fd_sink_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sinktemplate));
-
-  gst_element_class_set_details_simple (element_class,
-      "Multi filedescriptor sink", "Sink/Network",
-      "Send data to multiple filedescriptors",
-      "Thomas Vander Stichele <thomas at apestaart dot org>, "
-      "Wim Taymans <wim@fluendo.com>");
-}
-
-static void
 gst_multi_fd_sink_class_init (GstMultiFdSinkClass * klass)
 {
   GObjectClass *gobject_class;
@@ -380,12 +363,6 @@ gst_multi_fd_sink_class_init (GstMultiFdSinkClass * klass)
   gobject_class->get_property = gst_multi_fd_sink_get_property;
   gobject_class->finalize = gst_multi_fd_sink_finalize;
 
-  g_object_class_install_property (gobject_class, PROP_PROTOCOL,
-      g_param_spec_enum ("protocol", "Protocol", "The protocol to wrap data in"
-          ". GDP protocol here is deprecated. Please use gdppay element.",
-          GST_TYPE_TCP_PROTOCOL, DEFAULT_PROTOCOL,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
   /**
    * GstMultiFdSink::mode
    *
@@ -671,6 +648,15 @@ gst_multi_fd_sink_class_init (GstMultiFdSinkClass * klass)
           client_fd_removed), NULL, NULL, gst_tcp_marshal_VOID__INT,
       G_TYPE_NONE, 1, G_TYPE_INT);
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+
+  gst_element_class_set_details_simple (gstelement_class,
+      "Multi filedescriptor sink", "Sink/Network",
+      "Send data to multiple filedescriptors",
+      "Thomas Vander Stichele <thomas at apestaart dot org>, "
+      "Wim Taymans <wim@fluendo.com>");
+
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_multi_fd_sink_change_state);
 
@@ -687,11 +673,10 @@ gst_multi_fd_sink_class_init (GstMultiFdSinkClass * klass)
 }
 
 static void
-gst_multi_fd_sink_init (GstMultiFdSink * this, GstMultiFdSinkClass * klass)
+gst_multi_fd_sink_init (GstMultiFdSink * this)
 {
   GST_OBJECT_FLAG_UNSET (this, GST_MULTI_FD_SINK_OPEN);
 
-  this->protocol = DEFAULT_PROTOCOL;
   this->mode = DEFAULT_MODE;
 
   CLIENTS_LOCK_INIT (this);
@@ -1294,60 +1279,6 @@ ioctl_failed:
   }
 }
 
-/* Queue raw data for this client, creating a new buffer.
- * This takes ownership of the data by
- * setting it as GST_BUFFER_MALLOCDATA() on the created buffer so
- * be sure to pass g_free()-able @data.
- */
-static gboolean
-gst_multi_fd_sink_client_queue_data (GstMultiFdSink * sink,
-    GstTCPClient * client, gchar * data, gint len)
-{
-  GstBuffer *buf;
-
-  buf = gst_buffer_new ();
-  GST_BUFFER_DATA (buf) = (guint8 *) data;
-  GST_BUFFER_MALLOCDATA (buf) = (guint8 *) data;
-  GST_BUFFER_SIZE (buf) = len;
-
-  GST_LOG_OBJECT (sink, "[fd %5d] queueing data of length %d",
-      client->fd.fd, len);
-
-  client->sending = g_slist_append (client->sending, buf);
-
-  return TRUE;
-}
-
-/* GDP-encode given caps and queue them for sending */
-static gboolean
-gst_multi_fd_sink_client_queue_caps (GstMultiFdSink * sink,
-    GstTCPClient * client, const GstCaps * caps)
-{
-  guint8 *header;
-  guint8 *payload;
-  guint length;
-  gchar *string;
-
-  g_return_val_if_fail (caps != NULL, FALSE);
-
-  string = gst_caps_to_string (caps);
-  GST_DEBUG_OBJECT (sink, "[fd %5d] Queueing caps %s through GDP",
-      client->fd.fd, string);
-  g_free (string);
-
-  if (!gst_dp_packet_from_caps (caps, sink->header_flags, &length, &header,
-          &payload)) {
-    GST_DEBUG_OBJECT (sink, "Could not create GDP packet from caps");
-    return FALSE;
-  }
-  gst_multi_fd_sink_client_queue_data (sink, client, (gchar *) header, length);
-
-  length = gst_dp_header_payload_length (header);
-  gst_multi_fd_sink_client_queue_data (sink, client, (gchar *) payload, length);
-
-  return TRUE;
-}
-
 static gboolean
 is_sync_frame (GstMultiFdSink * sink, GstBuffer * buffer)
 {
@@ -1372,9 +1303,13 @@ gst_multi_fd_sink_client_queue_buffer (GstMultiFdSink * sink,
   gboolean send_streamheader = FALSE;
   GstStructure *s;
 
+#if 0
   /* before we queue the buffer, we check if we need to queue streamheader
    * buffers (because it's a new client, or because they changed) */
   caps = gst_buffer_get_caps (buffer);  /* cleaned up after streamheader */
+#else
+  caps = NULL;
+#endif
   if (!client->caps) {
     GST_DEBUG_OBJECT (sink,
         "[fd %5d] no previous caps for this client, send streamheader",
@@ -1457,24 +1392,9 @@ gst_multi_fd_sink_client_queue_buffer (GstMultiFdSink * sink,
         buffer = g_value_peek_pointer (bufval);
         GST_DEBUG_OBJECT (sink,
             "[fd %5d] queueing streamheader buffer of length %d",
-            client->fd.fd, GST_BUFFER_SIZE (buffer));
+            client->fd.fd, gst_buffer_get_size (buffer));
         gst_buffer_ref (buffer);
 
-        if (sink->protocol == GST_TCP_PROTOCOL_GDP) {
-          guint8 *header;
-          guint len;
-
-          if (!gst_dp_header_from_buffer (buffer, sink->header_flags, &len,
-                  &header)) {
-            GST_DEBUG_OBJECT (sink,
-                "[fd %5d] could not create header, removing client",
-                client->fd.fd);
-            return FALSE;
-          }
-          gst_multi_fd_sink_client_queue_data (sink, client, (gchar *) header,
-              len);
-        }
-
         client->sending = g_slist_append (client->sending, buffer);
       }
     }
@@ -1482,21 +1402,9 @@ gst_multi_fd_sink_client_queue_buffer (GstMultiFdSink * sink,
 
   gst_caps_unref (caps);
   caps = NULL;
-  /* now we can send the buffer, possibly sending a GDP header first */
-  if (sink->protocol == GST_TCP_PROTOCOL_GDP) {
-    guint8 *header;
-    guint len;
-
-    if (!gst_dp_header_from_buffer (buffer, sink->header_flags, &len, &header)) {
-      GST_DEBUG_OBJECT (sink,
-          "[fd %5d] could not create header, removing client", client->fd.fd);
-      return FALSE;
-    }
-    gst_multi_fd_sink_client_queue_data (sink, client, (gchar *) header, len);
-  }
 
   GST_LOG_OBJECT (sink, "[fd %5d] queueing buffer of length %d",
-      client->fd.fd, GST_BUFFER_SIZE (buffer));
+      client->fd.fd, gst_buffer_get_size (buffer));
 
   gst_buffer_ref (buffer);
   client->sending = g_slist_append (client->sending, buffer);
@@ -1583,7 +1491,7 @@ get_buffers_max (GstMultiFdSink * sink, gint64 max)
 
       for (i = 0; i < len; i++) {
         buf = g_array_index (sink->bufqueue, GstBuffer *, i);
-        acc += GST_BUFFER_SIZE (buf);
+        acc += gst_buffer_get_size (buf);
 
         if (acc > max)
           return i + 1;
@@ -1666,7 +1574,7 @@ find_limits (GstMultiFdSink * sink,
     }
     buf = g_array_index (sink->bufqueue, GstBuffer *, i);
 
-    bytes += GST_BUFFER_SIZE (buf);
+    bytes += gst_buffer_get_size (buf);
 
     /* take timestamp and save for the base first timestamp */
     if ((time = GST_BUFFER_TIMESTAMP (buf)) != -1) {
@@ -1992,7 +1900,6 @@ gst_multi_fd_sink_handle_client_write (GstMultiFdSink * sink,
 {
   int fd = client->fd.fd;
   gboolean more;
-  gboolean res;
   gboolean flushing;
   GstClockTime now;
   GTimeVal nowtv;
@@ -2002,39 +1909,6 @@ gst_multi_fd_sink_handle_client_write (GstMultiFdSink * sink,
 
   flushing = client->status == GST_CLIENT_STATUS_FLUSHING;
 
-  /* when using GDP, first check if we have queued caps yet */
-  if (sink->protocol == GST_TCP_PROTOCOL_GDP) {
-    /* don't need to do anything when the client is flushing */
-    if (!client->caps_sent && !flushing) {
-      GstPad *peer;
-      GstCaps *caps;
-
-      peer = gst_pad_get_peer (GST_BASE_SINK_PAD (sink));
-      if (!peer) {
-        GST_WARNING_OBJECT (sink, "pad has no peer");
-        return FALSE;
-      }
-      gst_object_unref (peer);
-
-      caps = gst_pad_get_negotiated_caps (GST_BASE_SINK_PAD (sink));
-      if (!caps) {
-        GST_WARNING_OBJECT (sink, "pad caps not yet negotiated");
-        return FALSE;
-      }
-
-      /* queue caps for sending */
-      res = gst_multi_fd_sink_client_queue_caps (sink, client, caps);
-
-      gst_caps_unref (caps);
-
-      if (!res) {
-        GST_DEBUG_OBJECT (sink, "Failed queueing caps, removing client");
-        return FALSE;
-      }
-      client->caps_sent = TRUE;
-    }
-  }
-
   more = TRUE;
   do {
     gint maxsize;
@@ -2105,10 +1979,14 @@ gst_multi_fd_sink_handle_client_write (GstMultiFdSink * sink,
     if (client->sending) {
       ssize_t wrote;
       GstBuffer *head;
+      guint8 *data;
+      gsize size;
 
       /* pick first buffer from list */
       head = GST_BUFFER (client->sending->data);
-      maxsize = GST_BUFFER_SIZE (head) - client->bufoffset;
+
+      data = gst_buffer_map (head, &size, NULL, GST_MAP_READ);
+      maxsize = size - client->bufoffset;
 
       /* try to write the complete buffer */
 #ifdef MSG_NOSIGNAL
@@ -2117,12 +1995,11 @@ gst_multi_fd_sink_handle_client_write (GstMultiFdSink * sink,
 #define FLAGS 0
 #endif
       if (client->is_socket) {
-        wrote =
-            send (fd, GST_BUFFER_DATA (head) + client->bufoffset, maxsize,
-            FLAGS);
+        wrote = send (fd, data + client->bufoffset, maxsize, FLAGS);
       } else {
-        wrote = write (fd, GST_BUFFER_DATA (head) + client->bufoffset, maxsize);
+        wrote = write (fd, data + client->bufoffset, maxsize);
       }
+      gst_buffer_unmap (head, data, size);
 
       if (wrote < 0) {
         /* hmm error.. */
@@ -2603,13 +2480,16 @@ gst_multi_fd_sink_render (GstBaseSink * bsink, GstBuffer * buf)
 {
   GstMultiFdSink *sink;
   gboolean in_caps;
+#if 0
   GstCaps *bufcaps, *padcaps;
+#endif
 
   sink = GST_MULTI_FD_SINK (bsink);
 
   g_return_val_if_fail (GST_OBJECT_FLAG_IS_SET (sink, GST_MULTI_FD_SINK_OPEN),
       GST_FLOW_WRONG_STATE);
 
+#if 0
   /* since we check every buffer for streamheader caps, we need to make
    * sure every buffer has caps set */
   bufcaps = gst_buffer_get_caps (buf);
@@ -2618,20 +2498,22 @@ gst_multi_fd_sink_render (GstBaseSink * bsink, GstBuffer * buf)
   /* make sure we have caps on the pad */
   if (!padcaps && !bufcaps)
     goto no_caps;
+#endif
 
   /* get IN_CAPS first, code below might mess with the flags */
   in_caps = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
 
+#if 0
   /* stamp the buffer with previous caps if no caps set */
   if (!bufcaps) {
-    if (!gst_buffer_is_metadata_writable (buf)) {
+    if (!gst_buffer_is_writable (buf)) {
       /* metadata is not writable, copy will be made and original buffer
        * will be unreffed so we need to ref so that we don't lose the
        * buffer in the render method. */
       gst_buffer_ref (buf);
       /* the new buffer is ours only, we keep it out of the scope of this
        * function */
-      buf = gst_buffer_make_metadata_writable (buf);
+      buf = gst_buffer_make_writable (buf);
     } else {
       /* else the metadata is writable, we ref because we keep the buffer
        * out of the scope of this method */
@@ -2645,6 +2527,7 @@ gst_multi_fd_sink_render (GstBaseSink * bsink, GstBuffer * buf)
     /* since we keep this buffer out of the scope of this method */
     gst_buffer_ref (buf);
   }
+#endif
 
   GST_LOG_OBJECT (sink, "received buffer %p, in_caps: %s, offset %"
       G_GINT64_FORMAT ", offset_end %" G_GINT64_FORMAT
@@ -2679,23 +2562,25 @@ gst_multi_fd_sink_render (GstBaseSink * bsink, GstBuffer * buf)
   if (in_caps) {
     GST_DEBUG_OBJECT (sink,
         "appending IN_CAPS buffer with length %d to streamheader",
-        GST_BUFFER_SIZE (buf));
+        gst_buffer_get_size (buf));
     sink->streamheader = g_slist_append (sink->streamheader, buf);
   } else {
     /* queue the buffer, this is a regular data buffer. */
     gst_multi_fd_sink_queue_buffer (sink, buf);
 
-    sink->bytes_to_serve += GST_BUFFER_SIZE (buf);
+    sink->bytes_to_serve += gst_buffer_get_size (buf);
   }
   return GST_FLOW_OK;
 
   /* ERRORS */
+#if 0
 no_caps:
   {
     GST_ELEMENT_ERROR (sink, CORE, NEGOTIATION, (NULL),
         ("Received first buffer without caps set"));
     return GST_FLOW_NOT_NEGOTIATED;
   }
+#endif
 }
 
 static void
@@ -2707,9 +2592,6 @@ gst_multi_fd_sink_set_property (GObject * object, guint prop_id,
   multifdsink = GST_MULTI_FD_SINK (object);
 
   switch (prop_id) {
-    case PROP_PROTOCOL:
-      multifdsink->protocol = g_value_get_enum (value);
-      break;
     case PROP_MODE:
       multifdsink->mode = g_value_get_enum (value);
       break;
@@ -2778,9 +2660,6 @@ gst_multi_fd_sink_get_property (GObject * object, guint prop_id, GValue * value,
   multifdsink = GST_MULTI_FD_SINK (object);
 
   switch (prop_id) {
-    case PROP_PROTOCOL:
-      g_value_set_enum (value, multifdsink->protocol);
-      break;
     case PROP_MODE:
       g_value_set_enum (value, multifdsink->mode);
       break;
index 0ee7888..b0465af 100644 (file)
@@ -153,8 +153,6 @@ typedef struct {
 
   gboolean discont;
 
-  GstTCPProtocol protocol;
-
   gboolean caps_sent;
   gboolean new_connection;
 
@@ -208,7 +206,6 @@ struct _GstMultiFdSink {
   GSList *streamheader; /* GSList of GstBuffers to use as streamheader */
   gboolean previous_buffer_in_caps;
 
-  GstTCPProtocol protocol;
   guint mtu;
   gint qos_dscp;
   gboolean handle_read;
index 894fcb8..471b217 100644 (file)
@@ -228,6 +228,7 @@ gst_tcp_read_buffer (GstElement * this, int socket, GstPoll * fdset,
   int ret;
   ssize_t bytes_read;
   int readsize;
+  guint8 *data;
 
   *buf = NULL;
 
@@ -251,7 +252,9 @@ gst_tcp_read_buffer (GstElement * this, int socket, GstPoll * fdset,
 
   *buf = gst_buffer_new_and_alloc (readsize);
 
-  bytes_read = read (socket, GST_BUFFER_DATA (*buf), readsize);
+  data = gst_buffer_map (*buf, NULL, NULL, GST_MAP_WRITE);
+  bytes_read = read (socket, data, readsize);
+  gst_buffer_unmap (*buf, data, bytes_read);
 
   if (bytes_read < 0)
     goto read_error;
@@ -260,7 +263,7 @@ gst_tcp_read_buffer (GstElement * this, int socket, GstPoll * fdset,
     /* but mom, you promised to give me readsize bytes! */
     goto short_read;
 
-  GST_LOG_OBJECT (this, "returning buffer of size %d", GST_BUFFER_SIZE (*buf));
+  GST_LOG_OBJECT (this, "returning buffer of size %d", bytes_read);
   return GST_FLOW_OK;
 
   /* ERRORS */
@@ -317,6 +320,8 @@ gst_tcp_gdp_read_buffer (GstElement * this, int socket, GstPoll * fdset,
 {
   GstFlowReturn ret;
   guint8 *header = NULL;
+  guint8 *data;
+  gsize size;
 
   GST_LOG_OBJECT (this, "Reading %d bytes for buffer packet header",
       GST_DP_HEADER_LENGTH);
@@ -341,8 +346,9 @@ gst_tcp_gdp_read_buffer (GstElement * this, int socket, GstPoll * fdset,
 
   g_free (header);
 
-  ret = gst_tcp_socket_read (this, socket, GST_BUFFER_DATA (*buf),
-      GST_BUFFER_SIZE (*buf), fdset);
+  data = gst_buffer_map (*buf, &size, NULL, GST_MAP_WRITE);
+  ret = gst_tcp_socket_read (this, socket, data, size, fdset);
+  gst_buffer_unmap (*buf, data, size);
 
   if (ret != GST_FLOW_OK)
     goto data_read_error;
@@ -466,104 +472,3 @@ payload_validate_error:
     return GST_FLOW_ERROR;
   }
 }
-
-/* write a GDP header to the socket.  Return false if fails. */
-gboolean
-gst_tcp_gdp_write_buffer (GstElement * this, int socket, GstBuffer * buffer,
-    gboolean fatal, const gchar * host, int port)
-{
-  guint length;
-  guint8 *header;
-  size_t wrote;
-
-  if (!gst_dp_header_from_buffer (buffer, 0, &length, &header))
-    goto create_error;
-
-  GST_LOG_OBJECT (this, "writing %d bytes for GDP buffer header", length);
-  wrote = gst_tcp_socket_write (socket, header, length);
-  g_free (header);
-
-  if (wrote != length)
-    goto write_error;
-
-  return TRUE;
-
-  /* ERRORS */
-create_error:
-  {
-    if (fatal)
-      GST_ELEMENT_ERROR (this, CORE, TOO_LAZY, (NULL),
-          ("Could not create GDP header from buffer"));
-    return FALSE;
-  }
-write_error:
-  {
-    if (fatal)
-      GST_ELEMENT_ERROR (this, RESOURCE, WRITE,
-          (_("Error while sending data to \"%s:%d\"."), host, port),
-          ("Only %" G_GSIZE_FORMAT " of %u bytes written: %s",
-              wrote, GST_BUFFER_SIZE (buffer), g_strerror (errno)));
-    return FALSE;
-  }
-}
-
-/* write GDP header and payload to the given socket for the given caps.
- * Return false if fails. */
-gboolean
-gst_tcp_gdp_write_caps (GstElement * this, int socket, const GstCaps * caps,
-    gboolean fatal, const char *host, int port)
-{
-  guint length;
-  guint8 *header;
-  guint8 *payload;
-  size_t wrote;
-
-  if (!gst_dp_packet_from_caps (caps, 0, &length, &header, &payload))
-    goto create_error;
-
-  GST_LOG_OBJECT (this, "writing %d bytes for GDP caps header", length);
-  wrote = gst_tcp_socket_write (socket, header, length);
-  if (wrote != length)
-    goto write_header_error;
-
-  length = gst_dp_header_payload_length (header);
-  g_free (header);
-
-  GST_LOG_OBJECT (this, "writing %d bytes for GDP caps payload", length);
-  wrote = gst_tcp_socket_write (socket, payload, length);
-  g_free (payload);
-
-  if (wrote != length)
-    goto write_payload_error;
-
-  return TRUE;
-
-  /* ERRORS */
-create_error:
-  {
-    if (fatal)
-      GST_ELEMENT_ERROR (this, CORE, TOO_LAZY, (NULL),
-          ("Could not create GDP packet from caps"));
-    return FALSE;
-  }
-write_header_error:
-  {
-    g_free (header);
-    g_free (payload);
-    if (fatal)
-      GST_ELEMENT_ERROR (this, RESOURCE, WRITE,
-          (_("Error while sending gdp header data to \"%s:%d\"."), host, port),
-          ("Only %" G_GSIZE_FORMAT " of %u bytes written: %s",
-              wrote, length, g_strerror (errno)));
-    return FALSE;
-  }
-write_payload_error:
-  {
-    if (fatal)
-      GST_ELEMENT_ERROR (this, RESOURCE, WRITE,
-          (_("Error while sending gdp payload data to \"%s:%d\"."), host, port),
-          ("Only %" G_GSIZE_FORMAT " of %u bytes written: %s",
-              wrote, length, g_strerror (errno)));
-    return FALSE;
-  }
-}
index 533c162..64299ef 100644 (file)
 
 G_BEGIN_DECLS
 
-/**
- * GstTCPProtocol:
- * @GST_TCP_PROTOCOL_NONE: Raw data transmission
- * @GST_TCP_PROTOCOL_GDP: #GstBuffers are wrapped and sent/received using the
- *      GDP protocol.
- *
- * This enum is provided by the tcp/multifd elements to configure the format of
- * data transmission/reception.
- *
- * The GDP protocol wraps data buffers in a header that also carries format
- * information and timestamps. The None value indicates the data is
- * sent/received as-is. In that case, format information and timestamping
- * must be transmitted separately, or implicit in the bytestream itself.
- */
-typedef enum
-{
-  GST_TCP_PROTOCOL_NONE,
-  GST_TCP_PROTOCOL_GDP
-} GstTCPProtocol;
-
 gchar * gst_tcp_host_to_ip (GstElement *element, const gchar *host);
 
 gint gst_tcp_socket_write (int socket, const void *buf, size_t count);
@@ -65,12 +45,6 @@ GstFlowReturn gst_tcp_read_buffer (GstElement * this, int socket, GstPoll * fdse
 GstFlowReturn gst_tcp_gdp_read_buffer (GstElement * this, int socket, GstPoll * fdset, GstBuffer **buf);
 GstFlowReturn gst_tcp_gdp_read_caps (GstElement * this, int socket, GstPoll * fdset, GstCaps **caps);
 
-GstEvent * gst_tcp_gdp_read_event (GstElement *elem, int socket, GstPoll * fdset);
-
-gboolean gst_tcp_gdp_write_buffer (GstElement *elem, int socket, GstBuffer *buffer, gboolean fatal, const gchar *host, int port);
-gboolean gst_tcp_gdp_write_event (GstElement *elem, int socket, GstEvent *event, gboolean fatal, const gchar *host, int port);
-gboolean gst_tcp_gdp_write_caps (GstElement *elem, int socket, const GstCaps *caps, gboolean fatal, const gchar *host, int port);
-
 G_END_DECLS
 
 #endif /* __GST_TCP_HELP_H__ */
index ca60578..de827ab 100644 (file)
@@ -57,9 +57,7 @@ enum
 {
   ARG_0,
   ARG_HOST,
-  ARG_PORT,
-  ARG_PROTOCOL
-      /* FILL ME */
+  ARG_PORT
 };
 
 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
@@ -67,9 +65,6 @@ static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS_ANY);
 
-static void gst_tcp_client_sink_base_init (gpointer g_class);
-static void gst_tcp_client_sink_class_init (GstTCPClientSink * klass);
-static void gst_tcp_client_sink_init (GstTCPClientSink * tcpclientsink);
 static void gst_tcp_client_sink_finalize (GObject * gobject);
 
 static gboolean gst_tcp_client_sink_setcaps (GstBaseSink * bsink,
@@ -85,53 +80,13 @@ static void gst_tcp_client_sink_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
 
-static GstElementClass *parent_class = NULL;
-
 /*static guint gst_tcp_client_sink_signals[LAST_SIGNAL] = { 0 }; */
 
-GType
-gst_tcp_client_sink_get_type (void)
-{
-  static GType tcpclientsink_type = 0;
-
-
-  if (!tcpclientsink_type) {
-    static const GTypeInfo tcpclientsink_info = {
-      sizeof (GstTCPClientSinkClass),
-      gst_tcp_client_sink_base_init,
-      NULL,
-      (GClassInitFunc) gst_tcp_client_sink_class_init,
-      NULL,
-      NULL,
-      sizeof (GstTCPClientSink),
-      0,
-      (GInstanceInitFunc) gst_tcp_client_sink_init,
-      NULL
-    };
-
-    tcpclientsink_type =
-        g_type_register_static (GST_TYPE_BASE_SINK, "GstTCPClientSink",
-        &tcpclientsink_info, 0);
-  }
-  return tcpclientsink_type;
-}
+#define gst_tcp_client_sink_parent_class parent_class
+G_DEFINE_TYPE (GstTCPClientSink, gst_tcp_client_sink, GST_TYPE_BASE_SINK);
 
 static void
-gst_tcp_client_sink_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sinktemplate));
-
-  gst_element_class_set_details_simple (element_class,
-      "TCP client sink", "Sink/Network",
-      "Send data as a client over the network via TCP",
-      "Thomas Vander Stichele <thomas at apestaart dot org>");
-}
-
-static void
-gst_tcp_client_sink_class_init (GstTCPClientSink * klass)
+gst_tcp_client_sink_class_init (GstTCPClientSinkClass * klass)
 {
   GObjectClass *gobject_class;
   GstElementClass *gstelement_class;
@@ -154,10 +109,14 @@ gst_tcp_client_sink_class_init (GstTCPClientSink * klass)
       g_param_spec_int ("port", "Port", "The port to send the packets to",
           0, TCP_HIGHEST_PORT, TCP_DEFAULT_PORT,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_PROTOCOL,
-      g_param_spec_enum ("protocol", "Protocol", "The protocol to wrap data in",
-          GST_TYPE_TCP_PROTOCOL, GST_TCP_PROTOCOL_NONE,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+
+  gst_element_class_set_details_simple (gstelement_class,
+      "TCP client sink", "Sink/Network",
+      "Send data as a client over the network via TCP",
+      "Thomas Vander Stichele <thomas at apestaart dot org>");
 
   gstelement_class->change_state = gst_tcp_client_sink_change_state;
 
@@ -174,7 +133,6 @@ gst_tcp_client_sink_init (GstTCPClientSink * this)
   this->port = TCP_DEFAULT_PORT;
 
   this->sock_fd.fd = -1;
-  this->protocol = GST_TCP_PROTOCOL_NONE;
   GST_OBJECT_FLAG_UNSET (this, GST_TCP_CLIENT_SINK_OPEN);
 }
 
@@ -195,41 +153,7 @@ gst_tcp_client_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
 
   sink = GST_TCP_CLIENT_SINK (bsink);
 
-  /* write the buffer header if we have one */
-  switch (sink->protocol) {
-    case GST_TCP_PROTOCOL_NONE:
-      break;
-
-    case GST_TCP_PROTOCOL_GDP:
-      /* if we haven't send caps yet, send them first */
-      if (!sink->caps_sent) {
-        const GstCaps *caps;
-        gchar *string;
-
-        caps = GST_PAD_CAPS (GST_PAD_PEER (GST_BASE_SINK_PAD (bsink)));
-        string = gst_caps_to_string (caps);
-        GST_DEBUG_OBJECT (sink, "Sending caps %s through GDP", string);
-        g_free (string);
-
-        if (!gst_tcp_gdp_write_caps (GST_ELEMENT (sink), sink->sock_fd.fd,
-                caps, TRUE, sink->host, sink->port))
-          goto gdp_write_error;
-
-        sink->caps_sent = TRUE;
-      }
-      break;
-    default:
-      g_warning ("Unhandled protocol type");
-      break;
-  }
-
   return TRUE;
-
-  /* ERRORS */
-gdp_write_error:
-  {
-    return FALSE;
-  }
 }
 
 static GstFlowReturn
@@ -237,33 +161,21 @@ gst_tcp_client_sink_render (GstBaseSink * bsink, GstBuffer * buf)
 {
   size_t wrote = 0;
   GstTCPClientSink *sink;
-  gint size;
+  guint8 *data;
+  gsize size;
 
   sink = GST_TCP_CLIENT_SINK (bsink);
 
   g_return_val_if_fail (GST_OBJECT_FLAG_IS_SET (sink, GST_TCP_CLIENT_SINK_OPEN),
       GST_FLOW_WRONG_STATE);
 
-  size = GST_BUFFER_SIZE (buf);
-
-  GST_LOG_OBJECT (sink, "writing %d bytes for buffer data", size);
-
-  /* write the buffer header if we have one */
-  switch (sink->protocol) {
-    case GST_TCP_PROTOCOL_NONE:
-      break;
-    case GST_TCP_PROTOCOL_GDP:
-      GST_LOG_OBJECT (sink, "Sending buffer header through GDP");
-      if (!gst_tcp_gdp_write_buffer (GST_ELEMENT (sink), sink->sock_fd.fd, buf,
-              TRUE, sink->host, sink->port))
-        goto gdp_write_error;
-      break;
-    default:
-      break;
-  }
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  GST_LOG_OBJECT (sink, "writing %" G_GSIZE_FORMAT " bytes for buffer data",
+      size);
 
   /* write buffer data */
-  wrote = gst_tcp_socket_write (sink->sock_fd.fd, GST_BUFFER_DATA (buf), size);
+  wrote = gst_tcp_socket_write (sink->sock_fd.fd, data, size);
+  gst_buffer_unmap (buf, data, size);
 
   if (wrote < size)
     goto write_error;
@@ -273,16 +185,12 @@ gst_tcp_client_sink_render (GstBaseSink * bsink, GstBuffer * buf)
   return GST_FLOW_OK;
 
   /* ERRORS */
-gdp_write_error:
-  {
-    return FALSE;
-  }
 write_error:
   {
     GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
         (_("Error while sending data to \"%s:%d\"."), sink->host, sink->port),
-        ("Only %" G_GSIZE_FORMAT " of %u bytes written: %s",
-            wrote, GST_BUFFER_SIZE (buf), g_strerror (errno)));
+        ("Only %" G_GSIZE_FORMAT " of %" G_GSIZE_FORMAT " bytes written: %s",
+            wrote, size, g_strerror (errno)));
     return GST_FLOW_ERROR;
   }
 }
@@ -308,9 +216,6 @@ gst_tcp_client_sink_set_property (GObject * object, guint prop_id,
     case ARG_PORT:
       tcpclientsink->port = g_value_get_int (value);
       break;
-    case ARG_PROTOCOL:
-      tcpclientsink->protocol = g_value_get_enum (value);
-      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -334,9 +239,6 @@ gst_tcp_client_sink_get_property (GObject * object, guint prop_id,
     case ARG_PORT:
       g_value_set_int (value, tcpclientsink->port);
       break;
-    case ARG_PROTOCOL:
-      g_value_set_enum (value, tcpclientsink->protocol);
-      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
index 4399870..09556ff 100644 (file)
@@ -76,7 +76,6 @@ struct _GstTCPClientSink {
   GstPollFD sock_fd;
 
   size_t data_written; /* how much bytes have we written ? */
-  GstTCPProtocol protocol; /* used with the protocol enum */
   gboolean caps_sent; /* whether or not we sent caps already */
 };
 
index b8ac849..acd54cd 100644 (file)
@@ -62,18 +62,17 @@ enum
 {
   PROP_0,
   PROP_HOST,
-  PROP_PORT,
-  PROP_PROTOCOL
+  PROP_PORT
 };
 
-
-GST_BOILERPLATE (GstTCPClientSrc, gst_tcp_client_src, GstPushSrc,
-    GST_TYPE_PUSH_SRC);
+#define gst_tcp_client_src_parent_class parent_class
+G_DEFINE_TYPE (GstTCPClientSrc, gst_tcp_client_src, GST_TYPE_PUSH_SRC);
 
 
 static void gst_tcp_client_src_finalize (GObject * gobject);
 
-static GstCaps *gst_tcp_client_src_getcaps (GstBaseSrc * psrc);
+static GstCaps *gst_tcp_client_src_getcaps (GstBaseSrc * psrc,
+    GstCaps * filter);
 
 static GstFlowReturn gst_tcp_client_src_create (GstPushSrc * psrc,
     GstBuffer ** outbuf);
@@ -87,29 +86,16 @@ static void gst_tcp_client_src_set_property (GObject * object, guint prop_id,
 static void gst_tcp_client_src_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-
-static void
-gst_tcp_client_src_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&srctemplate));
-
-  gst_element_class_set_details_simple (element_class,
-      "TCP client source", "Source/Network",
-      "Receive data as a client over the network via TCP",
-      "Thomas Vander Stichele <thomas at apestaart dot org>");
-}
-
 static void
 gst_tcp_client_src_class_init (GstTCPClientSrcClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseSrcClass *gstbasesrc_class;
   GstPushSrcClass *gstpush_src_class;
 
   gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
   gstbasesrc_class = (GstBaseSrcClass *) klass;
   gstpush_src_class = (GstPushSrcClass *) klass;
 
@@ -125,10 +111,14 @@ gst_tcp_client_src_class_init (GstTCPClientSrcClass * klass)
       g_param_spec_int ("port", "Port", "The port to receive packets from", 0,
           TCP_HIGHEST_PORT, TCP_DEFAULT_PORT,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, PROP_PROTOCOL,
-      g_param_spec_enum ("protocol", "Protocol", "The protocol to wrap data in",
-          GST_TYPE_TCP_PROTOCOL, GST_TCP_PROTOCOL_NONE,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+
+  gst_element_class_set_details_simple (gstelement_class,
+      "TCP client source", "Source/Network",
+      "Receive data as a client over the network via TCP",
+      "Thomas Vander Stichele <thomas at apestaart dot org>");
 
   gstbasesrc_class->get_caps = gst_tcp_client_src_getcaps;
   gstbasesrc_class->start = gst_tcp_client_src_start;
@@ -143,12 +133,11 @@ gst_tcp_client_src_class_init (GstTCPClientSrcClass * klass)
 }
 
 static void
-gst_tcp_client_src_init (GstTCPClientSrc * this, GstTCPClientSrcClass * g_class)
+gst_tcp_client_src_init (GstTCPClientSrc * this)
 {
   this->port = TCP_DEFAULT_PORT;
   this->host = g_strdup (TCP_DEFAULT_HOST);
   this->sock_fd.fd = -1;
-  this->protocol = GST_TCP_PROTOCOL_NONE;
   this->caps = NULL;
 
   GST_OBJECT_FLAG_UNSET (this, GST_TCP_CLIENT_SRC_OPEN);
@@ -165,7 +154,7 @@ gst_tcp_client_src_finalize (GObject * gobject)
 }
 
 static GstCaps *
-gst_tcp_client_src_getcaps (GstBaseSrc * bsrc)
+gst_tcp_client_src_getcaps (GstBaseSrc * bsrc, GstCaps * filter)
 {
   GstTCPClientSrc *src;
   GstCaps *caps = NULL;
@@ -173,11 +162,15 @@ gst_tcp_client_src_getcaps (GstBaseSrc * bsrc)
   src = GST_TCP_CLIENT_SRC (bsrc);
 
   if (!GST_OBJECT_FLAG_IS_SET (src, GST_TCP_CLIENT_SRC_OPEN))
-    caps = gst_caps_new_any ();
+    caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
+  else if (src->caps && filter)
+    caps =
+        gst_caps_intersect_full (filter, src->caps, GST_CAPS_INTERSECT_FIRST);
   else if (src->caps)
     caps = gst_caps_copy (src->caps);
   else
-    caps = gst_caps_new_any ();
+    caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
+
   GST_DEBUG_OBJECT (src, "returning caps %" GST_PTR_FORMAT, caps);
   g_assert (GST_IS_CAPS (caps));
   return caps;
@@ -196,49 +189,19 @@ gst_tcp_client_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
 
   GST_LOG_OBJECT (src, "asked for a buffer");
 
-  /* read the buffer header if we're using a protocol */
-  switch (src->protocol) {
-    case GST_TCP_PROTOCOL_NONE:
-      ret = gst_tcp_read_buffer (GST_ELEMENT (src), src->sock_fd.fd,
-          src->fdset, outbuf);
-      break;
-
-    case GST_TCP_PROTOCOL_GDP:
-      /* get the caps if we're using GDP */
-      if (!src->caps_received) {
-        GstCaps *caps;
-
-        GST_DEBUG_OBJECT (src, "getting caps through GDP");
-        ret = gst_tcp_gdp_read_caps (GST_ELEMENT (src), src->sock_fd.fd,
-            src->fdset, &caps);
-
-        if (ret != GST_FLOW_OK)
-          goto no_caps;
-
-        src->caps_received = TRUE;
-        src->caps = caps;
-      }
-
-      ret = gst_tcp_gdp_read_buffer (GST_ELEMENT (src), src->sock_fd.fd,
-          src->fdset, outbuf);
-      break;
-    default:
-      /* need to assert as buf == NULL */
-      g_assert ("Unhandled protocol type");
-      break;
-  }
+  /* read the buffer header */
+  ret = gst_tcp_read_buffer (GST_ELEMENT (src), src->sock_fd.fd,
+      src->fdset, outbuf);
 
   if (ret == GST_FLOW_OK) {
     GST_LOG_OBJECT (src,
         "Returning buffer from _get of size %d, ts %"
         GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT
         ", offset %" G_GINT64_FORMAT ", offset_end %" G_GINT64_FORMAT,
-        GST_BUFFER_SIZE (*outbuf),
+        gst_buffer_get_size (*outbuf),
         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (*outbuf)),
         GST_TIME_ARGS (GST_BUFFER_DURATION (*outbuf)),
         GST_BUFFER_OFFSET (*outbuf), GST_BUFFER_OFFSET_END (*outbuf));
-
-    gst_buffer_set_caps (*outbuf, src->caps);
   }
 
   return ret;
@@ -248,12 +211,6 @@ wrong_state:
     GST_DEBUG_OBJECT (src, "connection to closed, cannot read data");
     return GST_FLOW_WRONG_STATE;
   }
-no_caps:
-  {
-    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
-        ("Could not read caps through GDP"));
-    return ret;
-  }
 }
 
 static void
@@ -274,9 +231,6 @@ gst_tcp_client_src_set_property (GObject * object, guint prop_id,
     case PROP_PORT:
       tcpclientsrc->port = g_value_get_int (value);
       break;
-    case PROP_PROTOCOL:
-      tcpclientsrc->protocol = g_value_get_enum (value);
-      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -297,9 +251,6 @@ gst_tcp_client_src_get_property (GObject * object, guint prop_id,
     case PROP_PORT:
       g_value_set_int (value, tcpclientsrc->port);
       break;
-    case PROP_PROTOCOL:
-      g_value_set_enum (value, tcpclientsrc->protocol);
-      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
index 24d31e8..77d5702 100644 (file)
@@ -67,7 +67,6 @@ struct _GstTCPClientSrc {
   GstPollFD sock_fd;
   GstPoll *fdset;
 
-  GstTCPProtocol protocol; /* protocol used for reading data */
   gboolean caps_received;      /* if we have received caps yet */
   GstCaps *caps;
 };
index fdca0ec..1c9ea4a 100644 (file)
@@ -74,29 +74,18 @@ static void gst_tcp_server_sink_set_property (GObject * object, guint prop_id,
 static void gst_tcp_server_sink_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-
-GST_BOILERPLATE (GstTCPServerSink, gst_tcp_server_sink, GstMultiFdSink,
-    GST_TYPE_MULTI_FD_SINK);
-
-
-static void
-gst_tcp_server_sink_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class,
-      "TCP server sink", "Sink/Network",
-      "Send data as a server over the network via TCP",
-      "Thomas Vander Stichele <thomas at apestaart dot org>");
-}
+#define gst_tcp_server_sink_parent_class parent_class
+G_DEFINE_TYPE (GstTCPServerSink, gst_tcp_server_sink, GST_TYPE_MULTI_FD_SINK);
 
 static void
 gst_tcp_server_sink_class_init (GstTCPServerSinkClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstMultiFdSinkClass *gstmultifdsink_class;
 
   gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
   gstmultifdsink_class = (GstMultiFdSinkClass *) klass;
 
   gobject_class->set_property = gst_tcp_server_sink_set_property;
@@ -111,6 +100,11 @@ gst_tcp_server_sink_class_init (GstTCPServerSinkClass * klass)
           0, TCP_HIGHEST_PORT, TCP_DEFAULT_PORT,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "TCP server sink", "Sink/Network",
+      "Send data as a server over the network via TCP",
+      "Thomas Vander Stichele <thomas at apestaart dot org>");
+
   gstmultifdsink_class->init = gst_tcp_server_sink_init_send;
   gstmultifdsink_class->wait = gst_tcp_server_sink_handle_wait;
   gstmultifdsink_class->close = gst_tcp_server_sink_close;
@@ -120,8 +114,7 @@ gst_tcp_server_sink_class_init (GstTCPServerSinkClass * klass)
 }
 
 static void
-gst_tcp_server_sink_init (GstTCPServerSink * this,
-    GstTCPServerSinkClass * klass)
+gst_tcp_server_sink_init (GstTCPServerSink * this)
 {
   this->server_port = TCP_DEFAULT_PORT;
   /* should support as minimum 576 for IPV4 and 1500 for IPV6 */
index c4244da..4575441 100644 (file)
@@ -63,13 +63,11 @@ enum
 {
   PROP_0,
   PROP_HOST,
-  PROP_PORT,
-  PROP_PROTOCOL
+  PROP_PORT
 };
 
-
-GST_BOILERPLATE (GstTCPServerSrc, gst_tcp_server_src, GstPushSrc,
-    GST_TYPE_PUSH_SRC);
+#define gst_tcp_server_src_parent_class parent_class
+G_DEFINE_TYPE (GstTCPServerSrc, gst_tcp_server_src, GST_TYPE_PUSH_SRC);
 
 
 static void gst_tcp_server_src_finalize (GObject * gobject);
@@ -85,29 +83,16 @@ static void gst_tcp_server_src_set_property (GObject * object, guint prop_id,
 static void gst_tcp_server_src_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-
-static void
-gst_tcp_server_src_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&srctemplate));
-
-  gst_element_class_set_details_simple (element_class,
-      "TCP server source", "Source/Network",
-      "Receive data as a server over the network via TCP",
-      "Thomas Vander Stichele <thomas at apestaart dot org>");
-}
-
 static void
 gst_tcp_server_src_class_init (GstTCPServerSrcClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseSrcClass *gstbasesrc_class;
   GstPushSrcClass *gstpush_src_class;
 
   gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
   gstbasesrc_class = (GstBaseSrcClass *) klass;
   gstpush_src_class = (GstPushSrcClass *) klass;
 
@@ -122,10 +107,14 @@ gst_tcp_server_src_class_init (GstTCPServerSrcClass * klass)
       g_param_spec_int ("port", "Port", "The port to listen to",
           0, TCP_HIGHEST_PORT, TCP_DEFAULT_PORT,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, PROP_PROTOCOL,
-      g_param_spec_enum ("protocol", "Protocol", "The protocol to wrap data in",
-          GST_TYPE_TCP_PROTOCOL, GST_TCP_PROTOCOL_NONE,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+
+  gst_element_class_set_details_simple (gstelement_class,
+      "TCP server source", "Source/Network",
+      "Receive data as a server over the network via TCP",
+      "Thomas Vander Stichele <thomas at apestaart dot org>");
 
   gstbasesrc_class->start = gst_tcp_server_src_start;
   gstbasesrc_class->stop = gst_tcp_server_src_stop;
@@ -138,13 +127,12 @@ gst_tcp_server_src_class_init (GstTCPServerSrcClass * klass)
 }
 
 static void
-gst_tcp_server_src_init (GstTCPServerSrc * src, GstTCPServerSrcClass * g_class)
+gst_tcp_server_src_init (GstTCPServerSrc * src)
 {
   src->server_port = TCP_DEFAULT_PORT;
   src->host = g_strdup (TCP_DEFAULT_HOST);
   src->server_sock_fd.fd = -1;
   src->client_sock_fd.fd = -1;
-  src->protocol = GST_TCP_PROTOCOL_NONE;
 
   GST_OBJECT_FLAG_UNSET (src, GST_TCP_SERVER_SRC_OPEN);
 }
@@ -205,54 +193,15 @@ restart:
 
   GST_LOG_OBJECT (src, "asked for a buffer");
 
-  switch (src->protocol) {
-    case GST_TCP_PROTOCOL_NONE:
-      ret = gst_tcp_read_buffer (GST_ELEMENT (src), src->client_sock_fd.fd,
-          src->fdset, outbuf);
-      break;
-
-    case GST_TCP_PROTOCOL_GDP:
-      if (!src->caps_received) {
-        GstCaps *caps;
-        gchar *string;
-
-        ret = gst_tcp_gdp_read_caps (GST_ELEMENT (src), src->client_sock_fd.fd,
-            src->fdset, &caps);
-
-        if (ret == GST_FLOW_WRONG_STATE)
-          goto gdp_cancelled;
-
-        if (ret != GST_FLOW_OK)
-          goto gdp_caps_read_error;
-
-        src->caps_received = TRUE;
-        string = gst_caps_to_string (caps);
-        GST_DEBUG_OBJECT (src, "Received caps through GDP: %s", string);
-        g_free (string);
-
-        gst_pad_set_caps (GST_BASE_SRC_PAD (psrc), caps);
-      }
-
-      ret = gst_tcp_gdp_read_buffer (GST_ELEMENT (src), src->client_sock_fd.fd,
-          src->fdset, outbuf);
-
-      if (ret == GST_FLOW_OK)
-        gst_buffer_set_caps (*outbuf, GST_PAD_CAPS (GST_BASE_SRC_PAD (src)));
-
-      break;
-
-    default:
-      /* need to assert as buf == NULL */
-      g_assert ("Unhandled protocol type");
-      break;
-  }
+  ret = gst_tcp_read_buffer (GST_ELEMENT (src), src->client_sock_fd.fd,
+      src->fdset, outbuf);
 
   if (ret == GST_FLOW_OK) {
     GST_LOG_OBJECT (src,
         "Returning buffer from _get of size %d, ts %"
         GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT
         ", offset %" G_GINT64_FORMAT ", offset_end %" G_GINT64_FORMAT,
-        GST_BUFFER_SIZE (*outbuf),
+        gst_buffer_get_size (*outbuf),
         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (*outbuf)),
         GST_TIME_ARGS (GST_BUFFER_DURATION (*outbuf)),
         GST_BUFFER_OFFSET (*outbuf), GST_BUFFER_OFFSET_END (*outbuf));
@@ -282,20 +231,6 @@ accept_error:
         ("Could not accept client on server socket: %s", g_strerror (errno)));
     return GST_FLOW_ERROR;
   }
-gdp_cancelled:
-  {
-    GST_DEBUG_OBJECT (src, "reading gdp canceled");
-    return GST_FLOW_WRONG_STATE;
-  }
-gdp_caps_read_error:
-  {
-    /* if we did not get canceled, report an error */
-    if (ret != GST_FLOW_WRONG_STATE) {
-      GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
-          ("Could not read caps through GDP"));
-    }
-    return ret;
-  }
 }
 
 static void
@@ -316,9 +251,6 @@ gst_tcp_server_src_set_property (GObject * object, guint prop_id,
     case PROP_PORT:
       tcpserversrc->server_port = g_value_get_int (value);
       break;
-    case PROP_PROTOCOL:
-      tcpserversrc->protocol = g_value_get_enum (value);
-      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -339,9 +271,6 @@ gst_tcp_server_src_get_property (GObject * object, guint prop_id,
     case PROP_PORT:
       g_value_set_int (value, tcpserversrc->server_port);
       break;
-    case PROP_PROTOCOL:
-      g_value_set_enum (value, tcpserversrc->protocol);
-      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
index 22c7afe..f5e80e2 100644 (file)
@@ -74,7 +74,6 @@ struct _GstTCPServerSrc {
 
   GstPoll *fdset;
 
-  GstTCPProtocol protocol; /* protocol used for reading data */
   gboolean caps_received;      /* if we have received caps yet */
 };
 
index 98dbade..1000a52 100644 (file)
@@ -130,7 +130,7 @@ static gboolean
 utf8_type_find_have_valid_utf8_at_offset (GstTypeFind * tf, guint64 offset,
     GstTypeFindProbability * prob)
 {
-  guint8 *data;
+  const guint8 *data;
 
   /* randomly decided values */
   guint min_size = 16;          /* minimum size  */
@@ -222,7 +222,7 @@ static GstStaticCaps uri_caps = GST_STATIC_CAPS ("text/uri-list");
 static void
 uri_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, BUFFER_SIZE);
+  const guint8 *data = gst_type_find_peek (tf, 0, BUFFER_SIZE);
   guint pos = 0;
   guint offset = 0;
 
@@ -322,7 +322,7 @@ xml_check_first_element (GstTypeFind * tf, const gchar * element, guint elen,
     gboolean strict)
 {
   gboolean got_xmldec;
-  guint8 *data;
+  const guint8 *data;
   guint offset = 0;
   guint pos = 0;
 
@@ -386,7 +386,7 @@ static GstStaticCaps sdp_caps = GST_STATIC_CAPS ("application/sdp");
 static gboolean
 sdp_check_header (GstTypeFind * tf)
 {
-  guint8 *data;
+  const guint8 *data;
 
   data = gst_type_find_peek (tf, 0, 5);
   if (!data)
@@ -433,9 +433,9 @@ static GstStaticCaps html_caps = GST_STATIC_CAPS ("text/html");
 static void
 html_type_find (GstTypeFind * tf, gpointer unused)
 {
-  gchar *d, *data;
+  const gchar *d, *data;
 
-  data = (gchar *) gst_type_find_peek (tf, 0, 16);
+  data = (const gchar *) gst_type_find_peek (tf, 0, 16);
   if (!data)
     return;
 
@@ -444,7 +444,7 @@ html_type_find (GstTypeFind * tf, gpointer unused)
   } else if (xml_check_first_element (tf, "html", 4, FALSE)) {
     gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, HTML_CAPS);
   } else if ((d = memchr (data, '<', 16))) {
-    data = (gchar *) gst_type_find_peek (tf, d - data, 6);
+    data = (const gchar *) gst_type_find_peek (tf, d - data, 6);
     if (data && g_ascii_strncasecmp (data, "<html>", 6) == 0) {
       gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, HTML_CAPS);
     }
@@ -459,7 +459,7 @@ static GstStaticCaps mid_caps = GST_STATIC_CAPS ("audio/midi");
 static void
 mid_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 4);
+  const guint8 *data = gst_type_find_peek (tf, 0, 4);
 
   /* http://jedi.ks.uiuc.edu/~johns/links/music/midifile.html */
   if (data && data[0] == 'M' && data[1] == 'T' && data[2] == 'h'
@@ -475,7 +475,7 @@ static GstStaticCaps mxmf_caps = GST_STATIC_CAPS ("audio/mobile-xmf");
 static void
 mxmf_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = NULL;
+  const guint8 *data = NULL;
 
   /* Search FileId "XMF_" 4 bytes */
   data = gst_type_find_peek (tf, 0, 4);
@@ -503,7 +503,7 @@ static GstStaticCaps flx_caps = GST_STATIC_CAPS ("video/x-fli");
 static void
 flx_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 134);
+  const guint8 *data = gst_type_find_peek (tf, 0, 134);
 
   if (data) {
     /* check magic and the frame type of the first frame */
@@ -534,7 +534,7 @@ static GstStaticCaps id3_caps = GST_STATIC_CAPS ("application/x-id3");
 static void
 id3v2_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 10);
+  const guint8 *data = gst_type_find_peek (tf, 0, 10);
 
   if (data && memcmp (data, "ID3", 3) == 0 &&
       data[3] != 0xFF && data[4] != 0xFF &&
@@ -547,7 +547,7 @@ id3v2_type_find (GstTypeFind * tf, gpointer unused)
 static void
 id3v1_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, -128, 3);
+  const guint8 *data = gst_type_find_peek (tf, -128, 3);
 
   if (data && memcmp (data, "TAG", 3) == 0) {
     gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, ID3_CAPS);
@@ -562,7 +562,7 @@ static GstStaticCaps apetag_caps = GST_STATIC_CAPS ("application/x-apetag");
 static void
 apetag_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data;
+  const guint8 *data;
 
   /* APEv1/2 at start of file */
   data = gst_type_find_peek (tf, 0, 8);
@@ -587,7 +587,7 @@ static GstStaticCaps tta_caps = GST_STATIC_CAPS ("audio/x-ttafile");
 static void
 tta_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 3);
+  const guint8 *data = gst_type_find_peek (tf, 0, 3);
 
   if (data) {
     if (memcmp (data, "TTA", 3) == 0) {
@@ -985,8 +985,8 @@ static void
 mp3_type_find_at_offset (GstTypeFind * tf, guint64 start_off,
     guint * found_layer, GstTypeFindProbability * found_prob)
 {
-  guint8 *data = NULL;
-  guint8 *data_end = NULL;
+  const guint8 *data = NULL;
+  const guint8 *data_end = NULL;
   guint size;
   guint64 skipped;
   gint last_free_offset = -1;
@@ -1010,7 +1010,7 @@ mp3_type_find_at_offset (GstTypeFind * tf, guint64 start_off,
       data_end = data + size;
     }
     if (*data == 0xFF) {
-      guint8 *head_data = NULL;
+      const guint8 *head_data = NULL;
       guint layer = 0, bitrate, samplerate, channels;
       guint found = 0;          /* number of valid headers found */
       guint64 offset = skipped;
@@ -1123,7 +1123,7 @@ static void
 mp3_type_find (GstTypeFind * tf, gpointer unused)
 {
   GstTypeFindProbability prob, mid_prob;
-  guint8 *data;
+  const guint8 *data;
   guint layer, mid_layer;
   guint64 length;
 
@@ -1193,7 +1193,7 @@ GST_STATIC_CAPS ("audio/x-musepack, streamversion= (int) { 7, 8 }");
 static void
 musepack_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 4);
+  const guint8 *data = gst_type_find_peek (tf, 0, 4);
   GstTypeFindProbability prop = GST_TYPE_FIND_MINIMUM;
   gint streamversion = -1;
 
@@ -1515,7 +1515,7 @@ wavpack_type_find (GstTypeFind * tf, gpointer unused)
 {
   guint64 offset;
   guint32 blocksize;
-  guint8 *data;
+  const guint8 *data;
 
   data = gst_type_find_peek (tf, 0, 32);
   if (!data)
@@ -1578,7 +1578,7 @@ GST_STATIC_CAPS ("application/postscript");
 static void
 postscript_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 3);
+  const guint8 *data = gst_type_find_peek (tf, 0, 3);
   if (!data)
     return;
 
@@ -1628,8 +1628,8 @@ GST_STATIC_CAPS ("multipart/x-mixed-replace");
 static void
 multipart_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data;
-  guint8 *x;
+  const guint8 *data;
+  const guint8 *x;
 
 #define MULTIPART_MAX_BOUNDARY_OFFSET 16
   data = gst_type_find_peek (tf, 0, MULTIPART_MAX_BOUNDARY_OFFSET);
@@ -1738,7 +1738,7 @@ mpeg_sys_is_valid_pack (GstTypeFind * tf, const guint8 * data, guint len,
 }
 
 static gboolean
-mpeg_sys_is_valid_pes (GstTypeFind * tf, guint8 * data, guint len,
+mpeg_sys_is_valid_pes (GstTypeFind * tf, const guint8 * data, guint len,
     guint * pack_size)
 {
   guint pes_packet_len;
@@ -1766,7 +1766,7 @@ mpeg_sys_is_valid_pes (GstTypeFind * tf, guint8 * data, guint len,
 }
 
 static gboolean
-mpeg_sys_is_valid_sys (GstTypeFind * tf, guint8 * data, guint len,
+mpeg_sys_is_valid_sys (GstTypeFind * tf, const guint8 * data, guint len,
     guint * pack_size)
 {
   guint sys_hdr_len;
@@ -1807,7 +1807,7 @@ mpeg_sys_is_valid_sys (GstTypeFind * tf, guint8 * data, guint len,
 static void
 mpeg_sys_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data, *data0, *first_sync, *end;
+  const guint8 *data, *data0, *first_sync, *end;
   gint mpegversion = 0;
   guint pack_headers = 0;
   guint pes_headers = 0;
@@ -1948,7 +1948,7 @@ mpeg_ts_probe_headers (GstTypeFind * tf, guint64 offset, gint packet_size)
 {
   /* We always enter this function having found at least one header already */
   gint found = 1;
-  guint8 *data = NULL;
+  const guint8 *data = NULL;
 
   GST_LOG ("looking for mpeg-ts packets of size %u", packet_size);
   while (found < GST_MPEGTS_TYPEFIND_MAX_HEADERS) {
@@ -1973,8 +1973,7 @@ mpeg_ts_type_find (GstTypeFind * tf, gpointer unused)
   /* TS packet sizes to test: normal, DVHS packet size and 
    * FEC with 16 or 20 byte codes packet size. */
   const gint pack_sizes[] = { 188, 192, 204, 208 };
-
-  guint8 *data = NULL;
+  const guint8 *data = NULL;
   guint size = 0;
   guint64 skipped = 0;
 
@@ -2409,7 +2408,7 @@ static GstStaticCaps aiff_caps = GST_STATIC_CAPS ("audio/x-aiff");
 static void
 aiff_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 4);
+  const guint8 *data = gst_type_find_peek (tf, 0, 4);
 
   if (data && memcmp (data, "FORM", 4) == 0) {
     data += 8;
@@ -2426,7 +2425,7 @@ static GstStaticCaps svx_caps = GST_STATIC_CAPS ("audio/x-svx");
 static void
 svx_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 4);
+  const guint8 *data = gst_type_find_peek (tf, 0, 4);
 
   if (data && memcmp (data, "FORM", 4) == 0) {
     data += 8;
@@ -2443,7 +2442,7 @@ static GstStaticCaps shn_caps = GST_STATIC_CAPS ("audio/x-shorten");
 static void
 shn_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 4);
+  const guint8 *data = gst_type_find_peek (tf, 0, 4);
 
   if (data && memcmp (data, "ajkg", 4) == 0) {
     gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, SHN_CAPS);
@@ -2462,7 +2461,7 @@ static GstStaticCaps ape_caps = GST_STATIC_CAPS ("application/x-ape");
 static void
 ape_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 4);
+  const guint8 *data = gst_type_find_peek (tf, 0, 4);
 
   if (data && memcmp (data, "MAC ", 4) == 0) {
     gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY + 10, APE_CAPS);
@@ -2479,7 +2478,7 @@ static GstStaticCaps m4a_caps = GST_STATIC_CAPS ("audio/x-m4a");
 static void
 m4a_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 4, 8);
+  const guint8 *data = gst_type_find_peek (tf, 4, 8);
 
   if (data && (memcmp (data, "ftypM4A ", 8) == 0)) {
     gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, M4A_CAPS);
@@ -2516,7 +2515,7 @@ q3gp_type_find (GstTypeFind * tf, gpointer unused)
   const gchar *profile;
   guint32 ftyp_size = 0;
   gint offset = 0;
-  guint8 *data = NULL;
+  const guint8 *data = NULL;
 
   if ((data = gst_type_find_peek (tf, 0, 12)) == NULL) {
     return;
@@ -2566,7 +2565,7 @@ static GstStaticCaps jp2_caps = GST_STATIC_CAPS ("image/jp2");
 static void
 jp2_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data;
+  const guint8 *data;
 
   data = gst_type_find_peek (tf, 0, 24);
   if (!data)
@@ -2597,7 +2596,7 @@ static GstStaticCaps qt_caps = GST_STATIC_CAPS ("video/quicktime");
 static void
 qt_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data;
+  const guint8 *data;
   guint tip = 0;
   guint64 offset = 0;
   guint64 size;
@@ -2664,7 +2663,7 @@ qt_type_find (GstTypeFind * tf, gpointer unused)
       }
     }
     if (size == 1) {
-      guint8 *sizedata;
+      const guint8 *sizedata;
 
       sizedata = gst_type_find_peek (tf, offset + 8, 8);
       if (sizedata == NULL)
@@ -2760,7 +2759,7 @@ static GstStaticCaps mod_caps = GST_STATIC_CAPS ("audio/x-mod");
 static void
 mod_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data;
+  const guint8 *data;
 
   /* MOD */
   if ((data = gst_type_find_peek (tf, 1080, 4)) != NULL) {
@@ -2816,7 +2815,7 @@ mod_type_find (GstTypeFind * tf, gpointer unused)
     }
     /* DSM */
     if (memcmp (data, "RIFF", 4) == 0) {
-      guint8 *data2 = gst_type_find_peek (tf, 8, 4);
+      const guint8 *data2 = gst_type_find_peek (tf, 8, 4);
 
       if (data2) {
         if (memcmp (data2, "DSMF", 4) == 0) {
@@ -2827,7 +2826,7 @@ mod_type_find (GstTypeFind * tf, gpointer unused)
     }
     /* FAM */
     if (memcmp (data, "FAM\xFE", 4) == 0) {
-      guint8 *data2 = gst_type_find_peek (tf, 44, 3);
+      const guint8 *data2 = gst_type_find_peek (tf, 44, 3);
 
       if (data2) {
         if (memcmp (data2, "compare", 3) == 0) {
@@ -2841,7 +2840,7 @@ mod_type_find (GstTypeFind * tf, gpointer unused)
     }
     /* GDM */
     if (memcmp (data, "GDM\xFE", 4) == 0) {
-      guint8 *data2 = gst_type_find_peek (tf, 71, 4);
+      const guint8 *data2 = gst_type_find_peek (tf, 71, 4);
 
       if (data2) {
         if (memcmp (data2, "GMFS", 4) == 0) {
@@ -2872,7 +2871,7 @@ mod_type_find (GstTypeFind * tf, gpointer unused)
   if ((data = gst_type_find_peek (tf, 20, 8)) != NULL) {
     if (g_ascii_strncasecmp ((gchar *) data, "!Scream!", 8) == 0 ||
         g_ascii_strncasecmp ((gchar *) data, "BMOD2STM", 8) == 0) {
-      guint8 *id, *stmtype;
+      const guint8 *id, *stmtype;
 
       if ((id = gst_type_find_peek (tf, 28, 1)) == NULL)
         return;
@@ -2893,7 +2892,7 @@ GST_STATIC_CAPS ("application/x-shockwave-flash");
 static void
 swf_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 4);
+  const guint8 *data = gst_type_find_peek (tf, 0, 4);
 
   if (data && (data[0] == 'F' || data[0] == 'C') &&
       data[1] == 'W' && data[2] == 'S') {
@@ -3084,7 +3083,7 @@ static GstStaticCaps tiff_le_caps = GST_STATIC_CAPS ("image/tiff, "
 static void
 tiff_type_find (GstTypeFind * tf, gpointer ununsed)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 8);
+  const guint8 *data = gst_type_find_peek (tf, 0, 8);
   guint8 le_header[4] = { 0x49, 0x49, 0x2A, 0x00 };
   guint8 be_header[4] = { 0x4D, 0x4D, 0x00, 0x2A };
 
@@ -3201,7 +3200,7 @@ static GstStaticCaps sds_caps = GST_STATIC_CAPS ("audio/x-sds");
 static void
 sds_type_find (GstTypeFind * tf, gpointer ununsed)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 4);
+  const guint8 *data = gst_type_find_peek (tf, 0, 4);
   guint8 mask[4] = { 0xFF, 0xFF, 0x80, 0xFF };
   guint8 match[4] = { 0xF0, 0x7E, 0, 0x01 };
   gint x;
@@ -3222,7 +3221,7 @@ static GstStaticCaps ircam_caps = GST_STATIC_CAPS ("audio/x-ircam");
 static void
 ircam_type_find (GstTypeFind * tf, gpointer ununsed)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 4);
+  const guint8 *data = gst_type_find_peek (tf, 0, 4);
   guint8 mask[4] = { 0xFF, 0xFF, 0xF8, 0xFF };
   guint8 match[4] = { 0x64, 0xA3, 0x00, 0x00 };
   gint x;
@@ -3254,7 +3253,7 @@ static gboolean
 ebml_check_header (GstTypeFind * tf, const gchar * doctype, int doctype_len)
 {
   /* 4 bytes for EBML ID, 1 byte for header length identifier */
-  guint8 *data = gst_type_find_peek (tf, 0, 4 + 1);
+  const guint8 *data = gst_type_find_peek (tf, 0, 4 + 1);
   gint len_mask = 0x80, size = 1, n = 1, total;
 
   if (!data)
@@ -3382,7 +3381,7 @@ static GstStaticCaps dv_caps = GST_STATIC_CAPS ("video/x-dv, "
 static void
 dv_type_find (GstTypeFind * tf, gpointer private)
 {
-  guint8 *data;
+  const guint8 *data;
 
   data = gst_type_find_peek (tf, 0, 5);
 
@@ -3414,7 +3413,7 @@ static GstStaticCaps ogg_annodex_caps =
 static void
 ogganx_type_find (GstTypeFind * tf, gpointer private)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 4);
+  const guint8 *data = gst_type_find_peek (tf, 0, 4);
 
   if ((data != NULL) && (memcmp (data, "OggS", 4) == 0)) {
 
@@ -3436,7 +3435,7 @@ static GstStaticCaps vorbis_caps = GST_STATIC_CAPS ("audio/x-vorbis");
 static void
 vorbis_type_find (GstTypeFind * tf, gpointer private)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 30);
+  const guint8 *data = gst_type_find_peek (tf, 0, 30);
 
   if (data) {
     guint blocksize_0;
@@ -3481,7 +3480,7 @@ static GstStaticCaps theora_caps = GST_STATIC_CAPS ("video/x-theora");
 static void
 theora_type_find (GstTypeFind * tf, gpointer private)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 7); //42);
+  const guint8 *data = gst_type_find_peek (tf, 0, 7);   //42);
 
   if (data) {
     if (data[0] != 0x80)
@@ -3498,7 +3497,7 @@ theora_type_find (GstTypeFind * tf, gpointer private)
 static void
 kate_type_find (GstTypeFind * tf, gpointer private)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 64);
+  const guint8 *data = gst_type_find_peek (tf, 0, 64);
   gchar category[16] = { 0, };
 
   if (G_UNLIKELY (data == NULL))
@@ -3531,7 +3530,7 @@ GST_STATIC_CAPS ("application/x-ogm-video");
 static void
 ogmvideo_type_find (GstTypeFind * tf, gpointer private)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 9);
+  const guint8 *data = gst_type_find_peek (tf, 0, 9);
 
   if (data) {
     if (memcmp (data, "\001video\000\000\000", 9) != 0)
@@ -3546,7 +3545,7 @@ GST_STATIC_CAPS ("application/x-ogm-audio");
 static void
 ogmaudio_type_find (GstTypeFind * tf, gpointer private)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 9);
+  const guint8 *data = gst_type_find_peek (tf, 0, 9);
 
   if (data) {
     if (memcmp (data, "\001audio\000\000\000", 9) != 0)
@@ -3561,7 +3560,7 @@ static GstStaticCaps ogmtext_caps = GST_STATIC_CAPS ("application/x-ogm-text");
 static void
 ogmtext_type_find (GstTypeFind * tf, gpointer private)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 9);
+  const guint8 *data = gst_type_find_peek (tf, 0, 9);
 
   if (data) {
     if (memcmp (data, "\001text\000\000\000\000", 9) != 0)
@@ -3578,7 +3577,7 @@ static GstStaticCaps speex_caps = GST_STATIC_CAPS ("audio/x-speex");
 static void
 speex_type_find (GstTypeFind * tf, gpointer private)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 80);
+  const guint8 *data = gst_type_find_peek (tf, 0, 80);
 
   if (data) {
     /* 8 byte string "Speex   "
@@ -3614,7 +3613,7 @@ static GstStaticCaps celt_caps = GST_STATIC_CAPS ("audio/x-celt");
 static void
 celt_type_find (GstTypeFind * tf, gpointer private)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 8);
+  const guint8 *data = gst_type_find_peek (tf, 0, 8);
 
   if (data) {
     /* 8 byte string "CELT   " */
@@ -3633,7 +3632,7 @@ GST_STATIC_CAPS ("application/x-ogg-skeleton, parsed=(boolean)FALSE");
 static void
 oggskel_type_find (GstTypeFind * tf, gpointer private)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 12);
+  const guint8 *data = gst_type_find_peek (tf, 0, 12);
 
   if (data) {
     /* 8 byte string "fishead\0" for the ogg skeleton stream */
@@ -3659,7 +3658,7 @@ static void
 cmml_type_find (GstTypeFind * tf, gpointer private)
 {
   /* Header is 12 bytes minimum (though we don't check the minor version */
-  guint8 *data = gst_type_find_peek (tf, 0, 12);
+  const guint8 *data = gst_type_find_peek (tf, 0, 12);
 
   if (data) {
 
@@ -3686,7 +3685,7 @@ static GstStaticCaps tar_caps = GST_STATIC_CAPS ("application/x-tar");
 static void
 tar_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 257, 8);
+  const guint8 *data = gst_type_find_peek (tf, 257, 8);
 
   /* of course we are not certain, but we don't want other typefind funcs
    * to detect formats of files within the tar archive, e.g. mp3s */
@@ -3708,7 +3707,7 @@ static GstStaticCaps ar_caps = GST_STATIC_CAPS ("application/x-ar");
 static void
 ar_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 24);
+  const guint8 *data = gst_type_find_peek (tf, 0, 24);
 
   if (data && memcmp (data, "!<arch>", 7) == 0) {
     gint i;
@@ -3735,7 +3734,7 @@ static GstStaticCaps au_caps = GST_STATIC_CAPS ("audio/x-au");
 static void
 au_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 4);
+  const guint8 *data = gst_type_find_peek (tf, 0, 4);
 
   if (data) {
     if (memcmp (data, ".snd", 4) == 0 || memcmp (data, "dns.", 4) == 0) {
@@ -3757,7 +3756,7 @@ static GstStaticCaps nuv_caps = GST_STATIC_CAPS ("video/x-nuv");
 static void
 nuv_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 11);
+  const guint8 *data = gst_type_find_peek (tf, 0, 11);
 
   if (data) {
     if (memcmp (data, "MythTVVideo", 11) == 0
@@ -3775,7 +3774,7 @@ static GstStaticCaps paris_caps = GST_STATIC_CAPS ("audio/x-paris");
 static void
 paris_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 4);
+  const guint8 *data = gst_type_find_peek (tf, 0, 4);
 
   if (data) {
     if (memcmp (data, " paf", 4) == 0 || memcmp (data, "fap ", 4) == 0) {
@@ -3792,7 +3791,7 @@ static GstStaticCaps ilbc_caps = GST_STATIC_CAPS ("audio/iLBC-sh");
 static void
 ilbc_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 8);
+  const guint8 *data = gst_type_find_peek (tf, 0, 8);
 
   if (data) {
     if (memcmp (data, "#!iLBC30", 8) == 0 || memcmp (data, "#!iLBC20", 8) == 0) {
@@ -3810,7 +3809,7 @@ GST_STATIC_CAPS ("application/x-ms-dos-executable");
 static void
 msdos_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 64);
+  const guint8 *data = gst_type_find_peek (tf, 0, 64);
 
   if (data && data[0] == 'M' && data[1] == 'Z' &&
       GST_READ_UINT16_LE (data + 8) == 4) {
@@ -3837,7 +3836,7 @@ mmsh_type_find (GstTypeFind * tf, gpointer unused)
     0xcf, 0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c
   };
 
-  guint8 *data;
+  const guint8 *data;
 
   data = gst_type_find_peek (tf, 0, 2 + 2 + 4 + 2 + 2 + 16);
   if (data && data[0] == 0x24 && data[1] == 0x48 &&
@@ -3859,7 +3858,7 @@ static GstStaticCaps dirac_caps = GST_STATIC_CAPS ("video/x-dirac");
 static void
 dirac_type_find (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data = gst_type_find_peek (tf, 0, 8);
+  const guint8 *data = gst_type_find_peek (tf, 0, 8);
 
   if (data) {
     if (memcmp (data, "BBCD", 4) == 0 || memcmp (data, "KW-DIRAC", 8) == 0) {
@@ -3880,7 +3879,7 @@ vivo_type_find (GstTypeFind * tf, gpointer unused)
   static const guint8 vivo_marker[] = { 'V', 'e', 'r', 's', 'i', 'o', 'n',
     ':', 'V', 'i', 'v', 'o', '/'
   };
-  guint8 *data;
+  const guint8 *data;
   guint hdr_len, pos;
 
   data = gst_type_find_peek (tf, 0, 1024);
@@ -3918,7 +3917,7 @@ xdgmime_typefind (GstTypeFind * find, gpointer user_data)
   gchar *mimetype;
   gsize length = 16384;
   guint64 tf_length;
-  guint8 *data;
+  const guint8 *data;
   gchar *tmp;
 
   if ((tf_length = gst_type_find_get_length (find)) > 0)
@@ -3970,7 +3969,7 @@ xdgmime_typefind (GstTypeFind * find, gpointer user_data)
 static void
 windows_icon_typefind (GstTypeFind * find, gpointer user_data)
 {
-  guint8 *data;
+  const guint8 *data;
   gint64 datalen;
   guint16 type, nimages;
   gint32 size, offset;
@@ -4069,7 +4068,7 @@ static void
 start_with_type_find (GstTypeFind * tf, gpointer private)
 {
   GstTypeFindData *start_with = (GstTypeFindData *) private;
-  guint8 *data;
+  const guint8 *data;
 
   GST_LOG ("trying to find mime type %s with the first %u bytes of data",
       gst_structure_get_name (gst_caps_get_structure (start_with->caps, 0)),
@@ -4109,7 +4108,7 @@ static void
 riff_type_find (GstTypeFind * tf, gpointer private)
 {
   GstTypeFindData *riff_data = (GstTypeFindData *) private;
-  guint8 *data = gst_type_find_peek (tf, 0, 12);
+  const guint8 *data = gst_type_find_peek (tf, 0, 12);
 
   if (data && (memcmp (data, "RIFF", 4) == 0 || memcmp (data, "AVF0", 4) == 0)) {
     data += 8;
index 8045b12..45382c3 100644 (file)
@@ -139,23 +139,8 @@ static GstStateChangeReturn gst_video_rate_change_state (GstElement * element,
 static GParamSpec *pspec_drop = NULL;
 static GParamSpec *pspec_duplicate = NULL;
 
-GST_BOILERPLATE (GstVideoRate, gst_video_rate, GstElement, GST_TYPE_ELEMENT);
-
-static void
-gst_video_rate_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class,
-      "Video rate adjuster", "Filter/Effect/Video",
-      "Drops/duplicates/adjusts timestamps on video frames to make a perfect stream",
-      "Wim Taymans <wim@fluendo.com>");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_video_rate_sink_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_video_rate_src_template));
-}
+#define gst_video_rate_parent_class parent_class
+G_DEFINE_TYPE (GstVideoRate, gst_video_rate, GST_TYPE_ELEMENT);
 
 static void
 gst_video_rate_class_init (GstVideoRateClass * klass)
@@ -203,6 +188,16 @@ gst_video_rate_class_init (GstVideoRateClass * klass)
           "Don't produce buffers before the first one we receive",
           DEFAULT_SKIP_TO_FIRST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (element_class,
+      "Video rate adjuster", "Filter/Effect/Video",
+      "Drops/duplicates/adjusts timestamps on video frames to make a perfect stream",
+      "Wim Taymans <wim@fluendo.com>");
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_video_rate_sink_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_video_rate_src_template));
+
   /**
    * GstVideoRate:drop-only:
    *
@@ -236,16 +231,17 @@ gst_video_rate_class_init (GstVideoRateClass * klass)
 /* return the caps that can be used on out_pad given in_caps on in_pad */
 static gboolean
 gst_video_rate_transformcaps (GstPad * in_pad, GstCaps * in_caps,
-    GstPad * out_pad, GstCaps ** out_caps)
+    GstPad * out_pad, GstCaps ** out_caps, GstCaps * filter)
 {
-  GstCaps *intersect;
-  const GstCaps *in_templ;
+  GstCaps *intersect, *in_templ;
   gint i;
   GSList *extra_structures = NULL;
   GSList *iter;
 
   in_templ = gst_pad_get_pad_template_caps (in_pad);
-  intersect = gst_caps_intersect (in_caps, in_templ);
+  intersect =
+      gst_caps_intersect_full (in_caps, in_templ, GST_CAPS_INTERSECT_FIRST);
+  gst_caps_unref (in_templ);
 
   /* all possible framerates are allowed */
   for (i = 0; i < gst_caps_get_size (intersect); i++) {
@@ -269,13 +265,21 @@ gst_video_rate_transformcaps (GstPad * in_pad, GstCaps * in_caps,
   }
   g_slist_free (extra_structures);
 
+  if (filter) {
+    GstCaps *tmp;
+
+    tmp = gst_caps_intersect_full (filter, intersect, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (intersect);
+    intersect = tmp;
+  }
+
   *out_caps = intersect;
 
   return TRUE;
 }
 
 static GstCaps *
-gst_video_rate_getcaps (GstPad * pad)
+gst_video_rate_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstVideoRate *videorate;
   GstPad *otherpad;
@@ -287,16 +291,33 @@ gst_video_rate_getcaps (GstPad * pad)
       videorate->srcpad;
 
   /* we can do what the peer can */
-  caps = gst_pad_peer_get_caps (otherpad);
+  caps = gst_pad_peer_get_caps (otherpad, filter);
   if (caps) {
-    GstCaps *transform;
+    GstCaps *transform, *intersect;
 
-    gst_video_rate_transformcaps (otherpad, caps, pad, &transform);
-    gst_caps_unref (caps);
-    caps = transform;
+    gst_video_rate_transformcaps (otherpad, caps, pad, &transform, filter);
+
+    /* Now prefer the downstream caps if possible */
+    intersect =
+        gst_caps_intersect_full (caps, transform, GST_CAPS_INTERSECT_FIRST);
+    if (!gst_caps_is_empty (intersect)) {
+      gst_caps_append (intersect, transform);
+      gst_caps_unref (caps);
+      caps = intersect;
+    } else {
+      gst_caps_unref (intersect);
+      caps = transform;
+    }
   } else {
     /* no peer, our padtemplate is enough then */
-    caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+    caps = gst_pad_get_pad_template_caps (pad);
+    if (filter) {
+      GstCaps *intersection;
+      intersection =
+          gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+      gst_caps_unref (caps);
+      caps = intersection;
+    }
   }
 
   return caps;
@@ -351,27 +372,20 @@ gst_video_rate_setcaps (GstPad * pad, GstCaps * caps)
 
       ret = TRUE;
     } else {
-      GstCaps *peercaps;
       GstCaps *transform = NULL;
 
       ret = FALSE;
 
       /* see how we can transform the input caps */
-      if (!gst_video_rate_transformcaps (pad, caps, otherpad, &transform))
+      if (!gst_video_rate_transformcaps (pad, caps, otherpad, &transform, NULL))
         goto no_transform;
 
-      /* see what the peer can do */
-      peercaps = gst_pad_get_caps (opeer);
-
-      GST_DEBUG_OBJECT (opeer, "icaps %" GST_PTR_FORMAT, peercaps);
       GST_DEBUG_OBJECT (videorate, "transform %" GST_PTR_FORMAT, transform);
 
-      /* filter against our possibilities */
-      caps = gst_caps_intersect (peercaps, transform);
-      gst_caps_unref (peercaps);
-      gst_caps_unref (transform);
+      /* see what the peer can do */
+      caps = gst_pad_get_caps (opeer, transform);
 
-      GST_DEBUG_OBJECT (videorate, "intersect %" GST_PTR_FORMAT, caps);
+      GST_DEBUG_OBJECT (opeer, "icaps %" GST_PTR_FORMAT, caps);
 
       /* could turn up empty, due to e.g. colorspace etc */
       if (gst_caps_get_size (caps) == 0) {
@@ -380,6 +394,7 @@ gst_video_rate_setcaps (GstPad * pad, GstCaps * caps)
       }
 
       /* take first possibility */
+      caps = gst_caps_make_writable (caps);
       gst_caps_truncate (caps);
       structure = gst_caps_get_structure (caps, 0);
 
@@ -457,7 +472,7 @@ gst_video_rate_reset (GstVideoRate * videorate)
 }
 
 static void
-gst_video_rate_init (GstVideoRate * videorate, GstVideoRateClass * klass)
+gst_video_rate_init (GstVideoRate * videorate)
 {
   videorate->sinkpad =
       gst_pad_new_from_static_template (&gst_video_rate_sink_template, "sink");
@@ -505,8 +520,7 @@ gst_video_rate_flush_prev (GstVideoRate * videorate, gboolean duplicate)
     goto eos_before_buffers;
 
   /* make sure we can write to the metadata */
-  outbuf = gst_buffer_make_metadata_writable
-      (gst_buffer_ref (videorate->prevbuf));
+  outbuf = gst_buffer_make_writable (gst_buffer_ref (videorate->prevbuf));
 
   GST_BUFFER_OFFSET (outbuf) = videorate->out;
   GST_BUFFER_OFFSET_END (outbuf) = videorate->out + 1;
@@ -530,7 +544,7 @@ gst_video_rate_flush_prev (GstVideoRate * videorate, gboolean duplicate)
   if (videorate->to_rate_numerator) {
     /* interpolate next expected timestamp in the segment */
     videorate->next_ts =
-        videorate->segment.accum + videorate->segment.start +
+        videorate->segment.base + videorate->segment.start +
         videorate->base_ts + gst_util_uint64_scale (videorate->out_frame_count,
         videorate->to_rate_denominator * GST_SECOND,
         videorate->to_rate_numerator);
@@ -540,9 +554,8 @@ gst_video_rate_flush_prev (GstVideoRate * videorate, gboolean duplicate)
   /* We do not need to update time in VFR (variable frame rate) mode */
   if (!videorate->drop_only) {
     /* adapt for looping, bring back to time in current segment. */
-    GST_BUFFER_TIMESTAMP (outbuf) = push_ts - videorate->segment.accum;
+    GST_BUFFER_TIMESTAMP (outbuf) = push_ts - videorate->segment.base;
   }
-  gst_buffer_set_caps (outbuf, GST_PAD_CAPS (videorate->srcpad));
 
   GST_LOG_OBJECT (videorate,
       "old is best, dup, pushing buffer outgoing ts %" GST_TIME_FORMAT,
@@ -601,23 +614,19 @@ gst_video_rate_event (GstPad * pad, GstEvent * event)
   videorate = GST_VIDEO_RATE (gst_pad_get_parent (pad));
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      gint64 start, stop, time;
-      gdouble rate, arate;
-      gboolean update;
-      GstFormat format;
+      const GstSegment *segment;
 
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-          &start, &stop, &time);
+      gst_event_parse_segment (event, &segment);
 
-      if (format != GST_FORMAT_TIME)
+      if (segment->format != GST_FORMAT_TIME)
         goto format_error;
 
       GST_DEBUG_OBJECT (videorate, "handle NEWSEGMENT");
 
       /* close up the previous segment, if appropriate */
-      if (!update && videorate->prevbuf) {
+      if (videorate->prevbuf) {
         gint count = 0;
         GstFlowReturn res;
 
@@ -627,7 +636,7 @@ gst_video_rate_event (GstPad * pad, GstEvent * event)
          * regardless, prevent going loopy in strange cases */
         while (res == GST_FLOW_OK && count <= MAGIC_LIMIT &&
             ((GST_CLOCK_TIME_IS_VALID (videorate->segment.stop) &&
-                    videorate->next_ts - videorate->segment.accum
+                    videorate->next_ts - videorate->segment.base
                     < videorate->segment.stop)
                 || count < 1)) {
           res = gst_video_rate_flush_prev (videorate, count > 0);
@@ -650,8 +659,7 @@ gst_video_rate_event (GstPad * pad, GstEvent * event)
       }
 
       /* We just want to update the accumulated stream_time  */
-      gst_segment_set_newsegment_full (&videorate->segment, update, rate, arate,
-          format, start, stop, time);
+      gst_segment_copy_into (segment, &videorate->segment);
 
       GST_DEBUG_OBJECT (videorate, "updated segment: %" GST_SEGMENT_FORMAT,
           &videorate->segment);
@@ -669,7 +677,7 @@ gst_video_rate_event (GstPad * pad, GstEvent * event)
          * or only send out the stored buffer if there is no specific stop.
          * regardless, prevent going loopy in strange cases */
         while (res == GST_FLOW_OK && count <= MAGIC_LIMIT &&
-            ((videorate->next_ts - videorate->segment.accum <
+            ((videorate->next_ts - videorate->segment.base <
                     videorate->segment.stop)
                 || count < 1)) {
           res = gst_video_rate_flush_prev (videorate, count > 0);
@@ -683,7 +691,7 @@ gst_video_rate_event (GstPad * pad, GstEvent * event)
               videorate->next_ts + GST_BUFFER_DURATION (videorate->prevbuf);
 
           while (res == GST_FLOW_OK && count <= MAGIC_LIMIT &&
-              ((videorate->next_ts - videorate->segment.accum < end_ts)
+              ((videorate->next_ts - videorate->segment.base < end_ts)
                   || count < 1)) {
             res = gst_video_rate_flush_prev (videorate, count > 0);
             count++;
@@ -909,7 +917,7 @@ gst_video_rate_chain (GstPad * pad, GstBuffer * buffer)
 
   /* the input time is the time in the segment + all previously accumulated
    * segments */
-  intime = in_ts + videorate->segment.accum;
+  intime = in_ts + videorate->segment.base;
 
   /* we need to have two buffers to compare */
   if (videorate->prevbuf == NULL) {
@@ -923,8 +931,7 @@ gst_video_rate_chain (GstPad * pad, GstBuffer * buffer)
         videorate->base_ts = in_ts - videorate->segment.start;
         videorate->out_frame_count = 0;
       } else {
-        videorate->next_ts =
-            videorate->segment.start + videorate->segment.accum;
+        videorate->next_ts = videorate->segment.start + videorate->segment.base;
       }
     }
   } else {
@@ -1132,7 +1139,7 @@ gst_video_rate_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
-  ret = parent_class->change_state (element, transition);
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 
   switch (transition) {
     case GST_STATE_CHANGE_PAUSED_TO_READY:
index b941ed0..a3c4e08 100644 (file)
@@ -180,14 +180,14 @@ static GstPadTemplate *
 gst_video_scale_src_template_factory (void)
 {
   return gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
-      gst_caps_ref (gst_video_scale_get_capslist ()));
+      gst_video_scale_get_capslist ());
 }
 
 static GstPadTemplate *
 gst_video_scale_sink_template_factory (void)
 {
   return gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
-      gst_caps_ref (gst_video_scale_get_capslist ()));
+      gst_video_scale_get_capslist ());
 }
 
 
@@ -197,11 +197,11 @@ static gboolean gst_video_scale_src_event (GstBaseTransform * trans,
 
 /* base transform vmethods */
 static GstCaps *gst_video_scale_transform_caps (GstBaseTransform * trans,
-    GstPadDirection direction, GstCaps * caps);
+    GstPadDirection direction, GstCaps * caps, GstCaps * filter);
 static gboolean gst_video_scale_set_caps (GstBaseTransform * trans,
     GstCaps * in, GstCaps * out);
 static gboolean gst_video_scale_get_unit_size (GstBaseTransform * trans,
-    GstCaps * caps, guint * size);
+    GstCaps * caps, gsize * size);
 static GstFlowReturn gst_video_scale_transform (GstBaseTransform * trans,
     GstBuffer * in, GstBuffer * out);
 static void gst_video_scale_fixate_caps (GstBaseTransform * base,
@@ -212,28 +212,14 @@ static void gst_video_scale_set_property (GObject * object, guint prop_id,
 static void gst_video_scale_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-GST_BOILERPLATE (GstVideoScale, gst_video_scale, GstVideoFilter,
-    GST_TYPE_VIDEO_FILTER);
-
-static void
-gst_video_scale_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class,
-      "Video scaler", "Filter/Converter/Video/Scaler",
-      "Resizes video", "Wim Taymans <wim.taymans@chello.be>");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_video_scale_sink_template_factory ());
-  gst_element_class_add_pad_template (element_class,
-      gst_video_scale_src_template_factory ());
-}
+#define gst_video_scale_parent_class parent_class
+G_DEFINE_TYPE (GstVideoScale, gst_video_scale, GST_TYPE_VIDEO_FILTER);
 
 static void
 gst_video_scale_class_init (GstVideoScaleClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstElementClass *element_class = (GstElementClass *) klass;
   GstBaseTransformClass *trans_class = (GstBaseTransformClass *) klass;
 
   gobject_class->finalize = (GObjectFinalizeFunc) gst_video_scale_finalize;
@@ -251,6 +237,15 @@ gst_video_scale_class_init (GstVideoScaleClass * klass)
           DEFAULT_PROP_ADD_BORDERS,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (element_class,
+      "Video scaler", "Filter/Converter/Video/Scaler",
+      "Resizes video", "Wim Taymans <wim.taymans@chello.be>");
+
+  gst_element_class_add_pad_template (element_class,
+      gst_video_scale_sink_template_factory ());
+  gst_element_class_add_pad_template (element_class,
+      gst_video_scale_src_template_factory ());
+
   trans_class->transform_caps =
       GST_DEBUG_FUNCPTR (gst_video_scale_transform_caps);
   trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_video_scale_set_caps);
@@ -262,7 +257,7 @@ gst_video_scale_class_init (GstVideoScaleClass * klass)
 }
 
 static void
-gst_video_scale_init (GstVideoScale * videoscale, GstVideoScaleClass * klass)
+gst_video_scale_init (GstVideoScale * videoscale)
 {
   videoscale->tmp_buf = NULL;
   videoscale->method = DEFAULT_PROP_METHOD;
@@ -327,7 +322,7 @@ gst_video_scale_get_property (GObject * object, guint prop_id, GValue * value,
 
 static GstCaps *
 gst_video_scale_transform_caps (GstBaseTransform * trans,
-    GstPadDirection direction, GstCaps * caps)
+    GstPadDirection direction, GstCaps * caps, GstCaps * filter)
 {
   GstCaps *ret;
   GstStructure *structure;
@@ -340,7 +335,7 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
       (direction == GST_PAD_SINK) ? "sink" : "src");
 
   ret = gst_caps_copy (caps);
-  structure = gst_structure_copy (gst_caps_get_structure (ret, 0));
+  structure = gst_caps_get_structure (ret, 0);
 
   gst_structure_set (structure,
       "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
@@ -351,7 +346,15 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
     gst_structure_set (structure, "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE,
         1, G_MAXINT, G_MAXINT, 1, NULL);
   }
-  gst_caps_append_structure (ret, structure);
+
+  if (filter) {
+    GstCaps *intersection;
+
+    intersection =
+        gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (ret);
+    ret = intersection;
+  }
 
   GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, ret);
 
@@ -443,7 +446,7 @@ done:
 
 static gboolean
 gst_video_scale_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
-    guint * size)
+    gsize * size)
 {
   GstVideoFormat format;
   gint width, height;
@@ -1016,6 +1019,8 @@ gst_video_scale_transform (GstBaseTransform * trans, GstBuffer * in,
   gint method;
   const guint8 *black = _get_black_for_format (videoscale->format);
   gboolean add_borders;
+  guint8 *in_data, *out_data;
+  gsize in_size, out_size;
 
   GST_OBJECT_LOCK (videoscale);
   method = videoscale->method;
@@ -1030,12 +1035,14 @@ gst_video_scale_transform (GstBaseTransform * trans, GstBuffer * in,
     method = GST_VIDEO_SCALE_BILINEAR;
   }
 
+  in_data = gst_buffer_map (in, &in_size, NULL, GST_MAP_READ);
+  out_data = gst_buffer_map (out, &out_size, NULL, GST_MAP_WRITE);
+
   gst_video_scale_setup_vs_image (&src, videoscale->format, 0,
-      videoscale->from_width, videoscale->from_height, 0, 0,
-      GST_BUFFER_DATA (in));
+      videoscale->from_width, videoscale->from_height, 0, 0, in_data);
   gst_video_scale_setup_vs_image (&dest, videoscale->format, 0,
       videoscale->to_width, videoscale->to_height, videoscale->borders_w,
-      videoscale->borders_h, GST_BUFFER_DATA (out));
+      videoscale->borders_h, out_data);
 
   if (videoscale->format == GST_VIDEO_FORMAT_I420
       || videoscale->format == GST_VIDEO_FORMAT_YV12
@@ -1043,17 +1050,15 @@ gst_video_scale_transform (GstBaseTransform * trans, GstBuffer * in,
       || videoscale->format == GST_VIDEO_FORMAT_Y42B
       || videoscale->format == GST_VIDEO_FORMAT_Y41B) {
     gst_video_scale_setup_vs_image (&src_u, videoscale->format, 1,
-        videoscale->from_width, videoscale->from_height, 0, 0,
-        GST_BUFFER_DATA (in));
+        videoscale->from_width, videoscale->from_height, 0, 0, in_data);
     gst_video_scale_setup_vs_image (&src_v, videoscale->format, 2,
-        videoscale->from_width, videoscale->from_height, 0, 0,
-        GST_BUFFER_DATA (in));
+        videoscale->from_width, videoscale->from_height, 0, 0, in_data);
     gst_video_scale_setup_vs_image (&dest_u, videoscale->format, 1,
         videoscale->to_width, videoscale->to_height, videoscale->borders_w,
-        videoscale->borders_h, GST_BUFFER_DATA (out));
+        videoscale->borders_h, out_data);
     gst_video_scale_setup_vs_image (&dest_v, videoscale->format, 2,
         videoscale->to_width, videoscale->to_height, videoscale->borders_w,
-        videoscale->borders_h, GST_BUFFER_DATA (out));
+        videoscale->borders_h, out_data);
   }
 
   switch (videoscale->format) {
@@ -1260,7 +1265,11 @@ gst_video_scale_transform (GstBaseTransform * trans, GstBuffer * in,
   }
 
   GST_LOG_OBJECT (videoscale, "pushing buffer of %d bytes",
-      GST_BUFFER_SIZE (out));
+      gst_buffer_get_size (out));
+
+done:
+  gst_buffer_unmap (in, in_data, in_size);
+  gst_buffer_unmap (out, out_data, out_size);
 
   return ret;
 
@@ -1270,13 +1279,15 @@ unsupported:
     GST_ELEMENT_ERROR (videoscale, STREAM, NOT_IMPLEMENTED, (NULL),
         ("Unsupported format %d for scaling method %d",
             videoscale->format, method));
-    return GST_FLOW_ERROR;
+    ret = GST_FLOW_ERROR;
+    goto done;
   }
 unknown_mode:
   {
     GST_ELEMENT_ERROR (videoscale, STREAM, NOT_IMPLEMENTED, (NULL),
         ("Unknown scaling method %d", videoscale->method));
-    return GST_FLOW_ERROR;
+    ret = GST_FLOW_ERROR;
+    goto done;
   }
 }
 
index 227e0a9..45cd8b7 100644 (file)
@@ -82,9 +82,8 @@ enum
 };
 
 
-GST_BOILERPLATE (GstVideoTestSrc, gst_video_test_src, GstPushSrc,
-    GST_TYPE_PUSH_SRC);
-
+#define gst_video_test_src_parent_class parent_class
+G_DEFINE_TYPE (GstVideoTestSrc, gst_video_test_src, GST_TYPE_PUSH_SRC);
 
 static void gst_video_test_src_set_pattern (GstVideoTestSrc * videotestsrc,
     int pattern_type);
@@ -93,7 +92,8 @@ static void gst_video_test_src_set_property (GObject * object, guint prop_id,
 static void gst_video_test_src_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-static GstCaps *gst_video_test_src_getcaps (GstBaseSrc * bsrc);
+static GstCaps *gst_video_test_src_getcaps (GstBaseSrc * bsrc,
+    GstCaps * filter);
 static gboolean gst_video_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps);
 static void gst_video_test_src_src_fixate (GstPad * pad, GstCaps * caps);
 
@@ -107,6 +107,7 @@ static void gst_video_test_src_get_times (GstBaseSrc * basesrc,
 static GstFlowReturn gst_video_test_src_create (GstPushSrc * psrc,
     GstBuffer ** buffer);
 static gboolean gst_video_test_src_start (GstBaseSrc * basesrc);
+static gboolean gst_video_test_src_stop (GstBaseSrc * basesrc);
 
 #define GST_TYPE_VIDEO_TEST_SRC_PATTERN (gst_video_test_src_pattern_get_type ())
 static GType
@@ -165,27 +166,16 @@ gst_video_test_src_color_spec_get_type (void)
 }
 
 static void
-gst_video_test_src_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class,
-      "Video test source", "Source/Video",
-      "Creates a test video stream", "David A. Schleef <ds@schleef.org>");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
-          gst_video_test_src_getcaps (NULL)));
-}
-
-static void
 gst_video_test_src_class_init (GstVideoTestSrcClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseSrcClass *gstbasesrc_class;
   GstPushSrcClass *gstpushsrc_class;
+  GstCaps *templ_caps;
 
   gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
   gstbasesrc_class = (GstBaseSrcClass *) klass;
   gstpushsrc_class = (GstPushSrcClass *) klass;
 
@@ -303,6 +293,15 @@ gst_video_test_src_class_init (GstVideoTestSrcClass * klass)
           G_MININT32, G_MAXINT32, DEFAULT_HORIZONTAL_SPEED,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "Video test source", "Source/Video",
+      "Creates a test video stream", "David A. Schleef <ds@schleef.org>");
+
+  templ_caps = gst_video_test_src_getcaps (NULL, NULL);
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, templ_caps));
+  gst_caps_unref (templ_caps);
+
   gstbasesrc_class->get_caps = gst_video_test_src_getcaps;
   gstbasesrc_class->set_caps = gst_video_test_src_setcaps;
   gstbasesrc_class->is_seekable = gst_video_test_src_is_seekable;
@@ -310,12 +309,13 @@ gst_video_test_src_class_init (GstVideoTestSrcClass * klass)
   gstbasesrc_class->query = gst_video_test_src_query;
   gstbasesrc_class->get_times = gst_video_test_src_get_times;
   gstbasesrc_class->start = gst_video_test_src_start;
+  gstbasesrc_class->stop = gst_video_test_src_stop;
 
   gstpushsrc_class->create = gst_video_test_src_create;
 }
 
 static void
-gst_video_test_src_init (GstVideoTestSrc * src, GstVideoTestSrcClass * g_class)
+gst_video_test_src_init (GstVideoTestSrc * src)
 {
   GstPad *pad = GST_BASE_SRC_PAD (src);
 
@@ -577,7 +577,7 @@ gst_video_test_src_get_property (GObject * object, guint prop_id,
 
 /* threadsafe because this gets called as the plugin is loaded */
 static GstCaps *
-gst_video_test_src_getcaps (GstBaseSrc * bsrc)
+gst_video_test_src_getcaps (GstBaseSrc * bsrc, GstCaps * filter)
 {
   static GstCaps *capslist = NULL;
 
@@ -599,7 +599,10 @@ gst_video_test_src_getcaps (GstBaseSrc * bsrc)
     capslist = caps;
   }
 
-  return gst_caps_copy (capslist);
+  if (filter)
+    return gst_caps_intersect_full (filter, capslist, GST_CAPS_INTERSECT_FIRST);
+  else
+    return gst_caps_ref (capslist);
 }
 
 static gboolean
@@ -669,26 +672,72 @@ gst_video_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
   struct fourcc_list_struct *fourcc;
   GstVideoTestSrc *videotestsrc;
   GstVideoTestSrcColorSpec color_spec;
+  GstQuery *query;
+  GstBufferPool *pool;
+  guint size, min, max, prefix, alignment;
 
   videotestsrc = GST_VIDEO_TEST_SRC (bsrc);
 
   res = gst_video_test_src_parse_caps (caps, &width, &height,
       &rate_numerator, &rate_denominator, &fourcc, &color_spec);
-  if (res) {
-    /* looks ok here */
-    videotestsrc->fourcc = fourcc;
-    videotestsrc->width = width;
-    videotestsrc->height = height;
-    videotestsrc->rate_numerator = rate_numerator;
-    videotestsrc->rate_denominator = rate_denominator;
-    videotestsrc->bpp = videotestsrc->fourcc->bitspp;
-    videotestsrc->color_spec = color_spec;
-
-    GST_DEBUG_OBJECT (videotestsrc, "size %dx%d, %d/%d fps",
-        videotestsrc->width, videotestsrc->height,
-        videotestsrc->rate_numerator, videotestsrc->rate_denominator);
+  if (!res)
+    goto parse_failed;
+
+  /* looks ok here */
+  videotestsrc->fourcc = fourcc;
+  videotestsrc->width = width;
+  videotestsrc->height = height;
+  videotestsrc->rate_numerator = rate_numerator;
+  videotestsrc->rate_denominator = rate_denominator;
+  videotestsrc->bpp = videotestsrc->fourcc->bitspp;
+  videotestsrc->color_spec = color_spec;
+
+  GST_DEBUG_OBJECT (videotestsrc, "size %dx%d, %d/%d fps",
+      videotestsrc->width, videotestsrc->height,
+      videotestsrc->rate_numerator, videotestsrc->rate_denominator);
+
+  /* find a pool for the negotiated caps now */
+  query = gst_query_new_allocation (caps, TRUE);
+
+  if (gst_pad_peer_query (bsrc->srcpad, query)) {
+    /* we got configuration from our peer, parse them */
+    gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
+        &alignment, &pool);
+  } else {
+    size = gst_video_test_src_get_size (videotestsrc, width, height);
+    min = max = 0;
+    prefix = 0;
+    alignment = 1;
+    pool = NULL;
+  }
+
+  if (pool == NULL) {
+    GstStructure *config;
+
+    /* we did not get a pool, make one ourselves then */
+    pool = gst_buffer_pool_new ();
+
+    config = gst_buffer_pool_get_config (pool);
+    gst_buffer_pool_config_set (config, caps, size, min, max, prefix, 0,
+        alignment);
+    gst_buffer_pool_set_config (pool, config);
   }
+
+  if (videotestsrc->pool)
+    gst_object_unref (videotestsrc->pool);
+  videotestsrc->pool = pool;
+
+  /* and activate */
+  gst_buffer_pool_set_active (pool, TRUE);
+
   return res;
+
+  /* ERRORS */
+parse_failed:
+  {
+    GST_DEBUG_OBJECT (bsrc, "failed to parse caps");
+    return FALSE;
+  }
 }
 
 static gboolean
@@ -789,17 +838,17 @@ gst_video_test_src_get_times (GstBaseSrc * basesrc, GstBuffer * buffer,
 static gboolean
 gst_video_test_src_do_seek (GstBaseSrc * bsrc, GstSegment * segment)
 {
-  GstClockTime time;
+  GstClockTime position;
   GstVideoTestSrc *src;
 
   src = GST_VIDEO_TEST_SRC (bsrc);
 
   segment->time = segment->start;
-  time = segment->last_stop;
+  position = segment->position;
 
-  /* now move to the time indicated */
+  /* now move to the position indicated */
   if (src->rate_numerator) {
-    src->n_frames = gst_util_uint64_scale (time,
+    src->n_frames = gst_util_uint64_scale (position,
         src->rate_numerator, src->rate_denominator * GST_SECOND);
   } else {
     src->n_frames = 0;
@@ -812,7 +861,7 @@ gst_video_test_src_do_seek (GstBaseSrc * bsrc, GstSegment * segment)
     src->running_time = 0;
   }
 
-  g_assert (src->running_time <= time);
+  g_assert (src->running_time <= position);
 
   return TRUE;
 }
@@ -828,59 +877,36 @@ static GstFlowReturn
 gst_video_test_src_create (GstPushSrc * psrc, GstBuffer ** buffer)
 {
   GstVideoTestSrc *src;
-  gulong newsize, size;
+  gsize size;
   GstBuffer *outbuf = NULL;
   GstFlowReturn res;
   GstClockTime next_time;
+  guint8 *data;
 
   src = GST_VIDEO_TEST_SRC (psrc);
 
-  if (G_UNLIKELY (src->fourcc == NULL))
+  if (G_UNLIKELY (src->pool == NULL))
     goto not_negotiated;
 
   /* 0 framerate and we are at the second frame, eos */
   if (G_UNLIKELY (src->rate_numerator == 0 && src->n_frames == 1))
     goto eos;
 
-  newsize = gst_video_test_src_get_size (src, src->width, src->height);
-
-  g_return_val_if_fail (newsize > 0, GST_FLOW_ERROR);
-
   GST_LOG_OBJECT (src,
-      "creating buffer of %lu bytes with %dx%d image for frame %d", newsize,
-      src->width, src->height, (gint) src->n_frames);
-
-  if (src->peer_alloc) {
-    res =
-        gst_pad_alloc_buffer_and_set_caps (GST_BASE_SRC_PAD (psrc),
-        GST_BUFFER_OFFSET_NONE, newsize, GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc)),
-        &outbuf);
-    if (res != GST_FLOW_OK)
-      goto no_buffer;
-
-    /* the buffer could have renegotiated, we need to discard any buffers of the
-     * wrong size. */
-    size = GST_BUFFER_SIZE (outbuf);
-    newsize = gst_video_test_src_get_size (src, src->width, src->height);
-
-    if (size != newsize) {
-      gst_buffer_unref (outbuf);
-      outbuf = NULL;
-    }
-  }
+      "creating buffer from pool for frame %d", (gint) src->n_frames);
 
-  if (outbuf == NULL) {
-    outbuf = gst_buffer_new_and_alloc (newsize);
-    gst_buffer_set_caps (outbuf, GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc)));
-  }
+  res = gst_buffer_pool_acquire_buffer (src->pool, &outbuf, NULL);
+  if (res != GST_FLOW_OK)
+    goto no_buffer;
 
-  memset (GST_BUFFER_DATA (outbuf), 0, GST_BUFFER_SIZE (outbuf));
+  data = gst_buffer_map (outbuf, &size, NULL, GST_MAP_WRITE);
+  memset (data, 0, size);
   src->tmpline_u8 = g_malloc (src->width + 8);
   src->tmpline = g_malloc ((src->width + 8) * 4);
   src->tmpline2 = g_malloc ((src->width + 8) * 4);
 
-  src->make_image (src, (void *) GST_BUFFER_DATA (outbuf),
-      src->width, src->height);
+  src->make_image (src, (void *) data, src->width, src->height);
+  gst_buffer_unmap (outbuf, data, size);
 
   g_free (src->tmpline);
   g_free (src->tmpline2);
@@ -937,6 +963,22 @@ gst_video_test_src_start (GstBaseSrc * basesrc)
 }
 
 static gboolean
+gst_video_test_src_stop (GstBaseSrc * basesrc)
+{
+  GstVideoTestSrc *src = GST_VIDEO_TEST_SRC (basesrc);
+
+  /* deactivate */
+
+  if (src->pool) {
+    gst_buffer_pool_set_active (src->pool, FALSE);
+    gst_object_unref (src->pool);
+  }
+  src->pool = NULL;
+
+  return TRUE;
+}
+
+static gboolean
 plugin_init (GstPlugin * plugin)
 {
   gst_videotestsrc_orc_init ();
index ae63281..011b49a 100644 (file)
@@ -143,6 +143,9 @@ struct _GstVideoTestSrc {
   gint rate_numerator;
   gint rate_denominator;
 
+  /* the bufferpool */
+  GstBufferPool *pool;
+
   /* private */
   gint64 timestamp_offset;              /* base offset */
   GstClockTime running_time;            /* total running time */
index a592707..d2b7c5c 100644 (file)
@@ -142,32 +142,12 @@ enum
 static void gst_volume_interface_init (GstImplementsInterfaceClass * klass);
 static void gst_volume_mixer_init (GstMixerClass * iface);
 
-#define _init_interfaces(type)                                          \
-  {                                                                     \
-    static const GInterfaceInfo voliface_info = {                       \
-      (GInterfaceInitFunc) gst_volume_interface_init,                   \
-      NULL,                                                             \
-      NULL                                                              \
-    };                                                                  \
-    static const GInterfaceInfo volmixer_info = {                       \
-      (GInterfaceInitFunc) gst_volume_mixer_init,                       \
-      NULL,                                                             \
-      NULL                                                              \
-    };                                                                  \
-    static const GInterfaceInfo svol_info = {                           \
-      NULL,                                                             \
-      NULL,                                                             \
-      NULL                                                              \
-    };                                                                  \
-                                                                        \
-    g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,   \
-        &voliface_info);                                                \
-    g_type_add_interface_static (type, GST_TYPE_MIXER, &volmixer_info); \
-    g_type_add_interface_static (type, GST_TYPE_STREAM_VOLUME, &svol_info); \
-  }
-
-GST_BOILERPLATE_FULL (GstVolume, gst_volume, GstAudioFilter,
-    GST_TYPE_AUDIO_FILTER, _init_interfaces);
+#define gst_volume_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstVolume, gst_volume,
+    GST_TYPE_AUDIO_FILTER, G_IMPLEMENT_INTERFACE (GST_TYPE_IMPLEMENTS_INTERFACE,
+        gst_volume_interface_init);
+    G_IMPLEMENT_INTERFACE (GST_TYPE_MIXER, gst_volume_mixer_init);
+    G_IMPLEMENT_INTERFACE (GST_TYPE_STREAM_VOLUME, NULL));
 
 static void volume_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
@@ -432,29 +412,16 @@ gst_volume_dispose (GObject * object)
 }
 
 static void
-gst_volume_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-  GstAudioFilterClass *filter_class = GST_AUDIO_FILTER_CLASS (g_class);
-  GstCaps *caps;
-
-  gst_element_class_set_details_simple (element_class, "Volume",
-      "Filter/Effect/Audio",
-      "Set volume on audio/raw streams", "Andy Wingo <wingo@pobox.com>");
-
-  caps = gst_caps_from_string (ALLOWED_CAPS);
-  gst_audio_filter_class_add_pad_templates (filter_class, caps);
-  gst_caps_unref (caps);
-}
-
-static void
 gst_volume_class_init (GstVolumeClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *element_class;
   GstBaseTransformClass *trans_class;
   GstAudioFilterClass *filter_class;
+  GstCaps *caps;
 
   gobject_class = (GObjectClass *) klass;
+  element_class = (GstElementClass *) klass;
   trans_class = (GstBaseTransformClass *) klass;
   filter_class = (GstAudioFilterClass *) (klass);
 
@@ -472,6 +439,14 @@ gst_volume_class_init (GstVolumeClass * klass)
           0.0, VOLUME_MAX_DOUBLE, DEFAULT_PROP_VOLUME,
           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (element_class, "Volume",
+      "Filter/Effect/Audio",
+      "Set volume on audio/raw streams", "Andy Wingo <wingo@pobox.com>");
+
+  caps = gst_caps_from_string (ALLOWED_CAPS);
+  gst_audio_filter_class_add_pad_templates (filter_class, caps);
+  gst_caps_unref (caps);
+
   trans_class->before_transform = GST_DEBUG_FUNCPTR (volume_before_transform);
   trans_class->transform_ip = GST_DEBUG_FUNCPTR (volume_transform_ip);
   trans_class->stop = GST_DEBUG_FUNCPTR (volume_stop);
@@ -479,7 +454,7 @@ gst_volume_class_init (GstVolumeClass * klass)
 }
 
 static void
-gst_volume_init (GstVolume * self, GstVolumeClass * g_class)
+gst_volume_init (GstVolume * self)
 {
   GstMixerTrack *track = NULL;
 
@@ -874,7 +849,7 @@ volume_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
 {
   GstVolume *self = GST_VOLUME (base);
   guint8 *data;
-  guint size;
+  gsize size;
   GstControlSource *mute_csource, *volume_csource;
 
   if (G_UNLIKELY (!self->negotiated))
@@ -885,8 +860,7 @@ volume_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
       GST_BUFFER_FLAG_IS_SET (outbuf, GST_BUFFER_FLAG_GAP))
     return GST_FLOW_OK;
 
-  data = GST_BUFFER_DATA (outbuf);
-  size = GST_BUFFER_SIZE (outbuf);
+  data = gst_buffer_map (outbuf, &size, NULL, GST_MAP_READWRITE);
 
   mute_csource = gst_object_get_control_source (G_OBJECT (self), "mute");
   volume_csource = gst_object_get_control_source (G_OBJECT (self), "volume");
@@ -954,6 +928,7 @@ volume_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
   } else if (self->current_volume != 1.0) {
     self->process (self, data, size);
   }
+  gst_buffer_unmap (outbuf, data, size);
 
   return GST_FLOW_OK;
 
@@ -973,6 +948,7 @@ controller_failure:
 
     GST_ELEMENT_ERROR (self, CORE, FAILED,
         ("Failed to get values from controller"), (NULL));
+    gst_buffer_unmap (outbuf, data, size);
     return GST_FLOW_ERROR;
   }
 }
index 91776af..5d138e4 100644 (file)
@@ -57,8 +57,9 @@ GST_DEBUG_CATEGORY (v4lelement_debug);
 
 static void gst_v4lelement_init_interfaces (GType type);
 
-GST_BOILERPLATE_FULL (GstV4lElement, gst_v4lelement, GstPushSrc,
-    GST_TYPE_PUSH_SRC, gst_v4lelement_init_interfaces);
+#define gst_v4lelement_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstV4lElement, gst_v4lelement,
+    GST_TYPE_PUSH_SRC, gst_v4lelement_init_interfaces (g_define_type_id));
 
 static void gst_v4lelement_dispose (GObject * object);
 static void gst_v4lelement_set_property (GObject * object,
@@ -384,18 +385,6 @@ gst_v4lelement_init_interfaces (GType type)
       GST_TYPE_PROPERTY_PROBE, &v4l_propertyprobe_info);
 }
 
-
-static void
-gst_v4lelement_base_init (gpointer g_class)
-{
-  GstV4lElementClass *klass = GST_V4LELEMENT_CLASS (g_class);
-
-  klass->devices = NULL;
-
-  GST_DEBUG_CATEGORY_INIT (v4lelement_debug, "v4lelement", 0,
-      "V4L Base Class debug");
-}
-
 static void
 gst_v4lelement_class_init (GstV4lElementClass * klass)
 {
@@ -405,6 +394,9 @@ gst_v4lelement_class_init (GstV4lElementClass * klass)
   gobject_class = (GObjectClass *) klass;
   element_class = GST_ELEMENT_CLASS (klass);
 
+  GST_DEBUG_CATEGORY_INIT (v4lelement_debug, "v4lelement", 0,
+      "V4L Base Class debug");
+
   gobject_class->set_property = gst_v4lelement_set_property;
   gobject_class->get_property = gst_v4lelement_get_property;
   gobject_class->dispose = gst_v4lelement_dispose;
@@ -421,12 +413,10 @@ gst_v4lelement_class_init (GstV4lElementClass * klass)
       g_param_spec_flags ("flags", "Flags", "Device type flags",
           GST_TYPE_V4L_DEVICE_FLAGS, 0,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-
 }
 
-
 static void
-gst_v4lelement_init (GstV4lElement * v4lelement, GstV4lElementClass * klass)
+gst_v4lelement_init (GstV4lElement * v4lelement)
 {
   /* some default values */
   v4lelement->video_fd = -1;
index 61860a1..74f6079 100644 (file)
@@ -641,7 +641,7 @@ gst_v4lmjpegsrc_getcaps (GstPad * pad)
   0};
 
   if (!GST_V4L_IS_OPEN (GST_V4LELEMENT (v4lmjpegsrc))) {
-    return gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+    return gst_pad_get_pad_template_caps (pad);
   }
 
   g_value_init (&fps, GST_TYPE_FRACTION);
index c0b5f78..c7d2b29 100644 (file)
@@ -43,8 +43,8 @@ enum
   PROP_TIMESTAMP_OFFSET
 };
 
-
-GST_BOILERPLATE (GstV4lSrc, gst_v4lsrc, GstV4lElement, GST_TYPE_V4LELEMENT);
+#define gst_v4lsrc_parent_class parent_class
+G_DEFINE_TYPE (GstV4lSrc, gst_v4lsrc, GST_TYPE_V4LELEMENT);
 
 static GstStaticPadTemplate v4l_src_template = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
@@ -56,7 +56,7 @@ static GstStaticPadTemplate v4l_src_template = GST_STATIC_PAD_TEMPLATE ("src",
 static gboolean gst_v4lsrc_start (GstBaseSrc * src);
 static gboolean gst_v4lsrc_stop (GstBaseSrc * src);
 static gboolean gst_v4lsrc_set_caps (GstBaseSrc * src, GstCaps * caps);
-static GstCaps *gst_v4lsrc_get_caps (GstBaseSrc * src);
+static GstCaps *gst_v4lsrc_get_caps (GstBaseSrc * src, GstCaps * filter);
 static GstFlowReturn gst_v4lsrc_create (GstPushSrc * src, GstBuffer ** out);
 static gboolean gst_v4lsrc_query (GstBaseSrc * bsrc, GstQuery * query);
 static void gst_v4lsrc_fixate (GstBaseSrc * bsrc, GstCaps * caps);
@@ -66,32 +66,21 @@ static void gst_v4lsrc_set_property (GObject * object,
 static void gst_v4lsrc_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 
-
-static void
-gst_v4lsrc_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "Video (video4linux/raw) Source", "Source/Video",
-      "Reads raw frames from a video4linux device",
-      "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
-
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&v4l_src_template));
-}
-
 static void
 gst_v4lsrc_class_init (GstV4lSrcClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *element_class;
   GstBaseSrcClass *basesrc_class;
   GstPushSrcClass *pushsrc_class;
 
   gobject_class = (GObjectClass *) klass;
+  element_class = (GstElementClass *) klass;
   basesrc_class = (GstBaseSrcClass *) klass;
   pushsrc_class = (GstPushSrcClass *) klass;
 
+  GST_DEBUG_CATEGORY_INIT (v4lsrc_debug, "v4lsrc", 0, "V4L source element");
+
   gobject_class->set_property = gst_v4lsrc_set_property;
   gobject_class->get_property = gst_v4lsrc_get_property;
 
@@ -114,7 +103,13 @@ gst_v4lsrc_class_init (GstV4lSrcClass * klass)
           G_MININT64, G_MAXINT64, 0,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  GST_DEBUG_CATEGORY_INIT (v4lsrc_debug, "v4lsrc", 0, "V4L source element");
+  gst_element_class_set_details_simple (element_class,
+      "Video (video4linux/raw) Source", "Source/Video",
+      "Reads raw frames from a video4linux device",
+      "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&v4l_src_template));
 
   basesrc_class->get_caps = gst_v4lsrc_get_caps;
   basesrc_class->set_caps = gst_v4lsrc_set_caps;
@@ -127,7 +122,7 @@ gst_v4lsrc_class_init (GstV4lSrcClass * klass)
 }
 
 static void
-gst_v4lsrc_init (GstV4lSrc * v4lsrc, GstV4lSrcClass * klass)
+gst_v4lsrc_init (GstV4lSrc * v4lsrc)
 {
   v4lsrc->buffer_size = 0;
 
@@ -364,7 +359,7 @@ gst_v4lsrc_get_any_caps (void)
 }
 
 static GstCaps *
-gst_v4lsrc_get_caps (GstBaseSrc * src)
+gst_v4lsrc_get_caps (GstBaseSrc * src, GstCaps * filter)
 {
   GstCaps *list;
   GstV4lSrc *v4lsrc = GST_V4LSRC (src);
@@ -376,12 +371,30 @@ gst_v4lsrc_get_caps (GstBaseSrc * src)
   GList *item;
 
   if (!GST_V4L_IS_OPEN (GST_V4LELEMENT (v4lsrc))) {
-    return gst_v4lsrc_get_any_caps ();
+    GstCaps *caps, *intersection;
+
+    caps = gst_v4lsrc_get_any_caps ();
+    if (filter) {
+      intersection =
+          gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+      gst_caps_unref (caps);
+      caps = intersection;
+    }
+    return caps;
   }
 
   if (!v4lsrc->autoprobe) {
+    GstCaps *caps, *intersection;
+
     /* FIXME: query current caps and return those, with _any appended */
-    return gst_v4lsrc_get_any_caps ();
+    caps = gst_v4lsrc_get_any_caps ();
+    if (filter) {
+      intersection =
+          gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+      gst_caps_unref (caps);
+      caps = intersection;
+    }
+    return caps;
   }
 
   if (!v4lsrc->colorspaces) {
@@ -456,6 +469,15 @@ gst_v4lsrc_get_caps (GstBaseSrc * src)
     gst_caps_append (list, one);
   }
 
+  if (filter) {
+    GstCaps *intersection;
+
+    intersection =
+        gst_caps_intersect_full (filter, list, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (list);
+    list = intersection;
+  }
+
   return list;
 }
 
index 31bd6de..8c74638 100644 (file)
@@ -616,78 +616,27 @@ gst_v4lsrc_get_fps_list (GstV4lSrc * v4lsrc)
   }
 }
 
-#define GST_TYPE_V4LSRC_BUFFER (gst_v4lsrc_buffer_get_type())
-#define GST_IS_V4LSRC_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4LSRC_BUFFER))
-#define GST_V4LSRC_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4LSRC_BUFFER, GstV4lSrcBuffer))
-
-typedef struct _GstV4lSrcBuffer
+typedef struct _GstMetaV4lSrc
 {
-  GstBuffer buffer;
+  GstMeta meta;
 
   GstV4lSrc *v4lsrc;
-
   gint num;
-} GstV4lSrcBuffer;
-
-static void gst_v4lsrc_buffer_class_init (gpointer g_class,
-    gpointer class_data);
-static void gst_v4lsrc_buffer_init (GTypeInstance * instance, gpointer g_class);
-static void gst_v4lsrc_buffer_finalize (GstV4lSrcBuffer * v4lsrc_buffer);
+} GstMetaV4lSrc;
 
-static GstBufferClass *v4lbuffer_parent_class = NULL;
-
-static GType
-gst_v4lsrc_buffer_get_type (void)
-{
-  static GType _gst_v4lsrc_buffer_type;
-
-  if (G_UNLIKELY (_gst_v4lsrc_buffer_type == 0)) {
-    static const GTypeInfo v4lsrc_buffer_info = {
-      sizeof (GstBufferClass),
-      NULL,
-      NULL,
-      gst_v4lsrc_buffer_class_init,
-      NULL,
-      NULL,
-      sizeof (GstV4lSrcBuffer),
-      0,
-      gst_v4lsrc_buffer_init,
-      NULL
-    };
-    _gst_v4lsrc_buffer_type = g_type_register_static (GST_TYPE_BUFFER,
-        "GstV4lSrcBuffer", &v4lsrc_buffer_info, 0);
-  }
-  return _gst_v4lsrc_buffer_type;
-}
+#define GST_META_V4LSRC_GET(buf) ((GstMetaV4lSrc *)gst_buffer_get_meta(buf,gst_meta_v4lsrc_get_info()))
+#define GST_META_V4LSRC_ADD(buf) ((GstMetaV4lSrc *)gst_buffer_add_meta(buf,gst_meta_v4lsrc_get_info(), NULL))
 
 static void
-gst_v4lsrc_buffer_class_init (gpointer g_class, gpointer class_data)
+meta_v4lsrc_free (GstMetaV4lSrc * meta, GstBuffer * buffer)
 {
-  GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
-
-  v4lbuffer_parent_class = g_type_class_peek_parent (g_class);
-
-  mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
-      gst_v4lsrc_buffer_finalize;
-}
-
-static void
-gst_v4lsrc_buffer_init (GTypeInstance * instance, gpointer g_class)
-{
-
-}
-
-static void
-gst_v4lsrc_buffer_finalize (GstV4lSrcBuffer * v4lsrc_buffer)
-{
-  GstMiniObjectClass *miniobject_class;
   GstV4lSrc *v4lsrc;
   gint num;
 
-  v4lsrc = v4lsrc_buffer->v4lsrc;
-  num = v4lsrc_buffer->num;
+  v4lsrc = meta->v4lsrc;
+  num = meta->num;
 
-  GST_LOG_OBJECT (v4lsrc, "freeing buffer %p for frame %d", v4lsrc_buffer, num);
+  GST_LOG_OBJECT (v4lsrc, "freeing buffer %p for frame %d", buffer, num);
 
   /* only requeue if we still have an mmap buffer */
   if (GST_V4LELEMENT (v4lsrc)->buffer) {
@@ -696,15 +645,29 @@ gst_v4lsrc_buffer_finalize (GstV4lSrcBuffer * v4lsrc_buffer)
   }
 
   gst_object_unref (v4lsrc);
+}
 
-  miniobject_class = (GstMiniObjectClass *) v4lbuffer_parent_class;
-  miniobject_class->finalize (GST_MINI_OBJECT_CAST (v4lsrc_buffer));
+static const GstMetaInfo *
+gst_meta_v4lsrc_get_info (void)
+{
+  static const GstMetaInfo *meta_v4lsrc_info = NULL;
+
+  if (meta_v4lsrc_info == NULL) {
+    meta_v4lsrc_info = gst_meta_register ("GstMetaV4lSrc", "GstMetaV4lSrc",
+        sizeof (GstMetaV4lSrc),
+        (GstMetaInitFunction) NULL,
+        (GstMetaFreeFunction) meta_v4lsrc_free,
+        (GstMetaCopyFunction) NULL, (GstMetaTransformFunction) NULL);
+  }
+  return meta_v4lsrc_info;
 }
 
+
 /* Create a V4lSrc buffer from our mmap'd data area */
 GstBuffer *
 gst_v4lsrc_buffer_new (GstV4lSrc * v4lsrc, gint num)
 {
+  GstMetaV4lSrc *meta;
   GstClockTime duration, timestamp, latency;
   GstBuffer *buf;
   GstClock *clock;
@@ -715,14 +678,18 @@ gst_v4lsrc_buffer_new (GstV4lSrc * v4lsrc, gint num)
   if (!(gst_v4lsrc_get_fps (v4lsrc, &fps_n, &fps_d)))
     return NULL;
 
-  buf = (GstBuffer *) gst_mini_object_new (GST_TYPE_V4LSRC_BUFFER);
+  buf = gst_buffer_new ();
+
+  /* attach private metadata with the frame num and v4lsrc element */
+  meta = GST_META_V4LSRC_ADD (buf);
+  meta->num = num;
+  meta->v4lsrc = gst_object_ref (v4lsrc);
 
-  GST_V4LSRC_BUFFER (buf)->num = num;
-  GST_V4LSRC_BUFFER (buf)->v4lsrc = gst_object_ref (v4lsrc);
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          gst_v4lsrc_get_buffer (v4lsrc, num), NULL, v4lsrc->buffer_size,
+          0, v4lsrc->buffer_size));
 
-  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
-  GST_BUFFER_DATA (buf) = gst_v4lsrc_get_buffer (v4lsrc, num);
-  GST_BUFFER_SIZE (buf) = v4lsrc->buffer_size;
   GST_BUFFER_OFFSET (buf) = v4lsrc->offset++;
   GST_BUFFER_OFFSET_END (buf) = v4lsrc->offset;
 
index 69f9bbc..df14448 100644 (file)
@@ -1,6 +1,6 @@
 plugin_LTLIBRARIES = libgstximagesink.la
 
-libgstximagesink_la_SOURCES =  ximagesink.c ximage.c
+libgstximagesink_la_SOURCES =  ximagesink.c ximage.c ximagepool.c
 libgstximagesink_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(X_CFLAGS)
 libgstximagesink_la_LIBADD = \
        $(top_builddir)/gst-libs/gst/interfaces/libgstinterfaces-$(GST_MAJORMINOR).la \
@@ -11,4 +11,4 @@ libgstximagesink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstximagesink_la_DEPENDENCIES = $(top_builddir)/gst-libs/gst/video/libgstvideo-$(GST_MAJORMINOR).la
 libgstximagesink_la_LIBTOOLFLAGS = --tag=disable-static
 
-noinst_HEADERS = ximagesink.h 
+noinst_HEADERS = ximagesink.h ximagepool.h
index 24b7bf2..24a9e61 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
-
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include "ximagesink.h"
 
+GST_DEBUG_CATEGORY (gst_debug_ximagepool);
 GST_DEBUG_CATEGORY (gst_debug_ximagesink);
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
 
 static gboolean
 plugin_init (GstPlugin * plugin)
@@ -36,6 +36,10 @@ plugin_init (GstPlugin * plugin)
 
   GST_DEBUG_CATEGORY_INIT (gst_debug_ximagesink, "ximagesink", 0,
       "ximagesink element");
+  GST_DEBUG_CATEGORY_INIT (gst_debug_ximagepool, "ximagepool", 0,
+      "ximagepool object");
+
+  GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
 
   return TRUE;
 }
diff --git a/sys/ximage/ximagepool.c b/sys/ximage/ximagepool.c
new file mode 100644 (file)
index 0000000..b6edc3b
--- /dev/null
@@ -0,0 +1,566 @@
+/* GStreamer
+ * Copyright (C) <2005> Julien Moutte <julien@moutte.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Object header */
+#include "ximagesink.h"
+
+/* Debugging category */
+#include <gst/gstinfo.h>
+
+GST_DEBUG_CATEGORY_EXTERN (gst_debug_ximagepool);
+#define GST_CAT_DEFAULT gst_debug_ximagepool
+
+static void gst_meta_ximage_free (GstMetaXImage * meta, GstBuffer * buffer);
+
+/* ximage metadata */
+const GstMetaInfo *
+gst_meta_ximage_get_info (void)
+{
+  static const GstMetaInfo *meta_ximage_info = NULL;
+
+  if (meta_ximage_info == NULL) {
+    meta_ximage_info = gst_meta_register ("GstMetaXImage", "GstMetaXImage",
+        sizeof (GstMetaXImage),
+        (GstMetaInitFunction) NULL,
+        (GstMetaFreeFunction) gst_meta_ximage_free,
+        (GstMetaCopyFunction) NULL, (GstMetaTransformFunction) NULL);
+  }
+  return meta_ximage_info;
+}
+
+/* X11 stuff */
+static gboolean error_caught = FALSE;
+
+static int
+gst_ximagesink_handle_xerror (Display * display, XErrorEvent * xevent)
+{
+  char error_msg[1024];
+
+  XGetErrorText (display, xevent->error_code, error_msg, 1024);
+  GST_DEBUG ("ximagesink triggered an XError. error: %s", error_msg);
+  error_caught = TRUE;
+  return 0;
+}
+
+GstMetaXImage *
+gst_buffer_add_meta_ximage (GstBuffer * buffer, GstXImageSink * ximagesink,
+    gint width, gint height)
+{
+  int (*handler) (Display *, XErrorEvent *);
+  gboolean success = FALSE;
+  GstXContext *xcontext;
+  GstMetaXImage *meta;
+
+  xcontext = ximagesink->xcontext;
+
+  meta =
+      (GstMetaXImage *) gst_buffer_add_meta (buffer, GST_META_INFO_XIMAGE,
+      NULL);
+#ifdef HAVE_XSHM
+  meta->SHMInfo.shmaddr = ((void *) -1);
+  meta->SHMInfo.shmid = -1;
+#endif
+  meta->width = width;
+  meta->height = height;
+  meta->sink = gst_object_ref (ximagesink);
+
+  GST_DEBUG_OBJECT (ximagesink, "creating image %p (%dx%d)", buffer,
+      meta->width, meta->height);
+
+  g_mutex_lock (ximagesink->x_lock);
+
+  /* Setting an error handler to catch failure */
+  error_caught = FALSE;
+  handler = XSetErrorHandler (gst_ximagesink_handle_xerror);
+
+#ifdef HAVE_XSHM
+  if (xcontext->use_xshm) {
+    meta->ximage = XShmCreateImage (xcontext->disp,
+        xcontext->visual,
+        xcontext->depth,
+        ZPixmap, NULL, &meta->SHMInfo, meta->width, meta->height);
+    if (!meta->ximage || error_caught)
+      goto create_failed;
+
+    /* we have to use the returned bytes_per_line for our shm size */
+    meta->size = meta->ximage->bytes_per_line * meta->ximage->height;
+    GST_LOG_OBJECT (ximagesink,
+        "XShm image size is %" G_GSIZE_FORMAT ", width %d, stride %d",
+        meta->size, meta->width, meta->ximage->bytes_per_line);
+
+    /* get shared memory */
+    meta->SHMInfo.shmid = shmget (IPC_PRIVATE, meta->size, IPC_CREAT | 0777);
+    if (meta->SHMInfo.shmid == -1)
+      goto shmget_failed;
+
+    /* attach */
+    meta->SHMInfo.shmaddr = shmat (meta->SHMInfo.shmid, NULL, 0);
+    if (meta->SHMInfo.shmaddr == ((void *) -1))
+      goto shmat_failed;
+
+    /* now we can set up the image data */
+    meta->ximage->data = meta->SHMInfo.shmaddr;
+    meta->SHMInfo.readOnly = FALSE;
+
+    if (XShmAttach (xcontext->disp, &meta->SHMInfo) == 0)
+      goto xattach_failed;
+
+    XSync (xcontext->disp, FALSE);
+
+    /* Now that everyone has attached, we can delete the shared memory segment.
+     * This way, it will be deleted as soon as we detach later, and not
+     * leaked if we crash. */
+    shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL);
+
+    GST_DEBUG_OBJECT (ximagesink, "XServer ShmAttached to 0x%x, id 0x%lx",
+        meta->SHMInfo.shmid, meta->SHMInfo.shmseg);
+  } else
+#endif /* HAVE_XSHM */
+  {
+    guint allocsize;
+
+    meta->ximage = XCreateImage (xcontext->disp,
+        xcontext->visual,
+        xcontext->depth,
+        ZPixmap, 0, NULL, meta->width, meta->height, xcontext->bpp, 0);
+    if (!meta->ximage || error_caught)
+      goto create_failed;
+
+    /* upstream will assume that rowstrides are multiples of 4, but this
+     * doesn't always seem to be the case with XCreateImage() */
+    if ((meta->ximage->bytes_per_line % 4) != 0) {
+      GST_WARNING_OBJECT (ximagesink, "returned stride not a multiple of 4 as "
+          "usually assumed");
+    }
+
+    /* we have to use the returned bytes_per_line for our image size */
+    meta->size = meta->ximage->bytes_per_line * meta->ximage->height;
+
+    /* alloc a bit more for unexpected strides to avoid crashes upstream.
+     * FIXME: if we get an unrounded stride, the image will be displayed
+     * distorted, since all upstream elements assume a rounded stride */
+    allocsize =
+        GST_ROUND_UP_4 (meta->ximage->bytes_per_line) * meta->ximage->height;
+
+    meta->ximage->data = g_malloc (allocsize);
+    GST_LOG_OBJECT (ximagesink,
+        "non-XShm image size is %" G_GSIZE_FORMAT " (alloced: %u), width %d, "
+        "stride %d", meta->size, allocsize, meta->width,
+        meta->ximage->bytes_per_line);
+
+    XSync (xcontext->disp, FALSE);
+  }
+
+  /* Reset error handler */
+  error_caught = FALSE;
+  XSetErrorHandler (handler);
+
+  gst_buffer_take_memory (buffer,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, meta->ximage->data,
+          NULL, meta->size, 0, meta->size));
+
+  g_mutex_unlock (ximagesink->x_lock);
+
+  success = TRUE;
+
+beach:
+  if (!success)
+    meta = NULL;
+
+  return meta;
+
+  /* ERRORS */
+create_failed:
+  {
+    g_mutex_unlock (ximagesink->x_lock);
+    /* Reset error handler */
+    error_caught = FALSE;
+    XSetErrorHandler (handler);
+    /* Push an error */
+    GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
+        ("Failed to create output image buffer of %dx%d pixels",
+            meta->width, meta->height),
+        ("could not XShmCreateImage a %dx%d image", meta->width, meta->height));
+    goto beach;
+  }
+shmget_failed:
+  {
+    g_mutex_unlock (ximagesink->x_lock);
+    GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
+        ("Failed to create output image buffer of %dx%d pixels",
+            meta->width, meta->height),
+        ("could not get shared memory of %" G_GSIZE_FORMAT " bytes",
+            meta->size));
+    goto beach;
+  }
+shmat_failed:
+  {
+    g_mutex_unlock (ximagesink->x_lock);
+    GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
+        ("Failed to create output image buffer of %dx%d pixels",
+            meta->width, meta->height),
+        ("Failed to shmat: %s", g_strerror (errno)));
+    /* Clean up the shared memory segment */
+    shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL);
+    goto beach;
+  }
+xattach_failed:
+  {
+    /* Clean up the shared memory segment */
+    shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL);
+    g_mutex_unlock (ximagesink->x_lock);
+
+    GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
+        ("Failed to create output image buffer of %dx%d pixels",
+            meta->width, meta->height), ("Failed to XShmAttach"));
+    goto beach;
+  }
+}
+
+static void
+gst_meta_ximage_free (GstMetaXImage * meta, GstBuffer * buffer)
+{
+  GstXImageSink *ximagesink;
+
+  ximagesink = meta->sink;
+
+  GST_DEBUG_OBJECT (ximagesink, "free meta on buffer %p", buffer);
+
+  /* Hold the object lock to ensure the XContext doesn't disappear */
+  GST_OBJECT_LOCK (ximagesink);
+  /* We might have some buffers destroyed after changing state to NULL */
+  if (ximagesink->xcontext == NULL) {
+    GST_DEBUG_OBJECT (ximagesink, "Destroying XImage after XContext");
+#ifdef HAVE_XSHM
+    /* Need to free the shared memory segment even if the x context
+     * was already cleaned up */
+    if (meta->SHMInfo.shmaddr != ((void *) -1)) {
+      shmdt (meta->SHMInfo.shmaddr);
+    }
+#endif
+    goto beach;
+  }
+
+  g_mutex_lock (ximagesink->x_lock);
+
+#ifdef HAVE_XSHM
+  if (ximagesink->xcontext->use_xshm) {
+    if (meta->SHMInfo.shmaddr != ((void *) -1)) {
+      GST_DEBUG_OBJECT (ximagesink, "XServer ShmDetaching from 0x%x id 0x%lx",
+          meta->SHMInfo.shmid, meta->SHMInfo.shmseg);
+      XShmDetach (ximagesink->xcontext->disp, &meta->SHMInfo);
+      XSync (ximagesink->xcontext->disp, FALSE);
+      shmdt (meta->SHMInfo.shmaddr);
+      meta->SHMInfo.shmaddr = (void *) -1;
+    }
+    if (meta->ximage)
+      XDestroyImage (meta->ximage);
+  } else
+#endif /* HAVE_XSHM */
+  {
+    if (meta->ximage) {
+      XDestroyImage (meta->ximage);
+    }
+  }
+
+  XSync (ximagesink->xcontext->disp, FALSE);
+
+  g_mutex_unlock (ximagesink->x_lock);
+
+beach:
+  GST_OBJECT_UNLOCK (ximagesink);
+
+  gst_object_unref (meta->sink);
+}
+
+GstBuffer *
+gst_ximage_buffer_new (GstXImageSink * ximagesink, gint width, gint height)
+{
+  GstBuffer *buffer;
+  GstMetaXImage *meta;
+
+  buffer = gst_buffer_new ();
+  meta = gst_buffer_add_meta_ximage (buffer, ximagesink, width, height);
+  if (meta == NULL) {
+    gst_buffer_unref (buffer);
+    buffer = NULL;
+  }
+  return buffer;
+}
+
+#ifdef HAVE_XSHM
+/* This function checks that it is actually really possible to create an image
+   using XShm */
+gboolean
+gst_ximagesink_check_xshm_calls (GstXImageSink * ximagesink,
+    GstXContext * xcontext)
+{
+  XImage *ximage;
+  XShmSegmentInfo SHMInfo;
+  size_t size;
+  int (*handler) (Display *, XErrorEvent *);
+  gboolean result = FALSE;
+  gboolean did_attach = FALSE;
+
+  g_return_val_if_fail (xcontext != NULL, FALSE);
+
+  /* Sync to ensure any older errors are already processed */
+  XSync (xcontext->disp, FALSE);
+
+  /* Set defaults so we don't free these later unnecessarily */
+  SHMInfo.shmaddr = ((void *) -1);
+  SHMInfo.shmid = -1;
+
+  /* Setting an error handler to catch failure */
+  error_caught = FALSE;
+  handler = XSetErrorHandler (gst_ximagesink_handle_xerror);
+
+  /* Trying to create a 1x1 ximage */
+  GST_DEBUG ("XShmCreateImage of 1x1");
+
+  ximage = XShmCreateImage (xcontext->disp, xcontext->visual,
+      xcontext->depth, ZPixmap, NULL, &SHMInfo, 1, 1);
+
+  /* Might cause an error, sync to ensure it is noticed */
+  XSync (xcontext->disp, FALSE);
+  if (!ximage || error_caught) {
+    GST_WARNING ("could not XShmCreateImage a 1x1 image");
+    goto beach;
+  }
+  size = ximage->height * ximage->bytes_per_line;
+
+  SHMInfo.shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777);
+  if (SHMInfo.shmid == -1) {
+    GST_WARNING ("could not get shared memory of %" G_GSIZE_FORMAT " bytes",
+        size);
+    goto beach;
+  }
+
+  SHMInfo.shmaddr = shmat (SHMInfo.shmid, NULL, 0);
+  if (SHMInfo.shmaddr == ((void *) -1)) {
+    GST_WARNING ("Failed to shmat: %s", g_strerror (errno));
+    /* Clean up the shared memory segment */
+    shmctl (SHMInfo.shmid, IPC_RMID, NULL);
+    goto beach;
+  }
+
+  ximage->data = SHMInfo.shmaddr;
+  SHMInfo.readOnly = FALSE;
+
+  if (XShmAttach (xcontext->disp, &SHMInfo) == 0) {
+    GST_WARNING ("Failed to XShmAttach");
+    /* Clean up the shared memory segment */
+    shmctl (SHMInfo.shmid, IPC_RMID, NULL);
+    goto beach;
+  }
+
+  /* Sync to ensure we see any errors we caused */
+  XSync (xcontext->disp, FALSE);
+
+  /* Delete the shared memory segment as soon as everyone is attached.
+   * This way, it will be deleted as soon as we detach later, and not
+   * leaked if we crash. */
+  shmctl (SHMInfo.shmid, IPC_RMID, NULL);
+
+  if (!error_caught) {
+    GST_DEBUG ("XServer ShmAttached to 0x%x, id 0x%lx", SHMInfo.shmid,
+        SHMInfo.shmseg);
+
+    did_attach = TRUE;
+    /* store whether we succeeded in result */
+    result = TRUE;
+  } else {
+    GST_WARNING ("MIT-SHM extension check failed at XShmAttach. "
+        "Not using shared memory.");
+  }
+
+beach:
+  /* Sync to ensure we swallow any errors we caused and reset error_caught */
+  XSync (xcontext->disp, FALSE);
+
+  error_caught = FALSE;
+  XSetErrorHandler (handler);
+
+  if (did_attach) {
+    GST_DEBUG ("XServer ShmDetaching from 0x%x id 0x%lx",
+        SHMInfo.shmid, SHMInfo.shmseg);
+    XShmDetach (xcontext->disp, &SHMInfo);
+    XSync (xcontext->disp, FALSE);
+  }
+  if (SHMInfo.shmaddr != ((void *) -1))
+    shmdt (SHMInfo.shmaddr);
+  if (ximage)
+    XDestroyImage (ximage);
+  return result;
+}
+#endif /* HAVE_XSHM */
+
+/* bufferpool */
+static void gst_ximage_buffer_pool_finalize (GObject * object);
+
+#define GST_XIMAGE_BUFFER_POOL_GET_PRIVATE(obj)  \
+   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_XIMAGE_BUFFER_POOL, GstXImageBufferPoolPrivate))
+
+struct _GstXImageBufferPoolPrivate
+{
+  GstCaps *caps;
+  gint width, height;
+};
+
+G_DEFINE_TYPE (GstXImageBufferPool, gst_ximage_buffer_pool,
+    GST_TYPE_BUFFER_POOL);
+
+static gboolean
+ximage_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
+{
+  GstXImageBufferPool *xpool = GST_XIMAGE_BUFFER_POOL_CAST (pool);
+  GstXImageBufferPoolPrivate *priv = xpool->priv;
+  GstStructure *structure;
+  gint width, height;
+  const GstCaps *caps;
+
+  if (!gst_buffer_pool_config_get (config, &caps, NULL, NULL, NULL, NULL,
+          NULL, NULL))
+    goto wrong_config;
+
+  if (caps == NULL)
+    goto no_caps;
+
+  /* now parse the caps from the config */
+  structure = gst_caps_get_structure (caps, 0);
+
+  if (!gst_structure_get_int (structure, "width", &width) ||
+      !gst_structure_get_int (structure, "height", &height))
+    goto wrong_caps;
+
+  GST_LOG_OBJECT (pool, "%dx%d, caps %" GST_PTR_FORMAT, width, height, caps);
+
+  /* keep track of the width and height and caps */
+  if (priv->caps)
+    gst_caps_unref (priv->caps);
+  priv->caps = gst_caps_copy (caps);
+  priv->width = width;
+  priv->height = height;
+
+  return TRUE;
+
+  /* ERRORS */
+wrong_config:
+  {
+    GST_WARNING_OBJECT (pool, "invalid config");
+    return FALSE;
+  }
+no_caps:
+  {
+    GST_WARNING_OBJECT (pool, "no caps in config");
+    return FALSE;
+  }
+wrong_caps:
+  {
+    GST_WARNING_OBJECT (pool,
+        "failed getting geometry from caps %" GST_PTR_FORMAT, caps);
+    return FALSE;
+  }
+}
+
+/* This function handles GstXImageBuffer creation depending on XShm availability */
+static GstFlowReturn
+ximage_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
+    GstBufferPoolParams * params)
+{
+  GstXImageBufferPool *xpool = GST_XIMAGE_BUFFER_POOL_CAST (pool);
+  GstXImageBufferPoolPrivate *priv = xpool->priv;
+  GstBuffer *ximage;
+
+  ximage = gst_ximage_buffer_new (xpool->sink, priv->width, priv->height);
+  if (ximage == NULL)
+    goto no_buffer;
+
+  *buffer = ximage;
+
+  return GST_FLOW_OK;
+
+  /* ERROR */
+no_buffer:
+  {
+    GST_WARNING_OBJECT (pool, "can't create image");
+    return GST_FLOW_ERROR;
+  }
+}
+
+static void
+ximage_buffer_pool_free (GstBufferPool * pool, GstBuffer * buffer)
+{
+  gst_buffer_unref (buffer);
+}
+
+GstBufferPool *
+gst_ximage_buffer_pool_new (GstXImageSink * ximagesink)
+{
+  GstXImageBufferPool *pool;
+
+  g_return_val_if_fail (GST_IS_XIMAGESINK (ximagesink), NULL);
+
+  pool = g_object_new (GST_TYPE_XIMAGE_BUFFER_POOL, NULL);
+  pool->sink = gst_object_ref (ximagesink);
+
+  GST_LOG_OBJECT (pool, "new XImage buffer pool %p", pool);
+
+  return GST_BUFFER_POOL_CAST (pool);
+}
+
+static void
+gst_ximage_buffer_pool_class_init (GstXImageBufferPoolClass * klass)
+{
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass;
+
+  g_type_class_add_private (klass, sizeof (GstXImageBufferPoolPrivate));
+
+  gobject_class->finalize = gst_ximage_buffer_pool_finalize;
+
+  gstbufferpool_class->set_config = ximage_buffer_pool_set_config;
+  gstbufferpool_class->alloc_buffer = ximage_buffer_pool_alloc;
+  gstbufferpool_class->free_buffer = ximage_buffer_pool_free;
+}
+
+static void
+gst_ximage_buffer_pool_init (GstXImageBufferPool * pool)
+{
+  pool->priv = GST_XIMAGE_BUFFER_POOL_GET_PRIVATE (pool);
+}
+
+static void
+gst_ximage_buffer_pool_finalize (GObject * object)
+{
+  GstXImageBufferPool *pool = GST_XIMAGE_BUFFER_POOL_CAST (object);
+  GstXImageBufferPoolPrivate *priv = pool->priv;
+
+  GST_LOG_OBJECT (pool, "finalize XImage buffer pool %p", pool);
+
+  if (priv->caps)
+    gst_caps_unref (priv->caps);
+  gst_object_unref (pool->sink);
+
+  G_OBJECT_CLASS (gst_ximage_buffer_pool_parent_class)->finalize (object);
+}
diff --git a/sys/ximage/ximagepool.h b/sys/ximage/ximagepool.h
new file mode 100644 (file)
index 0000000..7f12bdc
--- /dev/null
@@ -0,0 +1,115 @@
+/* GStreamer
+ * Copyright (C) <2005> Julien Moutte <julien@moutte.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_XIMAGEPOOL_H__
+#define __GST_XIMAGEPOOL_H__
+
+#ifdef HAVE_XSHM
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif /* HAVE_XSHM */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#ifdef HAVE_XSHM
+#include <X11/extensions/XShm.h>
+#endif /* HAVE_XSHM */
+
+#include <string.h>
+#include <math.h>
+
+
+G_BEGIN_DECLS
+
+typedef struct _GstMetaXImage GstMetaXImage;
+
+typedef struct _GstXImageBufferPool GstXImageBufferPool;
+typedef struct _GstXImageBufferPoolClass GstXImageBufferPoolClass;
+typedef struct _GstXImageBufferPoolPrivate GstXImageBufferPoolPrivate;
+
+#include "ximagesink.h"
+
+const GstMetaInfo * gst_meta_ximage_get_info (void);
+#define GST_META_INFO_XIMAGE  (gst_meta_ximage_get_info())
+
+#define gst_buffer_get_meta_ximage(b) ((GstMetaXImage*)gst_buffer_get_meta((b),GST_META_INFO_XIMAGE))
+GstMetaXImage * gst_buffer_add_meta_ximage   (GstBuffer *buffer, GstXImageSink * ximagesink,
+                                              gint width, gint height);
+
+/**
+ * GstMetaXImage:
+ * @simagesink: a reference to the our #GstXImageSink
+ * @ximage: the XImage of this buffer
+ * @width: the width in pixels of XImage @ximage
+ * @height: the height in pixels of XImage @ximage
+ * @size: the size in bytes of XImage @ximage
+ *
+ * Subclass of #GstMeta containing additional information about an XImage.
+ */
+struct _GstMetaXImage
+{
+  GstMeta meta;
+
+  /* Reference to the ximagesink we belong to */
+  GstXImageSink *sink;
+
+  XImage *ximage;
+
+#ifdef HAVE_XSHM
+  XShmSegmentInfo SHMInfo;
+#endif                          /* HAVE_XSHM */
+
+  gint width, height;
+  size_t size;
+};
+
+GstBuffer *   gst_ximage_buffer_new    (GstXImageSink *ximagesink, gint width, gint height);
+
+/* buffer pool functions */
+#define GST_TYPE_XIMAGE_BUFFER_POOL      (gst_ximage_buffer_pool_get_type())
+#define GST_IS_XIMAGE_BUFFER_POOL(obj)   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_XIMAGE_BUFFER_POOL))
+#define GST_XIMAGE_BUFFER_POOL(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_XIMAGE_BUFFER_POOL, GstXImageBufferPool))
+#define GST_XIMAGE_BUFFER_POOL_CAST(obj) ((GstXImageBufferPool*)(obj))
+
+struct _GstXImageBufferPool
+{
+  GstBufferPool bufferpool;
+
+  GstXImageSink *sink;
+
+  GstXImageBufferPoolPrivate *priv;
+};
+
+struct _GstXImageBufferPoolClass
+{
+  GstBufferPoolClass parent_class;
+};
+
+GType gst_ximage_buffer_pool_get_type (void);
+
+GstBufferPool * gst_ximage_buffer_pool_new     (GstXImageSink * ximagesink);
+
+gboolean gst_ximagesink_check_xshm_calls (GstXImageSink * ximagesink,
+        GstXContext * xcontext);
+
+G_END_DECLS
+
+#endif /* __GST_XIMAGEPOOL_H__ */
index 99ad35b..1ef50ee 100644 (file)
 #include <gst/interfaces/navigation.h>
 #include <gst/interfaces/xoverlay.h>
 
+#include <gst/video/gstmetavideo.h>
+
 /* Object header */
 #include "ximagesink.h"
 
@@ -129,8 +131,6 @@ MotifWmHints, MwmHints;
 #define MWM_HINTS_DECORATIONS   (1L << 1)
 
 static void gst_ximagesink_reset (GstXImageSink * ximagesink);
-static void gst_ximagesink_ximage_destroy (GstXImageSink * ximagesink,
-    GstXImageBuffer * ximage);
 static void gst_ximagesink_xwindow_update_geometry (GstXImageSink * ximagesink);
 static void gst_ximagesink_expose (GstXOverlay * overlay);
 
@@ -156,481 +156,35 @@ enum
   PROP_WINDOW_HEIGHT
 };
 
-static GstVideoSinkClass *parent_class = NULL;
-
 /* ============================================================= */
 /*                                                               */
-/*                       Private Methods                         */
+/*                       Public Methods                          */
 /*                                                               */
 /* ============================================================= */
 
-/* ximage buffers */
-
-static GstBufferClass *ximage_buffer_parent_class = NULL;
-
-#define GST_TYPE_XIMAGE_BUFFER (gst_ximage_buffer_get_type())
-
-#define GST_IS_XIMAGE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_XIMAGE_BUFFER))
-#define GST_XIMAGE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_XIMAGE_BUFFER, GstXImageBuffer))
-#define GST_XIMAGE_BUFFER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_XIMAGE_BUFFER, GstXImageBufferClass))
-
-/* So some words about GstMiniObject, this is pretty messy...
-   GstMiniObject does not use the standard finalizing of GObjects, you are 
-   supposed to call gst_buffer_unref that's going to call gst_mini_objec_unref
-   which will handle its own refcount system and call gst_mini_object_free.
-   gst_mini_object_free will call the class finalize method which is not the 
-   one from GObject, after calling this finalize method it will free the object
-   instance for you if the refcount is still 0 so you should not chain up */
-static void
-gst_ximage_buffer_finalize (GstXImageBuffer * ximage)
-{
-  GstXImageSink *ximagesink = NULL;
-  gboolean recycled = FALSE;
-  gboolean running;
-
-  g_return_if_fail (ximage != NULL);
-
-  ximagesink = ximage->ximagesink;
-  if (G_UNLIKELY (ximagesink == NULL)) {
-    GST_WARNING_OBJECT (ximagesink, "no sink found");
-    goto beach;
-  }
-
-  GST_OBJECT_LOCK (ximagesink);
-  running = ximagesink->running;
-  GST_OBJECT_UNLOCK (ximagesink);
-
-  if (running == FALSE) {
-    /* If the sink is shutting down, need to clear the image */
-    GST_DEBUG_OBJECT (ximagesink,
-        "destroy image %p because the sink is shutting down", ximage);
-    gst_ximagesink_ximage_destroy (ximagesink, ximage);
-  } else if ((ximage->width != GST_VIDEO_SINK_WIDTH (ximagesink)) ||
-      (ximage->height != GST_VIDEO_SINK_HEIGHT (ximagesink))) {
-    /* If our geometry changed we can't reuse that image. */
-    GST_DEBUG_OBJECT (ximagesink,
-        "destroy image %p as its size changed %dx%d vs current %dx%d",
-        ximage, ximage->width, ximage->height,
-        GST_VIDEO_SINK_WIDTH (ximagesink), GST_VIDEO_SINK_HEIGHT (ximagesink));
-    gst_ximagesink_ximage_destroy (ximagesink, ximage);
-  } else {
-    /* In that case we can reuse the image and add it to our image pool. */
-    GST_LOG_OBJECT (ximagesink, "recycling image %p in pool", ximage);
-    /* need to increment the refcount again to recycle */
-    gst_buffer_ref (GST_BUFFER_CAST (ximage));
-    g_mutex_lock (ximagesink->pool_lock);
-    ximagesink->buffer_pool = g_slist_prepend (ximagesink->buffer_pool, ximage);
-    g_mutex_unlock (ximagesink->pool_lock);
-    recycled = TRUE;
-  }
-
-  if (!recycled)
-    GST_MINI_OBJECT_CLASS (ximage_buffer_parent_class)->finalize
-        (GST_MINI_OBJECT (ximage));
-
-beach:
-  return;
-}
-
-static void
-gst_ximage_buffer_free (GstXImageBuffer * ximage)
-{
-  /* make sure it is not recycled */
-  ximage->width = -1;
-  ximage->height = -1;
-  gst_buffer_unref (GST_BUFFER_CAST (ximage));
-}
-
-static void
-gst_ximage_buffer_init (GstXImageBuffer * ximage_buffer, gpointer g_class)
-{
-#ifdef HAVE_XSHM
-  ximage_buffer->SHMInfo.shmaddr = ((void *) -1);
-  ximage_buffer->SHMInfo.shmid = -1;
-#endif
-}
-
-static void
-gst_ximage_buffer_class_init (gpointer g_class, gpointer class_data)
-{
-  GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
-
-  ximage_buffer_parent_class = g_type_class_peek_parent (g_class);
-
-  mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
-      gst_ximage_buffer_finalize;
-}
+/* =========================================== */
+/*                                             */
+/*          Object typing & Creation           */
+/*                                             */
+/* =========================================== */
+static void gst_ximagesink_interface_init (GstImplementsInterfaceClass * klass);
+static void gst_ximagesink_navigation_init (GstNavigationInterface * klass);
+static void gst_ximagesink_xoverlay_init (GstXOverlayClass * klass);
+#define gst_ximagesink_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstXImageSink, gst_ximagesink, GST_TYPE_VIDEO_SINK,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_IMPLEMENTS_INTERFACE,
+        gst_ximagesink_interface_init);
+    G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION, gst_ximagesink_navigation_init);
+    G_IMPLEMENT_INTERFACE (GST_TYPE_X_OVERLAY, gst_ximagesink_xoverlay_init));
 
-static GType
-gst_ximage_buffer_get_type (void)
-{
-  static GType _gst_ximage_buffer_type;
-
-  if (G_UNLIKELY (_gst_ximage_buffer_type == 0)) {
-    static const GTypeInfo ximage_buffer_info = {
-      sizeof (GstBufferClass),
-      NULL,
-      NULL,
-      gst_ximage_buffer_class_init,
-      NULL,
-      NULL,
-      sizeof (GstXImageBuffer),
-      0,
-      (GInstanceInitFunc) gst_ximage_buffer_init,
-      NULL
-    };
-    _gst_ximage_buffer_type = g_type_register_static (GST_TYPE_BUFFER,
-        "GstXImageBuffer", &ximage_buffer_info, 0);
-  }
-  return _gst_ximage_buffer_type;
-}
+/* ============================================================= */
+/*                                                               */
+/*                       Private Methods                         */
+/*                                                               */
+/* ============================================================= */
 
 /* X11 stuff */
 
-static gboolean error_caught = FALSE;
-
-static int
-gst_ximagesink_handle_xerror (Display * display, XErrorEvent * xevent)
-{
-  char error_msg[1024];
-
-  XGetErrorText (display, xevent->error_code, error_msg, 1024);
-  GST_DEBUG ("ximagesink triggered an XError. error: %s", error_msg);
-  error_caught = TRUE;
-  return 0;
-}
-
-#ifdef HAVE_XSHM                /* Check that XShm calls actually work */
-
-static gboolean
-gst_ximagesink_check_xshm_calls (GstXImageSink * ximagesink,
-    GstXContext * xcontext)
-{
-  XImage *ximage;
-  XShmSegmentInfo SHMInfo;
-  size_t size;
-  int (*handler) (Display *, XErrorEvent *);
-  gboolean result = FALSE;
-  gboolean did_attach = FALSE;
-
-  g_return_val_if_fail (xcontext != NULL, FALSE);
-
-  /* Sync to ensure any older errors are already processed */
-  XSync (xcontext->disp, FALSE);
-
-  /* Set defaults so we don't free these later unnecessarily */
-  SHMInfo.shmaddr = ((void *) -1);
-  SHMInfo.shmid = -1;
-
-  /* Setting an error handler to catch failure */
-  error_caught = FALSE;
-  handler = XSetErrorHandler (gst_ximagesink_handle_xerror);
-
-  /* Trying to create a 1x1 ximage */
-  GST_DEBUG ("XShmCreateImage of 1x1");
-
-  ximage = XShmCreateImage (xcontext->disp, xcontext->visual,
-      xcontext->depth, ZPixmap, NULL, &SHMInfo, 1, 1);
-
-  /* Might cause an error, sync to ensure it is noticed */
-  XSync (xcontext->disp, FALSE);
-  if (!ximage || error_caught) {
-    GST_WARNING ("could not XShmCreateImage a 1x1 image");
-    goto beach;
-  }
-  size = ximage->height * ximage->bytes_per_line;
-
-  SHMInfo.shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777);
-  if (SHMInfo.shmid == -1) {
-    GST_WARNING ("could not get shared memory of %" G_GSIZE_FORMAT " bytes",
-        size);
-    goto beach;
-  }
-
-  SHMInfo.shmaddr = shmat (SHMInfo.shmid, NULL, 0);
-  if (SHMInfo.shmaddr == ((void *) -1)) {
-    GST_WARNING ("Failed to shmat: %s", g_strerror (errno));
-    /* Clean up shm seg */
-    shmctl (SHMInfo.shmid, IPC_RMID, NULL);
-    goto beach;
-  }
-
-  ximage->data = SHMInfo.shmaddr;
-  SHMInfo.readOnly = FALSE;
-
-  if (XShmAttach (xcontext->disp, &SHMInfo) == 0) {
-    GST_WARNING ("Failed to XShmAttach");
-    /* Clean up shm seg */
-    shmctl (SHMInfo.shmid, IPC_RMID, NULL);
-    goto beach;
-  }
-
-  /* Sync to ensure we see any errors we caused */
-  XSync (xcontext->disp, FALSE);
-
-  /* Delete the shared memory segment as soon as everyone is attached. 
-   * This way, it will be deleted as soon as we detach later, and not
-   * leaked if we crash. */
-  shmctl (SHMInfo.shmid, IPC_RMID, NULL);
-
-  if (!error_caught) {
-    did_attach = TRUE;
-    /* store whether we succeeded in result */
-    result = TRUE;
-  }
-
-beach:
-  /* Sync to ensure we swallow any errors we caused and reset error_caught */
-  XSync (xcontext->disp, FALSE);
-  error_caught = FALSE;
-  XSetErrorHandler (handler);
-
-  if (did_attach) {
-    XShmDetach (xcontext->disp, &SHMInfo);
-    XSync (xcontext->disp, FALSE);
-  }
-  if (SHMInfo.shmaddr != ((void *) -1))
-    shmdt (SHMInfo.shmaddr);
-  if (ximage)
-    XDestroyImage (ximage);
-  return result;
-}
-#endif /* HAVE_XSHM */
-
-/* This function handles GstXImageBuffer creation depending on XShm availability */
-static GstXImageBuffer *
-gst_ximagesink_ximage_new (GstXImageSink * ximagesink, GstCaps * caps)
-{
-  GstXImageBuffer *ximage = NULL;
-  GstStructure *structure = NULL;
-  gboolean succeeded = FALSE;
-  int (*handler) (Display *, XErrorEvent *);
-
-  g_return_val_if_fail (GST_IS_XIMAGESINK (ximagesink), NULL);
-
-  ximage = (GstXImageBuffer *) gst_mini_object_new (GST_TYPE_XIMAGE_BUFFER);
-
-  structure = gst_caps_get_structure (caps, 0);
-
-  if (!gst_structure_get_int (structure, "width", &ximage->width) ||
-      !gst_structure_get_int (structure, "height", &ximage->height)) {
-    GST_WARNING ("failed getting geometry from caps %" GST_PTR_FORMAT, caps);
-  }
-
-  GST_DEBUG_OBJECT (ximagesink, "creating image %p (%dx%d)", ximage,
-      ximage->width, ximage->height);
-
-  g_mutex_lock (ximagesink->x_lock);
-
-  /* Setting an error handler to catch failure */
-  error_caught = FALSE;
-  handler = XSetErrorHandler (gst_ximagesink_handle_xerror);
-
-#ifdef HAVE_XSHM
-  if (ximagesink->xcontext->use_xshm) {
-    ximage->ximage = XShmCreateImage (ximagesink->xcontext->disp,
-        ximagesink->xcontext->visual,
-        ximagesink->xcontext->depth,
-        ZPixmap, NULL, &ximage->SHMInfo, ximage->width, ximage->height);
-    if (!ximage->ximage || error_caught) {
-      g_mutex_unlock (ximagesink->x_lock);
-      /* Reset error handler */
-      error_caught = FALSE;
-      XSetErrorHandler (handler);
-      /* Push an error */
-      GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
-          ("Failed to create output image buffer of %dx%d pixels",
-              ximage->width, ximage->height),
-          ("could not XShmCreateImage a %dx%d image",
-              ximage->width, ximage->height));
-      goto beach;
-    }
-
-    /* we have to use the returned bytes_per_line for our shm size */
-    ximage->size = ximage->ximage->bytes_per_line * ximage->ximage->height;
-    GST_LOG_OBJECT (ximagesink,
-        "XShm image size is %" G_GSIZE_FORMAT ", width %d, stride %d",
-        ximage->size, ximage->width, ximage->ximage->bytes_per_line);
-
-    ximage->SHMInfo.shmid = shmget (IPC_PRIVATE, ximage->size,
-        IPC_CREAT | 0777);
-    if (ximage->SHMInfo.shmid == -1) {
-      g_mutex_unlock (ximagesink->x_lock);
-      GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
-          ("Failed to create output image buffer of %dx%d pixels",
-              ximage->width, ximage->height),
-          ("could not get shared memory of %" G_GSIZE_FORMAT " bytes",
-              ximage->size));
-      goto beach;
-    }
-
-    ximage->SHMInfo.shmaddr = shmat (ximage->SHMInfo.shmid, NULL, 0);
-    if (ximage->SHMInfo.shmaddr == ((void *) -1)) {
-      g_mutex_unlock (ximagesink->x_lock);
-      GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
-          ("Failed to create output image buffer of %dx%d pixels",
-              ximage->width, ximage->height),
-          ("Failed to shmat: %s", g_strerror (errno)));
-      /* Clean up the shared memory segment */
-      shmctl (ximage->SHMInfo.shmid, IPC_RMID, NULL);
-      goto beach;
-    }
-
-    ximage->ximage->data = ximage->SHMInfo.shmaddr;
-    ximage->SHMInfo.readOnly = FALSE;
-
-    if (XShmAttach (ximagesink->xcontext->disp, &ximage->SHMInfo) == 0) {
-      /* Clean up shm seg */
-      shmctl (ximage->SHMInfo.shmid, IPC_RMID, NULL);
-
-      g_mutex_unlock (ximagesink->x_lock);
-      GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
-          ("Failed to create output image buffer of %dx%d pixels",
-              ximage->width, ximage->height), ("Failed to XShmAttach"));
-      goto beach;
-    }
-
-    XSync (ximagesink->xcontext->disp, FALSE);
-
-    /* Now that everyone has attached, we can delete the shared memory segment.
-     * This way, it will be deleted as soon as we detach later, and not
-     * leaked if we crash. */
-    shmctl (ximage->SHMInfo.shmid, IPC_RMID, NULL);
-
-  } else
-#endif /* HAVE_XSHM */
-  {
-    guint allocsize;
-
-    ximage->ximage = XCreateImage (ximagesink->xcontext->disp,
-        ximagesink->xcontext->visual,
-        ximagesink->xcontext->depth,
-        ZPixmap, 0, NULL,
-        ximage->width, ximage->height, ximagesink->xcontext->bpp, 0);
-    if (!ximage->ximage || error_caught) {
-      g_mutex_unlock (ximagesink->x_lock);
-      /* Reset error handler */
-      error_caught = FALSE;
-      XSetErrorHandler (handler);
-      /* Push an error */
-      GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
-          ("Failed to create output image buffer of %dx%d pixels",
-              ximage->width, ximage->height),
-          ("could not XCreateImage a %dx%d image",
-              ximage->width, ximage->height));
-      goto beach;
-    }
-
-    /* upstream will assume that rowstrides are multiples of 4, but this
-     * doesn't always seem to be the case with XCreateImage() */
-    if ((ximage->ximage->bytes_per_line % 4) != 0) {
-      GST_WARNING_OBJECT (ximagesink, "returned stride not a multiple of 4 as "
-          "usually assumed");
-    }
-
-    /* we have to use the returned bytes_per_line for our image size */
-    ximage->size = ximage->ximage->bytes_per_line * ximage->ximage->height;
-
-    /* alloc a bit more for unexpected strides to avoid crashes upstream.
-     * FIXME: if we get an unrounded stride, the image will be displayed
-     * distorted, since all upstream elements assume a rounded stride */
-    allocsize =
-        GST_ROUND_UP_4 (ximage->ximage->bytes_per_line) *
-        ximage->ximage->height;
-    ximage->ximage->data = g_malloc (allocsize);
-    GST_LOG_OBJECT (ximagesink,
-        "non-XShm image size is %" G_GSIZE_FORMAT " (alloced: %u), width %d, "
-        "stride %d", ximage->size, allocsize, ximage->width,
-        ximage->ximage->bytes_per_line);
-
-    XSync (ximagesink->xcontext->disp, FALSE);
-  }
-
-  /* Reset error handler */
-  error_caught = FALSE;
-  XSetErrorHandler (handler);
-
-  succeeded = TRUE;
-
-  GST_BUFFER_DATA (ximage) = (guchar *) ximage->ximage->data;
-  GST_BUFFER_SIZE (ximage) = ximage->size;
-
-  /* Keep a ref to our sink */
-  ximage->ximagesink = gst_object_ref (ximagesink);
-
-  g_mutex_unlock (ximagesink->x_lock);
-beach:
-  if (!succeeded) {
-    gst_ximage_buffer_free (ximage);
-    ximage = NULL;
-  }
-
-  return ximage;
-}
-
-/* This function destroys a GstXImageBuffer handling XShm availability */
-static void
-gst_ximagesink_ximage_destroy (GstXImageSink * ximagesink,
-    GstXImageBuffer * ximage)
-{
-  g_return_if_fail (ximage != NULL);
-  g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
-
-  /* Hold the object lock to ensure the XContext doesn't disappear */
-  GST_OBJECT_LOCK (ximagesink);
-
-  /* If the destroyed image is the current one we destroy our reference too */
-  if (ximagesink->cur_image == ximage) {
-    ximagesink->cur_image = NULL;
-  }
-
-  /* We might have some buffers destroyed after changing state to NULL */
-  if (!ximagesink->xcontext) {
-    GST_DEBUG_OBJECT (ximagesink, "Destroying XImage after XContext");
-#ifdef HAVE_XSHM
-    if (ximage->SHMInfo.shmaddr != ((void *) -1)) {
-      shmdt (ximage->SHMInfo.shmaddr);
-    }
-#endif
-    goto beach;
-  }
-
-  g_mutex_lock (ximagesink->x_lock);
-
-#ifdef HAVE_XSHM
-  if (ximagesink->xcontext->use_xshm) {
-    if (ximage->SHMInfo.shmaddr != ((void *) -1)) {
-      XShmDetach (ximagesink->xcontext->disp, &ximage->SHMInfo);
-      XSync (ximagesink->xcontext->disp, 0);
-      shmdt (ximage->SHMInfo.shmaddr);
-    }
-    if (ximage->ximage)
-      XDestroyImage (ximage->ximage);
-
-  } else
-#endif /* HAVE_XSHM */
-  {
-    if (ximage->ximage) {
-      XDestroyImage (ximage->ximage);
-    }
-  }
-
-  XSync (ximagesink->xcontext->disp, FALSE);
-
-  g_mutex_unlock (ximagesink->x_lock);
-
-beach:
-  GST_OBJECT_UNLOCK (ximagesink);
-
-  if (ximage->ximagesink) {
-    /* Release the ref to our sink */
-    ximage->ximagesink = NULL;
-    gst_object_unref (ximagesink);
-  }
-
-  return;
-}
-
 /* We are called with the x_lock taken */
 static void
 gst_ximagesink_xwindow_draw_borders (GstXImageSink * ximagesink,
@@ -669,13 +223,12 @@ gst_ximagesink_xwindow_draw_borders (GstXImageSink * ximagesink,
 
 /* This function puts a GstXImageBuffer on a GstXImageSink's window */
 static gboolean
-gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstXImageBuffer * ximage)
+gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
 {
+  GstMetaXImage *meta;
   GstVideoRectangle src, dst, result;
   gboolean draw_border = FALSE;
 
-  g_return_val_if_fail (GST_IS_XIMAGESINK (ximagesink), FALSE);
-
   /* We take the flow_lock. If expose is in there we don't want to run
      concurrently from the data flow thread */
   g_mutex_lock (ximagesink->flow_lock);
@@ -695,11 +248,10 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstXImageBuffer * ximage)
   if (ximage && ximagesink->cur_image != ximage) {
     if (ximagesink->cur_image) {
       GST_LOG_OBJECT (ximagesink, "unreffing %p", ximagesink->cur_image);
-      gst_buffer_unref (GST_BUFFER_CAST (ximagesink->cur_image));
+      gst_buffer_unref (ximagesink->cur_image);
     }
     GST_LOG_OBJECT (ximagesink, "reffing %p as our current image", ximage);
-    ximagesink->cur_image =
-        GST_XIMAGE_BUFFER (gst_buffer_ref (GST_BUFFER_CAST (ximage)));
+    ximagesink->cur_image = gst_buffer_ref (ximage);
   }
 
   /* Expose sends a NULL image, we take the latest frame */
@@ -713,8 +265,10 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstXImageBuffer * ximage)
     }
   }
 
-  src.w = ximage->width;
-  src.h = ximage->height;
+  meta = gst_buffer_get_meta_ximage (ximage);
+
+  src.w = meta->width;
+  src.h = meta->height;
   dst.w = ximagesink->xwindow->width;
   dst.h = ximagesink->xwindow->height;
 
@@ -734,7 +288,7 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstXImageBuffer * ximage)
         ximage, 0, 0, result.x, result.y, result.w, result.h,
         ximagesink->xwindow->width, ximagesink->xwindow->height);
     XShmPutImage (ximagesink->xcontext->disp, ximagesink->xwindow->win,
-        ximagesink->xwindow->gc, ximage->ximage, 0, 0, result.x, result.y,
+        ximagesink->xwindow->gc, meta->ximage, 0, 0, result.x, result.y,
         result.w, result.h, FALSE);
   } else
 #endif /* HAVE_XSHM */
@@ -744,7 +298,7 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstXImageBuffer * ximage)
         ximage, 0, 0, result.x, result.y, result.w, result.h,
         ximagesink->xwindow->width, ximagesink->xwindow->height);
     XPutImage (ximagesink->xcontext->disp, ximagesink->xwindow->win,
-        ximagesink->xwindow->gc, ximage->ximage, 0, 0, result.x, result.y,
+        ximagesink->xwindow->gc, meta->ximage, 0, 0, result.x, result.y,
         result.w, result.h);
   }
 
@@ -769,7 +323,8 @@ gst_ximagesink_xwindow_decorate (GstXImageSink * ximagesink,
 
   g_mutex_lock (ximagesink->x_lock);
 
-  hints_atom = XInternAtom (ximagesink->xcontext->disp, "_MOTIF_WM_HINTS", 1);
+  hints_atom = XInternAtom (ximagesink->xcontext->disp, "_MOTIF_WM_HINTS",
+      True);
   if (hints_atom == None) {
     g_mutex_unlock (ximagesink->x_lock);
     return FALSE;
@@ -853,7 +408,7 @@ gst_ximagesink_xwindow_new (GstXImageSink * ximagesink, gint width, gint height)
 
   xwindow->win = XCreateSimpleWindow (ximagesink->xcontext->disp,
       ximagesink->xcontext->root,
-      0, 0, xwindow->width, xwindow->height, 0, 0, ximagesink->xcontext->black);
+      0, 0, width, height, 0, 0, ximagesink->xcontext->black);
 
   /* We have to do that to prevent X from redrawing the background on 
      ConfigureNotify. This takes away flickering of video when resizing. */
@@ -922,6 +477,7 @@ static void
 gst_ximagesink_xwindow_update_geometry (GstXImageSink * ximagesink)
 {
   XWindowAttributes attr;
+  gboolean reconfigure;
 
   g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
 
@@ -935,10 +491,17 @@ gst_ximagesink_xwindow_update_geometry (GstXImageSink * ximagesink)
   XGetWindowAttributes (ximagesink->xcontext->disp,
       ximagesink->xwindow->win, &attr);
 
+  /* Check if we would suggest a different width/height now */
+  reconfigure = (ximagesink->xwindow->width != attr.width)
+      || (ximagesink->xwindow->height != attr.height);
   ximagesink->xwindow->width = attr.width;
   ximagesink->xwindow->height = attr.height;
 
   g_mutex_unlock (ximagesink->x_lock);
+
+  if (reconfigure)
+    gst_pad_push_event (GST_BASE_SINK (ximagesink)->sinkpad,
+        gst_event_new_reconfigure ());
 }
 
 static void
@@ -1052,7 +615,6 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink)
           g_mutex_unlock (ximagesink->x_lock);
           gst_navigation_send_key_event (GST_NAVIGATION (ximagesink),
               e.type == KeyPress ? "key-press" : "key-release", key_str);
-
         } else {
           gst_navigation_send_key_event (GST_NAVIGATION (ximagesink),
               e.type == KeyPress ? "key-press" : "key-release", "unknown");
@@ -1066,6 +628,7 @@ gst_ximagesink_handle_xevents (GstXImageSink * ximagesink)
     g_mutex_lock (ximagesink->x_lock);
   }
 
+  /* Handle Expose */
   while (XCheckWindowEvent (ximagesink->xcontext->disp,
           ximagesink->xwindow->win, ExposureMask | StructureNotifyMask, &e)) {
     switch (e.type) {
@@ -1296,7 +859,7 @@ gst_ximagesink_xcontext_get (GstXImageSink * ximagesink)
     g_mutex_unlock (ximagesink->x_lock);
     g_free (xcontext->par);
     g_free (xcontext);
-    GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
+    GST_ELEMENT_ERROR (ximagesink, RESOURCE, SETTINGS,
         ("Could not get supported pixmap formats"), (NULL));
     return NULL;
   }
@@ -1320,7 +883,7 @@ gst_ximagesink_xcontext_get (GstXImageSink * ximagesink)
     xcontext->use_xshm = TRUE;
     GST_DEBUG ("ximagesink is using XShm extension");
   } else
-#endif
+#endif /* HAVE_XSHM */
   {
     xcontext->use_xshm = FALSE;
     GST_DEBUG ("ximagesink is not using XShm extension");
@@ -1410,27 +973,10 @@ gst_ximagesink_xcontext_clear (GstXImageSink * ximagesink)
   g_free (xcontext);
 }
 
-static void
-gst_ximagesink_bufferpool_clear (GstXImageSink * ximagesink)
-{
-
-  g_mutex_lock (ximagesink->pool_lock);
-
-  while (ximagesink->buffer_pool) {
-    GstXImageBuffer *ximage = ximagesink->buffer_pool->data;
-
-    ximagesink->buffer_pool = g_slist_delete_link (ximagesink->buffer_pool,
-        ximagesink->buffer_pool);
-    gst_ximage_buffer_free (ximage);
-  }
-
-  g_mutex_unlock (ximagesink->pool_lock);
-}
-
 /* Element stuff */
 
 static GstCaps *
-gst_ximagesink_getcaps (GstBaseSink * bsink)
+gst_ximagesink_getcaps (GstBaseSink * bsink, GstCaps * filter)
 {
   GstXImageSink *ximagesink;
   GstCaps *caps;
@@ -1438,17 +984,59 @@ gst_ximagesink_getcaps (GstBaseSink * bsink)
 
   ximagesink = GST_XIMAGESINK (bsink);
 
-  if (ximagesink->xcontext)
-    return gst_caps_ref (ximagesink->xcontext->caps);
+  g_mutex_lock (ximagesink->x_lock);
+  if (ximagesink->xcontext) {
+    GstCaps *caps;
+
+    caps = gst_caps_ref (ximagesink->xcontext->caps);
 
-  /* get a template copy and add the pixel aspect ratio */
-  caps =
-      gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SINK
-          (ximagesink)->sinkpad));
-  for (i = 0; i < gst_caps_get_size (caps); ++i) {
-    GstStructure *structure = gst_caps_get_structure (caps, i);
+    if (filter) {
+      GstCaps *intersection;
 
-    if (ximagesink->par) {
+      intersection =
+          gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+      gst_caps_unref (caps);
+      caps = intersection;
+    }
+
+    if (ximagesink->xwindow && ximagesink->xwindow->width) {
+      GstStructure *s0, *s1;
+
+      caps = gst_caps_make_writable (caps);
+
+      /* There can only be a single structure because the xcontext
+       * caps only have a single structure */
+      s0 = gst_caps_get_structure (caps, 0);
+      s1 = gst_structure_copy (gst_caps_get_structure (caps, 0));
+
+      gst_structure_set (s0, "width", G_TYPE_INT, ximagesink->xwindow->width,
+          "height", G_TYPE_INT, ximagesink->xwindow->height, NULL);
+      gst_caps_append_structure (caps, s1);
+
+      /* This will not change the order but will remove the
+       * fixed width/height caps again if not possible
+       * upstream */
+      if (filter) {
+        GstCaps *intersection;
+
+        intersection =
+            gst_caps_intersect_full (caps, filter, GST_CAPS_INTERSECT_FIRST);
+        gst_caps_unref (caps);
+        caps = intersection;
+      }
+    }
+
+    g_mutex_unlock (ximagesink->x_lock);
+    return caps;
+  }
+  g_mutex_unlock (ximagesink->x_lock);
+
+  /* get a template copy and add the pixel aspect ratio */
+  caps = gst_pad_get_pad_template_caps (GST_BASE_SINK (ximagesink)->sinkpad);
+  if (ximagesink->par) {
+    caps = gst_caps_make_writable (caps);
+    for (i = 0; i < gst_caps_get_size (caps); ++i) {
+      GstStructure *structure = gst_caps_get_structure (caps, i);
       int nom, den;
 
       nom = gst_value_get_fraction_numerator (ximagesink->par);
@@ -1458,6 +1046,15 @@ gst_ximagesink_getcaps (GstBaseSink * bsink)
     }
   }
 
+  if (filter) {
+    GstCaps *intersection;
+
+    intersection =
+        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (caps);
+    caps = intersection;
+  }
+
   return caps;
 }
 
@@ -1465,8 +1062,9 @@ static gboolean
 gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
 {
   GstXImageSink *ximagesink;
-  gboolean ret = TRUE;
   GstStructure *structure;
+  GstBufferPool *newpool, *oldpool;
+  gboolean ret = TRUE;
   const GValue *par;
   gint new_width, new_height;
   const GValue *fps;
@@ -1490,6 +1088,7 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
   ret &= gst_structure_get_int (structure, "height", &new_height);
   fps = gst_structure_get_value (structure, "framerate");
   ret &= (fps != NULL);
+
   if (!ret)
     return FALSE;
 
@@ -1524,11 +1123,8 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
 
   /* Creating our window and our image */
   if (GST_VIDEO_SINK_WIDTH (ximagesink) <= 0 ||
-      GST_VIDEO_SINK_HEIGHT (ximagesink) <= 0) {
-    GST_ELEMENT_ERROR (ximagesink, CORE, NEGOTIATION, (NULL),
-        ("Invalid image size."));
-    return FALSE;
-  }
+      GST_VIDEO_SINK_HEIGHT (ximagesink) <= 0)
+    goto invalid_size;
 
   g_mutex_lock (ximagesink->flow_lock);
   if (!ximagesink->xwindow) {
@@ -1537,18 +1133,28 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
   }
   /* Remember to draw borders for next frame */
   ximagesink->draw_border = TRUE;
-  g_mutex_unlock (ximagesink->flow_lock);
 
-  /* If our ximage has changed we destroy it, next chain iteration will create
-     a new one */
-  if ((ximagesink->ximage) &&
-      ((GST_VIDEO_SINK_WIDTH (ximagesink) != ximagesink->ximage->width) ||
-          (GST_VIDEO_SINK_HEIGHT (ximagesink) != ximagesink->ximage->height))) {
-    GST_DEBUG_OBJECT (ximagesink, "our image is not usable anymore, unref %p",
-        ximagesink->ximage);
-    gst_buffer_unref (GST_BUFFER_CAST (ximagesink->ximage));
-    ximagesink->ximage = NULL;
+  /* create a new pool for the new configuration */
+  newpool = gst_ximage_buffer_pool_new (ximagesink);
+
+  structure = gst_buffer_pool_get_config (newpool);
+  gst_buffer_pool_config_set (structure, caps, 0, 0, 0, 0, 0, 16);
+  if (!gst_buffer_pool_set_config (newpool, structure))
+    goto config_failed;
+
+  if (!gst_buffer_pool_set_active (newpool, TRUE))
+    goto activate_failed;
+
+  oldpool = ximagesink->pool;
+  ximagesink->pool = newpool;
+
+  /* unref the old sink */
+  if (oldpool) {
+    /* deactivate */
+    gst_buffer_pool_set_active (oldpool, FALSE);
+    gst_object_unref (oldpool);
   }
+  g_mutex_unlock (ximagesink->flow_lock);
 
   return TRUE;
 
@@ -1563,20 +1169,38 @@ wrong_aspect:
     GST_INFO_OBJECT (ximagesink, "pixel aspect ratio does not match");
     return FALSE;
   }
+invalid_size:
+  {
+    GST_ELEMENT_ERROR (ximagesink, CORE, NEGOTIATION, (NULL),
+        ("Invalid image size."));
+    return FALSE;
+  }
+config_failed:
+  {
+    GST_ERROR_OBJECT (ximagesink, "failed to set config.");
+    g_mutex_unlock (ximagesink->flow_lock);
+    return FALSE;
+  }
+activate_failed:
+  {
+    GST_ERROR_OBJECT (ximagesink, "failed to activate bufferpool.");
+    g_mutex_unlock (ximagesink->flow_lock);
+    gst_object_unref (newpool);
+    return FALSE;
+  }
 }
 
 static GstStateChangeReturn
 gst_ximagesink_change_state (GstElement * element, GstStateChange transition)
 {
-  GstXImageSink *ximagesink;
   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+  GstXImageSink *ximagesink;
   GstXContext *xcontext = NULL;
 
   ximagesink = GST_XIMAGESINK (element);
 
   switch (transition) {
     case GST_STATE_CHANGE_NULL_TO_READY:
-
       /* Initializing the XContext */
       if (ximagesink->xcontext == NULL) {
         xcontext = gst_ximagesink_xcontext_get (ximagesink);
@@ -1620,6 +1244,10 @@ gst_ximagesink_change_state (GstElement * element, GstStateChange transition)
       ximagesink->fps_d = 1;
       GST_VIDEO_SINK_WIDTH (ximagesink) = 0;
       GST_VIDEO_SINK_HEIGHT (ximagesink) = 0;
+      g_mutex_lock (ximagesink->flow_lock);
+      if (ximagesink->pool)
+        gst_buffer_pool_set_active (ximagesink->pool, FALSE);
+      g_mutex_unlock (ximagesink->flow_lock);
       break;
     case GST_STATE_CHANGE_READY_TO_NULL:
       gst_ximagesink_reset (ximagesink);
@@ -1657,70 +1285,93 @@ gst_ximagesink_get_times (GstBaseSink * bsink, GstBuffer * buf,
 static GstFlowReturn
 gst_ximagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
 {
+  GstFlowReturn res;
   GstXImageSink *ximagesink;
-
-  g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
+  GstMetaXImage *meta;
+  GstBuffer *temp;
+  gboolean unref;
 
   ximagesink = GST_XIMAGESINK (vsink);
 
-  /* This shouldn't really happen because state changes will fail
-   * if the xcontext can't be allocated */
-  if (!ximagesink->xcontext)
-    return GST_FLOW_ERROR;
+  meta = gst_buffer_get_meta_ximage (buf);
 
-  /* If this buffer has been allocated using our buffer management we simply
-     put the ximage which is in the PRIVATE pointer */
-  if (GST_IS_XIMAGE_BUFFER (buf)) {
+  if (meta) {
+    /* If this buffer has been allocated using our buffer management we simply
+       put the ximage which is in the PRIVATE pointer */
     GST_LOG_OBJECT (ximagesink, "buffer from our pool, writing directly");
-    if (!gst_ximagesink_ximage_put (ximagesink, GST_XIMAGE_BUFFER (buf)))
-      goto no_window;
+    res = GST_FLOW_OK;
+    unref = FALSE;
   } else {
+    guint8 *data;
+    gsize size;
+
     /* Else we have to copy the data into our private image, */
     /* if we have one... */
-    GST_LOG_OBJECT (ximagesink, "normal buffer, copying from it");
-    if (!ximagesink->ximage) {
-      GST_DEBUG_OBJECT (ximagesink, "creating our ximage");
-      ximagesink->ximage = gst_ximagesink_ximage_new (ximagesink,
-          GST_BUFFER_CAPS (buf));
-      if (!ximagesink->ximage)
-        /* The create method should have posted an informative error */
-        goto no_ximage;
-
-      if (ximagesink->ximage->size < GST_BUFFER_SIZE (buf)) {
-        GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
-            ("Failed to create output image buffer of %dx%d pixels",
-                ximagesink->ximage->width, ximagesink->ximage->height),
-            ("XServer allocated buffer size did not match input buffer"));
-
-        gst_ximagesink_ximage_destroy (ximagesink, ximagesink->ximage);
-        ximagesink->ximage = NULL;
-        goto no_ximage;
-      }
-    }
-    memcpy (GST_BUFFER_DATA (ximagesink->ximage), GST_BUFFER_DATA (buf),
-        MIN (GST_BUFFER_SIZE (buf), ximagesink->ximage->size));
-    if (!gst_ximagesink_ximage_put (ximagesink, ximagesink->ximage))
-      goto no_window;
+    GST_LOG_OBJECT (ximagesink, "buffer not from our pool, copying");
+
+    /* we should have a pool, configured in setcaps */
+    if (ximagesink->pool == NULL)
+      goto no_pool;
+
+    /* take a buffer form our pool */
+    res = gst_buffer_pool_acquire_buffer (ximagesink->pool, &temp, NULL);
+    if (res != GST_FLOW_OK)
+      goto no_buffer;
+
+    unref = TRUE;
+
+    if (gst_buffer_get_size (temp) < gst_buffer_get_size (buf))
+      goto wrong_size;
+
+    data = gst_buffer_map (temp, &size, NULL, GST_MAP_WRITE);
+    gst_buffer_extract (buf, 0, data, size);
+    gst_buffer_unmap (temp, data, size);
+
+    buf = temp;
   }
 
-  return GST_FLOW_OK;
+  if (!gst_ximagesink_ximage_put (ximagesink, buf))
+    goto no_window;
+
+done:
+  if (unref)
+    gst_buffer_unref (buf);
+
+  return res;
 
   /* ERRORS */
-no_ximage:
+no_pool:
+  {
+    GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
+        ("Internal error: can't allocate images"),
+        ("We don't have a bufferpool negotiated"));
+    return GST_FLOW_ERROR;
+  }
+no_buffer:
   {
     /* No image available. That's very bad ! */
     GST_WARNING_OBJECT (ximagesink, "could not create image");
-    return GST_FLOW_ERROR;
+    return res;
+  }
+wrong_size:
+  {
+    GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
+        ("Failed to create output image buffer"),
+        ("XServer allocated buffer size did not match input buffer %"
+            G_GSIZE_FORMAT " - %" G_GSIZE_FORMAT, gst_buffer_get_size (temp),
+            gst_buffer_get_size (buf)));
+    res = GST_FLOW_ERROR;
+    goto done;
   }
 no_window:
   {
     /* No Window available to put our image into */
     GST_WARNING_OBJECT (ximagesink, "could not output image - no window");
-    return GST_FLOW_ERROR;
+    res = GST_FLOW_ERROR;
+    goto done;
   }
 }
 
-
 static gboolean
 gst_ximagesink_event (GstBaseSink * sink, GstEvent * event)
 {
@@ -1752,198 +1403,96 @@ gst_ximagesink_event (GstBaseSink * sink, GstEvent * event)
     return TRUE;
 }
 
-
-/* Buffer management
- *
- * The buffer_alloc function must either return a buffer with given size and
- * caps or create a buffer with different caps attached to the buffer. This
- * last option is called reverse negotiation, ie, where the sink suggests a
- * different format from the upstream peer. 
- *
- * We try to do reverse negotiation when our geometry changes and we like a
- * resized buffer.
- */
-static GstFlowReturn
-gst_ximagesink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buf)
+static gboolean
+gst_ximagesink_sink_query (GstPad * sinkpad, GstQuery * query)
 {
-  GstXImageSink *ximagesink;
-  GstXImageBuffer *ximage = NULL;
-  GstStructure *structure = NULL;
-  GstFlowReturn ret = GST_FLOW_OK;
-  GstCaps *alloc_caps;
-  gboolean alloc_unref = FALSE;
-  gint width, height;
-  GstVideoRectangle dst, src, result;
-  gboolean caps_accepted = FALSE;
+  GstXImageSink *ximagesink = GST_XIMAGESINK (GST_PAD_PARENT (sinkpad));
+  gboolean res = TRUE;
 
-  ximagesink = GST_XIMAGESINK (bsink);
-
-  if (G_UNLIKELY (!caps)) {
-    GST_WARNING_OBJECT (ximagesink, "have no caps, doing fallback allocation");
-    *buf = NULL;
-    ret = GST_FLOW_OK;
-    goto beach;
-  }
-
-  /* This shouldn't really happen because state changes will fail
-   * if the xcontext can't be allocated */
-  if (!ximagesink->xcontext)
-    return GST_FLOW_ERROR;
-
-  GST_LOG_OBJECT (ximagesink,
-      "a buffer of %d bytes was requested with caps %" GST_PTR_FORMAT
-      " and offset %" G_GUINT64_FORMAT, size, caps, offset);
-
-  /* assume we're going to alloc what was requested, keep track of
-   * wheter we need to unref or not. When we suggest a new format 
-   * upstream we will create a new caps that we need to unref. */
-  alloc_caps = caps;
-  alloc_unref = FALSE;
-
-  /* get struct to see what is requested */
-  structure = gst_caps_get_structure (caps, 0);
-  if (!gst_structure_get_int (structure, "width", &width) ||
-      !gst_structure_get_int (structure, "height", &height)) {
-    GST_WARNING_OBJECT (ximagesink, "invalid caps for buffer allocation %"
-        GST_PTR_FORMAT, caps);
-    ret = GST_FLOW_NOT_NEGOTIATED;
-    goto beach;
-  }
-
-  src.w = width;
-  src.h = height;
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_ALLOCATION:
+    {
+      GstBufferPool *pool;
+      GstStructure *config;
+      GstCaps *caps;
+      guint size;
+      gboolean need_pool;
 
-  /* We take the flow_lock because the window might go away */
-  g_mutex_lock (ximagesink->flow_lock);
-  if (!ximagesink->xwindow) {
-    g_mutex_unlock (ximagesink->flow_lock);
-    goto alloc;
-  }
+      gst_query_parse_allocation (query, &caps, &need_pool);
 
-  /* What is our geometry */
-  dst.w = ximagesink->xwindow->width;
-  dst.h = ximagesink->xwindow->height;
+      if (caps == NULL)
+        goto no_caps;
 
-  g_mutex_unlock (ximagesink->flow_lock);
+      g_mutex_lock (ximagesink->flow_lock);
+      if ((pool = ximagesink->pool))
+        gst_object_ref (pool);
+      g_mutex_unlock (ximagesink->flow_lock);
 
-  if (ximagesink->keep_aspect) {
-    GST_LOG_OBJECT (ximagesink, "enforcing aspect ratio in reverse caps "
-        "negotiation");
-    gst_video_sink_center_rect (src, dst, &result, TRUE);
-  } else {
-    GST_LOG_OBJECT (ximagesink, "trying to resize to window geometry "
-        "ignoring aspect ratio");
-    result.x = result.y = 0;
-    result.w = dst.w;
-    result.h = dst.h;
-  }
+      if (pool != NULL) {
+        const GstCaps *pcaps;
+
+        /* we had a pool, check caps */
+        config = gst_buffer_pool_get_config (pool);
+        gst_buffer_pool_config_get (config, &pcaps, &size, NULL, NULL, NULL,
+            NULL, NULL);
+
+        GST_DEBUG_OBJECT (ximagesink,
+            "we had a pool with caps %" GST_PTR_FORMAT, pcaps);
+        if (!gst_caps_is_equal (caps, pcaps)) {
+          /* different caps, we can't use this pool */
+          GST_DEBUG_OBJECT (ximagesink, "pool has different caps");
+          gst_object_unref (pool);
+          pool = NULL;
+        }
+      }
+      if (pool == NULL && need_pool) {
+        GstVideoFormat format;
+        gint width, height;
 
-  /* We would like another geometry */
-  if (width != result.w || height != result.h) {
-    int nom, den;
-    GstCaps *desired_caps;
-    GstStructure *desired_struct;
+        GST_DEBUG_OBJECT (ximagesink, "create new pool");
+        pool = gst_ximage_buffer_pool_new (ximagesink);
 
-    /* make a copy of the incomming caps to create the new
-     * suggestion. We can't use make_writable because we might
-     * then destroy the original caps which we still need when the
-     * peer does not accept the suggestion. */
-    desired_caps = gst_caps_copy (caps);
-    desired_struct = gst_caps_get_structure (desired_caps, 0);
+        if (!gst_video_format_parse_caps (caps, &format, &width, &height))
+          goto invalid_caps;
 
-    GST_DEBUG ("we would love to receive a %dx%d video", result.w, result.h);
-    gst_structure_set (desired_struct, "width", G_TYPE_INT, result.w, NULL);
-    gst_structure_set (desired_struct, "height", G_TYPE_INT, result.h, NULL);
+        /* the normal size of a frame */
+        size = gst_video_format_get_size (format, width, height);
 
-    /* PAR property overrides the X calculated one */
-    if (ximagesink->par) {
-      nom = gst_value_get_fraction_numerator (ximagesink->par);
-      den = gst_value_get_fraction_denominator (ximagesink->par);
-      gst_structure_set (desired_struct, "pixel-aspect-ratio",
-          GST_TYPE_FRACTION, nom, den, NULL);
-    } else if (ximagesink->xcontext->par) {
-      nom = gst_value_get_fraction_numerator (ximagesink->xcontext->par);
-      den = gst_value_get_fraction_denominator (ximagesink->xcontext->par);
-      gst_structure_set (desired_struct, "pixel-aspect-ratio",
-          GST_TYPE_FRACTION, nom, den, NULL);
-    }
-
-
-    /* see if peer accepts our new suggestion, if there is no peer, this 
-     * function returns true. */
-    if (!ximagesink->xcontext->last_caps ||
-        !gst_caps_is_equal (desired_caps, ximagesink->xcontext->last_caps)) {
-      caps_accepted =
-          gst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (ximagesink),
-          desired_caps);
+        config = gst_buffer_pool_get_config (pool);
+        gst_buffer_pool_config_set (config, caps, size, 0, 0, 0, 0, 16);
+        if (!gst_buffer_pool_set_config (pool, config))
+          goto config_failed;
+      }
+      gst_query_set_allocation_params (query, size, 0, 0, 0, 16, pool);
 
-      /* Suggestion failed, prevent future attempts for the same caps
-       * to fail as well. */
-      if (!caps_accepted)
-        gst_caps_replace (&ximagesink->xcontext->last_caps, desired_caps);
-    }
+      /* we also support various metadata */
+      gst_query_add_allocation_meta (query, GST_META_API_VIDEO);
 
-    if (caps_accepted) {
-      /* we will not alloc a buffer of the new suggested caps. Make sure
-       * we also unref this new caps after we set it on the buffer. */
-      alloc_caps = desired_caps;
-      alloc_unref = TRUE;
-      width = result.w;
-      height = result.h;
-      GST_DEBUG ("peer pad accepts our desired caps %" GST_PTR_FORMAT,
-          desired_caps);
-    } else {
-      GST_DEBUG ("peer pad does not accept our desired caps %" GST_PTR_FORMAT,
-          desired_caps);
-      /* we alloc a buffer with the original incomming caps already in the
-       * width and height variables */
-      gst_caps_unref (desired_caps);
+      gst_object_unref (pool);
+      break;
     }
+    default:
+      res = FALSE;
+      break;
   }
+  return res;
 
-alloc:
-  /* Inspect our buffer pool */
-  g_mutex_lock (ximagesink->pool_lock);
-  while (ximagesink->buffer_pool) {
-    ximage = (GstXImageBuffer *) ximagesink->buffer_pool->data;
-
-    if (ximage) {
-      /* Removing from the pool */
-      ximagesink->buffer_pool = g_slist_delete_link (ximagesink->buffer_pool,
-          ximagesink->buffer_pool);
-
-      /* If the ximage is invalid for our need, destroy */
-      if ((ximage->width != width) || (ximage->height != height)) {
-        gst_ximage_buffer_free (ximage);
-        ximage = NULL;
-      } else {
-        /* We found a suitable ximage */
-        break;
-      }
-    }
+  /* ERRORS */
+no_caps:
+  {
+    GST_DEBUG_OBJECT (sinkpad, "no caps specified");
+    return FALSE;
   }
-  g_mutex_unlock (ximagesink->pool_lock);
-
-  /* We haven't found anything, creating a new one */
-  if (!ximage) {
-    ximage = gst_ximagesink_ximage_new (ximagesink, alloc_caps);
+invalid_caps:
+  {
+    GST_DEBUG_OBJECT (sinkpad, "invalid caps specified");
+    return FALSE;
   }
-  /* Now we should have a ximage, set appropriate caps on it */
-  if (ximage) {
-    /* Make sure the buffer is cleared of any previously used flags */
-    GST_MINI_OBJECT_CAST (ximage)->flags = 0;
-    gst_buffer_set_caps (GST_BUFFER_CAST (ximage), alloc_caps);
+config_failed:
+  {
+    GST_DEBUG_OBJECT (sinkpad, "failed setting config");
+    return FALSE;
   }
-
-  /* could be our new reffed suggestion or the original unreffed caps */
-  if (alloc_unref)
-    gst_caps_unref (alloc_caps);
-
-  *buf = GST_BUFFER_CAST (ximage);
-
-beach:
-  return ret;
 }
 
 /* Interfaces stuff */
@@ -2271,18 +1820,18 @@ gst_ximagesink_reset (GstXImageSink * ximagesink)
   if (thread)
     g_thread_join (thread);
 
-  if (ximagesink->ximage) {
-    gst_buffer_unref (GST_BUFFER_CAST (ximagesink->ximage));
-    ximagesink->ximage = NULL;
-  }
   if (ximagesink->cur_image) {
-    gst_buffer_unref (GST_BUFFER_CAST (ximagesink->cur_image));
+    gst_buffer_unref (ximagesink->cur_image);
     ximagesink->cur_image = NULL;
   }
 
-  gst_ximagesink_bufferpool_clear (ximagesink);
-
   g_mutex_lock (ximagesink->flow_lock);
+
+  if (ximagesink->pool) {
+    gst_object_unref (ximagesink->pool);
+    ximagesink->pool = NULL;
+  }
+
   if (ximagesink->xwindow) {
     gst_ximagesink_xwindow_clear (ximagesink, ximagesink->xwindow);
     gst_ximagesink_xwindow_destroy (ximagesink, ximagesink->xwindow);
@@ -2318,10 +1867,6 @@ gst_ximagesink_finalize (GObject * object)
     g_mutex_free (ximagesink->flow_lock);
     ximagesink->flow_lock = NULL;
   }
-  if (ximagesink->pool_lock) {
-    g_mutex_free (ximagesink->pool_lock);
-    ximagesink->pool_lock = NULL;
-  }
 
   g_free (ximagesink->media_title);
 
@@ -2331,10 +1876,13 @@ gst_ximagesink_finalize (GObject * object)
 static void
 gst_ximagesink_init (GstXImageSink * ximagesink)
 {
+  /* for the ALLOCATION query */
+  gst_pad_set_query_function (GST_BASE_SINK (ximagesink)->sinkpad,
+      gst_ximagesink_sink_query);
+
   ximagesink->display_name = NULL;
   ximagesink->xcontext = NULL;
   ximagesink->xwindow = NULL;
-  ximagesink->ximage = NULL;
   ximagesink->cur_image = NULL;
 
   ximagesink->event_thread = NULL;
@@ -2348,8 +1896,7 @@ gst_ximagesink_init (GstXImageSink * ximagesink)
 
   ximagesink->par = NULL;
 
-  ximagesink->pool_lock = g_mutex_new ();
-  ximagesink->buffer_pool = NULL;
+  ximagesink->pool = NULL;
 
   ximagesink->synchronous = FALSE;
   ximagesink->keep_aspect = FALSE;
@@ -2358,19 +1905,6 @@ gst_ximagesink_init (GstXImageSink * ximagesink)
 }
 
 static void
-gst_ximagesink_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class,
-      "Video sink", "Sink/Video",
-      "A standard X based videosink", "Julien Moutte <julien@moutte.net>");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_ximagesink_sink_template_factory));
-}
-
-static void
 gst_ximagesink_class_init (GstXImageSinkClass * klass)
 {
   GObjectClass *gobject_class;
@@ -2383,8 +1917,6 @@ gst_ximagesink_class_init (GstXImageSinkClass * klass)
   gstbasesink_class = (GstBaseSinkClass *) klass;
   videosink_class = (GstVideoSinkClass *) klass;
 
-  parent_class = g_type_class_peek_parent (klass);
-
   gobject_class->finalize = gst_ximagesink_finalize;
   gobject_class->set_property = gst_ximagesink_set_property;
   gobject_class->get_property = gst_ximagesink_get_property;
@@ -2439,70 +1971,19 @@ gst_ximagesink_class_init (GstXImageSinkClass * klass)
           "Height of the window", 0, G_MAXUINT64, 0,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "Video sink", "Sink/Video",
+      "A standard X based videosink", "Julien Moutte <julien@moutte.net>");
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_ximagesink_sink_template_factory));
+
   gstelement_class->change_state = gst_ximagesink_change_state;
 
   gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_ximagesink_getcaps);
   gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_ximagesink_setcaps);
-  gstbasesink_class->buffer_alloc =
-      GST_DEBUG_FUNCPTR (gst_ximagesink_buffer_alloc);
   gstbasesink_class->get_times = GST_DEBUG_FUNCPTR (gst_ximagesink_get_times);
   gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_ximagesink_event);
 
   videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_ximagesink_show_frame);
 }
-
-/* ============================================================= */
-/*                                                               */
-/*                       Public Methods                          */
-/*                                                               */
-/* ============================================================= */
-
-/* =========================================== */
-/*                                             */
-/*          Object typing & Creation           */
-/*                                             */
-/* =========================================== */
-
-GType
-gst_ximagesink_get_type (void)
-{
-  static GType ximagesink_type = 0;
-
-  if (!ximagesink_type) {
-    static const GTypeInfo ximagesink_info = {
-      sizeof (GstXImageSinkClass),
-      gst_ximagesink_base_init,
-      NULL,
-      (GClassInitFunc) gst_ximagesink_class_init,
-      NULL,
-      NULL,
-      sizeof (GstXImageSink), 0, (GInstanceInitFunc) gst_ximagesink_init,
-    };
-    static const GInterfaceInfo iface_info = {
-      (GInterfaceInitFunc) gst_ximagesink_interface_init, NULL, NULL,
-    };
-    static const GInterfaceInfo navigation_info = {
-      (GInterfaceInitFunc) gst_ximagesink_navigation_init, NULL, NULL,
-    };
-    static const GInterfaceInfo overlay_info = {
-      (GInterfaceInitFunc) gst_ximagesink_xoverlay_init, NULL, NULL,
-    };
-
-    ximagesink_type = g_type_register_static (GST_TYPE_VIDEO_SINK,
-        "GstXImageSink", &ximagesink_info, 0);
-
-    g_type_add_interface_static (ximagesink_type, GST_TYPE_IMPLEMENTS_INTERFACE,
-        &iface_info);
-    g_type_add_interface_static (ximagesink_type, GST_TYPE_NAVIGATION,
-        &navigation_info);
-    g_type_add_interface_static (ximagesink_type, GST_TYPE_X_OVERLAY,
-        &overlay_info);
-
-    /* register type and create class in a more safe place instead of at
-     * runtime since the type registration and class creation is not
-     * threadsafe. */
-    g_type_class_ref (gst_ximage_buffer_get_type ());
-  }
-
-  return ximagesink_type;
-}
index 83e973f..b47dcde 100644 (file)
@@ -49,15 +49,15 @@ G_BEGIN_DECLS
   (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_XIMAGESINK))
 #define GST_IS_XIMAGESINK_CLASS(klass) \
   (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_XIMAGESINK))
+
 typedef struct _GstXContext GstXContext;
 typedef struct _GstXWindow GstXWindow;
 
-typedef struct _GstXImageBuffer GstXImageBuffer;
-typedef struct _GstXImageBufferClass GstXImageBufferClass;
-
 typedef struct _GstXImageSink GstXImageSink;
 typedef struct _GstXImageSinkClass GstXImageSinkClass;
 
+#include "ximagepool.h"
+
 /*
  * GstXContext:
  * @disp: the X11 Display of this context
@@ -130,33 +130,6 @@ struct _GstXWindow
 };
 
 /**
- * GstXImageBuffer:
- * @ximagesink: a reference to our #GstXImageSink
- * @ximage: the XImage of this buffer
- * @width: the width in pixels of XImage @ximage
- * @height: the height in pixels of XImage @ximage
- * @size: the size in bytes of XImage @ximage
- *
- * Subclass of #GstBuffer containing additional information about an XImage.
- */
-struct _GstXImageBuffer
-{
-  GstBuffer buffer;
-
-  /* Reference to the ximagesink we belong to */
-  GstXImageSink *ximagesink;
-
-  XImage *ximage;
-
-#ifdef HAVE_XSHM
-  XShmSegmentInfo SHMInfo;
-#endif                          /* HAVE_XSHM */
-
-  gint width, height;
-  size_t size;
-};
-
-/**
  * GstXImageSink:
  * @display_name: the name of the Display we want to render to
  * @xcontext: our instance's #GstXContext
@@ -194,8 +167,7 @@ struct _GstXImageSink
 
   GstXContext *xcontext;
   GstXWindow *xwindow;
-  GstXImageBuffer *ximage;
-  GstXImageBuffer *cur_image;
+  GstBuffer *cur_image;
 
   GThread *event_thread;
   gboolean running;
@@ -210,8 +182,8 @@ struct _GstXImageSink
   /* object-set pixel aspect ratio */
   GValue *par;
 
-  GMutex *pool_lock;
-  GSList *buffer_pool;
+  /* the buffer pool */
+  GstBufferPool *pool;
 
   gboolean synchronous;
   gboolean keep_aspect;
index fbff4d8..9669e72 100644 (file)
@@ -1,6 +1,6 @@
 plugin_LTLIBRARIES = libgstxvimagesink.la
 
-libgstxvimagesink_la_SOURCES =  xvimagesink.c 
+libgstxvimagesink_la_SOURCES =  xvimagesink.c xvimage.c xvimagepool.c 
 libgstxvimagesink_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(X_CFLAGS)
 libgstxvimagesink_la_LIBADD = \
        $(top_builddir)/gst-libs/gst/interfaces/libgstinterfaces-$(GST_MAJORMINOR).la \
@@ -12,4 +12,4 @@ libgstxvimagesink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstxvimagesink_la_DEPENDENCIES = $(top_builddir)/gst-libs/gst/video/libgstvideo-$(GST_MAJORMINOR).la
 libgstxvimagesink_la_LIBTOOLFLAGS = --tag=disable-static
 
-noinst_HEADERS = xvimagesink.h 
+noinst_HEADERS = xvimagesink.h xvimagepool.h
diff --git a/sys/xvimage/xvimage.c b/sys/xvimage/xvimage.c
new file mode 100644 (file)
index 0000000..5e2d619
--- /dev/null
@@ -0,0 +1,51 @@
+/* GStreamer
+ * Copyright (C) <2003> Julien Moutte <julien@moutte.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xvimagesink.h"
+
+GST_DEBUG_CATEGORY (gst_debug_xvimagepool);
+GST_DEBUG_CATEGORY (gst_debug_xvimagesink);
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
+
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+  if (!gst_element_register (plugin, "xvimagesink",
+          GST_RANK_PRIMARY, GST_TYPE_XVIMAGESINK))
+    return FALSE;
+
+  GST_DEBUG_CATEGORY_INIT (gst_debug_xvimagesink, "xvimagesink", 0,
+      "xvimagesink element");
+  GST_DEBUG_CATEGORY_INIT (gst_debug_xvimagepool, "xvimagepool", 0,
+      "xvimagepool object");
+
+  GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
+
+  return TRUE;
+}
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+    GST_VERSION_MINOR,
+    "xvimagesink",
+    "XFree86 video output plugin using Xv extension",
+    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/sys/xvimage/xvimagepool.c b/sys/xvimage/xvimagepool.c
new file mode 100644 (file)
index 0000000..e5fafd3
--- /dev/null
@@ -0,0 +1,642 @@
+/* GStreamer
+ * Copyright (C) <2005> Julien Moutte <julien@moutte.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Object header */
+#include "xvimagesink.h"
+
+/* Debugging category */
+#include <gst/gstinfo.h>
+
+GST_DEBUG_CATEGORY_EXTERN (gst_debug_xvimagepool);
+#define GST_CAT_DEFAULT gst_debug_xvimagepool
+
+static void gst_meta_xvimage_free (GstMetaXvImage * meta, GstBuffer * buffer);
+
+/* xvimage metadata */
+const GstMetaInfo *
+gst_meta_xvimage_get_info (void)
+{
+  static const GstMetaInfo *meta_xvimage_info = NULL;
+
+  if (meta_xvimage_info == NULL) {
+    meta_xvimage_info = gst_meta_register ("GstMetaXvImage", "GstMetaXvImage",
+        sizeof (GstMetaXvImage),
+        (GstMetaInitFunction) NULL,
+        (GstMetaFreeFunction) gst_meta_xvimage_free,
+        (GstMetaCopyFunction) NULL, (GstMetaTransformFunction) NULL);
+  }
+  return meta_xvimage_info;
+}
+
+/* X11 stuff */
+static gboolean error_caught = FALSE;
+
+static int
+gst_xvimagesink_handle_xerror (Display * display, XErrorEvent * xevent)
+{
+  char error_msg[1024];
+
+  XGetErrorText (display, xevent->error_code, error_msg, 1024);
+  GST_DEBUG ("xvimagesink triggered an XError. error: %s", error_msg);
+  error_caught = TRUE;
+  return 0;
+}
+
+GstMetaXvImage *
+gst_buffer_add_meta_xvimage (GstBuffer * buffer, GstXvImageSink * xvimagesink,
+    gint width, gint height, gint im_format)
+{
+  int (*handler) (Display *, XErrorEvent *);
+  gboolean success = FALSE;
+  GstXContext *xcontext;
+  GstMetaXvImage *meta;
+
+  xcontext = xvimagesink->xcontext;
+
+  meta =
+      (GstMetaXvImage *) gst_buffer_add_meta (buffer, GST_META_INFO_XVIMAGE,
+      NULL);
+#ifdef HAVE_XSHM
+  meta->SHMInfo.shmaddr = ((void *) -1);
+  meta->SHMInfo.shmid = -1;
+#endif
+  meta->width = width;
+  meta->height = height;
+  meta->sink = gst_object_ref (xvimagesink);
+  meta->im_format = im_format;
+
+  GST_DEBUG_OBJECT (xvimagesink, "creating image %p (%dx%d)", buffer,
+      meta->width, meta->height);
+
+  g_mutex_lock (xvimagesink->x_lock);
+
+  /* Setting an error handler to catch failure */
+  error_caught = FALSE;
+  handler = XSetErrorHandler (gst_xvimagesink_handle_xerror);
+
+#ifdef HAVE_XSHM
+  if (xcontext->use_xshm) {
+    int expected_size;
+
+    meta->xvimage = XvShmCreateImage (xcontext->disp,
+        xcontext->xv_port_id,
+        meta->im_format, NULL, meta->width, meta->height, &meta->SHMInfo);
+    if (!meta->xvimage || error_caught)
+      goto create_failed;
+
+    /* we have to use the returned data_size for our shm size */
+    meta->size = meta->xvimage->data_size;
+    GST_LOG_OBJECT (xvimagesink, "XShm image size is %" G_GSIZE_FORMAT,
+        meta->size);
+
+    /* calculate the expected size.  This is only for sanity checking the
+     * number we get from X. */
+    switch (meta->im_format) {
+      case GST_MAKE_FOURCC ('I', '4', '2', '0'):
+      case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
+      {
+        gint pitches[3];
+        gint offsets[3];
+        guint plane;
+
+        offsets[0] = 0;
+        pitches[0] = GST_ROUND_UP_4 (meta->width);
+        offsets[1] = offsets[0] + pitches[0] * GST_ROUND_UP_2 (meta->height);
+        pitches[1] = GST_ROUND_UP_8 (meta->width) / 2;
+        offsets[2] =
+            offsets[1] + pitches[1] * GST_ROUND_UP_2 (meta->height) / 2;
+        pitches[2] = GST_ROUND_UP_8 (pitches[0]) / 2;
+
+        expected_size =
+            offsets[2] + pitches[2] * GST_ROUND_UP_2 (meta->height) / 2;
+
+        for (plane = 0; plane < meta->xvimage->num_planes; plane++) {
+          GST_DEBUG_OBJECT (xvimagesink,
+              "Plane %u has a expected pitch of %d bytes, " "offset of %d",
+              plane, pitches[plane], offsets[plane]);
+        }
+        break;
+      }
+      case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
+      case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
+        expected_size = meta->height * GST_ROUND_UP_4 (meta->width * 2);
+        break;
+      default:
+        expected_size = 0;
+        break;
+    }
+    if (expected_size != 0 && meta->size != expected_size) {
+      GST_WARNING_OBJECT (xvimagesink,
+          "unexpected XShm image size (got %" G_GSIZE_FORMAT ", expected %d)",
+          meta->size, expected_size);
+    }
+
+    /* Be verbose about our XvImage stride */
+    {
+      guint plane;
+
+      for (plane = 0; plane < meta->xvimage->num_planes; plane++) {
+        GST_DEBUG_OBJECT (xvimagesink, "Plane %u has a pitch of %d bytes, "
+            "offset of %d", plane, meta->xvimage->pitches[plane],
+            meta->xvimage->offsets[plane]);
+      }
+    }
+
+    /* get shared memory */
+    meta->SHMInfo.shmid = shmget (IPC_PRIVATE, meta->size, IPC_CREAT | 0777);
+    if (meta->SHMInfo.shmid == -1)
+      goto shmget_failed;
+
+    /* attach */
+    meta->SHMInfo.shmaddr = shmat (meta->SHMInfo.shmid, NULL, 0);
+    if (meta->SHMInfo.shmaddr == ((void *) -1))
+      goto shmat_failed;
+
+    /* now we can set up the image data */
+    meta->xvimage->data = meta->SHMInfo.shmaddr;
+    meta->SHMInfo.readOnly = FALSE;
+
+    if (XShmAttach (xcontext->disp, &meta->SHMInfo) == 0)
+      goto xattach_failed;
+
+    XSync (xcontext->disp, FALSE);
+
+    /* Delete the shared memory segment as soon as we everyone is attached.
+     * This way, it will be deleted as soon as we detach later, and not
+     * leaked if we crash. */
+    shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL);
+
+    GST_DEBUG_OBJECT (xvimagesink, "XServer ShmAttached to 0x%x, id 0x%lx",
+        meta->SHMInfo.shmid, meta->SHMInfo.shmseg);
+  } else
+#endif /* HAVE_XSHM */
+  {
+    meta->xvimage = XvCreateImage (xcontext->disp,
+        xcontext->xv_port_id, meta->im_format, NULL, meta->width, meta->height);
+    if (!meta->xvimage || error_caught)
+      goto create_failed;
+
+    /* we have to use the returned data_size for our image size */
+    meta->size = meta->xvimage->data_size;
+    meta->xvimage->data = g_malloc (meta->size);
+
+    XSync (xcontext->disp, FALSE);
+  }
+
+  /* Reset error handler */
+  error_caught = FALSE;
+  XSetErrorHandler (handler);
+
+  gst_buffer_take_memory (buffer,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, meta->xvimage->data,
+          NULL, meta->size, 0, meta->size));
+
+  g_mutex_unlock (xvimagesink->x_lock);
+
+  success = TRUE;
+
+beach:
+  if (!success)
+    meta = NULL;
+
+  return meta;
+
+  /* ERRORS */
+create_failed:
+  {
+    g_mutex_unlock (xvimagesink->x_lock);
+    /* Reset error handler */
+    error_caught = FALSE;
+    XSetErrorHandler (handler);
+    /* Push an error */
+    GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
+        ("Failed to create output image buffer of %dx%d pixels",
+            meta->width, meta->height),
+        ("could not XvShmCreateImage a %dx%d image", meta->width,
+            meta->height));
+    goto beach;
+  }
+shmget_failed:
+  {
+    g_mutex_unlock (xvimagesink->x_lock);
+    GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
+        ("Failed to create output image buffer of %dx%d pixels",
+            meta->width, meta->height),
+        ("could not get shared memory of %" G_GSIZE_FORMAT " bytes",
+            meta->size));
+    goto beach;
+  }
+shmat_failed:
+  {
+    g_mutex_unlock (xvimagesink->x_lock);
+    GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
+        ("Failed to create output image buffer of %dx%d pixels",
+            meta->width, meta->height),
+        ("Failed to shmat: %s", g_strerror (errno)));
+    /* Clean up the shared memory segment */
+    shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL);
+    goto beach;
+  }
+xattach_failed:
+  {
+    /* Clean up the shared memory segment */
+    shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL);
+    g_mutex_unlock (xvimagesink->x_lock);
+
+    GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
+        ("Failed to create output image buffer of %dx%d pixels",
+            meta->width, meta->height), ("Failed to XShmAttach"));
+    goto beach;
+  }
+}
+
+static void
+gst_meta_xvimage_free (GstMetaXvImage * meta, GstBuffer * buffer)
+{
+  GstXvImageSink *xvimagesink;
+
+  xvimagesink = meta->sink;
+
+  GST_DEBUG_OBJECT (xvimagesink, "free meta on buffer %p", buffer);
+
+  /* Hold the object lock to ensure the XContext doesn't disappear */
+  GST_OBJECT_LOCK (xvimagesink);
+  /* We might have some buffers destroyed after changing state to NULL */
+  if (xvimagesink->xcontext == NULL) {
+    GST_DEBUG_OBJECT (xvimagesink, "Destroying XvImage after Xcontext");
+#ifdef HAVE_XSHM
+    /* Need to free the shared memory segment even if the x context
+     * was already cleaned up */
+    if (meta->SHMInfo.shmaddr != ((void *) -1)) {
+      shmdt (meta->SHMInfo.shmaddr);
+    }
+#endif
+    goto beach;
+  }
+
+  g_mutex_lock (xvimagesink->x_lock);
+
+#ifdef HAVE_XSHM
+  if (xvimagesink->xcontext->use_xshm) {
+    if (meta->SHMInfo.shmaddr != ((void *) -1)) {
+      GST_DEBUG_OBJECT (xvimagesink, "XServer ShmDetaching from 0x%x id 0x%lx",
+          meta->SHMInfo.shmid, meta->SHMInfo.shmseg);
+      XShmDetach (xvimagesink->xcontext->disp, &meta->SHMInfo);
+      XSync (xvimagesink->xcontext->disp, FALSE);
+      shmdt (meta->SHMInfo.shmaddr);
+      meta->SHMInfo.shmaddr = (void *) -1;
+    }
+    if (meta->xvimage)
+      XFree (meta->xvimage);
+  } else
+#endif /* HAVE_XSHM */
+  {
+    if (meta->xvimage) {
+      g_free (meta->xvimage->data);
+      XFree (meta->xvimage);
+    }
+  }
+
+  XSync (xvimagesink->xcontext->disp, FALSE);
+
+  g_mutex_unlock (xvimagesink->x_lock);
+
+beach:
+  GST_OBJECT_UNLOCK (xvimagesink);
+
+  gst_object_unref (meta->sink);
+}
+
+GstBuffer *
+gst_xvimage_buffer_new (GstXvImageSink * xvimagesink, gint width, gint height,
+    gint im_format)
+{
+  GstBuffer *buffer;
+  GstMetaXvImage *meta;
+
+  buffer = gst_buffer_new ();
+  meta =
+      gst_buffer_add_meta_xvimage (buffer, xvimagesink, width, height,
+      im_format);
+  if (meta == NULL) {
+    gst_buffer_unref (buffer);
+    buffer = NULL;
+  }
+  return buffer;
+}
+
+#ifdef HAVE_XSHM
+/* This function checks that it is actually really possible to create an image
+   using XShm */
+gboolean
+gst_xvimagesink_check_xshm_calls (GstXvImageSink * xvimagesink,
+    GstXContext * xcontext)
+{
+  XvImage *xvimage;
+  XShmSegmentInfo SHMInfo;
+  size_t size;
+  int (*handler) (Display *, XErrorEvent *);
+  gboolean result = FALSE;
+  gboolean did_attach = FALSE;
+
+  g_return_val_if_fail (xcontext != NULL, FALSE);
+
+  /* Sync to ensure any older errors are already processed */
+  XSync (xcontext->disp, FALSE);
+
+  /* Set defaults so we don't free these later unnecessarily */
+  SHMInfo.shmaddr = ((void *) -1);
+  SHMInfo.shmid = -1;
+
+  /* Setting an error handler to catch failure */
+  error_caught = FALSE;
+  handler = XSetErrorHandler (gst_xvimagesink_handle_xerror);
+
+  /* Trying to create a 1x1 picture */
+  GST_DEBUG ("XvShmCreateImage of 1x1");
+  xvimage = XvShmCreateImage (xcontext->disp, xcontext->xv_port_id,
+      xcontext->im_format, NULL, 1, 1, &SHMInfo);
+
+  /* Might cause an error, sync to ensure it is noticed */
+  XSync (xcontext->disp, FALSE);
+  if (!xvimage || error_caught) {
+    GST_WARNING ("could not XvShmCreateImage a 1x1 image");
+    goto beach;
+  }
+  size = xvimage->data_size;
+
+  SHMInfo.shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777);
+  if (SHMInfo.shmid == -1) {
+    GST_WARNING ("could not get shared memory of %" G_GSIZE_FORMAT " bytes",
+        size);
+    goto beach;
+  }
+
+  SHMInfo.shmaddr = shmat (SHMInfo.shmid, NULL, 0);
+  if (SHMInfo.shmaddr == ((void *) -1)) {
+    GST_WARNING ("Failed to shmat: %s", g_strerror (errno));
+    /* Clean up the shared memory segment */
+    shmctl (SHMInfo.shmid, IPC_RMID, NULL);
+    goto beach;
+  }
+
+  xvimage->data = SHMInfo.shmaddr;
+  SHMInfo.readOnly = FALSE;
+
+  if (XShmAttach (xcontext->disp, &SHMInfo) == 0) {
+    GST_WARNING ("Failed to XShmAttach");
+    /* Clean up the shared memory segment */
+    shmctl (SHMInfo.shmid, IPC_RMID, NULL);
+    goto beach;
+  }
+
+  /* Sync to ensure we see any errors we caused */
+  XSync (xcontext->disp, FALSE);
+
+  /* Delete the shared memory segment as soon as everyone is attached.
+   * This way, it will be deleted as soon as we detach later, and not
+   * leaked if we crash. */
+  shmctl (SHMInfo.shmid, IPC_RMID, NULL);
+
+  if (!error_caught) {
+    GST_DEBUG ("XServer ShmAttached to 0x%x, id 0x%lx", SHMInfo.shmid,
+        SHMInfo.shmseg);
+
+    did_attach = TRUE;
+    /* store whether we succeeded in result */
+    result = TRUE;
+  } else {
+    GST_WARNING ("MIT-SHM extension check failed at XShmAttach. "
+        "Not using shared memory.");
+  }
+
+beach:
+  /* Sync to ensure we swallow any errors we caused and reset error_caught */
+  XSync (xcontext->disp, FALSE);
+
+  error_caught = FALSE;
+  XSetErrorHandler (handler);
+
+  if (did_attach) {
+    GST_DEBUG ("XServer ShmDetaching from 0x%x id 0x%lx",
+        SHMInfo.shmid, SHMInfo.shmseg);
+    XShmDetach (xcontext->disp, &SHMInfo);
+    XSync (xcontext->disp, FALSE);
+  }
+  if (SHMInfo.shmaddr != ((void *) -1))
+    shmdt (SHMInfo.shmaddr);
+  if (xvimage)
+    XFree (xvimage);
+  return result;
+}
+#endif /* HAVE_XSHM */
+
+/* bufferpool */
+static void gst_xvimage_buffer_pool_finalize (GObject * object);
+
+#define GST_XVIMAGE_BUFFER_POOL_GET_PRIVATE(obj)  \
+   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_XVIMAGE_BUFFER_POOL, GstXvImageBufferPoolPrivate))
+
+struct _GstXvImageBufferPoolPrivate
+{
+  GstCaps *caps;
+  gint width, height;
+  gint im_format;
+};
+
+G_DEFINE_TYPE (GstXvImageBufferPool, gst_xvimage_buffer_pool,
+    GST_TYPE_BUFFER_POOL);
+
+static gboolean
+xvimage_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
+{
+  GstXvImageBufferPool *xvpool = GST_XVIMAGE_BUFFER_POOL_CAST (pool);
+  GstXvImageBufferPoolPrivate *priv = xvpool->priv;
+  GstStructure *structure;
+  gint width, height;
+  const GstCaps *caps;
+
+  if (!gst_buffer_pool_config_get (config, &caps, NULL, NULL, NULL, NULL,
+          NULL, NULL))
+    goto wrong_config;
+
+  if (caps == NULL)
+    goto no_caps;
+
+  /* now parse the caps from the config */
+  structure = gst_caps_get_structure (caps, 0);
+
+  if (!gst_structure_get_int (structure, "width", &width) ||
+      !gst_structure_get_int (structure, "height", &height))
+    goto wrong_caps;
+
+  GST_LOG_OBJECT (pool, "%dx%d, caps %" GST_PTR_FORMAT, width, height, caps);
+
+  /* keep track of the width and height and caps */
+  if (priv->caps)
+    gst_caps_unref (priv->caps);
+  priv->caps = gst_caps_copy (caps);
+  priv->width = width;
+  priv->height = height;
+  priv->im_format =
+      gst_xvimagesink_get_format_from_caps (xvpool->sink, (GstCaps *) caps);
+
+  if (priv->im_format == -1) {
+    GST_WARNING_OBJECT (xvpool->sink, "failed to get format from caps %"
+        GST_PTR_FORMAT, caps);
+    GST_ELEMENT_ERROR (xvpool->sink, RESOURCE, WRITE,
+        ("Failed to create output image buffer of %dx%d pixels",
+            priv->width, priv->height), ("Invalid input caps"));
+    goto wrong_config;
+  }
+
+  return TRUE;
+
+  /* ERRORS */
+wrong_config:
+  {
+    GST_WARNING_OBJECT (pool, "invalid config");
+    return FALSE;
+  }
+no_caps:
+  {
+    GST_WARNING_OBJECT (pool, "no caps in config");
+    return FALSE;
+  }
+wrong_caps:
+  {
+    GST_WARNING_OBJECT (pool,
+        "failed getting geometry from caps %" GST_PTR_FORMAT, caps);
+    return FALSE;
+  }
+}
+
+/* This function handles GstXImageBuffer creation depending on XShm availability */
+static GstFlowReturn
+xvimage_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
+    GstBufferPoolParams * params)
+{
+  GstXvImageBufferPool *xvpool = GST_XVIMAGE_BUFFER_POOL_CAST (pool);
+  GstXvImageBufferPoolPrivate *priv = xvpool->priv;
+  GstBuffer *xvimage;
+
+  xvimage =
+      gst_xvimage_buffer_new (xvpool->sink, priv->width, priv->height,
+      priv->im_format);
+  if (xvimage == NULL)
+    goto no_buffer;
+
+  *buffer = xvimage;
+
+  return GST_FLOW_OK;
+
+  /* ERROR */
+no_buffer:
+  {
+    GST_WARNING_OBJECT (pool, "can't create image");
+    return GST_FLOW_ERROR;
+  }
+}
+
+static void
+xvimage_buffer_pool_free (GstBufferPool * pool, GstBuffer * buffer)
+{
+  gst_buffer_unref (buffer);
+}
+
+GstBufferPool *
+gst_xvimage_buffer_pool_new (GstXvImageSink * xvimagesink)
+{
+  GstXvImageBufferPool *pool;
+
+  g_return_val_if_fail (GST_IS_XVIMAGESINK (xvimagesink), NULL);
+
+  pool = g_object_new (GST_TYPE_XVIMAGE_BUFFER_POOL, NULL);
+  pool->sink = gst_object_ref (xvimagesink);
+
+  GST_LOG_OBJECT (pool, "new XvImage buffer pool %p", pool);
+
+  return GST_BUFFER_POOL_CAST (pool);
+}
+
+static void
+gst_xvimage_buffer_pool_class_init (GstXvImageBufferPoolClass * klass)
+{
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+  GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass;
+
+  g_type_class_add_private (klass, sizeof (GstXvImageBufferPoolPrivate));
+
+  gobject_class->finalize = gst_xvimage_buffer_pool_finalize;
+
+  gstbufferpool_class->set_config = xvimage_buffer_pool_set_config;
+  gstbufferpool_class->alloc_buffer = xvimage_buffer_pool_alloc;
+  gstbufferpool_class->free_buffer = xvimage_buffer_pool_free;
+}
+
+static void
+gst_xvimage_buffer_pool_init (GstXvImageBufferPool * pool)
+{
+  pool->priv = GST_XVIMAGE_BUFFER_POOL_GET_PRIVATE (pool);
+}
+
+static void
+gst_xvimage_buffer_pool_finalize (GObject * object)
+{
+  GstXvImageBufferPool *pool = GST_XVIMAGE_BUFFER_POOL_CAST (object);
+  GstXvImageBufferPoolPrivate *priv = pool->priv;
+
+  GST_LOG_OBJECT (pool, "finalize XvImage buffer pool %p", pool);
+
+  if (priv->caps)
+    gst_caps_unref (priv->caps);
+  gst_object_unref (pool->sink);
+
+  G_OBJECT_CLASS (gst_xvimage_buffer_pool_parent_class)->finalize (object);
+}
+
+/* This function tries to get a format matching with a given caps in the
+   supported list of formats we generated in gst_xvimagesink_get_xv_support */
+gint
+gst_xvimagesink_get_format_from_caps (GstXvImageSink * xvimagesink,
+    GstCaps * caps)
+{
+  GList *list = NULL;
+
+  g_return_val_if_fail (GST_IS_XVIMAGESINK (xvimagesink), 0);
+
+  list = xvimagesink->xcontext->formats_list;
+
+  while (list) {
+    GstXvImageFormat *format = list->data;
+
+    if (format) {
+      if (gst_caps_can_intersect (caps, format->caps)) {
+        return format->format;
+      }
+    }
+    list = g_list_next (list);
+  }
+
+  return -1;
+}
diff --git a/sys/xvimage/xvimagepool.h b/sys/xvimage/xvimagepool.h
new file mode 100644 (file)
index 0000000..d927251
--- /dev/null
@@ -0,0 +1,120 @@
+/* GStreamer
+ * Copyright (C) <2005> Julien Moutte <julien@moutte.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_XVIMAGEPOOL_H__
+#define __GST_XVIMAGEPOOL_H__
+
+#ifdef HAVE_XSHM
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif /* HAVE_XSHM */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#ifdef HAVE_XSHM
+#include <X11/extensions/XShm.h>
+#endif /* HAVE_XSHM */
+
+#include <string.h>
+#include <math.h>
+
+
+G_BEGIN_DECLS
+
+typedef struct _GstMetaXvImage GstMetaXvImage;
+
+typedef struct _GstXvImageBufferPool GstXvImageBufferPool;
+typedef struct _GstXvImageBufferPoolClass GstXvImageBufferPoolClass;
+typedef struct _GstXvImageBufferPoolPrivate GstXvImageBufferPoolPrivate;
+
+#include "xvimagesink.h"
+
+const GstMetaInfo * gst_meta_xvimage_get_info (void);
+#define GST_META_INFO_XVIMAGE  (gst_meta_xvimage_get_info())
+
+#define gst_buffer_get_meta_xvimage(b) ((GstMetaXvImage*)gst_buffer_get_meta((b),GST_META_INFO_XVIMAGE))
+GstMetaXvImage * gst_buffer_add_meta_xvimage   (GstBuffer *buffer, GstXvImageSink * xvimagesink,
+                                                gint width, gint height, gint im_format);
+
+/**
+ * GstMetaXvImage:
+ * @sink: a reference to the our #GstXvImageSink
+ * @xvimage: the XvImage of this buffer
+ * @width: the width in pixels of XvImage @xvimage
+ * @height: the height in pixels of XvImage @xvimage
+ * @im_format: the format of XvImage @xvimage
+ * @size: the size in bytes of XvImage @xvimage
+ *
+ * Subclass of #GstMeta containing additional information about an XvImage.
+ */
+struct _GstMetaXvImage
+{
+  GstMeta meta;
+
+  /* Reference to the xvimagesink we belong to */
+  GstXvImageSink *sink;
+
+  XvImage *xvimage;
+
+#ifdef HAVE_XSHM
+  XShmSegmentInfo SHMInfo;
+#endif                          /* HAVE_XSHM */
+
+  gint width, height, im_format;
+  size_t size;
+};
+
+GstBuffer *gst_xvimage_buffer_new (GstXvImageSink *xvimagesink, gint width, gint height,
+    gint in_format);
+
+/* buffer pool functions */
+#define GST_TYPE_XVIMAGE_BUFFER_POOL      (gst_xvimage_buffer_pool_get_type())
+#define GST_IS_XVIMAGE_BUFFER_POOL(obj)   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_XVIMAGE_BUFFER_POOL))
+#define GST_XVIMAGE_BUFFER_POOL(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_XVIMAGE_BUFFER_POOL, GstXvImageBufferPool))
+#define GST_XVIMAGE_BUFFER_POOL_CAST(obj) ((GstXvImageBufferPool*)(obj))
+
+struct _GstXvImageBufferPool
+{
+  GstBufferPool bufferpool;
+
+  GstXvImageSink *sink;
+
+  GstXvImageBufferPoolPrivate *priv;
+};
+
+struct _GstXvImageBufferPoolClass
+{
+  GstBufferPoolClass parent_class;
+};
+
+GType gst_xvimage_buffer_pool_get_type (void);
+
+GstBufferPool *gst_xvimage_buffer_pool_new (GstXvImageSink * xvimagesink);
+
+gboolean gst_xvimagesink_check_xshm_calls (GstXvImageSink * xvimagesink,
+      GstXContext * xcontext);
+
+gint gst_xvimagesink_get_format_from_caps (GstXvImageSink * xvimagesink,
+    GstCaps * caps);
+
+G_END_DECLS
+
+#endif /*__GST_XVIMAGEPOOL_H__*/
index 3e0b457..33f54ea 100644 (file)
 #include <gst/interfaces/propertyprobe.h>
 /* Helper functions */
 #include <gst/video/video.h>
+#include <gst/video/gstmetavideo.h>
 
 /* Object header */
 #include "xvimagesink.h"
 
 /* Debugging category */
 #include <gst/gstinfo.h>
-GST_DEBUG_CATEGORY_STATIC (gst_debug_xvimagesink);
+
+GST_DEBUG_CATEGORY_EXTERN (gst_debug_xvimagesink);
+GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE);
 #define GST_CAT_DEFAULT gst_debug_xvimagesink
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
 
 typedef struct
 {
@@ -143,14 +145,8 @@ MotifWmHints, MwmHints;
 #define MWM_HINTS_DECORATIONS   (1L << 1)
 
 static void gst_xvimagesink_reset (GstXvImageSink * xvimagesink);
-
-static GstBufferClass *xvimage_buffer_parent_class = NULL;
-static void gst_xvimage_buffer_finalize (GstXvImageBuffer * xvimage);
-
 static void gst_xvimagesink_xwindow_update_geometry (GstXvImageSink *
     xvimagesink);
-static gint gst_xvimagesink_get_format_from_caps (GstXvImageSink * xvimagesink,
-    GstCaps * caps);
 static void gst_xvimagesink_expose (GstXOverlay * overlay);
 
 /* Default template - initiated with class struct to allow gst-register to work
@@ -191,541 +187,44 @@ enum
   PROP_WINDOW_HEIGHT
 };
 
-static void
-gst_xvimagesink_init_interfaces (GType type);
-
-GST_BOILERPLATE_FULL (GstXvImageSink, gst_xvimagesink, GstVideoSink,
-    GST_TYPE_VIDEO_SINK, gst_xvimagesink_init_interfaces);
-
-
 /* ============================================================= */
 /*                                                               */
-/*                       Private Methods                         */
+/*                       Public Methods                          */
 /*                                                               */
 /* ============================================================= */
 
-/* xvimage buffers */
-
-#define GST_TYPE_XVIMAGE_BUFFER (gst_xvimage_buffer_get_type())
-
-#define GST_IS_XVIMAGE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_XVIMAGE_BUFFER))
-#define GST_XVIMAGE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_XVIMAGE_BUFFER, GstXvImageBuffer))
-#define GST_XVIMAGE_BUFFER_CAST(obj) ((GstXvImageBuffer *)(obj))
-
-/* This function destroys a GstXvImage handling XShm availability */
-static void
-gst_xvimage_buffer_destroy (GstXvImageBuffer * xvimage)
-{
-  GstXvImageSink *xvimagesink;
-
-  GST_DEBUG_OBJECT (xvimage, "Destroying buffer");
-
-  xvimagesink = xvimage->xvimagesink;
-  if (G_UNLIKELY (xvimagesink == NULL))
-    goto no_sink;
-
-  g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
-
-  GST_OBJECT_LOCK (xvimagesink);
-
-  /* If the destroyed image is the current one we destroy our reference too */
-  if (xvimagesink->cur_image == xvimage)
-    xvimagesink->cur_image = NULL;
-
-  /* We might have some buffers destroyed after changing state to NULL */
-  if (xvimagesink->xcontext == NULL) {
-    GST_DEBUG_OBJECT (xvimagesink, "Destroying XvImage after Xcontext");
-#ifdef HAVE_XSHM
-    /* Need to free the shared memory segment even if the x context
-     * was already cleaned up */
-    if (xvimage->SHMInfo.shmaddr != ((void *) -1)) {
-      shmdt (xvimage->SHMInfo.shmaddr);
-    }
-#endif
-    goto beach;
-  }
-
-  g_mutex_lock (xvimagesink->x_lock);
-
-#ifdef HAVE_XSHM
-  if (xvimagesink->xcontext->use_xshm) {
-    if (xvimage->SHMInfo.shmaddr != ((void *) -1)) {
-      GST_DEBUG_OBJECT (xvimagesink, "XServer ShmDetaching from 0x%x id 0x%lx",
-          xvimage->SHMInfo.shmid, xvimage->SHMInfo.shmseg);
-      XShmDetach (xvimagesink->xcontext->disp, &xvimage->SHMInfo);
-      XSync (xvimagesink->xcontext->disp, FALSE);
-
-      shmdt (xvimage->SHMInfo.shmaddr);
-    }
-    if (xvimage->xvimage)
-      XFree (xvimage->xvimage);
-  } else
-#endif /* HAVE_XSHM */
-  {
-    if (xvimage->xvimage) {
-      if (xvimage->xvimage->data) {
-        g_free (xvimage->xvimage->data);
-      }
-      XFree (xvimage->xvimage);
-    }
-  }
-
-  XSync (xvimagesink->xcontext->disp, FALSE);
-
-  g_mutex_unlock (xvimagesink->x_lock);
-
-beach:
-  GST_OBJECT_UNLOCK (xvimagesink);
-  xvimage->xvimagesink = NULL;
-  gst_object_unref (xvimagesink);
-
-  GST_MINI_OBJECT_CLASS (xvimage_buffer_parent_class)->finalize (GST_MINI_OBJECT
-      (xvimage));
-
-  return;
-
-no_sink:
-  {
-    GST_WARNING ("no sink found");
-    return;
-  }
-}
-
-static void
-gst_xvimage_buffer_finalize (GstXvImageBuffer * xvimage)
-{
-  GstXvImageSink *xvimagesink;
-  gboolean running;
-
-  xvimagesink = xvimage->xvimagesink;
-  if (G_UNLIKELY (xvimagesink == NULL))
-    goto no_sink;
-
-  g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
-
-  GST_OBJECT_LOCK (xvimagesink);
-  running = xvimagesink->running;
-  GST_OBJECT_UNLOCK (xvimagesink);
-
-  /* If our geometry changed we can't reuse that image. */
-  if (running == FALSE) {
-    GST_LOG_OBJECT (xvimage, "destroy image as sink is shutting down");
-    gst_xvimage_buffer_destroy (xvimage);
-  } else if ((xvimage->width != xvimagesink->video_width) ||
-      (xvimage->height != xvimagesink->video_height)) {
-    GST_LOG_OBJECT (xvimage,
-        "destroy image as its size changed %dx%d vs current %dx%d",
-        xvimage->width, xvimage->height,
-        xvimagesink->video_width, xvimagesink->video_height);
-    gst_xvimage_buffer_destroy (xvimage);
-  } else {
-    /* In that case we can reuse the image and add it to our image pool. */
-    GST_LOG_OBJECT (xvimage, "recycling image in pool");
-    /* need to increment the refcount again to recycle */
-    gst_buffer_ref (GST_BUFFER_CAST (xvimage));
-    g_mutex_lock (xvimagesink->pool_lock);
-    xvimagesink->image_pool = g_slist_prepend (xvimagesink->image_pool,
-        xvimage);
-    g_mutex_unlock (xvimagesink->pool_lock);
-  }
-  return;
-
-no_sink:
-  {
-    GST_WARNING ("no sink found");
-    return;
-  }
-}
-
-static void
-gst_xvimage_buffer_free (GstXvImageBuffer * xvimage)
-{
-  /* make sure it is not recycled */
-  xvimage->width = -1;
-  xvimage->height = -1;
-  gst_buffer_unref (GST_BUFFER (xvimage));
-}
-
-static void
-gst_xvimage_buffer_init (GstXvImageBuffer * xvimage, gpointer g_class)
-{
-#ifdef HAVE_XSHM
-  xvimage->SHMInfo.shmaddr = ((void *) -1);
-  xvimage->SHMInfo.shmid = -1;
-#endif
-}
-
+/* =========================================== */
+/*                                             */
+/*          Object typing & Creation           */
+/*                                             */
+/* =========================================== */
+static void gst_xvimagesink_interface_init (GstImplementsInterfaceClass *
+    klass);
+static void gst_xvimagesink_navigation_init (GstNavigationInterface * iface);
+static void gst_xvimagesink_xoverlay_init (GstXOverlayClass * iface);
+static void gst_xvimagesink_colorbalance_init (GstColorBalanceClass * iface);
 static void
-gst_xvimage_buffer_class_init (gpointer g_class, gpointer class_data)
-{
-  GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
-
-  xvimage_buffer_parent_class = g_type_class_peek_parent (g_class);
-
-  mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
-      gst_xvimage_buffer_finalize;
-}
-
-static GType
-gst_xvimage_buffer_get_type (void)
-{
-  static GType _gst_xvimage_buffer_type;
-
-  if (G_UNLIKELY (_gst_xvimage_buffer_type == 0)) {
-    static const GTypeInfo xvimage_buffer_info = {
-      sizeof (GstBufferClass),
-      NULL,
-      NULL,
-      gst_xvimage_buffer_class_init,
-      NULL,
-      NULL,
-      sizeof (GstXvImageBuffer),
-      0,
-      (GInstanceInitFunc) gst_xvimage_buffer_init,
-      NULL
-    };
-    _gst_xvimage_buffer_type = g_type_register_static (GST_TYPE_BUFFER,
-        "GstXvImageBuffer", &xvimage_buffer_info, 0);
-  }
-  return _gst_xvimage_buffer_type;
-}
-
-/* X11 stuff */
-
-static gboolean error_caught = FALSE;
-
-static int
-gst_xvimagesink_handle_xerror (Display * display, XErrorEvent * xevent)
-{
-  char error_msg[1024];
-
-  XGetErrorText (display, xevent->error_code, error_msg, 1024);
-  GST_DEBUG ("xvimagesink triggered an XError. error: %s", error_msg);
-  error_caught = TRUE;
-  return 0;
-}
-
-#ifdef HAVE_XSHM
-/* This function checks that it is actually really possible to create an image
-   using XShm */
-static gboolean
-gst_xvimagesink_check_xshm_calls (GstXContext * xcontext)
-{
-  XvImage *xvimage;
-  XShmSegmentInfo SHMInfo;
-  gint size;
-  int (*handler) (Display *, XErrorEvent *);
-  gboolean result = FALSE;
-  gboolean did_attach = FALSE;
-
-  g_return_val_if_fail (xcontext != NULL, FALSE);
-
-  /* Sync to ensure any older errors are already processed */
-  XSync (xcontext->disp, FALSE);
-
-  /* Set defaults so we don't free these later unnecessarily */
-  SHMInfo.shmaddr = ((void *) -1);
-  SHMInfo.shmid = -1;
-
-  /* Setting an error handler to catch failure */
-  error_caught = FALSE;
-  handler = XSetErrorHandler (gst_xvimagesink_handle_xerror);
-
-  /* Trying to create a 1x1 picture */
-  GST_DEBUG ("XvShmCreateImage of 1x1");
-  xvimage = XvShmCreateImage (xcontext->disp, xcontext->xv_port_id,
-      xcontext->im_format, NULL, 1, 1, &SHMInfo);
-
-  /* Might cause an error, sync to ensure it is noticed */
-  XSync (xcontext->disp, FALSE);
-  if (!xvimage || error_caught) {
-    GST_WARNING ("could not XvShmCreateImage a 1x1 image");
-    goto beach;
-  }
-  size = xvimage->data_size;
-
-  SHMInfo.shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777);
-  if (SHMInfo.shmid == -1) {
-    GST_WARNING ("could not get shared memory of %d bytes", size);
-    goto beach;
-  }
-
-  SHMInfo.shmaddr = shmat (SHMInfo.shmid, NULL, 0);
-  if (SHMInfo.shmaddr == ((void *) -1)) {
-    GST_WARNING ("Failed to shmat: %s", g_strerror (errno));
-    /* Clean up the shared memory segment */
-    shmctl (SHMInfo.shmid, IPC_RMID, NULL);
-    goto beach;
-  }
-
-  xvimage->data = SHMInfo.shmaddr;
-  SHMInfo.readOnly = FALSE;
-
-  if (XShmAttach (xcontext->disp, &SHMInfo) == 0) {
-    GST_WARNING ("Failed to XShmAttach");
-    /* Clean up the shared memory segment */
-    shmctl (SHMInfo.shmid, IPC_RMID, NULL);
-    goto beach;
-  }
-
-  /* Sync to ensure we see any errors we caused */
-  XSync (xcontext->disp, FALSE);
-
-  /* Delete the shared memory segment as soon as everyone is attached.
-   * This way, it will be deleted as soon as we detach later, and not
-   * leaked if we crash. */
-  shmctl (SHMInfo.shmid, IPC_RMID, NULL);
-
-  if (!error_caught) {
-    GST_DEBUG ("XServer ShmAttached to 0x%x, id 0x%lx", SHMInfo.shmid,
-        SHMInfo.shmseg);
-
-    did_attach = TRUE;
-    /* store whether we succeeded in result */
-    result = TRUE;
-  } else {
-    GST_WARNING ("MIT-SHM extension check failed at XShmAttach. "
-        "Not using shared memory.");
-  }
-
-beach:
-  /* Sync to ensure we swallow any errors we caused and reset error_caught */
-  XSync (xcontext->disp, FALSE);
-
-  error_caught = FALSE;
-  XSetErrorHandler (handler);
-
-  if (did_attach) {
-    GST_DEBUG ("XServer ShmDetaching from 0x%x id 0x%lx",
-        SHMInfo.shmid, SHMInfo.shmseg);
-    XShmDetach (xcontext->disp, &SHMInfo);
-    XSync (xcontext->disp, FALSE);
-  }
-  if (SHMInfo.shmaddr != ((void *) -1))
-    shmdt (SHMInfo.shmaddr);
-  if (xvimage)
-    XFree (xvimage);
-  return result;
-}
-#endif /* HAVE_XSHM */
-
-/* This function handles GstXvImage creation depending on XShm availability */
-static GstXvImageBuffer *
-gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
-{
-  GstXvImageBuffer *xvimage = NULL;
-  GstStructure *structure = NULL;
-  gboolean succeeded = FALSE;
-  int (*handler) (Display *, XErrorEvent *);
-
-  g_return_val_if_fail (GST_IS_XVIMAGESINK (xvimagesink), NULL);
-
-  if (caps == NULL)
-    return NULL;
-
-  xvimage = (GstXvImageBuffer *) gst_mini_object_new (GST_TYPE_XVIMAGE_BUFFER);
-  GST_DEBUG_OBJECT (xvimage, "Creating new XvImageBuffer");
-
-  structure = gst_caps_get_structure (caps, 0);
-
-  if (!gst_structure_get_int (structure, "width", &xvimage->width) ||
-      !gst_structure_get_int (structure, "height", &xvimage->height)) {
-    GST_WARNING ("failed getting geometry from caps %" GST_PTR_FORMAT, caps);
-  }
-
-  GST_LOG_OBJECT (xvimagesink, "creating %dx%d", xvimage->width,
-      xvimage->height);
-
-  xvimage->im_format = gst_xvimagesink_get_format_from_caps (xvimagesink, caps);
-  if (xvimage->im_format == -1) {
-    GST_WARNING_OBJECT (xvimagesink, "failed to get format from caps %"
-        GST_PTR_FORMAT, caps);
-    GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
-        ("Failed to create output image buffer of %dx%d pixels",
-            xvimage->width, xvimage->height), ("Invalid input caps"));
-    goto beach_unlocked;
-  }
-  xvimage->xvimagesink = gst_object_ref (xvimagesink);
-
-  g_mutex_lock (xvimagesink->x_lock);
-
-  /* Setting an error handler to catch failure */
-  error_caught = FALSE;
-  handler = XSetErrorHandler (gst_xvimagesink_handle_xerror);
-
-#ifdef HAVE_XSHM
-  if (xvimagesink->xcontext->use_xshm) {
-    int expected_size;
-
-    xvimage->xvimage = XvShmCreateImage (xvimagesink->xcontext->disp,
-        xvimagesink->xcontext->xv_port_id,
-        xvimage->im_format, NULL,
-        xvimage->width, xvimage->height, &xvimage->SHMInfo);
-    if (!xvimage->xvimage || error_caught) {
-      g_mutex_unlock (xvimagesink->x_lock);
-      /* Reset error handler */
-      error_caught = FALSE;
-      XSetErrorHandler (handler);
-      /* Push an error */
-      GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
-          ("Failed to create output image buffer of %dx%d pixels",
-              xvimage->width, xvimage->height),
-          ("could not XvShmCreateImage a %dx%d image",
-              xvimage->width, xvimage->height));
-      goto beach_unlocked;
-    }
-
-    /* we have to use the returned data_size for our shm size */
-    xvimage->size = xvimage->xvimage->data_size;
-    GST_LOG_OBJECT (xvimagesink, "XShm image size is %" G_GSIZE_FORMAT,
-        xvimage->size);
-
-    /* calculate the expected size.  This is only for sanity checking the
-     * number we get from X. */
-    switch (xvimage->im_format) {
-      case GST_MAKE_FOURCC ('I', '4', '2', '0'):
-      case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
-      {
-        gint pitches[3];
-        gint offsets[3];
-        guint plane;
-
-        offsets[0] = 0;
-        pitches[0] = GST_ROUND_UP_4 (xvimage->width);
-        offsets[1] = offsets[0] + pitches[0] * GST_ROUND_UP_2 (xvimage->height);
-        pitches[1] = GST_ROUND_UP_8 (xvimage->width) / 2;
-        offsets[2] =
-            offsets[1] + pitches[1] * GST_ROUND_UP_2 (xvimage->height) / 2;
-        pitches[2] = GST_ROUND_UP_8 (pitches[0]) / 2;
-
-        expected_size =
-            offsets[2] + pitches[2] * GST_ROUND_UP_2 (xvimage->height) / 2;
-
-        for (plane = 0; plane < xvimage->xvimage->num_planes; plane++) {
-          GST_DEBUG_OBJECT (xvimagesink,
-              "Plane %u has a expected pitch of %d bytes, " "offset of %d",
-              plane, pitches[plane], offsets[plane]);
-        }
-        break;
-      }
-      case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
-      case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
-        expected_size = xvimage->height * GST_ROUND_UP_4 (xvimage->width * 2);
-        break;
-      default:
-        expected_size = 0;
-        break;
-    }
-    if (expected_size != 0 && xvimage->size != expected_size) {
-      GST_WARNING_OBJECT (xvimagesink,
-          "unexpected XShm image size (got %" G_GSIZE_FORMAT ", expected %d)",
-          xvimage->size, expected_size);
-    }
-
-    /* Be verbose about our XvImage stride */
-    {
-      guint plane;
-
-      for (plane = 0; plane < xvimage->xvimage->num_planes; plane++) {
-        GST_DEBUG_OBJECT (xvimagesink, "Plane %u has a pitch of %d bytes, "
-            "offset of %d", plane, xvimage->xvimage->pitches[plane],
-            xvimage->xvimage->offsets[plane]);
-      }
-    }
-
-    xvimage->SHMInfo.shmid = shmget (IPC_PRIVATE, xvimage->size,
-        IPC_CREAT | 0777);
-    if (xvimage->SHMInfo.shmid == -1) {
-      g_mutex_unlock (xvimagesink->x_lock);
-      GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
-          ("Failed to create output image buffer of %dx%d pixels",
-              xvimage->width, xvimage->height),
-          ("could not get shared memory of %" G_GSIZE_FORMAT " bytes",
-              xvimage->size));
-      goto beach_unlocked;
-    }
-
-    xvimage->SHMInfo.shmaddr = shmat (xvimage->SHMInfo.shmid, NULL, 0);
-    if (xvimage->SHMInfo.shmaddr == ((void *) -1)) {
-      g_mutex_unlock (xvimagesink->x_lock);
-      GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
-          ("Failed to create output image buffer of %dx%d pixels",
-              xvimage->width, xvimage->height),
-          ("Failed to shmat: %s", g_strerror (errno)));
-      /* Clean up the shared memory segment */
-      shmctl (xvimage->SHMInfo.shmid, IPC_RMID, NULL);
-      goto beach_unlocked;
-    }
-
-    xvimage->xvimage->data = xvimage->SHMInfo.shmaddr;
-    xvimage->SHMInfo.readOnly = FALSE;
-
-    if (XShmAttach (xvimagesink->xcontext->disp, &xvimage->SHMInfo) == 0) {
-      /* Clean up the shared memory segment */
-      shmctl (xvimage->SHMInfo.shmid, IPC_RMID, NULL);
-
-      g_mutex_unlock (xvimagesink->x_lock);
-      GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
-          ("Failed to create output image buffer of %dx%d pixels",
-              xvimage->width, xvimage->height), ("Failed to XShmAttach"));
-      goto beach_unlocked;
-    }
-
-    XSync (xvimagesink->xcontext->disp, FALSE);
-
-    /* Delete the shared memory segment as soon as we everyone is attached.
-     * This way, it will be deleted as soon as we detach later, and not
-     * leaked if we crash. */
-    shmctl (xvimage->SHMInfo.shmid, IPC_RMID, NULL);
-
-    GST_DEBUG_OBJECT (xvimagesink, "XServer ShmAttached to 0x%x, id 0x%lx",
-        xvimage->SHMInfo.shmid, xvimage->SHMInfo.shmseg);
-  } else
-#endif /* HAVE_XSHM */
-  {
-    xvimage->xvimage = XvCreateImage (xvimagesink->xcontext->disp,
-        xvimagesink->xcontext->xv_port_id,
-        xvimage->im_format, NULL, xvimage->width, xvimage->height);
-    if (!xvimage->xvimage || error_caught) {
-      g_mutex_unlock (xvimagesink->x_lock);
-      /* Reset error handler */
-      error_caught = FALSE;
-      XSetErrorHandler (handler);
-      /* Push an error */
-      GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
-          ("Failed to create outputimage buffer of %dx%d pixels",
-              xvimage->width, xvimage->height),
-          ("could not XvCreateImage a %dx%d image",
-              xvimage->width, xvimage->height));
-      goto beach_unlocked;
-    }
-
-    /* we have to use the returned data_size for our image size */
-    xvimage->size = xvimage->xvimage->data_size;
-    xvimage->xvimage->data = g_malloc (xvimage->size);
-
-    XSync (xvimagesink->xcontext->disp, FALSE);
-  }
-
-  /* Reset error handler */
-  error_caught = FALSE;
-  XSetErrorHandler (handler);
-
-  succeeded = TRUE;
-
-  GST_BUFFER_DATA (xvimage) = (guchar *) xvimage->xvimage->data;
-  GST_BUFFER_SIZE (xvimage) = xvimage->size;
+gst_xvimagesink_property_probe_interface_init (GstPropertyProbeInterface *
+    iface);
+#define gst_xvimagesink_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstXvImageSink, gst_xvimagesink, GST_TYPE_VIDEO_SINK,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_IMPLEMENTS_INTERFACE,
+        gst_xvimagesink_interface_init);
+    G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION,
+        gst_xvimagesink_navigation_init);
+    G_IMPLEMENT_INTERFACE (GST_TYPE_X_OVERLAY, gst_xvimagesink_xoverlay_init);
+    G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE,
+        gst_xvimagesink_colorbalance_init);
+    G_IMPLEMENT_INTERFACE (GST_TYPE_PROPERTY_PROBE,
+        gst_xvimagesink_property_probe_interface_init));
 
-  g_mutex_unlock (xvimagesink->x_lock);
 
-beach_unlocked:
-  if (!succeeded) {
-    gst_xvimage_buffer_free (xvimage);
-    xvimage = NULL;
-  }
+/* ============================================================= */
+/*                                                               */
+/*                       Private Methods                         */
+/*                                                               */
+/* ============================================================= */
 
-  return xvimage;
-}
 
 /* We are called with the x_lock taken */
 static void
@@ -774,9 +273,9 @@ gst_xvimagesink_xwindow_draw_borders (GstXvImageSink * xvimagesink,
 /* This function puts a GstXvImage on a GstXvImageSink's window. Returns FALSE
  * if no window was available  */
 static gboolean
-gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink,
-    GstXvImageBuffer * xvimage)
+gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
 {
+  GstMetaXvImage *meta;
   GstVideoRectangle result;
   gboolean draw_border = FALSE;
 
@@ -799,11 +298,10 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink,
   if (xvimage && xvimagesink->cur_image != xvimage) {
     if (xvimagesink->cur_image) {
       GST_LOG_OBJECT (xvimagesink, "unreffing %p", xvimagesink->cur_image);
-      gst_buffer_unref (GST_BUFFER_CAST (xvimagesink->cur_image));
+      gst_buffer_unref (xvimagesink->cur_image);
     }
     GST_LOG_OBJECT (xvimagesink, "reffing %p as our current image", xvimage);
-    xvimagesink->cur_image =
-        GST_XVIMAGE_BUFFER_CAST (gst_buffer_ref (GST_BUFFER_CAST (xvimage)));
+    xvimagesink->cur_image = gst_buffer_ref (xvimage);
   }
 
   /* Expose sends a NULL image, we take the latest frame */
@@ -817,6 +315,8 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink,
     }
   }
 
+  meta = gst_buffer_get_meta_xvimage (xvimage);
+
   if (xvimagesink->keep_aspect) {
     GstVideoRectangle src, dst;
 
@@ -841,20 +341,17 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink,
         result);
     xvimagesink->redraw_border = FALSE;
   }
-
-  /* We scale to the window's geometry */
 #ifdef HAVE_XSHM
   if (xvimagesink->xcontext->use_xshm) {
     GST_LOG_OBJECT (xvimagesink,
         "XvShmPutImage with image %dx%d and window %dx%d, from xvimage %"
-        GST_PTR_FORMAT,
-        xvimage->width, xvimage->height,
+        GST_PTR_FORMAT, meta->width, meta->height,
         xvimagesink->render_rect.w, xvimagesink->render_rect.h, xvimage);
 
     XvShmPutImage (xvimagesink->xcontext->disp,
         xvimagesink->xcontext->xv_port_id,
         xvimagesink->xwindow->win,
-        xvimagesink->xwindow->gc, xvimage->xvimage,
+        xvimagesink->xwindow->gc, meta->xvimage,
         xvimagesink->disp_x, xvimagesink->disp_y,
         xvimagesink->disp_width, xvimagesink->disp_height,
         result.x, result.y, result.w, result.h, FALSE);
@@ -864,7 +361,7 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink,
     XvPutImage (xvimagesink->xcontext->disp,
         xvimagesink->xcontext->xv_port_id,
         xvimagesink->xwindow->win,
-        xvimagesink->xwindow->gc, xvimage->xvimage,
+        xvimagesink->xwindow->gc, meta->xvimage,
         xvimagesink->disp_x, xvimagesink->disp_y,
         xvimagesink->disp_width, xvimagesink->disp_height,
         result.x, result.y, result.w, result.h);
@@ -1201,6 +698,7 @@ gst_xvimagesink_handle_xevents (GstXvImageSink * xvimagesink)
     g_mutex_lock (xvimagesink->flow_lock);
     g_mutex_lock (xvimagesink->x_lock);
   }
+
   if (pointer_moved) {
     g_mutex_unlock (xvimagesink->x_lock);
     g_mutex_unlock (xvimagesink->flow_lock);
@@ -1266,7 +764,8 @@ gst_xvimagesink_handle_xevents (GstXvImageSink * xvimagesink)
         }
         break;
       default:
-        GST_DEBUG ("xvimagesink unhandled X event (%d)", e.type);
+        GST_DEBUG_OBJECT (xvimagesink, "xvimagesink unhandled X event (%d)",
+            e.type);
     }
     g_mutex_lock (xvimagesink->flow_lock);
     g_mutex_lock (xvimagesink->x_lock);
@@ -1732,6 +1231,7 @@ gst_xvimagesink_calculate_pixel_aspect_ratio (GstXContext * xcontext)
     ratio = 4.0 * 576 / (3.0 * 720);
   }
   GST_DEBUG ("calculated pixel aspect ratio: %f", ratio);
+
   /* now find the one from par[][2] with the lowest delta to the real one */
   delta = DELTA (0);
   index = 0;
@@ -1848,18 +1348,10 @@ gst_xvimagesink_xcontext_get (GstXvImageSink * xvimagesink)
 
   xcontext->caps = gst_xvimagesink_get_xv_support (xvimagesink, xcontext);
 
-  if (!xcontext->caps) {
-    XCloseDisplay (xcontext->disp);
-    g_mutex_unlock (xvimagesink->x_lock);
-    g_free (xcontext->par);
-    g_free (xcontext);
-    /* GST_ELEMENT_ERROR is thrown by gst_xvimagesink_get_xv_support */
-    return NULL;
-  }
-#ifdef HAVE_XSHM
   /* Search for XShm extension support */
+#ifdef HAVE_XSHM
   if (XShmQueryExtension (xcontext->disp) &&
-      gst_xvimagesink_check_xshm_calls (xcontext)) {
+      gst_xvimagesink_check_xshm_calls (xvimagesink, xcontext)) {
     xcontext->use_xshm = TRUE;
     GST_DEBUG ("xvimagesink is using XShm extension");
   } else
@@ -1869,6 +1361,15 @@ gst_xvimagesink_xcontext_get (GstXvImageSink * xvimagesink)
     GST_DEBUG ("xvimagesink is not using XShm extension");
   }
 
+  if (!xcontext->caps) {
+    XCloseDisplay (xcontext->disp);
+    g_mutex_unlock (xvimagesink->x_lock);
+    g_free (xcontext->par);
+    g_free (xcontext);
+    /* GST_ELEMENT_ERROR is thrown by gst_xvimagesink_get_xv_support */
+    return NULL;
+  }
+
   xv_attr = XvQueryPortAttributes (xcontext->disp,
       xcontext->xv_port_id, &N_attr);
 
@@ -2005,63 +1506,34 @@ gst_xvimagesink_xcontext_clear (GstXvImageSink * xvimagesink)
   g_free (xcontext);
 }
 
-static void
-gst_xvimagesink_imagepool_clear (GstXvImageSink * xvimagesink)
-{
-  g_mutex_lock (xvimagesink->pool_lock);
-
-  while (xvimagesink->image_pool) {
-    GstXvImageBuffer *xvimage = xvimagesink->image_pool->data;
-
-    xvimagesink->image_pool = g_slist_delete_link (xvimagesink->image_pool,
-        xvimagesink->image_pool);
-    gst_xvimage_buffer_free (xvimage);
-  }
-
-  g_mutex_unlock (xvimagesink->pool_lock);
-}
-
 /* Element stuff */
 
-/* This function tries to get a format matching with a given caps in the
-   supported list of formats we generated in gst_xvimagesink_get_xv_support */
-static gint
-gst_xvimagesink_get_format_from_caps (GstXvImageSink * xvimagesink,
-    GstCaps * caps)
-{
-  GList *list = NULL;
-
-  g_return_val_if_fail (GST_IS_XVIMAGESINK (xvimagesink), 0);
-
-  list = xvimagesink->xcontext->formats_list;
-
-  while (list) {
-    GstXvImageFormat *format = list->data;
-
-    if (format) {
-      if (gst_caps_can_intersect (caps, format->caps)) {
-        return format->format;
-      }
-    }
-    list = g_list_next (list);
-  }
-
-  return -1;
-}
-
 static GstCaps *
-gst_xvimagesink_getcaps (GstBaseSink * bsink)
+gst_xvimagesink_getcaps (GstBaseSink * bsink, GstCaps * filter)
 {
   GstXvImageSink *xvimagesink;
+  GstCaps *caps;
 
   xvimagesink = GST_XVIMAGESINK (bsink);
 
-  if (xvimagesink->xcontext)
-    return gst_caps_ref (xvimagesink->xcontext->caps);
+  if (xvimagesink->xcontext) {
+    if (filter)
+      return gst_caps_intersect_full (filter, xvimagesink->xcontext->caps,
+          GST_CAPS_INTERSECT_FIRST);
+    else
+      return gst_caps_ref (xvimagesink->xcontext->caps);
+  }
+
+  caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (xvimagesink));
+  if (filter) {
+    GstCaps *intersection;
 
-  return
-      gst_caps_copy (gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD
-          (xvimagesink)));
+    intersection =
+        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (caps);
+    caps = intersection;
+  }
+  return caps;
 }
 
 static gboolean
@@ -2069,8 +1541,9 @@ gst_xvimagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
 {
   GstXvImageSink *xvimagesink;
   GstStructure *structure;
-  guint32 im_format = 0;
+  GstBufferPool *newpool, *oldpool;
   gboolean ret;
+  guint32 im_format = 0;
   gint video_width, video_height;
   gint disp_x, disp_y;
   gint disp_width, disp_height;
@@ -2208,23 +1681,28 @@ gst_xvimagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
    * doesn't cover the same area */
   xvimagesink->redraw_border = TRUE;
 
-  /* We renew our xvimage only if size or format changed;
-   * the xvimage is the same size as the video pixel size */
-  if ((xvimagesink->xvimage) &&
-      ((im_format != xvimagesink->xvimage->im_format) ||
-          (video_width != xvimagesink->xvimage->width) ||
-          (video_height != xvimagesink->xvimage->height))) {
-    GST_DEBUG_OBJECT (xvimagesink,
-        "old format %" GST_FOURCC_FORMAT ", new format %" GST_FOURCC_FORMAT,
-        GST_FOURCC_ARGS (xvimagesink->xvimage->im_format),
-        GST_FOURCC_ARGS (im_format));
-    GST_DEBUG_OBJECT (xvimagesink, "renewing xvimage");
-    gst_buffer_unref (GST_BUFFER (xvimagesink->xvimage));
-    xvimagesink->xvimage = NULL;
-  }
+  /* create a new pool for the new configuration */
+  newpool = gst_xvimage_buffer_pool_new (xvimagesink);
+
+  structure = gst_buffer_pool_get_config (newpool);
+  gst_buffer_pool_config_set (structure, caps, 0, 0, 0, 0, 0, 16);
+  if (!gst_buffer_pool_set_config (newpool, structure))
+    goto config_failed;
+
+  if (!gst_buffer_pool_set_active (newpool, TRUE))
+    goto activate_failed;
 
+  oldpool = xvimagesink->pool;
+  xvimagesink->pool = newpool;
   g_mutex_unlock (xvimagesink->flow_lock);
 
+  /* unref the old sink */
+  if (oldpool) {
+    /* deactivate */
+    gst_buffer_pool_set_active (oldpool, FALSE);
+    gst_object_unref (oldpool);
+  }
+
   return TRUE;
 
   /* ERRORS */
@@ -2257,6 +1735,19 @@ no_display_size:
         ("Error calculating the output display ratio of the video."));
     return FALSE;
   }
+config_failed:
+  {
+    GST_ERROR_OBJECT (xvimagesink, "failed to set config.");
+    g_mutex_unlock (xvimagesink->flow_lock);
+    return FALSE;
+  }
+activate_failed:
+  {
+    GST_ERROR_OBJECT (xvimagesink, "failed to activate bufferpool.");
+    g_mutex_unlock (xvimagesink->flow_lock);
+    gst_object_unref (newpool);
+    return FALSE;
+  }
 }
 
 static GstStateChangeReturn
@@ -2273,8 +1764,10 @@ gst_xvimagesink_change_state (GstElement * element, GstStateChange transition)
       /* Initializing the XContext */
       if (xvimagesink->xcontext == NULL) {
         xcontext = gst_xvimagesink_xcontext_get (xvimagesink);
-        if (xcontext == NULL)
-          return GST_STATE_CHANGE_FAILURE;
+        if (xcontext == NULL) {
+          ret = GST_STATE_CHANGE_FAILURE;
+          goto beach;
+        }
         GST_OBJECT_LOCK (xvimagesink);
         if (xcontext)
           xvimagesink->xcontext = xcontext;
@@ -2295,16 +1788,10 @@ gst_xvimagesink_change_state (GstElement * element, GstStateChange transition)
       gst_xvimagesink_manage_event_thread (xvimagesink);
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
-      g_mutex_lock (xvimagesink->pool_lock);
-      xvimagesink->pool_invalid = FALSE;
-      g_mutex_unlock (xvimagesink->pool_lock);
       break;
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
       break;
     case GST_STATE_CHANGE_PAUSED_TO_READY:
-      g_mutex_lock (xvimagesink->pool_lock);
-      xvimagesink->pool_invalid = TRUE;
-      g_mutex_unlock (xvimagesink->pool_lock);
       break;
     default:
       break;
@@ -2320,6 +1807,10 @@ gst_xvimagesink_change_state (GstElement * element, GstStateChange transition)
       xvimagesink->fps_d = 1;
       GST_VIDEO_SINK_WIDTH (xvimagesink) = 0;
       GST_VIDEO_SINK_HEIGHT (xvimagesink) = 0;
+      g_mutex_lock (xvimagesink->flow_lock);
+      if (xvimagesink->pool)
+        gst_buffer_pool_set_active (xvimagesink->pool, FALSE);
+      g_mutex_unlock (xvimagesink->flow_lock);
       break;
     case GST_STATE_CHANGE_READY_TO_NULL:
       gst_xvimagesink_reset (xvimagesink);
@@ -2328,6 +1819,7 @@ gst_xvimagesink_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
+beach:
   return ret;
 }
 
@@ -2356,66 +1848,89 @@ gst_xvimagesink_get_times (GstBaseSink * bsink, GstBuffer * buf,
 static GstFlowReturn
 gst_xvimagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
 {
+  GstFlowReturn res;
   GstXvImageSink *xvimagesink;
+  GstMetaXvImage *meta;
+  GstBuffer *to_put;
 
   xvimagesink = GST_XVIMAGESINK (vsink);
 
-  /* If this buffer has been allocated using our buffer management we simply
-     put the ximage which is in the PRIVATE pointer */
-  if (GST_IS_XVIMAGE_BUFFER (buf)) {
-    GST_LOG_OBJECT (xvimagesink, "fast put of bufferpool buffer %p", buf);
-    if (!gst_xvimagesink_xvimage_put (xvimagesink,
-            GST_XVIMAGE_BUFFER_CAST (buf)))
-      goto no_window;
+  meta = gst_buffer_get_meta_xvimage (buf);
+
+  if (meta) {
+    /* If this buffer has been allocated using our buffer management we simply
+       put the ximage which is in the PRIVATE pointer */
+    GST_LOG_OBJECT (xvimagesink, "buffer %p from our pool, writing directly",
+        buf);
+    res = GST_FLOW_OK;
+    to_put = buf;
   } else {
-    GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, xvimagesink,
-        "slow copy into bufferpool buffer %p", buf);
+    guint8 *data;
+    gsize size;
+
     /* Else we have to copy the data into our private image, */
     /* if we have one... */
-    if (!xvimagesink->xvimage) {
-      GST_DEBUG_OBJECT (xvimagesink, "creating our xvimage");
+    GST_LOG_OBJECT (xvimagesink, "buffer %p not from our pool, copying", buf);
 
-      xvimagesink->xvimage = gst_xvimagesink_xvimage_new (xvimagesink,
-          GST_BUFFER_CAPS (buf));
+    /* we should have a pool, configured in setcaps */
+    if (xvimagesink->pool == NULL)
+      goto no_pool;
 
-      if (!xvimagesink->xvimage)
-        /* The create method should have posted an informative error */
-        goto no_image;
+    /* take a buffer form our pool */
+    res = gst_buffer_pool_acquire_buffer (xvimagesink->pool, &to_put, NULL);
+    if (res != GST_FLOW_OK)
+      goto no_buffer;
 
-      if (xvimagesink->xvimage->size < GST_BUFFER_SIZE (buf)) {
-        GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
-            ("Failed to create output image buffer of %dx%d pixels",
-                xvimagesink->xvimage->width, xvimagesink->xvimage->height),
-            ("XServer allocated buffer size did not match input buffer"));
+    if (gst_buffer_get_size (to_put) < gst_buffer_get_size (buf))
+      goto wrong_size;
 
-        gst_xvimage_buffer_destroy (xvimagesink->xvimage);
-        xvimagesink->xvimage = NULL;
-        goto no_image;
-      }
-    }
-
-    memcpy (xvimagesink->xvimage->xvimage->data,
-        GST_BUFFER_DATA (buf),
-        MIN (GST_BUFFER_SIZE (buf), xvimagesink->xvimage->size));
+    GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, xvimagesink,
+        "slow copy into bufferpool buffer %p", to_put);
 
-    if (!gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->xvimage))
-      goto no_window;
+    data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+    gst_buffer_fill (to_put, 0, data, size);
+    gst_buffer_unmap (buf, data, size);
   }
 
-  return GST_FLOW_OK;
+  if (!gst_xvimagesink_xvimage_put (xvimagesink, to_put))
+    goto no_window;
+
+done:
+  if (to_put != buf)
+    gst_buffer_unref (to_put);
+
+  return res;
 
   /* ERRORS */
-no_image:
+no_pool:
+  {
+    GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
+        ("Internal error: can't allocate images"),
+        ("We don't have a bufferpool negotiated"));
+    return GST_FLOW_ERROR;
+  }
+no_buffer:
   {
     /* No image available. That's very bad ! */
     GST_WARNING_OBJECT (xvimagesink, "could not create image");
-    return GST_FLOW_ERROR;
+    return res;
+  }
+wrong_size:
+  {
+    GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
+        ("Failed to create output image buffer"),
+        ("XServer allocated buffer size did not match input buffer %"
+            G_GSIZE_FORMAT " - %" G_GSIZE_FORMAT, gst_buffer_get_size (to_put),
+            gst_buffer_get_size (buf)));
+    res = GST_FLOW_ERROR;
+    goto done;
   }
 no_window:
   {
     /* No Window available to put our image into */
     GST_WARNING_OBJECT (xvimagesink, "could not output image - no window");
-    return GST_FLOW_ERROR;
+    res = GST_FLOW_ERROR;
+    goto done;
   }
 }
 
@@ -2450,271 +1965,93 @@ gst_xvimagesink_event (GstBaseSink * sink, GstEvent * event)
     return TRUE;
 }
 
-/* Buffer management */
-
-static GstCaps *
-gst_xvimage_sink_different_size_suggestion (GstXvImageSink * xvimagesink,
-    GstCaps * caps)
-{
-  GstCaps *intersection;
-  GstCaps *new_caps;
-  GstStructure *s;
-  gint width, height;
-  gint par_n = 1, par_d = 1;
-  gint dar_n, dar_d;
-  gint w, h;
-
-  new_caps = gst_caps_copy (caps);
-
-  s = gst_caps_get_structure (new_caps, 0);
-
-  gst_structure_get_int (s, "width", &width);
-  gst_structure_get_int (s, "height", &height);
-  gst_structure_get_fraction (s, "pixel-aspect-ratio", &par_n, &par_d);
-
-  gst_structure_remove_field (s, "width");
-  gst_structure_remove_field (s, "height");
-  gst_structure_remove_field (s, "pixel-aspect-ratio");
-
-  intersection = gst_caps_intersect (xvimagesink->xcontext->caps, new_caps);
-  gst_caps_unref (new_caps);
-
-  if (gst_caps_is_empty (intersection))
-    return intersection;
-
-  s = gst_caps_get_structure (intersection, 0);
-
-  gst_util_fraction_multiply (width, height, par_n, par_d, &dar_n, &dar_d);
-
-  /* xvimagesink supports all PARs */
-
-  gst_structure_fixate_field_nearest_int (s, "width", width);
-  gst_structure_fixate_field_nearest_int (s, "height", height);
-  gst_structure_get_int (s, "width", &w);
-  gst_structure_get_int (s, "height", &h);
-
-  gst_util_fraction_multiply (h, w, dar_n, dar_d, &par_n, &par_d);
-  gst_structure_set (s, "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d,
-      NULL);
-
-  return intersection;
-}
-
-static GstFlowReturn
-gst_xvimagesink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buf)
+static gboolean
+gst_xvimagesink_sink_query (GstPad * sinkpad, GstQuery * query)
 {
-  GstFlowReturn ret = GST_FLOW_OK;
-  GstXvImageSink *xvimagesink;
-  GstXvImageBuffer *xvimage = NULL;
-  GstCaps *intersection = NULL;
-  GstStructure *structure = NULL;
-  gint width, height, image_format;
-
-  xvimagesink = GST_XVIMAGESINK (bsink);
+  GstXvImageSink *xvimagesink = GST_XVIMAGESINK (GST_PAD_PARENT (sinkpad));
+  gboolean res = TRUE;
 
-  if (G_UNLIKELY (!caps))
-    goto no_caps;
-
-  g_mutex_lock (xvimagesink->pool_lock);
-  if (G_UNLIKELY (xvimagesink->pool_invalid))
-    goto invalid;
-
-  if (G_LIKELY (xvimagesink->xcontext->last_caps &&
-          gst_caps_is_equal (caps, xvimagesink->xcontext->last_caps))) {
-    GST_LOG_OBJECT (xvimagesink,
-        "buffer alloc for same last_caps, reusing caps");
-    intersection = gst_caps_ref (caps);
-    image_format = xvimagesink->xcontext->last_format;
-    width = xvimagesink->xcontext->last_width;
-    height = xvimagesink->xcontext->last_height;
-
-    goto reuse_last_caps;
-  }
-
-  GST_DEBUG_OBJECT (xvimagesink, "buffer alloc requested size %d with caps %"
-      GST_PTR_FORMAT ", intersecting with our caps %" GST_PTR_FORMAT, size,
-      caps, xvimagesink->xcontext->caps);
-
-  /* Check the caps against our xcontext */
-  intersection = gst_caps_intersect (xvimagesink->xcontext->caps, caps);
-
-  GST_DEBUG_OBJECT (xvimagesink, "intersection in buffer alloc returned %"
-      GST_PTR_FORMAT, intersection);
-
-  if (gst_caps_is_empty (intersection)) {
-    GstCaps *new_caps;
-
-    gst_caps_unref (intersection);
-
-    /* So we don't support this kind of buffer, let's define one we'd like */
-    new_caps = gst_caps_copy (caps);
-
-    structure = gst_caps_get_structure (new_caps, 0);
-    if (!gst_structure_has_field (structure, "width") ||
-        !gst_structure_has_field (structure, "height")) {
-      gst_caps_unref (new_caps);
-      goto invalid;
-    }
-
-    /* Try different dimensions */
-    intersection =
-        gst_xvimage_sink_different_size_suggestion (xvimagesink, new_caps);
-
-    if (gst_caps_is_empty (intersection)) {
-      /* Try with different YUV formats first */
-      gst_structure_set_name (structure, "video/x-raw-yuv");
-
-      /* Remove format specific fields */
-      gst_structure_remove_field (structure, "format");
-      gst_structure_remove_field (structure, "endianness");
-      gst_structure_remove_field (structure, "depth");
-      gst_structure_remove_field (structure, "bpp");
-      gst_structure_remove_field (structure, "red_mask");
-      gst_structure_remove_field (structure, "green_mask");
-      gst_structure_remove_field (structure, "blue_mask");
-      gst_structure_remove_field (structure, "alpha_mask");
-
-      /* Reuse intersection with Xcontext */
-      intersection = gst_caps_intersect (xvimagesink->xcontext->caps, new_caps);
-    }
-
-    if (gst_caps_is_empty (intersection)) {
-      /* Try with different dimensions and YUV formats */
-      intersection =
-          gst_xvimage_sink_different_size_suggestion (xvimagesink, new_caps);
-    }
-
-    if (gst_caps_is_empty (intersection)) {
-      /* Now try with RGB */
-      gst_structure_set_name (structure, "video/x-raw-rgb");
-      /* And interset again */
-      gst_caps_unref (intersection);
-      intersection = gst_caps_intersect (xvimagesink->xcontext->caps, new_caps);
-    }
-
-    if (gst_caps_is_empty (intersection)) {
-      /* Try with different dimensions and RGB formats */
-      intersection =
-          gst_xvimage_sink_different_size_suggestion (xvimagesink, new_caps);
-    }
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_ALLOCATION:
+    {
+      GstBufferPool *pool;
+      GstStructure *config;
+      GstCaps *caps;
+      guint size;
+      gboolean need_pool;
 
-    /* Clean this copy */
-    gst_caps_unref (new_caps);
+      gst_query_parse_allocation (query, &caps, &need_pool);
 
-    if (gst_caps_is_empty (intersection))
-      goto incompatible;
-  }
+      if (caps == NULL)
+        goto no_caps;
 
-  /* Ensure the returned caps are fixed */
-  gst_caps_truncate (intersection);
-
-  GST_DEBUG_OBJECT (xvimagesink, "allocating a buffer with caps %"
-      GST_PTR_FORMAT, intersection);
-  if (gst_caps_is_equal (intersection, caps)) {
-    /* Things work better if we return a buffer with the same caps ptr
-     * as was asked for when we can */
-    gst_caps_replace (&intersection, caps);
-  }
+      g_mutex_lock (xvimagesink->flow_lock);
+      if ((pool = xvimagesink->pool))
+        gst_object_ref (pool);
+      g_mutex_unlock (xvimagesink->flow_lock);
 
-  /* Get image format from caps */
-  image_format = gst_xvimagesink_get_format_from_caps (xvimagesink,
-      intersection);
+      if (pool != NULL) {
+        const GstCaps *pcaps;
 
-  /* Get geometry from caps */
-  structure = gst_caps_get_structure (intersection, 0);
-  if (!gst_structure_get_int (structure, "width", &width) ||
-      !gst_structure_get_int (structure, "height", &height) ||
-      image_format == -1)
-    goto invalid_caps;
+        /* we had a pool, check caps */
+        config = gst_buffer_pool_get_config (pool);
+        gst_buffer_pool_config_get (config, &pcaps, &size, NULL, NULL, NULL,
+            NULL, NULL);
 
-  /* Store our caps and format as the last_caps to avoid expensive
-   * caps intersection next time */
-  gst_caps_replace (&xvimagesink->xcontext->last_caps, intersection);
-  xvimagesink->xcontext->last_format = image_format;
-  xvimagesink->xcontext->last_width = width;
-  xvimagesink->xcontext->last_height = height;
+        if (!gst_caps_is_equal (caps, pcaps)) {
+          GST_DEBUG_OBJECT (xvimagesink, "pool has different caps");
+          /* different caps, we can't use this pool */
+          gst_object_unref (pool);
+          pool = NULL;
+        }
+      }
+      if (pool == NULL && need_pool) {
+        GstVideoFormat format;
+        gint width, height;
 
-reuse_last_caps:
+        GST_DEBUG_OBJECT (xvimagesink, "create new pool");
+        pool = gst_xvimage_buffer_pool_new (xvimagesink);
 
-  /* Walking through the pool cleaning unusable images and searching for a
-     suitable one */
-  while (xvimagesink->image_pool) {
-    xvimage = xvimagesink->image_pool->data;
+        if (!gst_video_format_parse_caps (caps, &format, &width, &height))
+          goto invalid_caps;
 
-    if (xvimage) {
-      /* Removing from the pool */
-      xvimagesink->image_pool = g_slist_delete_link (xvimagesink->image_pool,
-          xvimagesink->image_pool);
+        /* the normal size of a frame */
+        size = gst_video_format_get_size (format, width, height);
 
-      /* We check for geometry or image format changes */
-      if ((xvimage->width != width) ||
-          (xvimage->height != height) || (xvimage->im_format != image_format)) {
-        /* This image is unusable. Destroying... */
-        gst_xvimage_buffer_free (xvimage);
-        xvimage = NULL;
-      } else {
-        /* We found a suitable image */
-        GST_LOG_OBJECT (xvimagesink, "found usable image in pool");
-        break;
+        config = gst_buffer_pool_get_config (pool);
+        gst_buffer_pool_config_set (config, caps, size, 0, 0, 0, 0, 16);
+        if (!gst_buffer_pool_set_config (pool, config))
+          goto config_failed;
       }
-    }
-  }
+      gst_query_set_allocation_params (query, size, 0, 0, 0, 16, pool);
 
-  if (!xvimage) {
-    /* We found no suitable image in the pool. Creating... */
-    GST_DEBUG_OBJECT (xvimagesink, "no usable image in pool, creating xvimage");
-    xvimage = gst_xvimagesink_xvimage_new (xvimagesink, intersection);
-  }
-  g_mutex_unlock (xvimagesink->pool_lock);
-
-  if (xvimage) {
-    /* Make sure the buffer is cleared of any previously used flags */
-    GST_MINI_OBJECT_CAST (xvimage)->flags = 0;
-    gst_buffer_set_caps (GST_BUFFER_CAST (xvimage), intersection);
-  }
+      /* we also support various metadata */
+      gst_query_add_allocation_meta (query, GST_META_API_VIDEO);
 
-  *buf = GST_BUFFER_CAST (xvimage);
-
-beach:
-  if (intersection) {
-    gst_caps_unref (intersection);
+      gst_object_unref (pool);
+      break;
+    }
+    default:
+      res = FALSE;
+      break;
   }
-
-  return ret;
+  return res;
 
   /* ERRORS */
-invalid:
-  {
-    GST_DEBUG_OBJECT (xvimagesink, "the pool is flushing");
-    ret = GST_FLOW_WRONG_STATE;
-    g_mutex_unlock (xvimagesink->pool_lock);
-    goto beach;
-  }
-incompatible:
+no_caps:
   {
-    GST_WARNING_OBJECT (xvimagesink, "we were requested a buffer with "
-        "caps %" GST_PTR_FORMAT ", but our xcontext caps %" GST_PTR_FORMAT
-        " are completely incompatible with those caps", caps,
-        xvimagesink->xcontext->caps);
-    ret = GST_FLOW_NOT_NEGOTIATED;
-    g_mutex_unlock (xvimagesink->pool_lock);
-    goto beach;
+    GST_DEBUG_OBJECT (sinkpad, "no caps specified");
+    return FALSE;
   }
 invalid_caps:
   {
-    GST_WARNING_OBJECT (xvimagesink, "invalid caps for buffer allocation %"
-        GST_PTR_FORMAT, intersection);
-    ret = GST_FLOW_NOT_NEGOTIATED;
-    g_mutex_unlock (xvimagesink->pool_lock);
-    goto beach;
+    GST_DEBUG_OBJECT (sinkpad, "invalid caps specified");
+    return FALSE;
   }
-no_caps:
+config_failed:
   {
-    GST_WARNING_OBJECT (xvimagesink, "have no caps, doing fallback allocation");
-    *buf = NULL;
-    ret = GST_FLOW_OK;
-    goto beach;
+    GST_DEBUG_OBJECT (sinkpad, "failed setting config");
+    return FALSE;
   }
 }
 
@@ -2830,15 +2167,6 @@ gst_xvimagesink_set_window_handle (GstXOverlay * overlay, guintptr id)
 
   gst_xvimagesink_update_colorbalance (xvimagesink);
 
-  /* Clear image pool as the images are unusable anyway */
-  gst_xvimagesink_imagepool_clear (xvimagesink);
-
-  /* Clear the xvimage */
-  if (xvimagesink->xvimage) {
-    gst_xvimage_buffer_free (xvimagesink->xvimage);
-    xvimagesink->xvimage = NULL;
-  }
-
   /* If a window is there already we destroy it */
   if (xvimagesink->xwindow) {
     gst_xvimagesink_xwindow_destroy (xvimagesink, xvimagesink->xwindow);
@@ -2897,6 +2225,7 @@ gst_xvimagesink_expose (GstXOverlay * overlay)
 {
   GstXvImageSink *xvimagesink = GST_XVIMAGESINK (overlay);
 
+  GST_DEBUG ("doing expose");
   gst_xvimagesink_xwindow_update_geometry (xvimagesink);
   gst_xvimagesink_xvimage_put (xvimagesink, NULL);
 }
@@ -3402,32 +2731,28 @@ gst_xvimagesink_reset (GstXvImageSink * xvimagesink)
   xvimagesink->event_thread = NULL;
   GST_OBJECT_UNLOCK (xvimagesink);
 
-  /* invalidate the pool, current allocations continue, new buffer_alloc fails
-   * with wrong_state */
-  g_mutex_lock (xvimagesink->pool_lock);
-  xvimagesink->pool_invalid = TRUE;
-  g_mutex_unlock (xvimagesink->pool_lock);
-
   /* Wait for our event thread to finish before we clean up our stuff. */
   if (thread)
     g_thread_join (thread);
 
   if (xvimagesink->cur_image) {
-    gst_buffer_unref (GST_BUFFER_CAST (xvimagesink->cur_image));
+    gst_buffer_unref (xvimagesink->cur_image);
     xvimagesink->cur_image = NULL;
   }
-  if (xvimagesink->xvimage) {
-    gst_buffer_unref (GST_BUFFER_CAST (xvimagesink->xvimage));
-    xvimagesink->xvimage = NULL;
-  }
 
-  gst_xvimagesink_imagepool_clear (xvimagesink);
+  g_mutex_lock (xvimagesink->flow_lock);
+
+  if (xvimagesink->pool) {
+    gst_object_unref (xvimagesink->pool);
+    xvimagesink->pool = NULL;
+  }
 
   if (xvimagesink->xwindow) {
     gst_xvimagesink_xwindow_clear (xvimagesink, xvimagesink->xwindow);
     gst_xvimagesink_xwindow_destroy (xvimagesink, xvimagesink->xwindow);
     xvimagesink->xwindow = NULL;
   }
+  g_mutex_unlock (xvimagesink->flow_lock);
 
   xvimagesink->render_rect.x = xvimagesink->render_rect.y =
       xvimagesink->render_rect.w = xvimagesink->render_rect.h = 0;
@@ -3465,10 +2790,6 @@ gst_xvimagesink_finalize (GObject * object)
     g_mutex_free (xvimagesink->flow_lock);
     xvimagesink->flow_lock = NULL;
   }
-  if (xvimagesink->pool_lock) {
-    g_mutex_free (xvimagesink->pool_lock);
-    xvimagesink->pool_lock = NULL;
-  }
 
   g_free (xvimagesink->media_title);
 
@@ -3476,13 +2797,16 @@ gst_xvimagesink_finalize (GObject * object)
 }
 
 static void
-gst_xvimagesink_init (GstXvImageSink * xvimagesink, GstXvImageSinkClass *xvimagesinkclass)
+gst_xvimagesink_init (GstXvImageSink * xvimagesink)
 {
+  /* for the ALLOCATION query */
+  gst_pad_set_query_function (GST_BASE_SINK (xvimagesink)->sinkpad,
+      gst_xvimagesink_sink_query);
+
   xvimagesink->display_name = NULL;
   xvimagesink->adaptor_no = 0;
   xvimagesink->xcontext = NULL;
   xvimagesink->xwindow = NULL;
-  xvimagesink->xvimage = NULL;
   xvimagesink->cur_image = NULL;
 
   xvimagesink->hue = xvimagesink->saturation = 0;
@@ -3497,8 +2821,7 @@ gst_xvimagesink_init (GstXvImageSink * xvimagesink, GstXvImageSinkClass *xvimage
   xvimagesink->x_lock = g_mutex_new ();
   xvimagesink->flow_lock = g_mutex_new ();
 
-  xvimagesink->image_pool = NULL;
-  xvimagesink->pool_lock = g_mutex_new ();
+  xvimagesink->pool = NULL;
 
   xvimagesink->synchronous = FALSE;
   xvimagesink->double_buffer = TRUE;
@@ -3518,19 +2841,6 @@ gst_xvimagesink_init (GstXvImageSink * xvimagesink, GstXvImageSinkClass *xvimage
 }
 
 static void
-gst_xvimagesink_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class,
-      "Video sink", "Sink/Video",
-      "A Xv based videosink", "Julien Moutte <julien@moutte.net>");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_xvimagesink_sink_template_factory));
-}
-
-static void
 gst_xvimagesink_class_init (GstXvImageSinkClass * klass)
 {
   GObjectClass *gobject_class;
@@ -3543,6 +2853,8 @@ gst_xvimagesink_class_init (GstXvImageSinkClass * klass)
   gstbasesink_class = (GstBaseSinkClass *) klass;
   videosink_class = (GstVideoSinkClass *) klass;
 
+  parent_class = g_type_class_peek_parent (klass);
+
   gobject_class->set_property = gst_xvimagesink_set_property;
   gobject_class->get_property = gst_xvimagesink_get_property;
 
@@ -3675,92 +2987,20 @@ gst_xvimagesink_class_init (GstXvImageSinkClass * klass)
 
   gobject_class->finalize = gst_xvimagesink_finalize;
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "Video sink", "Sink/Video",
+      "A Xv based videosink", "Julien Moutte <julien@moutte.net>");
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_xvimagesink_sink_template_factory));
+
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_xvimagesink_change_state);
 
   gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_xvimagesink_getcaps);
   gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_xvimagesink_setcaps);
-  gstbasesink_class->buffer_alloc =
-      GST_DEBUG_FUNCPTR (gst_xvimagesink_buffer_alloc);
   gstbasesink_class->get_times = GST_DEBUG_FUNCPTR (gst_xvimagesink_get_times);
   gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_xvimagesink_event);
 
   videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_xvimagesink_show_frame);
 }
-
-/* ============================================================= */
-/*                                                               */
-/*                       Public Methods                          */
-/*                                                               */
-/* ============================================================= */
-
-/* =========================================== */
-/*                                             */
-/*          Object typing & Creation           */
-/*                                             */
-/* =========================================== */
-static void
-gst_xvimagesink_init_interfaces (GType type)
-{
-   static const GInterfaceInfo iface_info = {
-      (GInterfaceInitFunc) gst_xvimagesink_interface_init,
-      NULL,
-      NULL,
-    };
-    static const GInterfaceInfo navigation_info = {
-      (GInterfaceInitFunc) gst_xvimagesink_navigation_init,
-      NULL,
-      NULL,
-    };
-    static const GInterfaceInfo overlay_info = {
-      (GInterfaceInitFunc) gst_xvimagesink_xoverlay_init,
-      NULL,
-      NULL,
-    };
-    static const GInterfaceInfo colorbalance_info = {
-      (GInterfaceInitFunc) gst_xvimagesink_colorbalance_init,
-      NULL,
-      NULL,
-    };
-    static const GInterfaceInfo propertyprobe_info = {
-      (GInterfaceInitFunc) gst_xvimagesink_property_probe_interface_init,
-      NULL,
-      NULL,
-  };
-
-   g_type_add_interface_static (type,
-        GST_TYPE_IMPLEMENTS_INTERFACE, &iface_info);
-   g_type_add_interface_static (type, GST_TYPE_NAVIGATION,
-        &navigation_info);
-   g_type_add_interface_static (type, GST_TYPE_X_OVERLAY,
-        &overlay_info);
-   g_type_add_interface_static (type, GST_TYPE_COLOR_BALANCE,
-        &colorbalance_info);
-   g_type_add_interface_static (type, GST_TYPE_PROPERTY_PROBE,
-        &propertyprobe_info);
-
-   /* register type and create class in a more safe place instead of at
-    * runtime since the type registration and class creation is not
-    * threadsafe. */
-   g_type_class_ref (gst_xvimage_buffer_get_type ());
-}
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
-  if (!gst_element_register (plugin, "xvimagesink",
-          GST_RANK_PRIMARY, GST_TYPE_XVIMAGESINK))
-    return FALSE;
-
-  GST_DEBUG_CATEGORY_INIT (gst_debug_xvimagesink, "xvimagesink", 0,
-      "xvimagesink element");
-  GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
-
-  return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
-    GST_VERSION_MINOR,
-    "xvimagesink",
-    "XFree86 video output plugin using Xv extension",
-    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
index 0181018..4531cf3 100644 (file)
@@ -43,7 +43,6 @@
 #include <stdlib.h>
 
 G_BEGIN_DECLS
-
 #define GST_TYPE_XVIMAGESINK \
   (gst_xvimagesink_get_type())
 #define GST_XVIMAGESINK(obj) \
@@ -54,16 +53,15 @@ G_BEGIN_DECLS
   (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_XVIMAGESINK))
 #define GST_IS_XVIMAGESINK_CLASS(klass) \
   (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_XVIMAGESINK))
-
 typedef struct _GstXContext GstXContext;
 typedef struct _GstXWindow GstXWindow;
 typedef struct _GstXvImageFormat GstXvImageFormat;
-typedef struct _GstXvImageBuffer GstXvImageBuffer;
-typedef struct _GstXvImageBufferClass GstXvImageBufferClass;
 
 typedef struct _GstXvImageSink GstXvImageSink;
 typedef struct _GstXvImageSinkClass GstXvImageSinkClass;
 
+#include "xvimagepool.h"
+
 /*
  * GstXContext:
  * @disp: the X11 Display of this context
@@ -93,7 +91,8 @@ typedef struct _GstXvImageSinkClass GstXvImageSinkClass;
  * Structure used to store various informations collected/calculated for a
  * Display.
  */
-struct _GstXContext {
+struct _GstXContext
+{
   Display *disp;
 
   Screen *screen;
@@ -117,7 +116,7 @@ struct _GstXContext {
 
   XvPortID xv_port_id;
   guint nb_adaptors;
-  gchar ** adaptors;
+  gchar **adaptors;
   gint im_format;
 
   GList *formats_list;
@@ -143,7 +142,8 @@ struct _GstXContext {
  *
  * Structure used to store informations about a Window.
  */
-struct _GstXWindow {
+struct _GstXWindow
+{
   Window win;
   gint width, height;
   gboolean internal;
@@ -157,45 +157,18 @@ struct _GstXWindow {
  *
  * Structure storing image format to #GstCaps association.
  */
-struct _GstXvImageFormat {
+struct _GstXvImageFormat
+{
   gint format;
   GstCaps *caps;
 };
 
-/**
- * GstXImageBuffer:
- * @xvimagesink: a reference to our #GstXvImageSink
- * @xvimage: the XvImage of this buffer
- * @width: the width in pixels of XvImage @xvimage
- * @height: the height in pixels of XvImage @xvimage
- * @im_format: the image format of XvImage @xvimage
- * @size: the size in bytes of XvImage @xvimage
- *
- * Subclass of #GstBuffer containing additional information about an XvImage.
- */
-struct _GstXvImageBuffer {
-  GstBuffer   buffer;
-
-  /* Reference to the xvimagesink we belong to */
-  GstXvImageSink *xvimagesink;
-
-  XvImage *xvimage;
-
-#ifdef HAVE_XSHM
-  XShmSegmentInfo SHMInfo;
-#endif /* HAVE_XSHM */
-
-  gint width, height, im_format;
-  size_t size;
-};
 
 /**
  * GstXvImageSink:
  * @display_name: the name of the Display we want to render to
  * @xcontext: our instance's #GstXContext
  * @xwindow: the #GstXWindow we are rendering to
- * @xvimage: internal #GstXvImage used to store incoming buffers and render when
- * not using the buffer_alloc optimization mechanism
  * @cur_image: a reference to the last #GstXvImage that was put to @xwindow. It
  * is used when Expose events are received to redraw the latest video frame
  * @event_thread: a thread listening for events on @xwindow and handling them
@@ -225,7 +198,8 @@ struct _GstXvImageBuffer {
  *
  * The #GstXvImageSink data structure.
  */
-struct _GstXvImageSink {
+struct _GstXvImageSink
+{
   /* Our element stuff */
   GstVideoSink videosink;
 
@@ -234,12 +208,12 @@ struct _GstXvImageSink {
 
   GstXContext *xcontext;
   GstXWindow *xwindow;
-  GstXvImageBuffer *xvimage;
-  GstXvImageBuffer *cur_image;
+  GstBuffer *cur_image;
 
   GThread *event_thread;
   gboolean running;
 
+  /* Framerate numerator and denominator */
   gint fps_n;
   gint fps_d;
 
@@ -249,9 +223,8 @@ struct _GstXvImageSink {
   /* object-set pixel aspect ratio */
   GValue *par;
 
-  GMutex *pool_lock;
-  gboolean pool_invalid;
-  GSList *image_pool;
+  /* the buffer pool */
+  GstBufferPool *pool;
 
   gboolean synchronous;
   gboolean double_buffer;
@@ -276,14 +249,14 @@ struct _GstXvImageSink {
   /* port attributes */
   gboolean autopaint_colorkey;
   gint colorkey;
-  
+
   gboolean draw_borders;
-  
+
   /* port features */
   gboolean have_autopaint_colorkey;
   gboolean have_colorkey;
   gboolean have_double_buffer;
-  
+
   /* stream metadata */
   gchar *media_title;
 
@@ -292,12 +265,12 @@ struct _GstXvImageSink {
   gboolean have_render_rect;
 };
 
-struct _GstXvImageSinkClass {
+struct _GstXvImageSinkClass
+{
   GstVideoSinkClass parent_class;
 };
 
-GType gst_xvimagesink_get_type(void);
+GType gst_xvimagesink_get_type (void);
 
 G_END_DECLS
-
 #endif /* __GST_XVIMAGESINK_H__ */
index 34982ef..c26cb08 100644 (file)
@@ -198,10 +198,12 @@ GST_END_TEST;
 static GstBufferList *mylist;
 static GstCaps *mycaps;
 
+static gint values[] = { 1, 2, 4 };
+
 static GstBufferList *
 create_buffer_list (void)
 {
-  GstBufferListIterator *it;
+  guint len;
   GstBuffer *buffer;
 
   mylist = gst_buffer_list_new ();
@@ -210,29 +212,23 @@ create_buffer_list (void)
   mycaps = gst_caps_from_string ("application/x-gst-check");
   fail_if (mycaps == NULL);
 
-  it = gst_buffer_list_iterate (mylist);
-  fail_if (it == NULL);
-
-  gst_buffer_list_iterator_add_group (it);
+  len = gst_buffer_list_len (mylist);
+  fail_if (len != 0);
 
   buffer = gst_buffer_new_and_alloc (sizeof (gint));
-  *(gint *) GST_BUFFER_DATA (buffer) = 1;
+  gst_buffer_fill (buffer, 0, &values[0], sizeof (gint));
   gst_buffer_set_caps (buffer, mycaps);
-  gst_buffer_list_iterator_add (it, buffer);
-
-  gst_buffer_list_iterator_add_group (it);
+  gst_buffer_list_add (mylist, buffer);
 
   buffer = gst_buffer_new_and_alloc (sizeof (gint));
-  *(gint *) GST_BUFFER_DATA (buffer) = 2;
+  gst_buffer_fill (buffer, 0, &values[1], sizeof (gint));
   gst_buffer_set_caps (buffer, mycaps);
-  gst_buffer_list_iterator_add (it, buffer);
+  gst_buffer_list_add (mylist, buffer);
 
   buffer = gst_buffer_new_and_alloc (sizeof (gint));
-  *(gint *) GST_BUFFER_DATA (buffer) = 4;
+  gst_buffer_fill (buffer, 0, &values[2], sizeof (gint));
   gst_buffer_set_caps (buffer, mycaps);
-  gst_buffer_list_iterator_add (it, buffer);
-
-  gst_buffer_list_iterator_free (it);
+  gst_buffer_list_add (mylist, buffer);
 
   return mylist;
 }
@@ -240,43 +236,36 @@ create_buffer_list (void)
 static void
 check_buffer_list (GstBufferList * list)
 {
-  GstBufferListIterator *it;
+  guint len;
   GstBuffer *buf;
   GstCaps *caps;
 
   fail_unless (list == mylist);
-  fail_unless (gst_buffer_list_n_groups (list) == 2);
+  fail_unless (gst_buffer_list_len (list) == 3);
 
-  it = gst_buffer_list_iterate (list);
-  fail_if (it == NULL);
+  len = gst_buffer_list_len (list);
 
-  fail_unless (gst_buffer_list_iterator_next_group (it));
-  fail_unless (gst_buffer_list_iterator_n_buffers (it) == 1);
-  buf = gst_buffer_list_iterator_next (it);
+  buf = gst_buffer_list_get (list, 0);
   fail_if (buf == NULL);
-  fail_unless (*(gint *) GST_BUFFER_DATA (buf) == 1);
+  gst_check_buffer_data (buf, &values[0], sizeof (gint));
   caps = gst_buffer_get_caps (buf);
   fail_unless (caps == mycaps);
   fail_unless (gst_caps_is_equal (caps, mycaps));
   gst_caps_unref (caps);
 
-  fail_unless (gst_buffer_list_iterator_next_group (it));
-  fail_unless (gst_buffer_list_iterator_n_buffers (it) == 2);
-  buf = gst_buffer_list_iterator_next (it);
+  buf = gst_buffer_list_get (list, 1);
   fail_if (buf == NULL);
-  fail_unless (*(gint *) GST_BUFFER_DATA (buf) == 2);
+  gst_check_buffer_data (buf, &values[1], sizeof (gint));
   caps = gst_buffer_get_caps (buf);
   fail_unless (caps == mycaps);
   gst_caps_unref (caps);
 
-  buf = gst_buffer_list_iterator_next (it);
+  buf = gst_buffer_list_get (list, 2);
   fail_if (buf == NULL);
-  fail_unless (*(gint *) GST_BUFFER_DATA (buf) == 4);
+  gst_check_buffer_data (buf, &values[2], sizeof (gint));
   caps = gst_buffer_get_caps (buf);
   fail_unless (caps == mycaps);
   gst_caps_unref (caps);
-
-  gst_buffer_list_iterator_free (it);
 }
 
 static GstFlowReturn
@@ -329,13 +318,16 @@ callback_function_buffer (GstAppSink * appsink, gpointer p_counter)
   /* buffer list has 3 buffers in two groups */
   switch (*p_int_counter) {
     case 0:
-      fail_unless_equals_int (GST_BUFFER_SIZE (buf), sizeof (gint));
-      fail_unless_equals_int ((((gint *) GST_BUFFER_DATA (buf))[0]), 1);
+      fail_unless_equals_int (gst_buffer_get_size (buf), sizeof (gint));
+      gst_check_buffer_data (buf, &values[0], sizeof (gint));
       break;
     case 1:
-      fail_unless_equals_int (GST_BUFFER_SIZE (buf), 2 * sizeof (gint));
-      fail_unless_equals_int ((((gint *) GST_BUFFER_DATA (buf))[0]), 2);
-      fail_unless_equals_int ((((gint *) GST_BUFFER_DATA (buf))[1]), 4);
+      fail_unless_equals_int (gst_buffer_get_size (buf), sizeof (gint));
+      gst_check_buffer_data (buf, &values[1], sizeof (gint));
+      break;
+    case 2:
+      fail_unless_equals_int (gst_buffer_get_size (buf), sizeof (gint));
+      gst_check_buffer_data (buf, &values[2], sizeof (gint));
       break;
     default:
       g_warn_if_reached ();
@@ -367,7 +359,7 @@ GST_START_TEST (test_buffer_list_fallback)
   list = create_buffer_list ();
   fail_unless (gst_pad_push_list (mysrcpad, list) == GST_FLOW_OK);
 
-  fail_unless_equals_int (counter, 2);
+  fail_unless_equals_int (counter, 3);
 
   ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
   cleanup_appsink (sink);
@@ -394,7 +386,7 @@ GST_START_TEST (test_buffer_list_fallback_signal)
   list = create_buffer_list ();
   fail_unless (gst_pad_push_list (mysrcpad, list) == GST_FLOW_OK);
 
-  fail_unless_equals_int (counter, 2);
+  fail_unless_equals_int (counter, 3);
 
   ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
   cleanup_appsink (sink);
index b5e292d..caa9eb6 100644 (file)
@@ -449,7 +449,7 @@ verify_convert (const gchar * which, void *in, int inlength,
 
   GST_DEBUG ("Creating buffer of %d bytes", inlength);
   inbuffer = gst_buffer_new_and_alloc (inlength);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, inlength);
+  gst_buffer_fill (inbuffer, 0, in, inlength);
   gst_buffer_set_caps (inbuffer, incaps);
   ASSERT_CAPS_REFCOUNT (incaps, "incaps", 2);
   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
@@ -467,8 +467,10 @@ verify_convert (const gchar * which, void *in, int inlength,
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
 
   ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), outlength);
+  fail_unless_equals_int (gst_buffer_get_size (outbuffer), outlength);
 
+  gst_check_buffer_data (outbuffer, out, outlength);
+#if 0
   if (memcmp (GST_BUFFER_DATA (outbuffer), out, outlength) != 0) {
     g_print ("\nInput data:\n");
     gst_util_dump_mem (in, inlength);
@@ -479,6 +481,7 @@ verify_convert (const gchar * which, void *in, int inlength,
   }
   fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, outlength) == 0,
       "failed converting %s", which);
+#endif
 
   /* make sure that the channel positions are not lost */
   {
index 7845672..da45f87 100644 (file)
@@ -31,7 +31,7 @@ typedef GstElement TestInjector;
 typedef GstElementClass TestInjectorClass;
 
 GType test_injector_get_type (void);
-GST_BOILERPLATE (TestInjector, test_injector, GstElement, GST_TYPE_ELEMENT);
+G_DEFINE_TYPE (TestInjector, test_injector, GST_TYPE_ELEMENT);
 
 #define INJECTOR_CAPS \
   "audio/x-raw-float, "                                  \
@@ -58,9 +58,9 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_STATIC_CAPS (INJECTOR_CAPS));
 
 static void
-test_injector_base_init (gpointer g_class)
+test_injector_class_init (TestInjectorClass * klass)
 {
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&src_template));
@@ -68,12 +68,6 @@ test_injector_base_init (gpointer g_class)
       gst_static_pad_template_get (&sink_template));
 }
 
-static void
-test_injector_class_init (TestInjectorClass * klass)
-{
-  /* nothing to do here */
-}
-
 static GstFlowReturn
 test_injector_chain (GstPad * pad, GstBuffer * buf)
 {
@@ -146,7 +140,7 @@ test_injector_chain (GstPad * pad, GstBuffer * buf)
 }
 
 static void
-test_injector_init (TestInjector * injector, TestInjectorClass * klass)
+test_injector_init (TestInjector * injector)
 {
   GstPad *pad;
 
@@ -277,11 +271,12 @@ do_perfect_stream_test (guint rate, guint width, gdouble drop_probability,
     }
 
     /* check buffer size for sanity */
-    fail_unless_equals_int (GST_BUFFER_SIZE (buf) % (width / 8), 0);
+    fail_unless_equals_int (gst_buffer_get_size (buf) % (width / 8), 0);
 
     /* check there is actually as much data as there should be */
     num_samples = GST_BUFFER_OFFSET_END (buf) - GST_BUFFER_OFFSET (buf);
-    fail_unless_equals_int (GST_BUFFER_SIZE (buf), num_samples * (width / 8));
+    fail_unless_equals_int (gst_buffer_get_size (buf),
+        num_samples * (width / 8));
 
     next_time = GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
     next_offset = GST_BUFFER_OFFSET_END (buf);
index a8a79a3..8773538 100644 (file)
@@ -175,9 +175,8 @@ test_perfect_stream_instance (int inrate, int outrate, int samples,
   GstBuffer *inbuffer, *outbuffer;
   GstCaps *caps;
   guint64 offset = 0;
-
   int i, j;
-  gint16 *p;
+  gint16 *p, *data;
 
   audioresample = setup_audioresample (2, inrate, outrate, 16, FALSE);
   caps = gst_pad_get_negotiated_caps (mysrcpad);
@@ -198,7 +197,7 @@ test_perfect_stream_instance (int inrate, int outrate, int samples,
 
     gst_buffer_set_caps (inbuffer, caps);
 
-    p = (gint16 *) GST_BUFFER_DATA (inbuffer);
+    p = data = gst_buffer_map (inbuffer, NULL, NULL, GST_MAP_WRITE);
 
     /* create a 16 bit signed ramp */
     for (i = 0; i < samples; ++i) {
@@ -207,6 +206,7 @@ test_perfect_stream_instance (int inrate, int outrate, int samples,
       *p = -32767 + i * (65535 / samples);
       ++p;
     }
+    gst_buffer_unmap (inbuffer, data, samples * 4);
 
     /* pushing gives away my reference ... */
     fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
@@ -261,7 +261,7 @@ test_discont_stream_instance (int inrate, int outrate, int samples,
   GstClockTime ints;
 
   int i, j;
-  gint16 *p;
+  gint16 *p, *data;
 
   GST_DEBUG ("inrate:%d outrate:%d samples:%d numbuffers:%d",
       inrate, outrate, samples, numbuffers);
@@ -286,8 +286,7 @@ test_discont_stream_instance (int inrate, int outrate, int samples,
 
     gst_buffer_set_caps (inbuffer, caps);
 
-    p = (gint16 *) GST_BUFFER_DATA (inbuffer);
-
+    p = data = gst_buffer_map (inbuffer, NULL, NULL, GST_MAP_WRITE);
     /* create a 16 bit signed ramp */
     for (i = 0; i < samples; ++i) {
       *p = -32767 + i * (65535 / samples);
@@ -295,6 +294,7 @@ test_discont_stream_instance (int inrate, int outrate, int samples,
       *p = -32767 + i * (65535 / samples);
       ++p;
     }
+    gst_buffer_unmap (inbuffer, data, samples * 4);
 
     GST_DEBUG ("Sending Buffer time:%" G_GUINT64_FORMAT " duration:%"
         G_GINT64_FORMAT " discont:%d offset:%" G_GUINT64_FORMAT " offset_end:%"
@@ -351,6 +351,7 @@ GST_START_TEST (test_reuse)
   GstEvent *newseg;
   GstBuffer *inbuffer;
   GstCaps *caps;
+  guint8 *data;
 
   audioresample = setup_audioresample (1, 9343, 48000, 16, FALSE);
   caps = gst_pad_get_negotiated_caps (mysrcpad);
@@ -364,7 +365,9 @@ GST_START_TEST (test_reuse)
   fail_unless (gst_pad_push_event (mysrcpad, newseg) != FALSE);
 
   inbuffer = gst_buffer_new_and_alloc (9343 * 4);
-  memset (GST_BUFFER_DATA (inbuffer), 0, GST_BUFFER_SIZE (inbuffer));
+  data = gst_buffer_map (inbuffer, NULL, NULL, GST_MAP_WRITE);
+  memset (data, 0, 9343 * 4);
+  gst_buffer_unmap (inbuffer, data, 9343 * 4);
   GST_BUFFER_DURATION (inbuffer) = GST_SECOND;
   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
   GST_BUFFER_OFFSET (inbuffer) = 0;
@@ -388,7 +391,9 @@ GST_START_TEST (test_reuse)
   fail_unless (gst_pad_push_event (mysrcpad, newseg) != FALSE);
 
   inbuffer = gst_buffer_new_and_alloc (9343 * 4);
-  memset (GST_BUFFER_DATA (inbuffer), 0, GST_BUFFER_SIZE (inbuffer));
+  data = gst_buffer_map (inbuffer, NULL, NULL, GST_MAP_WRITE);
+  memset (data, 0, 9343 * 4);
+  gst_buffer_unmap (inbuffer, data, 9343 * 4);
   GST_BUFFER_DURATION (inbuffer) = GST_SECOND;
   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
   GST_BUFFER_OFFSET (inbuffer) = 0;
@@ -455,6 +460,7 @@ GST_START_TEST (test_shutdown)
 
 GST_END_TEST;
 
+#if 0
 static GstFlowReturn
 live_switch_alloc_only_48000 (GstPad * pad, guint64 offset,
     guint size, GstCaps * caps, GstBuffer ** buf)
@@ -480,6 +486,7 @@ live_switch_alloc_only_48000 (GstPad * pad, guint64 offset,
 
   return GST_FLOW_OK;
 }
+#endif
 
 static GstCaps *
 live_switch_get_sink_caps (GstPad * pad)
@@ -500,13 +507,18 @@ live_switch_push (int rate, GstCaps * caps)
   GstBuffer *inbuffer;
   GstCaps *desired;
   GList *l;
+  guint8 *data;
 
   desired = gst_caps_copy (caps);
   gst_caps_set_simple (desired, "rate", G_TYPE_INT, rate, NULL);
   gst_pad_set_caps (mysrcpad, desired);
 
+#if 0
   fail_unless (gst_pad_alloc_buffer_and_set_caps (mysrcpad,
           GST_BUFFER_OFFSET_NONE, rate * 4, desired, &inbuffer) == GST_FLOW_OK);
+#endif
+  inbuffer = gst_buffer_new_and_alloc (rate * 4);
+  gst_buffer_set_caps (inbuffer, desired);
 
   /* When the basetransform hits the non-configured case it always
    * returns a buffer with exactly the same caps as we requested so the actual
@@ -516,7 +528,10 @@ live_switch_push (int rate, GstCaps * caps)
       desired, GST_BUFFER_CAPS (inbuffer));
   fail_unless (gst_caps_is_equal (desired, GST_BUFFER_CAPS (inbuffer)));
 
-  memset (GST_BUFFER_DATA (inbuffer), 0, GST_BUFFER_SIZE (inbuffer));
+  data = gst_buffer_map (inbuffer, NULL, NULL, GST_MAP_WRITE);
+  memset (data, 0, rate * 4);
+  gst_buffer_unmap (inbuffer, data, rate * 4);
+
   GST_BUFFER_DURATION (inbuffer) = GST_SECOND;
   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
   GST_BUFFER_OFFSET (inbuffer) = 0;
@@ -551,7 +566,7 @@ GST_START_TEST (test_live_switch)
    * rate 48000- and can only allocate buffers for that rate, but if someone
    * tries to get a buffer with a rate higher then 48000 tries to renegotiate
    * */
-  gst_pad_set_bufferalloc_function (mysinkpad, live_switch_alloc_only_48000);
+  //gst_pad_set_bufferalloc_function (mysinkpad, live_switch_alloc_only_48000);
   gst_pad_set_getcaps_function (mysinkpad, live_switch_get_sink_caps);
 
   gst_pad_use_fixed_caps (mysrcpad);
@@ -769,7 +784,7 @@ fakesink_handoff_cb (GstElement * object, GstBuffer * buffer, GstPad * pad,
 
   ctx->out_buffer_count++;
   if (ctx->latency == GST_CLOCK_TIME_NONE) {
-    ctx->latency = 1000 - GST_BUFFER_SIZE (buffer) / 8;
+    ctx->latency = 1000 - gst_buffer_get_size (buffer) / 8;
   }
 
   /* Check if we have a perfectly timestampped stream */
@@ -781,10 +796,10 @@ fakesink_handoff_cb (GstElement * object, GstBuffer * buffer, GstPad * pad,
 
   /* Check if we have a perfectly offsetted stream */
   fail_unless (GST_BUFFER_OFFSET_END (buffer) ==
-      GST_BUFFER_OFFSET (buffer) + GST_BUFFER_SIZE (buffer) / 8,
+      GST_BUFFER_OFFSET (buffer) + gst_buffer_get_size (buffer) / 8,
       "expected offset end %" G_GUINT64_FORMAT " got offset end %"
       G_GUINT64_FORMAT,
-      GST_BUFFER_OFFSET (buffer) + GST_BUFFER_SIZE (buffer) / 8,
+      GST_BUFFER_OFFSET (buffer) + gst_buffer_get_size (buffer) / 8,
       GST_BUFFER_OFFSET_END (buffer));
   if (ctx->next_out_off != GST_BUFFER_OFFSET_NONE) {
     fail_unless (GST_BUFFER_OFFSET (buffer) == ctx->next_out_off,
index eb6f38a..005c63f 100644 (file)
@@ -42,12 +42,22 @@ static const gchar dummytext[] =
     "over a Lazy Frog Quick Brown Fox Jumps over a Lazy Frog Quick Brown Fox ";
 
 static void
-src_handoff_cb (GstElement * src, GstBuffer * buf, GstPad * pad, gpointer data)
+src_need_data_cb (GstElement * src, guint size, gpointer data)
 {
-  GST_BUFFER_DATA (buf) = (guint8 *) dummytext;
-  GST_BUFFER_SIZE (buf) = sizeof (dummytext);
+  GstBuffer *buf;
+  GstFlowReturn ret;
+
+  buf = gst_buffer_new ();
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          (gpointer) dummytext, NULL, sizeof (dummytext), 0,
+          sizeof (dummytext)));
+
   GST_BUFFER_OFFSET (buf) = 0;
-  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
+
+  g_signal_emit_by_name (src, "push-buffer", buf, &ret);
+
+  fail_unless (ret == GST_FLOW_OK);
 }
 
 static void
@@ -68,13 +78,12 @@ GST_START_TEST (test_text_plain_streams)
   pipe = gst_pipeline_new (NULL);
   fail_unless (pipe != NULL, "failed to create pipeline");
 
-  src = gst_element_factory_make ("fakesrc", "src");
-  fail_unless (src != NULL, "Failed to create fakesrc element");
+  src = gst_element_factory_make ("appsrc", "src");
+  fail_unless (src != NULL, "Failed to create appsrc element");
 
-  g_object_set (src, "signal-handoffs", TRUE, NULL);
+  g_object_set (src, "emit-signals", TRUE, NULL);
   g_object_set (src, "num-buffers", 1, NULL);
-  g_object_set (src, "can-activate-pull", FALSE, NULL);
-  g_signal_connect (src, "handoff", G_CALLBACK (src_handoff_cb), NULL);
+  g_signal_connect (src, "need-data", G_CALLBACK (src_need_data_cb), NULL);
 
   decodebin = gst_element_factory_make ("decodebin", "decodebin");
   fail_unless (decodebin != NULL, "Failed to create decodebin element");
index 84cf405..c57be0b 100644 (file)
@@ -42,12 +42,22 @@ static const gchar dummytext[] =
     "over a Lazy Frog Quick Brown Fox Jumps over a Lazy Frog Quick Brown Fox ";
 
 static void
-src_handoff_cb (GstElement * src, GstBuffer * buf, GstPad * pad, gpointer data)
+src_need_data_cb (GstElement * src, guint size, gpointer data)
 {
-  GST_BUFFER_DATA (buf) = (guint8 *) dummytext;
-  GST_BUFFER_SIZE (buf) = sizeof (dummytext);
+  GstBuffer *buf;
+  GstFlowReturn ret;
+
+  buf = gst_buffer_new ();
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          (gpointer) dummytext, NULL, sizeof (dummytext), 0,
+          sizeof (dummytext)));
+
   GST_BUFFER_OFFSET (buf) = 0;
-  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
+
+  g_signal_emit_by_name (src, "push-buffer", buf, &ret);
+
+  fail_unless (ret == GST_FLOW_OK);
 }
 
 static void
@@ -68,13 +78,12 @@ GST_START_TEST (test_text_plain_streams)
   pipe = gst_pipeline_new (NULL);
   fail_unless (pipe != NULL, "failed to create pipeline");
 
-  src = gst_element_factory_make ("fakesrc", "src");
-  fail_unless (src != NULL, "Failed to create fakesrc element");
+  src = gst_element_factory_make ("appsrc", "src");
+  fail_unless (src != NULL, "Failed to create appsrc element");
 
-  g_object_set (src, "signal-handoffs", TRUE, NULL);
+  g_object_set (src, "emit-signals", TRUE, NULL);
   g_object_set (src, "num-buffers", 1, NULL);
-  g_object_set (src, "can-activate-pull", FALSE, NULL);
-  g_signal_connect (src, "handoff", G_CALLBACK (src_handoff_cb), NULL);
+  g_signal_connect (src, "need-data", G_CALLBACK (src_need_data_cb), NULL);
 
   decodebin = gst_element_factory_make ("decodebin2", "decodebin");
   fail_unless (decodebin != NULL, "Failed to create decodebin element");
index 60179c6..d5946ff 100644 (file)
@@ -264,7 +264,7 @@ GST_START_TEST (test_rgb_to_rgb)
     "black", 2, 0x00, 0x00, 0x00}
   };
   GstElement *pipeline, *src, *filter1, *csp, *filter2, *sink;
-  const GstCaps *template_caps;
+  GstCaps *template_caps;
   GstBuffer *buf = NULL;
   GstPad *srcpad;
   GList *conversions, *l;
@@ -313,6 +313,8 @@ GST_START_TEST (test_rgb_to_rgb)
       GstStateChangeReturn state_ret;
       RGBFormat *from = &conv->from_fmt;
       RGBFormat *to = &conv->to_fmt;
+      guint8 *data;
+      gsize size;
 
       /* trick compiler into thinking from is used, might throw warning
        * otherwise if the debugging system is disabled */
@@ -393,16 +395,20 @@ GST_START_TEST (test_rgb_to_rgb)
       }
 
       /* now check the top-left pixel */
-      check_rgb_buf (GST_BUFFER_DATA (buf), to->red_mask,
+      data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+      check_rgb_buf (data, to->red_mask,
           to->green_mask, to->blue_mask, to->alpha_mask,
           test_patterns[p].r_expected, test_patterns[p].g_expected,
           test_patterns[p].b_expected, to->endianness, to->bpp, to->depth);
+      gst_buffer_unmap (buf, data, size);
 
       gst_buffer_unref (buf);
       buf = NULL;
     }
   }
 
+  gst_caps_unref (template_caps);
+
   g_list_foreach (conversions, (GFunc) rgb_conversion_free, NULL);
   g_list_free (conversions);
 
index 3ee83c8..6a1a9f1 100644 (file)
@@ -94,14 +94,15 @@ cleanup_gdpdepay (GstElement * gdpdepay)
 }
 
 static void
-gdpdepay_push_per_byte (const gchar * reason, guint8 * bytes, guint length)
+gdpdepay_push_per_byte (const gchar * reason, const guint8 * bytes,
+    guint length)
 {
   int i;
   GstBuffer *inbuffer;
 
   for (i = 0; i < length; ++i) {
     inbuffer = gst_buffer_new_and_alloc (1);
-    GST_BUFFER_DATA (inbuffer)[0] = bytes[i];
+    gst_buffer_fill (inbuffer, 0, &bytes[i], 1);
     fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK,
         "%s: failed pushing byte buffer", reason);
   }
@@ -148,13 +149,13 @@ GST_START_TEST (test_audio_per_byte)
   g_free (payload);
 
   buffer = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (buffer), "f00d", 4);
+  gst_buffer_fill (buffer, 0, "f00d", 4);
   GST_BUFFER_TIMESTAMP (buffer) = GST_SECOND;
   GST_BUFFER_DURATION (buffer) = GST_SECOND / 10;
   fail_unless (pk->header_from_buffer (buffer, 0, &len, &header));
   gdpdepay_push_per_byte ("buffer header", header, len);
   fail_unless_equals_int (g_list_length (buffers), 0);
-  gdpdepay_push_per_byte ("buffer payload", GST_BUFFER_DATA (buffer),
+  gdpdepay_push_per_byte ("buffer payload", (const guint8 *) "f00d",
       gst_dp_header_payload_length (header));
   g_free (header);
   gst_buffer_unref (buffer);
@@ -214,21 +215,20 @@ GST_START_TEST (test_audio_in_one_buffer)
           &caps_payload));
 
   buffer = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (buffer), "f00d", 4);
+  gst_buffer_fill (buffer, 0, "f00d", 4);
   fail_unless (pk->header_from_buffer (buffer, 0, &header_len, &buf_header));
 
   payload_len = gst_dp_header_payload_length (caps_header);
 
   inbuffer = gst_buffer_new_and_alloc (2 * GST_DP_HEADER_LENGTH +
-      payload_len + GST_BUFFER_SIZE (buffer));
-  memcpy (GST_BUFFER_DATA (inbuffer), caps_header, GST_DP_HEADER_LENGTH);
+      payload_len + gst_buffer_get_size (buffer));
+  gst_buffer_fill (inbuffer, 0, caps_header, GST_DP_HEADER_LENGTH);
   i = GST_DP_HEADER_LENGTH;
-  memcpy (GST_BUFFER_DATA (inbuffer) + i, caps_payload, payload_len);
+  gst_buffer_fill (inbuffer, i, caps_payload, payload_len);
   i += payload_len;
-  memcpy (GST_BUFFER_DATA (inbuffer) + i, buf_header, GST_DP_HEADER_LENGTH);
+  gst_buffer_fill (inbuffer, i, buf_header, GST_DP_HEADER_LENGTH);
   i += GST_DP_HEADER_LENGTH;
-  memcpy (GST_BUFFER_DATA (inbuffer) + i, GST_BUFFER_DATA (buffer),
-      GST_BUFFER_SIZE (buffer));
+  gst_buffer_fill (inbuffer, i, "f00d", 4);
 
   gst_caps_unref (caps);
   gst_buffer_unref (buffer);
@@ -287,7 +287,8 @@ GST_START_TEST (test_streamheader)
   GstPad *srcpad;
   GstElement *gdpdepay;
   GstBuffer *buffer, *inbuffer, *outbuffer, *shbuffer;
-  guint8 *caps_header, *caps_payload, *buf_header;
+  guint8 *caps_header, *caps_payload, *buf_header, *data;
+  gsize size;
   guint header_len, payload_len;
   guint i;
   GstStructure *structure;
@@ -315,7 +316,7 @@ GST_START_TEST (test_streamheader)
   caps = gst_caps_from_string ("application/x-gst-test-streamheader");
   structure = gst_caps_get_structure (caps, 0);
   buffer = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (buffer), "f00d", 4);
+  gst_buffer_fill (buffer, 0, "f00d", 4);
   GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_IN_CAPS);
   g_value_init (&array, GST_TYPE_ARRAY);
   g_value_init (&value, GST_TYPE_BUFFER);
@@ -338,16 +339,17 @@ GST_START_TEST (test_streamheader)
 
   payload_len = gst_dp_header_payload_length (caps_header);
 
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
   inbuffer = gst_buffer_new_and_alloc (2 * GST_DP_HEADER_LENGTH +
-      payload_len + GST_BUFFER_SIZE (buffer));
-  memcpy (GST_BUFFER_DATA (inbuffer), caps_header, GST_DP_HEADER_LENGTH);
+      payload_len + size);
+  gst_buffer_fill (inbuffer, 0, caps_header, GST_DP_HEADER_LENGTH);
   i = GST_DP_HEADER_LENGTH;
-  memcpy (GST_BUFFER_DATA (inbuffer) + i, caps_payload, payload_len);
+  gst_buffer_fill (inbuffer, i, caps_payload, payload_len);
   i += payload_len;
-  memcpy (GST_BUFFER_DATA (inbuffer) + i, buf_header, GST_DP_HEADER_LENGTH);
+  gst_buffer_fill (inbuffer, i, buf_header, GST_DP_HEADER_LENGTH);
   i += GST_DP_HEADER_LENGTH;
-  memcpy (GST_BUFFER_DATA (inbuffer) + i, GST_BUFFER_DATA (buffer),
-      GST_BUFFER_SIZE (buffer));
+  gst_buffer_fill (inbuffer, i, data, size);
+  gst_buffer_unmap (buffer, data, size);
 
   gst_caps_unref (caps);
   gst_buffer_unref (buffer);
index 13117a6..05391f1 100644 (file)
@@ -142,7 +142,7 @@ GST_START_TEST (test_audio)
   buffers = g_list_remove (buffers, outbuffer);
   ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 2);
   length = GST_DP_HEADER_LENGTH + (strlen (caps_string) + 1);
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), length);
+  fail_unless_equals_int (gst_buffer_get_size (outbuffer), length);
   gst_buffer_unref (outbuffer);
 
   /* the third buffer is the GDP buffer for our pushed buffer */
@@ -150,7 +150,7 @@ GST_START_TEST (test_audio)
   buffers = g_list_remove (buffers, outbuffer);
   ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
   length = GST_DP_HEADER_LENGTH + 4;
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), length);
+  fail_unless_equals_int (gst_buffer_get_size (outbuffer), length);
   gst_buffer_unref (outbuffer);
 
   /* second buffer */
@@ -170,7 +170,7 @@ GST_START_TEST (test_audio)
 
   /* the third output buffer is data */
   length = GST_DP_HEADER_LENGTH + 4;
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), length);
+  fail_unless_equals_int (gst_buffer_get_size (outbuffer), length);
   gst_buffer_unref (outbuffer);
 
   /* a third buffer without caps set explicitly; should work */
@@ -189,7 +189,7 @@ GST_START_TEST (test_audio)
 
   /* the fourth output buffer is data */
   length = GST_DP_HEADER_LENGTH + 4;
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), length);
+  fail_unless_equals_int (gst_buffer_get_size (outbuffer), length);
   gst_buffer_unref (outbuffer);
 
 
@@ -263,7 +263,7 @@ GST_START_TEST (test_streamheader)
 
   GST_DEBUG ("first buffer");
   inbuffer = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (inbuffer), "head", 4);
+  gst_buffer_fill (inbuffer, 0, "head", 4);
   caps = gst_caps_from_string ("application/x-gst-test-streamheader");
   structure = gst_caps_get_structure (caps, 0);
   GST_BUFFER_FLAG_SET (inbuffer, GST_BUFFER_FLAG_IN_CAPS);
@@ -316,7 +316,7 @@ GST_START_TEST (test_streamheader)
   buffers = g_list_remove (buffers, outbuffer);
   ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 2);
   length = GST_DP_HEADER_LENGTH + (strlen (caps_string) + 1);
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), length);
+  fail_unless_equals_int (gst_buffer_get_size (outbuffer), length);
   gst_buffer_unref (outbuffer);
 
   /* the third buffer is the GDP buffer for our pushed buffer */
@@ -324,7 +324,7 @@ GST_START_TEST (test_streamheader)
   buffers = g_list_remove (buffers, outbuffer);
   ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
   length = GST_DP_HEADER_LENGTH + 4;
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), length);
+  fail_unless_equals_int (gst_buffer_get_size (outbuffer), length);
   gst_buffer_unref (outbuffer);
 
   /* second buffer */
@@ -344,7 +344,7 @@ GST_START_TEST (test_streamheader)
 
   /* the third output buffer is data */
   length = GST_DP_HEADER_LENGTH + 4;
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), length);
+  fail_unless_equals_int (gst_buffer_get_size (outbuffer), length);
   gst_buffer_unref (outbuffer);
 
   /* a third buffer without caps set explicitly; should work */
@@ -363,7 +363,7 @@ GST_START_TEST (test_streamheader)
 
   /* the fourth output buffer is data */
   length = GST_DP_HEADER_LENGTH + 4;
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), length);
+  fail_unless_equals_int (gst_buffer_get_size (outbuffer), length);
   gst_buffer_unref (outbuffer);
 
 
@@ -464,6 +464,8 @@ GST_START_TEST (test_crc)
   GstEvent *event;
   gchar *caps_string;
   gint length;
+  guint8 *data;
+  gsize size;
   guint16 crc_calculated, crc_read;
 
   gdppay = setup_gdppay ();
@@ -503,16 +505,19 @@ GST_START_TEST (test_crc)
 
   /* verify the header checksum */
   /* CRC's start at 58 in the header */
-  crc_calculated = gst_dp_crc (GST_BUFFER_DATA (outbuffer), 58);
-  crc_read = GST_READ_UINT16_BE (GST_BUFFER_DATA (outbuffer) + 58);
+  outbuffer = gst_buffer_make_writable (outbuffer);
+  data = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READWRITE);
+  crc_calculated = gst_dp_crc (data, 58);
+  crc_read = GST_READ_UINT16_BE (data + 58);
   fail_unless_equals_int (crc_calculated, crc_read);
 
   /* change a byte in the header and verify that the checksum now fails */
-  GST_BUFFER_DATA (outbuffer)[0] = 0xff;
-  crc_calculated = gst_dp_crc (GST_BUFFER_DATA (outbuffer), 58);
+  data[0] = 0xff;
+  crc_calculated = gst_dp_crc (data, 58);
   fail_if (crc_calculated == crc_read,
       "Introducing a byte error in the header should make the checksum fail");
 
+  gst_buffer_unmap (outbuffer, data, size);
   gst_buffer_unref (outbuffer);
 
   /* second buffer is the serialized caps;
@@ -521,7 +526,7 @@ GST_START_TEST (test_crc)
   buffers = g_list_remove (buffers, outbuffer);
   ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 2);
   length = GST_DP_HEADER_LENGTH + (strlen (caps_string) + 1);
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), length);
+  fail_unless_equals_int (gst_buffer_get_size (outbuffer), length);
   gst_buffer_unref (outbuffer);
 
   /* the third buffer is the GDP buffer for our pushed buffer */
@@ -529,7 +534,7 @@ GST_START_TEST (test_crc)
   buffers = g_list_remove (buffers, outbuffer);
   ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
   length = GST_DP_HEADER_LENGTH + 4;
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), length);
+  fail_unless_equals_int (gst_buffer_get_size (outbuffer), length);
   gst_buffer_unref (outbuffer);
 
   fail_unless (gst_element_set_state (gdppay,
index f0cf64d..912ad7d 100644 (file)
@@ -87,9 +87,12 @@ cleanup_gnomevfssink (GstElement * gnomevfssink)
     G_STMT_START {                                                        \
       GstBuffer *buf = gst_buffer_new_and_alloc(num_bytes);               \
       GRand *rand = g_rand_new_with_seed (num_bytes);                     \
-      guint i;                                                            \
+      gsize i;                                                            \
+      guint8 *data;                                                       \
+      data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);             \
       for (i = 0; i < num_bytes; ++i)                                     \
-        GST_BUFFER_DATA(buf)[i] = (g_rand_int (rand) >> 24) & 0xff;       \
+        data[i] = (g_rand_int (rand) >> 24) & 0xff;                       \
+      gst_buffer_unmap (buf, data, num_bytes);                            \
       fail_unless_equals_int (gst_pad_push (mysrcpad, buf), GST_FLOW_OK); \
       g_rand_free (rand);                                                 \
     } G_STMT_END
index 4eb6e9e..e70402f 100644 (file)
@@ -121,7 +121,7 @@ GST_START_TEST (test_add_client)
   buffer = gst_buffer_new_and_alloc (4);
   gst_buffer_set_caps (buffer, caps);
   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
-  memcpy (GST_BUFFER_DATA (buffer), "dead", 4);
+  gst_buffer_fill (buffer, 0, "dead", 4);
   fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
 
   GST_DEBUG ("reading");
@@ -176,10 +176,10 @@ gst_multifdsink_create_streamheader (const gchar * data1,
    * buffers */
   *hbuf1 = gst_buffer_new_and_alloc (size1);
   GST_BUFFER_FLAG_SET (*hbuf1, GST_BUFFER_FLAG_IN_CAPS);
-  memcpy (GST_BUFFER_DATA (*hbuf1), data1, size1);
+  gst_buffer_fill (*hbuf1, 0, data1, size1);
   *hbuf2 = gst_buffer_new_and_alloc (size2);
   GST_BUFFER_FLAG_SET (*hbuf2, GST_BUFFER_FLAG_IN_CAPS);
-  memcpy (GST_BUFFER_DATA (*hbuf2), data2, size2);
+  gst_buffer_fill (*hbuf2, 0, data2, size2);
 
   g_value_init (&array, GST_TYPE_ARRAY);
 
@@ -265,7 +265,7 @@ GST_START_TEST (test_streamheader)
   /* push a non-IN_CAPS buffer, this should trigger the client receiving the
    * first three buffers */
   buf = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (buf), "f00d", 4);
+  gst_buffer_fill (buf, 0, "f00d", 4);
   gst_pad_push (mysrcpad, buf);
 
   fail_unless_read ("first client", pfd1[0], 4, "babe");
@@ -281,7 +281,7 @@ GST_START_TEST (test_streamheader)
   /* now push another buffer, which will trigger streamheader for second
    * client */
   buf = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (buf), "deaf", 4);
+  gst_buffer_fill (buf, 0, "deaf", 4);
   gst_pad_push (mysrcpad, buf);
 
   fail_unless_read ("first client", pfd1[0], 4, "deaf");
@@ -360,7 +360,7 @@ GST_START_TEST (test_change_streamheader)
 
   /* now push a buffer and read */
   buf = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (buf), "f00d", 4);
+  gst_buffer_fill (buf, 0, "f00d", 4);
   gst_pad_push (mysrcpad, buf);
 
   fail_unless_read ("change: first client", pfd1[0], 5, "first");
@@ -400,7 +400,7 @@ GST_START_TEST (test_change_streamheader)
   /* now push another buffer, which will trigger streamheader for second
    * client, but should also send new streamheaders to first client */
   buf = gst_buffer_new_and_alloc (8);
-  memcpy (GST_BUFFER_DATA (buf), "deadbabe", 8);
+  gst_buffer_fill (buf, 0, "deadbabe", 8);
   gst_pad_push (mysrcpad, buf);
 
   fail_unless_read ("first client", pfd1[0], 6, "second");
@@ -469,8 +469,9 @@ GST_START_TEST (test_burst_client_bytes)
     gst_buffer_set_caps (buffer, caps);
 
     /* copy some id */
-    data = (gchar *) GST_BUFFER_DATA (buffer);
+    data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE);
     g_snprintf (data, 16, "deadbee%08x", i);
+    gst_buffer_unmap (buffer, data, 16);
 
     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
   }
@@ -494,8 +495,9 @@ GST_START_TEST (test_burst_client_bytes)
     gst_buffer_set_caps (buffer, caps);
 
     /* copy some id */
-    data = (gchar *) GST_BUFFER_DATA (buffer);
+    data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE);
     g_snprintf (data, 16, "deadbee%08x", i);
+    gst_buffer_unmap (buffer, data, 16);
 
     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
   }
@@ -586,8 +588,9 @@ GST_START_TEST (test_burst_client_bytes_keyframe)
       GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
 
     /* copy some id */
-    data = (gchar *) GST_BUFFER_DATA (buffer);
+    data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE);
     g_snprintf (data, 16, "deadbee%08x", i);
+    gst_buffer_unmap (buffer, data, 16);
 
     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
   }
@@ -612,8 +615,9 @@ GST_START_TEST (test_burst_client_bytes_keyframe)
     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
 
     /* copy some id */
-    data = (gchar *) GST_BUFFER_DATA (buffer);
+    data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE);
     g_snprintf (data, 16, "deadbee%08x", i);
+    gst_buffer_unmap (buffer, data, 16);
 
     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
   }
@@ -701,8 +705,9 @@ GST_START_TEST (test_burst_client_bytes_with_keyframe)
       GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
 
     /* copy some id */
-    data = (gchar *) GST_BUFFER_DATA (buffer);
+    data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE);
     g_snprintf (data, 16, "deadbee%08x", i);
+    gst_buffer_unmap (buffer, data, 16);
 
     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
   }
@@ -727,8 +732,9 @@ GST_START_TEST (test_burst_client_bytes_with_keyframe)
     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
 
     /* copy some id */
-    data = (gchar *) GST_BUFFER_DATA (buffer);
+    data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE);
     g_snprintf (data, 16, "deadbee%08x", i);
+    gst_buffer_unmap (buffer, data, 16);
 
     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
   }
@@ -813,8 +819,9 @@ GST_START_TEST (test_client_next_keyframe)
     gst_buffer_set_caps (buffer, caps);
 
     /* copy some id */
-    data = (gchar *) GST_BUFFER_DATA (buffer);
+    data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE);
     g_snprintf (data, 16, "deadbee%08x", i);
+    gst_buffer_unmap (buffer, data, 16);
     if (i > 0)
       GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
 
index 08aace6..1de9024 100644 (file)
@@ -447,23 +447,8 @@ gst_red_video_src_init_type (GType type)
 typedef GstPushSrc GstRedVideoSrc;
 typedef GstPushSrcClass GstRedVideoSrcClass;
 
-GST_BOILERPLATE_FULL (GstRedVideoSrc, gst_red_video_src, GstPushSrc,
-    GST_TYPE_PUSH_SRC, gst_red_video_src_init_type);
-
-static void
-gst_red_video_src_base_init (gpointer klass)
-{
-  static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
-      GST_PAD_SRC, GST_PAD_ALWAYS,
-      GST_STATIC_CAPS ("video/x-raw-yuv, format=(fourcc)I420")
-      );
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
-  gst_element_class_set_details_simple (element_class,
-      "Red Video Src", "Source/Video", "yep", "me");
-}
+G_DEFINE_TYPE_WITH_CODE (GstRedVideoSrc, gst_red_video_src,
+    GST_TYPE_PUSH_SRC, gst_red_video_src_init_type (g_define_type_id));
 
 static GstFlowReturn
 gst_red_video_src_create (GstPushSrc * src, GstBuffer ** p_buf)
@@ -472,14 +457,15 @@ gst_red_video_src_create (GstPushSrc * src, GstBuffer ** p_buf)
   GstCaps *caps;
   guint8 *data;
   guint w = 64, h = 64;
-  guint size;
+  gsize size;
 
   size = w * h * 3 / 2;
   buf = gst_buffer_new_and_alloc (size);
-  data = GST_BUFFER_DATA (buf);
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
   memset (data, 76, w * h);
   memset (data + (w * h), 85, (w * h) / 4);
   memset (data + (w * h) + ((w * h) / 4), 255, (w * h) / 4);
+  gst_buffer_unmap (buf, data, size);
 
   caps = gst_caps_new_simple ("video/x-raw-yuv", "format", GST_TYPE_FOURCC,
       GST_MAKE_FOURCC ('I', '4', '2', '0'), "width", G_TYPE_INT, w, "height",
@@ -495,12 +481,22 @@ static void
 gst_red_video_src_class_init (GstRedVideoSrcClass * klass)
 {
   GstPushSrcClass *pushsrc_class = GST_PUSH_SRC_CLASS (klass);
+  static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
+      GST_PAD_SRC, GST_PAD_ALWAYS,
+      GST_STATIC_CAPS ("video/x-raw-yuv, format=(fourcc)I420")
+      );
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&src_templ));
+  gst_element_class_set_details_simple (element_class,
+      "Red Video Src", "Source/Video", "yep", "me");
 
   pushsrc_class->create = gst_red_video_src_create;
 }
 
 static void
-gst_red_video_src_init (GstRedVideoSrc * src, GstRedVideoSrcClass * klass)
+gst_red_video_src_init (GstRedVideoSrc * src)
 {
 }
 
@@ -559,32 +555,20 @@ gst_codec_src_init_type (GType type)
 typedef GstPushSrc GstCodecSrc;
 typedef GstPushSrcClass GstCodecSrcClass;
 
-GST_BOILERPLATE_FULL (GstCodecSrc, gst_codec_src, GstPushSrc,
-    GST_TYPE_PUSH_SRC, gst_codec_src_init_type);
-
-static void
-gst_codec_src_base_init (gpointer klass)
-{
-  static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
-      GST_PAD_SRC, GST_PAD_ALWAYS,
-      GST_STATIC_CAPS ("application/x-codec")
-      );
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
-  gst_element_class_set_details_simple (element_class,
-      "Codec Src", "Source/Video", "yep", "me");
-}
+G_DEFINE_TYPE_WITH_CODE (GstCodecSrc, gst_codec_src,
+    GST_TYPE_PUSH_SRC, gst_codec_src_init_type (g_define_type_id));
 
 static GstFlowReturn
 gst_codec_src_create (GstPushSrc * src, GstBuffer ** p_buf)
 {
   GstBuffer *buf;
   GstCaps *caps;
+  guint8 *data;
 
   buf = gst_buffer_new_and_alloc (20);
-  memset (GST_BUFFER_DATA (buf), 0, GST_BUFFER_SIZE (buf));
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+  memset (data, 0, 20);
+  gst_buffer_unmap (buf, data, 20);
 
   caps = gst_caps_new_simple ("application/x-codec", NULL);
   gst_buffer_set_caps (buf, caps);
@@ -598,12 +582,22 @@ static void
 gst_codec_src_class_init (GstCodecSrcClass * klass)
 {
   GstPushSrcClass *pushsrc_class = GST_PUSH_SRC_CLASS (klass);
+  static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
+      GST_PAD_SRC, GST_PAD_ALWAYS,
+      GST_STATIC_CAPS ("application/x-codec")
+      );
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&src_templ));
+  gst_element_class_set_details_simple (element_class,
+      "Codec Src", "Source/Video", "yep", "me");
 
   pushsrc_class->create = gst_codec_src_create;
 }
 
 static void
-gst_codec_src_init (GstCodecSrc * src, GstCodecSrcClass * klass)
+gst_codec_src_init (GstCodecSrc * src)
 {
 }
 
index aef9272..d501b5e 100644 (file)
@@ -559,23 +559,8 @@ gst_red_video_src_init_type (GType type)
 typedef GstPushSrc GstRedVideoSrc;
 typedef GstPushSrcClass GstRedVideoSrcClass;
 
-GST_BOILERPLATE_FULL (GstRedVideoSrc, gst_red_video_src, GstPushSrc,
-    GST_TYPE_PUSH_SRC, gst_red_video_src_init_type);
-
-static void
-gst_red_video_src_base_init (gpointer klass)
-{
-  static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
-      GST_PAD_SRC, GST_PAD_ALWAYS,
-      GST_STATIC_CAPS ("video/x-raw-yuv, format=(fourcc)I420")
-      );
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
-  gst_element_class_set_details_simple (element_class,
-      "Red Video Src", "Source/Video", "yep", "me");
-}
+G_DEFINE_TYPE_WITH_CODE (GstRedVideoSrc, gst_red_video_src,
+    GST_TYPE_PUSH_SRC, gst_red_video_src_init_type (g_define_type_id));
 
 static GstFlowReturn
 gst_red_video_src_create (GstPushSrc * src, GstBuffer ** p_buf)
@@ -588,10 +573,11 @@ gst_red_video_src_create (GstPushSrc * src, GstBuffer ** p_buf)
 
   size = w * h * 3 / 2;
   buf = gst_buffer_new_and_alloc (size);
-  data = GST_BUFFER_DATA (buf);
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
   memset (data, 76, w * h);
   memset (data + (w * h), 85, (w * h) / 4);
   memset (data + (w * h) + ((w * h) / 4), 255, (w * h) / 4);
+  gst_buffer_unmap (buf, data, size);
 
   caps = gst_caps_new_simple ("video/x-raw-yuv", "format", GST_TYPE_FOURCC,
       GST_MAKE_FOURCC ('I', '4', '2', '0'), "width", G_TYPE_INT, w, "height",
@@ -607,12 +593,22 @@ static void
 gst_red_video_src_class_init (GstRedVideoSrcClass * klass)
 {
   GstPushSrcClass *pushsrc_class = GST_PUSH_SRC_CLASS (klass);
+  static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
+      GST_PAD_SRC, GST_PAD_ALWAYS,
+      GST_STATIC_CAPS ("video/x-raw-yuv, format=(fourcc)I420")
+      );
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&src_templ));
+  gst_element_class_set_details_simple (element_class,
+      "Red Video Src", "Source/Video", "yep", "me");
 
   pushsrc_class->create = gst_red_video_src_create;
 }
 
 static void
-gst_red_video_src_init (GstRedVideoSrc * src, GstRedVideoSrcClass * klass)
+gst_red_video_src_init (GstRedVideoSrc * src)
 {
 }
 
@@ -671,32 +667,20 @@ gst_codec_src_init_type (GType type)
 typedef GstPushSrc GstCodecSrc;
 typedef GstPushSrcClass GstCodecSrcClass;
 
-GST_BOILERPLATE_FULL (GstCodecSrc, gst_codec_src, GstPushSrc,
-    GST_TYPE_PUSH_SRC, gst_codec_src_init_type);
-
-static void
-gst_codec_src_base_init (gpointer klass)
-{
-  static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
-      GST_PAD_SRC, GST_PAD_ALWAYS,
-      GST_STATIC_CAPS ("application/x-codec")
-      );
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
-  gst_element_class_set_details_simple (element_class,
-      "Codec Src", "Source/Video", "yep", "me");
-}
+G_DEFINE_TYPE_WITH_CODE (GstCodecSrc, gst_codec_src,
+    GST_TYPE_PUSH_SRC, gst_codec_src_init_type (g_define_type_id));
 
 static GstFlowReturn
 gst_codec_src_create (GstPushSrc * src, GstBuffer ** p_buf)
 {
   GstBuffer *buf;
   GstCaps *caps;
+  guint8 *data;
 
   buf = gst_buffer_new_and_alloc (20);
-  memset (GST_BUFFER_DATA (buf), 0, GST_BUFFER_SIZE (buf));
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+  memset (data, 0, 20);
+  gst_buffer_unmap (buf, data, 20);
 
   caps = gst_caps_new_simple ("application/x-codec", NULL);
   gst_buffer_set_caps (buf, caps);
@@ -710,12 +694,22 @@ static void
 gst_codec_src_class_init (GstCodecSrcClass * klass)
 {
   GstPushSrcClass *pushsrc_class = GST_PUSH_SRC_CLASS (klass);
+  static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
+      GST_PAD_SRC, GST_PAD_ALWAYS,
+      GST_STATIC_CAPS ("application/x-codec")
+      );
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&src_templ));
+  gst_element_class_set_details_simple (element_class,
+      "Codec Src", "Source/Video", "yep", "me");
 
   pushsrc_class->create = gst_codec_src_create;
 }
 
 static void
-gst_codec_src_init (GstCodecSrc * src, GstCodecSrcClass * klass)
+gst_codec_src_init (GstCodecSrc * src)
 {
 }
 
index 884140b..8f1c4ed 100644 (file)
@@ -43,11 +43,14 @@ static GstBuffer *
 buffer_from_static_string (const gchar * s)
 {
   GstBuffer *buf;
+  gsize len;
+
+  len = strlen (s);
 
   buf = gst_buffer_new ();
-  GST_BUFFER_DATA (buf) = (guint8 *) s;
-  GST_BUFFER_SIZE (buf) = strlen (s);
-  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          (gpointer) s, NULL, len, 0, len));
 
   return buf;
 }
@@ -209,7 +212,7 @@ test_srt_do_test (SubParseInputChunk * input, guint start_idx, guint num)
     const GstStructure *buffer_caps_struct;
     GstBuffer *buf;
     gchar *out;
-    guint out_size;
+    gsize out_size;
 
     buf = g_list_nth_data (buffers, n - start_idx);
     fail_unless (buf != NULL);
@@ -218,16 +221,20 @@ test_srt_do_test (SubParseInputChunk * input, guint start_idx, guint num)
     fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buf), input[n].from_ts);
     fail_unless_equals_uint64 (GST_BUFFER_DURATION (buf),
         input[n].to_ts - input[n].from_ts);
-    out = (gchar *) GST_BUFFER_DATA (buf);
-    out_size = GST_BUFFER_SIZE (buf);
-    /* shouldn't have trailing newline characters */
-    fail_if (out_size > 0 && out[out_size - 1] == '\n');
-    /* shouldn't include NUL-terminator in data size */
-    fail_if (out_size > 0 && out[out_size - 1] == '\0');
-    /* but should still have a  NUL-terminator behind the declared data */
-    fail_unless_equals_int (out[out_size], '\0');
-    /* make sure out string matches expected string */
-    fail_unless_equals_string (out, input[n].out);
+
+    out = gst_buffer_map (buf, &out_size, NULL, GST_MAP_READ);
+    /* can be NULL */
+    if (out != NULL) {
+      /* shouldn't have trailing newline characters */
+      fail_if (out_size > 0 && out[out_size - 1] == '\n');
+      /* shouldn't include NUL-terminator in data size */
+      fail_if (out_size > 0 && out[out_size - 1] == '\0');
+      /* but should still have a  NUL-terminator behind the declared data */
+      fail_unless_equals_int (out[out_size], '\0');
+      /* make sure out string matches expected string */
+      fail_unless_equals_string (out, input[n].out);
+    }
+    gst_buffer_unmap (buf, out, out_size);
     /* check caps */
     fail_unless (GST_BUFFER_CAPS (buf) != NULL);
     buffer_caps_struct = gst_caps_get_structure (GST_BUFFER_CAPS (buf), 0);
@@ -288,7 +295,7 @@ do_test (SubParseInputChunk * input, guint num, const gchar * media_type)
     const GstStructure *buffer_caps_struct;
     GstBuffer *buf;
     gchar *out;
-    guint out_size;
+    gsize out_size;
 
     buf = g_list_nth_data (buffers, n);
     fail_unless (buf != NULL);
@@ -305,16 +312,19 @@ do_test (SubParseInputChunk * input, guint num, const gchar * media_type)
           input[n].to_ts - input[n].from_ts);
     }
 
-    out = (gchar *) GST_BUFFER_DATA (buf);
-    out_size = GST_BUFFER_SIZE (buf);
-    /* shouldn't have trailing newline characters */
-    fail_if (out_size > 0 && out[out_size - 1] == '\n');
-    /* shouldn't include NUL-terminator in data size */
-    fail_if (out_size > 0 && out[out_size - 1] == '\0');
-    /* but should still have a  NUL-terminator behind the declared data */
-    fail_unless_equals_int (out[out_size], '\0');
-    /* make sure out string matches expected string */
-    fail_unless_equals_string (out, input[n].out);
+    out = gst_buffer_map (buf, &out_size, NULL, GST_MAP_READ);
+    /* can be NULL */
+    if (out != NULL) {
+      /* shouldn't have trailing newline characters */
+      fail_if (out_size > 0 && out[out_size - 1] == '\n');
+      /* shouldn't include NUL-terminator in data size */
+      fail_if (out_size > 0 && out[out_size - 1] == '\0');
+      /* but should still have a  NUL-terminator behind the declared data */
+      fail_unless_equals_int (out[out_size], '\0');
+      /* make sure out string matches expected string */
+      fail_unless_equals_string (out, input[n].out);
+    }
+    gst_buffer_unmap (buf, out, out_size);
     /* check caps */
     fail_unless (GST_BUFFER_CAPS (buf) != NULL);
     buffer_caps_struct = gst_caps_get_structure (GST_BUFFER_CAPS (buf), 0);
index 3c970b2..7c89ece 100644 (file)
@@ -164,6 +164,8 @@ buffer_is_all_black (GstBuffer * buf)
 {
   GstStructure *s;
   gint x, y, w, h;
+  guint8 *data;
+  gsize size;
 
   fail_unless (buf != NULL);
   fail_unless (GST_BUFFER_CAPS (buf) != NULL);
@@ -172,16 +174,18 @@ buffer_is_all_black (GstBuffer * buf)
   fail_unless (gst_structure_get_int (s, "width", &w));
   fail_unless (gst_structure_get_int (s, "height", &h));
 
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
   for (y = 0; y < h; ++y) {
-    guint8 *data = GST_BUFFER_DATA (buf) + (y * GST_ROUND_UP_4 (w));
+    guint8 *ptr = data + (y * GST_ROUND_UP_4 (w));
 
     for (x = 0; x < w; ++x) {
-      if (data[x] != 0x00) {
+      if (ptr[x] != 0x00) {
         GST_LOG ("non-black pixel at (x,y) %d,%d", x, y);
         return FALSE;
       }
     }
   }
+  gst_buffer_unmap (buf, data, size);
 
   return TRUE;
 }
@@ -193,6 +197,7 @@ create_black_buffer (const gchar * caps_string)
   GstBuffer *buffer;
   GstCaps *caps;
   gint w, h, size;
+  guint8 *data;
 
   fail_unless (caps_string != NULL);
 
@@ -207,9 +212,12 @@ create_black_buffer (const gchar * caps_string)
   GST_LOG ("creating buffer (%dx%d)", w, h);
   size = I420_SIZE (w, h);
   buffer = gst_buffer_new_and_alloc (size);
+
+  data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE);
   /* we're only checking the Y plane later, so just zero it all out,
    * even if it's not the blackest black there is */
-  memset (GST_BUFFER_DATA (buffer), 0, size);
+  memset (data, 0, size);
+  gst_buffer_unmap (buffer, data, size);
 
   gst_buffer_set_caps (buffer, caps);
   gst_caps_unref (caps);
@@ -232,7 +240,7 @@ create_text_buffer (const gchar * txt, GstClockTime ts, GstClockTime duration)
   txt_len = strlen (txt);
 
   buffer = gst_buffer_new_and_alloc (txt_len);
-  memcpy (GST_BUFFER_DATA (buffer), txt, txt_len);
+  gst_buffer_fill (buffer, 0, txt, txt_len);
 
   GST_BUFFER_TIMESTAMP (buffer) = ts;
   GST_BUFFER_DURATION (buffer) = duration;
@@ -375,8 +383,8 @@ GST_START_TEST (test_video_passthrough)
   /* pushing gives away one of the two references we have ... */
   fail_unless (gst_pad_push (myvideosrcpad, inbuffer) == GST_FLOW_OK);
 
-  /* should be the parent for a new subbuffer for the stamp fix-up */
-  ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 2);
+  /* should be a new buffer for the stamp fix-up */
+  ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_unless (GST_BUFFER_CAST (buffers->data) != inbuffer);
   fail_unless (GST_BUFFER_TIMESTAMP (GST_BUFFER_CAST (buffers->data)) ==
@@ -525,7 +533,7 @@ GST_START_TEST (test_video_waits_for_text)
   fail_unless (buffer_is_all_black (GST_BUFFER_CAST (buffers->data)));
 
   /* now, another video buffer */
-  inbuffer = gst_buffer_make_metadata_writable (inbuffer);
+  inbuffer = gst_buffer_make_writable (inbuffer);
   GST_BUFFER_TIMESTAMP (inbuffer) = GST_SECOND;
   GST_BUFFER_DURATION (inbuffer) = GST_SECOND / 2;
 
@@ -545,7 +553,7 @@ GST_START_TEST (test_video_waits_for_text)
       FALSE);
 
   /* a third video buffer */
-  inbuffer = gst_buffer_make_metadata_writable (inbuffer);
+  inbuffer = gst_buffer_make_writable (inbuffer);
   GST_BUFFER_TIMESTAMP (inbuffer) = 30 * GST_SECOND;
   GST_BUFFER_DURATION (inbuffer) = GST_SECOND / 2;
 
@@ -573,7 +581,7 @@ GST_START_TEST (test_video_waits_for_text)
               next->data)));
 
   /* a fourth video buffer */
-  inbuffer = gst_buffer_make_metadata_writable (inbuffer);
+  inbuffer = gst_buffer_make_writable (inbuffer);
   GST_BUFFER_TIMESTAMP (inbuffer) = 35 * GST_SECOND;
   GST_BUFFER_DURATION (inbuffer) = GST_SECOND;
 
index 69eb3c6..fb881a1 100644 (file)
@@ -142,6 +142,26 @@ cleanup_videorate (GstElement * videorate)
   gst_check_teardown_element (videorate);
 }
 
+static void
+buffer_memset (GstBuffer * buffer, gint val, gsize size)
+{
+  guint8 *data;
+
+  data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE);
+  memset (data, val, size);
+  gst_buffer_unmap (buffer, data, size);
+}
+
+static guint8
+buffer_get_byte (GstBuffer * buffer, gint offset)
+{
+  guint8 res;
+
+  gst_buffer_extract (buffer, offset, &res, 1);
+
+  return res;
+}
+
 GST_START_TEST (test_one)
 {
   GstElement *videorate;
@@ -154,7 +174,7 @@ GST_START_TEST (test_one)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (4);
-  memset (GST_BUFFER_DATA (inbuffer), 0, 4);
+  buffer_memset (inbuffer, 0, 4);
   caps = gst_caps_from_string (VIDEO_CAPS_STRING);
   gst_buffer_set_caps (inbuffer, caps);
   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
@@ -196,7 +216,7 @@ GST_START_TEST (test_more)
      streams */
   GST_BUFFER_OFFSET (first) = g_rand_int (rand);
   GST_BUFFER_OFFSET_END (first) = g_rand_int (rand);
-  memset (GST_BUFFER_DATA (first), 1, 4);
+  buffer_memset (first, 1, 4);
   caps = gst_caps_from_string (VIDEO_CAPS_STRING);
   gst_buffer_set_caps (first, caps);
   gst_caps_unref (caps);
@@ -215,7 +235,7 @@ GST_START_TEST (test_more)
   GST_BUFFER_TIMESTAMP (second) = GST_SECOND * 3 / 50;
   GST_BUFFER_OFFSET (first) = g_rand_int (rand);
   GST_BUFFER_OFFSET_END (first) = g_rand_int (rand);
-  memset (GST_BUFFER_DATA (second), 2, 4);
+  buffer_memset (second, 2, 4);
   caps = gst_caps_from_string (VIDEO_CAPS_STRING);
   gst_buffer_set_caps (second, caps);
   gst_caps_unref (caps);
@@ -230,7 +250,7 @@ GST_START_TEST (test_more)
   /* ... and the first one is pushed out, with timestamp 0 */
   fail_unless_equals_int (g_list_length (buffers), 1);
   assert_videorate_stats (videorate, "second buffer", 2, 1, 0, 0);
-  ASSERT_BUFFER_REFCOUNT (first, "first", 2);
+  ASSERT_BUFFER_REFCOUNT (first, "first", 1);
 
   outbuffer = buffers->data;
   fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (outbuffer), 0);
@@ -240,7 +260,7 @@ GST_START_TEST (test_more)
   GST_BUFFER_TIMESTAMP (third) = GST_SECOND * 12 / 50;
   GST_BUFFER_OFFSET (first) = g_rand_int (rand);
   GST_BUFFER_OFFSET_END (first) = g_rand_int (rand);
-  memset (GST_BUFFER_DATA (third), 3, 4);
+  buffer_memset (third, 3, 4);
   caps = gst_caps_from_string (VIDEO_CAPS_STRING);
   gst_buffer_set_caps (third, caps);
   gst_caps_unref (caps);
@@ -258,33 +278,33 @@ GST_START_TEST (test_more)
   /* check timestamp and source correctness */
   l = buffers;
   fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (l->data), 0);
-  fail_unless_equals_int (GST_BUFFER_DATA (l->data)[0], 1);
+  fail_unless_equals_int (buffer_get_byte (l->data, 0), 1);
   fail_unless_equals_uint64 (GST_BUFFER_OFFSET (l->data), 0);
   fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (l->data), 1);
 
   l = g_list_next (l);
   fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (l->data), GST_SECOND / 25);
-  fail_unless_equals_int (GST_BUFFER_DATA (l->data)[0], 2);
+  fail_unless_equals_int (buffer_get_byte (l->data, 0), 2);
   fail_unless_equals_uint64 (GST_BUFFER_OFFSET (l->data), 1);
   fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (l->data), 2);
 
   l = g_list_next (l);
   fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (l->data),
       GST_SECOND * 2 / 25);
-  fail_unless_equals_int (GST_BUFFER_DATA (l->data)[0], 2);
+  fail_unless_equals_int (buffer_get_byte (l->data, 0), 2);
   fail_unless_equals_uint64 (GST_BUFFER_OFFSET (l->data), 2);
   fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (l->data), 3);
 
   l = g_list_next (l);
   fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (l->data),
       GST_SECOND * 3 / 25);
-  fail_unless_equals_int (GST_BUFFER_DATA (l->data)[0], 2);
+  fail_unless_equals_int (buffer_get_byte (l->data, 0), 2);
   fail_unless_equals_uint64 (GST_BUFFER_OFFSET (l->data), 3);
   fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (l->data), 4);
 
   fail_unless_equals_int (g_list_length (buffers), 4);
   /* one held by us, three held by each output frame taken from the second */
-  ASSERT_BUFFER_REFCOUNT (second, "second", 4);
+  ASSERT_BUFFER_REFCOUNT (second, "second", 1);
 
   /* now send EOS */
   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
@@ -320,7 +340,7 @@ GST_START_TEST (test_wrong_order_from_zero)
   /* first buffer */
   first = gst_buffer_new_and_alloc (4);
   GST_BUFFER_TIMESTAMP (first) = GST_SECOND;
-  memset (GST_BUFFER_DATA (first), 0, 4);
+  buffer_memset (first, 0, 4);
   caps = gst_caps_from_string (VIDEO_CAPS_STRING);
   gst_buffer_set_caps (first, caps);
   gst_caps_unref (caps);
@@ -338,7 +358,7 @@ GST_START_TEST (test_wrong_order_from_zero)
   /* second buffer */
   second = gst_buffer_new_and_alloc (4);
   GST_BUFFER_TIMESTAMP (second) = 0;
-  memset (GST_BUFFER_DATA (second), 0, 4);
+  buffer_memset (second, 0, 4);
   caps = gst_caps_from_string (VIDEO_CAPS_STRING);
   gst_buffer_set_caps (second, caps);
   gst_caps_unref (caps);
@@ -358,7 +378,7 @@ GST_START_TEST (test_wrong_order_from_zero)
   /* third buffer */
   third = gst_buffer_new_and_alloc (4);
   GST_BUFFER_TIMESTAMP (third) = 2 * GST_SECOND;
-  memset (GST_BUFFER_DATA (third), 0, 4);
+  buffer_memset (third, 0, 4);
   caps = gst_caps_from_string (VIDEO_CAPS_STRING);
   gst_buffer_set_caps (third, caps);
   gst_caps_unref (caps);
@@ -373,7 +393,7 @@ GST_START_TEST (test_wrong_order_from_zero)
   /* and now the first one should be pushed once and dupped 24 + 13 times, to
    * reach the half point between 1 s (first) and 2 s (third) */
   fail_unless_equals_int (g_list_length (buffers), 38);
-  ASSERT_BUFFER_REFCOUNT (first, "first", 39);
+  ASSERT_BUFFER_REFCOUNT (first, "first", 1);
   ASSERT_BUFFER_REFCOUNT (second, "second", 1);
   ASSERT_BUFFER_REFCOUNT (third, "third", 2);
   assert_videorate_stats (videorate, "third", 3, 38, 1, 37);
@@ -409,7 +429,7 @@ GST_START_TEST (test_wrong_order)
   /* first buffer */
   first = gst_buffer_new_and_alloc (4);
   GST_BUFFER_TIMESTAMP (first) = 0;
-  memset (GST_BUFFER_DATA (first), 0, 4);
+  buffer_memset (first, 0, 4);
   caps = gst_caps_from_string (VIDEO_CAPS_STRING);
   gst_buffer_set_caps (first, caps);
   gst_caps_unref (caps);
@@ -427,7 +447,7 @@ GST_START_TEST (test_wrong_order)
   /* second buffer */
   second = gst_buffer_new_and_alloc (4);
   GST_BUFFER_TIMESTAMP (second) = GST_SECOND;
-  memset (GST_BUFFER_DATA (second), 0, 4);
+  buffer_memset (second, 0, 4);
   caps = gst_caps_from_string (VIDEO_CAPS_STRING);
   gst_buffer_set_caps (second, caps);
   gst_caps_unref (caps);
@@ -441,12 +461,12 @@ GST_START_TEST (test_wrong_order)
   /* and it created 13 output buffers as copies of the first frame */
   fail_unless_equals_int (g_list_length (buffers), 13);
   assert_videorate_stats (videorate, "second", 2, 13, 0, 12);
-  ASSERT_BUFFER_REFCOUNT (first, "first", 14);
+  ASSERT_BUFFER_REFCOUNT (first, "first", 1);
 
   /* third buffer */
   third = gst_buffer_new_and_alloc (4);
   GST_BUFFER_TIMESTAMP (third) = 2 * GST_SECOND;
-  memset (GST_BUFFER_DATA (third), 0, 4);
+  buffer_memset (third, 0, 4);
   caps = gst_caps_from_string (VIDEO_CAPS_STRING);
   gst_buffer_set_caps (third, caps);
   gst_caps_unref (caps);
@@ -460,15 +480,15 @@ GST_START_TEST (test_wrong_order)
 
   /* submitting a frame with 2 seconds triggers output of 25 more frames */
   fail_unless_equals_int (g_list_length (buffers), 38);
-  ASSERT_BUFFER_REFCOUNT (first, "first", 14);
-  ASSERT_BUFFER_REFCOUNT (second, "second", 26);
+  ASSERT_BUFFER_REFCOUNT (first, "first", 1);
+  ASSERT_BUFFER_REFCOUNT (second, "second", 1);
   /* three frames submitted; two of them output as is, and 36 duplicated */
   assert_videorate_stats (videorate, "third", 3, 38, 0, 36);
 
   /* fourth buffer */
   fourth = gst_buffer_new_and_alloc (4);
   GST_BUFFER_TIMESTAMP (fourth) = 0;
-  memset (GST_BUFFER_DATA (fourth), 0, 4);
+  buffer_memset (fourth, 0, 4);
   caps = gst_caps_from_string (VIDEO_CAPS_STRING);
   gst_buffer_set_caps (fourth, caps);
   gst_caps_unref (caps);
@@ -481,8 +501,8 @@ GST_START_TEST (test_wrong_order)
   ASSERT_BUFFER_REFCOUNT (fourth, "fourth", 1);
 
   fail_unless_equals_int (g_list_length (buffers), 38);
-  ASSERT_BUFFER_REFCOUNT (first, "first", 14);
-  ASSERT_BUFFER_REFCOUNT (second, "second", 26);
+  ASSERT_BUFFER_REFCOUNT (first, "first", 1);
+  ASSERT_BUFFER_REFCOUNT (second, "second", 1);
   assert_videorate_stats (videorate, "fourth", 4, 38, 1, 36);
 
   /* verify last buffer */
@@ -516,7 +536,7 @@ GST_START_TEST (test_no_framerate)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (4);
-  memset (GST_BUFFER_DATA (inbuffer), 0, 4);
+  buffer_memset (inbuffer, 0, 4);
   caps = gst_caps_from_string (VIDEO_CAPS_NO_FRAMERATE_STRING);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -564,7 +584,7 @@ GST_START_TEST (test_changing_size)
   fail_unless (gst_pad_push_event (mysrcpad, newsegment) == TRUE);
 
   first = gst_buffer_new_and_alloc (4);
-  memset (GST_BUFFER_DATA (first), 0, 4);
+  buffer_memset (first, 0, 4);
   caps = gst_caps_from_string (VIDEO_CAPS_STRING);
   GST_BUFFER_TIMESTAMP (first) = 0;
   gst_buffer_set_caps (first, caps);
@@ -575,7 +595,7 @@ GST_START_TEST (test_changing_size)
   /* second buffer */
   second = gst_buffer_new_and_alloc (4);
   GST_BUFFER_TIMESTAMP (second) = GST_SECOND / 25;
-  memset (GST_BUFFER_DATA (second), 0, 4);
+  buffer_memset (second, 0, 4);
   gst_buffer_set_caps (second, caps);
 
   fail_unless (gst_pad_push (mysrcpad, second) == GST_FLOW_OK);
@@ -588,7 +608,7 @@ GST_START_TEST (test_changing_size)
   /* third buffer with new size */
   third = gst_buffer_new_and_alloc (4);
   GST_BUFFER_TIMESTAMP (third) = 2 * GST_SECOND / 25;
-  memset (GST_BUFFER_DATA (third), 0, 4);
+  buffer_memset (third, 0, 4);
   caps_newsize = gst_caps_from_string (VIDEO_CAPS_NEWSIZE_STRING);
   gst_buffer_set_caps (third, caps_newsize);
 
@@ -603,7 +623,7 @@ GST_START_TEST (test_changing_size)
   /* fourth buffer with original size */
   fourth = gst_buffer_new_and_alloc (4);
   GST_BUFFER_TIMESTAMP (fourth) = 3 * GST_SECOND / 25;
-  memset (GST_BUFFER_DATA (fourth), 0, 4);
+  buffer_memset (fourth, 0, 4);
   gst_buffer_set_caps (fourth, caps);
 
   fail_unless (gst_pad_push (mysrcpad, fourth) == GST_FLOW_OK);
@@ -612,7 +632,7 @@ GST_START_TEST (test_changing_size)
   /* fifth buffer with original size */
   fifth = gst_buffer_new_and_alloc (4);
   GST_BUFFER_TIMESTAMP (fifth) = 4 * GST_SECOND / 25;
-  memset (GST_BUFFER_DATA (fifth), 0, 4);
+  buffer_memset (fifth, 0, 4);
   gst_buffer_set_caps (fifth, caps);
 
   fail_unless (gst_pad_push (mysrcpad, fifth) == GST_FLOW_OK);
@@ -643,7 +663,7 @@ GST_START_TEST (test_non_ok_flow)
       "could not set to playing");
 
   buf = gst_buffer_new_and_alloc (4);
-  memset (GST_BUFFER_DATA (buf), 0, 4);
+  buffer_memset (buf, 0, 4);
   caps = gst_caps_from_string (VIDEO_CAPS_STRING);
   gst_buffer_set_caps (buf, caps);
   gst_caps_unref (caps);
@@ -666,7 +686,7 @@ GST_START_TEST (test_non_ok_flow)
   gst_pad_set_active (mysinkpad, FALSE);
 
   /* push buffer on deactivated pad */
-  fail_unless (gst_buffer_is_metadata_writable (buf));
+  fail_unless (gst_buffer_is_writable (buf));
   GST_BUFFER_TIMESTAMP (buf) = ts;
 
   /* pushing gives away our reference */
index 276261f..4ed1dfa 100644 (file)
@@ -54,6 +54,7 @@ videoscale_get_allowed_caps (void)
     gst_caps_append_structure (ret[i], gst_structure_copy (s));
   }
 
+  gst_caps_unref (caps);
   gst_object_unref (scale);
 
   return ret;
@@ -240,9 +241,15 @@ GST_START_TEST (test_passthrough)
           l1 = l1->next, l2 = l2->next) {
         GstBuffer *a = l1->data;
         GstBuffer *b = l2->data;
+        gsize sa, sb;
+        guint8 *pa, *pb;
 
-        fail_unless_equals_int (GST_BUFFER_SIZE (a), GST_BUFFER_SIZE (b));
-        fail_unless (GST_BUFFER_DATA (a) == GST_BUFFER_DATA (b));
+        pa = gst_buffer_map (a, &sa, NULL, GST_MAP_READ);
+        pb = gst_buffer_map (b, &sb, NULL, GST_MAP_READ);
+        fail_unless_equals_int (sa, sb);
+        fail_unless (pa == pb);
+        gst_buffer_unmap (b, pb, sb);
+        gst_buffer_unmap (a, pa, sa);
 
         gst_buffer_unref (a);
         gst_buffer_unref (b);
@@ -562,14 +569,15 @@ struct _GstTestReverseNegotiationSinkClass
 
 GType gst_test_reverse_negotiation_sink_get_type (void);
 
-GST_BOILERPLATE (GstTestReverseNegotiationSink,
-    gst_test_reverse_negotiation_sink, GstBaseSink, GST_TYPE_BASE_SINK);
+G_DEFINE_TYPE (GstTestReverseNegotiationSink,
+    gst_test_reverse_negotiation_sink, GST_TYPE_BASE_SINK);
 
 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS (GST_VIDEO_CAPS_xRGB));
 
+#if 0
 static GstFlowReturn
 gst_test_reverse_negotiation_sink_buffer_alloc (GstBaseSink * bsink,
     guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf)
@@ -603,6 +611,7 @@ gst_test_reverse_negotiation_sink_buffer_alloc (GstBaseSink * bsink,
 
   return GST_FLOW_OK;
 }
+#endif
 
 static GstFlowReturn
 gst_test_reverse_negotiation_sink_render (GstBaseSink * bsink,
@@ -634,9 +643,14 @@ gst_test_reverse_negotiation_sink_render (GstBaseSink * bsink,
 }
 
 static void
-gst_test_reverse_negotiation_sink_base_init (gpointer g_class)
+gst_test_reverse_negotiation_sink_class_init (GstTestReverseNegotiationSinkClass
+    * klass)
 {
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
+  GstElementClass *gstelement_class;
+  GstBaseSinkClass *gstbase_sink_class;
+
+  gstelement_class = GST_ELEMENT_CLASS (klass);
+  gstbase_sink_class = GST_BASE_SINK_CLASS (klass);
 
   gst_element_class_set_details_simple (gstelement_class,
       "Test Reverse Negotiation Sink",
@@ -644,25 +658,17 @@ gst_test_reverse_negotiation_sink_base_init (gpointer g_class)
       "Some test sink", "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
   gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&sinktemplate));
-}
-
-static void
-gst_test_reverse_negotiation_sink_class_init (GstTestReverseNegotiationSinkClass
-    * klass)
-{
-  GstBaseSinkClass *gstbase_sink_class;
-
-  gstbase_sink_class = GST_BASE_SINK_CLASS (klass);
 
+#if 0
   gstbase_sink_class->buffer_alloc =
       GST_DEBUG_FUNCPTR (gst_test_reverse_negotiation_sink_buffer_alloc);
+#endif
   gstbase_sink_class->render =
       GST_DEBUG_FUNCPTR (gst_test_reverse_negotiation_sink_render);
 }
 
 static void
-gst_test_reverse_negotiation_sink_init (GstTestReverseNegotiationSink * sink,
-    GstTestReverseNegotiationSinkClass * g_class)
+gst_test_reverse_negotiation_sink_init (GstTestReverseNegotiationSink * sink)
 {
   sink->nbuffers = 0;
 }
index 635ca32..35eab3a 100644 (file)
@@ -261,7 +261,7 @@ GST_START_TEST (test_rgb_formats)
     "xRGB1555", 16, 15, 0x00007c00, 0x000003e0, 0x0000001f, 0x0000000}
   };
   GstElement *pipeline, *src, *filter, *sink;
-  const GstCaps *template_caps;
+  GstCaps *template_caps;
   GstBuffer *buf = NULL;
   GstPad *srcpad;
   gint p, i, e;
@@ -322,6 +322,8 @@ GST_START_TEST (test_rgb_formats)
         /* caps are supported, let's run some tests then ... */
         for (p = 0; p < G_N_ELEMENTS (test_patterns); ++p) {
           GstStateChangeReturn state_ret;
+          guint8 *data;
+          gsize size;
 
           g_object_set (src, "pattern", test_patterns[p].pattern_enum, NULL);
 
@@ -375,11 +377,13 @@ GST_START_TEST (test_rgb_formats)
 
 
           /* now check the first pixel */
-          check_rgb_buf (GST_BUFFER_DATA (buf), rgb_formats[i].red_mask,
+          data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+          check_rgb_buf (data, rgb_formats[i].red_mask,
               rgb_formats[i].green_mask, rgb_formats[i].blue_mask,
               rgb_formats[i].alpha_mask, test_patterns[p].r_expected,
               test_patterns[p].g_expected, test_patterns[p].b_expected,
               endianness, rgb_formats[i].bpp, rgb_formats[i].depth);
+          gst_buffer_unmap (buf, data, size);
 
           gst_buffer_unref (buf);
           buf = NULL;
@@ -392,6 +396,7 @@ GST_START_TEST (test_rgb_formats)
       gst_caps_unref (caps);
     }
   }
+  gst_caps_unref (template_caps);
 
   gst_object_unref (pipeline);
 }
index d59a96f..b5fcd44 100644 (file)
@@ -185,6 +185,7 @@ GST_START_TEST (test_unity_s8)
   GstCaps *caps;
   gint8 in[2] = { 64, -16 };
   gint8 *res;
+  gsize size;
 
   volume = setup_volume ();
   fail_unless (gst_element_set_state (volume,
@@ -192,7 +193,7 @@ GST_START_TEST (test_unity_s8)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (2);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 2);
+  gst_buffer_fill (inbuffer, 0, in, 2);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S8);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -205,9 +206,10 @@ GST_START_TEST (test_unity_s8)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gint8 *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", in[0], in[1], res[0], res[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 2) == 0);
+  fail_unless (memcmp (res, in, 2) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -224,6 +226,7 @@ GST_START_TEST (test_half_s8)
   gint8 in[2] = { 64, -16 };
   gint8 out[2] = { 32, -8 };
   gint8 *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
@@ -232,8 +235,7 @@ GST_START_TEST (test_half_s8)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (2);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 2);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 2) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 2);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S8);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -251,10 +253,11 @@ GST_START_TEST (test_half_s8)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gint8 *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
       res[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 2) == 0);
+  fail_unless (memcmp (res, out, 2) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -271,6 +274,7 @@ GST_START_TEST (test_double_s8)
   gint8 in[2] = { 64, -16 };
   gint8 out[2] = { 127, -32 };  /* notice the clamped sample */
   gint8 *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
@@ -279,8 +283,7 @@ GST_START_TEST (test_double_s8)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (2);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 2);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 2) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 2);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S8);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -298,10 +301,11 @@ GST_START_TEST (test_double_s8)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gint8 *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
       res[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 2) == 0);
+  fail_unless (memcmp (res, out, 2) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -318,6 +322,7 @@ GST_START_TEST (test_mute_s8)
   gint8 in[2] = { 64, -16 };
   gint8 out[2] = { 0, 0 };
   gint8 *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
@@ -326,8 +331,7 @@ GST_START_TEST (test_mute_s8)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (2);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 2);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 2) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 2);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S8);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -345,10 +349,11 @@ GST_START_TEST (test_mute_s8)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gint8 *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
       res[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 2) == 0);
+  fail_unless (memcmp (res, out, 2) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -363,6 +368,7 @@ GST_START_TEST (test_unity_s16)
   GstCaps *caps;
   gint16 in[2] = { 16384, -256 };
   gint16 *res;
+  gsize size;
 
   volume = setup_volume ();
   fail_unless (gst_element_set_state (volume,
@@ -370,7 +376,7 @@ GST_START_TEST (test_unity_s16)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 4);
+  gst_buffer_fill (inbuffer, 0, in, 4);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -383,9 +389,10 @@ GST_START_TEST (test_unity_s16)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gint16 *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", in[0], in[1], res[0], res[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 4) == 0);
+  fail_unless (memcmp (res, in, 4) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -402,6 +409,7 @@ GST_START_TEST (test_half_s16)
   gint16 in[2] = { 16384, -256 };
   gint16 out[2] = { 8192, -128 };
   gint16 *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
@@ -410,8 +418,7 @@ GST_START_TEST (test_half_s16)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 4);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 4) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 4);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -429,10 +436,11 @@ GST_START_TEST (test_half_s16)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gint16 *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
       res[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 4) == 0);
+  fail_unless (memcmp (res, out, 4) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -449,6 +457,7 @@ GST_START_TEST (test_double_s16)
   gint16 in[2] = { 16384, -256 };
   gint16 out[2] = { 32767, -512 };      /* notice the clamped sample */
   gint16 *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
@@ -457,8 +466,7 @@ GST_START_TEST (test_double_s16)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 4);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 4) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 4);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -476,10 +484,11 @@ GST_START_TEST (test_double_s16)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gint16 *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
       res[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 4) == 0);
+  fail_unless (memcmp (res, out, 4) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -497,6 +506,7 @@ GST_START_TEST (test_mute_s16)
   gint16 in[2] = { 16384, -256 };
   gint16 out[2] = { 0, 0 };
   gint16 *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
@@ -505,8 +515,7 @@ GST_START_TEST (test_mute_s16)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 4);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 4) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 4);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -524,10 +533,11 @@ GST_START_TEST (test_mute_s16)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gint16 *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
       res[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 4) == 0);
+  fail_unless (memcmp (res, out, 4) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -552,7 +562,7 @@ GST_START_TEST (test_unity_s24)
   guint8 in[6];
   guint8 *res;
   gint32 res_32[2];
-
+  gsize size;
 
   write_unaligned_u24 (in, in_32[0]);
   write_unaligned_u24 (in + 3, in_32[1]);
@@ -563,7 +573,7 @@ GST_START_TEST (test_unity_s24)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (6);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 6);
+  gst_buffer_fill (inbuffer, 0, in, 6);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S24);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -576,14 +586,15 @@ GST_START_TEST (test_unity_s24)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
 
   res_32[0] = get_unaligned_i24 (res);
   res_32[1] = get_unaligned_i24 ((res + 3));
 
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", in_32[0], in_32[1], res_32[0],
       res_32[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 6) == 0);
+  fail_unless (memcmp (res, in, 6) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -602,6 +613,7 @@ GST_START_TEST (test_half_s24)
   guint8 *res;
   gint32 res_32[2];
   gint32 out_32[2] = { 2097152, -2048 };
+  gsize size;
 
   write_unaligned_u24 (in, in_32[0]);
   write_unaligned_u24 (in + 3, in_32[1]);
@@ -613,8 +625,7 @@ GST_START_TEST (test_half_s24)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (6);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 6);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 6) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 6);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S24);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -632,7 +643,7 @@ GST_START_TEST (test_half_s24)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
 
   res_32[0] = get_unaligned_i24 (res);
   res_32[1] = get_unaligned_i24 ((res + 3));
@@ -640,6 +651,7 @@ GST_START_TEST (test_half_s24)
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out_32[0], out_32[1],
       res_32[0], res_32[1]);
   fail_unless (memcmp (res_32, out_32, 8) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -658,6 +670,7 @@ GST_START_TEST (test_double_s24)
   guint8 *res;
   gint32 res_32[2];
   gint32 out_32[2] = { 8388607, -8192 };        /* notice the clamped sample */
+  gsize size;
 
   write_unaligned_u24 (in, in_32[0]);
   write_unaligned_u24 (in + 3, in_32[1]);
@@ -669,8 +682,7 @@ GST_START_TEST (test_double_s24)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (6);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 6);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 6) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 6);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S24);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -688,7 +700,7 @@ GST_START_TEST (test_double_s24)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
 
   res_32[0] = get_unaligned_i24 (res);
   res_32[1] = get_unaligned_i24 ((res + 3));
@@ -696,6 +708,7 @@ GST_START_TEST (test_double_s24)
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out_32[0], out_32[1],
       res_32[0], res_32[1]);
   fail_unless (memcmp (res_32, out_32, 8) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -715,6 +728,7 @@ GST_START_TEST (test_mute_s24)
   guint8 *res;
   gint32 res_32[2];
   gint32 out_32[2] = { 0, 0 };  /* notice the clamped sample */
+  gsize size;
 
   write_unaligned_u24 (in, in_32[0]);
   write_unaligned_u24 (in + 3, in_32[1]);
@@ -726,8 +740,7 @@ GST_START_TEST (test_mute_s24)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (6);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 6);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 6) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 6);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S24);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -746,7 +759,7 @@ GST_START_TEST (test_mute_s24)
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
 
-  res = GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
 
   res_32[0] = get_unaligned_i24 (res);
   res_32[1] = get_unaligned_i24 ((res + 3));
@@ -754,6 +767,7 @@ GST_START_TEST (test_mute_s24)
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out_32[0], out_32[1],
       res_32[0], res_32[1]);
   fail_unless (memcmp (res_32, out_32, 8) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -768,6 +782,7 @@ GST_START_TEST (test_unity_s32)
   GstCaps *caps;
   gint32 in[2] = { 1073741824, -65536 };
   gint32 *res;
+  gsize size;
 
   volume = setup_volume ();
   fail_unless (gst_element_set_state (volume,
@@ -775,7 +790,7 @@ GST_START_TEST (test_unity_s32)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (8);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 8);
+  gst_buffer_fill (inbuffer, 0, in, 8);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S32);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -788,9 +803,10 @@ GST_START_TEST (test_unity_s32)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gint32 *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", in[0], in[1], res[0], res[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 8) == 0);
+  fail_unless (memcmp (res, in, 8) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -807,6 +823,7 @@ GST_START_TEST (test_half_s32)
   gint32 in[2] = { 1073741824, -65536 };
   gint32 out[2] = { 536870912, -32768 };
   gint32 *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
@@ -815,8 +832,7 @@ GST_START_TEST (test_half_s32)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (8);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 8);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 8) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 8);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S32);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -834,10 +850,11 @@ GST_START_TEST (test_half_s32)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gint32 *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
       res[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 8) == 0);
+  fail_unless (memcmp (res, out, 8) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -854,6 +871,7 @@ GST_START_TEST (test_double_s32)
   gint32 in[2] = { 1073741824, -65536 };
   gint32 out[2] = { 2147483647, -131072 };      /* notice the clamped sample */
   gint32 *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
@@ -862,8 +880,7 @@ GST_START_TEST (test_double_s32)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (8);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 8);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 8) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 8);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S32);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -881,10 +898,11 @@ GST_START_TEST (test_double_s32)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gint32 *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
       res[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 8) == 0);
+  fail_unless (memcmp (res, out, 8) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -902,6 +920,7 @@ GST_START_TEST (test_mute_s32)
   gint32 in[2] = { 1073741824, -65536 };
   gint32 out[2] = { 0, 0 };
   gint32 *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
@@ -910,8 +929,7 @@ GST_START_TEST (test_mute_s32)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (8);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 8);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 8) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 8);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S32);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -929,10 +947,11 @@ GST_START_TEST (test_mute_s32)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gint32 *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
       res[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 8) == 0);
+  fail_unless (memcmp (res, out, 8) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -947,6 +966,7 @@ GST_START_TEST (test_unity_f32)
   GstCaps *caps;
   gfloat in[2] = { 0.75, -0.25 };
   gfloat *res;
+  gsize size;
 
   volume = setup_volume ();
   fail_unless (gst_element_set_state (volume,
@@ -954,7 +974,7 @@ GST_START_TEST (test_unity_f32)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (8);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 8);
+  gst_buffer_fill (inbuffer, 0, in, 8);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F32);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -967,7 +987,7 @@ GST_START_TEST (test_unity_f32)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gfloat *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", in[0], in[1], res[0],
       res[1]);
   fail_unless_equals_float (res[0], in[0]);
@@ -988,6 +1008,7 @@ GST_START_TEST (test_half_f32)
   gfloat in[2] = { 0.75, -0.25 };
   gfloat out[2] = { 0.375, -0.125 };
   gfloat *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
@@ -996,8 +1017,7 @@ GST_START_TEST (test_half_f32)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (8);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 8);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 8) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 8);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F32);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -1015,11 +1035,12 @@ GST_START_TEST (test_half_f32)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gfloat *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", out[0], out[1],
       res[0], res[1]);
   fail_unless_equals_float (res[0], out[0]);
   fail_unless_equals_float (res[1], out[1]);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -1036,6 +1057,7 @@ GST_START_TEST (test_double_f32)
   gfloat in[2] = { 0.75, -0.25 };
   gfloat out[2] = { 1.5, -0.5 };        /* nothing is clamped */
   gfloat *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
@@ -1044,8 +1066,7 @@ GST_START_TEST (test_double_f32)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (8);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 8);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 8) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 8);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F32);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -1063,11 +1084,12 @@ GST_START_TEST (test_double_f32)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gfloat *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", out[0], out[1],
       res[0], res[1]);
   fail_unless_equals_float (res[0], out[0]);
   fail_unless_equals_float (res[1], out[1]);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -1085,6 +1107,7 @@ GST_START_TEST (test_mute_f32)
   gfloat in[2] = { 0.75, -0.25 };
   gfloat out[2] = { 0, 0 };
   gfloat *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
@@ -1093,8 +1116,7 @@ GST_START_TEST (test_mute_f32)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (8);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 8);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 8) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 8);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F32);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -1112,11 +1134,12 @@ GST_START_TEST (test_mute_f32)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gfloat *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", out[0], out[1],
       res[0], res[1]);
   fail_unless_equals_float (res[0], out[0]);
   fail_unless_equals_float (res[1], out[1]);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -1131,6 +1154,7 @@ GST_START_TEST (test_unity_f64)
   GstCaps *caps;
   gdouble in[2] = { 0.75, -0.25 };
   gdouble *res;
+  gsize size;
 
   volume = setup_volume ();
   fail_unless (gst_element_set_state (volume,
@@ -1138,7 +1162,7 @@ GST_START_TEST (test_unity_f64)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (16);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 16);
+  gst_buffer_fill (inbuffer, 0, in, 16);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F64);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -1151,7 +1175,7 @@ GST_START_TEST (test_unity_f64)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gdouble *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", in[0], in[1], res[0],
       res[1]);
   fail_unless_equals_float (res[0], in[0]);
@@ -1172,6 +1196,7 @@ GST_START_TEST (test_half_f64)
   gdouble in[2] = { 0.75, -0.25 };
   gdouble out[2] = { 0.375, -0.125 };
   gdouble *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
@@ -1180,8 +1205,7 @@ GST_START_TEST (test_half_f64)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (16);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 16);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 16) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 16);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F64);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -1199,11 +1223,12 @@ GST_START_TEST (test_half_f64)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gdouble *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", out[0], out[1],
       res[0], res[1]);
   fail_unless_equals_float (res[0], out[0]);
   fail_unless_equals_float (res[1], out[1]);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -1220,6 +1245,7 @@ GST_START_TEST (test_double_f64)
   gdouble in[2] = { 0.75, -0.25 };
   gdouble out[2] = { 1.5, -0.5 };       /* nothing is clamped */
   gdouble *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
@@ -1228,8 +1254,7 @@ GST_START_TEST (test_double_f64)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (16);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 16);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 16) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 16);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F64);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -1247,11 +1272,12 @@ GST_START_TEST (test_double_f64)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gdouble *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", out[0], out[1],
       res[0], res[1]);
   fail_unless_equals_float (res[0], out[0]);
   fail_unless_equals_float (res[1], out[1]);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -1269,6 +1295,7 @@ GST_START_TEST (test_mute_f64)
   gdouble in[2] = { 0.75, -0.25 };
   gdouble out[2] = { 0, 0 };
   gdouble *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
@@ -1277,8 +1304,7 @@ GST_START_TEST (test_mute_f64)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (16);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 16);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 16) == 0);
+  gst_buffer_fill (inbuffer, 0, in, 16);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F64);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -1296,11 +1322,12 @@ GST_START_TEST (test_mute_f64)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gdouble *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", out[0], out[1],
       res[0], res[1]);
   fail_unless_equals_float (res[0], out[0]);
   fail_unless_equals_float (res[1], out[1]);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -1325,7 +1352,7 @@ GST_START_TEST (test_wrong_caps)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 4);
+  gst_buffer_fill (inbuffer, 0, in, 4);
   caps = gst_caps_from_string (VOLUME_WRONG_CAPS_STRING);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -1362,6 +1389,7 @@ GST_START_TEST (test_passthrough)
   GstCaps *caps;
   gint16 in[2] = { 16384, -256 };
   gint16 *res;
+  gsize size;
 
   volume = setup_volume ();
   g_object_set (G_OBJECT (volume), "volume", 1.0, NULL);
@@ -1370,7 +1398,7 @@ GST_START_TEST (test_passthrough)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 4);
+  gst_buffer_fill (inbuffer, 0, in, 4);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
   gst_buffer_set_caps (inbuffer, caps);
   gst_caps_unref (caps);
@@ -1383,9 +1411,10 @@ GST_START_TEST (test_passthrough)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gint16 *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", in[0], in[1], res[0], res[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 4) == 0);
+  fail_unless (memcmp (res, in, 4) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   /* cleanup */
   cleanup_volume (volume);
@@ -1439,6 +1468,7 @@ GST_START_TEST (test_controller_processing)
   GstCaps *caps;
   gint16 in[2] = { 16384, -256 };
   gint16 *res;
+  gsize size;
 
   volume = setup_volume ();
 
@@ -1457,7 +1487,7 @@ GST_START_TEST (test_controller_processing)
       "could not set to playing");
 
   inbuffer = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (inbuffer), in, 4);
+  gst_buffer_fill (inbuffer, 0, in, 4);
   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
   gst_buffer_set_caps (inbuffer, caps);
   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
@@ -1471,9 +1501,10 @@ GST_START_TEST (test_controller_processing)
   fail_unless_equals_int (g_list_length (buffers), 1);
   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
   fail_unless (inbuffer == outbuffer);
-  res = (gint16 *) GST_BUFFER_DATA (outbuffer);
+  res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", in[0], in[1], res[0], res[1]);
-  fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 4) == 0);
+  fail_unless (memcmp (res, in, 4) == 0);
+  gst_buffer_unmap (outbuffer, res, size);
 
   g_object_unref (c);
 
index 29e3cd5..ecdc329 100644 (file)
@@ -147,7 +147,7 @@ GST_START_TEST (test_identification_header)
   bus = gst_bus_new ();
 
   inbuffer = gst_buffer_new_and_alloc (30);
-  memcpy (GST_BUFFER_DATA (inbuffer), identification_header, 30);
+  gst_buffer_fill (inbuffer, 0, identification_header, 30);
   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
   gst_buffer_ref (inbuffer);
 
@@ -161,7 +161,7 @@ GST_START_TEST (test_identification_header)
   fail_if ((message = gst_bus_pop (bus)) != NULL);
 
   inbuffer = gst_buffer_new_and_alloc (sizeof (comment_header));
-  memcpy (GST_BUFFER_DATA (inbuffer), comment_header, sizeof (comment_header));
+  gst_buffer_fill (inbuffer, 0, comment_header, sizeof (comment_header));
   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
   gst_buffer_ref (inbuffer);
 
@@ -214,7 +214,7 @@ _create_codebook_header_buffer (void)
   vorbis_analysis_headerout (&vd, &vc, &header, &header_comm, &header_code);
 
   buffer = gst_buffer_new_and_alloc (header_code.bytes);
-  memcpy (GST_BUFFER_DATA (buffer), header_code.packet, header_code.bytes);
+  gst_buffer_fill (buffer, 0, header_code.packet, header_code.bytes);
 
   return buffer;
 }
@@ -236,7 +236,7 @@ _create_audio_buffer (void)
   vorbis_bitrate_addblock (&vb);
   vorbis_bitrate_flushpacket (&vd, &packet);
   buffer = gst_buffer_new_and_alloc (packet.bytes);
-  memcpy (GST_BUFFER_DATA (buffer), packet.packet, packet.bytes);
+  gst_buffer_fill (buffer, 0, packet.packet, packet.bytes);
 
   vorbis_comment_clear (&vc);
   vorbis_block_clear (&vb);
@@ -260,7 +260,7 @@ GST_START_TEST (test_empty_vorbis_packet)
   bus = gst_bus_new ();
 
   inbuffer = gst_buffer_new_and_alloc (30);
-  memcpy (GST_BUFFER_DATA (inbuffer), identification_header, 30);
+  gst_buffer_fill (inbuffer, 0, identification_header, 30);
   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
   gst_buffer_ref (inbuffer);
 
@@ -275,7 +275,7 @@ GST_START_TEST (test_empty_vorbis_packet)
   fail_if ((message = gst_bus_pop (bus)) != NULL);
 
   inbuffer = gst_buffer_new_and_alloc (sizeof (comment_header));
-  memcpy (GST_BUFFER_DATA (inbuffer), comment_header, sizeof (comment_header));
+  gst_buffer_fill (inbuffer, 0, comment_header, sizeof (comment_header));
   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
   gst_buffer_ref (inbuffer);
 
index 4b20d6d..dd1841b 100644 (file)
@@ -160,6 +160,18 @@ stop_pipeline (GstElement * element)
   pending_buffers = NULL;
 }
 
+static void
+compare_buffer (GstBuffer * buf, const guint8 * data, gsize size)
+{
+  guint8 *bdata;
+  gsize bsize;
+
+  bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+  fail_unless_equals_int (bsize, size);
+  fail_unless_equals_int (memcmp (bdata, data, size), 0);
+  gst_buffer_unmap (buf, bdata, bsize);
+}
+
 static vorbis_comment vc;
 static vorbis_dsp_state vd;
 static vorbis_info vi;
@@ -182,7 +194,7 @@ _create_codebook_header_buffer (void)
   vorbis_analysis_headerout (&vd, &vc, &header, &header_comm, &header_code);
 
   buffer = gst_buffer_new_and_alloc (header_code.bytes);
-  memcpy (GST_BUFFER_DATA (buffer), header_code.packet, header_code.bytes);
+  gst_buffer_fill (buffer, 0, header_code.packet, header_code.bytes);
 
   return buffer;
 }
@@ -201,7 +213,7 @@ _create_audio_buffer (void)
   vorbis_bitrate_addblock (&vb);
   vorbis_bitrate_flushpacket (&vd, &packet);
   buffer = gst_buffer_new_and_alloc (packet.bytes);
-  memcpy (GST_BUFFER_DATA (buffer), packet.packet, packet.bytes);
+  gst_buffer_fill (buffer, 0, packet.packet, packet.bytes);
 
   vorbis_comment_clear (&vc);
   vorbis_block_clear (&vb);
@@ -232,13 +244,13 @@ GST_START_TEST (test_empty_tags_set)
 
   /* send identification header */
   inbuffer = gst_buffer_new_and_alloc (sizeof (identification_header));
-  memcpy (GST_BUFFER_DATA (inbuffer), identification_header,
+  gst_buffer_fill (inbuffer, 0, identification_header,
       sizeof (identification_header));
   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
 
   /* send empty comment buffer */
   inbuffer = gst_buffer_new_and_alloc (sizeof (empty_comment_header));
-  memcpy (GST_BUFFER_DATA (inbuffer), empty_comment_header,
+  gst_buffer_fill (inbuffer, 0, empty_comment_header,
       sizeof (empty_comment_header));
   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
 
@@ -251,18 +263,14 @@ GST_START_TEST (test_empty_tags_set)
 
   /* check identification header is unchanged */
   outbuffer = get_buffer ();
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer),
+  compare_buffer (outbuffer, identification_header,
       sizeof (identification_header));
-  fail_unless_equals_int (memcmp (GST_BUFFER_DATA (outbuffer),
-          identification_header, sizeof (identification_header)), 0);
   gst_buffer_unref (outbuffer);
 
   /* check comment header is correct */
   outbuffer = get_buffer ();
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer),
+  compare_buffer (outbuffer, title_comment_header,
       sizeof (title_comment_header));
-  fail_unless_equals_int (memcmp (GST_BUFFER_DATA (outbuffer),
-          title_comment_header, sizeof (title_comment_header)), 0);
   gst_buffer_unref (outbuffer);
 
   stop_pipeline (vorbistag);
@@ -291,13 +299,13 @@ GST_START_TEST (test_filled_tags_unset)
 
   /* send identification header */
   inbuffer = gst_buffer_new_and_alloc (sizeof (identification_header));
-  memcpy (GST_BUFFER_DATA (inbuffer), identification_header,
+  gst_buffer_fill (inbuffer, 0, identification_header,
       sizeof (identification_header));
   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
 
   /* send empty comment buffer */
   inbuffer = gst_buffer_new_and_alloc (sizeof (title_comment_header));
-  memcpy (GST_BUFFER_DATA (inbuffer), title_comment_header,
+  gst_buffer_fill (inbuffer, 0, title_comment_header,
       sizeof (title_comment_header));
   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
 
@@ -310,18 +318,14 @@ GST_START_TEST (test_filled_tags_unset)
 
   /* check identification header is unchanged */
   outbuffer = get_buffer ();
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer),
+  compare_buffer (outbuffer, identification_header,
       sizeof (identification_header));
-  fail_unless_equals_int (memcmp (GST_BUFFER_DATA (outbuffer),
-          identification_header, sizeof (identification_header)), 0);
   gst_buffer_unref (outbuffer);
 
   /* check comment header is correct */
   outbuffer = get_buffer ();
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer),
+  compare_buffer (outbuffer, empty_comment_header,
       sizeof (empty_comment_header));
-  fail_unless_equals_int (memcmp (GST_BUFFER_DATA (outbuffer),
-          empty_comment_header, sizeof (empty_comment_header)), 0);
   gst_buffer_unref (outbuffer);
 
   stop_pipeline (vorbistag);
@@ -351,13 +355,13 @@ GST_START_TEST (test_filled_tags_change)
 
   /* send identification header */
   inbuffer = gst_buffer_new_and_alloc (sizeof (identification_header));
-  memcpy (GST_BUFFER_DATA (inbuffer), identification_header,
+  gst_buffer_fill (inbuffer, 0, identification_header,
       sizeof (identification_header));
   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
 
   /* send empty comment buffer */
   inbuffer = gst_buffer_new_and_alloc (sizeof (artist_comment_header));
-  memcpy (GST_BUFFER_DATA (inbuffer), artist_comment_header,
+  gst_buffer_fill (inbuffer, 0, artist_comment_header,
       sizeof (artist_comment_header));
   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
 
@@ -370,18 +374,14 @@ GST_START_TEST (test_filled_tags_change)
 
   /* check identification header is unchanged */
   outbuffer = get_buffer ();
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer),
+  compare_buffer (outbuffer, identification_header,
       sizeof (identification_header));
-  fail_unless_equals_int (memcmp (GST_BUFFER_DATA (outbuffer),
-          identification_header, sizeof (identification_header)), 0);
   gst_buffer_unref (outbuffer);
 
   /* check comment header is correct */
   outbuffer = get_buffer ();
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer),
+  compare_buffer (outbuffer, title_comment_header,
       sizeof (title_comment_header));
-  fail_unless_equals_int (memcmp (GST_BUFFER_DATA (outbuffer),
-          title_comment_header, sizeof (title_comment_header)), 0);
   gst_buffer_unref (outbuffer);
 
   stop_pipeline (vorbistag);
index c53c671..29dec13 100644 (file)
@@ -62,8 +62,11 @@ GST_START_TEST (test_quicktime_mpeg4video)
   GstCaps *caps = NULL;
 
   buf = gst_buffer_new ();
-  GST_BUFFER_DATA (buf) = (guint8 *) qt_redirect_396042;
-  GST_BUFFER_SIZE (buf) = sizeof (qt_redirect_396042);
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          (gpointer) qt_redirect_396042, NULL,
+          sizeof (qt_redirect_396042), 0, sizeof (qt_redirect_396042)));
+
   GST_BUFFER_OFFSET (buf) = 0;
 
   caps = gst_type_find_helper_for_buffer (NULL, buf, &prob);
@@ -89,8 +92,11 @@ GST_START_TEST (test_broken_flac_in_ogg)
   GstCaps *caps = NULL;
 
   buf = gst_buffer_new ();
-  GST_BUFFER_DATA (buf) = (guint8 *) flac_id_packet;
-  GST_BUFFER_SIZE (buf) = sizeof (flac_id_packet);
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          (gpointer) flac_id_packet, NULL,
+          sizeof (flac_id_packet), 0, sizeof (flac_id_packet)));
+
   GST_BUFFER_OFFSET (buf) = 0;
 
   caps = gst_type_find_helper_for_buffer (NULL, buf, &prob);
@@ -123,8 +129,10 @@ typefind_test_file (const gchar * filename)
   }
 
   buf = gst_buffer_new ();
-  GST_BUFFER_DATA (buf) = (guint8 *) data;
-  GST_BUFFER_SIZE (buf) = data_len;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          (gpointer) data, NULL, data_len, 0, data_len));
+
   GST_BUFFER_OFFSET (buf) = 0;
 
   caps = gst_type_find_helper_for_buffer (NULL, buf, NULL);
@@ -222,11 +230,14 @@ GST_START_TEST (test_ac3)
   GstBuffer *buf;
   GstCaps *caps = NULL;
   guint bsid;
+  guint8 *data;
 
   for (bsid = 0; bsid < 32; bsid++) {
     buf = gst_buffer_new_and_alloc ((256 + 640) * 2);
-    make_ac3_packet (GST_BUFFER_DATA (buf), 256 * 2, bsid);
-    make_ac3_packet (GST_BUFFER_DATA (buf) + 256 * 2, 640 * 2, bsid);
+    data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+    make_ac3_packet (data, 256 * 2, bsid);
+    make_ac3_packet (data + 256 * 2, 640 * 2, bsid);
+    gst_buffer_unmap (buf, data, (256 + 640) * 2);
 
     caps = gst_type_find_helper_for_buffer (NULL, buf, &prob);
     if (bsid <= 8) {
@@ -281,11 +292,14 @@ GST_START_TEST (test_eac3)
   GstBuffer *buf;
   GstCaps *caps = NULL;
   guint bsid;
+  guint8 *data;
 
   for (bsid = 0; bsid <= 32; bsid++) {
     buf = gst_buffer_new_and_alloc (558 + 384);
-    make_eac3_packet (GST_BUFFER_DATA (buf), 558, bsid);
-    make_eac3_packet (GST_BUFFER_DATA (buf) + 558, 384, bsid);
+    data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+    make_eac3_packet (data, 558, bsid);
+    make_eac3_packet (data + 558, 384, bsid);
+    gst_buffer_unmap (buf, data, 558 + 384);
 
     caps = gst_type_find_helper_for_buffer (NULL, buf, &prob);
     if (bsid > 10 && bsid <= 16) {
@@ -335,8 +349,10 @@ GST_START_TEST (test_random_data)
     data[i] = g_random_int () & 0xff;
 
   buf = gst_buffer_new ();
-  GST_BUFFER_DATA (buf) = (guint8 *) data;
-  GST_BUFFER_SIZE (buf) = TEST_RANDOM_DATA_SIZE;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          data, NULL, TEST_RANDOM_DATA_SIZE, 0, TEST_RANDOM_DATA_SIZE));
+
   GST_BUFFER_OFFSET (buf) = 0;
 
   caps = gst_type_find_helper_for_buffer (NULL, buf, &prob);
index f5fab57..68bb6f8 100644 (file)
@@ -127,18 +127,16 @@ GST_END_TEST;
 GST_START_TEST (test_buffer_clipping_time)
 {
   GstSegment s;
-
   GstBuffer *buf;
-
   GstBuffer *ret;
-
-  guint8 *data;
+  guint8 *data, *sdata;
+  gsize ssize;
 
   /* Clip start and end */
   buf = gst_buffer_new ();
   data = (guint8 *) g_malloc (1000);
-  GST_BUFFER_SIZE (buf) = 1000;
-  GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = data;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (0, data, g_free, 1000, 0, 1000));
 
   gst_segment_init (&s, GST_FORMAT_TIME);
   gst_segment_set_newsegment (&s, FALSE, 1.0, GST_FORMAT_TIME, 4 * GST_SECOND,
@@ -156,16 +154,18 @@ GST_START_TEST (test_buffer_clipping_time)
   fail_unless (GST_BUFFER_DURATION (ret) == 4 * GST_SECOND);
   fail_unless (GST_BUFFER_OFFSET (ret) == 400);
   fail_unless (GST_BUFFER_OFFSET_END (ret) == 800);
-  fail_unless (GST_BUFFER_DATA (ret) == data + 200);
-  fail_unless (GST_BUFFER_SIZE (ret) == 400);
+  sdata = gst_buffer_map (ret, &ssize, NULL, GST_MAP_READ);
+  fail_unless (sdata == data + 200);
+  fail_unless (ssize == 400);
+  gst_buffer_unmap (ret, sdata, ssize);
 
   gst_buffer_unref (ret);
 
   /* Clip only start */
   buf = gst_buffer_new ();
   data = (guint8 *) g_malloc (1000);
-  GST_BUFFER_SIZE (buf) = 1000;
-  GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = data;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (0, data, g_free, 1000, 0, 1000));
 
   gst_segment_init (&s, GST_FORMAT_TIME);
   gst_segment_set_newsegment (&s, FALSE, 1.0, GST_FORMAT_TIME, 4 * GST_SECOND,
@@ -183,16 +183,18 @@ GST_START_TEST (test_buffer_clipping_time)
   fail_unless (GST_BUFFER_DURATION (ret) == 8 * GST_SECOND);
   fail_unless (GST_BUFFER_OFFSET (ret) == 400);
   fail_unless (GST_BUFFER_OFFSET_END (ret) == 1200);
-  fail_unless (GST_BUFFER_DATA (ret) == data + 200);
-  fail_unless (GST_BUFFER_SIZE (ret) == 800);
+  sdata = gst_buffer_map (ret, &ssize, NULL, GST_MAP_READ);
+  fail_unless (sdata == data + 200);
+  fail_unless (ssize == 800);
+  gst_buffer_unmap (ret, sdata, ssize);
 
   gst_buffer_unref (ret);
 
   /* Clip only stop */
   buf = gst_buffer_new ();
   data = (guint8 *) g_malloc (1000);
-  GST_BUFFER_SIZE (buf) = 1000;
-  GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = data;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (0, data, g_free, 1000, 0, 1000));
 
   gst_segment_init (&s, GST_FORMAT_TIME);
   gst_segment_set_newsegment (&s, FALSE, 1.0, GST_FORMAT_TIME, 2 * GST_SECOND,
@@ -210,16 +212,18 @@ GST_START_TEST (test_buffer_clipping_time)
   fail_unless (GST_BUFFER_DURATION (ret) == 8 * GST_SECOND);
   fail_unless (GST_BUFFER_OFFSET (ret) == 200);
   fail_unless (GST_BUFFER_OFFSET_END (ret) == 1000);
-  fail_unless (GST_BUFFER_DATA (ret) == data);
-  fail_unless (GST_BUFFER_SIZE (ret) == 800);
+  sdata = gst_buffer_map (ret, &ssize, NULL, GST_MAP_READ);
+  fail_unless (sdata == data);
+  fail_unless (ssize == 800);
+  gst_buffer_unmap (ret, sdata, ssize);
 
   gst_buffer_unref (ret);
 
   /* Buffer outside segment */
   buf = gst_buffer_new ();
   data = (guint8 *) g_malloc (1000);
-  GST_BUFFER_SIZE (buf) = 1000;
-  GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = data;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (0, data, g_free, 1000, 0, 1000));
 
   gst_segment_init (&s, GST_FORMAT_TIME);
   gst_segment_set_newsegment (&s, FALSE, 1.0, GST_FORMAT_TIME, 12 * GST_SECOND,
@@ -236,8 +240,8 @@ GST_START_TEST (test_buffer_clipping_time)
   /* Clip start and end but don't touch duration and offset_end */
   buf = gst_buffer_new ();
   data = (guint8 *) g_malloc (1000);
-  GST_BUFFER_SIZE (buf) = 1000;
-  GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = data;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (0, data, g_free, 1000, 0, 1000));
 
   gst_segment_init (&s, GST_FORMAT_TIME);
   gst_segment_set_newsegment (&s, FALSE, 1.0, GST_FORMAT_TIME, 4 * GST_SECOND,
@@ -255,8 +259,10 @@ GST_START_TEST (test_buffer_clipping_time)
   fail_unless (GST_BUFFER_DURATION (ret) == GST_CLOCK_TIME_NONE);
   fail_unless (GST_BUFFER_OFFSET (ret) == 400);
   fail_unless (GST_BUFFER_OFFSET_END (ret) == GST_BUFFER_OFFSET_NONE);
-  fail_unless (GST_BUFFER_DATA (ret) == data + 200);
-  fail_unless (GST_BUFFER_SIZE (ret) == 400);
+  sdata = gst_buffer_map (ret, &ssize, NULL, GST_MAP_READ);
+  fail_unless (sdata == data + 200);
+  fail_unless (ssize == 400);
+  gst_buffer_unmap (ret, sdata, ssize);
 
   gst_buffer_unref (ret);
 
@@ -266,8 +272,8 @@ GST_START_TEST (test_buffer_clipping_time)
    */
   buf = gst_buffer_new ();
   data = (guint8 *) g_malloc (1000);
-  GST_BUFFER_SIZE (buf) = 1000;
-  GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = data;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (0, data, g_free, 1000, 0, 1000));
 
   gst_segment_init (&s, GST_FORMAT_TIME);
   gst_segment_set_newsegment (&s, FALSE, 1.0, GST_FORMAT_TIME, 0 * GST_SECOND,
@@ -289,8 +295,8 @@ GST_START_TEST (test_buffer_clipping_time)
    */
   buf = gst_buffer_new ();
   data = (guint8 *) g_malloc (1000);
-  GST_BUFFER_SIZE (buf) = 1000;
-  GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = data;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (0, data, g_free, 1000, 0, 1000));
 
   gst_segment_init (&s, GST_FORMAT_PERCENT);
   gst_segment_set_newsegment (&s, FALSE, 1.0, GST_FORMAT_PERCENT, 0, 10, 0);
@@ -311,18 +317,16 @@ GST_END_TEST;
 GST_START_TEST (test_buffer_clipping_samples)
 {
   GstSegment s;
-
   GstBuffer *buf;
-
   GstBuffer *ret;
-
-  guint8 *data;
+  guint8 *data, *sdata;
+  gsize ssize;
 
   /* Clip start and end */
   buf = gst_buffer_new ();
   data = (guint8 *) g_malloc (1000);
-  GST_BUFFER_SIZE (buf) = 1000;
-  GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = data;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (0, data, g_free, 1000, 0, 1000));
 
   gst_segment_init (&s, GST_FORMAT_DEFAULT);
   gst_segment_set_newsegment (&s, FALSE, 1.0, GST_FORMAT_DEFAULT, 400,
@@ -340,16 +344,18 @@ GST_START_TEST (test_buffer_clipping_samples)
   fail_unless (GST_BUFFER_DURATION (ret) == 4 * GST_SECOND);
   fail_unless (GST_BUFFER_OFFSET (ret) == 400);
   fail_unless (GST_BUFFER_OFFSET_END (ret) == 800);
-  fail_unless (GST_BUFFER_DATA (ret) == data + 200);
-  fail_unless (GST_BUFFER_SIZE (ret) == 400);
+  sdata = gst_buffer_map (ret, &ssize, NULL, GST_MAP_READ);
+  fail_unless (sdata == data + 200);
+  fail_unless (ssize == 400);
+  gst_buffer_unmap (ret, sdata, ssize);
 
   gst_buffer_unref (ret);
 
   /* Clip only start */
   buf = gst_buffer_new ();
   data = (guint8 *) g_malloc (1000);
-  GST_BUFFER_SIZE (buf) = 1000;
-  GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = data;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (0, data, g_free, 1000, 0, 1000));
 
   gst_segment_init (&s, GST_FORMAT_DEFAULT);
   gst_segment_set_newsegment (&s, FALSE, 1.0, GST_FORMAT_DEFAULT, 400,
@@ -367,16 +373,18 @@ GST_START_TEST (test_buffer_clipping_samples)
   fail_unless (GST_BUFFER_DURATION (ret) == 8 * GST_SECOND);
   fail_unless (GST_BUFFER_OFFSET (ret) == 400);
   fail_unless (GST_BUFFER_OFFSET_END (ret) == 1200);
-  fail_unless (GST_BUFFER_DATA (ret) == data + 200);
-  fail_unless (GST_BUFFER_SIZE (ret) == 800);
+  sdata = gst_buffer_map (ret, &ssize, NULL, GST_MAP_READ);
+  fail_unless (sdata == data + 200);
+  fail_unless (ssize == 800);
+  gst_buffer_unmap (ret, sdata, ssize);
 
   gst_buffer_unref (ret);
 
   /* Clip only stop */
   buf = gst_buffer_new ();
   data = (guint8 *) g_malloc (1000);
-  GST_BUFFER_SIZE (buf) = 1000;
-  GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = data;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (0, data, g_free, 1000, 0, 1000));
 
   gst_segment_init (&s, GST_FORMAT_DEFAULT);
   gst_segment_set_newsegment (&s, FALSE, 1.0, GST_FORMAT_DEFAULT, 200,
@@ -394,16 +402,18 @@ GST_START_TEST (test_buffer_clipping_samples)
   fail_unless (GST_BUFFER_DURATION (ret) == 8 * GST_SECOND);
   fail_unless (GST_BUFFER_OFFSET (ret) == 200);
   fail_unless (GST_BUFFER_OFFSET_END (ret) == 1000);
-  fail_unless (GST_BUFFER_DATA (ret) == data);
-  fail_unless (GST_BUFFER_SIZE (ret) == 800);
+  sdata = gst_buffer_map (ret, &ssize, NULL, GST_MAP_READ);
+  fail_unless (sdata == data);
+  fail_unless (ssize == 800);
+  gst_buffer_unmap (ret, sdata, ssize);
 
   gst_buffer_unref (ret);
 
   /* Buffer outside segment */
   buf = gst_buffer_new ();
   data = (guint8 *) g_malloc (1000);
-  GST_BUFFER_SIZE (buf) = 1000;
-  GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = data;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (0, data, g_free, 1000, 0, 1000));
 
   gst_segment_init (&s, GST_FORMAT_DEFAULT);
   gst_segment_set_newsegment (&s, FALSE, 1.0, GST_FORMAT_DEFAULT, 1200,
@@ -420,8 +430,8 @@ GST_START_TEST (test_buffer_clipping_samples)
   /* Clip start and end but don't touch duration and offset_end */
   buf = gst_buffer_new ();
   data = (guint8 *) g_malloc (1000);
-  GST_BUFFER_SIZE (buf) = 1000;
-  GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = data;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (0, data, g_free, 1000, 0, 1000));
 
   gst_segment_init (&s, GST_FORMAT_DEFAULT);
   gst_segment_set_newsegment (&s, FALSE, 1.0, GST_FORMAT_DEFAULT, 400,
@@ -439,8 +449,10 @@ GST_START_TEST (test_buffer_clipping_samples)
   fail_unless (GST_BUFFER_DURATION (ret) == GST_CLOCK_TIME_NONE);
   fail_unless (GST_BUFFER_OFFSET (ret) == 400);
   fail_unless (GST_BUFFER_OFFSET_END (ret) == GST_BUFFER_OFFSET_NONE);
-  fail_unless (GST_BUFFER_DATA (ret) == data + 200);
-  fail_unless (GST_BUFFER_SIZE (ret) == 400);
+  sdata = gst_buffer_map (ret, &ssize, NULL, GST_MAP_READ);
+  fail_unless (sdata == data + 200);
+  fail_unless (ssize == 400);
+  gst_buffer_unmap (ret, sdata, ssize);
 
   gst_buffer_unref (ret);
 
@@ -450,8 +462,8 @@ GST_START_TEST (test_buffer_clipping_samples)
    */
   buf = gst_buffer_new ();
   data = (guint8 *) g_malloc (1000);
-  GST_BUFFER_SIZE (buf) = 1000;
-  GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = data;
+  gst_buffer_take_memory (buf,
+      gst_memory_new_wrapped (0, data, g_free, 1000, 0, 1000));
 
   gst_segment_init (&s, GST_FORMAT_DEFAULT);
   gst_segment_set_newsegment (&s, FALSE, 1.0, GST_FORMAT_DEFAULT, 0, 10, 0);
index 8747c9a..1c60c11 100644 (file)
@@ -183,8 +183,7 @@ struct _GstCdFooSrcClass
 };
 
 GType gst_cd_foo_src_get_type (void);
-GST_BOILERPLATE (GstCdFooSrc, gst_cd_foo_src, GstCddaBaseSrc,
-    GST_TYPE_CDDA_BASE_SRC);
+G_DEFINE_TYPE (GstCdFooSrc, gst_cd_foo_src, GST_TYPE_CDDA_BASE_SRC);
 
 static GstBuffer *gst_cd_foo_src_read_sector (GstCddaBaseSrc * src,
     gint sector);
@@ -193,17 +192,7 @@ static gboolean gst_cd_foo_src_open (GstCddaBaseSrc * src,
 static void gst_cd_foo_src_close (GstCddaBaseSrc * src);
 
 static void
-gst_cd_foo_src_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class,
-      "CD Audio (cdda) Source, FooBar", "Source/File",
-      "Read audio from CD", "Foo Bar <foo@bar.com>");
-}
-
-static void
-gst_cd_foo_src_init (GstCdFooSrc * src, GstCdFooSrcClass * klass)
+gst_cd_foo_src_init (GstCdFooSrc * src)
 {
   src->cur_disc = 0;
 }
@@ -212,6 +201,11 @@ static void
 gst_cd_foo_src_class_init (GstCdFooSrcClass * klass)
 {
   GstCddaBaseSrcClass *cddabasesrc_class = GST_CDDA_BASE_SRC_CLASS (klass);
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+  gst_element_class_set_details_simple (element_class,
+      "CD Audio (cdda) Source, FooBar", "Source/File",
+      "Read audio from CD", "Foo Bar <foo@bar.com>");
 
   cddabasesrc_class->open = gst_cd_foo_src_open;
   cddabasesrc_class->close = gst_cd_foo_src_close;
@@ -260,9 +254,12 @@ static GstBuffer *
 gst_cd_foo_src_read_sector (GstCddaBaseSrc * cddabasesrc, gint sector)
 {
   GstBuffer *buf;
+  guint8 *data;
 
   buf = gst_buffer_new_and_alloc (CD_FRAMESIZE_RAW);
-  memset (GST_BUFFER_DATA (buf), 0, CD_FRAMESIZE_RAW);
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+  memset (data, 0, CD_FRAMESIZE_RAW);
+  gst_buffer_unmap (buf, data, CD_FRAMESIZE_RAW);
 
   return buf;
 }
index aa80624..3cea168 100644 (file)
@@ -24,7 +24,6 @@
 #include <gst/gst.h>
 #include <gst/check/gstcheck.h>
 
-#include <gst/app/gstappbuffer.h>
 #include <gst/app/gstapp-marshal.h>
 #include <gst/app/gstappsink.h>
 #include <gst/app/gstappsrc.h>
index e2111ba..bebd67d 100644 (file)
@@ -23,7 +23,6 @@
 #include <config.h>
 #include <gst/check/gstcheck.h>
 
-#include <gst/app/gstappbuffer.h>
 #include <gst/app/gstappsrc.h>
 #include <gst/app/gstappsink.h>
 #include <gst/audio/audio.h>
 #endif
 #endif
 
+/* disabled for 0.11 */
+#undef HAVE_ABI_SIZES
+#define HAVE_ABI_SIZES FALSE
+
 GST_START_TEST (test_ABI)
 {
   gst_check_abi_list (list, HAVE_ABI_SIZES);
index 2dfd284..a5ed557 100644 (file)
@@ -50,8 +50,8 @@ GType test_element_get_type (void);
 static void init_interface (GType type);
 static void gst_implements_interface_init (GstImplementsInterfaceClass * klass);
 
-GST_BOILERPLATE_FULL (TestElement, test_element, GstElement, GST_TYPE_ELEMENT,
-    init_interface);
+G_DEFINE_TYPE_WITH_CODE (TestElement, test_element, GST_TYPE_ELEMENT,
+    init_interface (g_define_type_id));
 
 static void
 test_element_mixer_interface_init (GstMixerClass * klass)
@@ -79,11 +79,6 @@ init_interface (GType type)
 }
 
 static void
-test_element_base_init (gpointer klass)
-{
-}
-
-static void
 test_element_class_init (TestElementClass * klass)
 {
 }
@@ -105,7 +100,7 @@ gst_implements_interface_init (GstImplementsInterfaceClass * klass)
 }
 
 static void
-test_element_init (TestElement * this, TestElementClass * klass)
+test_element_init (TestElement * this)
 {
 }
 
index e3928d1..db64473 100644 (file)
@@ -58,8 +58,8 @@ static void gst_implements_interface_init (GstImplementsInterfaceClass * klass);
 static void nav_send_event (GstNavigation * navigation,
     GstStructure * structure);
 
-GST_BOILERPLATE_FULL (TestElement, test_element, GstElement, GST_TYPE_ELEMENT,
-    init_interface);
+G_DEFINE_TYPE_WITH_CODE (TestElement, test_element, GST_TYPE_ELEMENT,
+    init_interface (g_define_type_id));
 
 static void
 test_element_navigation_interface_init (GstNavigationInterface * klass)
@@ -88,11 +88,6 @@ init_interface (GType type)
 }
 
 static void
-test_element_base_init (gpointer klass)
-{
-}
-
-static void
 test_element_class_init (TestElementClass * klass)
 {
 }
@@ -114,7 +109,7 @@ gst_implements_interface_init (GstImplementsInterfaceClass * klass)
 }
 
 static void
-test_element_init (TestElement * this, TestElementClass * klass)
+test_element_init (TestElement * this)
 {
 }
 
index 3236a0f..752c224 100644 (file)
@@ -29,7 +29,7 @@
 
 GST_START_TEST (test_netbuffer_copy)
 {
-  GstNetBuffer *netbuf, *copy;
+  GstBuffer *netbuf, *copy;
   guint8 ipv6_addr[16] = { 0xff, 0x11, 0xee, 0x22, 0xdd, 0x33, 0xcc,
     0x44, 0xbb, 0x55, 0xaa, 0x66, 0x00, 0x77, 0x99, 0x88
   };
@@ -38,44 +38,88 @@ GST_START_TEST (test_netbuffer_copy)
   guint16 ipv6_port = 3490;
   guint16 ipv4_port = 5678;
   guint16 port;
+  GstMetaNetAddress *meta, *cmeta;
+  gsize len;
+  guint8 *data1, *data2;
+  gsize size1, size2;
 
-  netbuf = gst_netbuffer_new ();
+  netbuf = gst_buffer_new ();
   fail_unless (netbuf != NULL, "failed to create net buffer");
+  meta = gst_buffer_add_meta_net_address (netbuf);
 
-  gst_netaddress_set_ip4_address (&netbuf->from, ipv4_addr, ipv4_port);
-  gst_netaddress_set_ip6_address (&netbuf->to, ipv6_addr, ipv6_port);
+  gst_netaddress_set_ip4_address (&meta->naddr, ipv4_addr, ipv4_port);
+
+  len = strlen (DATA_STRING);
+  gst_buffer_take_memory (netbuf,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          (gpointer) DATA_STRING, NULL, len, 0, len));
 
-  GST_BUFFER_DATA (netbuf) = (guint8 *) DATA_STRING;
-  GST_BUFFER_SIZE (netbuf) = strlen (DATA_STRING);
   GST_BUFFER_FLAG_SET (netbuf, GST_BUFFER_FLAG_DISCONT);
-  GST_BUFFER_FLAG_SET (netbuf, GST_BUFFER_FLAG_READONLY);
 
-  copy = (GstNetBuffer *) gst_buffer_copy (GST_BUFFER_CAST (netbuf));
+  copy = gst_buffer_copy (netbuf);
   fail_unless (copy != NULL, "failed to copy net buffer");
-  fail_unless (GST_IS_NETBUFFER (copy), "copied buffer is not a GstNetBuffer!");
+
+  cmeta = gst_buffer_get_meta_net_address (copy);
+  fail_unless (cmeta != NULL, "copied buffer is not a GstNetBuffer!");
 
   fail_unless_equals_int (GST_MINI_OBJECT_REFCOUNT_VALUE (copy), 1);
 
-  fail_unless_equals_int (GST_BUFFER_SIZE (copy), GST_BUFFER_SIZE (netbuf));
-  fail_unless (memcmp (GST_BUFFER_DATA (copy), GST_BUFFER_DATA (netbuf),
-          GST_BUFFER_SIZE (copy)) == 0);
+  data1 = gst_buffer_map (netbuf, &size1, NULL, GST_MAP_READ);
+  data2 = gst_buffer_map (copy, &size2, NULL, GST_MAP_READ);
+  fail_unless_equals_int (size1, size2);
+  fail_unless (memcmp (data1, data2, size1) == 0);
+  gst_buffer_unmap (copy, data2, size2);
+  gst_buffer_unmap (netbuf, data1, size1);
 
-  fail_if (GST_BUFFER_FLAG_IS_SET (copy, GST_BUFFER_FLAG_READONLY));
   fail_unless (GST_BUFFER_FLAG_IS_SET (copy, GST_BUFFER_FLAG_DISCONT));
 
-  fail_unless (gst_netaddress_get_ip4_address (&copy->from, &ipv4_copy, &port));
+  fail_unless (gst_netaddress_get_ip4_address (&cmeta->naddr, &ipv4_copy,
+          &port));
   fail_unless (ipv4_copy == ipv4_addr,
       "Copied buffer has wrong IPV4 from address");
   fail_unless (port == ipv4_port, "Copied buffer has wrong IPV4 from port");
+  gst_buffer_unref (netbuf);
+  gst_buffer_unref (copy);
+
+  netbuf = gst_buffer_new ();
+  fail_unless (netbuf != NULL, "failed to create net buffer");
+  meta = gst_buffer_add_meta_net_address (netbuf);
+
+  gst_netaddress_set_ip6_address (&meta->naddr, ipv6_addr, ipv6_port);
+
+  len = strlen (DATA_STRING);
+  gst_buffer_take_memory (netbuf,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          (gpointer) DATA_STRING, NULL, len, 0, len));
+
+  GST_BUFFER_FLAG_SET (netbuf, GST_BUFFER_FLAG_DISCONT);
+
+  copy = gst_buffer_copy (netbuf);
+  fail_unless (copy != NULL, "failed to copy net buffer");
+
+  cmeta = gst_buffer_get_meta_net_address (copy);
+  fail_unless (cmeta != NULL, "copied buffer is not a GstNetBuffer!");
+
+  fail_unless_equals_int (GST_MINI_OBJECT_REFCOUNT_VALUE (copy), 1);
+
+  data1 = gst_buffer_map (netbuf, &size1, NULL, GST_MAP_READ);
+  data2 = gst_buffer_map (copy, &size2, NULL, GST_MAP_READ);
+  fail_unless_equals_int (size1, size2);
+  fail_unless (memcmp (data1, data2, size1) == 0);
+  gst_buffer_unmap (copy, data2, size2);
+  gst_buffer_unmap (netbuf, data1, size1);
+
+  fail_unless (GST_BUFFER_FLAG_IS_SET (copy, GST_BUFFER_FLAG_DISCONT));
 
-  fail_unless (gst_netaddress_get_ip6_address (&copy->to, ipv6_copy, &port));
+  fail_unless (gst_netaddress_get_ip6_address (&cmeta->naddr, ipv6_copy,
+          &port));
   fail_unless (memcmp (ipv6_copy, ipv6_addr, 16) == 0,
       "Copied buffer has wrong IPv6 destination address");
   fail_unless (port == ipv6_port,
       "Copied buffer has wrong IPv6 destination port");
+  gst_buffer_unref (netbuf);
+  gst_buffer_unref (copy);
 
-  gst_buffer_unref (GST_BUFFER_CAST (netbuf));
-  gst_buffer_unref (GST_BUFFER_CAST (copy));
 }
 
 GST_END_TEST;
index 144d9a6..c72f753 100644 (file)
@@ -623,7 +623,7 @@ GST_START_TEST (test_pb_utils_installer_details)
   /* uri source */
   detail1 = gst_missing_uri_source_installer_detail_new ("http");
   fail_unless (detail1 != NULL);
-  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.10|"));
+  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.11|"));
   fail_unless (g_str_has_suffix (detail1, "|urisource-http"));
   msg = gst_missing_uri_source_message_new (el, "http");
   fail_unless (msg != NULL);
@@ -637,7 +637,7 @@ GST_START_TEST (test_pb_utils_installer_details)
   /* uri sink */
   detail1 = gst_missing_uri_sink_installer_detail_new ("http");
   fail_unless (detail1 != NULL);
-  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.10|"));
+  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.11|"));
   fail_unless (g_str_has_suffix (detail1, "|urisink-http"));
   msg = gst_missing_uri_sink_message_new (el, "http");
   fail_unless (msg != NULL);
@@ -651,7 +651,7 @@ GST_START_TEST (test_pb_utils_installer_details)
   /* element */
   detail1 = gst_missing_element_installer_detail_new ("deinterlace");
   fail_unless (detail1 != NULL);
-  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.10|"));
+  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.11|"));
   fail_unless (g_str_has_suffix (detail1, "|element-deinterlace"));
   msg = gst_missing_element_message_new (el, "deinterlace");
   fail_unless (msg != NULL);
@@ -667,7 +667,7 @@ GST_START_TEST (test_pb_utils_installer_details)
       2, "channels", G_TYPE_INT, 6, NULL);
   detail1 = gst_missing_decoder_installer_detail_new (caps);
   fail_unless (detail1 != NULL);
-  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.10|"));
+  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.11|"));
   fail_unless (g_str_has_suffix (detail1,
           "|decoder-audio/x-spiffy, spiffyversion=(int)2"));
   msg = gst_missing_decoder_message_new (el, caps);
@@ -684,7 +684,7 @@ GST_START_TEST (test_pb_utils_installer_details)
   caps = gst_caps_new_simple ("audio/x-spiffy", "spiffyversion", G_TYPE_INT,
       2, "channels", G_TYPE_INT, 6, NULL);
   detail1 = gst_missing_encoder_installer_detail_new (caps);
-  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.10|"));
+  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.11|"));
   fail_unless (g_str_has_suffix (detail1,
           "|encoder-audio/x-spiffy, spiffyversion=(int)2"));
   fail_unless (detail1 != NULL);
index 285a58e..0fe2832 100644 (file)
@@ -289,7 +289,8 @@ GST_START_TEST (test_saving_profile)
   fail_unless (gst_encoding_target_save (orig, NULL));
 
   /* Check we can load it */
-  profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10",
+  profile_file_name =
+      g_build_filename (g_get_user_data_dir (), "gstreamer-0.11",
       "encoding-profiles", "herding", "myponytarget2.gep", NULL);
   GST_DEBUG ("Loading target from '%s'", profile_file_name);
   loaded = gst_encoding_target_load_from_file (profile_file_name, NULL);
@@ -396,7 +397,7 @@ GST_START_TEST (test_loading_profile)
   GstEncodingProfile *profile;
   GstCaps *tmpcaps;
   GValue strvalue = { 0, };
-  GValue miniobjectvalue = { 0, };
+  GValue objectvalue = { 0, };
 
   /* Test loading using short method and all arguments */
   target = gst_encoding_target_load ("myponytarget", "herding", NULL);
@@ -411,7 +412,8 @@ GST_START_TEST (test_loading_profile)
   gst_encoding_target_unref (target);
 
   /* Test loading using fully specified path */
-  profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10",
+  profile_file_name =
+      g_build_filename (g_get_user_data_dir (), "gstreamer-0.11",
       "encoding-profiles", "herding", "myponytarget.gep", NULL);
 
   GST_DEBUG ("Loading target from '%s'", profile_file_name);
@@ -442,13 +444,13 @@ GST_START_TEST (test_loading_profile)
 
   /* For my next trick, I will need the assistance of a GValue */
   g_value_init (&strvalue, G_TYPE_STRING);
-  g_value_init (&miniobjectvalue, GST_TYPE_ENCODING_PROFILE);
+  g_value_init (&objectvalue, GST_TYPE_ENCODING_PROFILE);
   g_value_set_static_string (&strvalue, "myponytarget/pony");
-  fail_unless (g_value_transform (&strvalue, &miniobjectvalue));
-  profile = (GstEncodingProfile *) gst_value_dup_mini_object (&miniobjectvalue);
+  fail_unless (g_value_transform (&strvalue, &objectvalue));
+  profile = (GstEncodingProfile *) g_value_dup_object (&objectvalue);
   fail_if (profile == NULL);
   g_value_unset (&strvalue);
-  g_value_unset (&miniobjectvalue);
+  g_value_unset (&objectvalue);
   tmpcaps = gst_caps_from_string ("animal/x-pony");
   CHECK_PROFILE (profile, "pony", "I don't want a description !", tmpcaps, NULL,
       0, 0);
@@ -489,7 +491,7 @@ GST_START_TEST (test_target_list)
   /* If tmp is NULL, it means we iterated the whole list without finding
    * our target */
   fail_if (tmp == NULL);
-  g_list_foreach (targets, (GFunc) gst_mini_object_unref, NULL);
+  g_list_foreach (targets, (GFunc) g_object_unref, NULL);
   g_list_free (targets);
 
   /* Try getting all available targets without a specified category */
@@ -503,7 +505,7 @@ GST_START_TEST (test_target_list)
   /* If tmp is NULL, it means we iterated the whole list without finding
    * our target */
   fail_if (tmp == NULL);
-  g_list_foreach (targets, (GFunc) gst_mini_object_unref, NULL);
+  g_list_foreach (targets, (GFunc) g_object_unref, NULL);
   g_list_free (targets);
 }
 
@@ -544,11 +546,13 @@ remove_profile_file (void)
 {
   gchar *profile_file_name;
 
-  profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10",
+  profile_file_name =
+      g_build_filename (g_get_user_data_dir (), "gstreamer-0.11",
       "encoding-profiles", "herding", "myponytarget.gep", NULL);
   g_unlink (profile_file_name);
   g_free (profile_file_name);
-  profile_file_name = g_build_filename (g_get_home_dir (), ".gstreamer-0.10",
+  profile_file_name =
+      g_build_filename (g_get_user_data_dir (), "gstreamer-0.11",
       "encoding-profiles", "herding", "myponytarget2.gep", NULL);
   g_unlink (profile_file_name);
   g_free (profile_file_name);
@@ -562,10 +566,10 @@ create_profile_file (void)
   GError *error = NULL;
 
   profile_dir =
-      g_build_filename (g_get_home_dir (), ".gstreamer-0.10",
+      g_build_filename (g_get_user_data_dir (), "gstreamer-0.11",
       "encoding-profiles", "herding", NULL);
   profile_file_name =
-      g_build_filename (g_get_home_dir (), ".gstreamer-0.10",
+      g_build_filename (g_get_user_data_dir (), "gstreamer-0.11",
       "encoding-profiles", "herding", "myponytarget.gep", NULL);
   g_mkdir_with_parents (profile_dir, S_IRUSR | S_IWUSR | S_IXUSR);
   if (!g_file_set_contents (profile_file_name, profile_string,
@@ -597,7 +601,7 @@ profile_suite (void)
   gchar *gst_dir;
 
   /* cehck if we can create profiles */
-  gst_dir = g_build_filename (g_get_home_dir (), ".gstreamer-0.10", NULL);
+  gst_dir = g_build_filename (g_get_user_data_dir (), "gstreamer-0.11", NULL);
   can_write = (g_access (gst_dir, R_OK | W_OK | X_OK) == 0);
   g_free (gst_dir);
 
index defd6b6..a8346c4 100644 (file)
@@ -34,99 +34,109 @@ GST_START_TEST (test_rtp_buffer)
 {
   GstBuffer *buf;
   guint8 *data;
+  gsize size;
+  GstRTPBuffer rtp = { NULL, };
 
   /* check GstRTPHeader structure alignment and packing */
   buf = gst_rtp_buffer_new_allocate (16, 4, 0);
   fail_unless (buf != NULL);
-  fail_unless_equals_int (GST_BUFFER_SIZE (buf), RTP_HEADER_LEN + 16 + 4);
-  data = GST_BUFFER_DATA (buf);
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  fail_unless_equals_int (size, RTP_HEADER_LEN + 16 + 4);
+
+  gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);
 
   /* check defaults */
-  fail_unless_equals_int (gst_rtp_buffer_get_version (buf), 2);
-  fail_unless (gst_rtp_buffer_get_padding (buf) == FALSE);
-  fail_unless (gst_rtp_buffer_get_extension (buf) == FALSE);
-  fail_unless_equals_int (gst_rtp_buffer_get_csrc_count (buf), 0);
-  fail_unless (gst_rtp_buffer_get_marker (buf) == FALSE);
-  fail_unless (gst_rtp_buffer_get_payload_type (buf) == 0);
+  fail_unless_equals_int (gst_rtp_buffer_get_version (&rtp), 2);
+  fail_unless (gst_rtp_buffer_get_padding (&rtp) == FALSE);
+  fail_unless (gst_rtp_buffer_get_extension (&rtp) == FALSE);
+  fail_unless_equals_int (gst_rtp_buffer_get_csrc_count (&rtp), 0);
+  fail_unless (gst_rtp_buffer_get_marker (&rtp) == FALSE);
+  fail_unless (gst_rtp_buffer_get_payload_type (&rtp) == 0);
   fail_unless_equals_int (GST_READ_UINT16_BE (data), 0x8000);
 
   /* check version in bitfield */
-  gst_rtp_buffer_set_version (buf, 3);
-  fail_unless_equals_int (gst_rtp_buffer_get_version (buf), 3);
+  gst_rtp_buffer_set_version (&rtp, 3);
+  fail_unless_equals_int (gst_rtp_buffer_get_version (&rtp), 3);
   fail_unless_equals_int ((data[0] & 0xC0) >> 6, 3);
-  gst_rtp_buffer_set_version (buf, 2);
-  fail_unless_equals_int (gst_rtp_buffer_get_version (buf), 2);
+  gst_rtp_buffer_set_version (&rtp, 2);
+  fail_unless_equals_int (gst_rtp_buffer_get_version (&rtp), 2);
   fail_unless_equals_int ((data[0] & 0xC0) >> 6, 2);
 
   /* check padding bit */
-  gst_rtp_buffer_set_padding (buf, TRUE);
-  fail_unless (gst_rtp_buffer_get_padding (buf) == TRUE);
+  gst_rtp_buffer_set_padding (&rtp, TRUE);
+  fail_unless (gst_rtp_buffer_get_padding (&rtp) == TRUE);
   fail_unless_equals_int ((data[0] & 0x20) >> 5, 1);
-  gst_rtp_buffer_set_padding (buf, FALSE);
-  fail_unless (gst_rtp_buffer_get_padding (buf) == FALSE);
+  gst_rtp_buffer_set_padding (&rtp, FALSE);
+  fail_unless (gst_rtp_buffer_get_padding (&rtp) == FALSE);
   fail_unless_equals_int ((data[0] & 0x20) >> 5, 0);
 
   /* check marker bit */
-  gst_rtp_buffer_set_marker (buf, TRUE);
-  fail_unless (gst_rtp_buffer_get_marker (buf) == TRUE);
+  gst_rtp_buffer_set_marker (&rtp, TRUE);
+  fail_unless (gst_rtp_buffer_get_marker (&rtp) == TRUE);
   fail_unless_equals_int ((data[1] & 0x80) >> 7, 1);
-  gst_rtp_buffer_set_marker (buf, FALSE);
-  fail_unless (gst_rtp_buffer_get_marker (buf) == FALSE);
+  gst_rtp_buffer_set_marker (&rtp, FALSE);
+  fail_unless (gst_rtp_buffer_get_marker (&rtp) == FALSE);
   fail_unless_equals_int ((data[1] & 0x80) >> 7, 0);
 
   /* check sequence offset */
-  gst_rtp_buffer_set_seq (buf, 0xF2C9);
-  fail_unless_equals_int (gst_rtp_buffer_get_seq (buf), 0xF2C9);
+  gst_rtp_buffer_set_seq (&rtp, 0xF2C9);
+  fail_unless_equals_int (gst_rtp_buffer_get_seq (&rtp), 0xF2C9);
   fail_unless_equals_int (GST_READ_UINT16_BE (data + 2), 0xF2C9);
-  gst_rtp_buffer_set_seq (buf, 0);
-  fail_unless_equals_int (gst_rtp_buffer_get_seq (buf), 0);
+  gst_rtp_buffer_set_seq (&rtp, 0);
+  fail_unless_equals_int (gst_rtp_buffer_get_seq (&rtp), 0);
   fail_unless_equals_int (GST_READ_UINT16_BE (data + 2), 0);
 
   /* check timestamp offset */
-  gst_rtp_buffer_set_timestamp (buf, 432191);
+  gst_rtp_buffer_set_timestamp (&rtp, 432191);
   fail_unless_equals_int (GST_READ_UINT32_BE (data + 4), 432191);
-  fail_unless_equals_int (gst_rtp_buffer_get_timestamp (buf), 432191);
-  gst_rtp_buffer_set_timestamp (buf, 0);
-  fail_unless_equals_int (gst_rtp_buffer_get_timestamp (buf), 0);
+  fail_unless_equals_int (gst_rtp_buffer_get_timestamp (&rtp), 432191);
+  gst_rtp_buffer_set_timestamp (&rtp, 0);
+  fail_unless_equals_int (gst_rtp_buffer_get_timestamp (&rtp), 0);
   fail_unless_equals_int (GST_READ_UINT32_BE (data + 4), 0);
 
   /* check ssrc offset */
-  gst_rtp_buffer_set_ssrc (buf, 0xf04043C2);
-  fail_unless_equals_int (gst_rtp_buffer_get_ssrc (buf), (gint) 0xf04043c2);
+  gst_rtp_buffer_set_ssrc (&rtp, 0xf04043C2);
+  fail_unless_equals_int (gst_rtp_buffer_get_ssrc (&rtp), (gint) 0xf04043c2);
   fail_unless_equals_int (GST_READ_UINT32_BE (data + 4 + 4), (gint) 0xf04043c2);
-  gst_rtp_buffer_set_ssrc (buf, 0);
-  fail_unless_equals_int (gst_rtp_buffer_get_ssrc (buf), 0);
+  gst_rtp_buffer_set_ssrc (&rtp, 0);
+  fail_unless_equals_int (gst_rtp_buffer_get_ssrc (&rtp), 0);
   fail_unless_equals_int (GST_READ_UINT32_BE (data + 4 + 4), 0);
 
   /* check csrc bits */
-  fail_unless_equals_int (gst_rtp_buffer_get_csrc_count (buf), 0);
-  ASSERT_CRITICAL (gst_rtp_buffer_get_csrc (buf, 0));
+  fail_unless_equals_int (gst_rtp_buffer_get_csrc_count (&rtp), 0);
+  ASSERT_CRITICAL (gst_rtp_buffer_get_csrc (&rtp, 0));
   fail_unless_equals_int (data[0] & 0xf, 0);
+
+  gst_rtp_buffer_unmap (&rtp);
+  gst_buffer_unmap (buf, data, size);
   gst_buffer_unref (buf);
 
   /* and again, this time with CSRCs */
   buf = gst_rtp_buffer_new_allocate (16, 4, 3);
   fail_unless (buf != NULL);
-  fail_unless_equals_int (GST_BUFFER_SIZE (buf),
-      RTP_HEADER_LEN + 16 + 4 + 4 * 3);
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  fail_unless_equals_int (size, RTP_HEADER_LEN + 16 + 4 + 4 * 3);
 
-  data = GST_BUFFER_DATA (buf);
+  gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);
 
-  fail_unless_equals_int (gst_rtp_buffer_get_csrc_count (buf), 3);
-  ASSERT_CRITICAL (gst_rtp_buffer_get_csrc (buf, 3));
+  fail_unless_equals_int (gst_rtp_buffer_get_csrc_count (&rtp), 3);
+  ASSERT_CRITICAL (gst_rtp_buffer_get_csrc (&rtp, 3));
   fail_unless_equals_int (data[0] & 0xf, 3);
-  fail_unless_equals_int (gst_rtp_buffer_get_csrc (buf, 0), 0);
-  fail_unless_equals_int (gst_rtp_buffer_get_csrc (buf, 1), 0);
-  fail_unless_equals_int (gst_rtp_buffer_get_csrc (buf, 2), 0);
+  fail_unless_equals_int (gst_rtp_buffer_get_csrc (&rtp, 0), 0);
+  fail_unless_equals_int (gst_rtp_buffer_get_csrc (&rtp, 1), 0);
+  fail_unless_equals_int (gst_rtp_buffer_get_csrc (&rtp, 2), 0);
 
   data += RTP_HEADER_LEN;       /* skip the other header stuff */
-  gst_rtp_buffer_set_csrc (buf, 0, 0xf7c0);
+  gst_rtp_buffer_set_csrc (&rtp, 0, 0xf7c0);
   fail_unless_equals_int (GST_READ_UINT32_BE (data + 0 * 4), 0xf7c0);
-  gst_rtp_buffer_set_csrc (buf, 1, 0xf7c1);
+  gst_rtp_buffer_set_csrc (&rtp, 1, 0xf7c1);
   fail_unless_equals_int (GST_READ_UINT32_BE (data + 1 * 4), 0xf7c1);
-  gst_rtp_buffer_set_csrc (buf, 2, 0xf7c2);
+  gst_rtp_buffer_set_csrc (&rtp, 2, 0xf7c2);
   fail_unless_equals_int (GST_READ_UINT32_BE (data + 2 * 4), 0xf7c2);
-  ASSERT_CRITICAL (gst_rtp_buffer_set_csrc (buf, 3, 0xf123));
+  ASSERT_CRITICAL (gst_rtp_buffer_set_csrc (&rtp, 3, 0xf123));
+
+  gst_rtp_buffer_unmap (&rtp);
+  gst_buffer_unmap (buf, data, size);
   gst_buffer_unref (buf);
 }
 
@@ -143,15 +153,15 @@ GST_START_TEST (test_rtp_buffer_validate_corrupt)
     0xb0, 0x97, 0x63, 0x08, 0x10, 0x4b, 0x43, 0x85, 0x37, 0x2c
   };
 
-  buf = gst_buffer_new ();
-  GST_BUFFER_DATA (buf) = corrupt_rtp_packet;
-  GST_BUFFER_SIZE (buf) = sizeof (corrupt_rtp_packet);
+  buf = gst_buffer_new_and_alloc (sizeof (corrupt_rtp_packet));
+  gst_buffer_fill (buf, 0, corrupt_rtp_packet, sizeof (corrupt_rtp_packet));
   fail_if (gst_rtp_buffer_validate (buf));
   gst_buffer_unref (buf);
 }
 
 GST_END_TEST;
 
+#if 0
 GST_START_TEST (test_rtp_buffer_list)
 {
   GstBuffer *rtp_header;
@@ -203,6 +213,7 @@ GST_START_TEST (test_rtp_buffer_list)
 }
 
 GST_END_TEST;
+#endif
 
 GST_START_TEST (test_rtp_buffer_set_extension_data)
 {
@@ -213,158 +224,185 @@ GST_START_TEST (test_rtp_buffer_set_extension_data)
   guint8 misc_data[4] = { 1, 2, 3, 4 };
   gpointer pointer;
   guint8 appbits;
+  gsize bsize;
+  GstRTPBuffer rtp = { NULL, };
 
   /* check GstRTPHeader structure alignment and packing */
   buf = gst_rtp_buffer_new_allocate (4, 0, 0);
-  data = GST_BUFFER_DATA (buf);
+  data = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+
+  gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);
 
   /* should be impossible to set the extension data */
-  ASSERT_WARNING (fail_unless (gst_rtp_buffer_set_extension_data (buf, 0,
+  ASSERT_WARNING (fail_unless (gst_rtp_buffer_set_extension_data (&rtp, 0,
               4) == FALSE));
-  fail_unless (gst_rtp_buffer_get_extension (buf) == FALSE);
+  fail_unless (gst_rtp_buffer_get_extension (&rtp) == FALSE);
 
   /* should be possible to set the extension data */
-  fail_unless (gst_rtp_buffer_set_extension_data (buf, 270, 0) == TRUE);
-  fail_unless (gst_rtp_buffer_get_extension (buf) == TRUE);
-  gst_rtp_buffer_get_extension_data (buf, &bits, &pointer, &size);
+  fail_unless (gst_rtp_buffer_set_extension_data (&rtp, 270, 0) == TRUE);
+  fail_unless (gst_rtp_buffer_get_extension (&rtp) == TRUE);
+  gst_rtp_buffer_get_extension_data (&rtp, &bits, &pointer, &size);
   fail_unless (bits == 270);
   fail_unless (size == 0);
-  fail_unless (pointer == GST_BUFFER_DATA (buf) + 16);
-  pointer = gst_rtp_buffer_get_payload (buf);
-  fail_unless (pointer == GST_BUFFER_DATA (buf) + 16);
+  fail_unless (pointer == data + 16);
+  pointer = gst_rtp_buffer_get_payload (&rtp);
+  fail_unless (pointer == data + 16);
+
+  gst_buffer_unmap (buf, data, bsize);
+  gst_rtp_buffer_unmap (&rtp);
   gst_buffer_unref (buf);
 
   buf = gst_rtp_buffer_new_allocate (20, 0, 0);
-  data = GST_BUFFER_DATA (buf);
-  fail_unless (gst_rtp_buffer_get_extension (buf) == FALSE);
-  fail_unless (gst_rtp_buffer_set_extension_data (buf, 333, 2) == TRUE);
-  fail_unless (gst_rtp_buffer_get_extension (buf) == TRUE);
-  gst_rtp_buffer_get_extension_data (buf, &bits, &pointer, &size);
+  data = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+  gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);
+
+  fail_unless (gst_rtp_buffer_get_extension (&rtp) == FALSE);
+  fail_unless (gst_rtp_buffer_set_extension_data (&rtp, 333, 2) == TRUE);
+  fail_unless (gst_rtp_buffer_get_extension (&rtp) == TRUE);
+  gst_rtp_buffer_get_extension_data (&rtp, &bits, &pointer, &size);
   fail_unless (bits == 333);
   fail_unless (size == 2);
-  fail_unless (pointer == GST_BUFFER_DATA (buf) + 16);
-  pointer = gst_rtp_buffer_get_payload (buf);
-  fail_unless (pointer == GST_BUFFER_DATA (buf) + 24);
+  fail_unless (pointer == data + 16);
+  pointer = gst_rtp_buffer_get_payload (&rtp);
+  fail_unless (pointer == data + 24);
+
+  gst_buffer_unmap (buf, data, bsize);
+  gst_rtp_buffer_unmap (&rtp);
   gst_buffer_unref (buf);
 
   /* Test header extensions with a one byte header */
   buf = gst_rtp_buffer_new_allocate (20, 0, 0);
-  fail_unless (gst_rtp_buffer_get_extension (buf) == FALSE);
+  data = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+  gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);
 
-  fail_unless (gst_rtp_buffer_add_extension_onebyte_header (buf, 5,
+  fail_unless (gst_rtp_buffer_get_extension (&rtp) == FALSE);
+
+  fail_unless (gst_rtp_buffer_add_extension_onebyte_header (&rtp, 5,
           misc_data, 2) == TRUE);
-  fail_unless (gst_rtp_buffer_get_extension_data (buf, &bits, &pointer, &size));
+  fail_unless (gst_rtp_buffer_get_extension_data (&rtp, &bits, &pointer,
+          &size));
   fail_unless (bits == 0xBEDE);
   fail_unless (size == 1);
   data = (guint8 *) pointer;
   fail_unless (data[0] == ((5 << 4) | 1));
-  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (buf, 2,
+  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (&rtp, 2,
           1, &pointer, &size) == FALSE);
-  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (buf, 5,
+  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (&rtp, 5,
           1, &pointer, &size) == FALSE);
-  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (buf, 5,
+  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (&rtp, 5,
           0, &pointer, &size) == TRUE);
   fail_unless (size == 2);
   fail_unless (memcmp (pointer, misc_data, 2) == 0);
 
-  fail_unless (gst_rtp_buffer_add_extension_onebyte_header (buf, 5,
+  fail_unless (gst_rtp_buffer_add_extension_onebyte_header (&rtp, 5,
           misc_data, 4) == TRUE);
-  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (buf, 5,
+  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (&rtp, 5,
           0, &pointer, &size) == TRUE);
   fail_unless (size == 2);
   fail_unless (memcmp (pointer, misc_data, 2) == 0);
-  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (buf, 5,
+  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (&rtp, 5,
           1, &pointer, &size) == TRUE);
   fail_unless (size == 4);
   fail_unless (memcmp (pointer, misc_data, 4) == 0);
-  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (buf, 5,
+  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (&rtp, 5,
           2, &pointer, &size) == FALSE);
-  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (buf, 2,
+  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (&rtp, 2,
           1, &pointer, &size) == FALSE);
 
-  fail_unless (gst_rtp_buffer_add_extension_onebyte_header (buf, 6,
+  fail_unless (gst_rtp_buffer_add_extension_onebyte_header (&rtp, 6,
           misc_data, 2) == TRUE);
-  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (buf, 5,
+  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (&rtp, 5,
           0, &pointer, &size) == TRUE);
   fail_unless (size == 2);
   fail_unless (memcmp (pointer, misc_data, 2) == 0);
-  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (buf, 5,
+  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (&rtp, 5,
           1, &pointer, &size) == TRUE);
   fail_unless (size == 4);
   fail_unless (memcmp (pointer, misc_data, 4) == 0);
-  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (buf, 5,
+  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (&rtp, 5,
           3, &pointer, &size) == FALSE);
-  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (buf, 2,
+  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (&rtp, 2,
           1, &pointer, &size) == FALSE);
-  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (buf, 6,
+  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (&rtp, 6,
           2, &pointer, &size) == FALSE);
-  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (buf, 5,
+  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (&rtp, 5,
           0, &pointer, &size) == TRUE);
   fail_unless (size == 2);
   fail_unless (memcmp (pointer, misc_data, 2) == 0);
+
+  gst_buffer_unmap (buf, data, bsize);
+  gst_rtp_buffer_unmap (&rtp);
   gst_buffer_unref (buf);
 
   /* Test header extensions with a two bytes header */
   buf = gst_rtp_buffer_new_allocate (20, 0, 0);
-  fail_unless (gst_rtp_buffer_get_extension (buf) == FALSE);
+  data = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+  gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);
+
+  fail_unless (gst_rtp_buffer_get_extension (&rtp) == FALSE);
 
-  fail_unless (gst_rtp_buffer_add_extension_twobytes_header (buf, 0, 5,
+  fail_unless (gst_rtp_buffer_add_extension_twobytes_header (&rtp, 0, 5,
           misc_data, 2) == TRUE);
-  fail_unless (gst_rtp_buffer_get_extension_data (buf, &bits, &pointer, &size));
+  fail_unless (gst_rtp_buffer_get_extension_data (&rtp, &bits, &pointer,
+          &size));
   fail_unless (bits == 0x100 << 4);
   fail_unless (size == 1);
   data = (guint8 *) pointer;
   fail_unless (data[0] == 5);
   fail_unless (data[1] == 2);
-  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (buf, &appbits, 2,
+  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (&rtp, &appbits, 2,
           0, &pointer, &size) == FALSE);
-  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (buf, &appbits, 5,
+  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (&rtp, &appbits, 5,
           1, &pointer, &size) == FALSE);
-  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (buf, &appbits, 5,
+  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (&rtp, &appbits, 5,
           0, &pointer, &size) == TRUE);
   fail_unless (size == 2);
   fail_unless (memcmp (pointer, misc_data, 2) == 0);
 
-  fail_unless (gst_rtp_buffer_add_extension_twobytes_header (buf, 0, 5,
+  fail_unless (gst_rtp_buffer_add_extension_twobytes_header (&rtp, 0, 5,
           misc_data, 4) == TRUE);
-  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (buf, &appbits, 5,
+  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (&rtp, &appbits, 5,
           0, &pointer, &size) == TRUE);
   fail_unless (size == 2);
   fail_unless (memcmp (pointer, misc_data, 2) == 0);
-  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (buf, &appbits, 5,
+  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (&rtp, &appbits, 5,
           1, &pointer, &size) == TRUE);
   fail_unless (size == 4);
   fail_unless (memcmp (pointer, misc_data, 4) == 0);
-  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (buf, &appbits, 5,
+  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (&rtp, &appbits, 5,
           2, &pointer, &size) == FALSE);
-  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (buf, &appbits, 2,
+  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (&rtp, &appbits, 2,
           0, &pointer, &size) == FALSE);
 
-  fail_unless (gst_rtp_buffer_add_extension_twobytes_header (buf, 0, 6,
+  fail_unless (gst_rtp_buffer_add_extension_twobytes_header (&rtp, 0, 6,
           misc_data, 2) == TRUE);
-  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (buf, &appbits, 5,
+  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (&rtp, &appbits, 5,
           0, &pointer, &size) == TRUE);
   fail_unless (size == 2);
   fail_unless (memcmp (pointer, misc_data, 2) == 0);
-  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (buf, &appbits, 5,
+  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (&rtp, &appbits, 5,
           1, &pointer, &size) == TRUE);
   fail_unless (size == 4);
   fail_unless (memcmp (pointer, misc_data, 4) == 0);
-  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (buf, &appbits, 5,
+  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (&rtp, &appbits, 5,
           2, &pointer, &size) == FALSE);
-  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (buf, &appbits, 2,
+  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (&rtp, &appbits, 2,
           0, &pointer, &size) == FALSE);
-  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (buf, &appbits, 6,
+  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (&rtp, &appbits, 6,
           1, &pointer, &size) == FALSE);
-  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (buf, &appbits, 5,
+  fail_unless (gst_rtp_buffer_get_extension_twobytes_header (&rtp, &appbits, 5,
           0, &pointer, &size) == TRUE);
   fail_unless (size == 2);
   fail_unless (memcmp (pointer, misc_data, 2) == 0);
+
+  gst_buffer_unmap (buf, data, bsize);
+  gst_rtp_buffer_unmap (&rtp);
   gst_buffer_unref (buf);
 }
 
 GST_END_TEST;
 
+#if 0
 GST_START_TEST (test_rtp_buffer_list_set_extension)
 {
   GstBufferList *list;
@@ -544,6 +582,7 @@ GST_START_TEST (test_rtp_buffer_list_set_extension)
 }
 
 GST_END_TEST;
+#endif
 
 GST_START_TEST (test_rtp_seqnum_compare)
 {
@@ -636,18 +675,22 @@ GST_START_TEST (test_rtcp_buffer)
   GstBuffer *buf;
   GstRTCPPacket packet;
   guint8 *data;
+  gsize size;
+  GstRTCPBuffer rtcp = { NULL, };
 
   buf = gst_rtcp_buffer_new (1400);
   fail_unless (buf != NULL);
-  fail_unless_equals_int (GST_BUFFER_SIZE (buf), 1400);
-  data = GST_BUFFER_DATA (buf);
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  fail_unless_equals_int (size, 1400);
+
+  gst_rtcp_buffer_map (buf, GST_MAP_READWRITE, &rtcp);
 
-  fail_unless (gst_rtcp_buffer_get_first_packet (buf, &packet) == FALSE);
-  fail_unless (gst_rtcp_buffer_get_packet_count (buf) == 0);
   fail_unless (gst_rtcp_buffer_validate (buf) == FALSE);
+  fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &packet) == FALSE);
+  fail_unless (gst_rtcp_buffer_get_packet_count (&rtcp) == 0);
 
   /* add an SR packet */
-  fail_unless (gst_rtcp_buffer_add_packet (buf, GST_RTCP_TYPE_SR,
+  fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_SR,
           &packet) == TRUE);
 
   fail_unless (gst_rtcp_packet_get_padding (&packet) == 0);
@@ -675,7 +718,7 @@ GST_START_TEST (test_rtcp_buffer)
   }
 
   /* go to first packet, this should be the packet we just added */
-  fail_unless (gst_rtcp_buffer_get_first_packet (buf, &packet) == TRUE);
+  fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &packet) == TRUE);
 
   fail_unless (gst_rtcp_packet_get_padding (&packet) == 0);
   fail_unless (gst_rtcp_packet_get_count (&packet) == 0);
@@ -685,14 +728,14 @@ GST_START_TEST (test_rtcp_buffer)
   fail_unless (gst_rtcp_packet_move_to_next (&packet) == FALSE);
 
   /* add some SDES */
-  fail_unless (gst_rtcp_buffer_add_packet (buf, GST_RTCP_TYPE_SDES,
+  fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_SDES,
           &packet) == TRUE);
   fail_unless (gst_rtcp_packet_sdes_add_item (&packet, 0xff658743) == TRUE);
   fail_unless (gst_rtcp_packet_sdes_add_entry (&packet, GST_RTCP_SDES_CNAME,
           sizeof ("test@foo.bar"), (guint8 *) "test@foo.bar") == TRUE);
 
   /* add some BYE */
-  fail_unless (gst_rtcp_buffer_add_packet (buf, GST_RTCP_TYPE_BYE,
+  fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_BYE,
           &packet) == TRUE);
   fail_unless (gst_rtcp_packet_bye_add_ssrc (&packet, 0x5613212f) == TRUE);
   fail_unless (gst_rtcp_packet_bye_add_ssrc (&packet, 0x00112233) == TRUE);
@@ -704,7 +747,7 @@ GST_START_TEST (test_rtcp_buffer)
   fail_unless (gst_rtcp_packet_get_length (&packet) == 2);
 
   /* move to SDES */
-  fail_unless (gst_rtcp_buffer_get_first_packet (buf, &packet) == TRUE);
+  fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &packet) == TRUE);
   fail_unless (gst_rtcp_packet_move_to_next (&packet) == TRUE);
 
   fail_unless (gst_rtcp_packet_get_padding (&packet) == 0);
@@ -722,7 +765,7 @@ GST_START_TEST (test_rtcp_buffer)
   fail_unless (gst_rtcp_packet_get_length (&packet) == 2);
 
   /* close and validate */
-  gst_rtcp_buffer_end (buf);
+  gst_rtcp_buffer_unmap (&rtcp);
   fail_unless (gst_rtcp_buffer_validate (buf) == TRUE);
   gst_buffer_unref (buf);
 }
@@ -739,12 +782,12 @@ rtp_suite (void)
   tcase_add_test (tc_chain, test_rtp_buffer);
   tcase_add_test (tc_chain, test_rtp_buffer_validate_corrupt);
   tcase_add_test (tc_chain, test_rtp_buffer_set_extension_data);
-  tcase_add_test (tc_chain, test_rtp_buffer_list_set_extension);
+  //tcase_add_test (tc_chain, test_rtp_buffer_list_set_extension);
   tcase_add_test (tc_chain, test_rtp_seqnum_compare);
 
   tcase_add_test (tc_chain, test_rtcp_buffer);
 
-  tcase_add_test (tc_chain, test_rtp_buffer_list);
+  //tcase_add_test (tc_chain, test_rtp_buffer_list);
 
   return s;
 }
index 6f504ad..bbedd28 100644 (file)
@@ -1,7 +1,5 @@
 
 GstCheckABIStruct list[] = {
-  {"GstAppBufferClass", sizeof (GstAppBufferClass), 16},
-  {"GstAppBuffer", sizeof (GstAppBuffer), 88},
   {"GstAppSinkCallbacks", sizeof (GstAppSinkCallbacks), 28},
   {"GstAppSinkClass", sizeof (GstAppSinkClass), 404},
   {"GstAppSink", sizeof (GstAppSink), 404},
@@ -49,8 +47,6 @@ GstCheckABIStruct list[] = {
   {"GstMixerTrack", sizeof (GstMixerTrack), 32},
   {"GstNavigationInterface", sizeof (GstNavigationInterface), 28},
   {"GstNetAddress", sizeof (GstNetAddress), 40},
-  {"GstNetBufferClass", sizeof (GstNetBufferClass), 32},
-  {"GstNetBuffer", sizeof (GstNetBuffer), 176},
   {"GstPropertyProbeInterface", sizeof (GstPropertyProbeInterface), 44},
   {"gst_riff_acid", sizeof (gst_riff_acid), 24},
   {"gst_riff_dmlh", sizeof (gst_riff_dmlh), 4},
index 3029e56..ad8bc7c 100644 (file)
@@ -1,7 +1,5 @@
 
 GstCheckABIStruct list[] = {
-  {"GstAppBufferClass", sizeof (GstAppBufferClass), 32},
-  {"GstAppBuffer", sizeof (GstAppBuffer), 136},
   {"GstAppSinkCallbacks", sizeof (GstAppSinkCallbacks), 56},
   {"GstAppSinkClass", sizeof (GstAppSinkClass), 800},
   {"GstAppSink", sizeof (GstAppSink), 640},
@@ -49,8 +47,6 @@ GstCheckABIStruct list[] = {
   {"GstMixerTrack", sizeof (GstMixerTrack), 48},
   {"GstNavigationInterface", sizeof (GstNavigationInterface), 56},
   {"GstNetAddress", sizeof (GstNetAddress), 56},
-  {"GstNetBufferClass", sizeof (GstNetBufferClass), 64},
-  {"GstNetBuffer", sizeof (GstNetBuffer), 264},
   {"GstPropertyProbeInterface", sizeof (GstPropertyProbeInterface), 88},
   {"gst_riff_acid", sizeof (gst_riff_acid), 24},
   {"gst_riff_dmlh", sizeof (gst_riff_dmlh), 4},
index 555cdb8..4181040 100644 (file)
@@ -407,6 +407,8 @@ GST_START_TEST (test_vorbis_tags)
   /* now, while we still have a taglist, test _to_vorbiscomment_buffer() */
   {
     GstBuffer *buf1, *buf2;
+    guint8 *data1, *data2;
+    gsize size1, size2;
 
     ASSERT_CRITICAL (gst_tag_list_to_vorbiscomment_buffer (NULL,
             (const guint8 *) "x", 1, "x"));
@@ -418,8 +420,13 @@ GST_START_TEST (test_vorbis_tags)
         (const guint8 *) "foo", 3, NULL);
     fail_unless (buf2 != NULL);
 
-    fail_unless (memcmp (GST_BUFFER_DATA (buf1), GST_BUFFER_DATA (buf2) + 3,
-            GST_BUFFER_SIZE (buf1)) == 0);
+    data1 = gst_buffer_map (buf1, &size1, NULL, GST_MAP_READ);
+    data2 = gst_buffer_map (buf2, &size2, NULL, GST_MAP_READ);
+
+    fail_unless (memcmp (data1, data2 + 3, size1) == 0);
+
+    gst_buffer_unmap (buf2, data2, size2);
+    gst_buffer_unmap (buf1, data1, size1);
 
     gst_buffer_unref (buf1);
     gst_buffer_unref (buf2);
@@ -437,8 +444,10 @@ GST_START_TEST (test_vorbis_tags)
     gchar *vendor = NULL;
 
     buf = gst_buffer_new ();
-    GST_BUFFER_DATA (buf) = (guint8 *) speex_comments_buf1;
-    GST_BUFFER_SIZE (buf) = sizeof (speex_comments_buf1);
+    gst_buffer_take_memory (buf,
+        gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+            (gpointer) speex_comments_buf1, NULL,
+            sizeof (speex_comments_buf1), 0, sizeof (speex_comments_buf1)));
 
     /* make sure it doesn't memcmp over the end of the buffer */
     fail_unless (gst_tag_list_from_vorbiscomment_buffer (buf,
@@ -480,8 +489,10 @@ GST_START_TEST (test_vorbis_tags)
     gchar *vendor = NULL;
 
     buf = gst_buffer_new ();
-    GST_BUFFER_DATA (buf) = (guint8 *) vorbis_comments_buf;
-    GST_BUFFER_SIZE (buf) = sizeof (vorbis_comments_buf);
+    gst_buffer_take_memory (buf,
+        gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+            (gpointer) vorbis_comments_buf, NULL,
+            sizeof (vorbis_comments_buf), 0, sizeof (vorbis_comments_buf)));
 
     /* make sure it doesn't memcmp over the end of the buffer */
     fail_unless (gst_tag_list_from_vorbiscomment_buffer (buf,
@@ -755,7 +766,7 @@ GST_START_TEST (test_xmp_formatting)
   GstTagList *list;
   GstBuffer *buf;
   const gchar *text;
-  guint len;
+  gsize len;
 
   /* test data */
   list = gst_tag_list_new_full (GST_TAG_TITLE, "test title",
@@ -765,8 +776,7 @@ GST_START_TEST (test_xmp_formatting)
   buf = gst_tag_list_to_xmp_buffer (list, FALSE);
   fail_unless (buf != NULL);
 
-  text = (const gchar *) GST_BUFFER_DATA (buf);
-  len = GST_BUFFER_SIZE (buf);
+  text = gst_buffer_map (buf, &len, NULL, GST_MAP_READ);
 
   /* check the content */
   fail_unless (g_strrstr_len (text, len, "<?xpacket begin") == text);
@@ -775,6 +785,7 @@ GST_START_TEST (test_xmp_formatting)
   fail_unless (g_strrstr_len (text, len, ">keyword1<") != NULL);
   fail_unless (g_strrstr_len (text, len, ">keyword2<") != NULL);
   fail_unless (g_strrstr_len (text, len, "<?xpacket end") != NULL);
+  gst_buffer_unmap (buf, (gpointer) text, len);
 
   gst_buffer_unref (buf);
   gst_tag_list_free (list);
@@ -814,16 +825,18 @@ GST_START_TEST (test_xmp_parsing)
   };
 
   /* test data */
-  buf = gst_buffer_new ();
-
   i = 0;
   while (test_data[i].xmp_data) {
+    gsize len;
+
     GST_DEBUG ("trying test-data %u", i);
 
     text = g_strconcat (xmp_header, test_data[i].xmp_data, xmp_footer, NULL);
-    GST_BUFFER_DATA (buf) = (guint8 *) text;
-    GST_BUFFER_SIZE (buf) = strlen (text) + 1;
 
+    buf = gst_buffer_new ();
+    len = strlen (text) + 1;
+    gst_buffer_take_memory (buf,
+        gst_memory_new_wrapped (0, text, NULL, len, 0, len));
 
     list = gst_tag_list_from_xmp_buffer (buf);
     if (test_data[i].result_size >= 0) {
@@ -844,11 +857,10 @@ GST_START_TEST (test_xmp_parsing)
     if (list)
       gst_tag_list_free (list);
 
+    gst_buffer_unref (buf);
     g_free (text);
     i++;
   }
-
-  gst_buffer_unref (buf);
 }
 
 GST_END_TEST;
@@ -1270,6 +1282,7 @@ GST_START_TEST (test_exif_tags_serialization_deserialization)
   GstBuffer *buf = NULL;
   gint i;
   GstTagList *taglist;
+  guint8 *data;
 
   gst_tag_register_musicbrainz_tags ();
 
@@ -1574,8 +1587,10 @@ GST_START_TEST (test_exif_tags_serialization_deserialization)
 
   g_value_init (&value, GST_TYPE_BUFFER);
   buf = gst_buffer_new_and_alloc (1024);
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
   for (i = 0; i < 1024; i++)
-    GST_BUFFER_DATA (buf)[i] = i % 255;
+    data[i] = i % 255;
+  gst_buffer_unmap (buf, data, 1024);
   gst_value_set_buffer (&value, buf);
   gst_buffer_unref (buf);
   do_simple_exif_tag_serialization_deserialization (GST_TAG_APPLICATION_DATA,
index a10ac64..977c5dc 100644 (file)
@@ -628,14 +628,16 @@ GST_START_TEST (test_convert_frame)
   guint8 *data;
 
   from_buffer = gst_buffer_new_and_alloc (640 * 480 * 4);
-  data = GST_BUFFER_DATA (from_buffer);
 
+  data = gst_buffer_map (from_buffer, NULL, NULL, GST_MAP_WRITE);
   for (i = 0; i < 640 * 480; i++) {
     data[4 * i + 0] = 0;        /* x */
     data[4 * i + 1] = 255;      /* R */
     data[4 * i + 2] = 0;        /* G */
     data[4 * i + 3] = 0;        /* B */
   }
+  gst_buffer_unmap (from_buffer, data, 640 * 480 * 4);
+
   from_caps = gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB,
       640, 480, 25, 1, 1, 1);
   gst_buffer_set_caps (from_buffer, from_caps);
@@ -697,14 +699,16 @@ GST_START_TEST (test_convert_frame_async)
   ConvertFrameContext cf_data = { NULL, NULL, NULL };
 
   from_buffer = gst_buffer_new_and_alloc (640 * 480 * 4);
-  data = GST_BUFFER_DATA (from_buffer);
 
+  data = gst_buffer_map (from_buffer, NULL, NULL, GST_MAP_WRITE);
   for (i = 0; i < 640 * 480; i++) {
     data[4 * i + 0] = 0;        /* x */
     data[4 * i + 1] = 255;      /* R */
     data[4 * i + 2] = 0;        /* G */
     data[4 * i + 3] = 0;        /* B */
   }
+  gst_buffer_unmap (from_buffer, data, 640 * 480 * 4);
+
   from_caps = gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB,
       640, 480, 25, 1, 1, 1);
   gst_buffer_set_caps (from_buffer, from_caps);
index 99b84ae..49fd1e7 100644 (file)
@@ -50,8 +50,8 @@ GType test_element_get_type (void);
 
 static void init_interface (GType type);
 
-GST_BOILERPLATE_FULL (TestElement, test_element, GstElement, GST_TYPE_ELEMENT,
-    init_interface);
+G_DEFINE_TYPE_WITH_CODE (TestElement, test_element, GST_TYPE_ELEMENT,
+    init_interface (g_define_type_id));
 
 static void
 init_interface (GType type)
@@ -67,17 +67,12 @@ init_interface (GType type)
 }
 
 static void
-test_element_base_init (gpointer klass)
-{
-}
-
-static void
 test_element_class_init (TestElementClass * klass)
 {
 }
 
 static void
-test_element_init (TestElement * this, TestElementClass * klass)
+test_element_init (TestElement * this)
 {
 }
 
@@ -143,11 +138,22 @@ tag_list_equals (GstTagList * taglist, GstTagList * taglist2)
 static gboolean
 gst_buffer_equals (GstBuffer * buf_a, GstBuffer * buf_b)
 {
-  if (GST_BUFFER_SIZE (buf_a) != GST_BUFFER_SIZE (buf_b))
-    return FALSE;
+  gboolean res;
+  gpointer data1, data2;
+  gsize size1, size2;
+
+  data1 = gst_buffer_map (buf_a, &size1, NULL, GST_MAP_READ);
+  data2 = gst_buffer_map (buf_b, &size2, NULL, GST_MAP_READ);
+
+  if (size1 == size2) {
+    res = memcmp (data1, data2, size1) == 0;
+  } else {
+    res = FALSE;
+  }
+  gst_buffer_unmap (buf_a, data1, size1);
+  gst_buffer_unmap (buf_b, data2, size2);
 
-  return memcmp (GST_BUFFER_DATA (buf_a), GST_BUFFER_DATA (buf_b),
-      GST_BUFFER_SIZE (buf_a)) == 0;
+  return res;
 }
 
 static GstTagList *
index f18a713..80a1001 100644 (file)
@@ -88,7 +88,10 @@ buffer_probe (GstPad * pad, GstMiniObject * obj, gpointer data)
   return TRUE;
 }
 
-GST_START_TEST (test_capsfilter_renegotiation)
+/* launch line is a pipeline that must have a capsfilter named 'cf' that
+ * will be used to trigger the renegotiation */
+static void
+run_capsfilter_renegotiation (const gchar * launch_line)
 {
   GstElement *capsfilter;
   GstElement *sink;
@@ -103,8 +106,7 @@ GST_START_TEST (test_capsfilter_renegotiation)
     gst_caps_unref (current_caps);
   current_caps = NULL;
 
-  pipeline = gst_parse_launch ("videotestsrc num-buffers=200 ! capsfilter "
-      "caps=\"" FIRST_CAPS "\" name=cf ! fakesink name=sink", NULL);
+  pipeline = gst_parse_launch (launch_line, NULL);
   g_assert (pipeline);
 
   capsfilter = gst_bin_get_by_name (GST_BIN (pipeline), "cf");
@@ -126,18 +128,30 @@ GST_START_TEST (test_capsfilter_renegotiation)
       GST_MESSAGE_EOS | GST_MESSAGE_ERROR);
 
   g_assert (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
-
   g_assert (caps_change == 4);
 
   gst_element_set_state (pipeline, GST_STATE_NULL);
 
   if (current_caps)
     gst_caps_unref (current_caps);
+  current_caps = NULL;
   gst_message_unref (msg);
   g_object_unref (bus);
   g_object_unref (G_OBJECT (pipeline));
 }
 
+GST_START_TEST (test_capsfilter_renegotiation)
+{
+  run_capsfilter_renegotiation ("videotestsrc num-buffers=200 peer-alloc=true"
+      " ! capsfilter caps=\"" FIRST_CAPS "\" name=cf ! fakesink name=sink");
+  run_capsfilter_renegotiation ("videotestsrc num-buffers=200 peer-alloc=false"
+      " ! capsfilter caps=\"" FIRST_CAPS "\" name=cf ! fakesink name=sink");
+  run_capsfilter_renegotiation ("videotestsrc num-buffers=200 peer-alloc=false"
+      " ! capsfilter caps=\"video/x-raw-yuv, format=(fourcc)I420, width=(int)100, height=(int)100\" "
+      " ! ffmpegcolorspace ! videoscale ! capsfilter caps=\"" FIRST_CAPS
+      "\" name=cf " " ! fakesink name=sink");
+}
+
 GST_END_TEST;
 
 static Suite *
index 81056ca..c1ae7b3 100644 (file)
@@ -162,16 +162,14 @@ eos_buffer_probe (GstPad * pad, GstBuffer * buffer, gpointer unused)
 {
   gint ret;
   gint size;
-  guint8 *data;
   gchar *oggbuffer;
   ChainState *state = NULL;
   gboolean has_video = FALSE;
 
-  size = GST_BUFFER_SIZE (buffer);
-  data = GST_BUFFER_DATA (buffer);
+  size = gst_buffer_get_size (buffer);
 
   oggbuffer = ogg_sync_buffer (&oggsync, size);
-  memcpy (oggbuffer, data, size);
+  gst_buffer_extract (buffer, 0, oggbuffer, size);
   ogg_sync_wrote (&oggsync, size);
 
   do {
index c3872ad..e32ba33 100644 (file)
@@ -122,6 +122,11 @@ static int n_in_caps = 0;
 static gboolean
 buffer_probe_cb (GstPad * pad, GstBuffer * buffer)
 {
+  guint8 *data;
+  gsize size;
+
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+
   if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_IN_CAPS)) {
     GstCaps *caps;
     GstStructure *s;
@@ -143,22 +148,27 @@ buffer_probe_cb (GstPad * pad, GstBuffer * buffer)
 
     for (i = 0; i < 3; ++i) {
       GValue *val;
+      guint8 *data2;
+      gsize size2;
 
       val = &g_array_index (buffers, GValue, i);
       buf = g_value_peek_pointer (val);
       fail_unless (GST_IS_BUFFER (buf));
-      if (GST_BUFFER_SIZE (buf) == GST_BUFFER_SIZE (buffer)) {
-        if (memcmp (GST_BUFFER_DATA (buf), GST_BUFFER_DATA (buffer),
-                GST_BUFFER_SIZE (buffer)) == 0) {
+
+      data2 = gst_buffer_map (buf, &size2, NULL, GST_MAP_READ);
+      if (size2 == size) {
+        if (memcmp (data2, data, size) == 0) {
           found = TRUE;
         }
       }
+      gst_buffer_unmap (buf, data2, size2);
     }
     fail_unless (found, "Did not find incoming IN_CAPS buffer %p on caps",
         buffer);
 
     gst_caps_unref (caps);
   }
+  gst_buffer_unmap (buffer, data, size);
 
   return TRUE;
 }
index b207dff..4e35aeb 100644 (file)
@@ -264,7 +264,12 @@ GST_END_TEST;
 static gboolean
 drop_second_data_buffer (GstPad * droppad, GstBuffer * buffer, gpointer unused)
 {
-  return !(GST_BUFFER_OFFSET (buffer) == 1024);
+  gboolean res;
+
+  res = !(GST_BUFFER_OFFSET (buffer) == 1024);
+  GST_DEBUG ("dropping %d", res);
+
+  return res;
 }
 
 GST_START_TEST (test_discontinuity)
@@ -356,11 +361,11 @@ GST_START_TEST (test_discontinuity)
      * samples (because of the overlap/add), so it won't increment the 
      * granulepos, which should be 2048 after the discontinuity.
      */
+    fail_unless (GST_BUFFER_IS_DISCONT (buffer),
+        "expected discontinuous buffer");
     fail_unless (GST_BUFFER_OFFSET_END (buffer) == 2048,
         "expected granulepos after gap: %" G_GUINT64_FORMAT,
         GST_BUFFER_OFFSET_END (buffer));
-    fail_unless (GST_BUFFER_IS_DISCONT (buffer),
-        "expected discontinuous buffer");
     gst_buffer_unref (buffer);
   }
 
index a92dfb5..9772e8a 100644 (file)
@@ -4,7 +4,6 @@
 
 #include <gst/app/gstappsrc.h>
 #include <gst/app/gstappsink.h>
-#include <gst/app/gstappbuffer.h>
 
 /* these are the caps we are going to pass through the appsink and appsrc */
 const gchar *audio_caps =
@@ -23,7 +22,6 @@ static void
 on_new_buffer_from_source (GstElement * elt, ProgramData * data)
 {
   guint size;
-  gpointer raw_buffer;
   GstBuffer *app_buffer, *buffer;
   GstElement *source;
 
@@ -32,15 +30,11 @@ on_new_buffer_from_source (GstElement * elt, ProgramData * data)
 
   /* turn it into an app buffer, it's not really needed, we could simply push
    * the retrieved buffer from appsink into appsrc just fine.  */
-  size = GST_BUFFER_SIZE (buffer);
+  size = gst_buffer_get_size (buffer);
   g_print ("Pushing a buffer of size %d\n", size);
-  raw_buffer = g_malloc0 (size);
-  memcpy (raw_buffer, GST_BUFFER_DATA (buffer), size);
-  app_buffer = gst_app_buffer_new (raw_buffer, size, g_free, raw_buffer);
+  app_buffer = gst_buffer_new_and_alloc (size);
 
-  /* newer basesrc will set caps for use automatically but it does not really
-   * hurt to set it on the buffer again */
-  gst_buffer_set_caps (app_buffer, GST_BUFFER_CAPS (buffer));
+  gst_buffer_copy_into (app_buffer, buffer, GST_BUFFER_COPY_MEMORY, 0, size);
 
   /* we don't need the appsink buffer anymore */
   gst_buffer_unref (buffer);
index af5d7a7..d382acf 100644 (file)
@@ -83,8 +83,10 @@ feed_data (GstElement * appsrc, guint size, App * app)
   if (app->offset + size > app->length)
     size = app->length - app->offset;
 
-  GST_BUFFER_DATA (buffer) = app->data + app->offset;
-  GST_BUFFER_SIZE (buffer) = size;
+  gst_buffer_take_memory (buffer,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          app->data, NULL, app->length, app->offset, size));
+
   /* we need to set an offset for random access */
   GST_BUFFER_OFFSET (buffer) = app->offset;
   GST_BUFFER_OFFSET_END (buffer) = app->offset + size;
index 9421f9b..d38e895 100644 (file)
@@ -89,8 +89,9 @@ feed_data (GstElement * appsrc, guint size, App * app)
   if (app->offset + len > app->length)
     len = app->length - app->offset;
 
-  GST_BUFFER_DATA (buffer) = app->data + app->offset;
-  GST_BUFFER_SIZE (buffer) = len;
+  gst_buffer_take_memory (buffer,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          app->data, NULL, app->length, app->offset, len));
 
   GST_DEBUG ("feed buffer %p, offset %" G_GUINT64_FORMAT "-%u", buffer,
       app->offset, len);
index d14e143..65bd04d 100644 (file)
@@ -96,8 +96,9 @@ read_data (App * app)
   if (app->offset + len > app->length)
     len = app->length - app->offset;
 
-  GST_BUFFER_DATA (buffer) = app->data + app->offset;
-  GST_BUFFER_SIZE (buffer) = len;
+  gst_buffer_take_memory (buffer,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          app->data, NULL, app->length, app->offset, len));
 
   GST_DEBUG ("feed buffer %p, offset %" G_GUINT64_FORMAT "-%u", buffer,
       app->offset, len);
index a80e4d1..ed97c3b 100644 (file)
@@ -96,8 +96,9 @@ feed_data (GstElement * appsrc, guint size, App * app)
   if (app->offset + len > app->length)
     len = app->length - app->offset;
 
-  GST_BUFFER_DATA (buffer) = app->data + app->offset;
-  GST_BUFFER_SIZE (buffer) = len;
+  gst_buffer_take_memory (buffer,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          app->data, NULL, app->length, app->offset, len));
 
   GST_DEBUG ("feed buffer %p, offset %" G_GUINT64_FORMAT "-%u", buffer,
       app->offset, len);
index c7aa4b6..5468a66 100644 (file)
@@ -6,7 +6,6 @@
 
 #include <gst/gst.h>
 #include <gst/app/gstappsrc.h>
-#include <gst/app/gstappbuffer.h>
 #include <gst/app/gstappsink.h>
 
 #include <stdio.h>
@@ -25,8 +24,6 @@ struct _App
 
 App s_app;
 
-static void dont_eat_my_chicken_wings (void *priv);
-
 int
 main (int argc, char *argv[])
 {
@@ -59,11 +56,12 @@ main (int argc, char *argv[])
     GstBuffer *buf;
     void *data;
 
-    data = malloc (100);
+    buf = gst_buffer_new_and_alloc (100);
+    data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
     memset (data, i, 100);
+    gst_buffer_unmap (buf, data, 100);
 
-    buf = gst_app_buffer_new (data, 100, dont_eat_my_chicken_wings, data);
-    printf ("%d: creating buffer for pointer %p, %p\n", i, data, buf);
+    printf ("%d: pushing buffer for pointer %p, %p\n", i, data, buf);
     gst_app_src_push_buffer (GST_APP_SRC (app->src), buf);
   }
 
@@ -86,10 +84,3 @@ main (int argc, char *argv[])
 
   return 0;
 }
-
-static void
-dont_eat_my_chicken_wings (void *priv)
-{
-  printf ("freeing buffer for pointer %p\n", priv);
-  free (priv);
-}
index 89674ce..497aa63 100644 (file)
@@ -225,7 +225,7 @@ pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstElement * encodebin)
     GstCaps *caps;
 
     /* Ask encodebin for a compatible pad */
-    caps = gst_pad_get_caps (pad);
+    caps = gst_pad_get_caps (pad, NULL);
     g_signal_emit_by_name (encodebin, "request-pad", caps, &sinkpad);
     if (caps)
       gst_caps_unref (caps);
index 0a8e202..cf34f55 100644 (file)
@@ -57,8 +57,7 @@ message_handler (GstBus * bus, GstMessage * message, gpointer user_data)
       if (strcmp (name, "not-mounted") == 0) {
         GMountOperation *mop = gtk_mount_operation_new (NULL);
         GFile *file =
-            G_FILE (g_value_get_object (gst_structure_get_value
-                (message->structure, "file")));
+            G_FILE (g_value_get_object (gst_structure_get_value (s, "file")));
 
         g_print ("not-mounted\n");
         gst_element_set_state (pipeline, GST_STATE_NULL);
index ec74cc8..39ae6d4 100644 (file)
@@ -2044,12 +2044,18 @@ shot_cb (GtkButton * button, gpointer data)
     gint width, height;
     GdkPixbuf *pixbuf;
     GError *error = NULL;
+    gsize size;
+    guint8 *data;
 
     /* get the snapshot buffer format now. We set the caps on the appsink so
      * that it can only be an rgb buffer. The only thing we have not specified
      * on the caps is the height, which is dependant on the pixel-aspect-ratio
      * of the source material */
+#if 0
     caps = GST_BUFFER_CAPS (buffer);
+#endif
+    /* FIXME, get the caps on the buffer somehow */
+    caps = NULL;
     if (!caps) {
       g_warning ("could not get snapshot format\n");
       goto done;
@@ -2066,12 +2072,17 @@ shot_cb (GtkButton * button, gpointer data)
 
     /* create pixmap from buffer and save, gstreamer video buffers have a stride
      * that is rounded up to the nearest multiple of 4 */
-    pixbuf = gdk_pixbuf_new_from_data (GST_BUFFER_DATA (buffer),
+    data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+    pixbuf = gdk_pixbuf_new_from_data (data,
         GDK_COLORSPACE_RGB, FALSE, 8, width, height,
         GST_ROUND_UP_4 (width * 3), NULL, NULL);
 
     /* save the pixbuf */
     gdk_pixbuf_save (pixbuf, "snapshot.png", "png", &error, NULL);
+    gst_buffer_unmap (buffer, data, size);
+
+    /* save the pixbuf */
+    gdk_pixbuf_save (pixbuf, "snapshot.png", "png", &error, NULL);
 
   done:
     gst_buffer_unref (buffer);
@@ -2445,7 +2456,7 @@ static GstBusSyncReply
 bus_sync_handler (GstBus * bus, GstMessage * message, GstPipeline * data)
 {
   if ((GST_MESSAGE_TYPE (message) == GST_MESSAGE_ELEMENT) &&
-      gst_structure_has_name (message->structure, "prepare-xwindow-id")) {
+      gst_message_has_name (message, "prepare-xwindow-id")) {
     GstElement *element = GST_ELEMENT (GST_MESSAGE_SRC (message));
 
     g_print ("got prepare-xwindow-id, setting XID %lu\n", embed_xid);
index 8bf0818..0780cd6 100644 (file)
@@ -2034,12 +2034,18 @@ shot_cb (GtkButton * button, gpointer data)
     gint width, height;
     GdkPixbuf *pixbuf;
     GError *error = NULL;
+    guint8 *data;
+    gsize size;
 
     /* get the snapshot buffer format now. We set the caps on the appsink so
      * that it can only be an rgb buffer. The only thing we have not specified
      * on the caps is the height, which is dependant on the pixel-aspect-ratio
      * of the source material */
+#if 0
     caps = GST_BUFFER_CAPS (buffer);
+#endif
+    /* FIXME, need to get the caps of the buffer somehow */
+    caps = NULL;
     if (!caps) {
       g_warning ("could not get snapshot format\n");
       goto done;
@@ -2056,12 +2062,14 @@ shot_cb (GtkButton * button, gpointer data)
 
     /* create pixmap from buffer and save, gstreamer video buffers have a stride
      * that is rounded up to the nearest multiple of 4 */
-    pixbuf = gdk_pixbuf_new_from_data (GST_BUFFER_DATA (buffer),
+    data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+    pixbuf = gdk_pixbuf_new_from_data (data,
         GDK_COLORSPACE_RGB, FALSE, 8, width, height,
         GST_ROUND_UP_4 (width * 3), NULL, NULL);
 
     /* save the pixbuf */
     gdk_pixbuf_save (pixbuf, "snapshot.png", "png", &error, NULL);
+    gst_buffer_unmap (buffer, data, size);
 
   done:
     gst_buffer_unref (buffer);
@@ -2437,7 +2445,7 @@ static GstBusSyncReply
 bus_sync_handler (GstBus * bus, GstMessage * message, GstPipeline * data)
 {
   if ((GST_MESSAGE_TYPE (message) == GST_MESSAGE_ELEMENT) &&
-      gst_structure_has_name (message->structure, "prepare-xwindow-id")) {
+      gst_message_has_name (message, "prepare-xwindow-id")) {
     GstElement *element = GST_ELEMENT (GST_MESSAGE_SRC (message));
 
     g_print ("got prepare-xwindow-id, setting XID %lu\n", embed_xid);
index 14f2809..b1ec777 100644 (file)
@@ -37,6 +37,8 @@ main (int argc, char *argv[])
   GstFormat format;
   GstStateChangeReturn ret;
   gboolean res;
+  guint8 *data;
+  gsize size;
 
   gst_init (&argc, &argv);
 
@@ -116,7 +118,11 @@ main (int argc, char *argv[])
      * that it can only be an rgb buffer. The only thing we have not specified
      * on the caps is the height, which is dependant on the pixel-aspect-ratio
      * of the source material */
+#if 0
     caps = GST_BUFFER_CAPS (buffer);
+#endif
+    /* FIXME, get buffer caps somehow */
+    caps = NULL;
     if (!caps) {
       g_print ("could not get snapshot format\n");
       exit (-1);
@@ -133,12 +139,17 @@ main (int argc, char *argv[])
 
     /* create pixmap from buffer and save, gstreamer video buffers have a stride
      * that is rounded up to the nearest multiple of 4 */
-    pixbuf = gdk_pixbuf_new_from_data (GST_BUFFER_DATA (buffer),
+    data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+    pixbuf = gdk_pixbuf_new_from_data (data,
         GDK_COLORSPACE_RGB, FALSE, 8, width, height,
         GST_ROUND_UP_4 (width * 3), NULL, NULL);
 
     /* save the pixbuf */
     gdk_pixbuf_save (pixbuf, "snapshot.png", "png", &error, NULL);
+    gst_buffer_unmap (buffer, data, size);
+
+    /* save the pixbuf */
+    gdk_pixbuf_save (pixbuf, "snapshot.png", "png", &error, NULL);
   } else {
     g_print ("could not make snapshot\n");
   }
index 3c944ec..4526b1d 100644 (file)
@@ -85,7 +85,7 @@ cb_newpad (GstElement * decodebin, GstPad * pad, gboolean last, gpointer data)
   GstPadLinkReturn lret;
 
   /* check media type */
-  caps = gst_pad_get_caps (pad);
+  caps = gst_pad_get_caps (pad, NULL);
   str = gst_caps_get_structure (caps, 0);
 
   name = gst_structure_get_name (str);
index 715b4bb..8badfd3 100644 (file)
@@ -60,18 +60,18 @@ static void
 dump_element_stats (GstElement * element)
 {
   GstIterator *it;
-  gpointer data;
+  GValue data = { 0, };
 
   it = gst_element_iterate_src_pads (element);
   while (gst_iterator_next (it, &data) == GST_ITERATOR_OK) {
-    GstPad *pad = GST_PAD (data);
+    GstPad *pad = g_value_get_object (&data);
     GstCaps *caps;
     gchar *str;
     GstQuery *query;
 
     g_print ("stream %s:\n", GST_OBJECT_NAME (pad));
 
-    caps = gst_pad_get_caps (pad);
+    caps = gst_pad_get_caps (pad, NULL);
     str = gst_caps_to_string (caps);
     g_print (" caps: %s\n", str);
     g_free (str);
@@ -87,8 +87,9 @@ dump_element_stats (GstElement * element)
     }
     gst_query_unref (query);
 
-    gst_object_unref (pad);
+    g_value_reset (&data);
   }
+  g_value_unset (&data);
   gst_iterator_free (it);
 }
 
index 17e50f9..696767b 100644 (file)
@@ -79,7 +79,7 @@ main (gint argc, gchar * argv[])
   GstStateChangeReturn res;
   GstIterator *it;
   GstBus *bus;
-  gpointer data;
+  GValue data = { 0, };
 
   gst_init (&argc, &argv);
 
@@ -133,14 +133,14 @@ main (gint argc, gchar * argv[])
 
   it = gst_element_iterate_src_pads (decodebin);
   while (gst_iterator_next (it, &data) == GST_ITERATOR_OK) {
-    GstPad *pad = GST_PAD (data);
+    GstPad *pad = g_value_get_object (&data);
     GstCaps *caps;
     gchar *str;
     GstQuery *query;
 
     g_print ("stream %s:\n", GST_OBJECT_NAME (pad));
 
-    caps = gst_pad_get_caps (pad);
+    caps = gst_pad_get_caps (pad, NULL);
     str = gst_caps_to_string (caps);
     g_print (" caps: %s\n", str);
     g_free (str);
@@ -156,8 +156,9 @@ main (gint argc, gchar * argv[])
     }
     gst_query_unref (query);
 
-    gst_object_unref (pad);
+    g_value_reset (&data);
   }
+  g_value_unset (&data);
   gst_iterator_free (it);
 
   return 0;
index 8fc3107..0b32ed0 100644 (file)
@@ -94,7 +94,7 @@ have_subtitle (GstElement * appsink, App * app)
 
   if (buffer) {
     guint8 *data;
-    guint size;
+    gsize size;
     GstFormat format;
     gint64 position;
     GstClock *clock;
@@ -114,10 +114,9 @@ have_subtitle (GstElement * appsink, App * app)
         ", running_time %" GST_TIME_FORMAT, GST_TIME_ARGS (position),
         GST_TIME_ARGS (running_time));
 
-    data = GST_BUFFER_DATA (buffer);
-    size = GST_BUFFER_SIZE (buffer);
-
+    data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
     gst_util_dump_mem (data, size);
+    gst_buffer_unmap (buffer, data, size);
   }
 }
 
index 00d2d0f..bcadc1b 100644 (file)
@@ -249,7 +249,9 @@ print_tag_each (GQuark field_id, const GValue * value, gpointer user_data)
     ser = g_value_dup_string (value);
   else if (GST_VALUE_HOLDS_BUFFER (value)) {
     GstBuffer *buf = gst_value_get_buffer (value);
-    ser = g_strdup_printf ("<GstBuffer [%d bytes]>", GST_BUFFER_SIZE (buf));
+    ser =
+        g_strdup_printf ("<GstBuffer [%" G_GSIZE_FORMAT " bytes]>",
+        gst_buffer_get_size (buf));
   } else
     ser = gst_value_serialize (value);
 
index 892d680..596a576 100644 (file)
@@ -1,6 +1,4 @@
 EXPORTS
-       gst_app_buffer_get_type
-       gst_app_buffer_new
        gst_app_sink_get_caps
        gst_app_sink_get_drop
        gst_app_sink_get_emit_signals
index bd6f8c7..4a191d4 100644 (file)
@@ -1,4 +1,5 @@
 EXPORTS
+       gst_meta_net_address_get_info
        gst_netaddress_equal
        gst_netaddress_get_address_bytes
        gst_netaddress_get_ip4_address
@@ -8,5 +9,3 @@ EXPORTS
        gst_netaddress_set_ip4_address
        gst_netaddress_set_ip6_address
        gst_netaddress_to_string
-       gst_netbuffer_get_type
-       gst_netbuffer_new
index 41c9660..54d855b 100644 (file)
@@ -19,12 +19,13 @@ EXPORTS
        gst_basertppayload_set_options
        gst_basertppayload_set_outcaps
        gst_rtcp_buffer_add_packet
-       gst_rtcp_buffer_end
        gst_rtcp_buffer_get_first_packet
        gst_rtcp_buffer_get_packet_count
+       gst_rtcp_buffer_map
        gst_rtcp_buffer_new
        gst_rtcp_buffer_new_copy_data
        gst_rtcp_buffer_new_take_data
+       gst_rtcp_buffer_unmap
        gst_rtcp_buffer_validate
        gst_rtcp_buffer_validate_data
        gst_rtcp_ntp_to_unix
@@ -99,21 +100,7 @@ EXPORTS
        gst_rtp_buffer_get_ssrc
        gst_rtp_buffer_get_timestamp
        gst_rtp_buffer_get_version
-       gst_rtp_buffer_list_add_extension_onebyte_header
-       gst_rtp_buffer_list_add_extension_twobytes_header
-       gst_rtp_buffer_list_from_buffer
-       gst_rtp_buffer_list_get_extension_onebyte_header
-       gst_rtp_buffer_list_get_extension_twobytes_header
-       gst_rtp_buffer_list_get_payload_len
-       gst_rtp_buffer_list_get_payload_type
-       gst_rtp_buffer_list_get_seq
-       gst_rtp_buffer_list_get_ssrc
-       gst_rtp_buffer_list_get_timestamp
-       gst_rtp_buffer_list_set_payload_type
-       gst_rtp_buffer_list_set_seq
-       gst_rtp_buffer_list_set_ssrc
-       gst_rtp_buffer_list_set_timestamp
-       gst_rtp_buffer_list_validate
+       gst_rtp_buffer_map
        gst_rtp_buffer_new_allocate
        gst_rtp_buffer_new_allocate_len
        gst_rtp_buffer_new_copy_data
@@ -130,6 +117,7 @@ EXPORTS
        gst_rtp_buffer_set_ssrc
        gst_rtp_buffer_set_timestamp
        gst_rtp_buffer_set_version
+       gst_rtp_buffer_unmap
        gst_rtp_buffer_validate
        gst_rtp_buffer_validate_data
        gst_rtp_payload_info_for_name
index bab6bbd..7eab5a5 100644 (file)
@@ -17,6 +17,7 @@ EXPORTS
        gst_tag_list_add_id3_image
        gst_tag_list_from_exif_buffer
        gst_tag_list_from_exif_buffer_with_tiff_header
+       gst_tag_list_from_vorbiscomment
        gst_tag_list_from_vorbiscomment_buffer
        gst_tag_list_from_xmp_buffer
        gst_tag_list_new_from_id3v1
index 0f09b80..96b7e45 100644 (file)
@@ -1,4 +1,9 @@
 EXPORTS
+       gst_buffer_add_meta_video
+       gst_buffer_add_meta_video_full
+       gst_meta_video_get_info
+       gst_meta_video_map
+       gst_meta_video_unmap
        gst_video_calculate_display_ratio
        gst_video_convert_frame
        gst_video_convert_frame_async