2 * This file is part of QMAFW
4 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
7 * Contact: Visa Smolander <visa.smolander@nokia.com>
9 * This software, including documentation, is protected by copyright controlled
10 * by Nokia Corporation. All rights are reserved. Copying, including
11 * reproducing, storing, adapting or translating, any or all of this material
12 * requires the prior written consent of Nokia Corporation. This material also
13 * contains confidential information which may not be disclosed to others
14 * without the prior written consent of Nokia.
18 #include "MafwGstScreenshot.h"
21 MafwGstScreenshot::MafwGstScreenshot(QObject *parent) : QObject(parent)
23 qDebug() << __PRETTY_FUNCTION__;
37 MafwGstScreenshot::~MafwGstScreenshot()
39 qDebug() << __PRETTY_FUNCTION__;
42 gst_element_set_state(m_pipeline, GST_STATE_NULL);
43 gst_object_unref(m_pipeline);
47 static void copyBufferToSource(GstElement *src, GstBuffer *buffer, GstPad *pad,
54 GstBuffer *in_buf = GST_BUFFER(data);
56 memcpy(GST_BUFFER_DATA(buffer), GST_BUFFER_DATA(in_buf),
57 GST_BUFFER_SIZE(in_buf));
58 GST_BUFFER_SIZE(buffer) = GST_BUFFER_SIZE(in_buf);
61 static void freeSourceBuffer(gpointer data)
63 GstBuffer *in_buf = GST_BUFFER(data);
64 gst_buffer_unref(in_buf);
67 static gboolean asyncBusHandler(GstBus *bus, GstMessage *msg, gpointer data)
73 MafwGstScreenshot *self = static_cast<MafwGstScreenshot*>(data);
75 switch(GST_MESSAGE_TYPE(msg))
79 ret = self->reportBack(NULL);
82 case GST_MESSAGE_ERROR:
86 gst_message_parse_error(msg, &error, NULL);
88 ret = self->reportBack(error);
98 /********************************************************************
99 * MafwGstScreenshot::savePauseFrame
100 ********************************************************************/
101 bool MafwGstScreenshot::savePauseFrame(GstBuffer *buffer, const char *filename)
103 qDebug() << __PRETTY_FUNCTION__;
110 m_pipeline = gst_pipeline_new("screenshot-pipeline");
115 m_src = gst_element_factory_make("fakesrc", NULL);
116 m_sink = gst_element_factory_make("filesink", NULL);
117 m_filter = gst_element_factory_make("capsfilter", NULL);
118 m_csp = gst_element_factory_make("ffmpegcolorspace", NULL);
119 m_enc = gst_element_factory_make("pngenc", NULL);
121 if(!m_src || !m_sink || !m_filter || !m_csp || !m_enc)
126 gst_bin_add_many(GST_BIN(m_pipeline), m_src, m_filter, m_csp, m_enc, m_sink, NULL);
128 if(!gst_element_link_many(m_src, m_filter, m_csp, m_enc, m_sink, NULL))
133 m_bus = gst_pipeline_get_bus(GST_PIPELINE(m_pipeline));
134 gst_bus_add_watch(m_bus, asyncBusHandler, this);
135 gst_object_unref(m_bus);
137 g_object_set(m_sink, "preroll-queue-len", 1, NULL);
141 "signal-handoffs", TRUE,
143 g_object_set(m_enc, "compression-level", 1, NULL);
146 m_caps = gst_caps_copy(GST_BUFFER_CAPS(buffer));
151 m_structure = gst_caps_get_structure(m_caps, 0);
152 gst_structure_remove_field(m_structure, "pixel-aspect-ratio");
153 /* limit image size in case it exceeds the pre-determined size */
154 if(gst_structure_get_int(m_structure, "width", &width) &&
155 gst_structure_get_int(m_structure, "height", &height))
157 gst_caps_set_simple(m_caps,
158 "width", G_TYPE_INT, width,
159 "height", G_TYPE_INT, height,
162 g_object_set(m_filter, "caps", m_caps, NULL);
163 gst_caps_unref(m_caps);
165 g_object_set(m_sink, "location", filename, NULL);
166 g_object_set(m_src, "sizemax", GST_BUFFER_SIZE(buffer), NULL);
168 m_handler_id = g_signal_connect_data(m_src, "handoff", G_CALLBACK(copyBufferToSource), buffer, (GClosureNotify) freeSourceBuffer, G_CONNECT_AFTER);
170 gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
177 gst_object_unref(m_pipeline);
182 gst_buffer_unref(buffer);
188 /********************************************************************
189 * MafwGstScreenshot::cancelPauseFrame
190 ********************************************************************/
191 void MafwGstScreenshot::cancelPauseFrame()
193 qDebug() << __PRETTY_FUNCTION__;
195 gst_element_set_state(m_pipeline, GST_STATE_NULL);
196 g_signal_handler_disconnect(m_src, m_handler_id);
198 Q_EMIT screenshotCancelled();
201 /********************************************************************
202 * MafwGstScreenshot::reportBack
203 ********************************************************************/
204 bool MafwGstScreenshot::reportBack(GError *error)
206 qDebug() << __PRETTY_FUNCTION__;
210 g_object_get(m_sink, "location", &location, NULL);
211 Q_EMIT screenshotTaken(location, NULL);
216 Q_EMIT screenshotTaken(NULL, error);
219 gst_element_set_state(m_pipeline, GST_STATE_NULL);
220 g_signal_handler_disconnect(m_src, m_handler_id);