[GStreamer] 0.11 video-sink
authorphiln@webkit.org <philn@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Jun 2012 02:25:14 +0000 (02:25 +0000)
committerphiln@webkit.org <philn@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Jun 2012 02:25:14 +0000 (02:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=77087

Reviewed by Martin Robinson.

* configure.ac: Fix required gstreamer 0.11 version

Source/WebCore:

Port the video sink to GStreamer 0.11 APIs. There is no change in
functionality compared to 0.10, for now.

* platform/graphics/gstreamer/GStreamerVersioning.cpp:
(webkitGetVideoSizeAndFormatFromCaps):
(webkitGstCreateBuffer):
* platform/graphics/gstreamer/GStreamerVersioning.h:
(WebCore):
* platform/graphics/gstreamer/ImageGStreamer.h:
(WebCore::ImageGStreamer::createImage):
(WebCore::ImageGStreamer::setCropRect):
(WebCore::ImageGStreamer::rect):
(ImageGStreamer):
* platform/graphics/gstreamer/ImageGStreamerCairo.cpp:
(ImageGStreamer::ImageGStreamer):
* platform/graphics/gstreamer/ImageGStreamerQt.cpp:
(ImageGStreamer::ImageGStreamer):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer):
(WebCore::MediaPlayerPrivateGStreamer::naturalSize):
* platform/graphics/gstreamer/VideoSinkGStreamer.cpp:
(_WebKitVideoSinkPrivate):
(webkitVideoSinkRender):
(webkitVideoSinkProposeAllocation):
(webkit_video_sink_class_init):
* platform/graphics/gstreamer/VideoSinkGStreamer.h:
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@120790 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
ChangeLog
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.cpp
Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.h
Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
Source/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp
Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp
Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp
Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h
Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
configure.ac

index 7be4ad4..91f15e3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-06-18  Philippe Normand  <pnormand@igalia.com>
+
+        [GStreamer] 0.11 video-sink
+        https://bugs.webkit.org/show_bug.cgi?id=77087
+
+        Reviewed by Martin Robinson.
+
+        * configure.ac: Fix required gstreamer 0.11 version
+
 2012-06-19  Jocelyn Turcotte  <jocelyn.turcotte@nokia.com>
 
         [Qt] Fix the Windows build when Qt is built without -release or -debug
index 0bd4432..d6cb304 100644 (file)
@@ -1,3 +1,38 @@
+2012-06-18  Philippe Normand  <pnormand@igalia.com>
+
+        [GStreamer] 0.11 video-sink
+        https://bugs.webkit.org/show_bug.cgi?id=77087
+
+        Reviewed by Martin Robinson.
+
+        Port the video sink to GStreamer 0.11 APIs. There is no change in
+        functionality compared to 0.10, for now.
+
+        * platform/graphics/gstreamer/GStreamerVersioning.cpp:
+        (webkitGetVideoSizeAndFormatFromCaps):
+        (webkitGstCreateBuffer):
+        * platform/graphics/gstreamer/GStreamerVersioning.h:
+        (WebCore):
+        * platform/graphics/gstreamer/ImageGStreamer.h:
+        (WebCore::ImageGStreamer::createImage):
+        (WebCore::ImageGStreamer::setCropRect):
+        (WebCore::ImageGStreamer::rect):
+        (ImageGStreamer):
+        * platform/graphics/gstreamer/ImageGStreamerCairo.cpp:
+        (ImageGStreamer::ImageGStreamer):
+        * platform/graphics/gstreamer/ImageGStreamerQt.cpp:
+        (ImageGStreamer::ImageGStreamer):
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer):
+        (WebCore::MediaPlayerPrivateGStreamer::naturalSize):
+        * platform/graphics/gstreamer/VideoSinkGStreamer.cpp:
+        (_WebKitVideoSinkPrivate):
+        (webkitVideoSinkRender):
+        (webkitVideoSinkProposeAllocation):
+        (webkit_video_sink_class_init):
+        * platform/graphics/gstreamer/VideoSinkGStreamer.h:
+        * platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
+
 2012-06-19  Tony Payne  <tpayne@chromium.org>
 
         Add monitor profile support for Win
index 852c261..06a8c9e 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "GStreamerVersioning.h"
 
-#include <gst/gst.h>
+#include "IntSize.h"
 
 void webkitGstObjectRefSink(GstObject* gstObject)
 {
@@ -48,3 +48,60 @@ GstCaps* webkitGstGetPadCaps(GstPad* pad)
 #endif
     return caps;
 }
