[kdemultimedia] kmix chewing up cpu and memory (#766678,kde#288675)

Rex Dieter rdieter at fedoraproject.org
Fri Dec 30 13:28:30 UTC 2011


commit 7d97dcb1745b42beb50d26346bf131a9989119cf
Author: Rex Dieter <rdieter at fedoraproject.org>
Date:   Fri Dec 30 07:28:27 2011 -0600

    kmix chewing up cpu and memory (#766678,kde#288675)

 kdemultimedia-4.7.95-kmix.patch |  355 +++++++++++++++++++++++++++++++++++++++
 kdemultimedia.spec              |    9 +-
 2 files changed, 363 insertions(+), 1 deletions(-)
---
diff --git a/kdemultimedia-4.7.95-kmix.patch b/kdemultimedia-4.7.95-kmix.patch
new file mode 100644
index 0000000..d0c328c
--- /dev/null
+++ b/kdemultimedia-4.7.95-kmix.patch
@@ -0,0 +1,355 @@
+Index: kmix/gui/mdwslider.h
+===================================================================
+--- kmix/gui/mdwslider.h	(revision 1270867)
++++ kmix/gui/mdwslider.h	(working copy)
+@@ -56,7 +56,7 @@
+ 	       bool includePlayback, bool includeCapture,
+ 	       bool small, Qt::Orientation,
+ 	       QWidget* parent, ViewBase* view, ProfControl *pctl);
+-    ~MDWSlider() { }
++    virtual ~MDWSlider();
+ 
+     enum LabelType { LT_ALL, LT_FIRST_CAPTURE, LT_NONE };
+     void addActionToPopup( KAction *action );
+Index: kmix/gui/viewbase.cpp
+===================================================================
+--- kmix/gui/viewbase.cpp	(revision 1270867)
++++ kmix/gui/viewbase.cpp	(working copy)
+@@ -128,13 +128,14 @@
+     // allow view to "polish" itself
+     constructionFinished();
+ 
+-   kDebug() << "CONNECT ViewBase count " << _mixers.size();
+-  foreach ( Mixer* mixer, _mixers )
+-  {
+-    kDebug(67100) << "CONNECT ViewBase controlschanged" << mixer->id(); 
+-   connect ( mixer, SIGNAL(controlChanged()), this, SLOT(refreshVolumeLevels()) );
+-   connect ( mixer, SIGNAL(controlsReconfigured(QString)), this, SLOT(controlsReconfigured(QString)) );
+-  }
++// Moved the following up one Level to KMixerWidget
++//   kDebug() << "CONNECT ViewBase count " << _mixers.size();
++//  foreach ( Mixer* mixer, _mixers )
++//  {
++//    kDebug(67100) << "CONNECT ViewBase controlschanged" << mixer->id();
++//   connect ( mixer, SIGNAL(controlChanged()), this, SLOT(refreshVolumeLevels()) );
++//   connect ( mixer, SIGNAL(controlsReconfigured(QString)), this, SLOT(controlsReconfigured(QString)) );
++//  }
+ 
+     
+ }
+@@ -217,10 +218,6 @@
+ 		setMixSet();
+ 		kDebug(67100) << "ViewBase::controlsReconfigured() " << mixer_ID << ": Recreating widgets (mixset contains: " << _mixSet->count() << ")";
+ 		createDeviceWidgets();
+-
+-		// We've done the low level stuff our selves but let elements
+-		// above know what has happened so they can reload config etc.
+-		emit redrawMixer(mixer_ID);
+ 	}
+ }
+ 
+Index: kmix/gui/kmixerwidget.h
+===================================================================
+--- kmix/gui/kmixerwidget.h	(revision 1270867)
++++ kmix/gui/kmixerwidget.h	(working copy)
+@@ -75,6 +75,10 @@
+    void saveConfig( KConfig *config );
+    void loadConfig( KConfig *config );
+ 
++  private slots:
++    void controlsReconfiguredToplevel(QString mixerId);
++    void refreshVolumeLevelsToplevel();
++
+   private:
+    Mixer *_mixer;
+    QVBoxLayout *m_topLayout; // contains TabWidget
+@@ -82,6 +86,7 @@
+    ProfTab* _tab;
+    std::vector<ViewBase*> _views;
+    KActionCollection* _actionCollection;  // -<- applciations wide action collection
++   QWidget* _mainWindow;
+ 
+    
+    void createLayout(ViewBase::ViewFlags vflags);
+Index: kmix/gui/mixdevicewidget.h
+===================================================================
+--- kmix/gui/mixdevicewidget.h	(revision 1270867)
++++ kmix/gui/mixdevicewidget.h	(working copy)
+@@ -47,7 +47,7 @@
+     MixDeviceWidget( MixDevice* md,
+                      bool small, Qt::Orientation orientation,
+                      QWidget* parent, ViewBase*, ProfControl * );
+-    ~MixDeviceWidget();
++    virtual ~MixDeviceWidget();
+ 
+     void addActionToPopup( KAction *action );
+ 
+Index: kmix/gui/mdwslider.cpp
+===================================================================
+--- kmix/gui/mdwslider.cpp	(revision 1270867)
++++ kmix/gui/mdwslider.cpp	(working copy)
+@@ -81,6 +81,17 @@
+     update();
+ }
+ 
++MDWSlider::~MDWSlider()
++{
++	foreach( QAbstractSlider* slider, m_slidersPlayback)
++	{
++		delete slider;
++	}
++	foreach( QAbstractSlider* slider, m_slidersCapture)
++	{
++		delete slider;
++	}
++}
+ 
+ void MDWSlider::createActions()
+ {
+Index: kmix/gui/viewsliders.cpp
+===================================================================
+--- kmix/gui/viewsliders.cpp	(revision 1270867)
++++ kmix/gui/viewsliders.cpp	(working copy)
+@@ -181,14 +181,15 @@
+         // The following for-loop could be simplified by using a std::find_if
+         for ( int i=0; i<mixset.count(); i++ ) {
+             MixDevice *md = mixset[i];
++
+             if ( md->id().contains(idRegexp) )
+             {
+                 // Match found (by name)
+                 if ( _mixSet->contains( md ) ) continue; // dup check
+ 
+                 // Now check whether subcontrols match
+-                bool subcontrolPlaybackWanted = (control->useSubcontrolPlayback() && md->playbackVolume().hasVolume());
+-                bool subcontrolCaptureWanted  = (control->useSubcontrolCapture()  && md->captureVolume().hasVolume());
++                bool subcontrolPlaybackWanted = (control->useSubcontrolPlayback() && ( md->playbackVolume().hasVolume() || md->playbackVolume().hasSwitch()) );
++                bool subcontrolCaptureWanted  = (control->useSubcontrolCapture()  && ( md->captureVolume() .hasVolume() || md->captureVolume() .hasSwitch()) );
+                 bool subcontrolEnumWanted  = (control->useSubcontrolEnum() && md->isEnum());
+                 bool subcontrolWanted =  subcontrolPlaybackWanted | subcontrolCaptureWanted | subcontrolEnumWanted;
+ 		bool splitWanted = control->isSplit();
+Index: kmix/gui/kmixerwidget.cpp
+===================================================================
+--- kmix/gui/kmixerwidget.cpp	(revision 1270867)
++++ kmix/gui/kmixerwidget.cpp	(working copy)
+@@ -37,6 +37,7 @@
+ #include <ktabwidget.h>
+ 
+ // KMix
++#include "apps/kmix.h"
+ #include "gui/guiprofile.h"
+ #include "gui/kmixerwidget.h"
+ #include "gui/kmixtoolbox.h"
+@@ -58,6 +59,8 @@
+      m_topLayout(0), _guiprof(guiprof),
+      _actionCollection(actionCollection)
+ {
++	_mainWindow = parent;
++	//kDebug() << "kmixWindow created: parent=" << parent << ", parentWidget()=" << parentWidget();
+    if ( _mixer )
+    {
+       createLayout(vflags);
+@@ -169,13 +172,42 @@
+       connect( vbase, SIGNAL(toggleMenuBar()), parentWidget(), SLOT(toggleMenuBar()) );
+       // *this will be deleted on rebuildGUI(), so lets queue the signal
+       connect( vbase, SIGNAL(rebuildGUI())   , parentWidget(), SLOT(recreateGUIwithSavingView()), Qt::QueuedConnection );
+-      connect( vbase, SIGNAL(redrawMixer(QString)), parentWidget(), SLOT(redrawMixer(QString)), Qt::QueuedConnection );
++      //connect( vbase, SIGNAL(redrawMixer(QString)), parentWidget(), SLOT(redrawMixer(QString)), Qt::QueuedConnection );
++
++      kDebug() << "CONNECT ViewBase count " << vbase->getMixers().size();
++	  foreach ( Mixer* mixer, vbase->getMixers() )
++	  {
++	    kDebug(67100) << "CONNECT ViewBase controlschanged" << mixer->id();
++	   connect ( mixer, SIGNAL(controlChanged()), this, SLOT(refreshVolumeLevelsToplevel()) );
++	   connect ( mixer, SIGNAL(controlsReconfigured(QString)), this, SLOT(controlsReconfiguredToplevel(QString)) );
++	  }
+       return true;
+    }
+ }
+ 
++void KMixerWidget::controlsReconfiguredToplevel(QString mixerId)
++{
++	foreach ( ViewBase* vbase, _views)
++	{
++		vbase->controlsReconfigured(mixerId);
++	}
++	KMixWindow* kmixWindow = qobject_cast<KMixWindow*>(_mainWindow);
++	kDebug() << "kmixWindow to redraw: " << kmixWindow << ", not-casted=" << _mainWindow;
++	if (kmixWindow != 0)
++	{
++		kmixWindow->redrawMixer(mixerId);
++	}
++}
+ 
++void KMixerWidget::refreshVolumeLevelsToplevel()
++{
++	foreach ( ViewBase* vbase, _views)
++	{
++		vbase->refreshVolumeLevels();
++	}
++}
+ 
++
+ /**
+  * Returns the current View. Normally we have only one View, so we always return the first view.
+  * This method is only here for one reason: We can plug in an action in the main menu, so that
+Index: kmix/gui/viewbase.h
+===================================================================
+--- kmix/gui/viewbase.h	(revision 1270867)
++++ kmix/gui/viewbase.h	(working copy)
+@@ -114,6 +114,8 @@
+    GUIProfile* guiProfile() { return _guiprof; };
+    KActionCollection* actionCollection() { return _actions; };
+ 
++   QSet<Mixer*>& getMixers() { return _mixers; };
++
+     /**
+      * Contains the widgets for the _mixSet. There is a 1:1 relationship, which means:
+      * _mdws[i] is the Widget for the MixDevice _mixSet[i] - please see ViewBase::createDeviceWidgets().
+@@ -124,7 +126,7 @@
+ 
+ signals:
+     void rebuildGUI();
+-    void redrawMixer( const QString& mixer_ID );
++    //void redrawMixer( const QString& mixer_ID );
+ 
+ 
+ protected:
+Index: kmix/TestCases
+===================================================================
+--- kmix/TestCases	(revision 1270867)
++++ kmix/TestCases	(working copy)
+@@ -13,6 +13,8 @@
+ 10: Basic: KMix KControl module
+ 11: kmixctrl --restore  (with existing .kmixctrlrc) must restore volumes
+ 12: kmixctrl --restore  (without existing .kmixctrlrc) must NOT change volumes
++13: "Switch-only" controls are available and work (e.g: IEC958': Capabilities: pswitch pswitch-joined cswitch cswitch-joined)
++ 
+ 
+ 
+ -----------+----+----+----+----+----+----+----+----+----+----+----+----+
+Index: kmix/apps/kmix.cpp
+===================================================================
+--- kmix/apps/kmix.cpp	(revision 1270867)
++++ kmix/apps/kmix.cpp	(working copy)
+@@ -782,11 +782,11 @@
+     if ( kmw ) {
+         kmw->saveConfig( KGlobal::config().data() );  // -<- This alone is not enough, as I need to save the META information as well. Thus use saveViewConfig() below
+         m_wsMixers->removeTab(idx);
+-        delete kmw;
++        m_wsMixers->setTabsClosable(!kmw->mixer()->isDynamic() && m_wsMixers->count() > 1); // This does not work properly in (experimental) multi-driver-mode
+ 
+-        m_wsMixers->setTabsClosable(!kmw->mixer()->isDynamic() && m_wsMixers->count() > 1);
++        saveViewConfig();
+ 
+-        saveViewConfig();
++        delete kmw;
+     }
+     kDebug() << "Exit";
+ }
+Index: kmix/backends/mixer_alsa9.cpp
+===================================================================
+--- kmix/backends/mixer_alsa9.cpp	(revision 1270867)
++++ kmix/backends/mixer_alsa9.cpp	(working copy)
+@@ -162,11 +162,6 @@
+ 
+         MixDevice::ChannelType ct = (MixDevice::ChannelType)identify( sid );
+ 
+-        m_id2numHash[mdID] = idx;
+-        //kDebug() << "m_id2numHash[mdID] mdID=" << mdID << " idx=" << idx;
+-        mixer_elem_list.append( elem );
+-        mixer_sid_list.append( sid );
+-        idx++;
+         /* ------------------------------------------------------------------------------- */
+ 
+         Volume* volPlay    = 0;
+@@ -177,37 +172,47 @@
+             // --- Enumerated ---
+             addEnumerated(elem, enumList);
+         }
+-		volPlay    = addVolume(elem, false);
+-        volCapture = addVolume(elem, true );
++        else
++        {
++			volPlay    = addVolume(elem, false);
++			volCapture = addVolume(elem, true );
++        }
+ 
+ 
+         QString readableName;
+         readableName = snd_mixer_selem_id_get_name( sid );
+-//        if ( readableName == "Front")
+-//        {
+-//        	qDebug("Front!");
+-//        }
+-
+-        int idx = snd_mixer_selem_id_get_index( sid );
+-        if ( idx > 0 ) {
++        int controlInstanceIndex = snd_mixer_selem_id_get_index( sid );
++        if ( controlInstanceIndex > 0 ) {
+             // Add a number to the control name, like "PCM 2", when the index is > 0
+             QString idxString;
+-            idxString.setNum(1+idx);
++            idxString.setNum(1+controlInstanceIndex);
+             readableName += " ";
+             readableName += idxString;
+         }
+-        MixDevice* md = new MixDevice(_mixer, mdID, readableName, ct );
+-        bool hasVolume = volPlay != 0 || volCapture != 0;
+-        bool hasEnum   = enumList.count() > 0;
+ 
+-        // If we have sliders and an enum, KMix needs two MixDevice instances (a MixDevice is EITHER a VolumeControl OR an ENUM, but never both)
+-        MixDevice* mdForEnum = ( hasVolume && hasEnum )
+-        		             ? new MixDevice(_mixer,mdID + ".enum", readableName,ct)  // For identifying/saving it needs a distinct ID. We add a ".enum"
+-        					 : md;   // It is a simple ENUM (no volume control)
++		// There can be an Enum-Control with the same name as a regular control. So we append a ".[cp]enum" prefix to always create a unique ID
++        QString finalMixdeviceID = mdID;
++        if ( ! enumList.isEmpty() )
++        {
++        	if (snd_mixer_selem_is_enum_capture ( elem ) )
++        		finalMixdeviceID = mdID + ".cenum"; // capture enum
++        	else
++        		finalMixdeviceID = mdID + ".penum"; // playback enum
++        }
++        if ( true || readableName.startsWith("Input Source") ) kDebug() << "Input Source! id=" << finalMixdeviceID << "readableName=" << readableName << ", idx=" << idx;
+ 
++        m_id2numHash[finalMixdeviceID] = idx;
++        //kDebug() << "m_id2numHash[mdID] mdID=" << mdID << " idx=" << idx;
++        mixer_elem_list.append( elem );
++        mixer_sid_list.append( sid );
++        idx++;
++
++
++        MixDevice* md = new MixDevice(_mixer, finalMixdeviceID, readableName, ct );
++
+         if ( volPlay    != 0      ) md->addPlaybackVolume(*volPlay);
+         if ( volCapture != 0      ) md->addCaptureVolume (*volCapture);
+-       	if ( hasEnum              ) mdForEnum->addEnums(enumList);
++       	if ( !enumList.isEmpty()  ) md->addEnums(enumList);
+          
+         m_mixDevices.append( md );
+          
+@@ -653,13 +658,17 @@
+     //kDebug() << "Mixer_ALSA::setEnumIdHW() id=" << id << " , idx=" << idx << ") 1\n";
+     int devnum = id2num(id);
+     snd_mixer_elem_t *elem = getMixerElem( devnum );
+-    int ret = snd_mixer_selem_set_enum_item(elem,SND_MIXER_SCHN_FRONT_LEFT,idx);
+-    if (ret < 0) {
+-        kError() << "Mixer_ALSA::setEnumIdHW(" << devnum << "), errno=" << ret << "\n";
+-    }
+-    snd_mixer_selem_set_enum_item(elem,SND_MIXER_SCHN_FRONT_RIGHT,idx);
+-    // we don't care about possible error codes on channel 1
+ 
++    for (int i = 0; i <= SND_MIXER_SCHN_LAST; ++i)
++    {
++		int ret = snd_mixer_selem_set_enum_item(elem, (snd_mixer_selem_channel_id_t)i,idx);
++		if (ret < 0 && i == 0)
++		{
++			// Log errors only for one channel. This should be enough, and another reason is that I also do not check which channels are supported at all.
++			kError() << "Mixer_ALSA::setEnumIdHW(" << devnum << "), errno=" << ret << "\n";
++		}
++	}
++
+     return;
+ }
+ 
diff --git a/kdemultimedia.spec b/kdemultimedia.spec
index 0c690ea..d06d545 100644
--- a/kdemultimedia.spec
+++ b/kdemultimedia.spec
@@ -6,7 +6,7 @@
 Name:    kdemultimedia
 Epoch:   6
 Version: 4.7.95
-Release: 1%{?dist}
+Release: 2%{?dist}
 Summary: KDE Multimedia applications
 
 Group:   Applications/Multimedia
@@ -19,6 +19,8 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 Patch1: kdemultimedia-4.6.2-no_thumbs.patch 
 
 ## upstream patches
+# fix cpu/mem issue, https://bugs.kde.org/show_bug.cgi?id=288675
+Patch100: kdemultimedia-4.7.95-kmix.patch
 
 BuildRequires: cdparanoia-devel cdparanoia
 BuildRequires: kdepimlibs-devel >= %{version}
@@ -133,6 +135,8 @@ Requires: %{name}-kio_audiocd = %{?epoch:%{epoch}:}%{version}-%{release}
 # no mplayerthumbs/ffmpegthumbs
 %patch1 -p1 -b .no_thumbs
 
+%patch100 -p0 -b .kmix
+
 
 %build
 
@@ -323,6 +327,9 @@ fi
 
 
 %changelog
+* Fri Dec 30 2011 Rex Dieter <rdieter at fedoraproject.org> 6:4.7.95-2
+- kmix chewing up cpu and memory (#766678,kde#288675)
+
 * Wed Dec 21 2011 Radek Novacek <rnovacek at redhat.com> - 6:4.7.95-1
 - 4.7.95
 


More information about the scm-commits mailing list