Recensubs HQ

Hardsubbare roba a 16bit YUV 4:4:4

« Older   Newer »
  Share  
view post Posted on 17/12/2012, 20:54     +1   -1
Avatar

Bimbosp

Group:
Administrator
Posts:
9,780
Reputation:
+929
Location:
Gallarate (VA)

Status:


Chi typesetta in after effects non si fa tutto l'episodio in alpha per l'overlay. Fa la singola scena, al che l'encoder deve fare overlay nel punto e basta.
Facendola in questo modo semplifico il tutto perché non ci sono eccezioni di cui tenere conto. Metti caso che l'overlay sia sul frame 0 o sull'ultimo frame e basta, oppure metti caso che realmente deve fare overlay su tutto il video (typeset in ass, in genere). Al posto di mettere qualche if per decidere come fare lo splice, io aggiungo sempre e comunque 2 frame in più all'inizio e due frame in più alla fine (non nel migliore dei modi, ok, dovrei farlo tramite blankclip per sicurezza, ma vabbè), cosicché ci sia sempre da fare splice all'inizio e alla fine (e anche in casi particolari come solo il frame 0 l'utente può specificare 0 -1 senza problemi e diventa 2 -1; specificare 0 0 si comporta come avisynth e tiene tutto).

Comunque ti sei perso un pezzo di codice per strada per la e
CODICE
e = default(e,0)
e = (e > 0) ? e+2 : (e == 0) ? framecount+1 : e

In questo modo funziona con qualsiasi metodo.
Se l'utente non specifica niente, viene messo a 0 (ultimo frame del video) di default, altrimenti tiene il parametro.
A quel punto, se e è maggiore di 0, significa che ha specificato il numero di frame. Siccome aggiungerò 2 frame in più all'inizio, anche la fine si sposterà di 2 frame in avanti.
Se e è uguale a 0, devo tenere l'ultimo frame del video. Siccome avisynth inizia a contare da 0, l'ultimo frame è normalmente framecount-1, ma in questo caso poi andrò ad aggiungere i due frame all'inizio per cui aggiungendo uno al framecount attuale è come se aggiungessi i due frame, facessi framecount-1 e poi aggiungessi i 2 finali che non voglio tenere.
Infine, se l'utente ha usato una e negativa, significa che vuole tenere un tot numero di frame (-1 tiene un frame, -2 tiene due frame, etc), per cui il valore di e non deve cambiare, siccome già s viene aggiustato.
 
Web  Top
view post Posted on 17/12/2012, 22:57     +1   -1
Avatar

Member

Group:
Utente abilitato
Posts:
501
Reputation:
+10

Status:


CITAZIONE (mirkosp @ 17/12/2012, 20:54) 
Chi typesetta in after effects non si fa tutto l'episodio in alpha per l'overlay. Fa la singola scena, al che l'encoder deve fare overlay nel punto e basta.
Facendola in questo modo semplifico il tutto perché non ci sono eccezioni di cui tenere conto. Metti caso che l'overlay sia sul frame 0 o sull'ultimo frame e basta, oppure metti caso che realmente deve fare overlay su tutto il video (typeset in ass, in genere). Al posto di mettere qualche if per decidere come fare lo splice, io aggiungo sempre e comunque 2 frame in più all'inizio e due frame in più alla fine (non nel migliore dei modi, ok, dovrei farlo tramite blankclip per sicurezza, ma vabbè), cosicché ci sia sempre da fare splice all'inizio e alla fine (e anche in casi particolari come solo il frame 0 l'utente può specificare 0 -1 senza problemi e diventa 2 -1; specificare 0 0 si comporta come avisynth e tiene tutto).

Comunque ti sei perso un pezzo di codice per strada per la e
CODICE
e = default(e,0)
e = (e > 0) ? e+2 : (e == 0) ? framecount+1 : e

In questo modo funziona con qualsiasi metodo.
Se l'utente non specifica niente, viene messo a 0 (ultimo frame del video) di default, altrimenti tiene il parametro.
A quel punto, se e è maggiore di 0, significa che ha specificato il numero di frame. Siccome aggiungerò 2 frame in più all'inizio, anche la fine si sposterà di 2 frame in avanti.
Se e è uguale a 0, devo tenere l'ultimo frame del video. Siccome avisynth inizia a contare da 0, l'ultimo frame è normalmente framecount-1, ma in questo caso poi andrò ad aggiungere i due frame all'inizio per cui aggiungendo uno al framecount attuale è come se aggiungessi i due frame, facessi framecount-1 e poi aggiungessi i 2 finali che non voglio tenere.
Infine, se l'utente ha usato una e negativa, significa che vuole tenere un tot numero di frame (-1 tiene un frame, -2 tiene due frame, etc), per cui il valore di e non deve cambiare, siccome già s viene aggiustato.

Spiegato perfettamente ^_^
Probabile che ho lasciato un po' di codice per strada... visto che sto riassemblando un po' il codice che hai scritto. Se avrò tempo le converto pure in un linguaggio più alto, visto che avisynth mi sta dando sui nervi per quando è limitato nella struttura.
 
Top
view post Posted on 14/4/2013, 21:18     +1   -1

Member

Group:
Utente abilitato
Posts:
968
Reputation:
+161
Location:
Trentino Alto Adige

Status:


CITAZIONE (mirkosp @ 18/11/2012, 21:48) 
Nuova versione del 4:2:0, perché c'era un errorone col mask, che m'ero scordato di aggiustare per il chroma. Oops.

CODICE
#HardSub Utilities for P016 v1.3 by mirkosp
#P016 is 16bit YUV 4:2:0, by the way. But if you care about this, you likely knew already.
#And of course I mean dithertools' stacked thing, which technically is
#a stacked 8bit thingie. Dem hacks.
#Requires dithertools. Also vsfilter and/or vsfiltermod for the ass support.
#I haven't done extensive testing, so please report any errors you find.

#First and foremost, rgb32 afx clips
#l is the video to overlay on (typically left to last)
#c is the clip to be overlayed
#s is the frame on which to start the overlay
#e is the frame on which to end the overlay
#I'm nice enough to allow the usage of -num_frames style too, tho.
#sm is the colormatrix and tv is a bool for tv range (true) or not (false).
#You should be using dither_convert_rgb_to_yuv's values for sm, but
#uf you're using avisynth's, I'm doing a somewhat rough check myself.
#This also allows me to just call this function later on for ass hardsubbing...

function rgb32onp016(clip l, clip c, int "s", int "e", string "sm", bool "tv") {
assert(c.isrgb32, "dudeplz.")
assert(l.isyv12, "dudeplz.")
assert(l.width == c.width, "check width")
assert(l.height/2 == c.height, "check height")
tv = defined(tv) ? tv : defined(sm) ? sm == "PC.601" ? false : sm == "PC.709" ? false : tv : true
sm = defined(sm) ? sm == "Rec601" ? "601" : sm == "Rec709" ? "709" : sm == "PC.601" ? "601" : sm == "PC.709" ? "709" : sm : (c.width > 1024 || c.height > 600) ? "709" : "601"
s = default(s,0)
e = default(e,0)
s=s+2
l
e = (e > 0) ? e+2 : (e == 0) ? framecount+1 : e
ps = s-1
pe = (e > 0) ? e+1 : s-e
l = l.trim(0,1)+l+l.trim(0,1) #HAX! I don't feel like doing special case checks. Maybe it executes faster this way, too.
l
sa = l.trim(0,ps).converttorgb32()+stackvertical(c.showalpha("rgb32"),c.showalpha("rgb32"))+last.trim(pe,0).converttorgb32()
oc = l.trim(0,ps)+(c.Dither_convert_rgb_to_yuv(output="yv12",matrix=sm,tv_range=tv).dither_convert_8_to_16())+last.trim(pe,0)
l.trim(0,ps)+ytouv(overlay(last.utoy(),oc.utoy(),mask=sa.reduceby2()),overlay(last.vtoy(),oc.vtoy(),mask=sa.reduceby2()),overlay(last,oc,mask=sa)).trim(s,e)+l.trim(pe,0)
return trim(2,framecount-3)
}

#And now for the ass functions
#sm is the colormatrix. If left unspecified, it's autoguessed based on res.
#path is the ass' path, hack is for the bt601 typeset deal.
#If the video you have to overlay on is bt709 and you
#have typeset in bt601 to compensate for the old vsfilter,
#set this to true.
#vfr is the path to the timecodes.
#At the time of the writing, softsubbed 4:2:0 is usually overlayed
#as bt601 due to an old vsfilter bug which is by now standard.
#This means that if you have HD video you should set this to true. Default behaviour autoguesses this.
#I'm not 100% sure these work correctly, please report bugs if you encounter them.

function textsubmodonp016(clip cs, string path, string "vfr", string "sm", bool "hack") {
c = cs.ditherpost(mode=8)
sm = defined(sm) ? sm : (c.width > 1024 || c.height > 600) ? "Rec709" : "Rec601"
hack = defined(hack) ? hack : sm == "Rec709" ? true : sm == "PC.709" ? true : false
bc = blankclip(c,pixel_type="RGB32",color=$FF000000)#pure alpha
crgb = hack ? c.converttorgb32(matrix="Rec601") : c.converttorgb32(matrix=sm)
mergeargb(bc.showalpha(),crgb.showred(),crgb.showgreen(),crgb.showblue())
defined(vfr) ? textsubmod(path,vfr=vfr) : textsubmod(path)
mergeargb(showalpha().invert(),showred(),showgreen(),showblue())
savealpha = last
o = converttoyv24(matrix="Rec601").converttorgb32(matrix="Rec709")
return hack ? rgb32onp016(cs,mergeargb(savealpha.showalpha(),o.showred(),o.showgreen(),o.showblue()),sm=sm) : rgb32onp016(cs,last,sm=sm)
}

function textsubonp016(clip cs, string path, string "vfr", string "sm", bool "hack") {
c = cs.ditherpost(mode=8)
sm = defined(sm) ? sm : (c.width > 1024 || c.height > 600) ? "Rec709" : "Rec601"
hack = defined(hack) ? hack : sm == "Rec709" ? true : sm == "PC.709" ? true : false
bc = blankclip(c,pixel_type="RGB32",color=$FF000000)#pure alpha
crgb = hack ? c.converttorgb32(matrix="Rec601") : c.converttorgb32(matrix=sm)
mergeargb(bc.showalpha(),crgb.showred(),crgb.showgreen(),crgb.showblue())
defined(vfr) ? textsub(path,vfr=vfr) : textsub(path)
mergeargb(showalpha().invert(),showred(),showgreen(),showblue())
savealpha = last
o = converttoyv24(matrix="Rec601").converttorgb32(matrix="Rec709")
return hack ? rgb32onp016(cs,mergeargb(savealpha.showalpha(),o.showred(),o.showgreen(),o.showblue()),sm=sm) : rgb32onp016(cs,last,sm=sm)
}

CODICE
Dither_convert_8_to_16()

       input = last

       gradfun3(0.3, smode=2, radius=17, lsb_in=true, lsb=true)
       
       Dither_resize16(848,480,src_left=-0.5,kernel="bilinear",y=3, u=1, v=1,invks=true,invkstaps=5)                        A

       noalias = input.Dither_resize16nr(848,480,src_left=-0.5,kernel="blackmanminlobe",taps=4,y=3,u=3,v=3)          B
       Mergechroma(noalias)                                                                                                                                  C

       dither_add_grain16(1.0, soft=100)

       textsubonp016(last, SUB_OP_ED, sm="Rec601")
       
#        Dither_quantize(10, reducerange=true, mode=8)

Dither_out()


Ottengo l'errore: "Mask and overlay must have the same image size! (Width is not the same)". Questo errore salta fuori anche se commento le righe A, B e C

Cosa sto sbagliando?

In ogni caso, grazie!
 
Top
view post Posted on 14/4/2013, 21:47     +1   +1   -1
Avatar

Distruttore di mercati

Group:
Utente abilitato
Posts:
682
Reputation:
+163
Location:
Aiur

Status:


A me quell'errore lo dava con la prima versione che aveva fatto sp per il 4:2:0, prova a rifare l'avsi con quella corretta che ha postato dopo:

#entry519405352

P.S. debanding meglio dopo il resize, poi perché stai shiftando luma e chroma di mezzo pixel?
 
Top
view post Posted on 14/4/2013, 22:15     +1   -1

Member

Group:
Utente abilitato
Posts:
968
Reputation:
+161
Location:
Trentino Alto Adige

Status:


CITAZIONE (Liquid Dr4k3 @ 14/4/2013, 22:47) 
A me quell'errore lo dava con la prima versione che aveva fatto sp per il 4:2:0, prova a rifare l'avsi con quella corretta che ha postato dopo:

#entry519405352

P.S. debanding meglio dopo il resize, poi perché stai shiftando luma e chroma di mezzo pixel?

Risolto... ma ancora non capisco qual era il problema. Lo stesso testo che, seguendo il tuo consiglio, ho messo in un file avsi lo avevo messo in testa allo script. Isolato in un file a parte, funziona.

Sì, fra prove di vario genere il gradfun3 è rimasto fuoriposto. Grazie in ogni caso per l'osservazione.

Il 0.5 viene da questo: https://recensubshq.forumfree.it/?t=64839203
Nel creare l'AVI ho usato il nnedi3, ma ammetto che sto utilizzando pezzi di codice senza avere molto chiaro che cosa sto usando; dato che poi al video cambio solo la dimensione orizzontale (invece di fare un encode anamorfico), c'è un solo 0.5. Immagino che sarebbe il caso di fare l'operazione completa (uso di nnedi3 e "resize") in quel passaggio.

In ogni caso, grazie ancora!
 
Top
view post Posted on 14/4/2013, 22:23     +1   -1
Avatar

Distruttore di mercati

Group:
Utente abilitato
Posts:
682
Reputation:
+163
Location:
Aiur

Status:


Figurati ^^
Se shifti sia luma che chroma è inutile perché il chroma resterà decentrato. Se nnedi lo hai usato sia orizzontalmente che verticalmente shifta 0,5 sopra e a sinistra, ma solo sul luma. Comunque se stai encodando da dvd ti consiglio di fare anamorfico e flaggare 16:9 così eviti sbattimenti. Inoltre se stai facendo output a 10 bit suppongo che tu stia encodando a 10 bit, quindi leva anche dither_add_grain16(1.0, soft=100) che tanto il banding non ti viene reintrodotto da h264.

Edited by Liquid Dr4k3 - 15/4/2013, 00:12
 
Top
view post Posted on 14/4/2013, 22:41     +1   -1

Member

Group:
Utente abilitato
Posts:
968
Reputation:
+161
Location:
Trentino Alto Adige

Status:


CITAZIONE (Liquid Dr4k3 @ 14/4/2013, 23:23) 
Figurati ^^
Se shifti sia luma che chroma è inutile perché il chroma resterà decentrato. Se nnedi lo hai usato sia orizzontalmente che verticalmente shifta 0,5 sopra e sotto, ma solo sul luma. Comunque se stai encodando da dvd ti consiglio di fare anamorfico e flaggare 16:9 così eviti sbattimenti. Inoltre se stai facendo output a 10 bit suppongo che tu stia encodando a 10 bit, quindi leva anche dither_add_grain16(1.0, soft=100) che tanto il banding non ti viene reintrodotto da h264.

Grazie per le informazioni!
Proverò entrambe le cose, resize e flag, con il resize messo come lo indichi tu. La quantizzazione a 10 è un refuso da un'altra prova; qui vorrei utilizzare l'opzione --input-depth 16 di x264.

:)
 
Top
view post Posted on 14/4/2013, 22:47     +1   +1   -1
Avatar

Distruttore di mercati

Group:
Utente abilitato
Posts:
682
Reputation:
+163
Location:
Aiur

Status:


Anche fare nnedi e invks solo orizzontalmente può essere una buona idea, sinceramente non ho mai provato quindi non so se sia meglio così o anamorfico. Ma in tal caso visto che stai upscalando solo orizzontalmente suppongo te abbia fatto turnright->nnedi->turnleft e quindi hai solo -0,5 di shift verticale.

P.S. ti consiglio di fare Dither_quantize(10, reducerange=true, mode=8) e da h264 --input-depth 10 in modo da evitare dither in h264
 
Top
view post Posted on 7/9/2016, 21:46     +1   -1

Member

Group:
Utente abilitato
Posts:
968
Reputation:
+161
Location:
Trentino Alto Adige

Status:


Ho provato a modificare le funzioni di Mirkosp usando MaskCL (sempre di Mirkosp) al posto di overlay.

Francamente non so se lo script che ne è risultato fa le cose correttamente (va ancora un bel al di là della mia piena comprensione) però, almeno per quanto riguarda textsubony416 (per 4:4:4 16bit) e textsubonp016 (4:2:0 16bit) mi restituisce l'immagine con le scritte e il colore corretto. Quindi casomai voleste verificare, aggiungo il codice sotto spoiler.

A vostro rischio e pericoloPer il vostro sollazzo.

CODICE
#MaskCL v1.3 by mirkosp
#Mask without the 255 bug and no weird workarounds using opencl.
#Might or might not be faster than dither_merge16 / dither_merge16_8, see if it is for you.
#0 keeps src, 255 keeps overlay, everything else is the intended inbetween (at least it should be).
#Requires tp7's CLExpr: https://github.com/tp7/CLExpr (check "Releases" for download links).
#No error checking so if shit doesn't work as expected blame it on yourself.
#Just supply YUV clips with same colorspace, resolution, framerate, and length to make sure it'll work fine.
#v1.0 and 1.1 were bugged with 16bit because I'm dumb. Like, a lot. YAAAY!
#v1.2 supported yv24 only with luma=true so here goes v1.3.

function MaskCL(clip src, clip overlay, clip mask, int "y", int "u", int "v", bool "luma", bool "lsb_inout", bool "mask8") {

y                         =         Default(y,3)
u                         =         Default(u,2)
v                         =         Default(v,2)
luma                         =         Default(luma,false)
lsb_inout                 =         Default(lsb_inout,false)
mask8                 =         lsb_inout ? Default(mask8,false) : false

mask                 =         luma ? ytouv(mask,mask,mask) : mask
mask                 =         src.isyv12() ? mask.converttoyv12(matrix="PC.601") : src.isyuy2() ? mask.converttoyuy2(matrix="PC.601") : src.isyv16() ? mask.converttoyv16(matrix="PC.601") : mask
mask                 =         mask8 ? stackvertical(mask,mask) : mask

                               lsb_inout ? cl_exprxyz(src,overlay,mask,"x 65535 z - * y z * + 65535 /",y=y,u=u,v=v,lsb=true) : cl_exprxyz(src,overlay,mask,"x 255 z - * y z * + 255 /",y=y,u=u,v=v,lsb=false)
}


#HardSub Utilities for Y416 v1.2 by mirkosp
#Y416 is 16bit YUV 4:4:4, by the way. But if you care about this, you likely knew already.
#And of course I mean dithertools' stacked thing, which technically is
#a stacked 8bit thingie. Dem hacks.
#Requires dithertools. Also vsfilter and/or vsfiltermod for the ass support.
#I haven't done extensive testing, so please report any errors you find.

#First and foremost, rgb32 afx clips
#l is the video to overlay on (typically left to last)
#c is the clip to be overlayed
#s is the frame on which to start the overlay
#e is the frame on which to end the overlay
#I'm nice enough to allow the usage of -num_frames style too, tho.
#sm is the colormatrix and tv is a bool for tv range (true) or not (false).
#You should be using dither_convert_rgb_to_yuv's values for sm, but
#uf you're using avisynth's, I'm doing a somewhat rough check myself.
#This also allows me to just call this function later on for ass hardsubbing...

function rgb32ony416(clip l, clip c, int "s", int "e", string "sm", bool "tv") {

                               assert(c.isrgb32, "dudeplz.")
                               assert(l.isyv24, "dudeplz.")
                               assert(l.width == c.width, "check width")
                               assert(l.height/2 == c.height, "check height")

tv                         =         defined(tv) ? tv : defined(sm) ? sm == "PC.601" ? false : sm == "PC.709" ? false : tv : true
sm                         =         defined(sm) ? sm == "Rec601" ? "601" : sm == "Rec709" ? "709" : sm == "PC.601" ? "601" : sm == "PC.709" ? "709" : sm : (c.width > 1024 || c.height > 600) ? "709" : "601"
s                         =         default(s,0)
e                         =         default(e,0)
s                         =        s+2

l

e                         =         (e > 0) ? e+2 : (e == 0) ? framecount+1 : e
ps                         =         s-1
pe                         =         (e > 0) ? e+1 : s-e
l                         =         l.trim(0,1)+l+l.trim(0,1) #HAX! I don't feel like doing special case checks. Maybe it executes faster this way, too.

l

sa                         =         l.trim(0,ps).converttorgb32()+stackvertical(c.showalpha("rgb32"),c.showalpha("rgb32"))+last.trim(pe,0).converttorgb32()
oc                         =         l.trim(0,ps)+(c.Dither_convert_rgb_to_yuv(output="yv24",matrix=sm,tv_range=tv).dither_convert_8_to_16())+last.trim(pe,0)

saC                         =         sa.Dither_convert_rgb_to_yuv(output="yv24",matrix=sm,tv_range=tv).dither_convert_8_to_16()

                                l.trim(0,ps)+ytouv(MaskCL(last.utoy(), oc.utoy(), saC), MaskCL(last.vtoy(), oc.vtoy(), saC), MaskCL(last, oc, saC)).trim(s,e)+l.trim(pe,0)

                                return trim(2,framecount-3) }

#And now for the ass functions
#sm is the colormatrix. If left unspecified, it's autoguessed based on res.
#path is the ass' path, hack is for the bt601 typeset deal.
#If the video you have to overlay on is bt709 and you
#have typeset in bt601 to compensate for the old vsfilter,
#set this to true.
#vfr is the path to the timecodes.
#At the time of the writing, softsubbed 4:4:4 has to be overlayed
#in rgb tho, so it's better to avoid the hack if you're
#dealing with 4:4:4 video, thus I won't account for it by default.
#I'm not 100% sure these work correctly, please report bugs if you encounter them.

function textsubmodony416(clip cs, string path, string "vfr", string "sm", bool "hack") {

hack                 =         default(hack,false)
c                         =         cs.ditherpost(mode=8)
sm                         =         defined(sm) ? sm : (c.width > 1024 || c.height > 600) ? "Rec709" : "Rec601"
bc                         =         blankclip(c,pixel_type="RGB32",color=$FF000000)#pure alpha
crgb                 =         hack ? c.converttorgb32(matrix="Rec601") : c.converttorgb32(matrix=sm)
                               
                               mergeargb(bc.showalpha(),crgb.showred(),crgb.showgreen(),crgb.showblue())
                               defined(vfr) ? textsubmod(path,vfr=vfr) : textsubmod(path)
                               mergeargb(showalpha().invert(),showred(),showgreen(),showblue())

                               savealpha         =         last
o                         =         converttoyv24(matrix="Rec601").converttorgb32(matrix="Rec709")

return hack ? rgb32ony416(cs,mergeargb(savealpha.showalpha(),o.showred(),o.showgreen(),o.showblue()),sm=sm) : rgb32ony416(cs,last,sm=sm)
}


function textsubony416(clip cs, string path, string "vfr", string "sm", bool "hack") {

hack                         =         default(hack,false)
c                         =         cs.ditherpost(mode=8)
sm                         =         defined(sm) ? sm : (c.width > 1024 || c.height > 600) ? "Rec709" : "Rec601"
bc                         =         blankclip(c,pixel_type="RGB32",color=$FF000000)#pure alpha
crgb                     =         hack ? c.converttorgb32(matrix="Rec601") : c.converttorgb32(matrix=sm)

                               mergeargb(bc.showalpha(),crgb.showred(),crgb.showgreen(),crgb.showblue())
                               defined(vfr) ? textsub(path,vfr=vfr) : textsub(path)
                               mergeargb(showalpha().invert(),showred(),showgreen(),showblue())

savealpha                 =        last
o                         =        converttoyv24(matrix="Rec601").converttorgb32(matrix="Rec709")

return hack ? rgb32ony416(cs,mergeargb(savealpha.showalpha(),o.showred(),o.showgreen(),o.showblue()),sm=sm) : rgb32ony416(cs,last,sm=sm)
}


#HardSub Utilities for P016 v1.3 by mirkosp
#P016 is 16bit YUV 4:2:0, by the way. But if you care about this, you likely knew already.
#And of course I mean dithertools' stacked thing, which technically is
#a stacked 8bit thingie. Dem hacks.
#Requires dithertools. Also vsfilter and/or vsfiltermod for the ass support.
#I haven't done extensive testing, so please report any errors you find.

#First and foremost, rgb32 afx clips
#l is the video to overlay on (typically left to last)
#c is the clip to be overlayed
#s is the frame on which to start the overlay
#e is the frame on which to end the overlay
#I'm nice enough to allow the usage of -num_frames style too, tho.
#sm is the colormatrix and tv is a bool for tv range (true) or not (false).
#You should be using dither_convert_rgb_to_yuv's values for sm, but
#uf you're using avisynth's, I'm doing a somewhat rough check myself.
#This also allows me to just call this function later on for ass hardsubbing...

function rgb32onp016(clip l, clip c, int "s", int "e", string "sm", bool "tv") {

                               assert(c.isrgb32, "dudeplz.")
                               assert(l.isyv12, "dudeplz.")
                               assert(l.width == c.width, "check width")
                               assert(l.height/2 == c.height, "check height")

                               
tv                         =         defined(tv) ? tv : defined(sm) ? sm == "PC.601" ? false : sm == "PC.709" ? false : tv : true
sm                         =         defined(sm) ? sm == "Rec601" ? "601" : sm == "Rec709" ? "709" : sm == "PC.601" ? "601" : sm == "PC.709" ? "709" : sm : (c.width > 1024 || c.height > 600) ? "709" : "601"
s                         =         default(s,0)
e                         =         default(e,0)
s                         =        s+2

l

e                         =         (e > 0) ? e+2 : (e == 0) ? framecount+1 : e
ps                         =         s-1
pe                         =        (e > 0) ? e+1 : s-e
l                         =         l.trim(0,1)+l+l.trim(0,1) #HAX! I don't feel like doing special case checks. Maybe it executes faster this way, too.

l

sa                         =         l.trim(0,ps).converttorgb32()+stackvertical(c.showalpha("rgb32"),c.showalpha("rgb32"))+last.trim(pe,0).converttorgb32()
oc                         =         l.trim(0,ps)+(c.Dither_convert_rgb_to_yuv(output="yv12",matrix=sm,tv_range=tv).dither_convert_8_to_16())+last.trim(pe,0)

laC                         =         last.ConvertToYV24().dither_convert_8_to_16()
saC                          =         sa.Dither_convert_rgb_to_yuv(output="yv24",matrix=sm,tv_range=tv, lsb=true).dither_convert_8_to_16()
lC                          =         l.ConvertToYV24().dither_convert_8_to_16()
ocC                         =         oc.ConvertToYV24().dither_convert_8_to_16()

                               lC.trim(0,ps)+ytouv(MaskCL(laC.utoy(), ocC.utoy(), saC), MaskCL(laC.vtoy(), ocC.vtoy(), saC), MaskCL(laC, ocC, saC)).trim(s,e)+lC.trim(pe,0)

                               last.DitherPost(mode=8)
                               
return trim(2,framecount-3)
}

#And now for the ass functions
#sm is the colormatrix. If left unspecified, it's autoguessed based on res.
#path is the ass' path, hack is for the bt601 typeset deal.
#If the video you have to overlay on is bt709 and you
#have typeset in bt601 to compensate for the old vsfilter,
#set this to true.
#vfr is the path to the timecodes.
#At the time of the writing, softsubbed 4:2:0 is usually overlayed
#as bt601 due to an old vsfilter bug which is by now standard.
#This means that if you have HD video you should set this to true. Default behaviour autoguesses this.
#I'm not 100% sure these work correctly, please report bugs if you encounter them.

function textsubmodonp016(clip cs, string path, string "vfr", string "sm", bool "hack") {

c                                 =         cs.ditherpost(mode=8)
sm                                 =         defined(sm) ? sm : (c.width > 1024 || c.height > 600) ? "Rec709" : "Rec601"
hack                                 =         defined(hack) ? hack : sm == "Rec709" ? true : sm == "PC.709" ? true : false
bc                                 =         blankclip(c,pixel_type="RGB32",color=$FF000000)#pure alpha
crgb                                 =         hack ? c.converttorgb32(matrix="Rec601") : c.converttorgb32(matrix=sm)

                                       mergeargb(bc.showalpha(),crgb.showred(),crgb.showgreen(),crgb.showblue())
                                       defined(vfr) ? textsubmod(path,vfr=vfr) : textsubmod(path)
                                       mergeargb(showalpha().invert(),showred(),showgreen(),showblue())

savealpha                         =         last
o                                 =         converttoyv24(matrix="Rec601").converttorgb32(matrix="Rec709")

return hack ? rgb32onp016(cs,mergeargb(savealpha.showalpha(),o.showred(),o.showgreen(),o.showblue()),sm=sm) : rgb32onp016(cs,last,sm=sm)
}


function textsubonp016(clip cs, string path, string "vfr", string "sm", bool "hack") {

c                                 =         cs.ditherpost(mode=8)
sm                                 =         defined(sm) ? sm : (c.width > 1024 || c.height > 600) ? "Rec709" : "Rec601"
hack                                 =         defined(hack) ? hack : sm == "Rec709" ? true : sm == "PC.709" ? true : false
bc                                 =         blankclip(c,pixel_type="RGB32",color=$FF000000)#pure alpha
crgb                                 =         hack ? c.converttorgb32(matrix="Rec601") : c.converttorgb32(matrix=sm)

                                       mergeargb(bc.showalpha(),crgb.showred(),crgb.showgreen(),crgb.showblue())
                                       defined(vfr) ? textsub(path,vfr=vfr) : textsub(path)

                                       mergeargb(showalpha().invert(),showred(),showgreen(),showblue())
                                       
savealpha                         =         last
o                                 =         converttoyv24(matrix="Rec601").converttorgb32(matrix="Rec709")

return hack ? rgb32onp016(cs,mergeargb(savealpha.showalpha(),o.showred(),o.showgreen(),o.showblue()),sm=sm) : rgb32onp016(cs,last,sm=sm)
}
 
Top
23 replies since 29/8/2012, 20:27   2425 views
  Share