gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnash-commit] /srv/bzr/gnash/trunk r10604: XV support, part one: co


From: Markus Gothe
Subject: Re: [Gnash-commit] /srv/bzr/gnash/trunk r10604: XV support, part one: colorspace conversion.
Date: Sat, 21 Feb 2009 21:13:21 +0100

Nice work!

//Markus

On 21 Feb 2009, at 15:19, Bastiaan Jacques wrote:

------------------------------------------------------------
revno: 10604
committer: Bastiaan Jacques <address@hidden>
branch nick: trunk
timestamp: Sat 2009-02-21 15:19:48 +0100
message:
 XV support, part one: colorspace conversion.

 * libmedia/VideoConverter.h: Base class for video converter
   implementations.
 * libmedia/MediaHandler.{h}: Media handler support for creating
   video converter objects.
 * libmedia/ffmpeg/MediaHandlerFfmpeg.{cpp,h}: Support creating
   the ffmpeg video converter.
 * libmedia/gst/MediaHandlerGst.{cpp,h}: Idem dito.
 * libmedia/gst/swfdec_codec_gst.{c,h}: Add a function specifically
   for creating a colorspace conversion "pipeline".
 * libmedia/ffmpeg/VideoConverterFfmpeg{cpp,h}: Implementation of the
   ffmpeg video converter.
 * libmedia/gst/VideoConverterGst.{cpp,h}: Gstreamer video converter
   implementation.
 * libmedia/Makefile.am: Enable building of newly added files.
added:
 libmedia/VideoConverter.h
 libmedia/ffmpeg/VideoConverterFfmpeg.cpp
 libmedia/ffmpeg/VideoConverterFfmpeg.h
 libmedia/gst/VideoConverterGst.cpp
 libmedia/gst/VideoConverterGst.h
modified:
 libmedia/Makefile.am
 libmedia/MediaHandler.h
 libmedia/ffmpeg/MediaHandlerFfmpeg.cpp
 libmedia/ffmpeg/MediaHandlerFfmpeg.h
 libmedia/gst/MediaHandlerGst.cpp
 libmedia/gst/MediaHandlerGst.h
 libmedia/gst/swfdec_codec_gst.c
 libmedia/gst/swfdec_codec_gst.h
=== modified file 'libmedia/Makefile.am'
--- a/libmedia/Makefile.am      2009-01-22 20:10:39 +0000
+++ b/libmedia/Makefile.am      2009-02-21 14:19:48 +0000
@@ -81,6 +81,7 @@
noinst_HEADERS = \
        AudioDecoder.h \
        VideoDecoder.h \
+       VideoConverter.h \
        MediaParser.h \
        MediaHandler.h \
        FLVParser.h \
@@ -97,6 +98,7 @@
                gst/VideoDecoderGst.cpp \
                gst/AudioDecoderGst.cpp \
                gst/MediaParserGst.cpp \
+               gst/VideoConverterGst.cpp \
                gst/GstUtil.cpp \
                gst/swfdec_codec_gst.c \
                $(NULL)
@@ -106,6 +108,7 @@
                gst/AudioDecoderGst.h \
                gst/VideoDecoderGst.h \
                gst/MediaParserGst.h \
+               gst/VideoConverterGst.cpp \
                gst/GstUtil.h \
                gst/swfdec_codec_gst.h \
                gst/gnash_gst_version.h \
@@ -129,6 +132,7 @@
                ffmpeg/AudioDecoderFfmpeg.cpp \
                ffmpeg/VideoDecoderFfmpeg.cpp \
                ffmpeg/AudioResamplerFfmpeg.cpp \
+               ffmpeg/VideoConverterFfmpeg.cpp \
                $(NULL)

   noinst_HEADERS += \
@@ -138,6 +142,7 @@
                ffmpeg/VideoDecoderFfmpeg.h \
                ffmpeg/AudioResamplerFfmpeg.h \
                ffmpeg/ffmpegHeaders.h \
