#
# YUV4MPEG filter which cuts frames out of a stream.  It is capable of
# taking comma-separated ranges as specifiers for the frames to cut.
#
#   cat stream.yuv | perl yuvcut.pl -c 10,15,20-25 > cut.yuv
#

use YUV4MPEG;
use Getopt::Long;

my $spec;
my $help;

GetOptions("c|cut=s" => \$spec,
           "h|?|help" => \$help);

do_help() if ($help);

$spec = parse_range($spec);

my $si = new YUV4MPEG::StreamInfo;
my $fi = new YUV4MPEG::FrameInfo;
my $frame_num = 0;
my $frame;

$si->read();
$si->write();

$frame = new YUV4MPEG::Frame($si);

while ($frame->read($fi) == Y4M_OK)
{
    if (! in_range($spec, $frame_num)) 
    {
        $frame->write($fi);
    }
    else
    {
        print STDERR "Skipping frame $frame_num...\n";
    }

    $frame_num++;

    $fi = new YUV4MPEG::FrameInfo;
}

sub in_range
{
    my @ranges = @{ $_[0] };
    my $num = $_[1];

    foreach (@ranges) {
        if (($_->{"low"} <= $num) &&
            ($_->{"high"} >= $num)) {
            return 1;
        }
    }

    return 0;
}

sub parse_range
{
    my $spec = shift;
    my @ranges = split(/,/, $spec);
    my @result;

    foreach (@ranges)
    {
        my @parts = split(/-/, $_);

        die "Invalid range specified: $_" if (($#parts > 1) || ($#parts < 0));

        $parts[1] = $parts[0] if (! defined $parts[1]);

        push @result, { "low" => $parts[0],
                        "high" => $parts[1] };
    }

    return \@result;
}

sub do_help
{
    print "Usage: $0 [options]\n";
    print "  The options are:\n";
    print "    -c, --cut=<range_specifier>\n\n";
    print "  Where range_specifier is a comma-separated list of ranges.  eg:\n";
    print "    yuvcut.pl -c 10-15,20,30,60-100\n";

    exit(0);
}
