This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Luma Scale Considerations and the "Full Luma Range" option.

Tags: None
(comma "," separated)
Inapickle
Registered Member
Posts
157
Karma
3
OK, before demonstrating how to apply the Vapoursynth version of the SmoothLevels filter, I just wanted to clarify a few points about the ffms2 and L-SmashSource filters.

In the above tests and examples I've been using a 1080/30PF.mts sample clip from a Canon HF-G10 AVCHD camcorder (the one with the Jester). Although the AVISynth version of L-SmashSource is able to load a wide range of video formats, there is an issue at this time loading AVCHD.mts clips (from Canon, Panasonic and Sony models) with the VapourSynth version. An index file is generated but VapourEditor crashes when reading it. Same occurs when piping to FFMPEG. Remuxing to mkv makes no difference. I tried compiling the plugin from git myself and it's the same thing. As I understand this bug emerged after a massive internal reading code update. It is unclear if and when this issue will be fixed.

That being the case, ffms2 is the only option at this time for loading these mts sources in VapourSynth. However, as I indicated a few posts back, there was also a bug loading the ffms2 plugin included in the last "Extra Plugins" package update from the ppa:djcj/vapoursynth repository. Last notification from the maintainer was that the problem has been identified and that an update can be expected soon. Meanwhile, if anyone has a burning need to run these Vapoursynth routines with AVCHD.mts footage, the following procedure for compiling the ffms2 plugin from git should work:

1.Download the ffms2-master zip file from here:
https://github.com/FFMS/ffms2
2.Extract the 'ffms2-master' folder (to Home directory)
3.Get these packages:
Code: Select all
sudo apt-get install pkg-config libavutil-dev libavformat-dev libavcodec-dev libswscale-dev libavresample-dev zlib1g-dev
and then
Code: Select all
cd ffms2-master
./configure --enable-shared --disable-static
make
cp src/core/.libs/libffms2.so ffms2.so
4.The built ffms2.so plugin will be located the ffms2-master folder. Copy it to the VapourSynth plugins folder. On my system, Kubuntu 15.10 (AMD 64), that is located at:
Code: Select all
/usr/lib/x86_64-linux-gnu/vapoursynth

