Log in

View Full Version : Spline64 - Faster?


zerowalker
20th September 2014, 03:16
Just wondering, is there any optimizations i have missed for Spline64?

Like an OpenCL version etc?

Or perhaps there is a similar approach that's quite faster?

Nothing special of use, just noticed that it could be quite slow when resizing to 1080p (which is understandable).

Keiyakusha
20th September 2014, 03:41
Just wondering, is there any optimizations i have missed for Spline64?

Like an OpenCL version etc?

Or perhaps there is a similar approach that's quite faster?

Nothing special of use, just noticed that it could be quite slow when resizing to 1080p (which is understandable).

Nothing I heard of, except... Spline36 :D. Spline64 is for those who whatever don't care about speed or think it improves something even though they hardly see the difference (Especially if you do some additional processing after scaling)

feisty2
20th September 2014, 05:37
just take a look at the speed of eedi3_rpow2, then I'm sure you'll believe spline64resize is incredibly fast :D

Groucho2004
20th September 2014, 10:13
I don't find Spline64 that slow compared to the "standard" resizers. Here's some numbers taken with AVSMeter resizing a SD clip (720*576) to 1920*1080:

pointresize(1920, 1080) : 615 fps
lanczosresize(1920, 1080): 256 fps
spline36resize(1920, 1080): 256 fps
spline64resize(1920, 1080): 215 fps

(i5 2500K, WinXP32, Avisynth 2.6A5)

feisty2
20th September 2014, 11:11
omg, is winxp still alive?