+               ffmpeg/VideoConverterFfmpeg.h \
                $(NULL)

   libgnashmedia_la_LIBADD += \

=== modified file 'libmedia/MediaHandler.h'
--- a/libmedia/MediaHandler.h   2009-01-22 20:10:39 +0000
+++ b/libmedia/MediaHandler.h   2009-02-21 14:19:48 +0000
@@ -26,6 +26,7 @@

#include "MediaParser.h" // for videoCodecType and audioCodecType enums
#include "dsodefs.h" // DSOEXPORT
+#include "VideoConverter.h"

#include <memory>

@@ -106,6 +107,15 @@
    ///             gnash::MediaException if a fatal error occurs.
virtual std::auto_ptr<AudioDecoder> createAudioDecoder(const AudioInfo& info)=0;

+    /// Create an VideoConverter for converting between color spaces.
+    //
+    /// @param srcFormat The source image color space
+    /// @param dstFormat The destination image color space
+    ///
+ /// @return A valid VideoConverter or a NULL auto_ptr if a fatal error occurs.
+    virtual std::auto_ptr<VideoConverter>
+ createVideoConverter(ImgBuf::Type4CC srcFormat, ImgBuf::Type4CC dstFormat)=0;
+
    /// Return the number of bytes padding needed for input buffers
    //
/// Bitstream readers are optimized to read several bytes at a time,

=== added file 'libmedia/VideoConverter.h'
--- a/libmedia/VideoConverter.h 1970-01-01 00:00:00 +0000
+++ b/libmedia/VideoConverter.h 2009-02-21 14:19:48 +0000
@@ -0,0 +1,113 @@
+//   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+#ifndef GNASH_VIDEOCONVERTER_H
+#define GNASH_VIDEOCONVERTER_H
+
+#include <boost/noncopyable.hpp>
+#include <boost/cstdint.hpp>
+#include <memory>
+
+namespace gnash {
+namespace media {
+
+
+
+/// Image buffer wrapper
+//
+/// Unfortunately, the GnashImage buffer class currently insists on owning +/// its buffer. Hacking around this results in things like gnashGstBuffer, +/// which is less than desirable. Furthermore, it only supports a handful of +/// pixel and image formats. Something more elaborate is needed to support the +/// various YUV formats and different bit depths for RGB. But in the mean time: +/// here's a simple image class for use in VideoConverter, at least until we
+/// merge the image classes.
+
+struct ImgBuf : public boost::noncopyable
+{
+    typedef boost::uint32_t Type4CC;
+    typedef void (*FreeFunc)(void*);
+
+ ImgBuf(Type4CC t, boost::uint8_t* dataptr, size_t datasize, size_t w,
+           size_t h)
+    : type(t),
+      data(dataptr),
+      size(datasize),
+      width(w),
+      height(h),
+      dealloc(array_delete)
+    {}
+
+    ~ImgBuf()
+    {
+        dealloc(data);
+    }
+
+    static void array_delete(void* voidptr)
+    {
+        boost::uint8_t* ptr = static_cast<boost::uint8_t*>(voidptr);
+        delete [] ptr;
+    }
+
+    static void noop(void* /*voidptr*/)
+    {
+    }
+
+    Type4CC type;
+    boost::uint8_t* data;
+
+    size_t size; // in bytes
+    size_t width; // in pixels
+    size_t height; // in pixels
+
+    size_t stride[4];
+
+    FreeFunc dealloc;
+};
+
+
+/// Abstract base class for video image space conversion.
+
+class VideoConverter : public boost::noncopyable {
+
+public:
+ VideoConverter(ImgBuf::Type4CC srcFormat, ImgBuf::Type4CC dstFormat)
+     : _src_fmt(srcFormat),
+       _dst_fmt(dstFormat)
+    {
+    }
+
+    virtual ~VideoConverter()
+    {
+    }
+
+    /// Convert a (video) image from one colorspace to another.
+    //
+    /// @param src the image to convert
+ /// @return the converted image or a NULL auto_ptr if an error occurred.
+    virtual std::auto_ptr<ImgBuf> convert(const ImgBuf& src) = 0;
+
+protected:
+    ImgBuf::Type4CC  _src_fmt;
+    ImgBuf::Type4CC  _dst_fmt;
+};
+
+       
+} // gnash.media namespace
+} // gnash namespace
+
+#endif // __VIDEOCONVERTER_H__