+
+bool getVideoSizeAndFormatFromCaps(GstCaps* caps, WebCore::IntSize& size, GstVideoFormat& format, int& pixelAspectRatioNumerator, int& pixelAspectRatioDenominator, int& stride)
+{
+#ifdef GST_API_VERSION_1
+    GstVideoInfo info;
+    if (!gst_video_info_from_caps(&info, caps))
+        return false;
+
+    format = GST_VIDEO_INFO_FORMAT(&info);
+    size.setWidth(GST_VIDEO_INFO_WIDTH(&info));
+    size.setHeight(GST_VIDEO_INFO_HEIGHT(&info));
+    pixelAspectRatioNumerator = GST_VIDEO_INFO_PAR_N(&info);
+    pixelAspectRatioDenominator = GST_VIDEO_INFO_PAR_D(&info);
+    stride = GST_VIDEO_INFO_PLANE_STRIDE(&info, 0);
+#else
+    gint width, height;
+    if (!GST_IS_CAPS(caps) || !gst_caps_is_fixed(caps)
+        || !gst_video_format_parse_caps(caps, &format, &width, &height)
+        || !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator,
+                                                    &pixelAspectRatioDenominator))
+        return false;
+    size.setWidth(width);
+    size.setHeight(height);
+    stride = size.width() * 4;
+#endif
+
+    return true;
+}
+
+GstBuffer* createGstBuffer(GstBuffer* buffer)
+{
+#ifndef GST_API_VERSION_1
+    GstBuffer* newBuffer = gst_buffer_try_new_and_alloc(GST_BUFFER_SIZE(buffer));
+#else
+    gsize bufferSize = gst_buffer_get_size(buffer);
+    GstBuffer* newBuffer = gst_buffer_new_and_alloc(bufferSize);
+#endif
+
+    if (!newBuffer)
+        return 0;
+
+#ifndef GST_API_VERSION_1
+    gst_buffer_copy_metadata(newBuffer, buffer, static_cast<GstBufferCopyFlags>(GST_BUFFER_COPY_ALL));
+#else
+    gst_buffer_copy_into(newBuffer, buffer, static_cast<GstBufferCopyFlags>(GST_BUFFER_COPY_METADATA), 0, bufferSize);
+#endif
+    return newBuffer;
+}
+
+void setGstElementClassMetadata(GstElementClass* elementClass, const char* name, const char* longName, const char* description, const char* author)
+{
+#ifdef GST_API_VERSION_1
+    gst_element_class_set_metadata(elementClass, name, longName, description, author);
+#else
+    gst_element_class_set_details_simple(elementClass, name, longName, description, author);
+#endif
+}
index 8dce21b..6b21b63 100644 (file)
 #ifndef GStreamerVersioning_h
 #define GStreamerVersioning_h
 
-typedef struct _GstCaps GstCaps;
-typedef struct _GstObject GstObject;
-typedef struct _GstPad GstPad;
+#include <gst/gst.h>
+#include <gst/video/video.h>
+
+namespace WebCore {
+class IntSize;
+};
 
 void webkitGstObjectRefSink(GstObject*);
 GstCaps* webkitGstGetPadCaps(GstPad*);
-
+bool getVideoSizeAndFormatFromCaps(GstCaps*, WebCore::IntSize&, GstVideoFormat&, int& pixelAspectRatioNumerator, int& pixelAspectRatioDenominator, int& stride);
+GstBuffer* createGstBuffer(GstBuffer*);
+void setGstElementClassMetadata(GstElementClass*, const char* name, const char* longName, const char* description, const char* author);
 #endif // GStreamerVersioning_h
index 38e083f..83bdfe2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Igalia S.L
+ * Copyright (C) 2010, 2011, 2012 Igalia S.L
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 #if ENABLE(VIDEO) && USE(GSTREAMER)
 
 #include "BitmapImage.h"
-#include <gst/gst.h>
-#include <gst/video/video.h>
+#include "FloatRect.h"
+#include "GStreamerVersioning.h"
 #include <wtf/PassRefPtr.h>
