QtGStreamer 0.10.1
|
00001 /* 00002 Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com> 00003 00004 This library is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as published 00006 by the Free Software Foundation; either version 2.1 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public License 00015 along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 #include "bus.h" 00018 #include "message.h" 00019 #include "../QGlib/signal.h" 00020 #include <gst/gst.h> 00021 #include <QtCore/QObject> 00022 #include <QtCore/QTimerEvent> 00023 #include <QtCore/QHash> 00024 #include <QtCore/QBasicTimer> 00025 00026 namespace QGst { 00027 namespace Private { 00028 00029 class BusWatch : public QObject 00030 { 00031 public: 00032 BusWatch(GstBus *bus) 00033 : QObject(), m_bus(bus) 00034 { 00035 m_timer.start(50, this); 00036 } 00037 00038 void stop() 00039 { 00040 m_timer.stop(); 00041 } 00042 00043 private: 00044 virtual void timerEvent(QTimerEvent *event) 00045 { 00046 if (event->timerId() == m_timer.timerId()) { 00047 dispatch(); 00048 } else { 00049 QObject::timerEvent(event); 00050 } 00051 } 00052 00053 void dispatch() 00054 { 00055 GstMessage *message; 00056 gst_object_ref(m_bus); 00057 while((message = gst_bus_pop(m_bus)) != NULL) { 00058 MessagePtr msg = MessagePtr::wrap(message, false); 00059 QGlib::Quark detail = gst_message_type_to_quark(static_cast<GstMessageType>(msg->type())); 00060 QGlib::emitWithDetail<void>(m_bus, "message", detail, msg); 00061 } 00062 gst_object_unref(m_bus); 00063 } 00064 00065 GstBus *m_bus; 00066 QBasicTimer m_timer; 00067 }; 00068 00069 class BusWatchManager 00070 { 00071 public: 00072 void addWatch(GstBus *bus) 00073 { 00074 if (m_watches.contains(bus)) { 00075 m_watches[bus].second++; //reference count 00076 } else { 00077 m_watches.insert(bus, qMakePair(new BusWatch(bus), uint(1))); 00078 g_object_weak_ref(G_OBJECT(bus), &BusWatchManager::onBusDestroyed, this); 00079 } 00080 } 00081 00082 void removeWatch(GstBus *bus) 00083 { 00084 if (m_watches.contains(bus) && --m_watches[bus].second == 0) { 00085 m_watches[bus].first->stop(); 00086 m_watches[bus].first->deleteLater(); 00087 m_watches.remove(bus); 00088 g_object_weak_unref(G_OBJECT(bus), &BusWatchManager::onBusDestroyed, this); 00089 } 00090 } 00091 00092 private: 00093 static void onBusDestroyed(gpointer selfPtr, GObject *busPtr) 00094 { 00095 BusWatchManager *self = static_cast<BusWatchManager*>(selfPtr); 00096 GstBus *bus = reinterpret_cast<GstBus*>(busPtr); 00097 00098 //we cannot call removeWatch() here because g_object_weak_unref will complain 00099 self->m_watches[bus].first->stop(); 00100 self->m_watches[bus].first->deleteLater(); 00101 self->m_watches.remove(bus); 00102 } 00103 00104 QHash< GstBus*, QPair<BusWatch*, uint> > m_watches; 00105 }; 00106 00107 Q_GLOBAL_STATIC(Private::BusWatchManager, s_watchManager) 00108 00109 } //namespace Private 00110 00111 00112 //static 00113 BusPtr Bus::create() 00114 { 00115 GstBus *bus = gst_bus_new(); 00116 if (bus) { 00117 gst_object_ref_sink(bus); 00118 } 00119 return BusPtr::wrap(bus, false); 00120 } 00121 00122 bool Bus::hasPendingMessages() const 00123 { 00124 return gst_bus_have_pending(object<GstBus>()); 00125 } 00126 00127 MessagePtr Bus::peek() const 00128 { 00129 return MessagePtr::wrap(gst_bus_peek(object<GstBus>()), false); 00130 } 00131 00132 MessagePtr Bus::pop(ClockTime timeout) 00133 { 00134 return MessagePtr::wrap(gst_bus_timed_pop(object<GstBus>(), timeout), false); 00135 } 00136 00137 MessagePtr Bus::pop(MessageType type, ClockTime timeout) 00138 { 00139 return MessagePtr::wrap(gst_bus_timed_pop_filtered(object<GstBus>(), timeout, 00140 static_cast<GstMessageType>(type)), false); 00141 } 00142 00143 bool Bus::post(const MessagePtr & message) 00144 { 00145 return gst_bus_post(object<GstBus>(), gst_message_copy(message)); 00146 } 00147 00148 void Bus::setFlushing(bool flush) 00149 { 00150 gst_bus_set_flushing(object<GstBus>(), flush); 00151 } 00152 00153 void Bus::addSignalWatch() 00154 { 00155 Private::s_watchManager()->addWatch(object<GstBus>()); 00156 } 00157 00158 void Bus::removeSignalWatch() 00159 { 00160 Private::s_watchManager()->removeWatch(object<GstBus>()); 00161 } 00162 00163 void Bus::enableSyncMessageEmission() 00164 { 00165 gst_bus_enable_sync_message_emission(object<GstBus>()); 00166 } 00167 00168 void Bus::disableSyncMessageEmission() 00169 { 00170 gst_bus_disable_sync_message_emission(object<GstBus>()); 00171 } 00172 00173 } //namespace QGst