The pic2mpg script of the 'pictures' plugin now generates HD images

This commit is contained in:
Klaus Schmidinger 2011-08-14 13:50:26 +02:00
parent 5e2f8e7613
commit c13d6e6070
5 changed files with 225 additions and 68 deletions

View File

@ -2153,6 +2153,7 @@ Andr
recording if Setup.UseDolbyDigital is true
for suggesting that the primary device should only be avoided for recording if
it is an old SD full featured card
for his support in using convert/ffmpeg in the pic2mpg script of the 'pictures' plugin
Jürgen Schilling <juergen_schilling@web.de>
for reporting that color buttons were displayed in the recording info menu if it

View File

@ -6650,7 +6650,7 @@ Video Disk Recorder Revision History
- Added support for "content identifier descriptor" and "default authority descriptor"
to 'libsi' (thanks to Dave Pickles).
2011-08-13: Version 1.7.20
2011-08-14: Version 1.7.20
- Added some missing 'const' to tChannelID (reported by Sundararaj Reel).
- The isnumber() function now checks the given pointer for NULL (thanks to Holger
@ -6683,3 +6683,6 @@ Video Disk Recorder Revision History
by a call to cIndexFile::GetLength() (suggested by Christoph Haubrich).
- Fixed some crashes in subtitle display (thanks to Rolf Ahrenberg).
- Made DELETENULL() thread safe (reported by Rolf Ahrenberg).
- The pic2mpg script of the 'pictures' plugin now generates HD images (thanks to
Andre Weidemann for his support in using convert/ffmpeg). The old SD version is
still available as pic2mpg-sd.

View File

@ -49,3 +49,9 @@ VDR Plugin 'pictures' Revision History
2011-07-23:
- Now rotating images according to the EXIF 'Orientation' parameter.
2011-08-14:
- The pic2mpg script now generates HD images (thanks to Andre Weidemann for his
support in using convert/ffmpeg). The old SD version is still available as
pic2mpg-sd.

View File

@ -7,63 +7,45 @@
#
# See the README file for copyright information and how to reach the author.
#
# $Id: pic2mpg 2.1 2011/07/23 14:23:59 kls Exp $
## TODO implement HDTV (1920 x 1080)
# $Id: pic2mpg 2.2 2011/08/14 13:34:15 kls Exp $
use File::Path;
use File::Spec;
use Getopt::Std;
use Image::ExifTool qw(:Public);
use Image::Size;
$Usage = qq{
Usage: $0 [options] picture-dir mpeg-dir
$0 [options] picture-file mpeg-file
Options: -a Aspect ratio 4:3 (default is 16:9)
-f Force conversion
Options: -f Force conversion
-h print Help
-i Ignore unknown file types
-n NTSC (default is PAL)
-s size Screen size (WIDTHxHEIGHT, default is 1920x1080)
-v num Verbose (0=none, 1=list files, 2=detailed)
-x percent X overscan in percent
-y percent Y overscan in percent
};
getopts("afhinv:x:y:") || die $Usage;
getopts("fhs:v:") || die $Usage;
die $Usage if $opt_h;
$Aspect = $opt_a;
$Force = $opt_f;
$Ignore = $opt_i;
$NTSC = $opt_n;
$Size = $opt_s || "1920x1080";
$Verbose = $opt_v;
$OverscanX = $opt_x;
$OverscanY = $opt_y;
$ListFiles = $Verbose >= 1;
$Detailed = $Verbose >= 2;
# Screen size:
# Supported picture types:
$SW = $NTSC ? 720 : 720;
$SH = $NTSC ? 480 : 576;
$ScreenRatio = $Aspect ? 4 / 3 : 16 / 9;
# Converter programs:
%PNMCONV = (
bmp => "bmptopnm",
gif => "giftopnm",
jpeg => "jpegtopnm",
jpg => "jpegtopnm",
png => "pngtopnm",
pnm => "cat",
tif => "tifftopnm",
tiff => "tifftopnm",
%PICTYPES = (
bmp => 1,
gif => 1,
jpeg => 1,
jpg => 1,
png => 1,
pnm => 1,
tif => 1,
tiff => 1,
);
# Command options:
@ -72,13 +54,6 @@ die "$0: missing parameter\n" unless $ARGV[0] && $ARGV[1];
die "$0: file or directory not found: $ARGV[0]\n" unless -e $ARGV[0];
die "$0: source and destination must be different\n" if $ARGV[0] eq $ARGV[1];
$verbose1 = $Detailed ? "--verbose" : "";
$verbose2 = $Detailed ? "-v 2" : "-v 0";
$system1 = $NTSC ? "" : "--pal";
$system2 = $NTSC ? "n" : "p";
$framerate = $NTSC ? "30000:1001" : "25:1";
$aspect = $Aspect ? "2" : "3";
# Convert a single file:
if (-f $ARGV[0]) {
@ -96,7 +71,7 @@ $MPGDIR = File::Spec->rel2abs($ARGV[1]);
chdir($PICDIR) || die "$PICDIR: $!\n";
@Pictures = `find -type f`;
@Pictures = `find -type f | sort`;
chomp(@Pictures);
for $pic (@Pictures) {
@ -146,39 +121,18 @@ sub ConvertFile
{
my ($Pict, $Mpeg) = @_;
(my $Type) = lc($Pict) =~ /\.([^\.]*)$/;
if (!defined $PNMCONV{$Type}) {
return if ($Ignore);
die "unknown file type '$Type': '$Pict'\n";
}
my ($w, $h) = imgsize($Pict);
print "image size is $w x $h\n" if ($Detailed);
return if (!defined $PICTYPES{$Type});
my $Exif = ImageInfo($Pict);
my $Orientation = $$Exif{"Orientation"};
my ($Degrees) = $Orientation =~ /Rotate ([0-9]+) /;
my $Rotate = "-null";
$Rotate = "-cw" if $Degrees eq "90";
$Rotate = "-ccw" if $Degrees eq "270";
$Rotate = "-r180" if $Degrees eq "180";
my $Rotate = $Degrees ? "-rotate $Degrees" : "";
print "orientation = '$Orientation' -> rotation = $Rotate\n" if ($Detailed);
($w, $h) = ($h, $w) if ($Degrees eq "90" || $Degrees eq "270");
if ($w / $h <= $ScreenRatio) {
$w = $h * $ScreenRatio;
}
else {
$h = $w / $ScreenRatio;
}
my $ScaleW = $SW / $w * (100 - 2 * $OverscanX) / 100;
my $ScaleH = $SH / $h * (100 - 2 * $OverscanY) / 100;
$Pict = EscapeMeta($Pict);
$Mpeg = EscapeMeta($Mpeg);
print "$Pict -> $Mpeg $Rotate\n" if $ListFiles;
my $Cmd = "$PNMCONV{$Type} $Pict 2> /dev/null |"
. "pamflip $verbose1 $Rotate |"
. "pnmscale $verbose1 --xscale=$ScaleW --yscale=$ScaleH |"
. "pnmpad $verbose1 --black --width $SW --height $SH |"
. "ppmntsc $verbose1 $system1 |"
. "ppmtoy4m $verbose2 -F $framerate -I p -S 420mpeg2 |"
. "mpeg2enc $verbose2 -f 3 -b 12500 -a $aspect -q 1 -n $system2 -o $Mpeg";
my $Cmd = "convert $Pict -background '#000000' $Rotate -resize $Size -gravity center -extent $Size ppm:- | "
. "ffmpeg -f image2pipe -vcodec ppm -i pipe:0 -an -vcodec libx264 -vpre baseline -s $Size -qscale 2 -f mpegts -y $Mpeg "
. ($Detailed ? "" : "2>/dev/null");
!system($Cmd) || die "$Cmd: $!\n";
$Cmd = "touch -r $Pict $Mpeg";
!system($Cmd) || die "$Cmd: $!\n";

193
PLUGINS/src/pictures/pic2mpg-sd Executable file
View File

@ -0,0 +1,193 @@
#!/usr/bin/perl
# pic2mpg: Convert picture files to MPEG still frames
#
# Converts either a single picture file or all files in a
# given directory (recursively) to MPEG still frames.
#
# See the README file for copyright information and how to reach the author.
#
# $Id: pic2mpg-sd 2.1 2011/07/23 14:23:59 kls Exp $
## TODO implement HDTV (1920 x 1080)
use File::Path;
use File::Spec;
use Getopt::Std;
use Image::ExifTool qw(:Public);
use Image::Size;
$Usage = qq{
Usage: $0 [options] picture-dir mpeg-dir
$0 [options] picture-file mpeg-file
Options: -a Aspect ratio 4:3 (default is 16:9)
-f Force conversion
-h print Help
-i Ignore unknown file types
-n NTSC (default is PAL)
-v num Verbose (0=none, 1=list files, 2=detailed)
-x percent X overscan in percent
-y percent Y overscan in percent
};
getopts("afhinv:x:y:") || die $Usage;
die $Usage if $opt_h;
$Aspect = $opt_a;
$Force = $opt_f;
$Ignore = $opt_i;
$NTSC = $opt_n;
$Verbose = $opt_v;
$OverscanX = $opt_x;
$OverscanY = $opt_y;
$ListFiles = $Verbose >= 1;
$Detailed = $Verbose >= 2;
# Screen size:
$SW = $NTSC ? 720 : 720;
$SH = $NTSC ? 480 : 576;
$ScreenRatio = $Aspect ? 4 / 3 : 16 / 9;
# Converter programs:
%PNMCONV = (
bmp => "bmptopnm",
gif => "giftopnm",
jpeg => "jpegtopnm",
jpg => "jpegtopnm",
png => "pngtopnm",
pnm => "cat",
tif => "tifftopnm",
tiff => "tifftopnm",
);
# Command options:
die "$0: missing parameter\n" unless $ARGV[0] && $ARGV[1];
die "$0: file or directory not found: $ARGV[0]\n" unless -e $ARGV[0];
die "$0: source and destination must be different\n" if $ARGV[0] eq $ARGV[1];
$verbose1 = $Detailed ? "--verbose" : "";
$verbose2 = $Detailed ? "-v 2" : "-v 0";
$system1 = $NTSC ? "" : "--pal";
$system2 = $NTSC ? "n" : "p";
$framerate = $NTSC ? "30000:1001" : "25:1";
$aspect = $Aspect ? "2" : "3";
# Convert a single file:
if (-f $ARGV[0]) {
die "$0: mixed file and directory ('$ARGV[0]' <-> '$ARGV[1]')\n" unless !-e $ARGV[1] || -f $ARGV[1];
ConvertFile($ARGV[0], $ARGV[1]);
exit;
}
die "$0: mixed directory and file ('$ARGV[0]' <-> '$ARGV[1]')\n" unless !-e $ARGV[1] || -d $ARGV[1];
$PICDIR = File::Spec->rel2abs($ARGV[0]);
$MPGDIR = File::Spec->rel2abs($ARGV[1]);
# Convert pictures to mpegs:
chdir($PICDIR) || die "$PICDIR: $!\n";
@Pictures = `find -type f`;
chomp(@Pictures);
for $pic (@Pictures) {
my $mpg = "$MPGDIR/$pic.mpg";
if ($Force || !-e $mpg || -M $mpg > -M $pic) {
(my $dir = $mpg) =~ s/\/[^\/]*$//;
mkpath($dir);
ConvertFile($pic, $mpg);
}
}
# Remove mpegs without pictures:
chdir($MPGDIR) || die "$MPGDIR: $!\n";
@Mpegs = `find -type f`;
chomp(@Mpegs);
for $mpg (@Mpegs) {
my $pic = "$PICDIR/$mpg";
$pic =~ s/\.mpg$//;
if (!-e $pic) {
print "removing $mpg\n";
unlink($mpg);
}
}
# Remove empty directories:
chdir($MPGDIR) || die "$MPGDIR: $!\n";
for ($i = 0; $i < 10; $i++) { # dirs might become empty when removing empty subdirs
@Dirs = `find -type d -empty`;
chomp(@Dirs);
last unless @Dirs;
for $dir (@Dirs) {
$dir = EscapeMeta($dir);
print "removing $dir\n";
!system("rm -rf $dir") || die "$dir: $!\n";
}
}
# Actual file conversion:
sub ConvertFile
{
my ($Pict, $Mpeg) = @_;
(my $Type) = lc($Pict) =~ /\.([^\.]*)$/;
if (!defined $PNMCONV{$Type}) {
return if ($Ignore);
die "unknown file type '$Type': '$Pict'\n";
}
my ($w, $h) = imgsize($Pict);
print "image size is $w x $h\n" if ($Detailed);
my $Exif = ImageInfo($Pict);
my $Orientation = $$Exif{"Orientation"};
my ($Degrees) = $Orientation =~ /Rotate ([0-9]+) /;
my $Rotate = "-null";
$Rotate = "-cw" if $Degrees eq "90";
$Rotate = "-ccw" if $Degrees eq "270";
$Rotate = "-r180" if $Degrees eq "180";
print "orientation = '$Orientation' -> rotation = $Rotate\n" if ($Detailed);
($w, $h) = ($h, $w) if ($Degrees eq "90" || $Degrees eq "270");
if ($w / $h <= $ScreenRatio) {
$w = $h * $ScreenRatio;
}
else {
$h = $w / $ScreenRatio;
}
my $ScaleW = $SW / $w * (100 - 2 * $OverscanX) / 100;
my $ScaleH = $SH / $h * (100 - 2 * $OverscanY) / 100;
$Pict = EscapeMeta($Pict);
$Mpeg = EscapeMeta($Mpeg);
print "$Pict -> $Mpeg $Rotate\n" if $ListFiles;
my $Cmd = "$PNMCONV{$Type} $Pict 2> /dev/null |"
. "pamflip $verbose1 $Rotate |"
. "pnmscale $verbose1 --xscale=$ScaleW --yscale=$ScaleH |"
. "pnmpad $verbose1 --black --width $SW --height $SH |"
. "ppmntsc $verbose1 $system1 |"
. "ppmtoy4m $verbose2 -F $framerate -I p -S 420mpeg2 |"
. "mpeg2enc $verbose2 -f 3 -b 12500 -a $aspect -q 1 -n $system2 -o $Mpeg";
!system($Cmd) || die "$Cmd: $!\n";
$Cmd = "touch -r $Pict $Mpeg";
!system($Cmd) || die "$Cmd: $!\n";
}
sub EscapeMeta
{
my $META = ' !"#$%&\'()*;<>?[\\]`{|}~';
my $s = shift;
$s =~ s/([$META])/\\$1/g;
return $s;
}