-
-#if USE(CAIRO)
-#include <cairo.h>
-#endif
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
 
 namespace WebCore {
 class IntSize;
 
 class ImageGStreamer : public RefCounted<ImageGStreamer> {
     public:
-        static PassRefPtr<ImageGStreamer> createImage(GstBuffer*);
+        static PassRefPtr<ImageGStreamer> createImage(GstBuffer* buffer, GstCaps* caps)
+        {
+            return adoptRef(new ImageGStreamer(buffer, caps));
+        }
         ~ImageGStreamer();
 
         PassRefPtr<BitmapImage> image()
@@ -45,17 +46,20 @@ class ImageGStreamer : public RefCounted<ImageGStreamer> {
             return m_image.get();
         }
 
-    private:
-        RefPtr<BitmapImage> m_image;
-
-#if USE(CAIRO)
-        ImageGStreamer(GstBuffer*&, IntSize, cairo_format_t&);
-#endif
+        void setCropRect(FloatRect rect) { m_cropRect = rect; }
+        FloatRect rect()
+        {
+            if (!m_cropRect.isEmpty())
+                return FloatRect(m_cropRect);
 
-#if PLATFORM(QT)
-        ImageGStreamer(GstBuffer*&, IntSize, QImage::Format);
-#endif
+            // Default rectangle used by GraphicsContext::drawImage().
+            return FloatRect(0, 0, -1, -1);
+        }
 
+    private:
+        ImageGStreamer(GstBuffer*, GstCaps*);
+        RefPtr<BitmapImage> m_image;
+        FloatRect m_cropRect;
     };
 }
 
index a0bf5f4..d3f7fa7 100644 (file)
 
 #if ENABLE(VIDEO) && USE(GSTREAMER)
 
+#include <cairo.h>
+#include <gst/gst.h>
+#include <gst/video/video.h>
 #include <wtf/gobject/GOwnPtr.h>
 
+#ifdef GST_API_VERSION_1
+#include <gst/video/gstvideometa.h>
+#endif
+
+
 using namespace std;
 using namespace WebCore;
 
-PassRefPtr<ImageGStreamer> ImageGStreamer::createImage(GstBuffer* buffer)
+ImageGStreamer::ImageGStreamer(GstBuffer* buffer, GstCaps* caps)
 {
-    int width = 0, height = 0;
-    GstCaps* caps = gst_buffer_get_caps(buffer);
     GstVideoFormat format;
-    if (!gst_video_format_parse_caps(caps, &format, &width, &height)) {
-        gst_caps_unref(caps);
-        return 0;
-    }
+    IntSize size;
+    int pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride;
+    getVideoSizeAndFormatFromCaps(caps, size, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride);
 
-    gst_caps_unref(caps);
+#ifdef GST_API_VERSION_1
+    GstMapInfo mapInfo;
+    gst_buffer_map(buffer, &mapInfo, GST_MAP_READ);
+    unsigned char* bufferData = reinterpret_cast<unsigned char*>(mapInfo.data);
+#else
+    unsigned char* bufferData = reinterpret_cast<unsigned char*>(GST_BUFFER_DATA(buffer));
+#endif
 
     cairo_format_t cairoFormat;
-    if (format == GST_VIDEO_FORMAT_ARGB || format == GST_VIDEO_FORMAT_BGRA)
-        cairoFormat = CAIRO_FORMAT_ARGB32;
-    else
-        cairoFormat = CAIRO_FORMAT_RGB24;
-
-    return adoptRef(new ImageGStreamer(buffer, IntSize(width, height), cairoFormat));
-}
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+    cairoFormat = (format == GST_VIDEO_FORMAT_BGRA) ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
+#else
+    cairoFormat = (format == GST_VIDEO_FORMAT_ARGB) ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
+#endif
 
-ImageGStreamer::ImageGStreamer(GstBuffer*& buffer, IntSize size, cairo_format_t& cairoFormat)
-    : m_image(0)
-{
-    cairo_surface_t* surface = cairo_image_surface_create_for_data(GST_BUFFER_DATA(buffer), cairoFormat,
-                                                    size.width(), size.height(),
-                                                    cairo_format_stride_for_width(cairoFormat, size.width()));
+    cairo_surface_t* surface = cairo_image_surface_create_for_data(bufferData, cairoFormat, size.width(), size.height(), stride);
     ASSERT(cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS);
     m_image = BitmapImage::create(surface);
+
+#ifdef GST_API_VERSION_1
+    if (GstVideoCropMeta* cropMeta = gst_buffer_get_video_crop_meta(buffer))
+        setCropRect(FloatRect(cropMeta->x, cropMeta->y, cropMeta->width, cropMeta->height));
+
+    gst_buffer_unmap(buffer, &mapInfo);
+#endif
 }
 
 ImageGStreamer::~ImageGStreamer()
index 36b0806..b354914 100644 (file)
 #include "ImageGStreamer.h"
 
 #if ENABLE(VIDEO) && USE(GSTREAMER)
+#include <gst/gst.h>
+#include <gst/video/video.h>
+
+#ifdef GST_API_VERSION_1
+#include <gst/video/gstvideometa.h>
+#endif
+
 #include <wtf/gobject/GOwnPtr.h>
 
 using namespace std;
 using namespace WebCore;
 
