diff options
Diffstat (limited to 'abs/core-testing/mplayer-wrapper/mplayer-wrapper.pl')
-rwxr-xr-x | abs/core-testing/mplayer-wrapper/mplayer-wrapper.pl | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/abs/core-testing/mplayer-wrapper/mplayer-wrapper.pl b/abs/core-testing/mplayer-wrapper/mplayer-wrapper.pl new file mode 100755 index 0000000..da0e838 --- /dev/null +++ b/abs/core-testing/mplayer-wrapper/mplayer-wrapper.pl @@ -0,0 +1,212 @@ +#!/usr/bin/perl + +use Shell; +use strict; +use POSIX qw(floor); + +# Written by Bob Igo from the MythTV Store at http://MythiC.TV +# including some original code and contributions from Nick C. +# and graysky. +# Email: bob@stormlogic.com +# +# If you run into problems with this script, please send me email + +# PURPOSE: +# -------------------------- +# This is a wrapper script that tries to find the best parameters +# for calling an underlying video player. The outer layer determines +# the best playback parameters, while the inner layer picks the best +# player to call. + +# RATIONALE: +# -------------------------- +# Default video playback options are not optimal on all hardware or +# for all video types. In addition, common video players do not +# offer to bookmark video so that you can resume where you left off. +# Both of these problems can be addressed by this wrapper. + +# PARAMETERS: +# -------------------------- +# The same parameters you'd use for mplayer, some of which may be +# translated automatically for use with smplayer. + +# FILES: +# -------------------------- +# $mediafile, the file to play + +sub run () { + my $mediafile = @ARGV[$#ARGV]; + my $player = &pick_player(); + + # mplayer evaluates configuration options in the following order, with + # later-evaluated options overriding earlier-evaluated ones, both within + # a given configuration location and between them: + # 1) system-wide configuration/profiles, /etc/mplayer/mplayer.conf + # 2) user-specific configuration/profiles, ~/.mplayer/config + # 3) commandline configuration parameters + # 4) file-specific configuration, ~/.mplayer/[filename].conf + # 5) any nonstandard configuration file, included via "-include" parameter + # + # This script's dynamic configuration options fall in at 2.5 above, + # so commandline options, file-specific configuration options, + # or a nonstandard configuration file will override the options that + # the script creates, but system-wide and user-specific configuration + # will be overridden by the dynamic configuration options. + # + # This is sub-optimal, as the easiest way for a user to compensate for + # a misfiring configuration rule would be to override it in a configuration + # file. Instead, they will have to change the way they run this script. + + my $player_parameters = join(' ', + &dynamic_parameters($mediafile), + &translate_parameters($player,@ARGV[0..$#ARGV-1])); + &player($player,$player_parameters,$mediafile); +} + +&run(); + +# Translates any parameters into ones that will be compatible with the given player. +sub translate_parameters() { + my($player,@parameters)=@_; + + if ($player eq "smplayer") { + # Stupidly, smplayer uses a different set of command-line parameters than generic + # mplayer, so we need to translate mplayer-centric ones into the few that are + # available in smplayer-ese. + my %smplayer_parameter_translation_array = ( + "-fs" => "-fullscreen", + "-zoom" => " " + ); + + sub translate() { + my($flag)=@_; + return $smplayer_parameter_translation_array{$flag}; + } + + return map(&translate($_), @parameters); + } else { + # currently, all other players used by this wrapper work with mplayer parameters + return @parameters; + } +} + +# Returns an array of dynamic parameters based on the media type, +# the presence of special playback decoding hardware, and the +# general capability of the CPU. +sub dynamic_parameters () { + my($mediafile)=@_; + my @parameters = (); + my $codec=""; + my %vdpau_supported_modes=(); + + # See if the GPU and driver support vdpau for GPU-based accelerated decoding + my $command="vdpinfo |"; + # On supported hardware, vdpinfo produces relevant results that look something like this (see + # http://www.phoronix.com/forums/showthread.php?t=14493 for additional details, or run + # vdpinfo on vdpau-capable hardware yourself): + # + #MPEG1 0 2 4096 4096 + #MPEG2_SIMPLE 3 2 4096 4096 + #MPEG2_MAIN 3 2 4096 4096 + #H264_MAIN 41 4 4096 4096 + #H264_HIGH 41 4 4096 4096 + + my $grabbing_modes=0; + open(SHELL, $command); + while (<SHELL>) { + chop; + if (m/Decoder Capabilities/gi) { + $grabbing_modes=1; + #print "*** MODES START NOW" + } elsif (m/Output Surface/gi) { + $grabbing_modes=0; + } elsif ($grabbing_modes) { + if (m/[A-Z]+[0-9]+/g) { + s/(_.*)//g; + #print "*** GRABBED MODE $_\n"; + $vdpau_supported_modes{$_} = 1; + } + } + } + close(SHELL); + + # figure out what codec the video uses + my $command="mplayer -identify -frames 0 \"$mediafile\" | grep ID_VIDEO_CODEC | cut -c 16- |"; + open(SHELL, $command); + while (<SHELL>) { + chop; + $codec = $_; + #print "DEBUG: codec is $codec\n"; + } + close(SHELL); + + # We should use vdpau if it's available and helps with the codec we need to decode. + if ($codec eq "ffh264") { # h.264 + if ($vdpau_supported_modes{"H264"}) { + push(@parameters, "-vo vdpau"); + push(@parameters, "-vc ffh264vdpau"); + } + } elsif ($codec eq "ffmpeg2") { # MPEG2 + if ($vdpau_supported_modes{"MPEG2"}) { + push(@parameters, "-vo vdpau"); + push(@parameters, "-vc ffmpeg12vdpau"); + } + + # ??? although MPEG1 is rare, it seems as if it should work with -vc ffmpeg12vdpau as well + + # problems have been reported with WMV3 support + +# } elsif ($codec eq "ffwmv3") { # WMV3 +# if ($vdpau_supported) { +# push(@parameters, "-vo vdpau"); +# push(@parameters, "-vc ffwmv3vdpau"); +# } + # problems have been reported with WVC1 support + +# } elsif ($codec eq "ffvc1") { # WVC1 +# if ($vdpau_supported) { +# push(@parameters, "-vo vdpau"); +# push(@parameters, "-vc ffvc1vdpau"); +# } + + } else { + push(@parameters, "-vo xv,x11,"); + push(@parameters, "-vc ,"); + push(@parameters, "-vf pp=lb,"); # doesn't actually work with vdpau, but doesn't break anything + } + return(@parameters); +} + +# Find the best player for use on this system. The script prefers smplayer, +# which has built-in bookmarking, falling back to mplayer-resumer.pl, which +# implements bookmarking as an mplayer wrapper, if smplayer cannot be found. +# Finally, if no bookmarking players can be found, a barebones mplayer is used. +sub pick_player () { + #my @possible_players = ("smplayer", "mplayer-resumer.pl", "mplayer"); + my @possible_players = ("mplayer-resumer.pl", "mplayer"); + my $command; + my $candidate_player; + foreach (@possible_players) { + $candidate_player = $_; + $command = "which $candidate_player |"; + open(SHELL, $command); + if (<SHELL>) { + #print "player $candidate_player : $_\n"; + return $candidate_player; + } + close(SHELL); + } +} + +# Calls player +sub player () { + my($player,$parameters,$mediafile)=@_; + my $command = "$player $parameters \"$mediafile\" 2>&1 |"; + + print "DEBUG: $0's player command is: *** $command ***\n"; + open(SHELL, $command); + while (<SHELL>) { + print $_; + } + close(SHELL); +} |