FFMPEG - Human Vision




CS185c

Chris Pollett

Apr 8, 2019

Outline

Introduction

Singleton Pattern and Resource Management

FFMPEG

Common Use Cases of FFMPEG 1

Common Use Cases of FFMPEG 2

Video Formats for VR

Making SBS Video From Two Video Sources

<?php
$flip = false;
$front = true;
$back = false;
$lenscorrection = false;
$letterbox = false;
foreach ($argv as $index => $arg) {
    if (in_array($arg, ['--flip', '--front', '--back', '--lenscorrection',
        '--letterbox'])) {
        $cmd_switch = ltrim($arg, "-");
        $$cmd_switch = true;
        unset($argv[$index]);
    }
}
$argv = array_values($argv);
if (count($argv) < 4) {
    echo <<< EOD
    To use:
This program should be run from the command line with a line like:
php vr180tool.php [option list]  left_eye_file right_eye_file output_file

Here [option list] can be any sequence of the following options
 --flip //flip images upside down
 --front // make 180 3d from just front camera results
 --back // make 180 3d from just back camera results
 --lenscorrection // apply fisheye len correction
 --letterbox // apply letterbox to top and bottom of video

Here left_eye_file, right_eye_file, output_file should be a file that ffmpeg
can manipulate. For the Insta 360 One camera, left_eye_file and right_eye_file
would typically be .insv files for the two different perspectives needed to
make a stereoscopic 3d movie.

EOD;
    exit();
}

$lens_correction = "lenscorrection=cx=0.5:cy=0.5:k1=-0.34:k2=-0.045";
$left_correction = ($lenscorrection) ? "[lensleft];[lensleft]$lens_correction" :
    "";
$right_correction = ($lenscorrection) ?
    "[lensright];[lensright]$lens_correction" : "";
$flip_cmd = ($flip) ? "[to_flip];[to_flip]vflip" : "";
$box = ($letterbox) ? '[stacked];' .
    '[stacked]scale=(iw*sar)*min(2560/(iw*sar)\,1440/ih):'.
    'ih*min(2560/(iw*sar)\,1440/ih), pad=2560:1440:'.
    '(2560-iw*min(2560/iw\,1440/ih))/2:(1440-ih*min(2560/iw\,1440/ih))/2' :
    "";
list(, $left_mov, $right_mov, $output) = $argv;
$is_dir = false;
$is_file = false;
foreach([$left_mov, $right_mov] as $mov) {
    if (!file_exists($mov)) {
        echo "File: $mov does not exist!\n";
        exit();
    }
    if (is_dir($mov) || is_link($mov)) {
        $is_dir = true;
    }
    if (is_file($mov)) {
        $is_file = true;
    }
    if ($is_dir && $is_file) {
        echo "Inputs must be both files or both folders\n";
        exit();
    }
}
if ($is_file) {
    $movs = [0 => [$left_mov, $right_mov, $output]];
} else {
    if (!file_exists($output)) {
        mkdir($output);
    }
    if (is_file($output)) {
        echo "If inputs are folders, output must be folder\n";
        exit();
    }
    $pre_left_movs = glob("$left_mov/*.{insv,INSV,mp4,MP4,m4v,M4V}",
        GLOB_BRACE);
    $movs = [];
    foreach ($pre_left_movs as $mov) {
        $pre_right_mov = str_replace($left_mov, $right_mov, $mov);
        if (file_exists($pre_right_mov)) {
            $path_info = pathinfo($mov);
            $movs[] = [$mov, $pre_right_mov, "$output/" .
                $path_info['filename'] . ".mp4"];
        }
    }
}
echo "Making 180 degree 3D Output \n";
foreach ($movs as $mov) {
    list($left_mov, $right_mov, $output) = $mov;
    echo "Making movie from $left_mov and $right_mov with command:\n";
    if ($back) {
        $ffmpeg =
            "ffmpeg -i \"$right_mov\" -i \"$left_mov\" -filter_complex ".
            "\"[0]crop=1920:1920:0:0{$left_correction}[cropl];" .
            "[1]crop=1920:1920:0:0{$right_correction}[cropr];" .
            "[cropl][cropr]hstack$flip_cmd$box\" \"$output\"";
    } else {
        $ffmpeg =
            "ffmpeg -i \"$right_mov\" -i \"$left_mov\" -filter_complex ".
            "\"[0]crop=1920:1920:1920:0{$left_correction}[cropl];" .
            "[1]crop=1920:1920:1920:0{$right_correction}[cropr];" .
            "[cropl][cropr]hstack$flip_cmd$box\" \"$output\"";
    }
    echo $ffmpeg . "\n";
    exec($ffmpeg);
}

Remarks on FFMPEG Script

Quiz

Which of the following statements is true?

  1. Nicephore Niepce took photos in the 1820s using a Charged Couple Device.
  2. Javascript Gamepad object cannot be used to find the state of the Oculus Go trackpad.
  3. app->GetSystemProperty can be used to figure out which is the dominant hand for an Oculus Go controller in a Native app.

The Physiology of Human Vision

Parts of the Eye

Parts of the Eye

Photoreceptors and Wavelength

Photorecepters and Wavelength Angular Distribution of rods and cones

From Photoreceptors to the Visual Cortex

Hierarchal Transmission