View Full Version : Detect sudden luma change
kolak
23rd July 2022, 13:04
How can I detect (fast) sudden change in luma? It's like you would overlay black frame on top of the original video with some opacity. Strength can vary from very strong to very settle, but always affects all pixels in the frame with same amount.
Scene changes should be of course not counted.
StainlessS
23rd July 2022, 18:50
Not enough info for anybody really. [seems like impossible task]
Single frame change, back to normal afterwards{easier}, OR, transition from one illuminant level to thereafter another illuminant level ?
{EDIT: Also Flash photography ? [only dark transition, or light also]}
Scene changes should be of course not counted.
The 'sudden' transition will often look like a scene change to scene change detectors [incl MvTools as detector].
Sample ?
Maybe tentatively suggest method {???} # only perhaps where biggish transition
if Detect Scene Change [ie sudden change] {
Transition = IsCorrelated(n,n-1) # Transition == Bingo : !Transition == Scene change
} else { Not transition }
RT_LumaCorrelation(clip c,clip c2,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,int "n2"=current_frame,
int "delta2"=0,int "x2"=x,int "y2"=y,bool "interlaced"=false,int "Matrix"=(Width>1100||Height>600||clip2.Width>1100||clip2.Height>600?3:2))
Returns FLOAT value luma correlation (-1.0 -> 1.0) between clip c frame (n+delta) area x,y,w,h, and clip c2 frame (n2+delta2) area x2,y2,w,h.
Note, 'x2' and 'y2' default to 'x' and 'y' respectively.
v2.0, c and c2 need not be same dimensions but BEWARE, x2 and y2 default to x and y also w and h default to 0
which is converted to c.width-x and c.height-y, may be best to provide x2, y2, w and h where c2 not same dimensions as c.
Pearson's Sample Correlation Coefficient.
http://en.wikipedia.org/wiki/Correlation_and_dependence
http://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient
Uses equivalent routine to the JMac698's JCorr plugin here:
http://forum.doom9.org/showthread.php?t=165386
and here:
http://forum.doom9.org/showthread.php?p=1495098#post1495098
For HBD, could do test on converted to 8 bit clips [RT_Stats only does 8 bit].
EDIT:
Also, YPlaneMinMaxDifference(Subtract(Last,Last.DuplicateFrame(0)),threshold=th) #should be close to 0 where NO MOVEMENT; only light change. [minmaxdif(n,n-1)]
EDIT: Also possible uses,
RT_LumaDifference(clip c,clip c2,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,
int "n2"=current_frame,int "delta2"=0,int "x2"=x,int "y2"=y,bool "interlaced"=false,int "Matrix"=(Width>1100||Height>600?3:2))
Returns FLOAT value luma difference (0.0 -> 255.0) between clip c frame (n+delta) area x,y,w,h, and clip c2 frame (n2+delta2) area x2,y2,w,h.
Note, 'x2' and 'y2' default to 'x' and 'y' respectively.
v2.0, c and c2 need not be same dimensions but BEWARE, x2 and y2 default to x and y also w and h default to 0
which is converted to c.width-x and c.height-y, may be best to provide x2, y2, w and h where c2 not same dimensions as c.
***
***
***
RT_LumaPixelsDifferent(clip c,clip c2,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0, \
int "n2"=current_frame,int "delta2"=0,int "x2"=x,int"y2"=y,bool "interlaced"=false, \
int "matrix"=(Width>1100||Height>600?3:2),int "Thresh"=0)
Compares clip c frame (n+delta) at x,y,w,h, and clip c2 frame (n2+delta2) at x2,y2,w,h, and returns amount of pixels
whose pixel luma difference is greater than Thresh (RGB converted to Luma-Y using Matrix).
Matrix 0=Rec601, 1=Rec709, 2=PC601, 3=PC709.
If Interlaced=True, then skips every other raster line, eg process only y, y+2, y+4 etc.
Thresh Default 0, returns number of pixels that are not exactly the same.
Return value is in range 0.0 (meaning none) to 255.0 meaning 100% of pixels.
v2.0, c and c2 need not be same dimensions but BEWARE, x2 and y2 default to x and y also w and h default to 0
which is converted to c.width-x and c.height-y, may be best to provide x2, y2, w and h where c2 not same dimensions as c.
***
***
***
RT_LumaPixelsDifferentCount(clip c,clip c2,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0, \
int "n2"=current_frame,int "delta2"=0,int "x2"=x,int"y2"=y,bool "interlaced"=false, \
int "matrix"=(Width>1100||Height>600?3:2),int "Thresh"=0)
Compares clip c frame (n+delta) at x,y,w,h, and clip c2 frame (n2+delta2) at x2,y2,w,h, and returns number of pixels
whose pixel luma difference is greater than Thresh (RGB converted to Luma-Y using Matrix).
Matrix 0=Rec601, 1=Rec709, 2=PC601, 3=PC709.
If Interlaced=True, then skips every other raster line, eg process only y, y+2, y+4 etc.
Thresh Default 0, returns number of pixels that are not exactly the same.
Note, returns the number of pixels whose difference is greater than Thresh, so ranges 0 -> (Width*Height).
v2.0, c and c2 need not be same dimensions but BEWARE, x2 and y2 default to x and y also w and h default to 0
which is converted to c.width-x and c.height-y, may be best to provide x2, y2, w and h where c2 not same dimensions as c.
kolak
23rd July 2022, 20:33
It's 1 frame jump and stays at new level.
What is special is that all pixels within frame are affected exactly the same amount.
As I said- imagine you have a timeline and at some point you add black video overlay with some opacity to the main video.
I will prepare sample.
If you wonder what it's then it's a misaligned Dolby Vision trim applied to HDR video (xml metadata not aligned with video master).
What can be useful is that xml does have expected scene changes, so this may help.
Comparing cut points from xml to detected in the video won't be "perfect" due to detection limitations. Using both info may be actually 100% accurate?
StainlessS
23rd July 2022, 21:37
Maybe someone else would best attempt this,
I aint got the faintest clue what Dolby Vision is, and no [editing] experience with HDR or that there xml metadata stuff.
I'll have a look though.
EDIT: Also, it is only ever 1 instance (per clip) of this problem, or gets steadily darker and darker in steps as the clip goes on ?
(xml metadata not aligned with video master)
(So, is it a single clip where 1st part is lighter, then 2nd part darker, or xml trim problem in multiple places, and so normal/dark/normal/dark etc)
What is special is that all pixels within frame are affected exactly the same amount.
Maybe pertinent
Also, YPlaneMinMaxDifference(Subtract(Last,Last.DuplicateFrame(0)),threshold=th) #should be close to 0 where NO MOVEMENT; only light change. [minmaxdif(n,n-1)]
EDIT: Also AverageLuma should drop by approx same amount [as YPlaneMinMaxDiff above] , [exception where pixels already 0, again where no movement]
EDIT: Just so I can find it again: Wikipedia DolbyVision:- https://en.wikipedia.org/wiki/Dolby_Vision
On Selur's site, SMPTE Standard Update, PDF, SMPTE ST 2094 and Dynamic Metadata https://forum.selur.net/attachment.php?aid=611
High-dynamic-range television:- https://en.wikipedia.org/wiki/High-dynamic-range_television
kolak
23rd July 2022, 22:17
Don't worry about Dolby Vision itself.
You don't need to understand it at all. Well good to know where this issue may come from but just for the sake of it.
When master is graded colorist works in timeline which has shots. Work is done per shot. When HDR grade is done colorist performs Dolby analysis which checks each shot and creates metadata for it based on some Dolby math. Then you export video and DV xml metadata. Both are aligned at this point- video and xml have exactly same cut positions.
Later master goes through whole chain and at some point it may get edited a bit. If you deliver newly edited master with old DV mxl you create misalignment and this is bad and manifests itself with this luma change.
I done sample and will post in a bit.
It will be video+ original scene changes positions.
StainlessS
23rd July 2022, 22:24
Is there some kind of codec required, or will ffms or LSmash be suitable, and if so, what if any additional args are necessary to source filter.
Supply when posting sample.
kolak
23rd July 2022, 22:53
Sample to work with is just normal h264.
https://we.tl/t-GfUiL23QJk
Here are original scene changes positions (as you would get in Dolby xml):
['0', '157', '454', '519', '650', '719', '847', '868', '923', '1003', '1019', '1034', '1070', '1079', '1114', '1202', '1344', '1411', '1454', '1467', '1515', '1557', '1619', '1712', '1794', '1852', '1930', '2018', '2042', '2153', '2184', '2268', '2413', '2485', '2540', '2604', '2660', '2760', '2826', '2904', '2926', '2945', '2999', '3084', '3875', '3916', '4039', '4123', '4207', '4564', '4896']
Up to 3875 they are not aligned with video as I removed 2 seconds from start to create a problem. So at each scene cut (actually some may not show it) up to 3875 you will see luma change. Later scenes are fine as I added 2 seconds to the video to get it aligned.
I think it all comes down to say if given scene change is a real one or just a jump in luma.
It's real example- maybe slightly special one due to very high dynamic nature of the actual video.
StainlessS
24th July 2022, 05:19
Got it [EDIT: sample] thanks.
rwill
24th July 2022, 07:50
I will prepare sample.
If you wonder what it's then it's a misaligned Dolby Vision trim applied to HDR video (xml metadata not aligned with video master).
What can be useful is that xml does have expected scene changes, so this may help.
Comparing cut points from xml to detected in the video won't be "perfect" due to detection limitations. Using both info may be actually 100% accurate?
If you want to check if metadata/RPU matches to pictures this sounds like a job for the Dolby Vision Video Impairment Detector, which is available to Dolby Laboratories Licensees.
*edit: Cant you just check if you can detect a scene boundary in the pixels when DV metadata says there should be one ? And If there almost never is one you have thus detected a miss-alignment ?
kolak
24th July 2022, 09:38
You can do it, but those luma changes for most detectors mean scene change, so it’s not enough. We need to distinguish between real scene change and just luma jump.
Dolby has different modules in their bundle, but not aware of anything for this task. Typically this is done manually by QC operator. Also paying an yearly license just for this task sounds excessive :p
I have semi automated way which reduces check time to minutes, but still requires operator. Trying to do it in fully automated way.
I assume this is task for an AI based system.
There is also another thing- we also have HDR master which is of course very different than SDR trim (although you could tonne map with non-Dolby way it to make it closer to SDR), but has no luma jumps. This also could be used, but overall it creates a complex project :)
rwill
24th July 2022, 10:53
You can do it, but those luma changes for most detectors mean scene change, so it’s not enough. We need to distinguish between real scene change and just luma jump.
You are supposed to detect the scene cut in the "not yet content mapped" mezzanine (source).
kolak
24th July 2022, 11:23
This doesn't help either if you want to make it fully automated.
Your detection is always flawed. When master is created you may work to slightly different cuts as operator dictates them. What you detect on HDR master won't align perfectly (also due to quality of the detection algorithm itself).
This is exactly what I use for my semi automated method. I check difference between xml and detected.
kolak
24th July 2022, 11:24
Another idea- if we scale source to few pixels by few pixels won't this make luma jumps way more distinct (all pixels change about same amount due to huge averaging) compared to real scene changes which will have each pixels changing diffrently?
This seems to work at least when I look it it by the eye in Vdub. Final 3x2 few pixels change about equally for luma jumps where in other cases they change sporadically. It may be still not measurable when whole video is analysed.
update: doesn't work
rwill
24th July 2022, 11:45
This doesn't help either if you want to make it fully automated.
Your detection is always flawed. When master is created you may work to slightly different cuts as operator dictates them. What you detect on HDR master won't align perfectly (also due to quality of the detection algorithm itself).
This is exactly what I use for my semi automated method. I check difference between xml and detected.
I am confused. So there is the mezz with the metadata. If the mezz is correctly aligned to the metadata or not can easily be checked by checking the pictures in the mezz against the shots in the metadata. Why should a content mapped (according to the trims in the metadata) version of the mezz have different cuts than the mezz ? It makes no sense.
kolak
24th July 2022, 11:54
You can manually check Dolby xml points against main HDR master, but you know how long it takes if you want to be 100% sure all cuts are aligned?
If misalignment is somewhere at the beginning it's quite obvious, but it can be on last scenes as well (eg. some localised credits slate etc. added).
Overall serious problems can be found quite quickly, but 100% guarantee takes time.
If xml is aligned to HDR master mapped video will be fine (unless you have bug in software which process both).
StainlessS
24th July 2022, 19:11
Just thought I'de point out that LSmashVideoSource loads your 24FPS test.mp4 clip as 0.0181 (524/29029) FPS,
FFVideoSource loads ok @ 24FPS. (neither with any additional args other than filename)
L-Smash dll = LSMASHSource_x64_20210810(Asd).dll # My extended name, I keep 2 copies, one with extended name so I know where it came from. [many dll's have no version resource]
I dont recall ever having that problem with that LSmashVideoSource() dll.
EDIT: Think LSmash Devname Should asd-g not asd, but I cant seem to find the repository on
https://github.com/Asd-g?tab=repositories
EDIT: Arh, I think Asd was the dev who deleted all his D9 Threads/Posts not so long ago. [EDIT: No, I think that was [B]HolyWu]
EDIT:
General
Complete name : D:\____KOLAK\test.mp4
Format : MPEG-4
Format profile : Base Media
Codec ID : isom (isom/iso2/avc1/mp41)
File size : 320 MiB
Duration : 4 min 23 s
Overall bit rate : 10.2 Mb/s
Encoded date : UTC 2022-07-23 21:09:59
Tagged date : UTC 2022-07-23 21:09:59
Writing application : Blackmagic Design DaVinci Resolve Studio
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High@L4
Format settings, CABAC : Yes
Format settings, ReFrames : 2 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 4 min 23 s
Bit rate : 10.1 Mb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 24.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.202
Stream size : 316 MiB (99%)
Encoded date : UTC 2022-07-23 21:09:59
Tagged date : UTC 2022-07-23 21:09:59
Color range : Limited
Color primaries : BT.709
Matrix coefficients : BT.709
Audio
ID : 2
Format : AAC
Format/Info : Advanced Audio Codec
Format profile : LC
Codec ID : 40
Duration : 4 min 23 s
Bit rate mode : Constant
Bit rate : 128 kb/s
Channel(s) : 2 channels
Channel positions : Front: L R
Sampling rate : 48.0 kHz
Frame rate : 46.875 FPS (1024 spf)
Compression mode : Lossy
Stream size : 4.02 MiB (1%)
Default : Yes
Alternate group : 1
Encoded date : UTC 2022-07-23 21:09:59
Tagged date : UTC 2022-07-23 21:09:59
Other
ID : 3
Type : Time code
Format : QuickTime TC
Duration : 4 min 23 s
Time code of first frame : 00:00:00:00
Time code, striped : Yes
Language : English
Default : No
Encoded date : UTC 2022-07-23 21:09:59
Tagged date : UTC 2022-07-23 21:09:59
kolak
24th July 2022, 20:58
No idea- standard mp4 out of Resolve which uses GPU on Mac for h264. I've noticed that ffmpeg has some issues with these files though (something with duration or timebase), so maybe they have some headers issue.
I used LWLibAvVideoSource and no problems.
Fps overall makes no difference- frame numbers are more important here.
Overall I never trusted ffmpeg based source filters. They are far from been 100% reliable.
I gave up on ideas- nothing works in the way that it could be automated and reliable.
If anything you would have to analyse quite a few frames around "jump point" and detect sudden luma raise this way. Like 3 frame before and 3 frame after (before and after bad frame typically there won't be dramatic changes, except scene changes, but those last 1 frame only) but even this won't be 100% reliable I think.
StainlessS
24th July 2022, 21:12
I am quite hopeful at the moment. [well have not given up]
Is there any (original) FrameCount in the Metadata thingy ?
kolak
24th July 2022, 21:49
Not directly but there is "in" and "duration" for each cut so no problem to get it.
Last in+duration - start point.
StainlessS
24th July 2022, 21:59
Do you actually have an XML file for that clip or not ?
And also, the clip is never going to be longer than the one the XML was created for, ie bit maybe chopped out but no additional clips added/inserted ?
If you chopped 2 seconds from beginning of clip, then all XML 'marks' should be advanced by 2 secs worth of frames, so without adding some extra footage, how would it get back in sync at frame 3875 ?
EDIT: This is what I've got at the minute
Import(".\ScSelect_HBD.avsi")
FN = ".\Test.mp4".RT_GetFullPathName
#LSmashVideoSource(FN) # 0.0181 (524/29029) FPS BAD FPS
LWLibAvVideoSource(FN)
#FFVideoSource(FN) # 24 FPS OK
# We scan on 8 bit only : This aint neessary with your suppleid 8 bit clip, but does not harm to leave in here
BPC = Last.BitsPerComponent
Last = (BPC==8) ? Last : Last.ConvertBits(8)
# SCSelect_HBD Args,
dFactor = 3.5
minDif = 1.0
Recycle_SOS = True
Show = True
FONT_SIZE = Round(Height / 8)
SCselect_SOS_Frames = ".\SCselect_SOS_Frames.txt".RT_GetFullPathName
(Recycle_SOS) ? NOP : RT_FileDelete(SCselect_SOS_Frames)
SC_SOS = Last.Subtitle("*** SCENE CHANGE ***",Text_Color=$FF00FF,Size=FONT_SIZE,align=5)
SOS_Exists = Exist(SCselect_SOS_Frames)
(SOS_Exists) ? NOP : SCSelect_HBD(Last,SC_SOS,Last,Last, dFactor=dfactor,minDif=minDif,show=Show,S_Frames=SCselect_SOS_Frames)
(SOS_Exists) ? NOP : RT_ForceProcess
if(!SOS_Exists && SHOW) {
return last
}
Sub = Last.DuplicateFrame(0).Subtract(Last)
SSS="""
n=current_frame
LC = Last.RT_AverageLuma(n=n)
LP = Last.RT_AverageLuma(n=n-1)
LD = Last.RT_LumaDifference(Last,n=n,n2=n-1)
MnMxDif = Sub.RT_YPLaneMin(n=n)
RT_Subtitle("%d] LC=%.3f LP=%.3f LD=%.3f MnMx=%d",n,LC,LP,LD,MnMxDif)
Return Last
"""
Scriptclip(SSS)
return last
I'm about to write a little bit to automatically extract a frames list from this lot
['0', '157', '454', '519', '650', '719', '847', '868', '923', '1003', '1019', '1034', '1070', '1079', '1114', '1202', '1344', '1411', '1454', '1467', '1515',
'1557', '1619', '1712', '1794', '1852', '1930', '2018', '2042', '2153', '2184', '2268', '2413', '2485', '2540', '2604', '2660', '2760', '2826', '2904', '2926',
'2945', '2999', '3084', '3875', '3916', '4039', '4123', '4207', '4564', '4896']
rwill
24th July 2022, 22:04
You know... I have implemented this twice already...
Get the scene boundaries from the metadata. Check (automated of course) if there is a scene cut at these picture numbers in the mezzanine. You most likely need 3 pictures before and 2 pictures trailing depending on your scene cut detection. If there is a scene change in the picture of the mezzanine at the scene boundary of the metadata its fine. If there is not - flag it - the more scene boundaries where no scene change is detected the more likely there is misalignment. Consecutive single picture scenes should not really be taken into account as this might be per frame metadata. If you are worried and want manual QC write out all non detected scene cuts with the surrounding pictures and let someone take a look at them.
StainlessS
24th July 2022, 22:09
One question, what the hell is a mezzanine :)
kolak
24th July 2022, 22:10
You know... I have implemented this twice already...
Get the scene boundaries from the metadata. Check (automated of course) if there is a scene cut at these picture numbers in the mezzanine. You most likely need 3 pictures before and 2 pictures trailing depending on your scene cut detection. If there is a scene change in the picture of the mezzanine at the scene boundary of the metadata its fine. If there is not - flag it - the more scene boundaries where no scene change is detected the more likely there is misalignment. Consecutive single picture scenes should not really be taken into account as this might be per frame metadata. If you are worried and want manual QC write out all non detected scene cuts with the surrounding pictures and let someone take a look at them.
Wit human assistance it can be done in many ways.
I want fully automated 99.x% reliable way :)
kolak
24th July 2022, 22:13
One question, what the hell is a mezzanine :)
High quality master which is used to create other "worse" masters. Can be in form of EXRs, TIFFs, JPEG2000 or ProRes etc. Depending on the project quality format can vary.
kolak
24th July 2022, 22:30
Do you actually have an XML file for that clip or not ?
And also, the clip is never going to be longer than the one the XML was created for, ie bit maybe chopped out but no additional clips added/inserted ?
If you chopped 2 seconds from beginning of clip, then all XML 'marks' should be advanced by 2 secs worth of frames, so without adding some extra footage, how would it get back in sync at frame 3875 ?
I have XML as I created it.
If clip is longer then it's a red flag straight away. It never should be.
I removed 2 seconds and added it back in the middle to make rest of the file aligned and your script did not detect anything after this places, so all looks fine.
kolak
24th July 2022, 22:47
I'm about to write a little bit to automatically extract a frames list from this lot
['0', '157', '454', '519', '650', '719', '847', '868', '923', '1003', '1019', '1034', '1070', '1079', '1114', '1202', '1344', '1411', '1454', '1467', '1515',
'1557', '1619', '1712', '1794', '1852', '1930', '2018', '2042', '2153', '2184', '2268', '2413', '2485', '2540', '2604', '2660', '2760', '2826', '2904', '2926',
'2945', '2999', '3084', '3875', '3916', '4039', '4123', '4207', '4564', '4896']
I thought this is your output :)
StainlessS
24th July 2022, 23:54
Sorry no, I said Extract a frames list FROM THAT stuff,
Here That stuff [source, I probably did some wrap around to make on 3 lines]
['0', '157', '454', '519', '650', '719', '847', '868', '923', '1003', '1019', '1034', '1070', '1079', '1114', '1202', '1344', '1411', '1454', '1467', '1515',
'1557', '1619', '1712', '1794', '1852', '1930', '2018', '2042', '2153', '2184', '2268', '2413', '2485', '2540', '2604', '2660', '2760', '2826', '2904', '2926',
'2945', '2999', '3084', '3875', '3916', '4039', '4123', '4207', '4564', '4896']
Here Converted to frames file, and to also to DBase [I've skipped any other script for now]
XML SOS List Converter,
######### FUNCS #################
Function ChrIsNul(String S) {return RT_Ord(S)== 0} # End of String
Function ChrIsDigit(String S) {C=RT_Ord(S) return C>=48&&C<=57}
Function ChrEatWhite(String S) {i=1 C=RT_Ord(S,i) While(C==32||C>=8&&C<=13) {i=i+1 C=RT_Ord(S,i)} return i>1?MidStr(S,i):S}
Function ChrEatDigits(String S) {i=1 C=RT_Ord(S,i) While(C>=48&&C<=57) {i=i+1 C=RT_Ord(S,i)} return i>1?MidStr(S,i):S}
# Convert XML Start Of Scene list TO simple Frames file, and/or set field FrameField (default 0) in DBase if DB given.
Function Extract_XmlSos2Frames(String Xml_Sos,String "Frames",String "DB",Int "FrameField") {
myName="Extract_XmlSos2Frames: "
Frames = Default(Frames,"")
DB = Default(DB, "") # Optional DB name [Must exist if given], if given then will add record and set FrameField field with extracted frameNos
FrameField = DEfault(FrameField,0) # Field set with FrameNo in existing DB when DB filename supplied. Default field 0.
if(DB != "") {
DB = DB.RT_GetFullPathName
Assert(DB.Exist,myName + DB+" Optional DB must exist if given")
nFields = DB.RT_DBaseFields()
Assert(0 <= FrameField < nfields,myName+"Invalid FrameField")
fTyp = DB.RT_DBaseFieldType(FrameField)
Assert(fTyp==1,RT_String("%sDB Field[%d]{%s} is NOT of type int{1} {DB=%s}",myName,Framefield,RT_DBaseTypeName(fTyp),DB))
}
Assert(xml_Sos!="",myName+"Xml_Sos Cannot be ''")
Assert(xml_Sos.Exist,myName+Xml_Sos+" Does Not Exist")
Assert(DB!="" || Frames!="",myName+"Must Provide Frames and/or DB file names")
Frames = (Frames!="") ? Frames.RT_GetFullPathName : Frames
(Frames!="") ? RT_FileDelete(Frames) : NOP
xml=RT_ReadTxtFromFile(xml_Sos)
Count = 0
While(!xml.ChrIsNul) {
While(!xml.ChrIsNul && !xml.ChrIsDigit) { xml=xml.MidStr(2) } # Ignore everything that aint a digit
if(xml.ChrIsDigit) {
n = xml.RT_NumberValue
(Frames != "") ? RT_WriteFile(Frames,"%d",n,Append=True) : NOP
if(DB != "") {
DB.RT_DBaseExtend() # Add a single record to DBase [all fields zero'ed]
DB.RT_DBaseSetField(DB.RT_DBaseRecords-1,FrameField,n) # Set DBase[records-1,FrameField] with n
}
xml=xml.ChrEatDigits
Count = Count + 1
}
}
Return Count
}
# Write to DebugView a DBase field value : For all Records. [Type of Field field can be any Variable type]
Function DebugView_ShowDbField(String DB,int "Field") {
myName = "DebugView_ShowDbField: "
Assert(DB !="",myName+"DB Cannot be ''")
DB = DB.RT_GetFullPathName
Assert(DB.Exist,myName+DB+" Does Not Exist")
nFields = DB.RT_DBaseFields()
Assert(0 <= Field < nfields,myName+"Invalid Field")
fTyp = DB.RT_DBaseFieldType(Field) # 0="Bool", 1="Int", 2 = "Float", 3 = "String", 4 = "Bin" {5="double" : RT_Stats Private type}
Records = DB.RT_DBaseRecords
RT_DebugF("\n##########################################################",name=myName)
RT_DebugF("# Showing FieldIndex=%d for DB='%s'",Field,DB,name=myName)
RT_DebugF("# Records=%d : Fields=%d : Fields TypeString='%s'",Records,nfields,DB.RT_DBaseGetTypeString,name=myName)
RT_DebugF("# Showing Field Type = %d{%s}",fTyp,RT_DBaseTypeName(fTyp),name=myName)
RT_DebugF("##########################################################\n",name=myName)
for(Rec=0,Records-1) {
FieldVal = DB.RT_DBaseGetField(Rec,Field) # Get the value from the DB field
S = (fTyp==3) ? "'" + FieldVal + "'" : String(FieldVal) # Convert to String if not already a string, and if already string then wrap in single quotes.
RT_DebugF("%d:%d] %s",Rec,Field,S,name=myName)
}
return Records
}
######### END FUNCS ################
XML_SOS = ".\Xml_SOS_Source_List.txt".RT_GetFullPathName # Filename, Start of scene frames from xml eg "['0', '157', '454', '519']"
XML_Frames = ".\Xml_Frames.txt".RT_GetFullPathName # Filename, Simple frames file, one frameNo per line.
XML_DB = ".\XML_DB.DB".RT_GetFullPathName # Filename, DBase, field 0 filled with framenos
RT_DBaseAlloc(XML_DB,0,"i") # Alloc a Dbase of 0 existing records, with single field of type int ("i").
Extract_XmlSos2Frames(XML_SOS,XML_Frames,DB=XML_DB) # Convert Xml Frames list to Frames File, AND, Fill XML_DB DBase field 0 with same FramNos.
DebugView_ShowDbField(XML_DB,Field=0) # Just to check FrameNos Ok.
Return MessageClip("Done")
Output to frames file =
0
157
454
519
650
719
847
868
923
1003
1019
1034
1070
1079
1114
1202
1344
1411
1454
1467
1515
1557
1619
1712
1794
1852
1930
2018
2042
2153
2184
2268
2413
2485
2540
2604
2660
2760
2826
2904
2926
2945
2999
3084
3875
3916
4039
4123
4207
4564
4896
And showing DB Field 0 for all records of output DBase [ Written to DebugView : Google "DebugView" ].
00000090 0.22797640 DebugView_ShowDbFields:
00000091 0.22799601 DebugView_ShowDbFields: ##########################################################
00000092 0.22806020 DebugView_ShowDbFields: # Showing FieldIndex=0 for DB='D:\____KOLAK\XML_DB.DB'
00000093 0.22815040 DebugView_ShowDbFields: # Records=51 : Fields=1 : Fields TypeString='i'
00000094 0.22821461 DebugView_ShowDbFields: # Showing Field Type = 1{Int}
00000095 0.22822630 DebugView_ShowDbFields: ##########################################################
00000096 0.22828980 DebugView_ShowDbFields:
00000097 0.22840500 DebugView_ShowDbFields: 0:0] 0
00000098 0.22849770 DebugView_ShowDbFields: 1:0] 157
00000099 0.22858930 DebugView_ShowDbFields: 2:0] 454
00000100 0.22868200 DebugView_ShowDbFields: 3:0] 519
00000101 0.22877420 DebugView_ShowDbFields: 4:0] 650
00000102 0.22886699 DebugView_ShowDbFields: 5:0] 719
00000103 0.22892810 DebugView_ShowDbFields: 6:0] 847
00000104 0.22899450 DebugView_ShowDbFields: 7:0] 868
00000105 0.22906110 DebugView_ShowDbFields: 8:0] 923
00000106 0.22912750 DebugView_ShowDbFields: 9:0] 1003
00000107 0.22919559 DebugView_ShowDbFields: 10:0] 1019
00000108 0.22926220 DebugView_ShowDbFields: 11:0] 1034
00000109 0.22932880 DebugView_ShowDbFields: 12:0] 1070
00000110 0.22939530 DebugView_ShowDbFields: 13:0] 1079
00000111 0.22946291 DebugView_ShowDbFields: 14:0] 1114
00000112 0.22952940 DebugView_ShowDbFields: 15:0] 1202
00000113 0.22959590 DebugView_ShowDbFields: 16:0] 1344
00000114 0.22966230 DebugView_ShowDbFields: 17:0] 1411
00000115 0.22972870 DebugView_ShowDbFields: 18:0] 1454
00000116 0.22979650 DebugView_ShowDbFields: 19:0] 1467
00000117 0.22986311 DebugView_ShowDbFields: 20:0] 1515
00000118 0.22992940 DebugView_ShowDbFields: 21:0] 1557
00000119 0.22999591 DebugView_ShowDbFields: 22:0] 1619
00000120 0.23006390 DebugView_ShowDbFields: 23:0] 1712
00000121 0.23013040 DebugView_ShowDbFields: 24:0] 1794
00000122 0.23019660 DebugView_ShowDbFields: 25:0] 1852
00000123 0.23026310 DebugView_ShowDbFields: 26:0] 1930
00000124 0.23033001 DebugView_ShowDbFields: 27:0] 2018
00000125 0.23039760 DebugView_ShowDbFields: 28:0] 2042
00000126 0.23046370 DebugView_ShowDbFields: 29:0] 2153
00000127 0.23053031 DebugView_ShowDbFields: 30:0] 2184
00000128 0.23059650 DebugView_ShowDbFields: 31:0] 2268
00000129 0.23066419 DebugView_ShowDbFields: 32:0] 2413
00000130 0.23073050 DebugView_ShowDbFields: 33:0] 2485
00000131 0.23079690 DebugView_ShowDbFields: 34:0] 2540
00000132 0.23086309 DebugView_ShowDbFields: 35:0] 2604
00000133 0.23093100 DebugView_ShowDbFields: 36:0] 2660
00000134 0.23099791 DebugView_ShowDbFields: 37:0] 2760
00000135 0.23106471 DebugView_ShowDbFields: 38:0] 2826
00000136 0.23113079 DebugView_ShowDbFields: 39:0] 2904
00000137 0.23119719 DebugView_ShowDbFields: 40:0] 2926
00000138 0.23126510 DebugView_ShowDbFields: 41:0] 2945
00000139 0.23133160 DebugView_ShowDbFields: 42:0] 2999
00000140 0.23139800 DebugView_ShowDbFields: 43:0] 3084
00000141 0.23147480 DebugView_ShowDbFields: 44:0] 3875
00000142 0.23154061 DebugView_ShowDbFields: 45:0] 3916
00000143 0.23160391 DebugView_ShowDbFields: 46:0] 4039
00000144 0.23166730 DebugView_ShowDbFields: 47:0] 4123
00000145 0.23173070 DebugView_ShowDbFields: 48:0] 4207
00000146 0.23179370 DebugView_ShowDbFields: 49:0] 4564
00000147 0.23185810 DebugView_ShowDbFields: 50:0] 4896
Updated
StainlessS
25th July 2022, 02:39
Prev post update, also writes XML SOS List frameNos to field 0 of a single field DBase. [as well as writing a frames file, Writes to Frames file AND/OR DBase]
kolak
25th July 2022, 10:04
This frames output is just a list from Python.
I can supply any other format if it’s easier.
I have script which extracts them from Dolby xml.
StainlessS
25th July 2022, 16:47
Its quite easy to extract from the supplied python list, every string of digits is a frameno, anything else is fluff,
a lot of the extract thingy is just checking args validity.
I'de still like to see what a raw extracted XML looks like [see if anything else is available that could assist in this task, eg List framecount or last frameNo of list].
With the DB, can now jump around the FrameNos quite easily, maybe tryin' to match from either start or end of clip.
EDIT: Also, a Frames File [rather than DB], could be useful to extract SOS [Start Of Scene] Frames for viewing/checking [ FrameSel() ].
kolak
25th July 2022, 19:46
I added xml to older post, but still pending, so here it's:
https://we.tl/t-6DDAJyIjSP
There is nothing what could help here except original scene changes. It's all cryptic Dolby info which is proprietary.
StainlessS
26th July 2022, 15:52
Yo Kolak, just to say I aint forgotten you [just yet].
So far got script producing this list of a 2 field DBase, extracted from the xml
XML_DB_sRec0_eRec50_sFld0_eFld1_DBUT_ListFieldRange.txt [Auto generated name for log file, outputs to DebugView too. Current name of list generator function.]
##########################################################
# Showing Fields 0 to 1 for DB='XML_DB.DB'
# Records=51 : Fields=2 : TypeString='ii'
# sRec=0 : eRec=50
##########################################################
0] 0 157
1] 157 297
2] 454 65
3] 519 131
4] 650 69
5] 719 128
6] 847 21
7] 868 55
8] 923 80
9] 1003 16
10] 1019 15
11] 1034 36
12] 1070 9
13] 1079 35
14] 1114 88
15] 1202 142
16] 1344 67
17] 1411 43
18] 1454 13
19] 1467 48
20] 1515 42
21] 1557 62
22] 1619 93
23] 1712 82
24] 1794 58
25] 1852 78
26] 1930 88
27] 2018 24
28] 2042 111
29] 2153 31
30] 2184 84
31] 2268 145
32] 2413 72
33] 2485 55
34] 2540 64
35] 2604 56
36] 2660 100
37] 2760 66
38] 2826 78
39] 2904 22
40] 2926 19
41] 2945 54
42] 2999 85
43] 3084 791
44] 3875 41
45] 3916 123
46] 4039 84
47] 4123 84
48] 4207 357
49] 4564 332
50] 4896 0
The first field is the Start Of Scene positions extracted from XML, the 2nd field is the length of each corresponding scene, where the last scene length is 0, ie unknown.
We will need to make similar DBase from Start Of Scene and scene Length, from detected scene change in video clip.
Once this is done, we have to match up sequences of multiple-consecutive-scene-lengths, to try match and detect where aligned.
I'll have to look at source code for linux/unix style text Diff utility, to get some ideas for that [I actually was in process of doing a modfied version of a variation of 'diff',
in the 90's, I dont think I ever completed it, but think I probably still have the source code somewhere].
Ideally we need a very simple version of diff, nothing over elaborate, maybe its got a lot more complex since I last looked at it.
EDIT: Diff, concerns itself in trying to figure out where complete blocks of text have been deleted/added/swapped/moved around in a text file, we [I presume] do not need worry about most of that,
and only need try find where bits are present in the original XML but have been chopped out of the edited result clip.
As I recall, first alignment step is finding all 'Unique_Length' sequences, unique in eg XML list, and then same again, unique in clip_SOS list,
then try link those unique scenes between both SOS sources, whilst matching and expanding consecutive sequence count in each SOS_source. [something like that].
EDIT: I'll also have to decide on better formatting of the two fields in list as shown, both SOS and SOS_Length are center justified, I probably need to right justify both, same as record number on left.
I have to get the list thing working well, it helps in development if I can see what I'm doing, and also will likely be of use to you too.
kolak
26th July 2022, 16:49
No worry- problem is not going anywhere, so we have plenty of time.
I actually got some new idea. Relying on a single scene change point can be misleading, but because we have points where we expect scene changes, we can do more.
We can keep checking start/end of a scene change as combined info, which should give a "better" data than single point. In case of good master both should be clear scene changes, in case of bad one they will be just luma jumps (less obvious?).
Is this what you are after?
StainlessS
26th July 2022, 17:12
Is this what you are after?
Right now I'm just trying to get the listing working, I like to concentrate on one thing at once.
With difficult problem, you solve the bits that you can do, and think "someone else can do the difficult stuff".
Then when easy part done ok, you can try break off another easy part of the problem to solve, leaving difficult stuff for somebody else.
Rinse and repeat.
When you get to the end, you find the thing works, and at no point did you actually know how to do it, it sort of solved itself.
EDIT: Also, the listing thing is important to get right, I want to be able to add/delete fields, change field type, and maybe even move fields around between DB versions,
and not have to keep changing the listing functions every time.
kolak
26th July 2022, 17:16
Focus on small thing which you can do instead of "impossible task" and soon you may find you've solved impossible :)
I know it.
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.