-PassRefPtr<ImageGStreamer> ImageGStreamer::createImage(GstBuffer* buffer)
+ImageGStreamer::ImageGStreamer(GstBuffer* buffer, GstCaps* caps)
+    : m_image(0)
 {
-    int width = 0, height = 0;
-    GstCaps* caps = gst_buffer_get_caps(buffer);
+    QPixmap* surface = new QPixmap;
     GstVideoFormat format;
-    if (!gst_video_format_parse_caps(caps, &format, &width, &height)) {
-        gst_caps_unref(caps);
-        return 0;
-    }
-
-    gst_caps_unref(caps);
+    IntSize size;
+    int pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride;
+    webkitGetVideoSizeAndFormatFromCaps(caps, size, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride);
 
+#ifdef GST_API_VERSION_1
+    GstMapInfo info;
+    gst_buffer_map(buffer, &info, GST_MAP_READ);
+    uchar* bufferData = reinterpret_cast<uchar*>(info.data);
+#else
+    uchar* bufferData = reinterpret_cast<uchar*>(GST_BUFFER_DATA(buffer));
+#endif
     QImage::Format imageFormat;
-    if (format == GST_VIDEO_FORMAT_RGB)
-        imageFormat = QImage::Format_RGB888;
-    else
-        imageFormat = QImage::Format_RGB32;
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+    imageFormat = (format == GST_VIDEO_FORMAT_BGRA) ? QImage::Format_RGB32 : QImage::Format_RGB888;
+#else
+    imageFormat = (format == GST_VIDEO_FORMAT_ARGB) ? QImage::Format_ARGB32 : QImage::Format_RGB888;
+#endif
 
-    return adoptRef(new ImageGStreamer(buffer, IntSize(width, height), imageFormat));
-}
+    QImage image(bufferData, size.width(), size.height(), imageFormat);
 
-ImageGStreamer::ImageGStreamer(GstBuffer*& buffer, IntSize size, QImage::Format imageFormat)
-    : m_image(0)
-{
-    QPixmap* surface = new QPixmap;
-    QImage image(GST_BUFFER_DATA(buffer), size.width(), size.height(), imageFormat);
     surface->convertFromImage(image);
     m_image = BitmapImage::create(surface);
+
+#ifdef GST_API_VERSION_1
+    gst_buffer_unmap(buffer, &info);
+#endif
 }
 
 ImageGStreamer::~ImageGStreamer()
index ac33ca7..05b78b0 100644 (file)
@@ -254,10 +254,12 @@ MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer()
         m_mediaLocations = 0;
     }
 
+#ifndef GST_API_VERSION_1
     if (m_videoSinkBin) {
         gst_object_unref(m_videoSinkBin);
         m_videoSinkBin = 0;
     }
+#endif
 
     if (m_playBin) {
         gst_element_set_state(m_playBin, GST_STATE_NULL);
@@ -497,9 +499,6 @@ IntSize MediaPlayerPrivateGStreamer::naturalSize() const
     if (!caps)
         return IntSize();
 
-    int pixelAspectRatioNumerator, pixelAspectRatioDenominator;
-    int displayWidth, displayHeight, displayAspectRatioGCD;
-    int originalWidth = 0, originalHeight = 0;
 
     // TODO: handle possible clean aperture data. See
     // https://bugzilla.gnome.org/show_bug.cgi?id=596571
@@ -508,50 +507,38 @@ IntSize MediaPlayerPrivateGStreamer::naturalSize() const
 
     // Get the video PAR and original size, if this fails the
     // video-sink has likely not yet negotiated its caps.
-#ifdef GST_API_VERSION_1
-    GstVideoInfo info;
-    if (!gst_video_info_from_caps(&info, caps))
-        return IntSize();
-
-    originalWidth = GST_VIDEO_INFO_WIDTH(&info);
-    originalHeight = GST_VIDEO_INFO_HEIGHT(&info);
-    pixelAspectRatioNumerator = GST_VIDEO_INFO_PAR_N(&info);
-    pixelAspectRatioDenominator = GST_VIDEO_INFO_PAR_D(&info);
-#else
-    // Get the video PAR and original size.
-    if (!GST_IS_CAPS(caps) || !gst_caps_is_fixed(caps)
-        || !gst_video_format_parse_caps(caps, 0, &originalWidth, &originalHeight)
-        || !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator,
-                                                    &pixelAspectRatioDenominator))
+    int pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride;
+    IntSize originalSize;
+    GstVideoFormat format;
+    if (!getVideoSizeAndFormatFromCaps(caps, originalSize, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride))
         return IntSize();
