From a140ce217138b26ee89e6f576973e89f75f30302 Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Sun, 5 Feb 2012 15:57:22 +0200 Subject: [PATCH] Add support for VideoWidget::snapshot() Add support for the snapshot() method of VideoWidget when building with gst-plugins-base 0.10.31+. This requires Phonon 4.4+, but the support isn't made optional since we already require a newer Phonon to successfully build. --- gstreamer/CMakeLists.txt | 2 +- gstreamer/videowidget.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++ gstreamer/videowidget.h | 6 +++- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/gstreamer/CMakeLists.txt b/gstreamer/CMakeLists.txt index 79dbb89..6342f33 100644 --- a/gstreamer/CMakeLists.txt +++ b/gstreamer/CMakeLists.txt @@ -26,7 +26,7 @@ if (BUILD_PHONON_GSTREAMER) ${GLIB2_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR} ${X11_X11_INCLUDE_PATH}) - add_definitions(-DPHONON_BACKEND_VERSION_4_2) + add_definitions(-DPHONON_BACKEND_VERSION_4_4) # configure plugin api if(USE_INSTALL_PLUGIN) diff --git a/gstreamer/videowidget.cpp b/gstreamer/videowidget.cpp index 0d2a2ad..851902e 100644 --- a/gstreamer/videowidget.cpp +++ b/gstreamer/videowidget.cpp @@ -1,6 +1,7 @@ /* This file is part of the KDE project. Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + Copyright (C) 2012 Anssi Hannula 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 @@ -27,6 +28,7 @@ #include #include #include +#include #include #include "abstractrenderer.h" #include "backend.h" @@ -293,6 +295,62 @@ QRect VideoWidget::calculateDrawFrameRect() const return drawFrameRect; } +QImage VideoWidget::snapshot() const +{ + // for gst_video_convert_frame() +#if GST_CHECK_PLUGINS_BASE_VERSION(0,10,31) + GstElement *videosink = m_renderer->videoSink(); + GstBuffer *videobuffer = NULL; + + // in case we get called just after a flush (e.g. seeking), wait for the + // pipeline state change to complete first (with a timeout) so that + // last-buffer will be populated + gst_element_get_state(videosink, NULL, NULL, GST_SECOND); + + g_object_get(G_OBJECT(videosink), "last-buffer", &videobuffer, NULL); + + if (videobuffer) { + GstCaps *snapcaps = gst_caps_new_simple("video/x-raw-rgb", + "bpp", G_TYPE_INT, 24, + "depth", G_TYPE_INT, 24, + "endianness", G_TYPE_INT, G_BIG_ENDIAN, + "red_mask", G_TYPE_INT, 0xff0000, + "green_mask", G_TYPE_INT, 0x00ff00, + "blue_mask", G_TYPE_INT, 0x0000ff, + NULL); + + GstBuffer *snapbuffer = gst_video_convert_frame(videobuffer, snapcaps, GST_SECOND, NULL); + + gst_buffer_unref(videobuffer); + gst_caps_unref(snapcaps); + + if (snapbuffer) { + gint width, height; + gboolean ret; + GstStructure *s = gst_caps_get_structure(GST_BUFFER_CAPS(snapbuffer), 0); + + ret = gst_structure_get_int(s, "width", &width); + ret &= gst_structure_get_int(s, "height", &height); + + if (ret && width > 0 && height > 0) { + QImage snapimage(width, height, QImage::Format_RGB888); + + for (int i = 0; i < height; ++i) + memcpy(snapimage.scanLine(i), + GST_BUFFER_DATA(snapbuffer) + i * GST_ROUND_UP_4(width * 3), + width * 3); + + gst_buffer_unref(snapbuffer); + return snapimage; + } + + gst_buffer_unref(snapbuffer); + } + } +#endif // gst_video_convert_frame() + return QImage(); +} + void VideoWidget::setScaleMode(Phonon::VideoWidget::ScaleMode scaleMode) { m_scaleMode = scaleMode; diff --git a/gstreamer/videowidget.h b/gstreamer/videowidget.h index 9fe3b9d..b5967ad 100644 --- a/gstreamer/videowidget.h +++ b/gstreamer/videowidget.h @@ -1,6 +1,7 @@ /* This file is part of the KDE project. Copyright (C) 2 //Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).007 Nokia Corporation and/or its subsidiary(-ies). + Copyright (C) 2012 Anssi Hannula 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 @@ -35,10 +36,10 @@ namespace Gstreamer class AbstractRenderer; class Backend; -class VideoWidget : public QWidget, public Phonon::VideoWidgetInterface, public MediaNode +class VideoWidget : public QWidget, public Phonon::VideoWidgetInterface44, public MediaNode { Q_OBJECT - Q_INTERFACES(Phonon::VideoWidgetInterface Phonon::Gstreamer::MediaNode) + Q_INTERFACES(Phonon::VideoWidgetInterface44 Phonon::Gstreamer::MediaNode) public: VideoWidget(Backend *backend, QWidget *parent = 0); ~VideoWidget(); @@ -62,6 +63,7 @@ public: QSize sizeHint() const; QRect scaleToAspect(QRect srcRect, int w, int h) const; QRect calculateDrawFrameRect() const; + QImage snapshot() const; GstElement *videoElement() { -- 1.7.8.4