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 =
44 map.values(gst_structure_get_name(s));
46 foreach (QtCamGStreamerMessageHandler *handler, list) {
47 handler->handleMessage(message);
53 void handleMessage(GstMessage *message) {
55 switch (GST_MESSAGE_TYPE(message)) {
56 case GST_MESSAGE_ELEMENT:
57 handleMessage(message, handlers);
60 case GST_MESSAGE_ERROR: {
64 gst_message_parse_error(message, &err, &debug);
66 QMetaObject::invokeMethod(q_ptr, "error", Q_ARG(QString, err->message),
67 Q_ARG(int, err->code), Q_ARG(QString, debug));
69 qDebug() << "Error" << err->message << ":" << debug;
76 case GST_MESSAGE_WARNING: {
80 gst_message_parse_warning(message, &err, &debug);
82 qDebug() << "Warning" << err->message << ":" << debug;
89 case GST_MESSAGE_INFO: {
93 gst_message_parse_info(message, &err, &debug);
95 qDebug() << "Info" << err->message << ":" << debug;
102 case GST_MESSAGE_STATE_CHANGED: {
103 if (GST_ELEMENT(GST_MESSAGE_SRC(message)) != dev->cameraBin) {
107 GstState oldState, newState, pending;
108 gst_message_parse_state_changed(message, &oldState, &newState, &pending);
109 if (oldState == GST_STATE_PAUSED && newState == GST_STATE_PLAYING) {
110 QMetaObject::invokeMethod(q_ptr, "started");
112 else if (oldState == GST_STATE_PLAYING && newState == GST_STATE_PAUSED) {
113 QMetaObject::invokeMethod(q_ptr, "stopping");
115 else if (oldState == GST_STATE_READY && newState == GST_STATE_NULL) {
116 QMetaObject::invokeMethod(q_ptr, "stopped");
127 bool handleSyncMessage(GstMessage *message) {
128 QMutexLocker locker(&syncMutex);
130 if (handleMessage(message, syncHandlers) != 0) {
137 void addHandler(QtCamGStreamerMessageHandler *handler,
138 QMultiMap<QString, QtCamGStreamerMessageHandler *>& map) {
139 if (!map.contains(handler->messageName(), handler)) {
140 map.insert(handler->messageName(), handler);
141 handler->setParent(q_ptr);
145 void removeHandler(QtCamGStreamerMessageHandler *handler,
146 QMultiMap<QString, QtCamGStreamerMessageHandler *>& map) {
147 map.remove(handler->messageName(), handler);
148 handler->setParent(0);
155 QtCamDevicePrivate *dev;
159 QtCamGStreamerMessageListener *q_ptr;
162 gboolean async_handler(GstBus *bus, GstMessage *message, gpointer data)
166 QtCamGStreamerMessageListenerPrivate *d_ptr =
167 static_cast<QtCamGStreamerMessageListenerPrivate *>(data);
169 d_ptr->handleMessage(message);
175 GstBusSyncReply sync_handler(GstBus *bus, GstMessage *message, gpointer data) {
178 QtCamGStreamerMessageListenerPrivate *d_ptr =
179 static_cast<QtCamGStreamerMessageListenerPrivate *>(data);
181 if (d_ptr->handleSyncMessage(message)) {
182 gst_message_unref(message);
189 QtCamGStreamerMessageListener::QtCamGStreamerMessageListener(GstBus *bus,
190 QtCamDevicePrivate *d,
192 QObject(parent), d_ptr(new QtCamGStreamerMessageListenerPrivate) {
198 d_ptr->watchId = gst_bus_add_watch(d_ptr->bus, async_handler, d_ptr);
200 gst_bus_set_sync_handler(d_ptr->bus, sync_handler, d_ptr);
203 QtCamGStreamerMessageListener::~QtCamGStreamerMessageListener() {
204 g_source_remove(d_ptr->watchId);
205 gst_bus_set_sync_handler(d_ptr->bus, NULL, NULL);
207 qDeleteAll(d_ptr->handlers);
209 d_ptr->syncMutex.lock();
210 qDeleteAll(d_ptr->syncHandlers);
211 d_ptr->syncMutex.unlock();
213 gst_object_unref(d_ptr->bus);
215 delete d_ptr; d_ptr = 0;
218 void QtCamGStreamerMessageListener::addHandler(QtCamGStreamerMessageHandler *handler) {
219 d_ptr->addHandler(handler, d_ptr->handlers);
222 void QtCamGStreamerMessageListener::removeHandler(QtCamGStreamerMessageHandler *handler) {
223 d_ptr->removeHandler(handler, d_ptr->handlers);
226 void QtCamGStreamerMessageListener::addSyncHandler(QtCamGStreamerMessageHandler *handler) {
227 QMutexLocker locker(&d_ptr->syncMutex);
229 d_ptr->addHandler(handler, d_ptr->syncHandlers);
232 void QtCamGStreamerMessageListener::removeSyncHandler(QtCamGStreamerMessageHandler *handler) {
233 QMutexLocker locker(&d_ptr->syncMutex);
235 d_ptr->removeHandler(handler, d_ptr->syncHandlers);
238 void QtCamGStreamerMessageListener::flushMessages() {
239 GstMessage *message = 0;
241 while ((message = gst_bus_pop(d_ptr->bus))) {
242 d_ptr->handleMessage(message);
243 gst_message_unref(message);