1 #include "qtcamgstreamermessagelistener.h"
2 #include "qtcamgstreamermessagehandler.h"
6 #include "qtcamdevice_p.h"
8 class QtCamGStreamerMessageListenerPrivate {
10 QMultiMap<QString, QtCamGStreamerMessageHandler *> handlers;
11 QMultiMap<QString, QtCamGStreamerMessageHandler *> syncHandlers;
13 int handleMessage(GstMessage *message, QMultiMap<QString, QtCamGStreamerMessageHandler *>& map) {
14 const GstStructure *s = gst_message_get_structure(message);
19 QList<QtCamGStreamerMessageHandler *> list =
20 map.values(gst_structure_get_name(s));
22 foreach (QtCamGStreamerMessageHandler *handler, list) {
23 handler->handleMessage(message);
29 void handleMessage(GstMessage *message) {
31 switch (GST_MESSAGE_TYPE(message)) {
32 case GST_MESSAGE_ELEMENT:
33 handleMessage(message, handlers);
36 case GST_MESSAGE_ERROR: {
40 gst_message_parse_error(message, &err, &debug);
42 QMetaObject::invokeMethod(q_ptr, "error", Q_ARG(QString, err->message),
43 Q_ARG(int, err->code), Q_ARG(QString, debug));
45 qDebug() << "Error" << err->message << ":" << debug;
52 case GST_MESSAGE_WARNING: {
56 gst_message_parse_warning(message, &err, &debug);
58 qDebug() << "Warning" << err->message << ":" << debug;
65 case GST_MESSAGE_INFO: {
69 gst_message_parse_info(message, &err, &debug);
71 qDebug() << "Info" << err->message << ":" << debug;
78 case GST_MESSAGE_STATE_CHANGED: {
79 if (GST_ELEMENT(GST_MESSAGE_SRC(message)) != dev->cameraBin) {
83 GstState oldState, newState, pending;
84 gst_message_parse_state_changed(message, &oldState, &newState, &pending);
85 if (oldState == GST_STATE_PAUSED && newState == GST_STATE_PLAYING) {
86 QMetaObject::invokeMethod(q_ptr, "started");
88 else if (oldState == GST_STATE_PLAYING && newState == GST_STATE_PAUSED) {
89 QMetaObject::invokeMethod(q_ptr, "stopped");
100 bool handleSyncMessage(GstMessage *message) {
101 QMutexLocker locker(&syncMutex);
103 if (handleMessage(message, syncHandlers) != 0) {
110 void addHandler(QtCamGStreamerMessageHandler *handler,
111 QMultiMap<QString, QtCamGStreamerMessageHandler *>& map) {
112 if (!map.contains(handler->messageName(), handler)) {
113 map.insert(handler->messageName(), handler);
114 handler->setParent(q_ptr);
118 void removeHandler(QtCamGStreamerMessageHandler *handler,
119 QMultiMap<QString, QtCamGStreamerMessageHandler *>& map) {
120 map.remove(handler->messageName(), handler);
121 handler->setParent(0);
128 QtCamDevicePrivate *dev;
132 QtCamGStreamerMessageListener *q_ptr;
135 gboolean async_handler(GstBus *bus, GstMessage *message, gpointer data)
139 QtCamGStreamerMessageListenerPrivate *d_ptr =
140 static_cast<QtCamGStreamerMessageListenerPrivate *>(data);
142 d_ptr->handleMessage(message);
148 GstBusSyncReply sync_handler(GstBus *bus, GstMessage *message, gpointer data) {
151 QtCamGStreamerMessageListenerPrivate *d_ptr =
152 static_cast<QtCamGStreamerMessageListenerPrivate *>(data);
154 if (d_ptr->handleSyncMessage(message)) {
155 gst_message_unref(message);
162 QtCamGStreamerMessageListener::QtCamGStreamerMessageListener(GstBus *bus,
163 QtCamDevicePrivate *d,
165 QObject(parent), d_ptr(new QtCamGStreamerMessageListenerPrivate) {
171 d_ptr->watchId = gst_bus_add_watch(d_ptr->bus, async_handler, d_ptr);
173 gst_bus_set_sync_handler(d_ptr->bus, sync_handler, d_ptr);
176 QtCamGStreamerMessageListener::~QtCamGStreamerMessageListener() {
177 g_source_remove(d_ptr->watchId);
178 gst_bus_set_sync_handler(d_ptr->bus, NULL, NULL);
180 qDeleteAll(d_ptr->handlers);
182 d_ptr->syncMutex.lock();
183 qDeleteAll(d_ptr->syncHandlers);
184 d_ptr->syncMutex.unlock();
186 gst_object_unref(d_ptr->bus);
188 delete d_ptr; d_ptr = 0;
191 void QtCamGStreamerMessageListener::addHandler(QtCamGStreamerMessageHandler *handler) {
192 d_ptr->addHandler(handler, d_ptr->handlers);
195 void QtCamGStreamerMessageListener::removeHandler(QtCamGStreamerMessageHandler *handler) {
196 d_ptr->removeHandler(handler, d_ptr->handlers);
199 void QtCamGStreamerMessageListener::addSyncHandler(QtCamGStreamerMessageHandler *handler) {
200 QMutexLocker locker(&d_ptr->syncMutex);
202 d_ptr->addHandler(handler, d_ptr->syncHandlers);
205 void QtCamGStreamerMessageListener::removeSyncHandler(QtCamGStreamerMessageHandler *handler) {
206 QMutexLocker locker(&d_ptr->syncMutex);
208 d_ptr->removeHandler(handler, d_ptr->syncHandlers);
211 void QtCamGStreamerMessageListener::flushMessages() {
212 GstMessage *message = 0;
214 while ((message = gst_bus_pop(d_ptr->bus))) {
215 d_ptr->handleMessage(message);
216 gst_message_unref(message);