1

this is my first post on this forum, so please be gentle in case I accidentally do trip over any forum rules that I would not know of yet :).

I would like to apply some color-grading to underwater GoPro footage. To quicker gauge the effect of my color settings (trial-and-error, as of yet), would like to see the original input video stream as a PIP (e.g., scaled down to 50% or even 30%), in the bottom-right corner of the converted output movie.

I have one input movie that is going to be color graded. The PIP should use the original as an input, just a scaled-down version of it.

I would like to use ffmpeg's "-filter_complex" option to do the PIP, but all examples I can find on "-filter_complex" would use two already existing movies. Instead, I would like to make the color-corrected stream an on-the-fly input to "-filter_complex", which then renders the PIP.

Is that doable, all in one go?

Both the individual snippets below work fine, I now would like to combine these and skip the creation of an intermediate color-graded TMP output which then gets combined, with the original, in a final PIP creation process. Your help combining these two separate steps into one single "-filter_complex" action is greatly appreciated!

Thanks in advance, raven.

[existing code snippets (M$ batch files)]

::declarations/defines::
set "INPUT=<path-to-movie>"
set "TMP=<path-to-intermediate-output-movie>"
set "OUTPUT=<path-to-movie>"
set "FFMPG=<path-to-executable>"
set "QU=9" :: quality settings

set "CONV='"0 -1 0 -1 5 -1 0 -1 0:0 -1 0 -1 5 -1 0 -1 0:0 -1 0 -1 5 -1 
0 -1 0:0 -1 0 -1 5 -1 0 -1 0'"" :: sharpening convolution filter

::color-grading part::
%FFMPG% -i %INPUT% -vf convolution=%CONV%,colorbalance=rs=%rs%:gs=%gs%:bs=%bs%:rm=%rm%:gm=%gm%:bm=%bm%:rh=%rh%:gh=%gh%:bh=%bh% -q:v %QU% -codec:v mpeg4 %TMP%

::PIP part::
%FFMPG% -i %TMP% -i %INPUT% -filter_complex "[1]scale=iw/3:ih/3 
[pip]; [0][pip] overlay=main_w-overlay_w-10:main_h-overlay_h-10" -q:v 
%QU% -codec:v mpeg4 %OUTPUT%

[/existing code]
raven
  • 23
  • 6
  • Your code resizes and overlays the graded video on top of the original but you say you wish to scale and overlay the original on top of the graded video. Which is it? – Gyan Oct 02 '19 at 12:13
  • Hi Gyan, thanks a lot for your reply, and for spotting my mistake :). In the code above, I have now swapped around the videos: color-graded = large, original video = small PIP, scaled 1/3, lower-right corner. Thanks for notifying :)!! – raven Oct 02 '19 at 21:12
  • @raven Why use mpeg4? – llogan Oct 02 '19 at 21:41
  • @Ilogan: I do not have any special requirements regarding the format, it's just what comes out of my GoPro, so I thought, why not use it? Do you recommend to switch to another format? If so, which format would you recommend? The purpose of this script is to run on a tiny (a.k.a. totally underpowered!) tablet, and to perform basic color-grading, in a batch process, over night. Cutting / joining of the graded video material during the next day. MP4 seems to work fine without bogging down that poor 8" tablet too much :). – raven Oct 02 '19 at 23:12
  • I'm assuming the gopro video format is H.264. Using mpeg4 will output MPEG-4 Part 2 video which is an older generation. I would use `-c:v libx264` and increase encoding speed with `-preset ultrafast` and add `-crf 18` for high quality since this seems to be for preview only. – llogan Oct 02 '19 at 23:58

2 Answers2

1
ffmpeg -i input -filter_complex "[0]scale=iw/3:-1[pip];[0]convolution,colorbalance[bg];[bg][pip]overlay=main_w-overlay_w-10:main_h-overlay_h-10[v]" -map "[v]" -map 0:a -c:a copy output

This is a simplified command. You'll need to enter your convolution and colorbalance values and integrate it into your batch file.

