Added qmafw-gst-subtitles-renderer-0.0.55 for Meego Harmattan 1.2
[mafwsubrenderer] / qmafw-gst-subtitles-renderer / src / MafwGstScreenshot.cpp
diff --git a/qmafw-gst-subtitles-renderer/src/MafwGstScreenshot.cpp b/qmafw-gst-subtitles-renderer/src/MafwGstScreenshot.cpp
new file mode 100644 (file)
index 0000000..610ab1d
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * This file is part of QMAFW
+ *
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+ * reserved.
+ *
+ * Contact: Visa Smolander <visa.smolander@nokia.com>
+ *
+ * This software, including documentation, is protected by copyright controlled
+ * by Nokia Corporation. All rights are reserved. Copying, including
+ * reproducing, storing, adapting or translating, any or all of this material
+ * requires the prior written consent of Nokia Corporation. This material also
+ * contains confidential information which may not be disclosed to others
+ * without the prior written consent of Nokia.
+ *
+ */
+
+#include "MafwGstScreenshot.h"
+#include <QDebug>
+
+MafwGstScreenshot::MafwGstScreenshot(QObject *parent) : QObject(parent)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    m_src = NULL;
+    m_sink = NULL;
+    m_pipeline = NULL;
+    m_filter = NULL;
+    m_csp = NULL;
+    m_enc = NULL;
+    m_bus = NULL;
+    m_caps = NULL;
+    m_structure = NULL;
+    m_handler_id = 0;
+}
+
+MafwGstScreenshot::~MafwGstScreenshot()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    if(m_pipeline)
+    {
+        gst_element_set_state(m_pipeline, GST_STATE_NULL);
+        gst_object_unref(m_pipeline);
+    }
+}
+
+static void copyBufferToSource(GstElement *src, GstBuffer *buffer, GstPad *pad,
+                         gpointer data)
+{
+
+    Q_UNUSED(src);
+    Q_UNUSED(pad);
+
+    GstBuffer *in_buf = GST_BUFFER(data);
+
+    memcpy(GST_BUFFER_DATA(buffer), GST_BUFFER_DATA(in_buf),
+           GST_BUFFER_SIZE(in_buf));
+    GST_BUFFER_SIZE(buffer) = GST_BUFFER_SIZE(in_buf);
+}
+
+static void freeSourceBuffer(gpointer data)
+{
+    GstBuffer *in_buf = GST_BUFFER(data);
+    gst_buffer_unref(in_buf);
+}
+
+static gboolean asyncBusHandler(GstBus *bus, GstMessage *msg, gpointer data)
+{
+    Q_UNUSED(bus);
+
+    gboolean ret = TRUE;
+
+    MafwGstScreenshot *self = static_cast<MafwGstScreenshot*>(data);
+
+    switch(GST_MESSAGE_TYPE(msg))
+    {
+        case GST_MESSAGE_EOS:
+        {
+            ret = self->reportBack(NULL);
+            break;
+        }
+        case GST_MESSAGE_ERROR:
+        {
+            GError *error = NULL;
+
+            gst_message_parse_error(msg, &error, NULL);
+
+            ret = self->reportBack(error);
+            g_error_free(error);
+            break;
+        }
+        default:
+            break;
+    }
+    return ret;
+}
+
+/********************************************************************
+ * MafwGstScreenshot::savePauseFrame
+ ********************************************************************/
+bool MafwGstScreenshot::savePauseFrame(GstBuffer *buffer, const char *filename)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    gint width = 0;
+    gint height = 0;
+
+    if(!m_pipeline)
+    {
+        m_pipeline = gst_pipeline_new("screenshot-pipeline");
+        if(!m_pipeline)
+        {
+            goto err_out;
+        }
+        m_src = gst_element_factory_make("fakesrc", NULL);
+        m_sink = gst_element_factory_make("filesink", NULL);
+        m_filter = gst_element_factory_make("capsfilter", NULL);
+        m_csp = gst_element_factory_make("ffmpegcolorspace", NULL);
+        m_enc = gst_element_factory_make("pngenc", NULL);
+
+        if(!m_src || !m_sink || !m_filter || !m_csp || !m_enc)
+        {
+            goto err_out;
+        }
+
+        gst_bin_add_many(GST_BIN(m_pipeline), m_src, m_filter, m_csp, m_enc, m_sink, NULL);
+
+        if(!gst_element_link_many(m_src, m_filter, m_csp, m_enc, m_sink, NULL))
+        {
+            goto err_out;
+        }
+
+        m_bus = gst_pipeline_get_bus(GST_PIPELINE(m_pipeline));
+        gst_bus_add_watch(m_bus, asyncBusHandler, this);
+        gst_object_unref(m_bus);
+
+        g_object_set(m_sink, "preroll-queue-len", 1, NULL);
+        g_object_set(m_src,
+                "sizetype", 2,
+                "num-buffers", 1,
+                "signal-handoffs", TRUE,
+                NULL);
+        g_object_set(m_enc, "compression-level", 1, NULL);
+    }
+
+    m_caps = gst_caps_copy(GST_BUFFER_CAPS(buffer));
+    if(!m_caps)
+    {
+        goto err_out;
+    }
+    m_structure = gst_caps_get_structure(m_caps, 0);
+    gst_structure_remove_field(m_structure, "pixel-aspect-ratio");
+    /* limit image size in case it exceeds the pre-determined size */
+    if(gst_structure_get_int(m_structure, "width", &width) &&
+       gst_structure_get_int(m_structure, "height", &height))
+    {
+        gst_caps_set_simple(m_caps,
+                            "width", G_TYPE_INT, width,
+                            "height", G_TYPE_INT, height,
+                            NULL);
+    }
+    g_object_set(m_filter, "caps", m_caps, NULL);
+    gst_caps_unref(m_caps);
+
+    g_object_set(m_sink, "location", filename, NULL);
+    g_object_set(m_src, "sizemax", GST_BUFFER_SIZE(buffer), NULL);
+
+    m_handler_id = g_signal_connect_data(m_src, "handoff", G_CALLBACK(copyBufferToSource), buffer, (GClosureNotify) freeSourceBuffer, G_CONNECT_AFTER);
+
+    gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
+
+    return true;
+
+err_out:
+    if( m_pipeline )
+    {
+        gst_object_unref(m_pipeline);
+        m_pipeline = NULL;
+    }
+    if( buffer )
+    {
+        gst_buffer_unref(buffer);
+    }
+
+    return false;
+}
+
+/********************************************************************
+ * MafwGstScreenshot::cancelPauseFrame
+ ********************************************************************/
+void MafwGstScreenshot::cancelPauseFrame()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    gst_element_set_state(m_pipeline, GST_STATE_NULL);
+    g_signal_handler_disconnect(m_src, m_handler_id);
+
+    Q_EMIT screenshotCancelled();
+}
+
+/********************************************************************
+ * MafwGstScreenshot::reportBack
+ ********************************************************************/
+bool MafwGstScreenshot::reportBack(GError *error)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+    if(!error)
+    {
+        char *location;
+        g_object_get(m_sink, "location", &location, NULL);
+        Q_EMIT screenshotTaken(location, NULL);
+        g_free(location);
+    }
+    else
+    {
+        Q_EMIT screenshotTaken(NULL, error);
+    }
+
+    gst_element_set_state(m_pipeline, GST_STATE_NULL);
+    g_signal_handler_disconnect(m_src, m_handler_id);
+
+    return true;
+}