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, "stopping");
91 else if (oldState == GST_STATE_READY && newState == GST_STATE_NULL) {
92 QMetaObject::invokeMethod(q_ptr, "stopped");
103 bool handleSyncMessage(GstMessage *message) {
104 QMutexLocker locker(&syncMutex);
106 if (handleMessage(message, syncHandlers) != 0) {
113 void addHandler(QtCamGStreamerMessageHandler *handler,
114 QMultiMap<QString, QtCamGStreamerMessageHandler *>& map) {
115 if (!map.contains(handler->messageName(), handler)) {
116 map.insert(handler->messageName(), handler);
117 handler->setParent(q_ptr);
121 void removeHandler(QtCamGStreamerMessageHandler *handler,
122 QMultiMap<QString, QtCamGStreamerMessageHandler *>& map) {
123 map.remove(handler->messageName(), handler);
124 handler->setParent(0);
131 QtCamDevicePrivate *dev;
135 QtCamGStreamerMessageListener *q_ptr;
138 gboolean async_handler(GstBus *bus, GstMessage *message, gpointer data)
142 QtCamGStreamerMessageListenerPrivate *d_ptr =
143 static_cast<QtCamGStreamerMessageListenerPrivate *>(data);
145 d_ptr->handleMessage(message);
151 GstBusSyncReply sync_handler(GstBus *bus, GstMessage *message, gpointer data) {
154 QtCamGStreamerMessageListenerPrivate *d_ptr =
155 static_cast<QtCamGStreamerMessageListenerPrivate *>(data);
157 if (d_ptr->handleSyncMessage(message)) {
158 gst_message_unref(message);
165 QtCamGStreamerMessageListener::QtCamGStreamerMessageListener(GstBus *bus,
166 QtCamDevicePrivate *d,
168 QObject(parent), d_ptr(new QtCamGStreamerMessageListenerPrivate) {
174 d_ptr->watchId = gst_bus_add_watch(d_ptr->bus, async_handler, d_ptr);
176 gst_bus_set_sync_handler(d_ptr->bus, sync_handler, d_ptr);
179 QtCamGStreamerMessageListener::~QtCamGStreamerMessageListener() {
180 g_source_remove(d_ptr->watchId);
181 gst_bus_set_sync_handler(d_ptr->bus, NULL, NULL);
183 qDeleteAll(d_ptr->handlers);
185 d_ptr->syncMutex.lock();
186 qDeleteAll(d_ptr->syncHandlers);
187 d_ptr->syncMutex.unlock();
189 gst_object_unref(d_ptr->bus);
191 delete d_ptr; d_ptr = 0;
194 void QtCamGStreamerMessageListener::addHandler(QtCamGStreamerMessageHandler *handler) {
195 d_ptr->addHandler(handler, d_ptr->handlers);
198 void QtCamGStreamerMessageListener::removeHandler(QtCamGStreamerMessageHandler *handler) {
199 d_ptr->removeHandler(handler, d_ptr->handlers);
202 void QtCamGStreamerMessageListener::addSyncHandler(QtCamGStreamerMessageHandler *handler) {
203 QMutexLocker locker(&d_ptr->syncMutex);
205 d_ptr->addHandler(handler, d_ptr->syncHandlers);
208 void QtCamGStreamerMessageListener::removeSyncHandler(QtCamGStreamerMessageHandler *handler) {
209 QMutexLocker locker(&d_ptr->syncMutex);
211 d_ptr->removeHandler(handler, d_ptr->syncHandlers);
214 void QtCamGStreamerMessageListener::flushMessages() {
215 GstMessage *message = 0;
217 while ((message = gst_bus_pop(d_ptr->bus))) {
218 d_ptr->handleMessage(message);
219 gst_message_unref(message);