#!/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 mencoder plugin v1.9

# 1.7 add kvcd back in
# 1.8 use mjpeg with -ovc copy (thanks to Rich Felker for the suggestion)
# 1.9 add ffv1 and png support (thanks to anonymous) 
# 1.91 add ffv1 image formats

#######################################################################

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


#######################################################################


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


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

    if (&location("mencoder") eq "") {
	print "Mencoder was not found. Please install it 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, 4 - can encode using mp2, 8 - vorbis

   print "mjpeg|mjpg|2|none|avi|\n";
   print "ffv1|ffv1 (lossless)|2|none|avi|\n";
   print "kvcd|kvcd (experimental)|4|arate=32000;44100;48000,fps=24;25;30,aspect=352:240,hblock=16,vblock=16|mpg|\n";
   
   exit 0;
}



if ($command eq "encode") {
    # encode 

    $encoder_command="mencoder";

    # remove ":"'s from comments, mencoder doesn't like them even in quotes
    $title=~ s/:/ /g;
    $author=~ s/:/ /g;
    $comment=~ s/:/ /g;

    # mencoder doesn't like empty strings either
    if ($title eq "") {
	$title=" ";
    }
    if ($author eq "") {
	$author=" ";
    }
    if ($comment eq "") {
	$comment=" ";
    }

    if ($otype eq "") {
	$otype="mjpeg";
	&rc_set("output_type",$otype);
    }

    # set the codec
    $vcodec="mjpeg";
    
    if ($otype eq "mpeg4" || $otype eq "mpeg2video" || $otype eq "ffv1") {
	$vcodec=$otype;
    }

    if ($otype eq "mpg1") {
	$vcodec="mpeg1video";
    }
    
    if ($otype eq "ffv1") {
	if ($img_ext eq ".png") {
	    $format=":format=BGR32";
	}
	else {
	    #jpeg
	    $format=":format=422P";
	}
    }
    else {
	$format="";
    }

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

    # TODO - recheck this
    $zeroframe=&mkname(0);
    `cp 00000001$img_ext $zeroframe$img_ext $err`;



    #prepare video stream

    if ($mf_ver==1) {
	if ($img_ext eq ".png") {
	    $syscom="$encoder_command  -mf on -mf type=png -vc mpng -o \"$tmpvid\" -ovc lavc -lavcopts vcodec=$vcodec:vhq$format -noskip -ofps $fps \\*$img_ext -frames " . ($end-$start+2) . " $err";
	}
	else {
	    $syscom="$encoder_command  -mf on -mf h=$vsize:w=$hsize:type=jpg -o \"$tmpvid\" -ovc lavc -lavcopts vcodec=$vcodec:vhq$format -noskip -ofps $fps \\*$img_ext -frames " . ($end-$start+2) . " $err";
	}
    }
    else {
	if ($img_ext eq ".png") {
	    $syscom=$encoder_command . " -mf fps=$fps:type=png -vc mpng -o \"" . $tmpvid . "\" -ovc lavc -lavcopts vcodec=$vcodec:vhq$format -noskip mf://*" . $img_ext . " -frames " . ($end-$start+2) . " $err";
	}
	else {
	    $syscom=$encoder_command . " -mf h=$vsize:w=$hsize:type=jpg -o \"" . $tmpvid . "\" -ovc lavc -lavcopts vcodec=$vcodec:vhq$format -noskip -ofps " . $fps . " mf://*" . $img_ext . " -frames " . ($end-$start+2) . " $err";
	}
    }
    if (defined($DEBUG_ENCODERS)) {
	print STDERR "Debug: mencoder command 1 is: $syscom\n";
    }
    system($syscom);

    $audio_com="";
    unless ($audiofile eq "") {
	$audio_com=" -oac copy -audiofile " . $audiofile;
    }

    if ($otype eq "mjpeg" || $otype eq "ffv1") {
	$syscom=$encoder_command . " -mc 0 -o \"$nfile\" $audio_com -ovc copy -noskip -ofps $fps $tmpvid -info comment=\"$comment\":name=\"$title\":artist=\"$author\" $err";
    }
    elsif ($otype eq "kvcd") {
	$abitrate=112;
	$matrix="8,9,12,22,26,27,29,34,9,10,14,26,27,29,34,37,12,14,18,27,29,34,37,38,22,26,27,31,36,37,38,40,26,27,29,36,39,38,40,48,27,29,34,37,38,40,48,58,29,34,37,38,40,48,58,69,34,37,38,40,48,58,69,79";
	$inter_matrix="16,18,20,22,24,26,28,30,18,20,22,24,26,28,30,32,20,22,24,26,28,30,32,34,22,24,26,30,32,32,34,36,24,26,28,32,34,34,36,38,26,28,30,32,34,36,38,40,28,30,32,34,36,38,42,42,30,32,34,36,38,40,42,44";
	$scale="scale=352:240";

	$syscom="$encoder_command $tmpvid -mc 0 -of mpeg -ovc lavc -oac lavc -lavcopts acodec=mp2:abitrate=$abitrate:vcodec=mpeg1video:keyint=".int($fps).":mbd=1:vrc_minrate=64:vrc_maxrate=3000:vrc_buf_size=320:aspect=4/3:intra_matrix=$matrix:inter_matrix=$inter_matrix -vf $scale -o \"$nfile\"";

    }
    if (defined($DEBUG_ENCODERS)) {
	print STDERR "Debug: mencoder command 2 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;
 

    $tmpvid="tmpvid";
    if (-f $tmpvid) {
	unlink $tmpvid;
    }
    &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 7; # clipped pcm wav, clipped frames
}