=== modified file 'libmedia/ffmpeg/MediaHandlerFfmpeg.cpp'
--- a/libmedia/ffmpeg/MediaHandlerFfmpeg.cpp    2009-01-22 20:10:39 +0000
+++ b/libmedia/ffmpeg/MediaHandlerFfmpeg.cpp    2009-02-21 14:19:48 +0000
@@ -24,6 +24,7 @@
#include "AudioDecoderFfmpeg.h"
#include "GnashException.h"
#include "FLVParser.h"
+#include "VideoConverterFfmpeg.h"

#include "IOChannel.h" // for visibility of destructor
#include "MediaParser.h" // for visibility of destructor
@@ -64,6 +65,26 @@
        return ret;
}

+std::auto_ptr<VideoConverter>
+MediaHandlerFfmpeg::createVideoConverter(ImgBuf::Type4CC srcFormat,
+                                         ImgBuf::Type4CC dstFormat)
+{
+    std::auto_ptr<VideoConverter> converter;
+
+    try
+    {
+ converter.reset(new VideoConverterFfmpeg(srcFormat, dstFormat));
+    }
+    catch (GnashException& ex)
+    {
+ log_error("Could not create Ffmpeg based video converter parser for "
+                "input format: %s", ex.what());
+    }
+
+    return converter;
+}
+
+
std::auto_ptr<AudioDecoder>
MediaHandlerFfmpeg::createAudioDecoder(const AudioInfo& info)
{

=== modified file 'libmedia/ffmpeg/MediaHandlerFfmpeg.h'
--- a/libmedia/ffmpeg/MediaHandlerFfmpeg.h      2008-10-27 11:20:47 +0000
+++ b/libmedia/ffmpeg/MediaHandlerFfmpeg.h      2009-02-21 14:19:48 +0000
@@ -51,6 +51,9 @@
virtual std::auto_ptr<MediaParser> createMediaParser(std::auto_ptr<IOChannel> stream);

virtual std::auto_ptr<VideoDecoder> createVideoDecoder(const VideoInfo& info);
+       
+       virtual std::auto_ptr<VideoConverter>
+ createVideoConverter(ImgBuf::Type4CC srcFormat, ImgBuf::Type4CC dstFormat);

virtual std::auto_ptr<AudioDecoder> createAudioDecoder(const AudioInfo& info);


=== added file 'libmedia/ffmpeg/VideoConverterFfmpeg.cpp'
--- a/libmedia/ffmpeg/VideoConverterFfmpeg.cpp 1970-01-01 00:00:00 +0000 +++ b/libmedia/ffmpeg/VideoConverterFfmpeg.cpp 2009-02-21 14:19:48 +0000
@@ -0,0 +1,193 @@
+//
+//     Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+//     Copyright (C) 1999-2008 the VideoLAN team
+//
+// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "VideoConverterFfmpeg.h"
+#include "GnashException.h"
+
+namespace gnash {
+namespace media {
+namespace ffmpeg {
+
+#ifdef HAVE_SWSCALE_H
+/// A wrapper round an SwsContext that ensures it's
+/// freed on destruction.
+class SwsContextWrapper
+{
+public:
+
+    SwsContextWrapper(SwsContext* context)
+        :
+        _context(context)
+    {}
+
+    ~SwsContextWrapper()
+    {
+         sws_freeContext(_context);
+    }
+
+    SwsContext* getContext() const { return _context; }
+
+private:
+    SwsContext* _context;
+
+};
+#endif
+
+// The lookup table in this function is adapted from chroma.c from the VLC
+// codebase; its license permits distribution under GPLv3 and later.
+PixelFormat
+fourcc_to_ffmpeg(ImgBuf::Type4CC code)
+{
+
+#define GNASH_FOURCC( a, b, c, d ) \
+              ( ((uint32_t)a) | ( ((uint32_t)b) << 8 ) \
+              | ( ((uint32_t)c) << 16 ) | ( ((uint32_t)d) << 24 ) )
+
+    static const struct
+    {
+        ImgBuf::Type4CC  fourcc;
+        PixelFormat ffmpegcode;
+    } pixfmt_table[] =
+    {
+        // Planar YUV formats
+        {GNASH_FOURCC('I','4','4','4'), PIX_FMT_YUV444P},
+        {GNASH_FOURCC('J','4','4','4'), PIX_FMT_YUVJ444P},
+
+#if LIBAVUTIL_VERSION_INT >= ((49<<16)+(5<<8)+0)
+        {GNASH_FOURCC('I','4','4','0'), PIX_FMT_YUV440P},
+        {GNASH_FOURCC('J','4','4','0'), PIX_FMT_YUVJ440P},
+#endif
+
+        {GNASH_FOURCC('I','4','2','2'), PIX_FMT_YUV422P},
+        {GNASH_FOURCC('J','4','2','2'), PIX_FMT_YUVJ422P},
+
+        {GNASH_FOURCC('I','4','2','0'), PIX_FMT_YUV420P},
+        {GNASH_FOURCC('Y','V','1','2'), PIX_FMT_YUV420P},
+        {GNASH_FOURCC('I','Y','U','V'), PIX_FMT_YUV420P},
+        {GNASH_FOURCC('J','4','2','0'), PIX_FMT_YUVJ420P},
+        {GNASH_FOURCC('I','4','1','1'), PIX_FMT_YUV411P},
+        {GNASH_FOURCC('I','4','1','0'), PIX_FMT_YUV410P},
+        {GNASH_FOURCC('Y','V','U','9'), PIX_FMT_YUV410P},
+
+        {GNASH_FOURCC('N','V','1','2'), PIX_FMT_NV12},
+        {GNASH_FOURCC('N','V','2','1'), PIX_FMT_NV21},
+
+        {GNASH_FOURCC('Y','U','Y','2'), PIX_FMT_YUYV422},
+        {GNASH_FOURCC('Y','U','Y','V'), PIX_FMT_YUYV422},
+        {GNASH_FOURCC('U','Y','V','Y'), PIX_FMT_UYVY422},
+        {GNASH_FOURCC('Y','4','1','1'), PIX_FMT_UYYVYY411},
+
+        { 0, PIX_FMT_NONE}
+    };
+#undef GNASH_FOURCC
+
+    for (int i = 0; pixfmt_table[i].fourcc != 0; i++ ) {
+
+        if (pixfmt_table[i].fourcc == code) {
+            return pixfmt_table[i].ffmpegcode;
+        }
+    }
+
+    return PIX_FMT_NONE;
+}
+
+VideoConverterFfmpeg::VideoConverterFfmpeg(ImgBuf::Type4CC srcFormat, ImgBuf::Type4CC dstFormat)
+    : VideoConverter(srcFormat, dstFormat)
+{
+     if(fourcc_to_ffmpeg(_dst_fmt) == PIX_FMT_NONE) {
+ throw MediaException(_("VideoConverterFfmpeg cannot convert to the "
+                              "requested format"));
+     }
+}
+
+VideoConverterFfmpeg::~VideoConverterFfmpeg()
+{
+
+}
+
+
+std::auto_ptr<ImgBuf>
+VideoConverterFfmpeg::convert(const ImgBuf& src)
+{
+    std::auto_ptr<ImgBuf> ret;
+
+    const int width = src.width;
+    const int height = src.height;
+
+    PixelFormat dst_pixFmt = fourcc_to_ffmpeg(_dst_fmt);
+    assert(dst_pixFmt != PIX_FMT_NONE);
+    PixelFormat src_pixFmt = PIX_FMT_RGB24;
+
+#ifdef HAVE_SWSCALE_H
+
+    if (!_swsContext.get()) {
+
+ _swsContext.reset(new SwsContextWrapper(sws_getContext(width, height, + src_pixFmt, width, height, dst_pixFmt, SWS_BILINEAR, NULL, NULL,
+            NULL)));
+
+        if (!_swsContext->getContext()) {
+
+            // This means we will try to assign the
+            // context again next time.
+            _swsContext.reset();
+
+            return ret;
+        }
+    }
+#endif
+
+
+ AVPicture srcpicture = {{src.data, 0, 0, 0}, src.stride[0], 0, 0, 0};
+
+
+    int bufsize = avpicture_get_size(dst_pixFmt, width, height);
+    if (bufsize == -1) {
+        return ret;
+    }
+
+    boost::uint8_t* dstbuffer = new boost::uint8_t[bufsize];
+
+    AVPicture dstpicture;
+ avpicture_fill(&dstpicture, dstbuffer, dst_pixFmt, width, height);
+
+#ifndef HAVE_SWSCALE_H
+ img_convert(&dstpicture, dst_pixFmt, &srcpicture, src_pixFmt, width,
+                height);
+#else
+
+    int rv = sws_scale(_swsContext->getContext(), srcpicture.data,
+ srcpicture.linesize, 0, height, dstpicture.data,
+                       dstpicture.linesize);
+
+    if (rv == -1) {
+        return ret;
+    }
+#endif
+    ret.reset(new ImgBuf(_dst_fmt, dstbuffer, bufsize, src.width,
+                         src.height));
+ std::copy(dstpicture.linesize, dstpicture.linesize+4, ret- >stride);
+
+    return ret;
+}
+
+
+
+} // gnash.media.ffmpeg namespace
+} // gnash.media namespace
+} // gnash namespace

=== added file 'libmedia/ffmpeg/VideoConverterFfmpeg.h'
--- a/libmedia/ffmpeg/VideoConverterFfmpeg.h    1970-01-01 00:00:00 +0000
+++ b/libmedia/ffmpeg/VideoConverterFfmpeg.h    2009-02-21 14:19:48 +0000
@@ -0,0 +1,62 @@
+//
+//     Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+#ifndef GNASH_VIDEOCONVERTERFFMPEG_H
+#define GNASH_VIDEOCONVERTERFFMPEG_H
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include "ffmpegHeaders.h"
+#include "VideoConverter.h"
+
+#include "log.h"
+
+#if HAVE_SWSCALE_H
+#include <libswscale/swscale.h>
+#endif
+
+
+namespace gnash {
+namespace media {
+namespace ffmpeg {
+
+class SwsContextWrapper;
+
+class VideoConverterFfmpeg : public VideoConverter {
+
+public:
+ VideoConverterFfmpeg(ImgBuf::Type4CC srcFormat, ImgBuf::Type4CC dstFormat);
+
+    ~VideoConverterFfmpeg();
+
+    std::auto_ptr<ImgBuf> convert(const ImgBuf& src);
+
+private:
+
+#if HAVE_SWSCALE_H
+    std::auto_ptr<SwsContextWrapper> _swsContext;
+#endif
+};
+
+}
+}
+}
+
+#endif // GNASH_VIDEOCONVERTERFFMPEG_H

=== modified file 'libmedia/gst/MediaHandlerGst.cpp'
--- a/libmedia/gst/MediaHandlerGst.cpp  2009-01-22 20:10:39 +0000
+++ b/libmedia/gst/MediaHandlerGst.cpp  2009-02-21 14:19:48 +0000
@@ -22,6 +22,7 @@
#include "VideoDecoderGst.h"
#include "AudioDecoderGst.h"
#include "MediaParserGst.h"
+#include "VideoConverterGst.h"
#include "FLVParser.h"

#ifdef DECODING_SPEEX
@@ -132,6 +133,24 @@
        return ret;
}

