Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
3rd February 2018, 16:32 | #1 | Link |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,031
|
VideoTek (Avisynth and MPV Waveform Monitor)
Hi,
I love the Tektronix Videoscope I have at work, but I can't use it at home, that's why I tried to reproduce a similar output using Avisynth built-in videoscope (Histogram). Please welcome VideoTek, a Tektronix-like waveform monitor for Avisynth and MPV. VideoTek() (Avisynth Version) - VideoTek (MPV Version) picture (top left), luma (top right) chroma (bottom left), audio channels and Lissajou (bottom right) Avisynth Usage: just call the function: VideoTek() in your script MPV Usage: Press "Y" to turn on the waveform monitor while you're playing back a video. Please note that due to the limitation of LAV Filter Complex, the MPV version is slightly different from the Avisynth Version: Changelog: v0.5 Crappy original version by FranceBB v0.6 Commit by magiblot v0.7 Major code cleanup by StainlessS v0.8 Added 6ch display with the graph of the first two by Stainless v0.9 Fixed a bug occurring with 1ch in the Lissajou graph by Stainless v1.0 Added yv16 and yv24 planar 8bit support by FranceBB v1.1 Introduced High Bit Depth Support, Frame Properties, Timecode and Luma Values in Volts by FranceBB v1.2 Added support to all color spaces and code cleanup by StainlessS v1.3 Added MPV Support by Algie v1.4 Added frame properties support by FranceBB v1.5 Improved small monitor image conversion and fixed a bug that would sometimes report invalid info at the bottom on the left by FranceBB v1.6 Added Fractional Framerates Support. v1.7 Implemented the new VideoTek(Mode="PQ") with the new 0.406V 58% Reference White marker v1.8 Implemented new "Type" parameter to allow nits display instead of volts VideoTek(Mode="HLG", Type="nits"), but by default Type="volts". v1.9 Introduced Type="nits" support for the recently introduced PQ Mode to display the 0, 203, 1000, 5000 and 10000 nits markers and Detailed=true to see all the 1k nits increments. Cheers. Last edited by FranceBB; 17th May 2024 at 17:08. |
3rd February 2018, 23:25 | #2 | Link |
Registered User
Join Date: Sep 2006
Posts: 1,657
|
To me the real deal of Tektronix's hardware is the double diamond vectorscope, it makes color matching looks so easy. But I think they patented it.
https://www.youtube.com/watch?v=8NTLqybQQSU |
4th February 2018, 16:12 | #3 | Link |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,031
|
@lansing... yep, that's really useful, but I mainly work on post-production, so this is how I set it:
Tektronix - Avisynth Another example: https://i.imgur.com/EF3VWbu.png |
6th February 2018, 20:50 | #4 | Link |
Registered User
Join Date: Sep 2006
Posts: 1,657
|
Taking more look into the screenshot, the proportion of the graphs should be independent from the video window, they shouldn't be scaled 16:9 along with the video. And there needs to be boxes in the vectorscope to indicate the legal saturation range for standard definition and high definition. Also the wave form needs to have a some kind of indication of brightness, such as percentage.
I have a video only clip and it just return an error because I don't have an audio. Last edited by lansing; 6th February 2018 at 20:57. |
21st July 2018, 11:07 | #5 | Link |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,031
|
I updated it to a newer version. It's supposed to automatically detect the audio channels number and make a graph accordingly, but... it doesn't work... I think I broke my own code xD
Do you have any idea why it doesn't show the audio graph anymore? |
21st July 2018, 12:06 | #7 | Link |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,031
|
That's the thing. I'd like to use Overlay(audio_levelsx) according to how many channels are detected, but I don't know how to do it.
Last edited by FranceBB; 21st July 2018 at 12:33. |
21st July 2018, 13:41 | #8 | Link |
Eurobeat Fan
Join Date: Sep 2014
Posts: 108
|
No problem
Try with the following changes: Code:
source_audio_channels = clp.AudioChannels() #Does this return 0 if there is no audio? myaudio = (source_audio_channels==0) ? GetChannels(myfakeaudio, 1, 2) : \ (source_audio_channels==1) ? GetChannels(clean, 1) : \ (source_audio_channels==2) ? GetChannels(clean, 1, 2) : \ (source_audio_channels==3) ? GetChannels(clean, 1, 2, 3) : \ (source_audio_channels==4) ? GetChannels(clean, 1, 2, 3, 4) : \ (source_audio_channels==5) ? GetChannels(clean, 1, 2, 3, 4, 5) : \ (source_audio_channels==6) ? GetChannels(clean, 1, 2, 3, 4, 5, 6) : \ (source_audio_channels==7) ? GetChannels(clean, 1, 2, 3, 4, 5, 6, 7) : \ (source_audio_channels==8) ? GetChannels(clean, 1, 2, 3, 4, 5, 6, 7, 8) : \ NOP() for_audio_levels = AudioDub(myblack, myaudio) audio_levels = for_audio_levels.Histogram("audiolevels").Crop(0, 0, -736, -0).BilinearResize(340, 420) my_audio_levels_overlay = Overlay(audio_levels, x=700, y=450, opacity=1.0, mode="blend", greymask=true, ignore_conditional=false, pc_range=false) final=Overlay(my_audio_levels_overlay) #you will probably want to add additional parameters |
21st July 2018, 14:10 | #9 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,992
|
Where is 'mylissajou' supposed to come from ? (what histogram or whatever plug).
EDIT: Histogram(mode="StereoOverlay") ???
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 21st July 2018 at 14:13. |
21st July 2018, 15:02 | #10 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,992
|
Looks about right, might need [EDIT: WILL NEED] some adjustment to dimension, overlay coords.
Have used Histogram(mode="StereoOverlay") for the mylissajou thing, hope that its correct. Code:
#simple Videoscope by FranceBB:- https://forum.doom9.org/showthread.php?t=175249 #it resembles Tektronix WVR 7020 #Accepts 8bit clip only. It works internally in 4:2:0 (yv12) #Accepts up to 8 audio channels Function VideoTek(clip clp) { clp nChannels=(HasAudio)?AudioChannels:0 # ssS, HasAudio = audio_samples_per_second!=0 #Assert block Assert(IsYV12,"VideoTek: source must be yv12 (YUV 4:2:0 8bit)") # Assert(IsFrameBased, "VideoTek: source must be progressive") # ssS, IsFrameBased means SeparateFields NOT used, does not indicate Progressive Assert(nChannels<9,"VideoTek: sources with more than 8 audio channels are not supported") SilentStereo=Last.BlankClip(width=1480, height=920,audio_rate=48000,channels=2,sample_type="Float") myBlack= (nChannels>0) ? SilentStereo.AudioDubEx(Last) : SilentStereo.Killaudio Stereo = (nChannels>=2) ? Last.GetChannels(1,2) : (nChannels==1) ? MergeChannels(GetChannels(1),GetChannels(1)) : SilentStereo StereoClip = Last.BlankClip(width=460,height=460).AudioDub(Stereo) # Histogram(mode="StereoOverlay") requires 2 channel only clip. clean1=PointResize(704, 396) Picture = clean1 luma = clean1.TurnRight.Histogram(mode="classic").TurnLeft.Crop(0,0,0,256).BilinearResize(704, 396) chroma = clean1.Histogram("color2").Crop(704, 0, 256,256).BilinearResize(480,480) Audio = myBlack.Crop(0,0,340,420).Histogram(Mode="audiolevels") mylissajou = StereoClip.Histogram(mode="StereoOverlay") # Dont know where to get lissajou from, so improvised Result = MyBlack Result = Result.Overlay(Picture, x=0, y=0) # ssS, Removed all of the Optional Args assigned with Defaults Result = Result.Overlay(luma, x=710, y=0) Result = Result.Overlay(chroma, x=100, y=430) Result = Result.Overlay(Audio, x=700, y=450) Result = Result.Overlay(mylissajou, x=1000,y=450) return Result } Untested with more than 2 channels. [EDIT: or with single channel, tested on 0 and 2 channels only] Code:
ColorBars(Pixel_Type="YV12") VideoTek Return Last.Spline64Resize(854,480) EDIT: Below bottom right image is more like what I remember as lissajou figure [EDIT: perhaps samplerate just too low] EDIT: Quote:
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 21st July 2018 at 23:35. |
|
21st July 2018, 17:55 | #11 | Link |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,031
|
Thank you magiblot and StainlessS
@StainlessS... yes, it's Histogram(mode="StereoOverlay"). The idea is to pick both Left and Right channel when stereo and pick just Front Left and Front Right when is Dolby. It might not be as complex and detailed as the official waveform provided by Tektronix, but it kinda reminds its layout and it uses the internal filters already available in Avisynth, so I thought it was kinda cool to have a similar layout. ^_^ Thank you both, once again, this is exactly what I wanted. ^_^ |
21st July 2018, 18:32 | #12 | Link | ||
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,992
|
bugFix,
was Code:
Stereo = (nChannels>=2) ? Last.GetChannels(1,2) : (nChannels==2) ? MergeChannels(GetChannels(1),GetChannels(1)) : SilentStereo Code:
Stereo = (nChannels>=2) ? Last.GetChannels(1,2) : (nChannels==1) ? MergeChannels(GetChannels(1),GetChannels(1)) : SilentStereo Fixed in prev post. EDIT: Your original Big Buck Bunny Link (downsized to 854,480) And current script(approx same frame, needs some coords fixed a bit) EDIT: Quote:
Quote:
Code:
reference: channel 1: channel 2: channel 3: channel 4: channel 5: channel 6: 5.1 WAV front left front right front center LFE rear left rear right
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 21st July 2018 at 20:18. |
||
21st July 2018, 22:12 | #13 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,992
|
Bit more fiddling about.
Code:
Function VideoTek(clip clp) { clp nChannels=(HasAudio)?AudioChannels:0 # ssS, HasAudio = audio_samples_per_second!=0 Assert(IsYV12,"VideoTek: source must be yv12 (YUV 4:2:0 8bit)") Assert(nChannels<9,"VideoTek: sources with more than 8 audio channels are not supported") CSZ = 480 # Chroma Size box (W & H) A_W = 320 # Audio Box Width A_H = 460 # Audio Box Height (Audio & Lissajoua) L_W = (704+704+6)-700-A_W # Lissajous Width SilentStereo=Last.BlankClip(width=1480, height=920,audio_rate=48000,channels=2,sample_type="Float") myBlack= (nChannels>0) ? SilentStereo.AudioDubEx(Last) : SilentStereo.Killaudio Stereo = (nChannels>=2) ? Last.GetChannels(1,2) : (nChannels==1) ? MergeChannels(GetChannels(1),GetChannels(1)) : SilentStereo StereoClip = Last.BlankClip(width=16,height=16).AudioDub(Stereo) # Histogram(mode="StereoOverlay") requires 2 channel only clip. Picture = BicubicResize(704, 396) luma = TurnRight.Histogram(mode="classic").TurnLeft.Crop(0,0,0,256).BiCubicResize(704, 396) chroma = Histogram("color2").Crop(clp.Width, 0, 0,256).BilinearResize(CSZ,CSZ) Audio = myBlack.Crop(0,0,A_W,A_H).Histogram(Mode="audiolevels") lissajous = StereoClip.Histogram(mode="StereoOverlay").BicubicResize(L_W,A_H) MyBlack Overlay(Picture, x=0, y=0) Overlay(luma, x=704+6, y=0) Overlay(chroma, x=(704-chroma.Width)/2,y=396 + (920-396-chroma.height)/2) Overlay(Audio, x=704-4, y=396 + (920-396-audio.height) /2) Overlay(lissajous, x=700+Audio.Width, y=396 + (920-396-lissajous.height) /2) return Last } Code:
CSZ = 480 # Chroma Size box (W & H) A_W = 320 # Audio Box Width A_H = 460 # Audio Box Height (Audio & Lissajoua) L_W = (704+704+6)-700-A_W # Lissajous Width if too slow, then change BiCubics to BiLinear. EDIT: Added Levels() on Lissajous trying to make more visible, only minor improvement (before downsize). Here, downsized, EDIT: In Steinberg, I think that the Lissajous thing is known as Phase (or Phase Scope), when spreads out horizontally, is broader stereo, if dot or vertical line, then is mono, height being amplitude (I guess FranceBB, already knows this). The Phase Scope, shows info from only first two channels (Left & Right, it is stereo specific, perhaps eg 5.1 should be downmixed somehow). EDIT: Moved Levels() before BiCubicResize() for Lissajous. (Levels improvement is only on the cross hair thing, is a bit more visible on FranceBB linked image than in this script) EDIT: Changed Levels 126-4 and 126+4, to 126-1, 126+1. (126 being TV levels mid point) Code:
lissajous = StereoClip.Histogram(mode="StereoOverlay").Levels(126-1,1.0,126+1,16,235,coring=false).BicubicResize(L_W,A_H) Code:
Stereo = (nChannels>=2) ? Last.GetChannels(1,2) : (nChannels==1) ? MergeChannels(GetChannels(1),GetChannels(1)) : SilentStereo
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 22nd July 2018 at 00:24. |
23rd July 2018, 08:23 | #14 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,992
|
FrancBB, I see your there,
NOTE, the bug that crept back in is also present in your 1st post, must have edited on-line and forgot to make same bug fix in my script and then made mod with unfixed script. (2nd last edit in above post).
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? |
23rd July 2018, 10:38 | #15 | Link | |||
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,031
|
Quote:
Quote:
Quote:
Anyway, thank you for modifying the code. I owe you a beer. Perhaps, one day, when there'll be perfect 3D scanners... xD |
|||
9th November 2020, 03:05 | #17 | Link |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,031
|
Version 1.1 Released:
- Introduced High Bit Depth Support (***) - Introduced Frame Properties and Timecode - Introduced Luma Values in Volts *** I actually cheated as I'm doing things in 8bit planar, however it works as bit-shifting is done in a way that preserves fullrange/limitedrange values In the bottom left, you're now gonna see the resolution, framerate, colorspace and bit depth of the clip you indexed and on the bottom right you're gonna see the timecode which scales according to the framerate, just like you would in the Tektronix waveform monitor (or in a Sony VTR). I'm glad you like it. I wanted to bring those waveform monitors to Avisynth so that I could check the files I encode before sending them to the QC guys without having to be in the office with my workstation connected to a piece of hardware via SDI. |
9th November 2020, 03:45 | #18 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,992
|
FBB,
Some Comments flagged by ssS: Code:
Function VideoTek(clip clp) { clp nChannels=(HasAudio)?AudioChannels:0 # HasAudio = audio_samples_per_second!=0 #Errors checking Assert(IsPlanar && IsYUV, "VideoTek: source must be planar YUV") # ssS: IsPlanar simpler than IsYV12 etc Assert(nChannels<9,"VideoTek: sources with more than 8 audio channels are not supported") #Getting info #Resolution x=clp.Width() y=clp.Height() #Framerate fps=clp.FrameRate() # ssS: Not FrameRateNumerator (check Src with eg Assumefps(30000,1001) #ColorSpace colorspace=clp.PixelType() #Taking care of High bit Depth Bpc = clp.BitsPerComponent clp.ConvertBits(bits=8) # ssS: If already 8 bits then ConvertBits should do nothing anyway (return original) # ... Appended testcode after your script, in the avs Code:
AviSource("d:\Parade.avi") Assumefps(30000,1001) # Test FrameRate # UnComment ONLY ONE of below #ConvertToRGB32 # RGB32 #ConvertToRGB24 # RGB24 #ConvertToYUY2 # YUY2 #ConvertToYV12 # YV12 # v2.60 + #ConvertToYV411 # YV411 #ConvertToYV16 # YV16 #ConvertToYV24 # YV24 #ConvertToY8 # Y8 # Avs+ #ConvertToRGB48 # RGB48 Intereleaved RGB 16 bit #ConvertToRGB64 # RGB64 Intereleaved RGBA 16 bit # ... + Loads more # 32 Bit Float #ConvertToRGB48.ConvertToPlanarRGB.ConvertBits(32) # RGBPS #ConvertToRGB64.ConvertToPlanarRGBA.ConvertBits(32) # RGBAPS #ConvertToY8.ConvertBits(32) # Y32 #ConvertToYV12.ConvertBits(32) # YUV420PS #ConvertToYV16.ConvertBits(32) # YUV422PS #ConvertToYV24.ConvertBits(32) # YUV444PS #ConvertToYV12.ConvertBits(32).AddAlphaPlane # YUVA420PS #ConvertToYV16.ConvertBits(32).AddAlphaPlane # YUVA422PS ConvertToYV24.ConvertBits(32).AddAlphaPlane # YUVA444PS ################### Videotek EDIT: More mods, posted on SendSpace. [also, removed references to clp after initializing Last]. Code:
Function VideoTek(clip clp) { clp nChannels=(HasAudio)?AudioChannels:0 # HasAudio = audio_samples_per_second!=0 #Errors checking # ssS: Might as well do at beginning (after errchk, known Planar YUV & < 9 channels) # Assert(IsPlanar && IsYUV, "VideoTek: source must be planar YUV") # ssS: IsPlanar simpler than IsYV12 etc Assert(nChannels<9,"VideoTek: sources with more than 8 audio channels are not supported") #Getting info #Resolution x=Width() y=Height() #Framerate fps=FrameRate() # ssS: Not FrameRateNumerator (check Src with eg Assumefps(30000,1001) #ColorSpace colorspace=PixelType() #Taking care of High bit Depth Bpc = BitsPerComponent # ConvertBits(bits=8) # ssS: If already 8 bits then ConvertBits should do nothing anyway (return original) ConvertToYUV444.ConvertBits(bits=8) # ssS: Convert To YV444, 8 bit, support all colorspace input # ... EDIT: Fixed Error in either Avs+ or VD2. Bug report here in devs forum:- https://forum.doom9.org/showthread.p...58#post1927858 fix [Updated script on SendSpace] Code:
Function VideoTek(clip clp) { clp nChannels=(HasAudio)?AudioChannels:0 # HasAudio = audio_samples_per_second!=0 #Errors checking Assert(nChannels<9,"VideoTek: sources with more than 8 audio channels are not supported") #Getting info #Resolution x=Width() y=Height() #Framerate fps=FrameRate() #ColorSpace colorspace=PixelType() #Taking care of High bit Depth Bpc = BitsPerComponent ConvertToYUV444 (HasAlpha) ? RemoveAlphaPlane : NOP # ssS: Avoid eg YUVA444 error in VirtualDub2 (OK in PotPlayer but grey screen in VD2 if YUVA) ConvertBits(bits=8) # ssS: Convert To YUV444, 8 bit, NO ALPHA, support all colorspace input # ...
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 9th November 2020 at 06:27. |
9th November 2020, 09:06 | #19 | Link |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,031
|
Woah, thank you for that!
I just tested it, it works like a charm. I've just updated the code on GitHub. Version 1.2 released. Updated Changelog: v1.2 Added support to all planar color spaces and code cleanup by StainlessS p.s if you have a GitHub account, I'll give you full access to the repository p.p.s you know why I used millivolt (or rather Volts) as a measurement instead of putting 16-235 in the luma monitor? 'cause Volt levels are the same for each signal, no matter the bit depth, while bit values (16-235) change with bit depth (like 10bit, 64-940 etc) and I didn't want to write a conditional based on that xD Still, the Tektronix engineers did the same and showed Volts as scale, so... I guess it's fine. xD Last edited by FranceBB; 9th November 2020 at 09:09. |
9th November 2020, 17:20 | #20 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,992
|
Quote:
"v1.2 Added support for all input color spaces ..." I will not remove my prev post, as it gives some background to bugrep in devs forum. EDIT: Nope, no GitHub account just yet, one day maybe. Temp VideoTek.avs removed from SendSpace.
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 9th November 2020 at 17:36. |
|
Thread Tools | Search this Thread |
Display Modes | |
|
|