HDColorBars

From Avisynth wiki
Jump to navigationJump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

HDColorBars

#Attribution-ShareAlike 3.0

#Generate HD colorbars, arib_std_b28
#by jmac698, jan/2010, for Midzuki
#version 0.1.  
#Bugs/Limitations:
#Width of bars may not be totally accurate, especially e.g. section1 where width divisor of 7 doesn't add up.
#the color for plusI is not accurate, however -I is currently being used.
#only evaluated for 1080p.  Other sizes may not be of correct size of blocks, and
#also incorrect total size (as it's pieced together from blocks/sections).
#also framerate is 29.976, you can adjust this.  There is also some sound.
#to use: adjust GLOBAL definitions below for overall video parameters, then adjust choice
#to one of 3 options specified by the standard.
#also duration is fixed at about 3minutes
#also it's very slow, could be done with blankclip in block(), but ramp() still needs recursive

#Function summary
#pair(int y1,int y2,int w, int h, int d) - creates a pair of lines in YV12, with luminence Y1 and Y2
#loopstack(clip vid,int index,int end, string dir, string hfunc, string vfunc) - create a loop of 'count' over the function specified. 
#  The resulting videos are stacked.
#StrReplace(string base, string sought, string rep) - utility to help parse strings.  It replaces all occurences of a string.
#...some other utilities

#These values define full control over the video type generated
global fps=30000
global fps_denom=1001
global sr=48000
global ch=2

#pair - this works perfectly.  directly specify y1,y2,u,v (u=v=128 is grey)
function pair(int y1,int y2, int u, int v, int w, int h, int d) {
    #creates a clip with a pair of lines colored y1,y2 and common color u,v with width w and height h
    #stack horizontally (d=0) or vertically (d=1). eg d=0, y1|y2.  Each line is 1 pixel.  Output is YV12.
    l1=blankclip(pixel_type="YV12",width=w,height=h,fps=fps,fps_denominator=fps_denom,audio_rate=sr,channels=ch,length=720/4*30).ColorYUV(off_y=y1-16,off_u=u-128, off_v=v-128)
    l2=blankclip(pixel_type="YV12",width=w,height=h,fps=fps,fps_denominator=fps_denom,audio_rate=sr,channels=ch).ColorYUV(off_y=y2-16,off_u=u-128, off_v=v-128)
    d==1?stackvertical(l1,l2):stackhorizontal(l1,l2)
    pointresize(w,h)#two 1 pixel lines specified in direct YUV and resized
}

function loopstack(clip vid,int index,int end, string dir, string hfunc, string vfunc) {
    #generic for/next loop of hfunc/vfunc called with index as $i
    d=(dir=="v"||dir=="vertical")?1:0
    dir=(d==1)?"vertical":"horizontal"
    hfunc=StrReplace(hfunc,"$i","index")#string(index) doesn't update
    vfunc=StrReplace(vfunc,"$i","index")#select is slow
    #assert(false,hfunc)#shows first call to pair()
    d==1?index<end?Apply("stack"+dir,Eval(vfunc),loopstack(vid,index+1,end,dir,hfunc,vfunc)):Eval(vfunc): \
    index<end?Apply("stack"+dir,Eval(hfunc),loopstack(vid,index+1,end,dir,hfunc,vfunc)):Eval(hfunc)
}
   

Function StrReplace(string base, string sought, string rep)
	{
		pos = FindStr(base, sought)
		return (sought == "") || (pos == 0) \
			? base \
			: StrReplace( \
				LeftStr(base, pos - 1) + rep + \
				MidStr(base, pos + StrLen(sought)), \
				sought, rep)
	}
