Log in

View Full Version : Automatically apply different processing to letterboxed clips


Lyris
13th February 2015, 21:56
Hey forum,
When I author BDs and DVDs, I often cram the discs totally full of bonus content. To allow that to happen while keeping the movie at a nice high bitrate, I'm in the habit of noise reducing all of the talking head interview bonus content (which is often shot on DSLRs or other noisy video sources). With the quality of x264's compression that often allows 1080p interviews at around 3-4mbps.

Of course, that also takes out all the film grain on any inserted clips. Those clips are usually short so don't eat up a lot of space. And, de-grained film is nasty. So, I'd like to apply NR filtering to the video camera interviews but not the film inserts - without having to go into an NLE and manually mark the film segments. (Film grain = good, video noise = bad, get rid of it).

The film-originated stuff is almost always letterboxed or pillarboxed - be in 2.35:1, 1.85:1 with small borders, or 1.66:1 pillarboxed. It is very rare that we get a film master that occupies the entire 16:9 video frame. So, that's an easy automatic way to differentiate the footage.

TL;DR: is there a way to get Avisynth to detect a certain amount of black pixels at the top left and bottom right edges of the frame and apply different processing to those portions?

StainlessS
14th February 2015, 05:45
The DBSC thread (Work in progress) generates a DBase with scene changes, you can scan the DB and do your own processing instead of the crop/resize/splice
function. Take a look at DynaSplice function, you could mod for your purpose (will probably work quite well as a guide already as it stands).

EDIT: Here it is

Function DBSC_DynaSplice(clip c,String SpliceDB,String "Func",Bool "DEBUG") {
/*
DBSC_DynaSplice(), Function to trim, crop, resize and splice trims in SpliceDB DBase [as created via DBSC_DynaCrop()].
Optionally can call user function 'Func' on each cropped and resized trim, prior to splicing.
The Func arg must (if used) supply all required args (excluding initial clip) and parenthesis to call the required user function.
Eg, Func="MyFunc(Show=True)", where will be called with explicit OOP style clip as 1st arg (ie DONT INCLUDE clip as first arg in
Func string), called as in ClipName.MyFunc(Show=True) from within DBSC_DynaSplice().
See below DBSC_Levels() for example usage.
After viewing output of this function, might like to create OVERRIDE.TXT file and use DBSC_Override() to insert additional
scene changes into ScanDB (it is easlier to find problem areas with remaining borders once this has been processed, also easier to
spot blended scene transitions and force a scene change there).
*/
c
myName="DBSC_DynaSplice: "
Func=Default(Func,"")
DEBUG=Default(DEBUG,TRUE)
Assert(SpliceDB!="",RT_String("%sNeed SpliceDB name",myName))
Assert(Exist(SpliceDB),RT_String("%sSpliceDB Does not exist\n%s",myName,SpliceDB))
Assert(RT_DBaseGetID(SpliceDB,0)==DBSC_Str2ID("DYNS"),RT_String("%sNot a SpliceDB\n%s",myName,SpliceDB))
Records=RT_DBaseRecords(SpliceDB) Fields=RT_DBaseFields(SpliceDB)
Assert(Records>0,RT_String("%sInvalid SpliceDB, Zero records\n%s",myName,SpliceDB))
Assert(Fields>=13,RT_String("%sInvalid SpliceDB, at least 12 Int fields and 1 String[256] field\n%s",myName,SpliceDB))
oc=0
GScript("""
for(i=0,11) {Assert(RT_DBaseFieldType(SpliceDB,i)==1,RT_String("%sSpliceDB field %d is NOT type Int\n%s",myName,i,SpliceDB))}
Assert(RT_DBaseFieldType(SpliceDB,12)==3,RT_String("%sSpliceDB field 12 is NOT type String\n%s",myName,SpliceDB))
Resizer=RT_DBaseGetField(SpliceDB,0,12) # Resizer String, "_W_" and "_H_" are width and Height
OutW=RT_DBaseGetField(SpliceDB,0,4)
OutH=RT_DBaseGetField(SpliceDB,0,5)
FND_S=RT_String("_W_\n_H_\n")
REP_S=RT_String("%d\n%d\n",OutW,OutH)
Resizer="c.trim(Start,End).Crop(XX,YY,WW,HH)."+RT_StrReplaceMulti(Resizer,FND_S,REP_S)
HasFunc=(Func!="")
Func=(HasFunc)?"tmpc."+Func:Func
for(SceneNo=0,Records-1) {
Start = RT_DBaseGetField(SpliceDB,SceneNo,0) # Start frame of scene
End = RT_DBaseGetField(SpliceDB,SceneNo,1)
Length = End-Start+1
XX = RT_DBaseGetField(SpliceDB,SceneNo,6) # crop coords
YY = RT_DBaseGetField(SpliceDB,SceneNo,7)
WW = RT_DBaseGetField(SpliceDB,SceneNo,8)
HH = RT_DBaseGetField(SpliceDB,SceneNo,9)
(DEBUG)?RT_DebugF("#%d Start=%d End=%d Length=%d Crop(%d,%d,%d,%d)",SceneNo,Start,End,Length,XX,YY,WW,HH,name=myName):NOP
tmpc=Eval(Resizer)
tmpc=(HasFunc)?Eval(Func):tmpc
oc = (oc.IsClip()) ? oc++tmpc : tmpc # Splice
}
""")
Return oc
}


Should not be too complicated to modify.

EDIT: DynaCrop generates Dbase of scenes with dynamically changing borders, that is processed by DynaSplice,
all you have to do is modify Dynasplice to decide whether it is and 'A' scene or a 'B' scene, then eg crop (using the coords from the
DBase) and do processing on that trim, then eg Add Borders to original/or other size and splice to an output clip.
You might want to create an addition dbase where similar or nearly similar sized frames are concatenated, or just pre-scan ahead
to do it with the original DBase.

EDIT: Or you could just process the DBase, writing a ClipClop command file of frame ranges, after you have concatenated
similar dimension croppings, then create eg two clips with processing stacks, and use ClipClop (or RempframeSimple) to select the correct processing chain for a particular range.

EDIT: The spell checker is working again :)

EDIT:
TL;DR: is there a way to get Avisynth to detect a certain amount of black pixels at the top left and bottom right edges of the frame and apply different processing to those portions?

RT_QueryBorderCrop()

EDIT: I'm knocking up a little function that should work for you.

StainlessS
14th February 2015, 09:30
Hi Lyris, here you go, http://forum.doom9.org/showthread.php?p=1709460#post1709460

Tested on 4:3 clip with borders only changing a little, dont have a suitable clip handy at the moment.
Say in DBSC thread if you have problems.

Implemented as a DBSC_DynaSplice() User function.

Lyris
15th February 2015, 19:42
Good grief man, you always come to the rescue. Do you have a PayPal account? Or at least an Amazon wishlist? Give me a PM!

StainlessS
15th February 2015, 20:02
Wishlist: World peace and lots of fluffy little puppies :)