+std::auto_ptr<VideoConverter>
+MediaHandlerGst::createVideoConverter(ImgBuf::Type4CC srcFormat, ImgBuf::Type4CC dstFormat)
+{
+    std::auto_ptr<VideoConverter> converter;
+
+    try
+    {
+        converter.reset(new VideoConverterGst(srcFormat, dstFormat));
+    }
+    catch (GnashException& ex)
+    {
+ log_error("Could not create Gstreamer based video converter parser for "
+                "input format: %s", ex.what());
+    }
+
+    return converter;
+}
+
} // gnash.media.gst namespace
} // gnash.media namespace
} // gnash namespace

=== modified file 'libmedia/gst/MediaHandlerGst.h'
--- a/libmedia/gst/MediaHandlerGst.h    2008-10-27 11:20:47 +0000
+++ b/libmedia/gst/MediaHandlerGst.h    2009-02-21 14:19:48 +0000
@@ -53,6 +53,9 @@
virtual std::auto_ptr<VideoDecoder> createVideoDecoder(const VideoInfo& info);

virtual std::auto_ptr<AudioDecoder> createAudioDecoder(const AudioInfo& info);
+       
+ virtual std::auto_ptr<VideoConverter> createVideoConverter(ImgBuf::Type4CC srcFormat, + ImgBuf::Type4CC dstFormat);
};



