aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2011-06-17 19:48:04 (GMT)
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-06-17 19:48:04 (GMT)
commit16cf0606fd59484236356e400a89c083e76da64b (patch)
treefd320811c9af66449fc480f01771357e1adc1f6d
parent6378f138c5f3bd78ca209af42551b5aeef643b17 (diff)
rmmod.pl: Add a logic to allow removing audio modules with pulseaudio
Pulseaudio keeps audio devices opened forever. In order to be able to remove a device, pulseaudio needs to de-allocate the device. Unfortunately, pulseaudio recognizes alsa drivers as "module" (an integer number, not related to the device nodename), and only allows module removal if running with user matches the console owner. The logic inside rmmod.pl will now take the above into account. So, it will detect if pulseaudio is running. If it is, it will: 1) list the pulseaudio modules with "pacmd list-sinks" and "pacmd list-sources" 2) detect if any of the modules there is provided by a v4l device; 3) If they're provided by a video device, it removes the module with: pactl unload-module 26 Even the above logic is not perfect as, due to a pulseaudio libs bug, pulseaudio can't detect the name of em28xx-alsa driver, as it uses the same interface as the video node. Similar hacks will may be needed for other USB devices, like tm6000 and cx231xx. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rwxr-xr-xbuild.sh2
-rwxr-xr-xv4l/scripts/rmmod.pl71
2 files changed, 71 insertions, 2 deletions
diff --git a/build.sh b/build.sh
index 60d0c26..3cc21f8 100755
--- a/build.sh
+++ b/build.sh
@@ -12,6 +12,8 @@ echo "Checking if the needed tools are present"
run ./check_needs.pl
echo "Checking for Digest::SHA1 (package perl-Digest-SHA1)"
run perl -MDigest::SHA1 -e 1
+echo "Checking for Proc::ProcessTable (package perl-Proc-ProcessTable)"
+run perl -MProc::ProcessTable -e 1
echo
echo "************************************************************"
echo "* This script will download the latest tarball and build it*"
diff --git a/v4l/scripts/rmmod.pl b/v4l/scripts/rmmod.pl
index ed79cbe..53ea451 100755
--- a/v4l/scripts/rmmod.pl
+++ b/v4l/scripts/rmmod.pl
@@ -1,6 +1,8 @@
#!/usr/bin/perl
use strict;
use File::Find;
+use Proc::ProcessTable;
+
my %depend = ();
my %depend2 = ();
@@ -166,6 +168,69 @@ sub insmod ($)
}
}
+my @pulse;
+my $try_pulseaudio = 1;
+
+sub check_pulseaudio()
+{
+ my $t = new Proc::ProcessTable;
+ foreach my $p ( @{$t->table} ) {
+ push @pulse, $p->uid if ($p->cmndline =~m,/pulseaudio ,);
+ }
+ $try_pulseaudio = 0 if (!@pulse);
+
+ print "Pulseaudio is running with UUID(s): @pulse\n";
+}
+
+sub unload_pulseaudio($)
+{
+ my $driver_name = shift;
+ my $cur_module;
+
+ return if (!$try_pulseaudio);
+
+ check_pulseaudio() if (!@pulse);
+ return if (!$try_pulseaudio);
+
+ for my $pid (@pulse) {
+# printf "LANG=C sudo -u \\\#$pid pacmd list-sources |\n";
+ open IN, "LANG=C sudo -u \\\#$pid pacmd list-sources |";
+ while (<IN>) {
+ $cur_module = $1 if (/^\s*module:\s*(\d+)/);
+
+ if (/^\s*alsa.driver_name\s*=\s*"(.*)"/) {
+ if ($1 eq $driver_name) {
+ print "LANG=C sudo -u \\#$pid pactl unload-module $cur_module\n";
+ system ("LANG=C sudo -u \\#$pid pactl unload-module $cur_module");
+ }
+ next;
+ }
+
+ # Special case: em28xx sometimes use a Vendor Class at
+ # the same interface as the video node. Pulseaudio can't
+ # get the driver name in this case
+ if (/^\s*alsa.card_name\s*=\s*"Em28xx/) {
+ print "LANG=C sudo -u \\#$pid pactl unload-module $cur_module\n";
+ system ("LANG=C sudo -u \\#$pid pactl unload-module $cur_module");
+ }
+ }
+ close IN;
+
+# printf "LANG=C sudo -u \\\#$pid pacmd list-sinks |\n";
+ open IN, "LANG=C sudo -u \\#$pid pacmd list-sinks |" or return;
+ while (<IN>) {
+ $cur_module = $1 if (/^\s*module:\s*(\d+)/);
+ if (/^\s*alsa.driver_name\s*=\s*"(.*)"/) {
+ if ($1 eq $driver_name) {
+ print "LANG=C sudo -u \\#$pid pactl unload-module $1\n";
+ system ("LANG=C sudo -u \\#$pid pactl unload-module $1");
+ }
+ }
+ }
+ }
+ close IN;
+}
+
sub rmmod(@)
{
my $rmmod = findprog('rmmod');
@@ -173,8 +238,10 @@ sub rmmod(@)
foreach (reverse @_) {
s/-/_/g;
if (exists ($loaded{$_})) {
- print "$rmmod $_\n";
- unshift @not, $_ if (system "$rmmod $_");
+ my $module = $_;
+ print "$rmmod $module\n";
+ unload_pulseaudio($module);
+ unshift @not, $module if (system "$rmmod $module");
}
}
return @not;

Privacy Policy