From 7a69c39ee33566bf9016df0ae57dc2c5899e51c9 Mon Sep 17 00:00:00 2001 From: Rex Dieter Date: Mar 17 2010 01:46:30 +0000 Subject: - phonon-4.4.0 final --- diff --git a/.cvsignore b/.cvsignore index 734ae23..1158bb2 100644 --- a/.cvsignore +++ b/.cvsignore @@ -6,3 +6,4 @@ hi32-phonon-gstreamer.png hi48-phonon-gstreamer.png hi64-phonon-gstreamer.png phonon-4.3.80.tar.bz2 +phonon-4.4.0.tgz diff --git a/phonon-4.2.0-ogg-mime-type.patch b/phonon-4.2.0-ogg-mime-type.patch deleted file mode 100644 index 1213b3a..0000000 --- a/phonon-4.2.0-ogg-mime-type.patch +++ /dev/null @@ -1,20 +0,0 @@ -Index: gstreamer/backend.cpp -=================================================================== ---- gstreamer/backend.cpp (revision 862019) -+++ gstreamer/backend.cpp (working copy) -@@ -226,6 +227,15 @@ - } - } - g_list_free(factoryList); -+ if (availableMimeTypes.contains("audio/x-vorbis") -+ && availableMimeTypes.contains("application/x-ogm-audio")) { -+ if (!availableMimeTypes.contains("audio/x-vorbis+ogg")) -+ availableMimeTypes.append("audio/x-vorbis+ogg"); -+ if (!availableMimeTypes.contains("application/ogg")) /* *.ogg */ -+ availableMimeTypes.append("application/ogg"); -+ if (!availableMimeTypes.contains("audio/ogg")) /* *.oga */ -+ availableMimeTypes.append("audio/ogg"); -+ } - availableMimeTypes.sort(); - return availableMimeTypes; - } diff --git a/phonon-4.3.80-fix-gstreamer-pulseaudio-deadlock.patch b/phonon-4.3.80-fix-gstreamer-pulseaudio-deadlock.patch deleted file mode 100644 index b11abf2..0000000 --- a/phonon-4.3.80-fix-gstreamer-pulseaudio-deadlock.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 104872f266cf6675e27cc6e122300f4ed5baf3ab Mon Sep 17 00:00:00 2001 -From: Colin Guthrie -Date: Wed, 13 Jan 2010 22:57:29 +0000 -Subject: [PATCH] gstreamer: Fix a problem where the fact a reset was needed was lost. - -If you create the path (createPath()) *before* setting the media source, -(setCurrentSource()) the gstreamer backend would forget the fact that a reset -was needed and ultimately end up in an error state. - -This change simply does not wipe out the m_resetNeeded flag when -the source is set and leaves it as it is. - -This fixes the test case application posted on -https://qa.mandriva.com/show_bug.cgi?id=56807 ---- - gstreamer/mediaobject.cpp | 4 +++- - 1 files changed, 3 insertions(+), 1 deletions(-) - -diff --git a/gstreamer/mediaobject.cpp b/gstreamer/mediaobject.cpp -index 15eb080..40e4246 100644 ---- a/gstreamer/mediaobject.cpp -+++ b/gstreamer/mediaobject.cpp -@@ -916,7 +916,9 @@ void MediaObject::setSource(const MediaSource &source) - // Go into to loading state - changeState(Phonon::LoadingState); - m_loading = true; -- m_resetNeeded = false; -+ // IMPORTANT: Honor the m_resetNeeded flag as it currently stands. -+ // See https://qa.mandriva.com/show_bug.cgi?id=56807 -+ //m_resetNeeded = false; - m_resumeState = false; - m_pendingState = Phonon::StoppedState; - --- -1.6.6 - -commit 6fbea9b56a12281819a8c04afd5caa53cfeee39f -Author: cguthrie -Date: Thu Jan 21 18:23:12 2010 +0000 - - gstreamer: Fix a problem encountered when playing, stopping and playing again. - - As reported by Harald Fernengel, a similar problem to that fixed in r1076454 - also exists when you play->stop->play a media object. - - This should fix the issue by marking a reset needed whenever we reach the stopped state. - Thanks to Harald for finding the problem and pointing the way to the fix. - - git-svn-id: svn+ssh://svn.kde.org/home/kde/trunk/kdesupport/phonon@1078188 283d02a7-25f6-0310-bc7c-ecb5cbfe19da - -diff --git a/gstreamer/mediaobject.cpp b/gstreamer/mediaobject.cpp -index 509e749..d1707dd 100644 ---- a/gstreamer/mediaobject.cpp -+++ b/gstreamer/mediaobject.cpp -@@ -741,6 +741,8 @@ void MediaObject::changeState(State newstate) - - case Phonon::StoppedState: - m_backend->logMessage("phonon state changed: Stopped", Backend::Info, this); -+ // We must reset the pipeline when playing again -+ m_resetNeeded = true; - m_tickTimer->stop(); - break; - diff --git a/phonon-4.3.80-kde223662.patch b/phonon-4.3.80-kde223662.patch deleted file mode 100644 index 2eacfcf..0000000 --- a/phonon-4.3.80-kde223662.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- trunk/kdesupport/phonon/xine/audiooutput.cpp 2009/12/27 16:57:19 1066664 -+++ trunk/kdesupport/phonon/xine/audiooutput.cpp 2010/01/21 20:13:50 1078226 -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include "mediaobject.h" - #include "backend.h" - #include "events.h" -@@ -48,10 +49,6 @@ - AudioOutput::AudioOutput(QObject *parent) - : AbstractAudioOutput(new AudioOutputXT, parent) - { -- // Always initialise the "device" in use. -- // This is needed for PulseAudio support as subsequent calls to setOutputDevice() -- // are suppressed -- setOutputDevice(0); - } - - AudioOutput::~AudioOutput() -@@ -132,6 +129,17 @@ - { - K_XT(AudioOutput); - xine_audio_port_t *port = 0; -+ -+ PulseSupport *pulse = PulseSupport::getInstance(); -+ if (pulse->isActive()) { -+ // Here we trust that the PA plugin is setup correctly and we just want to use it. -+ const QByteArray &outputPlugin = "pulseaudio"; -+ debug() << Q_FUNC_INFO << "PA Active: use output plugin:" << outputPlugin; -+ port = xine_open_audio_driver(xt->m_xine, outputPlugin.constData(), 0); -+ debug() << Q_FUNC_INFO << "----------------------------------------------- audio_port created"; -+ return port; -+ } -+ - if (!deviceDesc.isValid()) { - // use null output for invalid devices - port = xine_open_audio_driver(xt->m_xine, "none", 0); ---- trunk/kdesupport/phonon/xine/backend.cpp 2009/12/27 16:57:19 1066664 -+++ trunk/kdesupport/phonon/xine/backend.cpp 2010/01/21 20:13:50 1078226 -@@ -588,9 +588,6 @@ - - QByteArray Backend::audioDriverFor(int audioDevice) - { -- if (PulseSupport::getInstance()->isActive()) -- return "pulseaudio"; -- - instance()->checkAudioOutputs(); - const Backend *const that = instance(); - for (int i = 0; i < that->m_audioOutputInfos.size(); ++i) { diff --git a/phonon-4.3.80-old_pa.patch b/phonon-4.3.80-old_pa.patch deleted file mode 100644 index 9983bdc..0000000 --- a/phonon-4.3.80-old_pa.patch +++ /dev/null @@ -1,186 +0,0 @@ -diff -up phonon-4.3.80/phonon/CMakeLists.txt.old_pa phonon-4.3.80/phonon/CMakeLists.txt ---- phonon-4.3.80/phonon/CMakeLists.txt.old_pa 2009-12-03 13:29:35.000000000 -0600 -+++ phonon-4.3.80/phonon/CMakeLists.txt 2010-01-22 09:52:53.195187362 -0600 -@@ -8,15 +8,21 @@ endif (PHONON_BUILD_EXAMPLES) - - add_subdirectory(experimental) - --set(PULSEAUDIO_MINIMUM_VERSION "0.9.21") -+set(PULSEAUDIO_MINIMUM_VERSION "0.9.15") - macro_optional_find_package(PulseAudio) -+# PULSEAUDIO_DEVICE_MANAGER feature check could be moved to FindPulseAudio.cmake, hint hint. -- Rex -+macro_ensure_version("0.9.21" "${PULSEAUDIO_VERSION}" PULSEAUDIO_DEVICE_MANAGER) - macro_log_feature(PULSEAUDIO_FOUND "PulseAudio" "A cross-platform, networked sound server." "http://www.pulseaudio.org" FALSE "" "Allows audio playback via the PulseAudio soundserver when it is running") - macro_optional_find_package(GLIB2) - macro_log_feature(GLIB2_FOUND "GLib2" "GLib 2 is required to compile the pulseaudio for Phonon" "http://www.gtk.org/download/" FALSE) - -+ - if (GLIB2_FOUND AND PULSEAUDIO_FOUND) - add_definitions(-DHAVE_PULSEAUDIO) - include_directories(${GLIB2_INCLUDE_DIR} ${PULSEAUDIO_INCLUDE_DIR}) -+ if (PULSEAUDIO_DEVICE_MANAGER) -+ add_definitions(-DHAVE_PULSEAUDIO_DEVICE_MANAGER) -+ endif(PULSEAUDIO_DEVICE_MANAGER) - else(GLIB2_FOUND AND PULSEAUDIO_FOUND) - set(PULSEAUDIO_INCLUDE_DIR "") - set(PULSEAUDIO_LIBRARY "") -diff -up phonon-4.3.80/phonon/pulsesupport.cpp.old_pa phonon-4.3.80/phonon/pulsesupport.cpp ---- phonon-4.3.80/phonon/pulsesupport.cpp.old_pa 2009-12-03 13:29:35.000000000 -0600 -+++ phonon-4.3.80/phonon/pulsesupport.cpp 2010-01-22 09:48:15.699935986 -0600 -@@ -30,7 +30,9 @@ - #include - #include - #include --#include -+#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER -+# include -+#endif - #endif // HAVE_PULSEAUDIO - - #include "pulsesupport_p.h" -@@ -151,7 +153,34 @@ static QMap s_captureStreamIndexMap; - static QMap s_captureStreamMoveQueue; - -+static void fakeSingleOutputDevice() -+{ -+ // OK so we don't have the device manager extension, but we can show a single device and fake it. -+ int index; -+ s_outputDeviceIndexes.clear(); -+ s_outputDevices.clear(); -+ s_outputDevicePriorities.clear(); -+ index = s_deviceIndexCounter++; -+ s_outputDeviceIndexes.insert("sink:default", index); -+ s_outputDevices.insert(index, AudioDevice("sink:default", QObject::tr("PulseAudio Sound Server").toUtf8(), "audio-backend-pulseaudio", 0)); -+ for (int i = Phonon::NoCategory; i <= Phonon::LastCategory; ++i) { -+ Phonon::Category cat = static_cast(i); -+ s_outputDevicePriorities[cat].insert(0, index); -+ } -+ -+ s_captureDeviceIndexes.clear(); -+ s_captureDevices.clear(); -+ s_captureDevicePriorities.clear(); -+ index = s_deviceIndexCounter++; -+ s_captureDeviceIndexes.insert("source:default", index); -+ s_captureDevices.insert(index, AudioDevice("source:default", QObject::tr("PulseAudio Sound Server").toUtf8(), "audio-backend-pulseaudio", 0)); -+ for (int i = Phonon::NoCategory; i <= Phonon::LastCategory; ++i) { -+ Phonon::Category cat = static_cast(i); -+ s_captureDevicePriorities[cat].insert(0, index); -+ } -+} - -+#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER - static void ext_device_manager_subscribe_cb(pa_context *, void *); - static void ext_device_manager_read_cb(pa_context *c, const pa_ext_device_manager_info *info, int eol, void *userdata) { - Q_ASSERT(c); -@@ -171,30 +200,7 @@ static void ext_device_manager_read_cb(p - - if (eol < 0) { - logMessage(QString("Failed to initialize device manager extension: %1").arg(pa_strerror(pa_context_errno(c)))); -- // OK so we don't have the device manager extension, but we can show a single device and fake it. -- int index; -- s_outputDeviceIndexes.clear(); -- s_outputDevices.clear(); -- s_outputDevicePriorities.clear(); -- index = s_deviceIndexCounter++; -- s_outputDeviceIndexes.insert("sink:default", index); -- s_outputDevices.insert(index, AudioDevice("sink:default", QObject::tr("PulseAudio Sound Server").toUtf8(), "audio-backend-pulseaudio", 0)); -- for (int i = Phonon::NoCategory; i <= Phonon::LastCategory; ++i) { -- Phonon::Category cat = static_cast(i); -- s_outputDevicePriorities[cat].insert(0, index); -- } -- -- s_captureDeviceIndexes.clear(); -- s_captureDevices.clear(); -- s_captureDevicePriorities.clear(); -- index = s_deviceIndexCounter++; -- s_captureDeviceIndexes.insert("source:default", index); -- s_captureDevices.insert(index, AudioDevice("source:default", QObject::tr("PulseAudio Sound Server").toUtf8(), "audio-backend-pulseaudio", 0)); -- for (int i = Phonon::NoCategory; i <= Phonon::LastCategory; ++i) { -- Phonon::Category cat = static_cast(i); -- s_captureDevicePriorities[cat].insert(0, index); -- } -- -+ fakeSingleOutputDevice(); - return; - } - -@@ -369,6 +375,7 @@ static void ext_device_manager_read_cb(p - } - } - } -+#endif - - static void set_output_device(QString streamUuid) - { -@@ -550,12 +557,12 @@ static void subscribe_cb(pa_context *c, - } - } - -- - static void ext_device_manager_subscribe_cb(pa_context *c, void *) { - Q_ASSERT(c); - - pa_operation *o; - PulseUserData *u = new PulseUserData; /** @todo Make some object to receive the info... */ -+#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER - if (!(o = pa_ext_device_manager_read(c, ext_device_manager_read_cb, u))) { - // We need to deal with failure on first iteration - if (s_connectionEventloop) { -@@ -566,6 +573,7 @@ static void ext_device_manager_subscribe - return; - } - pa_operation_unref(o); -+#endif - - - // Register for the stream changes... -@@ -584,6 +592,7 @@ static void context_state_callback(pa_co - { - Q_ASSERT(c); - -+ logMessage(QString("context_state_callback %1").arg(pa_context_get_state(c))); - switch (pa_context_get_state(c)) { - case PA_CONTEXT_UNCONNECTED: - case PA_CONTEXT_CONNECTING: -@@ -592,8 +601,18 @@ static void context_state_callback(pa_co - break; - - case PA_CONTEXT_READY: -+#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER - // Attempt to load things up - ext_device_manager_subscribe_cb(c, NULL); -+#else -+ s_pulseActive = true; -+ if (s_connectionEventloop) { -+ s_connectionEventloop->exit(0); -+ s_connectionEventloop = 0; -+ } -+ fakeSingleOutputDevice(); -+ ext_device_manager_subscribe_cb(c, NULL); -+#endif - break; - - case PA_CONTEXT_FAILED: -@@ -665,6 +684,7 @@ PulseSupport::PulseSupport() - if (pa_context_connect(s_context, NULL, static_cast(0), 0) >= 0) { - pa_context_set_state_callback(s_context, &context_state_callback, s_connectionEventloop); - // Now we block until we connect or otherwise... -+ logMessage("Entering eventloop..."); - s_connectionEventloop->exec(); - } - #endif -@@ -821,11 +841,13 @@ static void setDevicePriority(Category c - } - devices[list.size()] = NULL; - -+#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER - pa_operation *o; - if (!(o = pa_ext_device_manager_reorder_devices_for_role(s_context, role.toUtf8().constData(), (const char**)devices, NULL, NULL))) - logMessage(QString("pa_ext_device_manager_reorder_devices_for_role() failed")); - else - pa_operation_unref(o); -+#endif - - for (i = 0; i < list.size(); ++i) - pa_xfree(devices[i]); diff --git a/phonon-4.3.80-pulse-devicemove-rejig.patch b/phonon-4.3.80-pulse-devicemove-rejig.patch new file mode 100644 index 0000000..4eff732 --- /dev/null +++ b/phonon-4.3.80-pulse-devicemove-rejig.patch @@ -0,0 +1,454 @@ +diff --git a/phonon/audiooutput.cpp b/phonon/audiooutput.cpp +index e99c394..ddbf360 100644 +--- a/phonon/audiooutput.cpp ++++ b/phonon/audiooutput.cpp +@@ -99,7 +99,9 @@ void AudioOutputPrivate::init(Phonon::Category c) + + category = c; + streamUuid = QUuid::createUuid().toString(); +- PulseSupport::getInstance()->setStreamPropList(category, streamUuid); ++ PulseSupport *pulse = PulseSupport::getInstance(); ++ pulse->setStreamPropList(category, streamUuid); ++ q->connect(pulse, SIGNAL(usingDevice(QString,int)), SLOT(_k_deviceChanged(QString,int))); + + createBackendObject(); + +@@ -232,14 +234,14 @@ bool AudioOutput::setOutputDevice(const AudioOutputDevice &newAudioOutputDevice) + { + K_D(AudioOutput); + if (!newAudioOutputDevice.isValid()) { +- d->outputDeviceOverridden = false; ++ d->outputDeviceOverridden = d->forceMove = false; + const int newIndex = GlobalConfig().audioOutputDeviceFor(d->category); + if (newIndex == d->device.index()) { + return true; + } + d->device = AudioOutputDevice::fromIndex(newIndex); + } else { +- d->outputDeviceOverridden = true; ++ d->outputDeviceOverridden = d->forceMove = true; + if (d->device == newAudioOutputDevice) { + return true; + } +@@ -272,7 +274,10 @@ void AudioOutputPrivate::setupBackendObject() + pINTERFACE_CALL(setVolume(pow(volume, VOLTAGE_TO_LOUDNESS_EXPONENT))); + + // if the output device is not available and the device was not explicitly set +- if (!callSetOutputDevice(this, device) && !outputDeviceOverridden) { ++ // There is no need to set the output device initially if PA is used as ++ // we know it will not work (stream doesn't exist yet) and that this will be ++ // handled by _k_deviceChanged() ++ if (!PulseSupport::getInstance()->isActive() && !callSetOutputDevice(this, device) && !outputDeviceOverridden) { + // fall back in the preference list of output devices + QList deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices); + if (deviceList.isEmpty()) { +@@ -316,6 +321,9 @@ void AudioOutputPrivate::_k_revertFallback() + + void AudioOutputPrivate::_k_audioDeviceFailed() + { ++ if (PulseSupport::getInstance()->isActive()) ++ return; ++ + pDebug() << Q_FUNC_INFO; + // outputDeviceIndex identifies a failing device + // fall back in the preference list of output devices +@@ -338,7 +346,14 @@ void AudioOutputPrivate::_k_audioDeviceFailed() + + void AudioOutputPrivate::_k_deviceListChanged() + { ++ if (PulseSupport::getInstance()->isActive()) ++ return; ++ + pDebug() << Q_FUNC_INFO; ++ // Check to see if we have an override and do not change to a higher priority device if the overridden device is still present. ++ if (outputDeviceOverridden && device.property("available").toBool()) { ++ return; ++ } + // let's see if there's a usable device higher in the preference list + QList deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings); + DeviceChangeType changeType = HigherPreferenceChange; +@@ -365,6 +380,36 @@ void AudioOutputPrivate::_k_deviceListChanged() + } + } + ++void AudioOutputPrivate::_k_deviceChanged(QString inStreamUuid, int deviceIndex) ++{ ++ // Note that this method is only used by PulseAudio at present. ++ if (inStreamUuid == streamUuid) { ++ // 1. Check to see if we are overridden. If we are, and devices do not match, ++ // then try and apply our own device as the output device. ++ // We only do this the first time ++ if (outputDeviceOverridden && forceMove) { ++ forceMove = false; ++ const AudioOutputDevice ¤tDevice = AudioOutputDevice::fromIndex(deviceIndex); ++ if (currentDevice != device) { ++ if (!callSetOutputDevice(this, device)) { ++ // What to do if we are overridden and cannot change to our preferred device? ++ } ++ } ++ } ++ // 2. If we are not overridden, then we need to update our perception of what ++ // device we are using. If the devices do not match, something lower in the ++ // stack is overriding our preferences (e.g. a per-application stream preference, ++ // specific application move, priority list changed etc. etc.) ++ else if (!outputDeviceOverridden) { ++ const AudioOutputDevice ¤tDevice = AudioOutputDevice::fromIndex(deviceIndex); ++ if (currentDevice != device) { ++ // The device is not what we think it is, so lets say what is happening. ++ handleAutomaticDeviceChange(currentDevice, SoundSystemChange); ++ } ++ } ++ } ++} ++ + static struct + { + int first; +@@ -409,6 +454,27 @@ void AudioOutputPrivate::handleAutomaticDeviceChange(const AudioOutputDevice &de + g_lastFallback.second = 0; + } + break; ++ case SoundSystemChange: ++ { ++#ifndef QT_NO_PHONON_PLATFORMPLUGIN ++ if (device1.property("available").toBool()) { ++ const QString text = AudioOutput::tr("Switching to the audio playback device %1
" ++ "which has higher preference or is specifically configured for this stream.").arg(device2.name()); ++ Platform::notification("AudioDeviceFallback", text, ++ QStringList(AudioOutput::tr("Revert back to device '%1'").arg(device1.name())), ++ q, SLOT(_k_revertFallback())); ++ } else { ++ const QString &text = ++ AudioOutput::tr("The audio playback device %1 does not work.
" ++ "Falling back to %2.").arg(device1.name()).arg(device2.name()); ++ Platform::notification("AudioDeviceFallback", text); ++ } ++#endif //QT_NO_PHONON_PLATFORMPLUGIN ++ //outputDeviceOverridden = true; ++ g_lastFallback.first = 0; ++ g_lastFallback.second = 0; ++ } ++ break; + } + } + +diff --git a/phonon/audiooutput.h b/phonon/audiooutput.h +index 4edf135..513a863 100644 +--- a/phonon/audiooutput.h ++++ b/phonon/audiooutput.h +@@ -169,6 +169,7 @@ namespace Phonon + Q_PRIVATE_SLOT(k_func(), void _k_revertFallback()) + Q_PRIVATE_SLOT(k_func(), void _k_audioDeviceFailed()) + Q_PRIVATE_SLOT(k_func(), void _k_deviceListChanged()) ++ Q_PRIVATE_SLOT(k_func(), void _k_deviceChanged(QString streamUuid, int device)) + }; + } //namespace Phonon + +diff --git a/phonon/audiooutput_p.h b/phonon/audiooutput_p.h +index 0a90c3d..01dc48f 100644 +--- a/phonon/audiooutput_p.h ++++ b/phonon/audiooutput_p.h +@@ -59,6 +59,7 @@ class AudioOutputPrivate : public AbstractAudioOutputPrivate + #endif + deviceBeforeFallback(-1), + outputDeviceOverridden(false), ++ forceMove(false), + muted(false) + { + } +@@ -67,7 +68,8 @@ class AudioOutputPrivate : public AbstractAudioOutputPrivate + + enum DeviceChangeType { + FallbackChange, +- HigherPreferenceChange ++ HigherPreferenceChange, ++ SoundSystemChange + }; + void handleAutomaticDeviceChange(const AudioOutputDevice &newDev, DeviceChangeType type); + +@@ -75,6 +77,7 @@ class AudioOutputPrivate : public AbstractAudioOutputPrivate + void _k_revertFallback(); + void _k_audioDeviceFailed(); + void _k_deviceListChanged(); ++ void _k_deviceChanged(QString streamUuid, int deviceIndex); + + private: + QString name; +@@ -87,6 +90,7 @@ class AudioOutputPrivate : public AbstractAudioOutputPrivate + Category category; + int deviceBeforeFallback; + bool outputDeviceOverridden; ++ bool forceMove; + bool muted; + }; + } //namespace Phonon +diff --git a/phonon/pulsesupport.cpp b/phonon/pulsesupport.cpp +index f102177..9d3dd82 100644 +--- a/phonon/pulsesupport.cpp ++++ b/phonon/pulsesupport.cpp +@@ -145,13 +145,11 @@ static QMap s_outputDeviceIndexes; + static QMap s_outputDevices; + static QMap > s_outputDevicePriorities; // prio, device + static QMap s_outputStreamIndexMap; +-static QMap s_outputStreamMoveQueue; + + static QMap s_captureDeviceIndexes; + static QMap s_captureDevices; + static QMap > s_captureDevicePriorities; // prio, device + static QMap s_captureStreamIndexMap; +-static QMap s_captureStreamMoveQueue; + + static void createGenericDevices() + { +@@ -378,80 +376,6 @@ static void ext_device_manager_read_cb(pa_context *c, const pa_ext_device_manage + } + #endif + +-static void set_output_device(QString streamUuid) +-{ +- // If we only have one device, bail. This will be true if we are not using module-device-manager +- if (s_outputDevices.size() < 2) +- return; +- +- if (!s_outputStreamMoveQueue.contains(streamUuid)) +- return; +- +- if (!s_outputStreamIndexMap.contains(streamUuid)) +- return; +- +- if (s_outputStreamIndexMap[streamUuid] == PA_INVALID_INDEX) +- return; +- +- int device = s_outputStreamMoveQueue[streamUuid]; +- if (!s_outputDevices.contains(device)) +- return; +- +- // We don't remove the uuid from the s_captureStreamMoveQueue +- // as an application may reuse the phonon AudioOutput object +- +- uint32_t pulse_device_index = s_outputDevices[device].pulseIndex; +- uint32_t pulse_stream_index = s_outputStreamIndexMap[streamUuid]; +- +- const QVariant var = s_outputDevices[device].properties["name"]; +- logMessage(QString("Moving Pulse Sink Input %1 to '%2' (Pulse Sink %3)").arg(pulse_stream_index).arg(var.toString()).arg(pulse_device_index)); +- +- /// @todo Find a way to move the stream without saving it... We don't want to pollute the stream restore db. +- pa_operation* o; +- if (!(o = pa_context_move_sink_input_by_index(s_context, pulse_stream_index, pulse_device_index, NULL, NULL))) { +- logMessage(QString("pa_context_move_sink_input_by_index() failed")); +- return; +- } +- pa_operation_unref(o); +-} +- +-static void set_capture_device(QString streamUuid) +-{ +- // If we only have one device, bail. This will be true if we are not using module-device-manager +- if (s_captureDevices.size() < 2) +- return; +- +- if (!s_captureStreamMoveQueue.contains(streamUuid)) +- return; +- +- if (!s_captureStreamIndexMap.contains(streamUuid)) +- return; +- +- if (s_captureStreamIndexMap[streamUuid] == PA_INVALID_INDEX) +- return; +- +- int device = s_captureStreamMoveQueue[streamUuid]; +- if (!s_captureDevices.contains(device)) +- return; +- +- // We don't remove the uuid from the s_captureStreamMoveQueue +- // as an application may reuse the phonon AudioCapture object (when it exists!) +- +- uint32_t pulse_device_index = s_captureDevices[device].pulseIndex; +- uint32_t pulse_stream_index = s_captureStreamIndexMap[streamUuid]; +- +- const QVariant var = s_captureDevices[device].properties["name"]; +- logMessage(QString("Moving Pulse Source Output %1 to '%2' (Pulse Sink %3)").arg(pulse_stream_index).arg(var.toString()).arg(pulse_device_index)); +- +- /// @todo Find a way to move the stream without saving it... We don't want to pollute the stream restore db. +- pa_operation* o; +- if (!(o = pa_context_move_source_output_by_index(s_context, pulse_stream_index, pulse_device_index, NULL, NULL))) { +- logMessage(QString("pa_context_move_source_output_by_index() failed")); +- return; +- } +- pa_operation_unref(o); +-} +- + void sink_input_cb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata) { + Q_UNUSED(userdata); + Q_ASSERT(c); +@@ -474,8 +398,25 @@ void sink_input_cb(pa_context *c, const pa_sink_input_info *i, int eol, void *us + if ((t = pa_proplist_gets(i->proplist, "phonon.streamid"))) { + logMessage(QString("Found PulseAudio stream index %1 for Phonon Output Stream %2").arg(i->index).arg(t)); + s_outputStreamIndexMap[QString(t)] = i->index; +- // Process any pending moves... +- set_output_device(QString(t)); ++ ++ // Find the sink's phonon index and notify whoever cares... ++ if (PA_INVALID_INDEX != i->sink) { ++ bool found = false; ++ int device; ++ QMap::iterator it; ++ for (it = s_outputDevices.begin(); it != s_outputDevices.end(); ++it) { ++ if ((*it).pulseIndex == i->sink) { ++ found = true; ++ device = it.key(); ++ break; ++ } ++ } ++ if (found) { ++ // OK so we just emit our signal ++ logMessage(QString("Letting the rest of phonon know about this")); ++ s_instance->emitUsingDevice(QString(t), device); ++ } ++ } + } + } + +@@ -501,8 +442,25 @@ void source_output_cb(pa_context *c, const pa_source_output_info *i, int eol, vo + if ((t = pa_proplist_gets(i->proplist, "phonon.streamid"))) { + logMessage(QString("Found PulseAudio stream index %1 for Phonon Capture Stream %2").arg(i->index).arg(t)); + s_captureStreamIndexMap[QString(t)] = i->index; +- // Process any pending moves... +- set_capture_device(QString(t)); ++ ++ // Find the source's phonon index and notify whoever cares... ++ if (PA_INVALID_INDEX != i->source) { ++ bool found = false; ++ int device; ++ QMap::iterator it; ++ for (it = s_captureDevices.begin(); it != s_captureDevices.end(); ++it) { ++ if ((*it).pulseIndex == i->source) { ++ found = true; ++ device = it.key(); ++ break; ++ } ++ } ++ if (found) { ++ // OK so we just emit our signal ++ logMessage(QString("Letting the rest of phonon know about this")); ++ s_instance->emitUsingDevice(QString(t), device); ++ } ++ } + } + } + +@@ -520,7 +478,6 @@ static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t + } else { + logMessage(QString("Removing Phonon Output Stream %1 (it's gone!)").arg(phononid)); + s_outputStreamIndexMap.remove(phononid); +- s_outputStreamMoveQueue.remove(phononid); + } + } + } else { +@@ -543,7 +500,6 @@ static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t + } else { + logMessage(QString("Removing Phonon Capture Stream %1 (it's gone!)").arg(phononid)); + s_captureStreamIndexMap.remove(phononid); +- s_captureStreamMoveQueue.remove(phononid); + } + } + } else { +@@ -933,6 +889,11 @@ void PulseSupport::emitObjectDescriptionChanged(ObjectDescriptionType type) + emit objectDescriptionChanged(type); + } + ++void PulseSupport::emitUsingDevice(QString streamUuid, int device) ++{ ++ emit usingDevice(streamUuid, device); ++} ++ + bool PulseSupport::setOutputDevice(QString streamUuid, int device) { + #ifndef HAVE_PULSEAUDIO + Q_UNUSED(streamUuid); +@@ -949,13 +910,24 @@ bool PulseSupport::setOutputDevice(QString streamUuid, int device) { + const QVariant var = s_outputDevices[device].properties["name"]; + logMessage(QString("Attempting to set Output Device to '%1' for Output Stream %2").arg(var.toString()).arg(streamUuid)); + +- s_outputStreamMoveQueue[streamUuid] = device; + // Attempt to look up the pulse stream index. + if (s_outputStreamIndexMap.contains(streamUuid) && s_outputStreamIndexMap[streamUuid] != PA_INVALID_INDEX) { + logMessage(QString("... Found in map. Moving now")); +- set_output_device(streamUuid); ++ ++ uint32_t pulse_device_index = s_outputDevices[device].pulseIndex; ++ uint32_t pulse_stream_index = s_outputStreamIndexMap[streamUuid]; ++ ++ logMessage(QString("Moving Pulse Sink Input %1 to '%2' (Pulse Sink %3)").arg(pulse_stream_index).arg(var.toString()).arg(pulse_device_index)); ++ ++ /// @todo Find a way to move the stream without saving it... We don't want to pollute the stream restore db. ++ pa_operation* o; ++ if (!(o = pa_context_move_sink_input_by_index(s_context, pulse_stream_index, pulse_device_index, NULL, NULL))) { ++ logMessage(QString("pa_context_move_sink_input_by_index() failed")); ++ return false; ++ } ++ pa_operation_unref(o); + } else { +- logMessage(QString("... Not found in map. Saving move for when the stream appears")); ++ logMessage(QString("... Not found in map. We will be notified of the device when the stream appears and we can process any moves needed then")); + } + return true; + #endif +@@ -977,13 +949,24 @@ bool PulseSupport::setCaptureDevice(QString streamUuid, int device) { + const QVariant var = s_captureDevices[device].properties["name"]; + logMessage(QString("Attempting to set Capture Device to '%1' for Capture Stream %2").arg(var.toString()).arg(streamUuid)); + +- s_captureStreamMoveQueue[streamUuid] = device; + // Attempt to look up the pulse stream index. + if (s_captureStreamIndexMap.contains(streamUuid) && s_captureStreamIndexMap[streamUuid] == PA_INVALID_INDEX) { + logMessage(QString("... Found in map. Moving now")); +- set_capture_device(streamUuid); ++ ++ uint32_t pulse_device_index = s_captureDevices[device].pulseIndex; ++ uint32_t pulse_stream_index = s_captureStreamIndexMap[streamUuid]; ++ ++ logMessage(QString("Moving Pulse Source Output %1 to '%2' (Pulse Sink %3)").arg(pulse_stream_index).arg(var.toString()).arg(pulse_device_index)); ++ ++ /// @todo Find a way to move the stream without saving it... We don't want to pollute the stream restore db. ++ pa_operation* o; ++ if (!(o = pa_context_move_source_output_by_index(s_context, pulse_stream_index, pulse_device_index, NULL, NULL))) { ++ logMessage(QString("pa_context_move_source_output_by_index() failed")); ++ return false; ++ } ++ pa_operation_unref(o); + } else { +- logMessage(QString("... Not found in map. Saving move for when the stream appears")); ++ logMessage(QString("... Not found in map. We will be notified of the device when the stream appears and we can process any moves needed then")); + } + return true; + #endif +@@ -996,9 +979,7 @@ void PulseSupport::clearStreamCache(QString streamUuid) { + #else + logMessage(QString("Clearing stream cache for stream %1").arg(streamUuid)); + s_outputStreamIndexMap.remove(streamUuid); +- s_outputStreamMoveQueue.remove(streamUuid); + s_captureStreamIndexMap.remove(streamUuid); +- s_captureStreamMoveQueue.remove(streamUuid); + #endif + } + +diff --git a/phonon/pulsesupport.h b/phonon/pulsesupport.h +index bba5fd5..c38bece 100644 +--- a/phonon/pulsesupport.h ++++ b/phonon/pulsesupport.h +@@ -54,6 +54,7 @@ namespace Phonon + + void setStreamPropList(Category category, QString streamUuid); + void emitObjectDescriptionChanged(ObjectDescriptionType); ++ void emitUsingDevice(QString streamUuid, int device); + + bool setOutputDevice(QString streamUuid, int device); + bool setCaptureDevice(QString streamUuid, int device); +@@ -61,6 +62,8 @@ namespace Phonon + + signals: + void objectDescriptionChanged(ObjectDescriptionType); ++ void usingDevice(QString streamUuid, int device); ++ + private: + PulseSupport(); + ~PulseSupport(); diff --git a/phonon.spec b/phonon.spec index 13ae586..3237bbd 100644 --- a/phonon.spec +++ b/phonon.spec @@ -1,14 +1,14 @@ -#define snap 20091203svn +%define tar_ver 4.4 Summary: Multimedia framework api Name: phonon -Version: 4.3.80 -Release: 5%{?dist}.2 +Version: 4.4.0 +Release: 1%{?dist} Group: System Environment/Libraries License: LGPLv2+ URL: http://phonon.kde.org/ -Source0: ftp://ftp.kde.org/pub/kde/unstable/phonon/phonon-%{version}.tar.bz2 +Source0: ftp://ftp.kde.org/pub/kde/stable/phonon/4.4.0/phonon-%{version}.tgz #Source0: phonon-%{snap}.tar.bz2 Source1: phonon_snapshot.sh BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -28,19 +28,12 @@ Patch0: phonon-4.3.80-pulseaudio-device-priorities.patch Patch1: phonon-4.3.50-xine_pulseaudio.patch ## Mandriva/upstreamable patches -Patch50: phonon-4.2.0-ogg-mime-type.patch Patch51: phonon-4.3.50-fix-decodebin-usage.patch Patch52: phonon-4.3.50-gstreamer-fix-seekable-query-failed.patch Patch53: phonon-4.3.50-phonon-allow-stop-empty-source.patch -Patch54: phonon-4.3.80-fix-gstreamer-pulseaudio-deadlock.patch - -# patch adapted from http://permalink.gmane.org/gmane.comp.kde.users.multimedia/5700 -# splits out device_manager bits used only on pa >= 0.9.21 -Patch60: phonon-4.3.80-old_pa.patch +Patch57: phonon-4.3.80-pulse-devicemove-rejig.patch ## Upstream patches -# http://bugs.kde.org/223662 -Patch100: phonon-4.3.80-kde223662.patch BuildRequires: automoc4 >= 0.9.86 BuildRequires: cmake >= 2.6.0 @@ -69,7 +62,7 @@ Requires: qt4%{?_isa} >= %{_qt4_version} %package devel Summary: Developer files for %{name} Group: Development/Libraries -Requires: %{name} = %{version}-%{release} +Requires: %{name}%{?_isa} = %{version}-%{release} Requires: qt4-devel Requires: pkgconfig %description devel @@ -97,26 +90,25 @@ Provides: %{name}-backend-gst = %{version}-%{release} %prep -%setup -q -n phonon%{!?snap:-%{version}} +%setup -q -n phonon%{!?snap:-%{?tar_ver}%{!?tar_ver:%{version}}} %if 0%{?pa_keep_old_hacks} -%patch0 -p1 -b .pulseaudio-device-priorities -%patch1 -p1 -b .xine_pulseaudio +# FIXME/adapt to 4.4, or drop +#patch0 -p1 -b .pulseaudio-device-priorities +#patch1 -p1 -b .xine_pulseaudio %endif -%patch50 -p0 -b .ogg-mime-type %patch51 -p0 -b .fix-decodebin-usage %patch52 -p1 -b .gstreamer-fix-seekable-query-failed %patch53 -p1 -b .phonon-allow-stop-empty-source -%patch54 -p1 -b .gstreamer-pulseaudio-deadlock -%patch60 -p1 -b .old_pa -%patch100 -p3 -b .kde223662 +%patch57 -p1 -b .pulse-devicemove-rejig %build mkdir -p %{_target_platform} pushd %{_target_platform} %{cmake} \ + %{?_cmake_skip_rpath} \ -DUSE_INSTALL_PLUGIN=TRUE \ .. popd @@ -215,6 +207,18 @@ gtk-update-icon-cache %{_kde4_iconsdir}/hicolor &> /dev/null ||: %changelog +* Tue Mar 16 2010 Rex Dieter - 4.4.0-1 +- phonon-4.4.0 final + +* Fri Mar 12 2010 Rex Dieter - 4.4.0-0.3 +- phonon-4.3.80-pulse-devicemove-rejig.patch (from mdv) + +* Wed Feb 24 2010 Rex Dieter - 4.4.0-0.2 +- preliminary phonon-4.4.0 tarball + +* Fri Jan 22 2010 Rex Dieter - 4.3.80-6 +- sync w/mdv patches + * Fri Jan 22 2010 Rex Dieter - 4.3.80-5.2 - F11: patch/modularize pa device-manager bits diff --git a/sources b/sources index dc0adc2..e9f9fad 100644 --- a/sources +++ b/sources @@ -5,4 +5,4 @@ 12db12c009b722a6dc141f78feb7e330 hi32-phonon-gstreamer.png 86c34a1b81d44980b1381f94ed6b7a23 hi48-phonon-gstreamer.png 153505c71ec021b0a3bd4b74f2492e93 hi64-phonon-gstreamer.png -6b0c5554291615433c14c3c38f741690 phonon-4.3.80.tar.bz2 +80544b876cf0e0af05f2303b3f534351 phonon-4.4.0.tgz