Description:

  1. [0] refers to the first (and only in this case) input file and is the input for the scale filter. The output from scale is arbitrarily named [pip]. You can give it just about any name you prefer. See Filtering Introduction, Filtergraph description, and Filtergraph syntax for more info.
  2. [0] is also used as the input for convolution. The output from convolution is fed directly to colorbalance. Linear chains of filters are connected via a comma (see above link). The output from colorbalance is named [bg].
  3. overlay needs two inputs which are [bg] and [pip]. [pip] is overlaid on [bg]. The output from overlay is named [v].
  4. -map option is used to manually select the streams to put into the output. It is generally a good idea to get into the habit to use -map unless you fully understand the default stream selection behavior.
  5. I'm assuming the input audio is AAC, so you can stream copy the audio instead of re-encoding it. If not then you can remove -c:a copy and a default encoder will be chosen depending on your output file format or you can choose a specific encoder.
llogan
  • 121,796
  • 28
  • 232
  • 243
  • OK, thanks, will try ... can you please explain a bit more regarding the syntax you are using here? I assume the command assings the name [0] to the input stream "i", then takes [0] and creates a [pip] sub-stream, and takes [0] and creates a [bg] substream. The [bg] substream gets color-graded and sharpened. Finally, you are making the overlay ... which is named [v] ... but then ... what does the "-map" command do? Finally, you are not re-encoding the stream, but simply copying it ... is that assumption true? If so, why recommending copy vs. re-encode? My apologies for asking a lot :)!! – raven Oct 02 '19 at 23:23
  • I have tried your suggested approach in my script (see below), but get an error msg as follows: "Unrecognized option '1'. Error splitting the argument list: Option not found" [code] %FFMPG% -i %IN% -filter_complex "[0]scale=iw/3:-1[pip];[0]colorbalance=%COLORBALANCE%,convolution=%CONV%[bg];[bg][pip]overlay=main_w-overlay_w-10:main_h-overlay_h-10 [v]" -map "[v]" -map 0:a -c:a copy %OUT% [/code] Where am I doing wrong, where did I miss? Thanks in advance! raven. – raven Oct 02 '19 at 23:33
  • @raven Run the command in `cmd` or PowerShell first. Once you verify that it works then you can add it to your batch file. Right now it's hard to tell if the ffmpeg command or the batch file is the culprit. – llogan Oct 02 '19 at 23:41
  • I will try my best ... not easy to run the original command in a cmd shell - these filter specifics are little monsters themselves ... but I did manage to create a proxy filter setting - and it works! Here's what I had put into cmd (without the [tags]): [code]ffmpeg -i in.mp4 -filter_complex "[0]scale=iw/3:-1[pip];[0] eq=gamma=1.5:saturation=1.3[bg];[bg][pip]overlay=main_w-overlay_w-10:main_h-overlay_h-10[v]" -map [v]" -map 0:a -c:a copy out.mp4 [/code] ... so that works quite well, actually!! – raven Oct 03 '19 at 00:00
  • Looks like you're getting the hang of it. – llogan Oct 03 '19 at 00:04
  • Based on your excellent feedback, I have revised my code, posted above. The error-throwing culprit was the convolution definition - it's been single quotes when I had used the regular ones ... oh my! Thanks a lot for your comprehensive + uplifting responses, really makes my day :)!! Cheers! – raven Oct 03 '19 at 01:06
1

Here's a revised (now working) color-grading batch file.

[revised code (M$ batch file)]

@echo off
cls
rem ------------------------------------------------------------------------
rem Purpose: color correction, saturation, sharpening for underwater video. 
rem Function: color-grades video, inserts the original video in lower right
rem corner as a PIP (picture-in-picture) overlay, for comparison
rem Error handling: basic. 
rem                 Checks for availability of input video (%IN%)
rem                 Deletes possibly pre-existing output file (%OUTP%) 
rem Inputs: %IN%
rem Outputs: %OUTP% (with ungraded video as PIP) 
rem Parameters: To be tested with actual GoPro footage (manual 6500K setting) 
rem ------------------------------------------------------------------------

