Creating video from PAL decodes - happycube/ld-decode GitHub Wiki
The following is a series of notes about how to use FFmpeg to convert the output from ld-decode (and ld-chroma-decoder) into usable video that can be watched using any compatible video player such as VLC or MPC.
Information is compiled from a number of sources; however the project would like to thank Stephen Neal for his valuable advice on this subject.
TV System | Lines | Full-Frame 4fsc | Frequency | Frame Rate | Field Rate |
---|---|---|---|---|---|
PAL | 625 | 1135x624 | 17727262 Hz | 25i | 50 |
PAL - Phase Alternating Line, used in UK, Europe primarily, with PAL-M being used in Brazil.
The following text uses the EBU standard descriptions for video formats wherever possible.
So PAL SD interlaced video is written as 576/i25 - whereas (in earlier descriptions) it was typically described as 576/50i.
In the EBU notation, if the letter is first then the following number is always frames. If the letter is last then the number is either fields (for interlaced video) or frames (for progressive video).
So, for example, PAL SD progressive film source is 576p25 2:2-ed in a 576i25 frame - but that would have been described as 576/25p in a 576/50i signal in the old format.
PAL SD progressive deinterlaced is 576p50 (which isn't a broadcast standard outside of Australia...) however, 576p50 is a lot easier for computers to handle than 576i25 as it removes the need for them to deinterlace - which many PC based players often can't do, or don't do well.
There is now the TBC-Video-Export the universal export tool for Linux/MacOS/Windows systems.
Which has pre-made easy to edit FFmpeg profiles and allows quick and simple exporting of CVBS & Y/C TBC files from ld-decode & vhs-decode and automatic encoding of the chroma-decoded output to ready to use interlaced or progressive video files.
This provides a very hands off lazy initial export experience suitable for new users and ones wanting a tool with advanced scripting abbilitys.
FFV1 10-bit 4:2:2 is the stock export profile.
Linux & MacOS
tbc-video-export Input-Media.tbc
Windows
tbc-video-export.exe Input-Media.tbc
To convert the TBC output to playable video, you need to do the following:
- Tell the chroma-decoder how to decode the colour from TBC
- Tell the chroma-decoder the frame size of the video output
- Tell FFmpeg if/how you want to process the video (deinterlace, 3:2 removal etc.)
- Tell FFmpeg the required output format
See the ld-chroma-decoder wiki page for full possible options.
The majorty of users today will just want to use a YUV stream via y4m output from the chroma-decoder and a pipe to FFmpeg allowing easy creation of standard video files.
Lets breakdown a combined command that decodes the chroma and encodes a V210 uncompressed video file via FFmpeg and pipes ready for playback and editing with virtually any software.
INPUT.tbc
& OUTPUT.mov
just need to be changed to use this command right now on your decoded media!
ld-chroma-decoder --decoder transform3d -p y4m -q INPUT.tbc| ffmpeg -i - -c:v v210 -f mov -top 1 -vf setfield=tff -flags +ilme+ildct -pix_fmt yuv422p10le -color_primaries bt470bg -color_trc bt709 -colorspace bt470bg -color_range tv -vf setdar=4/3,setfield=tff OUTPUT.mov
The first stage is the chroma-decoder arguments.
ld-chroma-decoder --decoder transform3d --output-format y4m input.tbc| ffmpeg -i -
ld-chroma-decoder
- Calls the application a ./
might be needed at the start (ld-chroma-decoder.exe in windows)
--decoder transform3d
- Tells the chroma-decoder to use the PAL Trasform 3D decoder on the signal.
--output-format y4m
- Tells the chroma-decoder to output uncompressed YUV (-p
short hand command option)
The 2'nd stage is piping |
video to FFmpeg.
input.tbc| ffmpeg -i -
- Pipes the YUV stream from the y4m option to FFmpeg ready for encoding and muxing with audio or outher data such as subtitles.
Just replace input.tbc
with your TBC file and add standard FFmpeg commands after the -i -
part like shown examples in this page.
The 3'rd stage is the actual FFmpeg command that makes the video file
ffmpeg -i - -c:v v210 -f mov -top 1 -vf setfield=tff -flags +ilme+ildct -pix_fmt yuv422p10le -color_primaries bt470bg -color_trc bt709 -colorspace bt470bg -color_range tv -vf setdar=4/3,setfield=tff OUTPUT.mov
Video Codec: -c:v v210 -f mov
Interlaced Flag: -top 1 -vf setfield=tff -flags +ilme+ildct
- Interlaced Top Field first "tff"
Pixel Format: -pix_fmt yuv422p10le
- 10-bit 4:2:2
Colour Space & Transfer: -color_primaries bt470bg -color_trc bt709 -colorspace bt470bg
- Sets origin as PAL and trasfer to HDTV.
Colour Range: -color_range tv
sets the black levels to 16-255 limited TV range. (ware as pc would do 0-255 full range)
Aspect Ratio: -vf setdar=4/3,setfield=tff
- This sets it to 4:3 standard, also added is an redundent field flag to ensure field store is set to interlaced.
Container: is defined by the final item in the command OUTPUT.mov
so .mov for Quicktime or .mkv for Mastroska.
PAL options pal2d
,transform2d
, transform3d
, mono
NTSC options ntsc1d
, ntsc2d
, ntsc3d
, ntsc3dnoadapt
, mono
--chroma-nr <number>
NTSC: Chroma noise reduction level in dB (default 0.0)
--luma-nr <number>
Luma noise reduction level in dB (default 1.0)
--chroma-gain <number>
Gain factor applied to chroma components (default 1.0)
--chroma-phase <number>
Phase rotation applied to chroma components (degrees; default 0.0)
If you wish to have just the active or vbi area included just use the following commands.
TBC Video Export:
python3 tbc-video-export.py --vbi Input-Media.tbc
(Y4M Only*) you can use these 2 commands.
NTSC:
ld-chroma-decoder --ffll 1 --lfll 259 --ffrl 2 --lfrl 525 --decoder ntsc3d -p y4m -q INPUT.tbc OUTPUT.mov
PAL:
ld-chroma-decoder --ffll 2 --lfll 308 --ffrl 2 --lfrl 620 --decoder transform3d -p y4m -q INPUT.tbc OUTPUT.mov
You want to edit input.tbc
and output.xxx
on each command for your respective input and output file name, and container.
Use the .mkv
container if you dont need .mov
or .mp4
for compatability sake.
To encode a video without deinterlacing (note that the -top 1
switch tells FFmpeg that the video is first field first; this hint is required for players to correctly de-interlace the video during playback. If the original LaserDisc is second field first, this switch should be removed) :
ffmpeg -i "input.mkv" -pix_fmt yuv420p -top 1 -vcodec libx264 -crf 18 -flags +ildct+ilme -aspect 768:576 "output.576i25.mp4"
To add PCM analogue audio to the encoding add the following parameters before the initial -f in the command above:
-f s16le -ar 44.1k -ac 2 -i input.pcm
To chroma decode the .tbc file and combine analogue sound (pcm) with the video, use the following command line:
ld-chroma-decoder --decoder transform3d input.tbc -p y4m | ffmpeg -f s16le -ar 44.1k -ac 2 -i input.pcm -i - -pix_fmt yuv420p -vcodec libx264 -crf 18 -flags +ildct+ilme -aspect 768:576 output.576i25.mp4
To export a more practical codec for editing or post production you can encode to ProRes HQ.
ld-chroma-decoder --decoder transform3d -p y4m -q input.tbc | ffmpeg -i - -c:v prores -profile:v 3 -vendor apl0 -bits_per_mb 8000 -quant_mat hq -f mov -top 1 -vf setfield=tff -flags +ilme+ildct -pix_fmt yuv422p10 -color_primaries bt470bg -color_trc bt709 -colorspace bt470bg -color_range tv -vf setdar=4/3,setfield=tff OUTPUT.mov
ffmpeg -i "input.mkv" -vf "w3fdif=complex:all" -pix_fmt yuv420p -vcodec libx264 -crf 18 -aspect 768:576 "output.576p50.mp4"
Decode the .tbc file, deinterlace with w3fdif, and combine analogue sound (pcm) with the video:
ld-chroma-decoder -p y4m --decoder transform3d input.tbc | ffmpeg -f s16le -ar 44.1k -ac 2 -i input.pcm -i - -filter:v "w3fdif=complex:all" -pix_fmt yuv420p -c:v libx264 -crf 18 -aspect 768:576 "output.576p50.mp4"
Decode the .tbc file, deinterlace with bwdif, and combine analogue sound (pcm) with the video:
ld-chroma-decoder -p y4m --decoder transform3d input.tbc| ffmpeg -f s16le -ar 44.1k -ac 2 -i input.pcm -i - -filter:v "bwdif=1" -pix_fmt yuv420p -c:v libx264 -crf 16 -flags +ildct+ilme -aspect 768:576 output.576p50.mp4
For upload to YouTube (deinterlaced files only) it is recommended to scale the video to 2880x2176
up to 5760x4320
to prevent YouTube's SD-HD highly macroblock baised encoding from causing a massive drop in visual image quality, while this will create large files however the resulting playback quality after upload is far better then the alternative.
- FFV1 (If under size limit)
- HEVC (120mbps for 50/59.97p)
ld-chroma-decoder --decoder transform3d -p y4m -q input.tbc | ffmpeg -i - -f s16le -ar 44.1k -ac 2 -c:v prores -profile:v 3 -vendor apl0 -bits_per_mb 8000 -quant_mat hq -f mov -top 1 -pix_fmt yuv422p10 -color_primaries bt470bg -color_trc bt709 -colorspace bt470bg -color_range tv -vf bwdif=1:0:0 -vf scale=2880x2176:flags=lanczos -aspect 768:576 output_ProRes_HQ_YT.mov
The .mov
container is used for compliance as the codec used is ProRes HQ which is natively supported by YouTube in either container so if you do not need it for complince on editing or playback hardware or are storing the file long term you are better off using the .mkv
container which is harder to damage and easyer to stream/upload due to not being headder dependent.
For platforms that don't re-encode their uploaded files like Odysee, you can use a lower bitrate native SD file with this re-encoding script:
ld-chroma-decoder --decoder transform3d -p y4m -q input.tbc | ffmpeg -i - -f s16le -ar 44.1k -ac 2 -c:v libx264 -bufsize 16000k -crf 20 -maxrate 8000k -movflags +faststart -pix_fmt yuv420p -color_primaries bt470bg -color_trc bt709 -colorspace bt470bg -color_range tv -vf bwdif=1:0:0 -vf -aspect 768:576 output_web.mov
The mov or mp4 container is recommended for web-browser support.
AVC/H.264 & HEVC/H.265 8mbps 4:2:0 web profiles are included in the tbc-video-export tool, but for highest compatability AVC/H.264 is the best codec to use today sadly and not HEVC or the newer AV1 codecs.
Deinterlacing is the process of taking the 576i25 (i.e. 50 x 288 line fields sampled 1/50th second apart) and create a 576p50 (i.e. 50 x 576 line frames)
Today there is 3 widly used options.
BWDIF (Bob Weaver Deinterlacing Filter) -vf bwdif=1:0:0
combining elements from yadif & w3fdif FFmpegs newest hybrid deinterlacing filter for PAL.
W3FDIF (BBC R&D Weston 3-field deinterlacing) -filter:v "w3fdif=complex:all"
based off the BBC filter.
Complex forces it to use the complex VT co-efficients, all forces it to deinterlace all frames (not just those flagged as interlaced - which the rawvideo won't be). This is only required if you want to avoid your display solution deinterlacing.
QTGMC, which is an modern AviSynth/VapourSynth scriptable filter is not available in FFmpeg, but used with ease in tools like Hybrid which is cross platfrom & StaxRip witch is windows based.
If you want to scale to a standard resolution from 928x576 PAL or 760x488 NTSC can do this with -vf "scale=768:576"
or you can do a pad and scale to 720 x 576 standard SD video resolution (TBC as I need to work out exact options to this as 4:3 analogue video should be in the central 702x576 area within a 720x576 frame, but a quick and dirty would be to ignore the 9 samples of blanking each side.
-vf "scale=720:480"
- Standard SD NTSC
-vf "scale=720:576"
- Standard SD PAL
-vf "scale=1440:1080"
- HDTV
-vf "scale=5760:4320"
- YouTube 8k Bracket Use
If you keep things interlaced then you may need a -vf "scale=interl=1"
in the path to ensure 4:2:0 interlaced-aware chroma scaling.
AviSynth/VapourSynth - Also have filters like Spline16 wich are widly used.
Today you have AVC/H.264 used with your common MP4 files from the last 15 years, then you have the modern HEVC/H.265 used over the last decade on phones/UHD blu-ray using the mp4/mov container or mkv if recorded with desktop applicaitons.
Note for UHD Blu-ray players and modern devices, 4:2:0 10-bit H.265 encoding can be used with -pix_fmt yuv420p10
.
-c:v libx264
will signal to use the AVC/x264 encoder.
-c:v libx265
will signal to use the HEVC/x265 encoder. (Nearly half the file size of AVC)
-crf = constant rate factor. 0 is mathematically lossless, 18 is deemed near-transparent and visually close-to-lossless. Default is 23. (Order of magnitude - decreasing crf by 6 doubles file size, increasing crf by 6 halves file size approx)
-pix_fmt yuv420p -vcodec libx264 -crf 0 -aspect 768:576 'colourbars.mp4'
H.264/AVC using the x264 encoder is a good solution for playback on older consumer devices (it's the Blu-ray format and used for HDTV in most of Europe).
For graphics card accelerated encoding use -hwaccel
for AMD and Nvidia -hwaccel cuda
at the start of your command just after ffmpeg
.
A container or wrapper as its commonly referred to as is what holds your audio video data for example "mp4" is not a format is a container.
.mov
is QuickTime and .mkv
is Mastroska, .wav
is almost always uncompressed PCM and .flac
is FLAC compressed audio.
Today .mov
is ideal for consumer devices and .mxf
for editors, and .mkv
is suitable for archival and media server use but also works with resolve today so is what most people will stick to.
Standard 4:3 and Widescreen 16:9
-aspect 768:576
This flags the display aspect ratio as square pixel 'PAL' but leaves the video as 928x576 within the codec. It's then up to the player to handle the scaling. I keep the vertical resolution the same to avoid a vertical scale. Effectively the two different figures let the player calculate the pixel aspect ratio - as it is non-square for most SD video formats - 4fSC and Rec.601 4:3 or 16:9.
If you haven't deinterlaced to 50p with a deinterlacer and want native interlaced output:
-flags +ildct+ilme
force FFmpeg to encode native interlaced (using interlaced DCT and motion estimation) rather than progressive.
If this is not defined the field store
flag will most likely be set to progressive.
Example Command
-pix_fmt yuv420p -vcodec libx264 -crf 0 -flags +ildct+ilme -aspect 768:576 'colourbars.576i.mp4'
-color_range tv
defines 16-255 Limited TV Display Levels (Black Range)
-color_range pc
defines 0-255 Full Desktop Monitor Levels (Black Range)
-color_primaries bt470bg -colorspace bt470bg
Defines PAL colour space.
-color_primaries smpte170m -colorspace smpte170m
Defines NTSC colour space.
-color_trc bt709
transfers the colour space for SD content being displayed on HDTVs
For compatibility with consumer video devices you need to go from 4:2:2 10-bit / 4:4:4 16-bit to 4:2:0 8-bit -
which -pix_fmt yuv420p
will do.
-pix_fmt yuv444p10le
10-bit 4:4:4 - Full Information
-pix_fmt yuv422p10le
10-bit 4:2:2 - Covers SD Colour Entirely (Editing/Archive)
-pix_fmt yuv420p
8-bit 4:2:0 - Supported by any digital playback device (Smart TV, Smartphone, Blu-Ray Player etc)
This segment deals with how to handle audio.
LaserDiscs mostly contain standard 2 channel left/right stereo.
This is decoded to a standard output.pcm
file ready for FFmpeg encoding/remuxing with a video file.
The analog track on some discs can be slightly slower than the video, digital, and AC3 tracks.
The best way to workaround this currently is to use a lower samplerate value when importing/encoding the PCM file, between 44085
and 44089
and then resampling to 44100
which effectivly "stretches" the audio to fit correctly.
Some LaserDiscs provide bilingual/dual-mono sound. This is where the stereo audio is two independent mono tracks.
To map this correctly through FFmpeg use a command similar to the following:
ffmpeg -i stereo.wav -map_channel 0.0.0 left.wav -map_channel 0.0.1 right.wav
4.0 Matrix - AC3
5.1 Surround - DTS
Digital audio was one of the main benfits of LD when it came out, as until this point only 35mm & 16mm film prints was common to have digital audio tracks optically off to the side, this also included 5.1 surround audio.
Using ffmpeg
you can embed multiple audio tracks into a video container.
For any PCM files you will need to tell ffmpeg
the format of the
audio before you include it with -f s16le -r 44.1k -ac 2
.
Then you can use the normal -i $filename
include it.
You can then -map
the included audio files using the ID numbers for the streams (which start at 0 and include all
inputs). You will likely always be outputting to a single file as well.
So to map the second included file's audio to the output video you would map
-map 1:a:0
. This can be done for any kind of audio inputs.
You may also want to adjust the channel of tracks, for AC3 discs you may want to convert from AC3 encoded audio to PCM and specifying for example:
-channel_layout:a:1 "5.1" -c:a:1 pcm_s16le -osr 44100
Note
Where a:1
is the output audio track will correct the sample rate, re-encode it, and set it as
5.1 surround.
You will then likely want to use
-filter_complex "[3:a]channelsplit=channel_layout=stereo[left][right]"
where 3:a
is the input ID for the analog audio.
Then you can -map "[left]"
to only include the left channel analog audio channel in your output file.
ld-chroma-decoder --decoder ntsc3d -p y4m -q "$input" | ffmpeg -y -i - \
-i digital-audio.dts \
-f s16le -ar $analog_rate -ac 2 -i output.pcm \
-i ffdata \
$srt \
$vcodec $vfilter \
-map 0:v:0 \
-map 2:a:0 \
-metadata:s:a:0 title="Analog Stereo" \
-c:a:0 $stereo -ar 44100 \
-map 1:a:0 \
-metadata:s:a:1 title="PCM Surround" \
-channel_layout:a:1 "5.1" \
-c:a:1 pcm_s16le \
-map_metadata 4 \
output.mov 2>&1 | tee -a log/ffmpeg.log
ld-export-metadata
chapters and subtitles (as SRT) can be embedded in the
output file.
Chapters from the --ffmetadata
option and be included with
-map_metadata 4
where 4
is the input file ID.
Subtitles can be included with -map 5:s:0 -c:s mov_text -metadata:s:s:0 language=eng
where 5:s
is
the input ID.
The -c:s mov_text
is for an MOV file and will be different
for other video containers.
Direct RAW FFmpeg Usage
ffmpeg -f rawvideo -r 25 -pix_fmt rgb48 -s 928x576 -i "input.rgb"
This will take a PAL input.rgb
source - tell it the source is raw video, at 25 frames per second, in RGB48 format and 928x576 resolution.
ffmpeg -i "input.y4m"
This will take a input.y4m
source and automatically determine the framerate, pixel format, and resolution.
Previous Page Home