#!/usr/bin/perl

# (c) G. Finch (salsaman)

# released under the GNU GPL 3 or later
# see file COPYING or www.gnu.org for details


#######################################################################
# LiVES transcode plugin v1.5
#######################################################################

if (!defined($standalone)) {
    my $smogrify=`which smogrify`;
    chomp($smogrify);
    require $smogrify;
}
else {
    $command=$ARGV[0];
}


#######################################################################
# version history - 
# 1.1 gf - changed get_image_size so it takes a parameter ($file)
# 1.2 gf - add more formats, clean up syntax
# 1.3 - add debug code $DEBUG_ENCODERS for monitoring
# 1.4 changed pref audio_encode_quality to encoder_acodec
# 1.5 updated to transcode 1.0.1
# 1.6 allow encoding of png; update --use_rgb to -V rgb
# 1.7 set options to enable/disable flip and swap

if ($command eq "version") {
    print "transcode encoder plugin v1.7\n";
    exit 0;
}


if ($command eq "init") {
    # perform any initialisation needed
    # On error, print error message and exit 1
    # otherwise exit 0

    if (&location("transcode") eq "") {
	print "Transcode was not found. Please install transcode and try again.";
	exit 1;
    }
    
    # end init code
    print "initialised\n";
    exit 0;
}



if ($command eq "get_capabilities") {
    # return capabilities - this is a bitmap field
    # bit 0 - takes extra parameters (using RFX request)
    # bit 1 - unused
    # bit 2 - can encode png
    # bit 3 - not pure perl
    print "4\n";
    exit 0;
}



if ($command eq "get_formats") {
   # for each format: -
   # return format_name|display_name|audio_types|restrictions|extension|

   # audio types are: 0 - cannot encode audio, 1 - can encode using
   #  mp3, 2 - can encode using pcm, 3 - can encode using pcm and mp3
    
   # restrictions: currently the only one implemented is 'fps=xx.yy' which
   # means "can only encode at xx.yy frames per second" 
   # - otherwise set it to 'none'

    print "mjpeg|mjpeg|3|none|avi|\n";
    print "mpeg4|mpeg4|3|none|mpg|\n";
    print "wmv2|wmv2|3|none|wmv|\n";

    exit 0;
}


if ($command eq "get_rfx") {
    # nice example of how to give the user a choice of options

    # mandatory section
    print "<define>\n";
    print "|1.7\n";
    print "</define>\n";
    
    # mandatory section
    print "<language_code>\n";
    print "0xF0\n";
    print "</language_code>\n";
    
    # optional section
    print "<params>\n";
    print "flip|_Flip images vertically|bool|1|0\n";
    print "swap|_Swap Red/Blue channels|bool|1|0\n";
    print "</params>\n";
    
    print "<paramwindow>\n";
    print "layout|\"Adjust these values if the resulting video comes out wrong\"|\n";
    print "layout|\$p0|\n";
    print "layout|\$p1|\n";
    print "</paramwindow>\n";


}