-#endif
 
-    LOG_VERBOSE(Media, "Original video size: %dx%d", originalWidth, originalHeight);
+    LOG_VERBOSE(Media, "Original video size: %dx%d", originalSize.width(), originalSize.height());
     LOG_VERBOSE(Media, "Pixel aspect ratio: %d/%d", pixelAspectRatioNumerator, pixelAspectRatioDenominator);
 
     // Calculate DAR based on PAR and video size.
-    displayWidth = originalWidth * pixelAspectRatioNumerator;
-    displayHeight = originalHeight * pixelAspectRatioDenominator;
+    int displayWidth = originalSize.width() * pixelAspectRatioNumerator;
+    int displayHeight = originalSize.height() * pixelAspectRatioDenominator;
 
     // Divide display width and height by their GCD to avoid possible overflows.
-    displayAspectRatioGCD = greatestCommonDivisor(displayWidth, displayHeight);
+    int displayAspectRatioGCD = greatestCommonDivisor(displayWidth, displayHeight);
     displayWidth /= displayAspectRatioGCD;
     displayHeight /= displayAspectRatioGCD;
 
     // Apply DAR to original video size. This is the same behavior as in xvimagesink's setcaps function.
     guint64 width = 0, height = 0;
-    if (!(originalHeight % displayHeight)) {
+    if (!(originalSize.height() % displayHeight)) {
         LOG_VERBOSE(Media, "Keeping video original height");
-        width = gst_util_uint64_scale_int(originalHeight, displayWidth, displayHeight);
-        height = static_cast<guint64>(originalHeight);
-    } else if (!(originalWidth % displayWidth)) {
+        width = gst_util_uint64_scale_int(originalSize.height(), displayWidth, displayHeight);
+        height = static_cast<guint64>(originalSize.height());
+    } else if (!(originalSize.width() % displayWidth)) {
         LOG_VERBOSE(Media, "Keeping video original width");
-        height = gst_util_uint64_scale_int(originalWidth, displayHeight, displayWidth);
-        width = static_cast<guint64>(originalWidth);
+        height = gst_util_uint64_scale_int(originalSize.width(), displayHeight, displayWidth);
+        width = static_cast<guint64>(originalSize.width());
     } else {
         LOG_VERBOSE(Media, "Approximating while keeping original video height");
-        width = gst_util_uint64_scale_int(originalHeight, displayWidth, displayHeight);
-        height = static_cast<guint64>(originalHeight);
+        width = gst_util_uint64_scale_int(originalSize.height(), displayWidth, displayHeight);
+        height = static_cast<guint64>(originalSize.height());
     }
 
     LOG_VERBOSE(Media, "Natural size: %" G_GUINT64_FORMAT "x%" G_GUINT64_FORMAT, width, height);
@@ -957,7 +944,7 @@ unsigned MediaPlayerPrivateGStreamer::totalBytes() const
     bool done = false;
     while (!done) {
 #ifdef GST_API_VERSION_1
-        GValue item = {0, };
+        GValue item = G_VALUE_INIT;
         switch (gst_iterator_next(iter, &item)) {
         case GST_ITERATOR_OK: {
             GstPad* pad = static_cast<GstPad*>(g_value_get_object(&item));
@@ -1481,17 +1468,20 @@ void MediaPlayerPrivateGStreamer::paint(GraphicsContext* context, const IntRect&
     if (!m_buffer)
         return;
 
-    RefPtr<ImageGStreamer> gstImage = ImageGStreamer::createImage(m_buffer);
+    GstCaps* caps = webkitGstGetPadCaps(m_videoSinkPad.get());
+    if (!caps)
+        return;
+
+    RefPtr<ImageGStreamer> gstImage = ImageGStreamer::createImage(m_buffer, caps);
     if (!gstImage)
         return;
 
     context->drawImage(reinterpret_cast<Image*>(gstImage->image().get()), ColorSpaceSRGB,
-                       rect, CompositeCopy, DoNotRespectImageOrientation, false);
+                       rect, gstImage->rect(), CompositeCopy, DoNotRespectImageOrientation, false);
 }
 
 static HashSet<String> mimeTypeCache()
 {
-
     initializeGStreamerAndRegisterWebKitElements();
 
     DEFINE_STATIC_LOCAL(HashSet<String>, cache, ());
@@ -1673,7 +1663,11 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin()
     g_signal_connect(m_playBin, "video-changed", G_CALLBACK(mediaPlayerPrivateVideoChangedCallback), this);
     g_signal_connect(m_playBin, "audio-changed", G_CALLBACK(mediaPlayerPrivateAudioChangedCallback), this);
 
+#ifndef GST_API_VERSION_1
     m_webkitVideoSink = webkitVideoSinkNew(m_gstGWorld.get());
+#else
+    m_webkitVideoSink = webkitVideoSinkNew();
+#endif
     m_videoSinkPad = adoptGRef(gst_element_get_static_pad(m_webkitVideoSink, "sink"));
 
     g_signal_connect(m_webkitVideoSink, "repaint-requested", G_CALLBACK(mediaPlayerPrivateRepaintCallback), this);
index 1389b69..fdb6f4c 100644 (file)
 #if USE(GSTREAMER)
 #include "VideoSinkGStreamer.h"
 
+#include "GStreamerVersioning.h"
+#include "IntSize.h"
 #include <glib.h>
 #include <gst/gst.h>
+#ifdef GST_API_VERSION_1
+#include <gst/video/gstvideometa.h>
+#include <gst/video/gstvideopool.h>
+#endif
 #include <wtf/FastAllocBase.h>
 
 // CAIRO_FORMAT_RGB24 used to render the video buffers is little/big endian dependant.
 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#ifndef GST_API_VERSION_1
 #define WEBKIT_VIDEO_SINK_PAD_CAPS GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_BGRA
 #else
+#define WEBKIT_VIDEO_SINK_PAD_CAPS GST_VIDEO_CAPS_MAKE("{ BGRx, BGRA }")
+#endif
+#else
+#ifndef GST_API_VERSION_1
 #define WEBKIT_VIDEO_SINK_PAD_CAPS GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_ARGB
+#else
+#define WEBKIT_VIDEO_SINK_PAD_CAPS GST_VIDEO_CAPS_MAKE("{ xRGB, ARGB }")
+#endif
 #endif
 static GstStaticPadTemplate s_sinkTemplate = GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS(WEBKIT_VIDEO_SINK_PAD_CAPS));
 
@@ -62,7 +76,13 @@ struct _WebKitVideoSinkPrivate {
     GMutex* bufferMutex;
     GCond* dataCondition;
 
+#ifdef GST_API_VERSION_1
+    GstVideoInfo info;
+#endif
+
+#ifndef GST_API_VERSION_1
     WebCore::GStreamerGWorld* gstGWorld;
+#endif
 
     // If this is TRUE all processing should finish ASAP
     // This is necessary because there could be a race between
@@ -91,6 +111,10 @@ static void webkit_video_sink_init(WebKitVideoSink* sink)
     sink->priv->dataCondition = g_cond_new();
     sink->priv->bufferMutex = g_mutex_new();
 #endif
+
+#ifdef GST_API_VERSION_1
+    gst_video_info_init(&sink->priv->info);
+#endif
 }
 
 static gboolean webkitVideoSinkTimeoutCallback(gpointer data)
@@ -129,15 +153,18 @@ static GstFlowReturn webkitVideoSinkRender(GstBaseSink* baseSink, GstBuffer* buf
         return GST_FLOW_OK;
     }
 
+#ifndef GST_API_VERSION_1
     // Ignore buffers if the video is already in fullscreen using
     // another sink.
     if (priv->gstGWorld->isFullscreen()) {
         g_mutex_unlock(priv->bufferMutex);
         return GST_FLOW_OK;
     }
+#endif
 
     priv->buffer = gst_buffer_ref(buffer);
 
+#ifndef GST_API_VERSION_1
     // For the unlikely case where the buffer has no caps, the caps
     // are implicitely the caps of the pad. This shouldn't happen.
     if (UNLIKELY(!GST_BUFFER_CAPS(buffer))) {
@@ -146,14 +173,26 @@ static GstFlowReturn webkitVideoSinkRender(GstBaseSink* baseSink, GstBuffer* buf
     }
 
     GstCaps* caps = GST_BUFFER_CAPS(buffer);
+#else
+    GstCaps* caps = gst_video_info_to_caps(&priv->info);
+#endif
+
     GstVideoFormat format;
-    int width, height;
-    if (UNLIKELY(!gst_video_format_parse_caps(caps, &format, &width, &height))) {
+    WebCore::IntSize size;
+    int pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride;
+    if (!getVideoSizeAndFormatFromCaps(caps, size, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride)) {
         gst_buffer_unref(buffer);
+#ifdef GST_API_VERSION_1
+        gst_caps_unref(caps);
+#endif
         g_mutex_unlock(priv->bufferMutex);
         return GST_FLOW_ERROR;
     }
 
+#ifdef GST_API_VERSION_1
+    gst_caps_unref(caps);
+#endif
+
     // Cairo's ARGB has pre-multiplied alpha while GStreamer's doesn't.
     // Here we convert to Cairo's ARGB.
     if (format == GST_VIDEO_FORMAT_ARGB || format == GST_VIDEO_FORMAT_BGRA) {
@@ -162,7 +201,7 @@ static GstFlowReturn webkitVideoSinkRender(GstBaseSink* baseSink, GstBuffer* buf
         // The buffer content should not be changed here because the same buffer
         // could be passed multiple times to this method (in theory).
 
-        GstBuffer* newBuffer = gst_buffer_try_new_and_alloc(GST_BUFFER_SIZE(buffer));
+        GstBuffer* newBuffer = createGstBuffer(buffer);
 
         // Check if allocation failed.
         if (UNLIKELY(!newBuffer)) {
@@ -170,17 +209,24 @@ static GstFlowReturn webkitVideoSinkRender(GstBaseSink* baseSink, GstBuffer* buf
             return GST_FLOW_ERROR;
         }
 
-        gst_buffer_copy_metadata(newBuffer, buffer, static_cast<GstBufferCopyFlags>(GST_BUFFER_COPY_ALL));
-
         // We don't use Color::premultipliedARGBFromColor() here because
         // one function call per video pixel is just too expensive:
         // For 720p/PAL for example this means 1280*720*25=23040000
         // function calls per second!
+#ifndef GST_API_VERSION_1
         const guint8* source = GST_BUFFER_DATA(buffer);
         guint8* destination = GST_BUFFER_DATA(newBuffer);
+#else
+        GstMapInfo sourceInfo;
+        GstMapInfo destinationInfo;
+        gst_buffer_map(buffer, &sourceInfo, GST_MAP_READ);
+        const guint8* source = const_cast<guint8*>(sourceInfo.data);
+        gst_buffer_map(newBuffer, &destinationInfo, GST_MAP_WRITE);
+        guint8* destination = static_cast<guint8*>(destinationInfo.data);
+#endif
 
-        for (int x = 0; x < height; x++) {
-            for (int y = 0; y < width; y++) {
+        for (int x = 0; x < size.height(); x++) {
+            for (int y = 0; y < size.width(); y++) {
 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
                 unsigned short alpha = source[3];
                 destination[0] = (source[0] * alpha + 128) / 255;
@@ -199,6 +245,10 @@ static GstFlowReturn webkitVideoSinkRender(GstBaseSink* baseSink, GstBuffer* buf
             }
         }
 
+#ifdef GST_API_VERSION_1
+        gst_buffer_unmap(buffer, &sourceInfo);
+        gst_buffer_unmap(newBuffer, &destinationInfo);
+#endif
         gst_buffer_unref(buffer);
         buffer = priv->buffer = newBuffer;
     }
@@ -293,6 +343,25 @@ static gboolean webkitVideoSinkStart(GstBaseSink* baseSink)
     return TRUE;
 }
 
+#ifdef GST_API_VERSION_1
+static gboolean webkitVideoSinkProposeAllocation(GstBaseSink* baseSink, GstQuery* query)
+{
+    GstCaps* caps;
+    gst_query_parse_allocation(query, &caps, 0);
+    if (!caps)
+        return FALSE;
+
+    WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(baseSink);
+    if (!gst_video_info_from_caps(&sink->priv->info, caps))
+        return FALSE;
+
+    gst_query_add_allocation_meta(query, GST_VIDEO_META_API_TYPE);
+    gst_query_add_allocation_meta(query, GST_VIDEO_CROP_META_API_TYPE);
+    return TRUE;
+}
+#endif
+
+#ifndef GST_API_VERSION_1
 static void webkitVideoSinkMarshalVoidAndMiniObject(GClosure* closure, GValue* returnValue, guint parametersNumber, const GValue* parameterValues, gpointer invocationHint, gpointer marshalData)
 {
     typedef void (*marshalfunc_VOID__MINIOBJECT) (gpointer obj, gpointer arg1, gpointer data2);
@@ -313,6 +382,7 @@ static void webkitVideoSinkMarshalVoidAndMiniObject(GClosure* closure, GValue* r
     callback = (marshalfunc_VOID__MINIOBJECT) (marshalData ? marshalData : cclosure->callback);
     callback(data1, gst_value_get_mini_object(parameterValues + 1), data2);
 }
+#endif
 
 static void webkit_video_sink_class_init(WebKitVideoSinkClass* klass)
 {
@@ -321,7 +391,11 @@ static void webkit_video_sink_class_init(WebKitVideoSinkClass* klass)
     GstElementClass* elementClass = GST_ELEMENT_CLASS(klass);
 
     gst_element_class_add_pad_template(elementClass, gst_static_pad_template_get(&s_sinkTemplate));
+#ifdef GST_API_VERSION_1
+    gst_element_class_set_metadata(elementClass,
+#else
     gst_element_class_set_details_simple(elementClass,
+#endif
             "WebKit video sink",
             "Sink/Video", "Sends video data from a GStreamer pipeline to a Cairo surface",
             "Alp Toker <alp@atoker.com>");
@@ -336,6 +410,9 @@ static void webkit_video_sink_class_init(WebKitVideoSinkClass* klass)
     baseSinkClass->preroll = webkitVideoSinkRender;
     baseSinkClass->stop = webkitVideoSinkStop;
     baseSinkClass->start = webkitVideoSinkStart;
+#ifdef GST_API_VERSION_1
+    baseSinkClass->propose_allocation = webkitVideoSinkProposeAllocation;
+#endif
 
     webkitVideoSinkSignals[REPAINT_REQUESTED] = g_signal_new("repaint-requested",
             G_TYPE_FROM_CLASS(klass),
@@ -343,18 +420,29 @@ static void webkit_video_sink_class_init(WebKitVideoSinkClass* klass)
             0, // Class offset
             0, // Accumulator
             0, // Accumulator data
+#ifndef GST_API_VERSION_1
             webkitVideoSinkMarshalVoidAndMiniObject,
+#else
+            g_cclosure_marshal_generic,
+#endif
             G_TYPE_NONE, // Return type
             1, // Only one parameter
             GST_TYPE_BUFFER);
 }
 
 
+#ifndef GST_API_VERSION_1
 GstElement* webkitVideoSinkNew(WebCore::GStreamerGWorld* gstGWorld)
 {
     GstElement* element = GST_ELEMENT(g_object_new(WEBKIT_TYPE_VIDEO_SINK, 0));
     WEBKIT_VIDEO_SINK(element)->priv->gstGWorld = gstGWorld;
     return element;
 }
+#else
+GstElement* webkitVideoSinkNew()
+{
+    return GST_ELEMENT(g_object_new(WEBKIT_TYPE_VIDEO_SINK, 0));
+}
+#endif
 
 #endif // USE(GSTREAMER)
index 34057aa..061b694 100644 (file)
 
 #if ENABLE(VIDEO) && USE(GSTREAMER)
 
+#ifndef GST_API_VERSION_1
 #include "GStreamerGWorld.h"
+#endif
+
 #include <glib-object.h>
 #include <gst/video/gstvideosink.h>
 #include <gst/video/video.h>
@@ -58,7 +61,11 @@ struct _WebKitVideoSinkClass {
 
 GType webkit_video_sink_get_type() G_GNUC_CONST;
 
+#ifndef GST_API_VERSION_1
 GstElement* webkitVideoSinkNew(WebCore::GStreamerGWorld*);
+#else
+GstElement* webkitVideoSinkNew();
+#endif
 
 #endif // USE(GSTREAMER)
 #endif
index d1d9147..c5d7690 100644 (file)
@@ -853,10 +853,14 @@ void StreamingClient::didReceiveResponse(ResourceHandle*, const ResourceResponse
     }
 
     if (gst_tag_list_is_empty(tags))
+#ifdef GST_API_VERSION_1
+        gst_tag_list_unref(tags);
+#else
         gst_tag_list_free(tags);
+#endif
     else
 #ifdef GST_API_VERSION_1
-        gst_pad_push_event(GST_PAD_CAST(m_src->priv->srcpad), gst_event_new_tag(tags));
+        gst_pad_push_event(GST_PAD_CAST(m_src->priv->srcpad), gst_event_new_tag("WebKitWebSrc", tags));
 #else
         gst_element_found_tags_for_pad(GST_ELEMENT(m_src), m_src->priv->srcpad, tags);
 #endif
index 1da7975..95957b5 100644 (file)
@@ -348,7 +348,7 @@ AC_MSG_RESULT([$with_gstreamer])
 
 GSTREAMER_0_10_REQUIRED_VERSION=0.10
 GSTREAMER_0_10_PLUGINS_BASE_REQUIRED_VERSION=0.10.30
-GSTREAMER_1_0_REQUIRED_VERSION=1.0
+GSTREAMER_1_0_REQUIRED_VERSION=0.11.90
 GSTREAMER_1_0_PLUGINS_BASE_REQUIRED_VERSION=0.11.90
 
 case "$with_gstreamer" in