diff options
Diffstat (limited to 'src/3rdparty/phonon/gstreamer/qwidgetvideosink.cpp')
-rw-r--r-- | src/3rdparty/phonon/gstreamer/qwidgetvideosink.cpp | 221 |
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 |