=== added file 'libmedia/gst/VideoConverterGst.cpp'
--- a/libmedia/gst/VideoConverterGst.cpp        1970-01-01 00:00:00 +0000
+++ b/libmedia/gst/VideoConverterGst.cpp        2009-02-21 14:19:48 +0000
@@ -0,0 +1,162 @@
+//   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "VideoConverterGst.h"
+#include "MediaParser.h"
+#include "log.h"
+#include <cassert>
+
+
+namespace gnash {
+namespace media {
+namespace gst {
+
+/// Base class for video image space conversion.
+
+VideoConverterGst::VideoConverterGst(ImgBuf::Type4CC srcFormat, ImgBuf::Type4CC dstFormat)
+    : VideoConverter(srcFormat, dstFormat)
+{
+    gst_init (NULL, NULL);
+
+ GstElementFactory* colorspacefactory = gst_element_factory_find ("ffmpegcolorspace");
+    if (!colorspacefactory) {
+ throw MediaException(_("VideoConverterGst: ffmpegcolorspace element missing"));
+    }
+
+    GstCaps* caps = gst_caps_new_simple("video/x-raw-yuv",
+ "format", GST_TYPE_FOURCC, _dst_fmt,
+                                        NULL);
+
+ // Verify that ffmpegcolorspace can actually convert to the requested fmt.
+    bool found = false;
+ for (const GList* walk = gst_element_factory_get_static_pad_templates (colorspacefactory);
+         walk; walk = walk->next) {
+ GstStaticPadTemplate* templ = (GstStaticPadTemplate*) walk- >data;
+
+        if (templ->direction != GST_PAD_SRC) {
+            continue;
+        }
+
+ GstCaps* template_caps = gst_static_caps_get (&templ- >static_caps); + GstCaps* intersect = gst_caps_intersect (caps, template_caps);
+        gst_caps_unref (template_caps);
+
+        found = !gst_caps_is_empty (intersect);
+        gst_caps_unref (intersect);
+
+        if (found) {
+            break;
+        }
+    }
+
+    gst_caps_unref(caps);
+    gst_object_unref(colorspacefactory);
+
+    if (!found) {
+ throw MediaException(_("VideoConverterGst: can't output requested format"));
+    }
+}
+
+bool
+VideoConverterGst::init(const ImgBuf& src)
+{
+    // FIXME: mask values are probably wrong.
+    GstCaps* srccaps = gst_caps_new_simple("video/x-raw-rgb",
+            "bpp", G_TYPE_INT, 24,
+            "depth", G_TYPE_INT, 24,
+            "width", G_TYPE_INT, src.width,
+            "height", G_TYPE_INT, src.height,
+            "red_mask", G_TYPE_INT, 16711680,
+            "green_mask", G_TYPE_INT, 65280,
+            "blue_mask", G_TYPE_INT, 255,
+            "endianness",G_TYPE_INT,  4321,
+            "framerate", GST_TYPE_FRACTION, 0, 1,
+            NULL);
+
+    GstCaps* sinkcaps = gst_caps_new_simple("video/x-raw-yuv",
+            "format", GST_TYPE_FOURCC, _dst_fmt,
+            "width", G_TYPE_INT, src.width,
+            "height", G_TYPE_INT, src.height,
+            "framerate", GST_TYPE_FRACTION, 0, 1,
+            NULL);
+
+    if (!sinkcaps || !srccaps) {
+        log_error(_("VideoConverterGst: internal error "
+                    "(caps creation failed)"));
+        return false;
+    }
+
+ bool rv = swfdec_gst_colorspace_init (&_decoder, srccaps, sinkcaps);
+    if (!rv) {
+        log_error(_("VideoConverterGst: initialisation failed."));
+        return false;
+    }
+
+    gst_caps_unref (srccaps);
+    gst_caps_unref (sinkcaps);
+
+    return true;
+}
+
+VideoConverterGst::~VideoConverterGst()
+{
+    swfdec_gst_decoder_push_eos(&_decoder);
+    swfdec_gst_decoder_finish(&_decoder);
+}
+
+std::auto_ptr<ImgBuf>
+VideoConverterGst::convert(const ImgBuf& src)
+{
+    std::auto_ptr<ImgBuf> ret;
+
+    if (!init(src)) {
+        return ret;
+    }
+
+    GstBuffer* buffer = gst_buffer_new();
+
+    GST_BUFFER_DATA(buffer) = const_cast<boost::uint8_t*>(src.data);
+    GST_BUFFER_SIZE(buffer) = src.size;
+    GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_READONLY);
+
+    bool success = swfdec_gst_decoder_push(&_decoder, buffer);
+    if (!success) {
+        log_error(_("VideoConverterGst: buffer push failed."));
+        return ret;
+    }
+
+    GstBuffer* retbuffer = swfdec_gst_decoder_pull (&_decoder);
+
+    if (!retbuffer) {
+        log_error(_("VideoConverterGst: buffer pull failed."));
+        return ret;
+    }
+
+    ret.reset(new ImgBuf(_dst_fmt, GST_BUFFER_DATA(retbuffer),
+ GST_BUFFER_SIZE(retbuffer), src.width, src.height));
+
+    GST_BUFFER_MALLOCDATA(retbuffer) = 0; // don't free
+    gst_buffer_unref(retbuffer);
+
+    ret->dealloc = g_free;
+
+    return ret;
+}
+
+} // gnash.media.gst namespace
+} // gnash.media namespace
+} // gnash namespace
+