#YRamp: ramp luma from y1 to y2 (left to right) and color u,v, in a block (even) w, h
#potential bug: if w is odd, it will be widened to the nearest even amount (because of YV12), and final y2 will be +1
#   if you need an odd-width ramp, you will have to do this in another color space (or twice as big framesize later reduced)
#ie w=219, y1=16, y2=235 gives, a 220 wide video ending in y=235,236 in last two columns
#also special rounding is used, so that w=440, y1=16, y2=235 gives 440 wide video starting y=16,16,17,17....234,235,235.  This is not possible without round tie to zero!
Function YRamp(int y1,int y2, int u, int v, int w, int h) {
    yd=y2-y1#change in luma
    i=(float(yd)/(w-2))#change in luma per x, note -2 is to make end y 'longer' ie w=438, ends with 235,235 (actually 235.5)
    #this is an interesting case where round to zero on tie is better, as (0,.5,1,1.5)->(0,1,1,2) is out of range and too much total power, (0,0,1,1) is more correct
    j=int((w-1)/2)

    loopstack(blankclip,0,j,"h","pair(rnd(index*2*"+String(i)+"+16),rnd((index*2+1)*"+String(i)+"+16),"+String(u)+","+String(v)+",2,"+String(h)+",0)","pair(index*2+16,index*2+17,"+String(u)+","+String(v)+",48,4,0)") 
}	
Function Ramp(int w, int h) {
    YRamp(16, 235, 128, 128, w, h) 
}
#special round:  round towards 0 on tie; rnd(1.5)=1, rnd(-1.5)=-1
Function rnd(float i) {
    Return (frac(abs(i))==0.5) ? floorz(i) : round(i)
}
#special floor: floor towards 0; floorz(1.9)=0, floorz(-1.9)=-1
Function floorz(float i) {
    return sign(i)*floor(abs(i))
}
#parse color strings
Function yof(string c) {
    return int(value(midstr(c,1,3)))
}
Function uof(string c) {
    return int(value(midstr(c,5,3)))
}
Function vof(string c) {
    return int(value(midstr(c,9,3)))
}
#simple block of color w,h, color
Function block(string c, int w, int h) {
    w=(w%2)==1?w+1:w
    pair(yof(c),yof(c),uof(c),vof(c),int(w),h,0)
}
#Rec.709 values of color bars, to be used only for digital or hd signals
blkm2="012,128,128"
blk="016,128,128"
blkp2="020,128,128"
blkp4="025,128,128"
gry15="049,128,128"
gry40="104,128,128"
wht75="180,128,128"
wht100="235,128,128"
yel75="168,044,136"
cyn75="145,147,44"
grn75="134,063,052"
mag75="063,193,204"
red75="051,109,212"
blu75="028,212,120"
yel100="219,016,138"
cyn100="188,154,016"
red100="063,102,240"
blu100="032,240,118"
#need to check this, as -I is 16,158,95, document specified +I
plusi="016,158,095"
plusq="16,175,150" #used for SMPTE HD (ref?)

choice=plusi

	w=220*1
	d=0
	h=480
	u=10
	v=12
#Function Demos
#loopstack(clip vid,int index,int end, string dir, string hfunc, string vfunc)
#pair(127,128,u,v,2,48,0)
#loopstack(blankclip,1,360,"h","pair(index*2+16,index*2+17,"+String(u)+","+String(v)+",2,"+String(h)+",0)","pair(index*2+16,index*2+17,"+String(u)+","+String(v)+",48,4,0)") 
#YRamp(16,235,128,128,w,h)

a=1920 #or 1280
b=1080 #or 720
c=a*.75/7 #205 5/7
d=(a-.75*a)/2 #240
b1of12=b/12
b3of12=b*3/12
b7of12=b*7/12
c3of2=c*3/2
c5of6=c*5/6
c1of3=c*1/3

#section1
s1a=block(gry40,int(d),b7of12)
s1b=block(wht75,int(c),b7of12)
s1c=block(yel75,int(c),b7of12)
s1d=block(cyn75,int(c),b7of12)
s1e=block(grn75,int(c),b7of12)
s1f=block(mag75,int(c),b7of12)
s1g=block(red75,int(c),b7of12)
s1h=block(blu75,int(c),b7of12)
s1i=block(gry40,int(d),b7of12)
s1=stackhorizontal(s1a,s1b,s1c,s1d,s1e,s1f,s1g,s1h,s1i).pointresize(a,b7of12)

#section2
h=b1of12
s2a=block(cyn100,int(d),h)
s2b=block(choice,int(c),h)
s2c=block(wht75,int(6*c),h)
s2d=block(blu100,int(d),h)
s2=stackhorizontal(s2a,s2b,s2c,s2d)

#section3
h=b1of12
s3a=block(yel100,int(d),h)
s3b=ramp(int(7*c),h)
s3c=block(red100,int(d),h)
s3=stackhorizontal(s3a,s3b,s3c)

#section4
h=b3of12
s4a=block(gry15,int(d),h)
s4b=block(blk,int(c3of2),h)
s4c=block(wht100,int(c*2),h)
s4d=block(blk,int(c5of6),h)
s4e=block(blkm2,int(c1of3),h)
s4f=block(blk,int(c1of3),h)
s4g=block(blkp2,int(c1of3),h)
s4h=block(blk,int(c1of3),h)
s4i=block(blkp4,int(c1of3),h)
s4j=block(blk,int(c),h)
s4k=block(gry15,int(d),h)
s4=stackhorizontal(s4a,s4b,s4c,s4d,s4e,s4f,s4g,s4h,s4i,s4j,s4k).pointresize(a,h)
arib_std_b28=stackvertical(s1,s2,s3,s4)
arib_std_b28