zerowalker
20th September 2014, 15:37
Hmm, interesting, 215 fps is far faster than i achieved in my test (though i encoded with x264, but that wasn't the bottleneck funny enough).
The only thing i did was pretty much, resize and then ConverttoYV12, and i can't see that being the culprit as it simply "discards" data, which should be fairly fast.

I think i compared 64 to 32, and in this case i saw a very small different, but to the better (it's very simple cartoon like stuff, so edges and small lines etc, Happy Wheels).
Will have to do a test next time i do the same thing and come back.

Still, couldn't this stuff be improved a lot with OpenCL, as isn't Resizing something that GPUs handle really well?

feisty2
20th September 2014, 15:57
can you post the full script that resulted in low speed spline64resize?

zerowalker
20th September 2014, 16:00
Avisource("Z:\Happy Wheels - 2014-09-18 9-58 PM.avi").ChangeFPS(30, linear=true)
ZoomBox(width=1920, height=1080, ResizeMethod="Spline64Resize")
ConvertToYV12(matrix="Rec709", interlaced=false)
Amplify(8.0)


(ZoomBox basically keeps the Aspect Ratio by adding black borders automatically).

But will do another recording now, and see if i get same results.

feisty2
20th September 2014, 16:05
what's the colorspace of your clip, is it rgb24?

zerowalker
20th September 2014, 16:40
RGB32.

Also did a test right now.

ZoomBox = about 35fps.
Stretch (normal resize) = about 58 fps.

Original Size is 900x500.

Reel.Deel
20th September 2014, 16:46
Since you're converting to YV12 anyways, why don't you do something like this? Did not try but I assume is a little bit faster.
Avisource("Z:\Happy Wheels - 2014-09-18 9-58 PM.avi").ChangeFPS(30, linear=true)
ConvertToYV12(matrix="Rec709", interlaced=false)
ZoomBox(width=1920, height=1080, ResizeMethod="Spline64Resize")
Amplify(8.0)

zerowalker
20th September 2014, 16:50
I Convert to YV12 afterwards as it reduces Chroma Bleeding (as it has some very small colored text at times).

But yeah it will be faster, about 15fps it seems.

Can't see how you get 200fps with Spline64, i get 50-60.
And if i don't do anything and just Decode i get about 400-500, so the Codec isn't the bottleneck.

Groucho2004
20th September 2014, 16:54
Can't see how you get 200fps with Spline64, i get 50-60.
- Which Avisynth version do you use (older Avisynth versions are significantly slower at resizing)
- What CPU? AMD CPUs are notoriously slow with Avisynth.

Also, post the Zoombox script just for reference.

zerowalker
20th September 2014, 17:21
Avisynth+ r1697.

CPU Intel i5 760 @ 4Ghz.


ZoomBox script (It's Not mine, found it some years ago).

# ZoomBox() - June 12st, 2008
# Put a "box" around a clip. Box can be used to zoom in or out. Accepts Any Colorspace. Can correct for DAR (Display Aspect Ratio).
#
#
# Inputs
# clip c: Accepts Any Colorspace.
# Optional Parameters:
# int width: output width
# int height: output height
# string ResizeMethod: name of resize function. Default = BilinearResize
# float ModAR: Set the Output Aspect Ratio. If 0 then it uses the source aspect ratio (needed for animate).
#
# Mode 2 - Align clip
# int Align: -9 to +9 (0=Do not use Align). Positive values - fit with no black borders, may crop clip. Negative values - fit with black borders, may letterbox clip.
# 1:top left. 2:top center. 3:top right.
# 4:middle left. 5:middle center. 6:middle bottom.
# 7:bottom left. 8:bottom center. 9:bottom right.
#
# Mode 1 - Coordinates for ZoomBox:
# float x1: upper left x cord
# float y1: upper left y cord
# float x2: lower right x cord
# float y2: lower right y cord
# 3 or 4 out of 4 points must be defined when using Mode 1
# when omitting a single point, it will calculate the missing value, with the Aspect Ratio in mind.
#
# float zoomFactor: 100 = 100%, ect...
# Negative values is the zoom of the pixels, positive values is the zoom of the frame.
# When converting AR, this isn't perfect.
# float panX: shift the clip x pixels. Value in source pixels. - left, + right
# float panY: shift the clip x pixels. Value in source pixels. - up, + down
# int color: Color of letterbox border. Default: $000000 (Black).
#
#
# Notes
# Clip should be deinterlaced for best visual quality.
# Aspect ratio for output and box(x1,y1,x2,y2) should be the same, unless you want to distort the clip.
# Default behavor is to center clip by adding borders (Align=-5).
# Useful for resizing clip sources (like pictures) to match the dimension of another clip.
# If you specify Align (Mode 2) and x1,y1,x2,y2 (Mode 1), Mode 1 will be used and the align will controll the position of the zoomFactor.
# Mode 1 (x1,y1,x2,y2) can take values from a crop opperation. x2 and y2 must be negative though; so if x2 or y2 equals 0, replace 0 with -0.00001.

Function ZoomBox(clip c, int "width", int "height", string "ResizeMethod",
\ float "SourcePAR", float "SourceDAR", float "TargetPAR", float "TargetDAR",
\ int "Align", float "x1", float "y1", float "x2", float "y2", float "zoomFactor", float "panX", float "panY",
\ int "color")
{
#Set Defaults
width = Default(width, c.width())
height = Default(height, c.height())
ResizeMethod = Default(ResizeMethod, "BilinearResize")
SourceAR = float(c.width())/float(c.height())
TargetAR = float(width)/float(height)
Align = Default(Align, -5) #Align=-5 (center and add borders to fit).
zoomFactor = Default(zoomFactor, 100.0)
panX = Default(panX, 0)
panY = Default(panY, 0)
color = Default(color, $000000)

modzoom = Max(Float(c.width())/Float(width),Float(c.height())/Float(height))
zoomFactor = zoomFactor<0 ? (abs(zoomFactor)/100.0)*modzoom : (abs(zoomFactor)/100.0)

#Check Inputs
Assert(zoomFactor<>0, "ZoomBox: zoomFactor can not be zero.")
Assert((Defined(x1) && Defined(y1) && (Defined(x2) || Defined(y2))) || !(Defined(x1) && Defined(y1) && Defined(x2) && Defined(y2)), "ZoomBox: when using Mode 1, you must define x1,y1, x2 and/or y2")
Assert(Align<9 || Align>-9, "ZoomBox: Align [" + String(Align) + "] should be between -9 and 9.")

#Do Some Magic
Eval (CalcBox(c, 1, width, height, TargetAR, SourceAR, zoomFactor, panX, panY, Align, x1, y1, x2, y2, SourcePAR, SourceDAR, TargetPAR, TargetDAR))

BoxAR = Float(x2-x1)/Float(y2-y1)
#Check for any unreasonable inputs before resize opperation
Assert(x1<x2, "ZoomBox: x1[" + String(x1) + "] point larger then x2 Point[" + String(x2) + "]")
Assert(y1<y2, "ZoomBox: y1[" + String(y1) + "] point larger then y2 Point[" + String(y2) + "]")


ZoomBoxIt(c, width, height, ResizeMethod, x1, y1, x2, y2, color)
}

Function ZoomBoxIt(clip c, int width, int height, string ResizeMethod, float x1, float y1, float x2, float y2, int color)
{
#Pad clip so resizer interpolates from border when zooming out.
#Conditional Borders... only add if it's going to be used. Border size is size of input frame. Prevents "streaking" when zooming out alot.
borderLeft = x1 < 0 ? c.width():0
borderTop = y1 < 0 ? c.height():0
borderRight = x2 > c.width() ? c.width():0
borderBottom = y2 > c.height() ? c.height():0
c = c.AddBorders(borderLeft,borderTop,borderRight,borderBottom,color)

#Do it! Yes there are only 2 lines that directly act upon the clip.
Eval(ResizeMethod + "(c, " + String(Round(width)) + ", " + String(Round(height)) + ", src_left=" + String(x1+borderLeft) + ", src_top=" + String(y1+borderTop) + ", src_width=" + String(x2-x1) + ", src_height=" + String(y2-y1) + ")")
}

Function CalcBox(clip c, int mode, int width, int height, float TargetAR, float SourceAR, float zoomFactor, float panX, float panY, float Align, float "x1", float "y1", float "x2", float "y2", float "SourcePAR", float "SourceDAR", float "TargetPAR", float "TargetDAR")
{
#PAR/DAR Calculations
SourceDAR = Defined(SourcePAR) ?
\ SourcePAR==0 ? SourceAR : SourcePAR*SourceAR
\ : Defined(SourceDAR) ?
\ SourceDAR==0 ? SourceAR : Float(SourceDAR)
\ : SourceAR
TargetDAR = Defined(TargetPAR) ?
\ TargetPAR==0 ? TargetAR : TargetPAR*TargetAR
\ : Defined(TargetDAR) ?
\ TargetDAR==0 ? TargetAR : Float(TargetDAR)
\ : TargetAR

#Calc ModAR
ModAR = SourceDAR*TargetAR/TargetDAR


#If Align=5 or -5 then center clip. -5: Add borders. 5: Crop. "Mode 2"
#Display Aspect Ratio = Final Output Ratio. No Change, Show All Pixels
#Display Aspect Ratio > Final Output Ratio. Add Height or Crop Width
#Display Aspect Ratio < Final Output Ratio. Add Width or Crop Height
EvalString =
\ Align<>0 && ModAR==TargetAR ?
\ "x1=0
x2=c.width()
y1=0
y2=c.height()"


\ : (Align==-5 || Align==-4 || Align==-6) && ModAR>TargetAR ?
\ "y1=0 - ((height*ModAR-width)/2.0)*(c.height()/Float(width))
y2=c.height() + ((height*ModAR-width)/2.0)*(c.height()/Float(width))
x1=0" + "
x2=c.width()"
\ : (Align==5 || Align==2 || Align==8) && ModAR>TargetAR ?
\ "x1=0 + ((height-width/ModAR)/2.0)*(c.width()/Float(height))
x2=c.width() - ((height-width/ModAR)/2.0)*(c.width()/Float(height))
y1=0
y2=c.height()"
\ : (Align==-5 || Align==-2 || Align==-8) && ModAR<TargetAR ?
\ "x1=0 - ((width/ModAR-height)/2.0)*(c.width()/Float(height))
x2=c.width() + ((width/ModAR-height)/2.0)*(c.width()/Float(height))
y1=0
y2=c.height()"
\ : (Align==5 || Align==4 || Align==6) && ModAR<TargetAR ?
\ "y1=0 + ((width-height*ModAR)/2.0)*(c.height()/Float(width))
y2=c.height() - ((width-height*ModAR)/2.0)*(c.height()/Float(width))
x1=0
x2=c.width()"


\ : (Align==-1 || Align==-2 || Align==-3) && ModAR>TargetAR ?
\ "y1=0
y2=c.height() + ((height*ModAR-width)/1.0)*(c.height()/Float(width))
x1=0
x2=c.width()"
\ : (Align==-1 || Align==-4 || Align==-7) && ModAR<TargetAR ?
\ "x1=0
x2=c.width() + ((width/ModAR-height)/1.0)*(c.width()/Float(height))
y1=0
y2=c.height()"
\ : (Align==-9 || Align==-8 || Align==-7) && ModAR>TargetAR ?
\ "y1=0 - ((height*ModAR-width)/1.0)*(c.height()/Float(width))
y2=c.height()
x1=0
x2=c.width()"
\ : (Align==-9 || Align==-6 || Align==-3) && ModAR<TargetAR ?
\ "x1=0 - ((width/ModAR-height)/1.0)*(c.width()/Float(height))
x2=c.width()
y1=0
y2=c.height()"


\ : (Align==2 || Align==1 || Align==3) && ModAR<TargetAR ?
\ "y1=0
y2=c.height() - ((width-height*ModAR)/1.0)*(c.height()/Float(width))
x1=0
x2=c.width()"
\ : (Align==8 || Align==7 || Align==9) && ModAR<TargetAR ?
\ "y1=0 + ((width-height*ModAR)/1.0)*(c.height()/Float(width))
y2=c.height()
x1=0
x2=c.width()"
\ : (Align==4 || Align==1 || Align==7) && ModAR>TargetAR ?
\ "x1=0
x2=c.width() - ((height-width/ModAR)/1.0)*(c.width()/Float(height))
y1=0
y2=c.height()"
\ : (Align==6 || Align==3 || Align==9) && ModAR>TargetAR ?
\ "x1=0 + ((height-width/ModAR)/1.0)*(c.width()/Float(height))
x2=c.width()
y1=0
y2=c.height()"


\ : ""
Defined(x1) || Defined(y1) || Defined(x2) || Defined(y2) ? nop() : Eval(EvalString)

#For non Align Input "Mode 1"
x1tmp = Default(x1, 0)
y1tmp = Default(y1, 0)
x2tmp = Default(x2, c.width())
y2tmp = Default(y2, c.height())

#Take Crop Like Input
x2tmp = x2tmp<=x1tmp && x2tmp<0 ? c.width() + x2tmp : x2tmp
y2tmp = y2tmp<=y1tmp && y2tmp<0 ? c.height() + y2tmp : y2tmp

#Set Optional parameters "Mode 1"
test = 0
test = Defined(x1) ? test+1 : test+0
test = Defined(x2) ? test+1 : test+0
test = Defined(y1) ? test+1 : test+0
test = Defined(y2) ? test+1 : test+0
Assert(test>=3, "ZoomBox/KenBurnsEffect: At least 3 out of 4 x1, y1, x2, y2 points must be defined; or do not set any")

y2t = !Defined(y2) && Defined(y1) && Defined(x1) && Defined(x2) ? y1tmp + ((x2tmp-x1tmp)/TargetAR)/(SourceAR/ModAR) : y2tmp
x2t = !Defined(x2) && Defined(x1) && Defined(y1) && Defined(y2) ? x1tmp + ((y2tmp-y1tmp)*TargetAR)*(SourceAR/ModAR) : x2tmp
y1t = !Defined(y1) && Defined(y2) && Defined(x1) && Defined(x2) ? y2tmp - ((x2tmp-x1tmp)/TargetAR)/(SourceAR/ModAR) : y1tmp
x1t = !Defined(x1) && Defined(x2) && Defined(y1) && Defined(y2) ? x2tmp - ((y2tmp-y1tmp)*TargetAR)*(SourceAR/ModAR) : x1tmp

#Calc Pan Factor
x1 = x1t-panX
y1 = y1t-panY
x2 = x2t-panX
y2 = y2t-panY

#Calc Zoom Factor
CenterX = (x2-x1)/2.0
CenterY = (y2-y1)/2.0
CenterY = (Align<0 && ModAR>TargetAR)? CenterY*(TargetAR/ModAR): (Align>0 && ModAR<TargetAR)? CenterY*(TargetAR/ModAR): CenterY
CenterX = (Align>0 && ModAR>TargetAR)? CenterX/(TargetAR/ModAR): (Align<0 && ModAR<TargetAR)? CenterX/(TargetAR/ModAR): CenterX

Align = abs(Align)
x1 = (Align==0 || Align==5 || Align==2 || Align==8) && zoomFactor<>1 ? CenterX-((CenterX-x1)/(zoomFactor)) : (Align==3 || Align==6 || Align==9) && zoomFactor<>1 ? CenterX*2.0-(CenterX*2.0-x1)/zoomFactor : x1
y1 = (Align==0 || Align==5 || Align==4 || Align==6) && zoomFactor<>1 ? CenterY-((CenterY-y1)/(zoomFactor)) : (Align==7 || Align==8 || Align==9) && zoomFactor<>1 ? CenterY*2.0-(CenterY*2.0-y1)/zoomFactor : y1
x2 = (Align==0 || Align==5 || Align==2 || Align==8) && zoomFactor<>1 ? CenterX+((x2-CenterX)/(zoomFactor)) : (Align==7 || Align==4 || Align==1) && zoomFactor<>1 ? 1.0/zoomFactor*CenterX+(x2-CenterX)/zoomFactor : x2
y2 = (Align==0 || Align==5 || Align==4 || Align==6) && zoomFactor<>1 ? CenterY+((y2-CenterY)/(zoomFactor)) : (Align==3 || Align==2 || Align==1) && zoomFactor<>1 ? 1.0/zoomFactor*CenterY+(y2-CenterY)/zoomFactor : y2


startString = "startX1=" + String(x1) + "
startY1=" + String(y1) + "
startX2=" + String(x2) + "
startY2=" + String(y2) + ""

endString = "endX1=" + String(x1) + "
endY1=" + String(y1) + "
endX2=" + String(x2) + "
endY2=" + String(y2) + ""

boxString = "x1=" + String(x1) + "
y1=" + String(y1) + "
x2=" + String(x2) + "
y2=" + String(y2) + ""

Return mode==1 ? boxString : mode==2 ? startString : mode==3 ? endString : ""
}


Function SplineCalc(clip c, int mode, int startFrame, float startF, int endFrame, float endF)
{
splineString = mode==1 ?
\ "spline(n, "
\ + String(startFrame-1) + "," + String(startF) + ", "
\ + String(startFrame) + "," + String(startF) + ", "
\ + String(endFrame) + "," + String(endF) + ", "
\ + String(endFrame+1) + "," + String(endF) + ", true)"

\ : mode==2 ? "spline(n, "
\ + String(startFrame) + "," + String(startF) + ", "
\ + String(startFrame+(endFrame-startFrame)/3.0) + "," + String(startF) + ", "
\ + String(endFrame-(endFrame-startFrame)/3.0) + "," + String(endF) + ", "
\ + String(endFrame) + "," + String(endF) + ", true)"

\ : mode==3 ? "spline(n, "
\ + String(startFrame) + "," + String(startF) + ", "
\ + String(startFrame+(endFrame-startFrame)/3.0) + "," + String(endF) + ", "
\ + String(endFrame-(endFrame-startFrame)/3.0) + "," + String(startF) + ", "
\ + String(endFrame) + "," + String(endF) + ", true)"

\ : mode==4 ? "spline(n, "
\ + String(startFrame) + "," + String(startF) + ", "
\ + String((endFrame-startFrame)/2.0) + "," + String(startF) + ", "
\ + String(endFrame) + "," + String(endF) + ", true)"

\ : mode==5 ? "spline(n, "
\ + String(startFrame) + "," + String(startF) + ", "
\ + String((endFrame-startFrame)/2.0) + "," + String(endF) + ", "
\ + String(endFrame) + "," + String(endF) + ", true)"

\ : "spline(n, "
\ + String(startFrame) + "," + String(startF) + ", "
\ + String(endFrame) + "," + String(endF) + ", true)"
Return splineString
}

Groucho2004
20th September 2014, 17:31
Can't see how you get 200fps with Spline64, i get 50-60.
Have you tried a plain Spline64Resize or only Zoombox? There's a lot of floating point math in that function which might explain the lower speed.

Just tried it. The culprit is clearly the fact that the resizer is a lot slower when processing RGB data (I get 35 fps instead of 215 fps).

zerowalker
20th September 2014, 17:48
Done with and without, and posted it, ZoomBox is clearly a bit slower.

Oh, that's very good to know.
Hmm, problematic that i have to resize from 900x500 to 1920x1067 and add black borders in order to keep aspect ratio.
I don't think this can be done with YUV as it can't be divided by 2.

Hmm, perhaps i can add borders before resizing...

EDIT:

Then again YV12 will destroy the colored text as it's so small.
Damn, i just can't win;P
I guess YV24 first and YV12 later will improve it somewhat.

feisty2
21st September 2014, 01:32
how about split every rgb frame to 3 neighbor y8 frames, then it's in yuv colorspace to resizers now, and it's lossless compared to converting to yv24 first (converting to yuv will lose about 2bpc precision)

zerowalker
21st September 2014, 13:19
No idea how to do that;S

feisty2
21st September 2014, 13:30
xxxsource
r=showred ("y8")
g=showgreen ("y8")
b=showblue ("y8")
interleave (r,g,b)
spline64resize (1920,1080)
mergergb (selectevery (3,0),selectevery (3,1),selectevery (3,2))
donno if it will be faster
I guess the whole convert to yv12 stuff is somehow a bad idea since there're texts in the clip, you will obviously observe some quality loss around the texts (what you said, "color bleed"), yv12 could be not so nasty to natural images but computer graphics will be worsened a lot if convert them to yv12.
if you just gotta stick to yv12 somehow, I advice "bt 2020" matrix as an advanced choice, it splits brightness and colors under linear rgb colorspace while "bt 601" and "bt 709" split them under gamma compressed rgb colorspace (which leads to some tiny brightness information gets distributed to chroma channels then chroma channels get downsized and image quality heads to hallelujah disaster)
edit2: just checked "dither" document, it still adopts non constant luma method (same as old "bt709"), guess u gotta do gamma linear conversion urself

the better way to get a not so crappy yv12 output (slow!)

#rgb32 input#
r=showred ("y8").convert8to16 (tv_range=false).Dither_y_gamma_to_linear (tv_range_in=false,tv_range_out=false,curve="srgb",sigmoid=true).dither_resize16nr (1920,1080,kernel="spline",taps=4)
g=showgreen ("y8").convert8to16 (tv_range=false).Dither_y_gamma_to_linear (tv_range_in=false,tv_range_out=false,curve="srgb",sigmoid=true).dither_resize16nr (1920,1080,kernel="spline",taps=4)
b=showblue ("y8").convert8to16 (tv_range=false).Dither_y_gamma_to_linear (tv_range_in=false,tv_range_out=false,curve="srgb",sigmoid=true).dither_resize16nr (1920,1080,kernel="spline",taps=4)
dither_convert_rgb_to_yuv (r,g,b,lsb=true,output="yv12",matrix="2020",chromak="spline64",mode=-1)
Dither_y_linear_to_gamma (tv_range_in=true,tv_range_out=true,curve="2020",sigmoid=true,u=2,v=2)
#round to 10bpc now or dither to 8bpc (change "curve" in "Dither_y_linear_to_gamma" from 2020 to 709 if using 8bpc)
#encode with x264 with "bt2020" matrix flag and selected transfer characteristics (curve) flag
Function Convert8To16 (clip input, bool "tv_range")
{
tv_range = Default (tv_range, True)

iCceil = (255-128) / (255.5-128) * (65535.5-32768) + 32768
Yexpr = "0-0 ; 255-65535 ;65535-65535 "
Cexpr = "0-0.5;0.5-0.5;128-32768;255-"+String(iCceil)+";65535-"+String(iCceil)
fullrange = StackVertical (input.Dither_gen_null_lsb (), input).
\ SmoothCurve16 (Ycurve=Yexpr, Ucurve=Cexpr, Vcurve=Cexpr, mode=0, interp=0, HQ=True,
\ dither=-1, limiter=False, TVrange=0)

output = tv_range ? input.Dither_convert_8_to_16 ()
\ : fullrange

return output
}

TheSkiller
21st September 2014, 15:47
You can also resize the chroma straight in one go to YV12 like this.
It avoids resizing the chroma plane two or more times, reducing blurring to the minimum.


AddBorders(0,3,0,3) #make up for 16:9 (900x506)
ConvertToYV24(matrix="Rec709")

Y = ConvertToY8().Spline64Resize(1920, 1080)
U = UToY8().Spline64Resize(1920/2, 1080/2, src_left=-0.5)
V = VToY8().Spline64Resize(1920/2, 1080/2, src_left=-0.5)

YToUV(U, V, Y) #results in YV12



That being said I personally wouldn't recommend Spline64 for chroma resizing because ringing chroma can be quite ugly whereas it might look good on the luma (which is 4 times the chroma res). I'd recommend Spline16 for the chroma.

feisty2
21st September 2014, 16:31
right, the perfect solution (for yv12) would be, first use the method at #19 to resize ur clip to 1920x1080 and get the y plane
then use the method again to resize ur clip to 960x540 then merge the earlier full resolution y and latter half resolution uv together, and I forgot, set thr and cont constant thru the whole gamma linear process which are variable by default
edit: change output to y8 at the first full resolution luma resize step
change output to yv24 at the latter half resolution chroma resize step

zerowalker
22nd September 2014, 17:48
Okay i think i get the grasp of it. Will try it out next time and compare the quality and speed:)

zerowalker
1st October 2014, 21:37
Okay did some testing, and it seems to be A Lot faster. And i can't see any difference at all, so this is great;D