1/*
2 * Copyright (C) 2010 Igalia S.L
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB.  If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "config.h"
21#include "ImageGStreamer.h"
22
23#if ENABLE(VIDEO) && USE(GSTREAMER)
24
25#include <cairo.h>
26#include <gst/gst.h>
27#include <gst/video/video.h>
28#include <wtf/gobject/GOwnPtr.h>
29
30#ifdef GST_API_VERSION_1
31#include <gst/video/gstvideometa.h>
32#endif
33
34
35using namespace std;
36using namespace WebCore;
37
38ImageGStreamer::ImageGStreamer(GstBuffer* buffer, GstCaps* caps)
39#ifdef GST_API_VERSION_1
40    : m_buffer(buffer)
41#endif
42{
43    GstVideoFormat format;
44    IntSize size;
45    int pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride;
46    getVideoSizeAndFormatFromCaps(caps, size, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride);
47
48#ifdef GST_API_VERSION_1
49    gst_buffer_map(buffer, &m_mapInfo, GST_MAP_READ);
50    unsigned char* bufferData = reinterpret_cast<unsigned char*>(m_mapInfo.data);
51#else
52    unsigned char* bufferData = reinterpret_cast<unsigned char*>(GST_BUFFER_DATA(buffer));
53#endif
54
55    cairo_format_t cairoFormat;
56#if G_BYTE_ORDER == G_LITTLE_ENDIAN
57    cairoFormat = (format == GST_VIDEO_FORMAT_BGRA) ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
58#else
59    cairoFormat = (format == GST_VIDEO_FORMAT_ARGB) ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
60#endif
61
62    RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create_for_data(bufferData, cairoFormat, size.width(), size.height(), stride));
63    ASSERT(cairo_surface_status(surface.get()) == CAIRO_STATUS_SUCCESS);
64    m_image = BitmapImage::create(surface.release());
65
66#ifdef GST_API_VERSION_1
67    if (GstVideoCropMeta* cropMeta = gst_buffer_get_video_crop_meta(buffer))
68        setCropRect(FloatRect(cropMeta->x, cropMeta->y, cropMeta->width, cropMeta->height));
69#endif
70}
71
72ImageGStreamer::~ImageGStreamer()
73{
74    if (m_image)
75        m_image.clear();
76
77    m_image = 0;
78
79#ifdef GST_API_VERSION_1
80    // We keep the buffer memory mapped until the image is destroyed because the internal
81    // cairo_surface_t was created using cairo_image_surface_create_for_data().
82    gst_buffer_unmap(m_buffer.get(), &m_mapInfo);
83#endif
84}
85#endif // USE(GSTREAMER)
86