=== added file 'libmedia/gst/VideoConverterGst.h'
--- a/libmedia/gst/VideoConverterGst.h  1970-01-01 00:00:00 +0000
+++ b/libmedia/gst/VideoConverterGst.h  2009-02-21 14:19:48 +0000
@@ -0,0 +1,53 @@
+//   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+#ifndef GNASH_VIDEOCONVERTERGST_H
+#define GNASH_VIDEOCONVERTERGST_H
+
+#include "VideoConverter.h"
+#include "swfdec_codec_gst.h"
+
+
+
+#include <gst/gst.h>
+
+namespace gnash {
+namespace media {
+namespace gst {
+
+/// Base class for video image space conversion.
+
+class VideoConverterGst : public VideoConverter {
+
+public:
+ VideoConverterGst(ImgBuf::Type4CC srcFormat, ImgBuf::Type4CC dstFormat);
+
+    ~VideoConverterGst();
+
+    std::auto_ptr<ImgBuf> convert(const ImgBuf& src);
+
+    bool init(const ImgBuf& src);
+
+private:
+    SwfdecGstDecoder _decoder;
+};
+
+} // gnash.media.gst namespace
+} // gnash.media namespace
+} // gnash namespace
+
+#endif // __VIDEOCONVERTERGST_H__

=== modified file 'libmedia/gst/swfdec_codec_gst.c'
--- a/libmedia/gst/swfdec_codec_gst.c   2008-10-05 00:08:38 +0000
+++ b/libmedia/gst/swfdec_codec_gst.c   2009-02-21 14:19:48 +0000
@@ -234,6 +234,37 @@
}

