From 9dc5807743492fe1c9b3d63f495e2ee774cec6fe Mon Sep 17 00:00:00 2001 From: Rex Dieter Date: Apr 05 2010 13:14:13 +0000 Subject: sync w/devel --- diff --git a/phonon-4.3.50-xine_pulseaudio.patch b/phonon-4.3.50-xine_pulseaudio.patch deleted file mode 100644 index ca7c300..0000000 --- a/phonon-4.3.50-xine_pulseaudio.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up phonon/xine/backend.cpp.pulseaudio phonon/xine/backend.cpp ---- phonon/xine/backend.cpp.pulseaudio 2009-10-03 14:00:19.000000000 -0500 -+++ phonon/xine/backend.cpp 2009-10-19 12:23:17.768923476 -0500 -@@ -649,7 +649,7 @@ void Backend::checkAudioOutputs() - "in KDE2 and KDE3. Its use is discouraged.

"), - /*icon name */"audio-backend-arts", outputPlugins[i]); - } else if (0 == strcmp(outputPlugins[i], "pulseaudio")) { -- addAudioOutput(nextIndex++, 10, tr("PulseAudio"), -+ addAudioOutput(nextIndex++, 2000, tr("PulseAudio"), - xine_get_audio_driver_plugin_description(m_xine, outputPlugins[i]), - /*icon name */"audio-backend-pulseaudio", outputPlugins[i]); - } else if (0 == strcmp(outputPlugins[i], "esd")) { diff --git a/phonon-4.3.80-pulseaudio-device-priorities.patch b/phonon-4.3.80-pulseaudio-device-priorities.patch deleted file mode 100644 index bb993c4..0000000 --- a/phonon-4.3.80-pulseaudio-device-priorities.patch +++ /dev/null @@ -1,43 +0,0 @@ -diff -ur phonon-4.3.80/phonon/globalconfig.cpp phonon-4.3.80-pulseaudio-device-priorities/phonon/globalconfig.cpp ---- phonon-4.3.80/phonon/globalconfig.cpp 2009-12-03 20:29:35.000000000 +0100 -+++ phonon-4.3.80-pulseaudio-device-priorities/phonon/globalconfig.cpp 2010-01-22 15:57:25.000000000 +0100 -@@ -33,6 +33,7 @@ - #include "pulsesupport_p.h" - - #include -+#include - #include - - QT_BEGIN_NAMESPACE -@@ -314,6 +315,15 @@ - | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) - ); - } -+ // make PulseAudio the global default (assume it is already default in this list) -+ if (!list.isEmpty()) { -+ int firstIndex = list.first(); -+ if (backendIface->objectDescriptionProperties(Phonon::AudioOutputDeviceType, -+ firstIndex)["icon"].toString() == "audio-backend-pulseaudio") { -+ list.removeFirst(); -+ defaultList.prepend(firstIndex); -+ } -+ } - defaultList += list; - } - -@@ -394,6 +404,15 @@ - | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0) - ); - } -+ // make PulseAudio the global default (assume it is already default in this list) -+ if (!list.isEmpty()) { -+ int firstIndex = list.first(); -+ if (backendIface->objectDescriptionProperties(Phonon::AudioCaptureDeviceType, -+ firstIndex)["icon"].toString() == "audio-backend-pulseaudio") { -+ list.removeFirst(); -+ defaultList.prepend(firstIndex); -+ } -+ } - defaultList += list; - } - diff --git a/phonon-4.4.0-eventloop.patch b/phonon-4.4.0-eventloop.patch new file mode 100644 index 0000000..a20b5e8 --- /dev/null +++ b/phonon-4.4.0-eventloop.patch @@ -0,0 +1,327 @@ +diff --git a/phonon/pulsesupport.cpp b/phonon/pulsesupport.cpp +index d0387c3..a3733ad 100644 +--- a/phonon/pulsesupport.cpp ++++ b/phonon/pulsesupport.cpp +@@ -135,7 +135,6 @@ static bool s_pulseActive = false; + + static pa_glib_mainloop *s_mainloop = NULL; + static pa_context *s_context = NULL; +-static QEventLoop *s_connectionEventloop = NULL; + + + +@@ -179,31 +178,25 @@ static void createGenericDevices() + } + + #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); + Q_ASSERT(userdata); + +- // If this is our first iteration, set things up properly +- if (s_connectionEventloop) { +- logMessage("Exiting connection event loop (PulseAudio server found)"); +- s_connectionEventloop->exit(0); +- s_connectionEventloop = NULL; +- s_pulseActive = true; +- +- pa_operation *o; +- pa_ext_device_manager_set_subscribe_cb(c, ext_device_manager_subscribe_cb, NULL); +- if ((o = pa_ext_device_manager_subscribe(c, 1, NULL, NULL))) +- pa_operation_unref(o); +- } ++ PulseUserData *u = reinterpret_cast(userdata); + + if (eol < 0) { + logMessage(QString("Failed to initialize device manager extension: %1").arg(pa_strerror(pa_context_errno(c)))); ++ logMessage("Falling back to single device mode"); + createGenericDevices(); ++ delete u; ++ ++ // If this is our probe phase, exit now ++ if (s_context != c) ++ pa_context_disconnect(c); ++ + return; + } + +- PulseUserData *u = reinterpret_cast(userdata); + if (eol) { + // We're done reading the data, so order it by priority and copy it into the + // static variables where it can then be accessed by those classes that need it. +@@ -289,6 +282,8 @@ static void ext_device_manager_read_cb(pa_context *c, const pa_ext_device_manage + } + + if (s_instance) { ++ // This wont be emitted durring the connection probe phase ++ // which is intensional + if (output_changed) + s_instance->emitObjectDescriptionChanged(AudioOutputDeviceType); + if (capture_changed) +@@ -323,6 +318,11 @@ static void ext_device_manager_read_cb(pa_context *c, const pa_ext_device_manage + } + } + } ++ ++ // If this is our probe phase, exit now as we're finished reading ++ // our device info and can exit and reconnect ++ if (s_context != c) ++ pa_context_disconnect(c); + } + + if (!info) +@@ -374,6 +374,19 @@ static void ext_device_manager_read_cb(pa_context *c, const pa_ext_device_manage + } + } + } ++ ++static void ext_device_manager_subscribe_cb(pa_context *c, void *) { ++ Q_ASSERT(c); ++ ++ pa_operation *o; ++ PulseUserData *u = new PulseUserData; ++ if (!(o = pa_ext_device_manager_read(c, ext_device_manager_read_cb, u))) { ++ logMessage(QString("pa_ext_device_manager_read() failed.")); ++ delete u; ++ return; ++ } ++ pa_operation_unref(o); ++} + #endif + + void sink_input_cb(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata) { +@@ -515,49 +528,6 @@ static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t + } + + +-static void ext_device_manager_subscribe_cb(pa_context *c, void *) { +- Q_ASSERT(c); +- +- pa_operation *o; +-#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER +- PulseUserData *u = new PulseUserData; /** @todo Make some object to receive the info... */ +- 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) { +- logMessage("Entering connection eventloop (initialisation failed)"); +- s_connectionEventloop->exit(0); +- s_connectionEventloop = NULL; +- } +- logMessage(QString("pa_ext_device_manager_read() failed")); +- return; +- } +- pa_operation_unref(o); +-#else +- // If we do not have Device Manager support. We just bail out now +- // and say we are active with our single "devices" for playback and capture +- s_pulseActive = true; +- logMessage("Entering connection eventloop (successfully detected PulseAudio)"); +- if (s_connectionEventloop) { +- s_connectionEventloop->exit(0); +- s_connectionEventloop = NULL; +- } +- createGenericDevices(); +-#endif +- +- +- // Register for the stream changes... +- pa_context_set_subscribe_callback(c, subscribe_cb, NULL); +- +- if (!(o = pa_context_subscribe(c, (pa_subscription_mask_t) +- (PA_SUBSCRIPTION_MASK_SINK_INPUT| +- PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT), NULL, NULL))) { +- logMessage(QString("pa_context_subscribe() failed")); +- return; +- } +- pa_operation_unref(o); +-} +- +- + static const char* statename(pa_context_state_t state) + { + switch (state) +@@ -581,32 +551,68 @@ static void context_state_callback(pa_context *c, void *) + Q_ASSERT(c); + + logMessage(QString("context_state_callback %1").arg(statename(pa_context_get_state(c)))); +- switch (pa_context_get_state(c)) { +- case PA_CONTEXT_UNCONNECTED: +- case PA_CONTEXT_CONNECTING: +- case PA_CONTEXT_AUTHORIZING: +- case PA_CONTEXT_SETTING_NAME: +- break; ++ pa_context_state_t state = pa_context_get_state(c); ++ if (state == PA_CONTEXT_READY) { ++ // We've connected to PA, so it is active ++ s_pulseActive = true; + +- case PA_CONTEXT_READY: +- // Attempt to load things up +- ext_device_manager_subscribe_cb(c, NULL); +- break; ++ // Attempt to load things up ++ pa_operation *o; ++ ++ // 1. Register for the stream changes (except during probe) ++ if (s_context == c) { ++ pa_context_set_subscribe_callback(c, subscribe_cb, NULL); + +- case PA_CONTEXT_FAILED: +- s_pulseActive = false; +- if (s_connectionEventloop) { +- logMessage("Entering connection eventloop (connection failed)"); +- s_connectionEventloop->exit(0); +- s_connectionEventloop = NULL; ++ if (!(o = pa_context_subscribe(c, (pa_subscription_mask_t) ++ (PA_SUBSCRIPTION_MASK_SINK_INPUT| ++ PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT), NULL, NULL))) { ++ logMessage(QString("pa_context_subscribe() failed")); ++ return; + } +- break; ++ pa_operation_unref(o); ++ } + +- case PA_CONTEXT_TERMINATED: +- default: +- s_pulseActive = false; +- /// @todo Deal with reconnection... +- break; ++#ifdef HAVE_PULSEAUDIO_DEVICE_MANAGER ++ // 2a. Attempt to initialise Device Manager info (except during probe) ++ if (s_context == c) { ++ pa_ext_device_manager_set_subscribe_cb(c, ext_device_manager_subscribe_cb, NULL); ++ if (!(o = pa_ext_device_manager_subscribe(c, 1, NULL, NULL))) { ++ logMessage(QString("pa_ext_device_manager_subscribe() failed")); ++ return; ++ } ++ pa_operation_unref(o); ++ } ++ ++ // 3. Attempt to read info from Device Manager ++ PulseUserData *u = new PulseUserData; ++ if (!(o = pa_ext_device_manager_read(c, ext_device_manager_read_cb, u))) { ++ logMessage(QString("pa_ext_device_manager_read() failed. Attempting to continue without device manager support")); ++ createGenericDevices(); ++ delete u; ++ ++ // If this is our probe phase, exit immediately ++ if (s_context != c) ++ pa_context_disconnect(c); ++ ++ return; ++ } ++ pa_operation_unref(o); ++ ++#else ++ // If we know do not have Device Manager support, we just create our dummy devices now ++ createGenericDevices(); ++ ++ // If this is our probe phase, exit immediately ++ if (s_context != c) ++ pa_context_disconnect(c); ++#endif ++ } else if (!PA_CONTEXT_IS_GOOD(state)) { ++ /// @todo Deal with reconnection... ++ //logMessage("Connection to PulseAudio lost"); ++ ++ // If this is our probe phase, exit our context immediately ++ if (s_context != c) ++ pa_context_disconnect(c); + } + } + #endif // HAVE_PULSEAUDIO +@@ -645,27 +651,67 @@ PulseSupport::PulseSupport() + + // To allow for easy debugging, give an easy way to disable this pulseaudio check + QString pulseenv = qgetenv("PHONON_PULSEAUDIO_DISABLE"); +- if (pulseenv.toInt()) ++ if (pulseenv.toInt()) { ++ logMessage("PulseAudio support disabled: PHONON_PULSEAUDIO_DISABLE is set"); ++ return; ++ } ++ ++ // First of all conenct to PA via simple/blocking means and if that succeeds, ++ // use a fully async integrated mainloop method to connect and get proper support. ++ pa_mainloop *p_test_mainloop; ++ if (!(p_test_mainloop = pa_mainloop_new())) { ++ logMessage("PulseAudio support disabled: Unable to create mainloop"); ++ return; ++ } ++ ++ pa_context *p_test_context; ++ if (!(p_test_context = pa_context_new(pa_mainloop_get_api(p_test_mainloop), "libphonon-probe"))) { ++ logMessage("PulseAudio support disabled: Unable to create context"); ++ pa_mainloop_free(p_test_mainloop); ++ return; ++ } ++ ++ logMessage("Probing for PulseAudio..."); ++ // (cg) Convert to PA_CONTEXT_NOFLAGS when PulseAudio 0.9.19 is required ++ if (pa_context_connect(p_test_context, NULL, static_cast(0), NULL) < 0) { ++ logMessage(QString("PulseAudio support disabled: %1").arg(pa_strerror(pa_context_errno(p_test_context)))); ++ pa_context_disconnect(p_test_context); ++ pa_context_unref(p_test_context); ++ pa_mainloop_free(p_test_mainloop); + return; ++ } ++ ++ pa_context_set_state_callback(p_test_context, &context_state_callback, NULL); ++ for (;;) { ++ pa_mainloop_iterate(p_test_mainloop, 1, NULL); + ++ if (!PA_CONTEXT_IS_GOOD(pa_context_get_state(p_test_context))) { ++ logMessage("PulseAudio probe complete."); ++ break; ++ } ++ } ++ pa_context_disconnect(p_test_context); ++ pa_context_unref(p_test_context); ++ pa_mainloop_free(p_test_mainloop); ++ ++ if (!s_pulseActive) { ++ logMessage("PulseAudio support is not available."); ++ return; ++ } ++ ++ // If we're still here, PA is available. ++ logMessage("PulseAudio support enabled"); ++ ++ // Now we connect for real using a proper main loop that we can forget ++ // all about processing. + s_mainloop = pa_glib_mainloop_new(NULL); + Q_ASSERT(s_mainloop); + pa_mainloop_api *api = pa_glib_mainloop_get_api(s_mainloop); + +- // We create a simple event loop to allow the glib loop +- // to iterate until we've connected or not to the server. +- s_connectionEventloop = new QEventLoop; +- +- // XXX I don't want to show up in the client list. All I want to know is the list of sources +- // and sinks... + s_context = pa_context_new(api, "libphonon"); + // (cg) Convert to PA_CONTEXT_NOFLAGS when PulseAudio 0.9.19 is required +- 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 connection eventloop..."); +- s_connectionEventloop->exec(); +- } ++ if (pa_context_connect(s_context, NULL, static_cast(0), 0) >= 0) ++ pa_context_set_state_callback(s_context, &context_state_callback, NULL); + #endif + } + +@@ -681,11 +727,6 @@ PulseSupport::~PulseSupport() + pa_glib_mainloop_free(s_mainloop); + s_mainloop = NULL; + } +- +- if (s_connectionEventloop) { +- delete s_connectionEventloop; +- s_connectionEventloop = NULL; +- } + #endif + } + diff --git a/phonon.spec b/phonon.spec index 3237bbd..c70ed6d 100644 --- a/phonon.spec +++ b/phonon.spec @@ -4,12 +4,12 @@ Summary: Multimedia framework api Name: phonon Version: 4.4.0 -Release: 1%{?dist} +Release: 3%{?dist} Group: System Environment/Libraries License: LGPLv2+ URL: http://phonon.kde.org/ Source0: ftp://ftp.kde.org/pub/kde/stable/phonon/4.4.0/phonon-%{version}.tgz -#Source0: phonon-%{snap}.tar.bz2 +## FIXME: update to point to http://gitorious.org/phonon Source1: phonon_snapshot.sh BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -21,12 +21,6 @@ Source14: hi48-phonon-gstreamer.png Source15: hi64-phonon-gstreamer.png Source16: hi128-phonon-gstreamer.png -# Make PulseAudio the default when listed by the Xine backend and native -# PulseAudio integration is not available (e.g. F-11 with too old PulseAudio). -Patch0: phonon-4.3.80-pulseaudio-device-priorities.patch -# Give PulseAudio the highest priority in the Xine backend so the above works. -Patch1: phonon-4.3.50-xine_pulseaudio.patch - ## Mandriva/upstreamable patches Patch51: phonon-4.3.50-fix-decodebin-usage.patch Patch52: phonon-4.3.50-gstreamer-fix-seekable-query-failed.patch @@ -34,6 +28,8 @@ Patch53: phonon-4.3.50-phonon-allow-stop-empty-source.patch Patch57: phonon-4.3.80-pulse-devicemove-rejig.patch ## Upstream patches +# https://bugs.kde.org/show_bug.cgi?id=228324#c23 +Patch100: phonon-4.4.0-eventloop.patch BuildRequires: automoc4 >= 0.9.86 BuildRequires: cmake >= 2.6.0 @@ -46,14 +42,12 @@ BuildRequires: libxml2-devel BuildRequires: pkgconfig BuildRequires: qt4-devel BuildRequires: xine-lib-devel -%if 0%{?fedora} > 10 BuildRequires: pulseaudio-libs-devel >= 0.9.15 -%else -%define pa_keep_old_hacks 1 -%endif -Requires: phonon-backend%{?_isa} >= %{version} +%global pulseaudio_version %(pkg-config --modversion libpulse 2>/dev/null || echo 0.9.15) +Requires: phonon-backend%{?_isa} => %{version} +Requires: pulseaudio-libs%{?_isa} >= %{pulseaudio_version} Requires: qt4%{?_isa} >= %{_qt4_version} %description @@ -92,17 +86,13 @@ Provides: %{name}-backend-gst = %{version}-%{release} %prep %setup -q -n phonon%{!?snap:-%{?tar_ver}%{!?tar_ver:%{version}}} -%if 0%{?pa_keep_old_hacks} -# FIXME/adapt to 4.4, or drop -#patch0 -p1 -b .pulseaudio-device-priorities -#patch1 -p1 -b .xine_pulseaudio -%endif - %patch51 -p0 -b .fix-decodebin-usage %patch52 -p1 -b .gstreamer-fix-seekable-query-failed %patch53 -p1 -b .phonon-allow-stop-empty-source %patch57 -p1 -b .pulse-devicemove-rejig +%patch100 -p1 -b .eventloop + %build mkdir -p %{_target_platform} @@ -207,6 +197,12 @@ gtk-update-icon-cache %{_kde4_iconsdir}/hicolor &> /dev/null ||: %changelog +* Thu Apr 01 2010 Rex Dieter - 4.4.0-3 +- add minimal pulseaudio runtime dep + +* Wed Mar 17 2010 Rex Dieter - 4.4.0-2 +- pa glib/qt eventloop patch (kde#228324) + * Tue Mar 16 2010 Rex Dieter - 4.4.0-1 - phonon-4.4.0 final