Projects
Multimedia
dvswitch-git
dvsource-firewire2switch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File dvsource-firewire2switch of Package dvswitch-git
#! /usr/bin/perl -w # # Copyright: # # Copyright (C) 2011-2013, SUSE Linux Products GmbH # Author: Martin Caj <mcaj@suse.cz> # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of the Novell nor the names of its contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # # About the script: # # The idea was from the script dvsource-firewire_jw.pl by jw@suse.de. # dvsource-firewire_jw.pl -- a rewrite of the firewire grabber. # The original dvsource-firewire suffers from the following issues: # (C) 2012, jw@suse.de, distribute under GPL-2.0+ or ask. # ############# ## Requires: dvgrab and perl modules bellow # # How it is working ? # 1. It check your FW device and valid devices save into array @good. # 2. Run dv-switch GUI app. # 3. for each FW device it run dvsource-firewire with uniqe GUID # # TODO: # Add -c option - sometime childern are not properrly exited so # we need function to kill all dv* apps, or maybe reload FW kernel # modules. # # -s :save file to the created dir does`n work at the moment. We # need to spilt var $opts{s} . # -r :option currently is we use it it does`nt kill chldern process # when GUI is gone. # (C) SUSE 2013, mcaj@suse.cz, distribute under GPL-2.0+ use strict; use warnings; #use Data::Dumper; use File::stat; use File::Glob; #use Getopt::Long qw(:config no_ignore_case); use Getopt::Std; use POSIX ":sys_wait_h"; my $version = '0.3'; # Parameter my %opts; getopts('s:vrhH:P:tl:', \%opts) or usage(); if ($opts{h} || !$opts{s}) { usage(); } # Do we need them ? my $a_chan = undef; my $a_name = undef; # for the stream are need it: my $retry_connect = 0; my $host = undef; my $port = undef; my $tally = undef; my $dvswitch='/usr/bin/dvswitch'; #path to dvswitch my $dvsink='/usr/bin/dvsink-files'; #path to dvsink-files #my $cmd = '/usr/bin/dvsource-dvgrab'; my $cmd = '/usr/bin/dvsource-firewire'; #path to dvsource-firewire $cmd .= " --tally" if ($opts{t}); $cmd .= " -v" if ($opts{v}); $cmd .= ' --retry' if ($opts{r}); $cmd .= " --port=$opts{P}" if ($opts{P}); $cmd .= " --host=$opts{H}" if ($opts{H}); my $dvgrab = 'dvgrab'; my $dvgrab_opts = '-noavc'; my $ignore_missing_units = 0; my $devices = 0; # devices start on Zero my @good; # array for founded FW dev. my $good; my @children; # Store connections to them my $children; my %children; my $fwpid; my $help = undef; sub get_ps(); sub run_grab; sub search_dev; sub usage { print "Usage: dvsource-firewire2switch [OPTION] -s [SAVE TO FILE] -l [LOG FILE] \n"; print "************************************************************************ \n"; print "The script check all avaible FW devices on the machine and start dvsource.\n"; print "It using fork to run them separetly.Dead devices (without guid) are skipped.\n"; print "Devices that are in use (guid appears in /proc/*/cmdline) are also skipped."; print "the options -s is mandatory !\n\n"; print "Valid options are:\n"; print "\t -s : path there video data are store. this options is mandatory \n"; print "\t -v : verbose mode print more information at startup.\n"; print "\t -r : keep retrying to connect, in case DVswitch is not yet listening. -not Working yet!\n"; print "\t -H : send dvsource to remote HOST -not Working yet!\n"; print "\t -P : the port to remote HOST -not Working yet!\n"; # Not working yet: # Specify the network address on which DVswitch is listening. The # host address may be specified by name or as an IPv4 or IPv6 literal. print "\t -t :tally mode Print notices of activation and deactivation in the mixer \n"; # , for use with a tally light. These will take the form "TALLY: on" or "TALLY: off". print "\t -l :path to log file, if it not present all messages go to STDOUT \n\n"; print "version: $version \n"; print "In case of trouble please send me bug report to mcaj\@suse.cz \n"; exit 1; } #Run part: # search FW device and store them in @good: search_dev; my $max_procs=$#good ; # How many children we'll create -1 $max_procs++; #add one becasue is start at 0 # run save video: # This need to be add if dir exist. # and file name needs date stemps too. # check if dir does not exist yet: if (-d $opts{s}) { print STDERR "Info: directory $opts{s} alredy exist \n" if ($opts{v}); } else { print STDERR "Info: creating directory $opts{s} \n" if ($opts{v}); unless(mkdir $opts{s}) { die "Error: Unable to create $opts{s}\n"; } } $opts{s} .="-%F-%T"; #add timestemp $dvsink .=" $opts{s}"; # $dvsink .= ' --retry' if ($opts{r}); do not use it at the moment, # otherwise process can not be killed record ($dvsink); # run dvswitch app $dvswitch .=">/dev/null 2>&1 &"; #run it in beckground with no output run_command ($dvswitch); print "Slow down the script. \n" ; sleep 5; # In this cycle parent will make as many childern as # FW devices system has. There is also 2 sec. slees time after # FW stream start. print STDERR " Info: $max_procs FW devices found on the machine \n" if ($opts{v}); print "********************************************************* \n"; foreach $good (@good ) { $fwpid = fork(); die "cannot fork" unless defined $fwpid; if ($fwpid == 0) { $children{$fwpid}=1; print STDERR "Working on the device:$devices: \n" if ($opts{v}); print "Starting dev/$good[$devices][0] guid=$good[$devices][1]\n \n"; run_grab ( $devices ); sleep 2; print STDERR "Info: this child is going to exit now \n" if ($opts{v}); exit 0; } else { print STDERR "The parent $fwpid match, and will live \n" if ($opts{v}); $devices++; print "Devices count was increase up to : $devices " if ($opts{v}); } # check is FW is still streaming ?: } exit 0; ##################################################### ################################### # wait for end children functions: ################################### $SIG{CHLD} = sub { print "Runnig $SIG{CHLD} \n"; # don't change $! and $? outside handler local ($!, $?); $fwpid = waitpid(-1, WNOHANG); return if $fwpid == -1; return unless defined $children{$fwpid}; print "children pid: $children{$fwpid} \n"; delete $children{$fwpid}; print "cleanup_child($fwpid, $?)"; cleanup_child($fwpid, $?); }; sub record ############################################################################# #On the storage machine (usually the mixer itself) via bash it was loop: # sh -c 'while true; do dvsink-files /tmp/dvswitch/test-%F-%T; sleep 2; done' ############################################################################## { ($dvsink) = @_; my $savepid = fork(); die "cannot fork" unless defined $savepid; if ($savepid == 0) { $children{$savepid}=1; sleep 4; print "Starting the infinite save-loop for video now \n"; while(1) { # The infinite loop my $k = (`ps fax|grep /usr/bin/dvswitch | grep -v "ps fax" |grep -v grep|cut -d " " -f1`); last if !$k; # exit from the infinite loop after GUI is gone print "Info: GUI $dvswitch is still running with PID:$k \n" if ($opts{v}); run_command ($dvsink); sleep 2 ; } print STDERR "Info: the infinite save-loop is going to exit now \n" if ($opts{v}); exit 0; } else { print STDERR "The parent $savepid match, and will live \n" if ($opts{v}); } return 0; } sub run_command ###################################### # send STDOUT & STDERR from system to # : log file # : STDOUT # : dev/null ###################################### { my ($run_system ) = @_; if ($opts{l}) { system ("$run_system &>>$opts{l} ") and die "Error start $run_system"; }elsif ($opts{v}) { system ("$run_system ") and die "Error start $run_system"; } else { system ("$run_system >/dev/null 2>&1 ") and die "Error start $run_system"; } return 0; } sub search_dev ##################################################### # searching for "good" device with valid units ID: ##################################################### { opendir DIR, "/sys/bus/firewire/devices/" or die "no /sys/bus/firewire/devices/: $!"; my @fw = grep { !/^\./ } readdir DIR; closedir DIR; my %fw = map { $_ => { guid => undef } } @fw; print STDERR "Founded FW devices @fw \n" if ($opts{v}); for my $fw (sort @fw) { if (open IN, '<', "/sys/bus/firewire/devices/$fw/guid") { print STDERR "Working on /sys/bus/firewire/devices/$fw/guid \n" if ($opts{v}); my $guid = <IN> || ''; chomp $guid; $fw{$fw}{guid} = $guid; close IN; if (open IN, '<', "/sys/bus/firewire/devices/$fw/units") { # expect 0x00a02d:0x010001 my $units = <IN> || ''; chomp $units; $fw{$fw}{units} = $units; close IN; $units = '0x0:0x0' if $ignore_missing_units; if (($guid =~ m{^0x[\da-f]*[1-9a-f][\da-f]*$}) and ($units =~ m{^0x[\da-f]+:0x[\da-f]+$})) { push @good, [$fw, $guid]; #print STDERR "variable good-0-1 is $good[0][1] \n" if ($opts{v}); #print STDERR "variable good-* is @good scalar: "if ($opts{v}); #print scalar @good if ($opts{v}); #print " \n device is: $good[0][0] \n"; print STDERR "Usable devices: /dev/$fw guid=$guid with units: $units\n" if ($opts{v}); } else { print STDERR "Device : $fw has guid=$guid with empty units: $units\n" if ($opts{v}); } } } } return @good; } ##################################################### # This function run grab command for fw device ##################################################### sub run_grab { my $all_commands = join("\n", get_ps()); my ($devices ) = @_; # This part need to be check : while (@good && $all_commands =~ m{\b$good[$devices][1]\b}) { print STDERR "Already in use: /dev/$good([$devices][0]) guid=$good([$devices][1])\n" if ($opts{v}); # $fw{$good[$devices][0]}{in_use} = 1; # shift @good; } #die "No usable devices: " . Dumper \%fw unless scalar @good; $cmd .= " -g '$good[$devices][1]'"; # Run bin go background: print STDERR "Running command $cmd to background now: \n" if ($opts{v}) ; run_command ($cmd); return 0; } ##################################################### # This function run ps only ##################################################### sub get_ps() { my @r = (); opendir DIR, "/proc/" or return @r; my @pids = grep { /^\d+$/ } readdir DIR; closedir DIR; for my $pid (@pids) { if (open IN, "<", "/proc/$pid/cmdline") { my $cmdline = <IN> || ''; chomp $cmdline; push @r, $cmdline; } } return @r; }
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.