So, on to the applying the SmoothLevels filter. And for that we need to incorporate two scripts - havsfunc and mvsfunc
1. Download the zip files from here:
https://github.com/HomeOfVapourSynthEvolution/havsfunc
https://github.com/HomeOfVapourSynthEvolution/mvsfunc
2. Extract the zip files and copy the havsfunc.py and mvsfunc.py script files to Python\Lib\site-packages. If you followed the procedure for installing VapourSynth on Kubuntu 15.10 as described earlier (viewtopic.php?f=272&t=130641&start=30#p350999) that will be located at:
Code: Select all
/usr/local/lib/python3.4/site-packages
Now we can set-up the Vapoursynth script. For loading 16-255 luma range HD-AVC.mp4 or mov clips (e.g from Canon HF-G30 or Panasonic DSLR's) the L-SmashSource (LWLibavSource) filter should work just fine:
Code: Select all
import vapoursynth as vs
import havsfunc as haf
core = vs.get_core()
clip = core.lsmas.LWLibavSource(source=r"Path...../Video.mp4")
#
#Scale 16-255 luma to 16-235:
#clip = core.std.Levels(clip, min_in=16, gamma=1.0, max_in=255, min_out=16, max_out=235, planes=0)
clip = haf.SmoothLevels(clip, 16, 1.0, 255, 16, 235)
#
#Assert source framerate e.g. for 60p
clip = core.std.AssumeFPS(clip,fpsnum=60000, fpsden=1001)
#
#clip = core.hist.Levels(clip)
clip.set_output()

So there we have the two "Levels" filters. The built-in one:
Code: Select all
clip = core.std.Levels(clip, min_in=16, gamma=1.0, max_in=255, min_out=16, max_out=235, planes=0)
and the SmoothLevels filter imported with havsfunc:
Code: Select all
clip = haf.SmoothLevels(clip, 16, 1.0, 255, 16, 235)

For loading 16-255 luma range AVCHD.mts clips recorded in 30/25PF format (as used in Canon AVCHD camcorders ) with ffms2, some added measures are needed to account for the nuances of the PF (Progressive Segmented Frame) format and how ffms2 handles it. For anyone not familiar with the PF (PsF) format - as mentioned earlier (viewtopic.php?f=272&t=130641&start=30#p350999) this is progressive content (with progressive pattern YV12 4:2:0 chroma sub-sampling) encoded with a field_pic_flag structure (and MBAFF syntax) - meaning it is flagged as interlaced. This is purely to satisfy the Blu-Ray/AVCHD standards which don't permit 30p and 25p. Often this is referred to as "30p/25p wrapped in 60i/50i" which is not correct. It has nothing to do with the container. It is hard-coded in the H.264 stream.

A quirk of the ffms2 source plugin when handling interlace-flagged sources is that it that the field rate gets reported as the frame-rate and so, if not corrected, it outputs duplicated frames at double rate. To avoid this it is necessary to set the true frame rate of the source video. And we add another two lines to assert (assume) that the output from ffms2 is progressive (frame based).

So taking the example of the Canon HF-G10 1080/30PF clip used in the tests, the script looks like this:
Code: Select all
import vapoursynth as vs
import havsfunc as haf
core = vs.get_core()
clip = core.ffms2.Source("Path....../TestHFG10.mts",fpsnum=30000,fpsden=1001)
#Assume Progressive (Frame Based):
clip = core.std.SetFrameProp(clip, prop="_FieldBased", intval=0)
clip = core.std.SetFrameProp(clip, prop='_Field', delete=True)
#
#Scale 16-255 luma to 16-235:
#clip = core.std.Levels(clip, min_in=16, gamma=1.0, max_in=255, min_out=16, max_out=235, planes=0)
clip = haf.SmoothLevels(clip, 16, 1.0, 255, 16, 235)
#
clip = core.std.AssumeFPS(clip,fpsnum=30000,fpsden=1001)
#clip = core.hist.Levels(clip)
clip.set_output()

To restore the original 16-255 luma scaling after rendering out to one of the lossless formats, one would apply the 'levels' filters again. But now the L-SmashSource (LWLibavSource) filter could be used for loading the rendered file, instead of ffms2:
Code: Select all
import vapoursynth as vs
import havsfunc as haf
core = vs.get_core()
clip = core.lsmas.LWLibavSource(source=r"Path......./Editedvideo.mkv")
#
#Scale compressed 16-235 luma back to 16-255:
#clip = core.std.Levels(clip, min_in=16, gamma=1.0, max_in=235, min_out=16, max_out=255, planes=0)
clip = haf.SmoothLevels(clip, 16, 1.0, 235, 16, 255)
#
clip = core.std.AssumeFPS(clip,fpsnum=30000,fpsden=1001)
#clip = core.hist.Levels(clip)
clip.set_output()
OK, I think that's enough. Didn't really want to turn this into a VapourSynth tutorial. But the routines I've described do at least provide an alternative approach to generating transcodes for input into KDenLive, as well as means of restoring the original luma scaling of sources that have been edited and rendered with compressed (16-235) scaling. Hope some find it useful.
Inapickle
Registered Member
Posts
157
Karma
3
Update regarding:
Inapickle wrote:....... I just wanted to clarify a few points about the ffms2 and L-SmashSource filters.

In the above tests and examples I've been using a 1080/30PF.mts sample clip from a Canon HF-G10 AVCHD camcorder (the one with the Jester). Although the AVISynth version of L-SmashSource is able to load a wide range of video formats, there is an issue at this time loading AVCHD.mts clips (from Canon, Panasonic and Sony models) with the VapourSynth version. An index file is generated but VapourEditor crashes when reading it. Same occurs when piping to FFMPEG. Remuxing to mkv makes no difference. I tried compiling the plugin from git myself and it's the same thing. As I understand this bug emerged after a massive internal reading code update. It is unclear if and when this issue will be fixed.

That being the case, ffms2 is the only option at this time for loading these mts sources in VapourSynth. However, as I indicated a few posts back, there was also a bug loading the ffms2 plugin included in the last "Extra Plugins" package update from the ppa:djcj/vapoursynth repository. Last notification from the maintainer was that the problem has been identified and that an update can be expected soon. Meanwhile, if anyone has a burning need to run these Vapoursynth routines with AVCHD.mts footage, the following procedure for compiling the ffms2 plugin from git should work:

1.Download the ffms2-master zip file from here:
https://github.com/FFMS/ffms2
2.Extract the 'ffms2-master' folder (to Home directory)
3.Get these packages:
Code: Select all
sudo apt-get install pkg-config libavutil-dev libavformat-dev libavcodec-dev libswscale-dev libavresample-dev zlib1g-dev
and then
Code: Select all
cd ffms2-master
./configure --enable-shared --disable-static
make
cp src/core/.libs/libffms2.so ffms2.so
4.The built ffms2.so plugin will be located the ffms2-master folder. Copy it to the VapourSynth plugins folder. On my system, Kubuntu 15.10 (AMD 64), that is located at:
Code: Select all
/usr/lib/x86_64-linux-gnu/vapoursynth

So, on to the applying the SmoothLevels filter. And for that we need to incorporate two scripts - havsfunc and mvsfunc
1. Download the zip files from here:
https://github.com/HomeOfVapourSynthEvolution/havsfunc
https://github.com/HomeOfVapourSynthEvolution/mvsfunc
2. Extract the zip files and copy the havsfunc.py and mvsfunc.py script files to Python\Lib\site-packages. If you followed the procedure for installing VapourSynth on Kubuntu 15.10 as described earlier (viewtopic.php?f=272&t=130641&start=30#p350999) that will be located at:
Code: Select all
/usr/local/lib/python3.4/site-packages
There was another ppa update of the VapourSynth "Extra Plugins" package last night (20160230-1~wily). Unfortunately I'm now experiencing a further problem with the ffms2 source filter. When loading a basic script in VSEditor and opening Preview, the plugin will now load, and index file will be created and the scripted video will display in Preview. But on attempting to re-open Preview, it will freeze-up. This happens with any video format, not just AVCHD.mts clips. Tried replacing the ffms2 plugin with one compiled from git (as described above), but the same result. Tried completely removing and reinstalling VapourSynth and associated packages, but the same issue. I've notified the ppa maintainer about it.

If you have experienced the same issue with this update, best I can suggest for now is not trying to use ffsms2 at all and using only the L-Smash (LWLibavSource) filter. Unfortunately, for native AVCHD.mts clips the only workaround is to first transcode to one of the lossless formats (UTVideo, HuffYuv etc) using ffmpeg or a KDEnLive transcode preset. The transcode should then load with LWLibavSource with the 16-255 luma range preserved.
Inapickle
Registered Member
Posts
157
Karma
3
A further update on the status of the ffms2 and L-SmashSource filters for VapourSynth.

As regards ffms2; there was a further ppa update of the "Extra Plugins" pack (20160306-1~wily) and VapourSynth Editor (5-1ppa1~wily) last night and it appears that the "Preview hang" issue in VS Editor, has finally been fixed. However, my recommendation would still be to avoid using ffms2 for loading native AVCHD.mts clips. Another issue that has come to light (and reported by many) is that the current VapourSynth version of ffms2 does not respect the interlace-flagged field order of AVCHD.mts clips and is outputting Bottom Field First (BFF) instead of Top Field First (TFF). This is not so critical for 1080/30PF and 1080/25PF clips, but has disastrous consequences for processing native 1080/50i and 1080/60i mts clips. Unfortunately, setting the SetFrameProp filter to assume TFF does not correct this.

So what option does this leave for for loading AVCHD.mts then, given that the current VapourSynth version of L-SmashSource crashes with these clips ? Well, as I mentioned above, the "L-Smash crash bug" (as it has come to be known) arose after a massive internal reading code update in January. Consensus is that the last good working version before this rework was r859. For users of the Windows version of VapourSynth archived r859 L-SmashSource.dll's are readily available. For Linux however it means compiling the plugin from the r859 git commit. Here's the procedure:

1. Get the following pre-requisite compiler packages with Synaptic:

ffmpeg-dev packages (7:2.7.6-0ubuntu0.15.10.1 at the time of writing):

libavcodec-ffmpeg-dev
libavdevice-ffmpeg-dev
libavfilter-ffmpeg-dev
libavformat-ffmpeg-dev
libavresample-ffmpeg-dev
libavutil-ffmpeg-dev
libpostproc-ffmpeg-dev
libswresample-ffmpeg-dev
libswscale-ffmpeg-dev

git (1:2.5.0-1ubuntu0.1)
or
Code: Select all
sudo apt-get install git

checkinstall (1.6.2-4ubuntu1)
or
Code: Select all
sudo apt-get install checkinstall

2. Get, compile and install L-Smash from git:
Code: Select all
git clone git://github.com/l-smash/l-smash.git
cd l-smash
./configure --extra-cflags="-fPIC"
make -j$(nproc)
sudo checkinstall --pkgname=lsmash --pkgversion="0:$(git rev-list --count HEAD)-g$(git rev-parse --short HEAD)" \
--backup=no --deldoc=yes --delspec=yes --deldesc=yes --strip=yes --fstrans=no –default --stripso=yes –addso=yes
Locate the compiled deb file in “l-smash” folder in Home directory. Right click on file and install with Qapt Package Installer

3. Get L-Smash-WORKS from r859 git commit and compile L-SmashSource plugin:

Download the zipped L-Smash-WORKS pack from here:
https://github.com/VFR-maniac/L-SMASH-W ... 7af66f5b3f
Unzip to Home folder
If preferred, shorten the folder name L-SMASH-Works-58dd7bc1cc18338cb3f634cb3df1147af66f5b3f e.g. to 'L-SMASH-Works-r859'
Compile:
Code: Select all
cd L-SMASH-Works-r859/VapourSynth/
./configure
make -j$(nproc)
sudo checkinstall --pkgname=vslsmashsource --pkgversion="1:$(git rev-list --count HEAD)-g$(git rev-parse --short HEAD)" \
--backup=no --deldoc=yes --delspec=yes --deldesc=yes --strip=yes --stripso=yes --addso=yes --fstrans=no –default

Locate the compiled deb file in the 'L-SMASH-Works-r859' folder. Right click and install with Qapt Package Installer

The L-SmashSource plugin ( libvslsmashsource.so) will be installed by default to /usr/local/lib/vapoursynth/
To enable auto-loading, it needs to be moved or copied to /usr/lib/x86_64-linux-gnu/vapoursynth/
This is assuming that VapourSynth was installed from the ppa as per the procedure described earlier.
So:
Code: Select all
sudo mv /usr/local/lib/vapoursynth/libvslsmashsource.so /usr/lib/x86_64-linux-gnu/vapoursynth/
The existing lsmashsource.so plugin supplied by the ppa "Extra Plugins" pack, having a different name, will not be overwritten. However, I've observed no conflict and so it can be left there. By the same token, the compiled (r859) libvslsmashsource.so plugin will not be overwritten whenever the "Extra Plugins" pack is updated from the ppa.

It should now be possible to load AVCHD.mts clips into VapourSynth scripts using the LWLibavSource filter without crashing.

Two other aspects of processing AVCHD.mts clips with VapourSynth that are probably worth mentioning here are:

1. Converting 1080/50i and 1080/60i.mts clips to YUY2 (4:2:2), in which case the conversion is applied to the separated fields.
For example:

Code: Select all
import vapoursynth as vs
core = vs.get_core()
clip = core.lsmas.LWLibavSource(source=r"path........./Test60iclip.mts")
clip = core.std.SeparateFields (clip, tff=True)
clip = core.fmtc.resample (clip, css="422", interlaced=True)
clip = core.fmtc.bitdepth (clip, bits=8)
clip = core.std.DoubleWeave (clip, tff=True)
clip = core.std.SelectEvery (clip, cycle=2, offsets=0)
clip = core.std.AssumeFPS(clip,fpsnum=30000,fpsden=1001)
clip.set_output()

2. Processing of 1080/24PF AVCHD.mts clips. In this mode of recording used on some Canon camcorders, we have another representation of the "Progressive Segmented Frame" format, where the 23.976p content is flagged for 3:2 pulldown. That is to say it is "soft telecined" or what some refer to as "24p-in-60i", again purely to satisfy Bluray/AVCHD broadcast standards. To extract the 23.976p content in VapourSynth requires the following IVTC routine:
Code: Select all
import vapoursynth as vs
core = vs.get_core()
clip = core.lsmas.LWLibavSource(source=r"path........./Test24PFclip.mts")
#
clip = core.vivtc.VFM(clip, 1)
clip = core.vivtc.VDecimate(clip)
#
clip = core.std.AssumeFPS(clip,fpsnum=24000,fpsden=1001)
clip.set_output()

To convert to YUY2 (4:2:2) one would apply the conversion after the IVTC step:
Code: Select all
import vapoursynth as vs
core = vs.get_core()
clip = core.lsmas.LWLibavSource(source=r"path........./Test24PFclip.mts")
clip = core.vivtc.VFM(clip, 1)
clip = core.vivtc.VDecimate(clip)
clip = core.fmtc.resample (clip, css="422")
clip = core.fmtc.bitdepth (clip, bits=8)
clip = core.std.AssumeFPS(clip,fpsnum=24000,fpsden=1001)
clip.set_output()
Obviously this would also be with a view to applying the luma range manipulation procedures described earlier, which was the main reason for turning to these alternative VapourSynth transcode routines.

OK, I think that about covers everything relevant to the topic of discussion.


Bookmarks



Who is online

Registered users: Bing [Bot], blue_bullet, Google [Bot], Yahoo [Bot]