gboolean
+swfdec_gst_colorspace_init (SwfdecGstDecoder *dec, GstCaps *srccaps, GstCaps *sinkcaps)
+{
+  GstElement *converter;
+
+  dec->bin = gst_bin_new ("bin");
+
+  converter = gst_element_factory_make ("ffmpegcolorspace", NULL);
+  if (converter == NULL) {
+    SWFDEC_ERROR ("failed to create converter");
+    return FALSE;
+  }
+  gst_bin_add (GST_BIN (dec->bin), converter);
+  dec->src = swfdec_gst_connect_srcpad (converter, srccaps);
+  if (dec->src == NULL)
+    return FALSE;
+
+  dec->sink = swfdec_gst_connect_sinkpad (converter, sinkcaps);
+  if (dec->sink == NULL)
+    return FALSE;
+  gst_pad_set_chain_function (dec->sink, swfdec_gst_chain_func);
+  dec->queue = g_queue_new ();
+ g_object_set_data (G_OBJECT (dec->sink), "swfdec-queue", dec- >queue); + if (!gst_element_set_state (dec->bin, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS) {
+    SWFDEC_ERROR ("could not change element state");
+    return FALSE;
+  }
+  return TRUE;
+}
+
+
+gboolean
swfdec_gst_decoder_init (SwfdecGstDecoder *dec, GstCaps *srccaps, GstCaps *sinkcaps, ...)
{
  va_list args;

=== modified file 'libmedia/gst/swfdec_codec_gst.h'
--- a/libmedia/gst/swfdec_codec_gst.h   2008-10-05 00:08:38 +0000
+++ b/libmedia/gst/swfdec_codec_gst.h   2009-02-21 14:19:48 +0000
@@ -37,6 +37,11 @@
                                                 GstCaps *              srccaps,
                                                 GstCaps *              
sinkcaps,
                                                 ...) G_GNUC_NULL_TERMINATED;
+
+gboolean       swfdec_gst_colorspace_init      (SwfdecGstDecoder *     dec,
+                                                GstCaps *              srccaps,
+                                                GstCaps *              
sinkcaps);
+                                               
void            swfdec_gst_decoder_push_eos     (SwfdecGstDecoder *     dec);
GstBuffer *     swfdec_gst_decoder_pull         (SwfdecGstDecoder *     dec);
gboolean        swfdec_gst_decoder_push         (SwfdecGstDecoder *     dec,

_______________________________________________
Gnash-commit mailing list
address@hidden
http://lists.gnu.org/mailman/listinfo/gnash-commit

Attachment: PGP.sig
Description: This is a digitally signed message part


reply via email to

[Prev in Thread] Current Thread [Next in Thread]