2 * This file is part of CameraPlus.
4 * Copyright (C) 2012 Mohammed Sameer <msameer@foolab.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "qtcamgstreamermessagelistener.h"
22 #include "qtcamgstreamermessagehandler.h"
26 #include "qtcamdevice_p.h"
28 class QtCamGStreamerMessageListenerPrivate {
30 QMultiMap<QString, QtCamGStreamerMessageHandler *> handlers;
31 QMultiMap<QString, QtCamGStreamerMessageHandler *> syncHandlers;
33 int handleMessage(GstMessage *message, QMultiMap<QString, QtCamGStreamerMessageHandler *>& map) {
34 const GstStructure *s = gst_message_get_structure(message);
40 qDebug() << "Message" << gst_structure_get_name(s);
43 QList<QtCamGStreamerMessageHandler *> list = map.values(gst_structure_get_name(s));
45 foreach (QtCamGStreamerMessageHandler *handler, list) {
46 handler->handleMessage(message);
52 void handleMessage(GstMessage *message) {
54 switch (GST_MESSAGE_TYPE(message)) {
55 case GST_MESSAGE_ELEMENT:
56 handleMessage(message, handlers);
59 case GST_MESSAGE_ERROR: {
63 gst_message_parse_error(message, &err, &debug);
65 QMetaObject::invokeMethod(q_ptr, "error", Q_ARG(QString, err->message),
66 Q_ARG(int, err->code), Q_ARG(QString, debug));
68 qDebug() << "Error" << err->message << ":" << debug;
75 case GST_MESSAGE_WARNING: {
79 gst_message_parse_warning(message, &err, &debug);
81 qDebug() << "Warning" << err->message << ":" << debug;
88 case GST_MESSAGE_INFO: {
92 gst_message_parse_info(message, &err, &debug);
94 qDebug() << "Info" << err->message << ":" << debug;
101 case GST_MESSAGE_STATE_CHANGED: {
102 if (GST_ELEMENT(GST_MESSAGE_SRC(message)) != dev->cameraBin) {
106 GstState oldState, newState, pending;
107 gst_message_parse_state_changed(message, &oldState, &newState, &pending);
108 if (oldState == GST_STATE_PAUSED && newState == GST_STATE_PLAYING) {
109 QMetaObject::invokeMethod(q_ptr, "started");
111 else if (oldState == GST_STATE_PLAYING && newState == GST_STATE_PAUSED) {
112 QMetaObject::invokeMethod(q_ptr, "stopping");
114 else if (oldState == GST_STATE_READY && newState == GST_STATE_NULL) {
115 QMetaObject::invokeMethod(q_ptr, "stopped");
125 bool handleSyncMessage(GstMessage *message) {
126 QMutexLocker locker(&syncMutex);
128 if (handleMessage(message, syncHandlers) != 0) {
135 void addHandler(QtCamGStreamerMessageHandler *handler,
136 QMultiMap<QString, QtCamGStreamerMessageHandler *>& map) {
137 if (!map.contains(handler->messageName(), handler)) {
138 map.insert(handler->messageName(), handler);
139 handler->setParent(q_ptr);
143 void removeHandler(QtCamGStreamerMessageHandler *handler,
144 QMultiMap<QString, QtCamGStreamerMessageHandler *>& map) {
145 map.remove(handler->messageName(), handler);
146 handler->setParent(0);
153 QtCamDevicePrivate *dev;
157 QtCamGStreamerMessageListener *q_ptr;
160 gboolean async_handler(GstBus *bus, GstMessage *message, gpointer data)
164 QtCamGStreamerMessageListenerPrivate *d_ptr =
165 static_cast<QtCamGStreamerMessageListenerPrivate *>(data);
167 d_ptr->handleMessage(message);
173 GstBusSyncReply sync_handler(GstBus *bus, GstMessage *message, gpointer data) {
176 QtCamGStreamerMessageListenerPrivate *d_ptr =
177 static_cast<QtCamGStreamerMessageListenerPrivate *>(data);
179 if (d_ptr->handleSyncMessage(message)) {
180 gst_message_unref(message);
187 QtCamGStreamerMessageListener::QtCamGStreamerMessageListener(GstBus *bus,
188 QtCamDevicePrivate *d,
190 QObject(parent), d_ptr(new QtCamGStreamerMessageListenerPrivate) {
196 d_ptr->watchId = gst_bus_add_watch(d_ptr->bus, async_handler, d_ptr);
198 gst_bus_set_sync_handler(d_ptr->bus, sync_handler, d_ptr);
201 QtCamGStreamerMessageListener::~QtCamGStreamerMessageListener() {
202 g_source_remove(d_ptr->watchId);
203 gst_bus_set_sync_handler(d_ptr->bus, NULL, NULL);
205 qDeleteAll(d_ptr->handlers);
207 d_ptr->syncMutex.lock();
208 qDeleteAll(d_ptr->syncHandlers);
209 d_ptr->syncMutex.unlock();
211 gst_object_unref(d_ptr->bus);
213 delete d_ptr; d_ptr = 0;
216 void QtCamGStreamerMessageListener::addHandler(QtCamGStreamerMessageHandler *handler) {
217 d_ptr->addHandler(handler, d_ptr->handlers);
220 void QtCamGStreamerMessageListener::removeHandler(QtCamGStreamerMessageHandler *handler) {
221 d_ptr->removeHandler(handler, d_ptr->handlers);
224 void QtCamGStreamerMessageListener::addSyncHandler(QtCamGStreamerMessageHandler *handler) {
225 QMutexLocker locker(&d_ptr->syncMutex);
227 d_ptr->addHandler(handler, d_ptr->syncHandlers);
230 void QtCamGStreamerMessageListener::removeSyncHandler(QtCamGStreamerMessageHandler *handler) {
231 QMutexLocker locker(&d_ptr->syncMutex);
233 d_ptr->removeHandler(handler, d_ptr->syncHandlers);
236 void QtCamGStreamerMessageListener::flushMessages() {
237 GstMessage *message = 0;
239 while ((message = gst_bus_pop(d_ptr->bus))) {
240 d_ptr->handleMessage(message);
241 gst_message_unref(message);