::declarations/defines::
set "IN=<path-to-movie>"
set "OUTP=<path-to-movie>"
set "FFMPG=<path-to-executable>"

::test availability of input file::
if not exist %IN% (
echo "Error: No input file (in.mp4) found. Aborting script."
goto eof
)

::remove potentially existing output file:: 
if exist %OUTP% DEL %OUTP%

::convolution (sharpening)::
set "CONV='0 -1 0 -1 5 -1 0 -1 0:0 -1 0 -1 5 -1 0 -1 0:0 -1 0 -1 5 -1 0 -1 0:0 -1 0 -1 5 -1 0 -1 0'"

::equalizer settings::
set "CONTRAST=1.0"        :: Contrast in range -1000 to 1000 (normal is 1.0)
set "BRIGHT=0.0"          :: Brightness in range -1.0 to 1.0 (normal is 0.0)
set "SATUR=1.05"          :: Saturation in range 0.0 to 3.0 (normal is 1.0; the higher, the more pure the colors will get)
set "GAMMA=1.15"          :: Gamma in range 0.1 to 10.0 (normal is 1.0; greater 1.0 is more contrast, darker shades, brighter highlights)

::colorlevels settings::
set "rmin=0.10"           :: colorlevel red minimum
set "gmin=0.05"           :: colorlevel green minimum
set "bmin=0.05"           :: colorlevel blue minimum
set "rmax=0.70"           :: colorlevel red maximum
set "gmax=1.00"           :: colorlevel green maximum
set "bmax=0.95"           :: colorlevel blue maximum

::colorbalance and hue::
set "HUE=-5"              :: Color correction (hue), negative shifts towards red and positive towards blue, normal is 0, typical is -30...+30 range
set "rs=+0.00"            ::   red - cyan    :: Adjust red, green and blue shadows (darkest pixels) 
set "gs=-0.10"            :: green - magenta ::
set "bs=-0.10"            ::  blue - yellow  ::

set "rm=+0.10"            ::   red - cyan    :: Adjust red, green and blue midtones (medium pixels)
set "gm=-0.25"            :: green - magenta ::
set "bm=-0.25"            ::  blue - yellow  ::

set "rh=+0.05"            ::   red - cyan    :: Adjust red, green and blue highlights (brightest pixels)
set "gh=-0.20"            :: green - magenta ::
set "bh=-0.20"            ::  blue - yellow  ::

::equalizer (contrast, brightness, saturation, gamma)::
set "EQUALIZER=contrast=%CONTRAST%:brightness=%BRIGHT%:saturation=%SATUR%:gamma=%GAMMA%"

::colorlevels::
set "COLORLEVELS=rimin=%rmin%:gimin=%gmin%:bimin=%bmin%:rimax=%rmax%:gimax=%gmax%:bimax=%bmax%"

::colorbalance::
set "COLORBALANCE=rs=%rs%:gs=%gs%:bs=%bs%:rm=%rm%:gm=%gm%:bm=%bm%:rh=%rh%:gh=%gh%:bh=%bh%"

::applying all of these filter settings (color-grading and PIP combined)::
::using libx264 encoding and "-preset ultrafast", "-crf 18" for high quality, as recommended (for quick preview purposes rather than smallest file sizes)::
%FFMPG% -i %IN% -filter_complex "[0]scale=iw/3:-1[pip];[0]colorbalance=%COLORBALANCE%[1],[1]hue=h=%HUE%[2],[2]colorlevels=%COLORLEVELS%[3],[3]eq=%EQUALIZER%[4],[4]convolution=%CONV%[bg];[bg][pip]overlay=main_w-overlay_w-10:main_h-overlay_h-10 [v]" -map "[v]" -map 0:a -c:a copy -c:v libx264 -preset ultrafast -crf 18 %OUTP%
goto eof

:: End
:eof

[/revised code]

Excellent responses, learned quite a bit, thanks a lot :))!!

Cheers, raven.

raven
  • 23
  • 6