summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/phonon/gstreamer/qwidgetvideosink.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/phonon/gstreamer/qwidgetvideosink.cpp')
-rw-r--r--src/3rdparty/phonon/gstreamer/qwidgetvideosink.cpp221
1 files changed, 221 insertions, 0 deletions
diff --git a/src/3rdparty/phonon/gstreamer/qwidgetvideosink.cpp b/src/3rdparty/phonon/gstreamer/qwidgetvideosink.cpp
new file mode 100644
index 0000000..89d5a9d
--- /dev/null
+++ b/src/3rdparty/phonon/gstreamer/qwidgetvideosink.cpp
@@ -0,0 +1,221 @@
+/* This file is part of the KDE project.
+
+ Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+ This library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 2.1 or 3 of the License.
+
+ 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <QApplication>
+#include "videowidget.h"
+#include "qwidgetvideosink.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace Gstreamer
+{
+
+static GstVideoSinkClass* parentClass;
+
+/*!
+ \class gstreamer::QWidgetVideoSink
+ \internal
+*/
+
+template <VideoFormat FMT>
+GstCaps* QWidgetVideoSink<FMT>::get_caps(GstBaseSink* sink)
+{
+ Q_UNUSED(sink);
+ return 0;
+}
+
+template <>
+const char* QWidgetVideoSinkClass<VideoFormat_YUV>::get_name()
+{
+ return "QWidgetVideoSinkYUV";
+}
+
+template <>
+const char* QWidgetVideoSinkClass<VideoFormat_RGB>::get_name()
+{
+ return "QWidgetVideoSinkRGB";
+}
+
+template <VideoFormat FMT>
+gboolean QWidgetVideoSink<FMT>::set_caps(GstBaseSink* sink, GstCaps* caps)
+{
+ GstStructure* data;
+ QWidgetVideoSink<FMT> *self = G_TYPE_CHECK_INSTANCE_CAST(sink, QWidgetVideoSinkClass<FMT>::get_type(), QWidgetVideoSink<FMT>);
+
+ data = gst_caps_get_structure(caps, 0);
+
+ gst_structure_get_int(data, "width", &self->width);
+ gst_structure_get_int(data, "height", &self->height);
+ gst_structure_get_int(data, "bpp", &self->bpp);
+ gst_structure_get_int(data, "depth", &self->depth);
+ return TRUE;
+}
+
+template <VideoFormat FMT>
+GstStateChangeReturn QWidgetVideoSink<FMT>::change_state(GstElement* element, GstStateChange transition)
+{
+ return GST_ELEMENT_CLASS(parentClass)->change_state(element, transition);
+}
+
+template <VideoFormat FMT>
+GstFlowReturn QWidgetVideoSink<FMT>::render(GstBaseSink* sink, GstBuffer* buf)
+{
+ GstFlowReturn rc = GST_FLOW_OK;
+
+ if (buf != 0)
+ {
+ QWidgetVideoSink<FMT> *self = G_TYPE_CHECK_INSTANCE_CAST(sink, QWidgetVideoSinkClass<FMT>::get_type(), QWidgetVideoSink<FMT>);
+ QByteArray frame;
+ frame.resize(buf->size);
+ memcpy(frame.data(), buf->data, buf->size);
+ NewFrameEvent *frameEvent = new NewFrameEvent(frame, self->width, self->height);
+ QApplication::postEvent(self->renderWidget, frameEvent);
+ }
+ else
+ rc = GST_FLOW_ERROR;
+ return rc;
+}
+
+static GstStaticPadTemplate template_factory_yuv =
+ GST_STATIC_PAD_TEMPLATE("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS("video/x-raw-yuv, "
+ "framerate = (fraction) [ 0, MAX ], "
+ "width = (int) [ 1, MAX ], "
+ "height = (int) [ 1, MAX ],"
+ "bpp = (int) 32"));
+
+static GstStaticPadTemplate template_factory_rgb =
+ GST_STATIC_PAD_TEMPLATE("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS("video/x-raw-rgb, "
+ "framerate = (fraction) [ 0, MAX ], "
+ "width = (int) [ 1, MAX ], "
+ "height = (int) [ 1, MAX ],"
+ "bpp = (int) 32"));
+
+template <VideoFormat FMT>
+struct template_factory;
+
+
+template <>
+struct template_factory<VideoFormat_YUV>
+{
+ static GstStaticPadTemplate *getFactory()
+ {
+ return &template_factory_yuv;
+ }
+};
+
+template <>
+struct template_factory<VideoFormat_RGB>
+{
+ static GstStaticPadTemplate *getFactory()
+ {
+ return &template_factory_rgb;
+ }
+};
+
+template <VideoFormat FMT>
+void QWidgetVideoSink<FMT>::base_init(gpointer g_class)
+{
+ gst_element_class_add_pad_template(GST_ELEMENT_CLASS(g_class),
+ gst_static_pad_template_get(template_factory<FMT>::getFactory()));
+}
+
+template <VideoFormat FMT>
+void QWidgetVideoSink<FMT>::instance_init(GTypeInstance *instance, gpointer g_class)
+{
+ Q_UNUSED(g_class);
+
+ QWidgetVideoSink<FMT>* self = reinterpret_cast<QWidgetVideoSink<FMT>*>(instance);
+
+ self->renderWidget = 0;
+ self->width = 0;
+ self->height = 0;
+ self->bpp = 0;
+ self->depth = 0;
+}
+
+// QWidgetVideoSinkClass
+template <VideoFormat FMT>
+void QWidgetVideoSinkClass<FMT>::class_init(gpointer g_class, gpointer class_data)
+{
+ Q_UNUSED(class_data);
+ GstBaseSinkClass* gstBaseSinkClass = (GstBaseSinkClass*)g_class;
+ GstElementClass* gstElementClass = (GstElementClass*)g_class;
+
+ parentClass = reinterpret_cast<GstVideoSinkClass*>(g_type_class_peek_parent(g_class));
+
+ // base
+ gstBaseSinkClass->set_caps = QWidgetVideoSink<FMT>::set_caps;
+ gstBaseSinkClass->preroll = QWidgetVideoSink<FMT>::render;
+ gstBaseSinkClass->render = QWidgetVideoSink<FMT>::render;
+
+ // element
+ gstElementClass->change_state = QWidgetVideoSink<FMT>::change_state;
+}
+
+template <VideoFormat FMT>
+GType QWidgetVideoSinkClass<FMT>::get_type()
+{
+ static GType type = 0;
+
+ if (type == 0)
+ {
+ static const GTypeInfo info =
+ {
+ sizeof(QWidgetVideoSinkClass<FMT>), // class_size
+ QWidgetVideoSink<FMT>::base_init, // base init
+ NULL, // base_finalize
+
+ QWidgetVideoSinkClass<FMT>::class_init, // class_init
+ NULL, // class_finalize
+ NULL, // class_data
+
+ sizeof(QWidgetVideoSink<FMT>), // instance_size
+ 0, // n_preallocs
+ QWidgetVideoSink<FMT>::instance_init, // instance_init
+ 0 // value_table
+ };
+
+ type = g_type_register_static(GST_TYPE_VIDEO_SINK,
+ QWidgetVideoSinkClass<FMT>::get_name(),
+ &info,
+ GTypeFlags(0));
+ }
+ return type;
+}
+
+GType get_type_YUV()
+{
+ return QWidgetVideoSinkClass<VideoFormat_YUV>::get_type();
+}
+
+GType get_type_RGB()
+{
+ return QWidgetVideoSinkClass<VideoFormat_RGB>::get_type();
+}
+
+}
+} //namespace Phonon::Gstreamer
+
+QT_END_NAMESPACE