#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;

my ($input, $copy, $vbitrate, $abitrate, $fullscreen, $stereo, $print);
my ($title, $timestamp, $cmdline);

Getopt::Long::Configure('bundling');
GetOptions('i|input=s' => \$input
          ,'c|copy' => \$copy
          ,'v|vbitrate=i' => \$vbitrate
          ,'a|abitrate=i' => \$abitrate
          ,'f|fullscreen' => \$fullscreen
          ,'s|stereo' => \$stereo
          ,'p|print' => \$print);

if (!defined $input)
{
    $0 =~ s#.*/##;
    print <<EOD
PSP video converter script
Usage: $0 -i <inputfile> -c | -v <vbitrate> -a <abitrate> -f -s -p

Arguments:
   -i     Input video file
   -c     Copy bitrate and screen aspect ratio
   -v     Bitrate of video in kbps (default=192, overrides -c)
   -a     Bitrate of audio in kbps (default=64, overrides -c)
   -f     Force output to 4:3 (e.g. for 5:4 PAL input)
   -s     Indicate if audio should be in stereo (default=disabled, overrides -c)
   -p     Indicate if commands should be printed (default=disabled)

You can also use these longer command line parameters:
  --input, --copy, --vbitrate, --abitrate, --fullscreen, --stereo, --print
EOD
;
    exit;
}

if ($copy)
{
    my $info = `avconv -i "$input" 2>&1`;
    $abitrate = $1 if !defined $abitrate && $info =~ m#Stream.*?Audio.*?(\d+) kb/s#i;
    $vbitrate = $1 - $abitrate if !defined $vbitrate && $info =~ m#Duration.*?bitrate: (\d+) kb/s#i;
    $vbitrate /= 1.5 if $info !~ m#Stream.*?Video.*?h264#i; # h264 does a good job, bitrate can be lower
    $stereo   = 1 if !defined $stereo && $info =~ m#Stream.*?Audio.*?stereo#i;
}

$vbitrate   = 256 if !defined $vbitrate;
$abitrate   =  64 if !defined $abitrate;
$fullscreen =   0 if !defined $fullscreen;
$stereo     =   2 if !defined $stereo;
$stereo     =   3 - $stereo;

$print      =   0 if !defined $print;

($title = $input) =~ s#^(.*/)?(.*?)\.\w{3,5}$#$2#; # comment
my ($sec,$min,$hour, $day,$month,$year) = localtime(time);
$month++; $year += 1900;
$timestamp = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $month, $day, $hour, $min, $sec);

# Build avconv command line
$cmdline  = "nice -n 19 avconv -threads 2 -i \"$input\" -strict experimental -metadata title=\"$title\" -metadata creation_time=\"$timestamp\" ";
$cmdline .= "-vcodec libx264 -coder 1 -g 250 -s 480x270 ";
$cmdline .= "-b ${vbitrate}k -level 21 -refs 2 ".($fullscreen == 1 ? '-aspect 4:3 ' : '');
# Forcing the framerate is necessary when codec frame rate != container frame rate, e.g.:
# "Seems stream 0 codec frame rate differs from container frame rate: 23.98 (65535/2733) -> 23.98 (23976024/1000000)"
# This framerate doesn't seem to have any effect during playback, but without it, files are "Unsupported data"
# Note: this error may still occur, but it won't matter anymore
$cmdline .= "-r 29.97 ";
# Some weird PSP stuff
$cmdline .= "-flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -me_method umh -subq 6 -trellis 1 -refs 2 -bf 1 -me_range 16 -g 300 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -maxrate 4M -bufsize 4M -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 ";
$cmdline .= "-acodec aac -ac $stereo -ar 48000 ";
$cmdline .= "-ab ${abitrate}k -vol 768 ";
$title =~ s#[^\w\d \-]##g;
$cmdline .= "-f psp \"$title.psp.mp4\"";

if ($print)
{ print $cmdline, "\n"; }
else
{ system($cmdline); }

# Create thumbnail
$cmdline  = "avconv -i \"$input\" -f mjpeg -ss 5 -vframes 1 ";
$cmdline .= "-s 160x120 -an \"$title.psp.jpg\"";

if ($print)
{ print $cmdline, "\n"; }
else
{ system($cmdline); }