if ($command eq "encode") {
    # encode
    $encoder_command="transcode";

    # make tombstone file - transcode should pass this to ffmpeg but doesn't
    open OUT,"> comments";
    print OUT "INAM $title\n";
    print OUT "IART $author\n";
    print OUT "ICMT $comment\n";
    close OUT;

    $flip=$ARGV[13];
    $swap=$ARGV[14];

    if ($flip) {
	$flipopt=" -z";
    }
    else {
	$flipopt="";
    }

    if ($swap) {
	$swapopt=" -k";
    }
    else {
	$swapopt="";
    }


    # make a list of the frames to encode
    unlink "list";
    for ($i=$start;$i<=$end;$i++) {
	$name=&mkname($i);
	$syscom="echo $name$img_ext >> list";
	system $syscom;
    }

    $err=">/dev/null 2>&1";
    if (defined($DEBUG_ENCODERS)) {
	$err="1>&2";
    }


    #transcode seems to get the fps wrong sometimes, let's help it
    $fps=$fps*1.;

    if ($fps>23.9760&&$fps<23.9761) {
	$fps="0,1";
    }
    elsif ($fps==24) {
	$fps="0,2";
    }
    elsif ($fps==25) {
	$fps="0,3";
    }
    elsif ($fps>29.9700&&$fps<29.9701) {
	$fps="0,4";
    }
    elsif ($fps eq "30") {
	$fps="0,5";
    }
    elsif ($fps eq "50") {
	$fps="0,6";
    }
    elsif ($fps>59.9400&&$fps<59.9401) {
	$fps="0,7";
    }
    elsif ($fps eq "60") {
	$fps="0,8";
    }
    elsif ($fps==1) {
	$fps="0,9";
    }
    elsif ($fps==5) {
	$fps="0,10";
    }
    elsif ($fps==10) {
	$fps="0,11";
    }
    elsif ($fps==12) {
	$fps="0,12";
    }
    elsif ($fps==15) {
	$fps="0,13";
    }

    if ($otype eq "mpeg4"||$otype eq "mjpeg"||$otype eq "wmv2"||$otype eq "mpeg1video") {
	# use ffmpeg
	if (-f $audiofile) {
	    if (&rc_get("encoder_acodec")==1) {
		#pcm encoding
		$syscom="$encoder_command -i list -x imlist,raw -p $audiofile -V rgb24 -e $arate,$asamps,$achans -E $arate,$asamps,$achans -g $hsize"."x$vsize -f $fps --export_fps $fps -o \"$nfile\" -y ffmpeg -F $otype -N 0x1 $flipopt $swapopt --avi_comments comments $err";
	    }
	    else {
		# mp3 encoding
		$syscom="$encoder_command -i list -x imlist,raw -p $audiofile -V rgb24 -e $arate,$asamps,$achans -E $arate,$asamps,$achans -g $hsize"."x$vsize -f $fps --export_fps $fps -o \"$nfile\" -y ffmpeg -F $otype -N 0x55 $flipopt $swapopt --avi_comments comments $err";
	    }
	}
	else {
	    $syscom="$encoder_command -i list -V rgb24 -x imlist,null -g $hsize"."x$vsize -f $fps --export_fps $fps -o \"$nfile\" -y ffmpeg -F $otype -N 0x1 $flipopt $swapopt --avi_comments comments $err";
	}
    }
    else {
	if (-f $audiofile) {
	    if (&rc_get("encoder_acodec")==1) {
		#pcm encoding
		$syscom="$encoder_command -i list -x imlist,raw -p $audiofile -V rgb24 -e $arate,$asamps,$achans -E $arate,$asamps,$achans -g $hsize"."x$vsize -f $fps --export_fps $fps -o \"$nfile\" -y $otype -N 0x1 $flipopt $swapopt --avi_comments comments $err";
	    }
	    else {
		# mp3 encoding
		$syscom="$encoder_command -i list -x imlist,raw -p $audiofile -V rgb24 -e $arate,$asamps,$achans -E $arate,$asamps,$achans -g $hsize"."x$vsize -f $fps --export_fps $fps -o \"$nfile\" -y $otype -N 0x55 $flipopt $swapopt --avi_comments comments $err";
	    }
	}
	else {
	    $syscom="$encoder_command -i list -x imlist,null -g $hsize"."x$vsize -V rgb24 -f $fps --export_fps $fps -o \"$nfile\" -y $otype -N 0x1 $flipopt $swapopt --avi_comments comments $err";
	}
    }
    
    if (defined($DEBUG_ENCODERS)) {
	print STDERR "Debug: transcode command is $syscom\n";
    }
    system($syscom);

    # required
    &sig_complete;
    exit 0;
}


if ($command eq "clear") {
    # this is called after "encode"
    # note that encoding could have been stopped at any time
    chdir $curtmpdir;

    if (-f "list") {
	unlink "list";
    }
    if (-f "comments") {
	unlink "comments";
    }
    &sig_complete;
    exit 0;
}


if ($command eq "finalise") {
    # do any finalising code

    # ...

    # end finalising code
    print "finalised\n";
    exit 0;
}


###### subroutines #######




sub get_format_request {
    # return the code for how we would like audio and video delivered
    # this is a bitmap field composed of:
    # bit 0 - unset=raw pcm audio; set=pcm audio with wav header
    # bit 1 - unset=all audio; set=clipped audio
    # bit 2 - unset=all frames; set=frames for selection only

    return 1; # clipped raw, all frames
}

