[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: playground/network/kcall
From: George Kiagiadakis <gkiagiad () csd ! uoc ! gr>
Date: 2009-07-09 19:05:09
Message-ID: 1247166309.293842.6373.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 993939 by gkiagia:
Cleanup the MediaHandler api and implementation.
- Allocate resources on request and not at construction time.
- Use signals to inform the GUI about changes.
- Remove the useless AbstractMediaHandler::State.
M +1 -14 kcall_handler/abstractmediahandler.cpp
M +5 -31 kcall_handler/abstractmediahandler.h
M +32 -7 kcall_handler/callwindow.cpp
M +5 -0 kcall_handler/callwindow.h
M +82 -104 kcall_handler/farsight/mediahandler.cpp
M +3 -4 kcall_handler/farsight/mediahandler.h
M +2 -0 libkgstdevices/devicefactory.cpp
--- trunk/playground/network/kcall/kcall_handler/abstractmediahandler.cpp #993938:993939
@@ -18,7 +18,7 @@
#include "farsight/mediahandler.h"
AbstractMediaHandler::AbstractMediaHandler(QObject *parent)
- : QObject(parent), m_status(Disconnected)
+ : QObject(parent)
{
}
@@ -29,17 +29,4 @@
return new Farsight::MediaHandler(channel, parent);
}
-AbstractMediaHandler::Status AbstractMediaHandler::status() const
-{
- return m_status;
-}
-
-void AbstractMediaHandler::setStatus(AbstractMediaHandler::Status s)
-{
- if ( s != m_status ) {
- m_status = s;
- emit statusChanged(s);
- }
-}
-
#include "abstractmediahandler.moc"
--- trunk/playground/network/kcall/kcall_handler/abstractmediahandler.h #993938:993939
@@ -24,45 +24,19 @@
class AbstractMediaHandler : public QObject
{
Q_OBJECT
- Q_ENUMS(Capability)
- Q_FLAGS(Capabilities)
public:
- enum Capability {
- None = 0x0,
- SendAudio = 0x1,
- ReceiveAudio = 0x2,
- SendVideo = 0x4,
- ReceiveVideo = 0x8
- };
- Q_DECLARE_FLAGS(Capabilities, Capability);
-
- enum Status {
- Disconnected,
- Connecting,
- Connected
- };
-
static AbstractMediaHandler *create(const Tp::StreamedMediaChannelPtr & channel,
QObject *parent = 0);
- Status status() const;
- virtual Capabilities capabilities() const = 0;
- virtual VolumeControlInterface *inputVolumeControl() const = 0;
- virtual VolumeControlInterface *outputVolumeControl() const = 0;
-
Q_SIGNALS:
- void statusChanged(AbstractMediaHandler::Status newStatus);
+ void audioInputDeviceCreated(VolumeControlInterface *inputVolumeControl);
+ void audioInputDeviceDestroyed();
+ void audioOutputDeviceCreated(VolumeControlInterface *outputVolumeControl);
+ void audioOutputDeviceDestroyed();
+
protected:
AbstractMediaHandler(QObject *parent = 0);
-
-protected Q_SLOTS:
- void setStatus(AbstractMediaHandler::Status s);
-
-private:
- Status m_status;
};
-Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMediaHandler::Capabilities)
-
#endif
--- trunk/playground/network/kcall/kcall_handler/callwindow.cpp #993938:993939
@@ -108,8 +108,9 @@
{
d->hangupAction->setEnabled(false);
d->ui.participantsDock->setEnabled(false);
- d->ui.tabWidget->setTabEnabled(VolumeTabIndex, false);
- d->ui.volumeTab->setEnabled(false);
+ //d->ui.tabWidget->setTabEnabled(VolumeTabIndex, false);
+ d->ui.microphoneGroupBox->setEnabled(false);
+ d->ui.speakersGroupBox->setEnabled(false);
d->ui.tabWidget->setTabEnabled(VideoControlsTabIndex, false);
d->ui.videoControlsTab->setEnabled(false);
d->ui.tabWidget->setTabEnabled(DialpadTabIndex, false);
@@ -162,13 +163,37 @@
void CallWindow::onMediaHandlerCreated(AbstractMediaHandler *handler)
{
- //FIXME this signal doesn't imply that we have an audio stream
- d->ui.tabWidget->setTabEnabled(VolumeTabIndex, true);
- d->ui.volumeTab->setEnabled(true);
- d->ui.inputVolumeWidget->setVolumeControl(handler->inputVolumeControl());
- d->ui.outputVolumeWidget->setVolumeControl(handler->outputVolumeControl());
+ connect(handler, SIGNAL(audioInputDeviceCreated(VolumeControlInterface*)),
+ SLOT(onAudioInputDeviceCreated(VolumeControlInterface*)));
+ connect(handler, SIGNAL(audioInputDeviceDestroyed()), SLOT(onAudioInputDeviceDestroyed()));
+
+ connect(handler, SIGNAL(audioOutputDeviceCreated(VolumeControlInterface*)),
+ SLOT(onAudioOutputDeviceCreated(VolumeControlInterface*)));
+ connect(handler, SIGNAL(audioOutputDeviceDestroyed()), SLOT(onAudioOutputDeviceDestroyed()));
}
+void CallWindow::onAudioInputDeviceCreated(VolumeControlInterface *control)
+{
+ d->ui.microphoneGroupBox->setEnabled(true);
+ d->ui.inputVolumeWidget->setVolumeControl(control);
+}
+
+void CallWindow::onAudioInputDeviceDestroyed()
+{
+ d->ui.microphoneGroupBox->setEnabled(false);
+}
+
+void CallWindow::onAudioOutputDeviceCreated(VolumeControlInterface *control)
+{
+ d->ui.speakersGroupBox->setEnabled(true);
+ d->ui.outputVolumeWidget->setVolumeControl(control);
+}
+
+void CallWindow::onAudioOutputDeviceDestroyed()
+{
+ d->ui.speakersGroupBox->setEnabled(false);
+}
+
void CallWindow::onGroupMembersModelCreated(GroupMembersModel *model)
{
d->ui.participantsDock->setEnabled(true);
--- trunk/playground/network/kcall/kcall_handler/callwindow.h #993938:993939
@@ -19,6 +19,7 @@
#include "channelhandler.h"
#include <KXmlGuiWindow>
+class VolumeControlInterface;
class CallWindow : public KXmlGuiWindow
{
@@ -36,6 +37,10 @@
void setState(ChannelHandler::State state);
void setStatus(const QString & msg);
void onMediaHandlerCreated(AbstractMediaHandler *handler);
+ void onAudioInputDeviceCreated(VolumeControlInterface *control);
+ void onAudioInputDeviceDestroyed();
+ void onAudioOutputDeviceCreated(VolumeControlInterface *control);
+ void onAudioOutputDeviceDestroyed();
void onGroupMembersModelCreated(GroupMembersModel *model);
void onDtmfHandlerCreated(DtmfHandler *handler);
void onCallDurationTimerTimeout();
--- trunk/playground/network/kcall/kcall_handler/farsight/mediahandler.cpp #993938:993939
@@ -40,9 +40,8 @@
static void onSrcPadAdded(TfStream *stream, GstPad *src, FsCodec *codec, MediaHandler *self);
static gboolean onRequestResource(TfStream *stream, guint direction, MediaHandler *self);
- GstPad *audioSinkPad();
+ GstPad *newAudioSinkPad();
- AbstractMediaHandler::Capabilities caps;
Tp::StreamedMediaChannelPtr channel;
TfChannel *tfChannel;
GstElement *pipeline;
@@ -52,31 +51,9 @@
guint busWatchSrc;
};
-GstPad *MediaHandler::Private::audioSinkPad()
-{
- if ( !liveadder ) {
- if ( !(liveadder = gst_element_factory_make("liveadder", NULL)) ) {
- kDebug() << "liveadder not available. Attempting to use plain adder";
- if ( !(liveadder = gst_element_factory_make("adder", NULL)) ) {
- kFatal() << "Failed to create an adder gstreamer element. Please install "
- "either the \"adder\" or the \"liveadder\" gstreamer plugin.";
- }
- }
-
- gst_bin_add(GST_BIN(pipeline), liveadder);
- gst_bin_add(GST_BIN(pipeline), deviceFactory->audioOutputDevice()->bin());
- gst_element_link(liveadder, deviceFactory->audioOutputDevice()->bin());
-
- gst_element_set_state(liveadder, GST_STATE_PLAYING);
- gst_element_set_state(deviceFactory->audioOutputDevice()->bin(), GST_STATE_PLAYING);
- }
- return gst_element_get_request_pad(liveadder, "sink%d");
-}
-
MediaHandler::MediaHandler(const Tp::StreamedMediaChannelPtr & channel, QObject *parent)
: AbstractMediaHandler(parent), d(new Private)
{
- d->caps = None;
d->channel = channel;
d->tfChannel = NULL;
d->pipeline = NULL;
@@ -85,6 +62,7 @@
d->bus = NULL;
d->busWatchSrc = 0;
+ qRegisterMetaType<VolumeControlInterface*>("VolumeControlInterface*");
initialize();
}
@@ -113,21 +91,6 @@
delete d;
}
-AbstractMediaHandler::Capabilities MediaHandler::capabilities() const
-{
- return d->caps;
-}
-
-VolumeControlInterface *MediaHandler::inputVolumeControl() const
-{
- return d->deviceFactory->audioInputDevice();
-}
-
-VolumeControlInterface *MediaHandler::outputVolumeControl() const
-{
- return d->deviceFactory->audioOutputDevice();
-}
-
void MediaHandler::initialize()
{
static bool gInitDone = false;
@@ -161,49 +124,61 @@
const KConfigGroup deviceSettings = KGlobal::config()->group("Gstreamer Devices");
d->deviceFactory = new KGstDevices::DeviceFactory(deviceSettings);
-
- if ( d->deviceFactory->createAudioInputDevice() ) {
- d->caps |= SendAudio;
- }
-
- if ( d->deviceFactory->createAudioOutputDevice() ) {
- gst_element_link(d->liveadder, d->deviceFactory->audioOutputDevice()->bin());
- d->caps |= ReceiveAudio;
- }
-
- setStatus(Connecting);
}
void MediaHandler::stop()
{
- if (status() == Disconnected) {
- return;
- }
-
if (d->bus) {
if (d->busWatchSrc != 0) {
g_source_remove(d->busWatchSrc);
}
}
- if ( d->liveadder ) {
- gst_element_set_state(d->liveadder, GST_STATE_NULL);
+ if (d->pipeline) {
+ gst_element_set_state(d->pipeline, GST_STATE_NULL);
}
- if ( d->deviceFactory->audioInputDevice() ) {
- gst_element_set_state(d->deviceFactory->audioInputDevice()->bin(), GST_STATE_NULL);
- }
+ QMetaObject::invokeMethod(this, "audioInputDeviceDestroyed", Qt::QueuedConnection);
+ QMetaObject::invokeMethod(this, "audioOutputDeviceDestroyed", Qt::QueuedConnection);
+}
- if ( d->deviceFactory->audioOutputDevice() ) {
- gst_element_set_state(d->deviceFactory->audioOutputDevice()->bin(), GST_STATE_NULL);
+void MediaHandler::onAudioSrcPadAdded(GstPad *srcPad)
+{
+ if ( !d->deviceFactory->audioOutputDevice() ) {
+ if ( !d->deviceFactory->createAudioOutputDevice() ) {
+ kError() << "Could not create audio output device"; //TODO use error log
+ return;
+ }
+ gst_bin_add(GST_BIN(d->pipeline), d->deviceFactory->audioOutputDevice()->bin());
+ gst_element_set_state(d->deviceFactory->audioOutputDevice()->bin(), GST_STATE_PLAYING);
}
- if (d->pipeline) {
- gst_element_set_state(d->pipeline, GST_STATE_NULL);
+ GstPad *sinkPad = d->newAudioSinkPad();
+ Q_ASSERT(sinkPad);
+ gst_pad_link(srcPad, sinkPad);
+
+ QMetaObject::invokeMethod(this, "audioOutputDeviceCreated", Qt::QueuedConnection,
+ Q_ARG(VolumeControlInterface*, d->deviceFactory->audioOutputDevice()));
+}
+
+void MediaHandler::onAudioSinkPadAdded(GstPad *sinkPad)
+{
+ if ( !d->deviceFactory->audioInputDevice() ) {
+ if ( !d->deviceFactory->createAudioInputDevice() ) {
+ kError() << "Could not create audio input device"; //TODO use error log
+ return;
+ }
+ gst_bin_add(GST_BIN(d->pipeline), d->deviceFactory->audioInputDevice()->bin());
+ gst_element_set_state(d->deviceFactory->audioInputDevice()->bin(), GST_STATE_PLAYING);
}
- d->caps = None;
- setStatus(Disconnected);
+ GstPad *srcPad = gst_element_get_static_pad(d->deviceFactory->audioInputDevice()->bin(), "src");
+ Q_ASSERT(srcPad);
+ gst_pad_link(srcPad, sinkPad);
+ gst_object_unref(srcPad);
+
+ QMetaObject::invokeMethod(this, "audioInputDeviceCreated", Qt::QueuedConnection,
+ Q_ARG(VolumeControlInterface*, d->deviceFactory->audioInputDevice()));
}
gboolean MediaHandler::Private::busWatch(GstBus *bus, GstMessage *message, MediaHandler *self)
@@ -236,34 +211,10 @@
MediaHandler *self)
{
Q_UNUSED(tfChannel);
- guint media_type;
- GstPad *sink;
- GstElement *element = NULL;
-
- g_object_get(stream, "media-type", &media_type, "sink-pad", &sink, NULL);
-
- switch (media_type) {
- case Tp::MediaStreamTypeAudio:
- element = self->d->deviceFactory->audioInputDevice()->bin();
- break;
- case Tp::MediaStreamTypeVideo:
- kWarning() << "Handling video is not supported yet.";
- return;
- default:
- Q_ASSERT(false);
- }
-
g_signal_connect(stream, "src-pad-added",
G_CALLBACK(&MediaHandler::Private::onSrcPadAdded), self);
g_signal_connect(stream, "request-resource",
G_CALLBACK(&MediaHandler::Private::onRequestResource), self);
-
- GstPad *pad = gst_element_get_static_pad(element, "src");
- gst_bin_add(GST_BIN(self->d->pipeline), element);
- gst_pad_link(pad, sink);
- gst_object_unref(sink);
- gst_object_unref(pad);
- gst_element_set_state(element, GST_STATE_PLAYING);
}
void MediaHandler::Private::onSrcPadAdded(TfStream *stream, GstPad *src,
@@ -271,14 +222,11 @@
{
Q_UNUSED(codec);
guint media_type;
- GstPad *pad = NULL;
-
g_object_get(stream, "media-type", &media_type, NULL);
switch (media_type) {
case Tp::MediaStreamTypeAudio:
- pad = self->d->audioSinkPad();
- Q_ASSERT(pad);
+ self->onAudioSrcPadAdded(src);
break;
case Tp::MediaStreamTypeVideo:
kWarning() << "Handling video is not supported yet.";
@@ -286,9 +234,6 @@
default:
Q_ASSERT(false);
}
-
- gst_pad_link(src, pad);
- self->setStatus(Connected);
}
gboolean MediaHandler::Private::onRequestResource(TfStream *stream, guint direction,
@@ -299,23 +244,56 @@
switch (media_type) {
case Tp::MediaStreamTypeAudio:
- if ( (direction & Tp::MediaStreamDirectionSend)
- && !(self->d->caps & SendAudio) ) {
- return FALSE;
+
+ switch(direction) {
+ case Tp::MediaStreamDirectionSend:
+ GstPad *sink;
+ g_object_get(stream, "sink-pad", &sink, NULL);
+ self->onAudioSinkPadAdded(sink);
+ gst_object_unref(sink);
+ return (self->d->deviceFactory->audioInputDevice() != NULL);
+
+ case Tp::MediaStreamDirectionReceive:
+ /* The tp-farsight api is broken, so this signal will come after
+ the src-pad-added signal, which will allocate the resource instead.
+ Here we just return whether src-pad-added could allocate the device or not. */
+ return (self->d->deviceFactory->audioOutputDevice() != NULL);
+
+ default:
+ Q_ASSERT(false);
}
- if ( (direction & Tp::MediaStreamDirectionReceive)
- && !(self->d->caps & ReceiveAudio) ) {
- return FALSE;
- }
- return TRUE;
+ break;
+
case Tp::MediaStreamTypeVideo:
return FALSE;
+
default:
Q_ASSERT(false);
}
return FALSE; //warnings--
}
+GstPad *MediaHandler::Private::newAudioSinkPad()
+{
+ if ( !liveadder ) {
+ if ( !(liveadder = gst_element_factory_make("liveadder", NULL)) ) {
+ kDebug() << "liveadder not available. Attempting to use plain adder";
+ if ( !(liveadder = gst_element_factory_make("adder", NULL)) ) {
+ kFatal() << "Failed to create an adder gstreamer element. Please install "
+ "either the \"adder\" or the \"liveadder\" gstreamer plugin.";
+ }
+ }
+
+ gst_bin_add(GST_BIN(pipeline), liveadder);
+ gst_bin_add(GST_BIN(pipeline), deviceFactory->audioOutputDevice()->bin());
+ gst_element_link(liveadder, deviceFactory->audioOutputDevice()->bin());
+
+ gst_element_set_state(liveadder, GST_STATE_PLAYING);
+ gst_element_set_state(deviceFactory->audioOutputDevice()->bin(), GST_STATE_PLAYING);
+ }
+ return gst_element_get_request_pad(liveadder, "sink%d");
+}
+
} //namespace Farsight
#include "mediahandler.moc"
--- trunk/playground/network/kcall/kcall_handler/farsight/mediahandler.h #993938:993939
@@ -18,6 +18,7 @@
#define _FARSIGHT_MEDIAHANDLER_H
#include "../abstractmediahandler.h"
+typedef struct _GstPad GstPad;
namespace Farsight {
@@ -28,13 +29,11 @@
explicit MediaHandler(const Tp::StreamedMediaChannelPtr & channel, QObject *parent = 0);
virtual ~MediaHandler();
- virtual Capabilities capabilities() const;
- virtual VolumeControlInterface *inputVolumeControl() const;
- virtual VolumeControlInterface *outputVolumeControl() const;
-
private:
void initialize();
void stop();
+ void onAudioSrcPadAdded(GstPad *srcPad);
+ void onAudioSinkPadAdded(GstPad *sinkPad);
struct Private;
friend class Private;
--- trunk/playground/network/kcall/libkgstdevices/devicefactory.cpp #993938:993939
@@ -39,6 +39,8 @@
: d(new Private)
{
d->config = group;
+ d->audioInputDevice = NULL;
+ d->audioOutputDevice = NULL;
}
DeviceFactory::~DeviceFactory()
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic