Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
|
|
Thread Tools | Search this Thread | Display Modes |
1st September 2017, 11:54 | #1 | Link |
Registered User
Join Date: Oct 2002
Location: France
Posts: 2,309
|
Internaly multi-threaded desampling functions (DeBilinear, DeBicubic,...)
I've created a specific thread even if it will be implemented inside the ResampleMT dll, because i've thought it would be more appropriate. And if i didn't create a specific dll, it's because it's exactly the same thing, and just adding around 1% of code add the functions.
Download is on the ResampleMT dll page here. The new functions are : DeBilinearResizeMT DeBicubicResizeMT DeLanczosResizeMT DeLanczos4ResizeMT DeBlackmanResizeMT DeSpline16ResizeMT DeSpline36ResizeMT DeSpline64ResizeMT DeGaussResizeMT DeSincResizeMT DeSinSqrResizeMT (same parameters than DeGauss) DeSincLin2ResizeMT (same parameters than Sinc, default param 15) DeUserDefined2ResizeMT (Same parameters as BicubicResize) Parameters are identicals to the resampling functions, except there is two others parameters at the end. accuracy - Will specify the accuracy used for the desampling. 0 : Average 1 : A little less than 0. 2 : A little better than 0. Default: 0 (int) order - Will specify in what order the desampling will be done (process horizontal or vertical first). 0 : Automatic, will choose according the same method implemented in the core filters. 1 : Process vertical first. 2 : Process horizontal first. Default: 0 (int) So, syntax is : DesampleFunction([parameters of ResampleMT],int accuracy,int order) The usage is the following : You have to enter in the parameters exactly the same that have been used for the original resampling, except the size of course, where you specify the original size you want back. For exemple, if the source file is an 720x480 video : Code:
Spline36ResizeMT(1280,720,src_left=17.2,src_width=680,src_top=-8.7,src_height=440) # or Spline36Resize(1280,720,src_left=17.2,src_width=680,src_top=-8.7,src_height=440) # To revert : DeSpline36ResizeMT(720,480,src_left=17.2,src_width=680,src_top=-8.7,src_height=440,accuracy=0,order=0) Now, a little explaination of how it works. I'll note 'A the transpose matrix of A. If X is your input line to resample, you can write the resampling method like this : Y=A*X. Using the less square method, you can revert by the following method : 'A*Y='A*A*X B = inverse_matrix ('A*A) C = B*'A We have X=C*Y. So applying the matrix C, we can revert the resampling process. Now, if in the A matrix, around 95% are 0.0 value (size of rif resampler is only around 3 or 4), it's absolutely not the same for the C matrix. For exemple, in a case of reverting a 720 -> 1080 upscale, with an upscale rif filter of 4. The scan in the lines of resulting matrix C showed that it will produce a rif size filter of 311. This this where the accuracy parameter is used. For the default value, 0, it will use what i would call "integer" precision. In the filter, the integer values of the filter are converted with the following formula : int(0.5+f*16384). So, if this result in 0, the coefficient in the C matrix is set to 0.0. In our example, it will produce a rif filter of size 30. With the value of 1, it will keep a 0.1% of precision. On each line of C, the max(abs(f)) is scanned, and any value lower than 0.1% of this max is set to 0. In our example, it will produce a rif filter of size 20. With the value of 2, any value within C which abs()<1e-6 is set to 0. In our example case, it will produce a rif filter of size 41. So, for a 720 data vector input [0, 1, 2, ..., 719] inside, "upscaled" to 1080 values, and then reduce back to 720 values, the results are the following : accuracy 0 : [-0.000209 1.000103 1.999724 3.000118 3.999680 5.000134 .... 714.983521 716.005859 716.983643 718.006226 718.985046] accuracy 1 : [-0.000512 1.003681 1.999033 3.004512 3.998633 5.005422 ... 714.856384 716.323120 716.855835 718.331421 718.868530] Rounded it's still good. accuracy 2 : [-0.000005 1.000017 1.999993 3.000018 3.999994 5.000021 ... 714.999573 716.000732 716.999756 718.000977 718.999634] Now, the order parameter. This will set if the image of the video will be processed horizontaly first, or verticaly first. If the value is 0, in automatic mode, the filter will figure out, according the internal avisynth core filter algorithm, in what order the image would have been processed by the original resampling, to do the oposite. For example, if the original resampling would result in resampling horizontal first, then vertical, the filter in that case will do vertical, then horizontal. Of course, if original resampling is not done by avisynth, you can't know for sure, this is why you can set the order to the filter, to check what produce the best result. Quality improvement tip There is the accuracy parameter, but another way to eventualy improve the quality is to increase the bit depth if you're using avs+. If you are in 8 bits, the resampler compute using integer rif parameters converted from the float rif parameters. But, if you are in bit depth>8, the resampler uses the float coefficients. In desampling cases, where rif size can easely be of 40 or 50, if you're trying to be the most accurate, i would advise to increase the bitdepth to 16 (or even to float if you're searching for ultra accuracy) just for the desampling filter. WARNING !!!! The init phase of the filter is very slow, it can take easely several seconds, and the bigger the picture is, the more it will take. If you don't even have SSE2 instructions, it may take several dozen of seconds ! So, in a standard filter chain doing : Create,Constructor,getframe(n=0),getframe(n=1),getframe(n=2),...destructor, there will be no issue. Now, if you are using something like ScriptClip, which works like this : Create,Constructor,getframe(n=0),Destructor,Create,Constructor,getframe(n=1),Destructor,Create,Constructor, getframe(n=2),Destructor,... It will be slow as hell !!! Avoid absolutely using it in this case. Last edited by jpsdr; 29th April 2021 at 17:40. |
6th September 2017, 03:52 | #2 | Link |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 2,883
|
Works.
Quality-wise it does its job and, although it doesn't use all my cores and threads at 100%, it's really fast (10fps in a 1080 -> 720 reverse upscale using debilinear is quite good). Code:
FFMpegSource2("GTO (2014) - 02 [1080p].mkv", fpsnum=30000, fpsden=1001, atrack=-1) DeBilinearResizeMT(1280, 720, threads=8, logicalCores=true, MaxPhysCore=true, SetAffinity=true) TextSub("GTO_2014_ep2.ass") ResampleAudio(48000) Normalize(0.89, show=false) video=last FFMpegSource2("logo_finaleGTO.avi", fpsnum=30000, fpsden=1001, atrack=-1) Converttoyv12() ResampleAudio(48000) TextSub("Onizuka Credits.ass") logo=last logo++video++logo Last edited by FranceBB; 6th September 2017 at 03:58. |
6th September 2017, 08:52 | #3 | Link |
Registered User
Join Date: Oct 2002
Location: France
Posts: 2,309
|
For now it works if fabs(shift)<1 and no cropping. Working on to make it works even with things like this (source 720x480) :
Code:
Spline36ResizeMT(a,1280,720,src_left=17.2,src_width=680,src_top=-8.7,src_height=440) DeSpline36ResizeMT(720,480,src_left=17.2,src_width=680,src_top=-8.7,src_height=440) Last edited by jpsdr; 6th September 2017 at 08:54. |
3rd November 2017, 05:25 | #5 | Link |
Registered User
Join Date: Jan 2012
Location: Mesopotamia
Posts: 2,587
|
tried to play with it but I think there are some bug!
Code:
some SD source here w=Width h=Height IResize(1080,1440,resifilter="BilinearResizeMT") IResize(w,h,resifilter="DeBilinearResizeMT") even some interlaced bluray (seen in some movie of detective conan for example) edit: tried with dither_resize16 Code:
w=Width h=Height IResize(1080,1440,resifilter="resizex",res_params=""",lsb=true,kernel="Bilinear"""") IResize(w,h,resifilter="resizex",res_params=""",lsb=true,kernel="Bilinear",dither_params=",invks=true"""") edit: now it work with Desample, forget about old resizex and IResize above and even with resizex (Important if you work with 422 and 411 sources cuz there are some chroma shift, but don't worry when you work with 420 and 444 of even Y*) Code:
IResize(720,480,resifilter="resizex",res_params=""",desampling=true,kernel="Bilinear"""")
__________________
See My Avisynth Stuff Last edited by real.finder; 29th January 2022 at 14:22. |
3rd November 2017, 10:58 | #6 | Link |
Registered User
Join Date: Oct 2002
Location: France
Posts: 2,309
|
I think the issue comes from the fact the it resizes splitting planes and shifting chroma according resize size.
As i said in the 1rst post : Code:
The usage is the following : You have to enter in the parameters exactly the same that have been used for the original resampling, except the size of course, where you specify the original size you want back. See the example to look how exactly how it has to be done. I've never said the filter behave exactly like "old/original" desampler, because i don't have the code and the author gave me only the global description of the algorithm, and i don't know how it handles shift parameters, but i will not change what i've done in my filter. The way IResize works, or you use it, is not compatible with the way my desample works. You have either to change adapt the IResize, or manualy set the shift parameters, or use it differently. I don't look deep enough to say what exactly is the correct answer. My desample will try to retreive the original before resampling, it will not do any shift, if you want to to shift, you have to do it afterward. For a desample to do shift, it would need "2" shift parameters instead of "1". One for the shift used in original resampling, one for the shift you want to produce afterward. "Original" desampler didn't have the shift paramaters doubled, neither mine. I choose to consider that the shift parameter you put is the one you've put in the original resampler, and not a shift you want to produce afterward, otherwise, it means you'll be unable to desample a resampling with shift, if you're unable to provide the original shift information to your desample. Last edited by jpsdr; 3rd November 2017 at 11:05. |
3rd November 2017, 18:36 | #7 | Link | |
Registered User
Join Date: Jan 2012
Location: Mesopotamia
Posts: 2,587
|
Quote:
anyway IResize do the shift in fields, it needed for resize interlaced sources, without shift the output will be wrong
__________________
See My Avisynth Stuff |
|
6th November 2017, 10:45 | #8 | Link |
Registered User
Join Date: Oct 2002
Location: France
Posts: 2,309
|
So, if "original" version can do shift, it means it's not able to properly desample shifted resampled video. Because the shift parameter is used like the shift parameter in the original resample to shift the video, and not as an information of the shift value in the original resampler.
So, even if with the "original" desampler the little 2 lines script seems to work, i think it's not also working realy properly, because the desampling phase doesn't know the shift value used in the sampling phase. Honestly, i don't think you can use IResize for both sampling and desampling with real proper result. You need to create a specific IDesize, where you'll add another shift parameter which is the shift value used in the resampling phase, or, automaticaly compute what you think the shift value in the previous resampling phase may have been to properly desample, and then, after desampling and retrieve the real proper original picture, before the shift&resample, add another shift if you want. All i can say, it's if you're doing this : Code:
a=SD Video w=a.Width() h=a.Height() b=BilinearResize(a,1080,1440,src_left=0.5) (or MT, whatever) c=DeBilinearResizeMT(b,w,h,src_left=0.5) If you change the value of src_left, you'll have improper result. If you want after to shift the result, you'll have to do : Code:
a=SD Video w=a.Width() h=a.Height() b=BilinearResize(a,1080,1440,src_left=0.5) (or MT, whatever) c=DeBilinearResizeMT(b,w,h,src_left=0.5) BilinearResize(c,c.Width(),c.Height(),src_left="the shift you want") Last edited by jpsdr; 6th November 2017 at 11:05. |
6th November 2017, 15:08 | #9 | Link |
Registered User
Join Date: Jan 2012
Location: Mesopotamia
Posts: 2,587
|
well, I already did some edit for that, even did support resizex case, the result is better now but not perfect
__________________
See My Avisynth Stuff |
6th November 2017, 15:54 | #10 | Link |
Registered User
Join Date: Oct 2002
Location: France
Posts: 2,309
|
Can you tell/describe me what you want to do exactly, with a precise specific exemple ?
(Like : I have a 1080i upsample video i want do desample to 520i, assuming the resampling have been done using xxxx). I think you use IResize for the chroma resize shift adjustment, but, just assume for one moment, we ignore this, and don't try to correct/this issue, and don't split planes. With just Bilinear and Debilinear, what would be your script ? (But maybe before doing the script, the description would be enough...). Maybe with the description, i could be able to make a script (even if specific) which will do what you want to do ? |
6th November 2017, 20:50 | #11 | Link |
Registered User
Join Date: Jan 2012
Location: Mesopotamia
Posts: 2,587
|
here the original post by IanB https://forum.doom9.org/showpost.php...7&postcount=35
and here Gavino one https://forum.doom9.org/showpost.php...0&postcount=51 yes, lets say we have 1080i but the original of it was in SD (480i or 520i) and they did upscale (resize) it to 1080i without deinterlacing (VirtualDub has an option for that for example)
__________________
See My Avisynth Stuff |
7th November 2017, 09:58 | #12 | Link |
Registered User
Join Date: Oct 2002
Location: France
Posts: 2,309
|
By resize without deinterlacing, you mean they resize each field separetely. It's at my request that Avery Lee added the option on VDub, but he "refused" to make it work on YV12, because he "stuck" on the fact that YV12 is only progressive by format definition/specification, so if you check the interlaced box in resize filter on YV12 video, it automaticaly converts to YV16...
I'll think/work on something later during my lunch break for a script. |
7th November 2017, 13:43 | #13 | Link |
Registered User
Join Date: Oct 2002
Location: France
Posts: 2,309
|
Ok, if i didn't make any mistakes and understood properly :
Code:
function IBilinearYV12(clip c,int NewWidth,int NewHeight) { Wr=Float(NewWidth) Hr=Float(NewHeight)/2.0 v=SeparateFields(c) W0=Float(v.Width()) H0=Float(v.Height()) C_Shift=0.25*(1.0-W0/Wr) V_Shift=(GetParity(v) ? -0.25 : 0.25)*((H0/Hr)-1.0) Video=SelectEven(v) Ye=ConvertToY8(Video).BilinearResizeMT(NewWidth,NewHeight/2,src_top=V_Shift) Ue=UToY8(Video).BilinearResizeMT(NewWidth/2,NewHeight/4,src_top=V_Shift,src_left=C_Shift) Ve=VToY8(Video).BilinearResizeMT(NewWidth/2,NewHeight/4,src_top=V_Shift,src_left=C_Shift) Video=SelectOdd(v) Yo=ConvertToY8(Video).BilinearResizeMT(NewWidth,NewHeight/2,src_top=-V_Shift) Uo=UToY8(Video).BilinearResizeMT(NewWidth/2,NewHeight/4,src_top=-V_Shift,src_left=C_Shift) Vo=VToY8(Video).BilinearResizeMT(NewWidth/2,NewHeight/4,src_top=-V_Shift,src_left=C_Shift) Y=Interleave(Ye,Yo) U=Interleave(Ue,Uo) V=Interleave(Ve,Vo) YToUV(U,V,Y).Weave() } function IDeBilinearYV12(clip c,int OriginalWidth,int OriginalHeight,int "order") { order=default(order,0) W0=Float(OriginalWidth) H0=Float(OriginalHeight)/2.0 v=SeparateFields(c) Wr=Float(v.Width()) Hr=Float(v.Height()) Original_C_Shift=0.25*(1.0-W0/Wr) Original_V_Shift=(GetParity(v) ? -0.25 : 0.25)*((H0/Hr)-1.0) Video=SelectEven(v) Ye=ConvertToY8(Video).DeBilinearResizeMT(OriginalWidth,OriginalHeight/2,src_top=Original_V_Shift,order=order) Ue=UToY8(Video).DeBilinearResizeMT(OriginalWidth/2,OriginalHeight/4,src_top=Original_V_Shift,src_left=Original_C_Shift,order=order) Ve=VToY8(Video).DeBilinearResizeMT(OriginalWidth/2,OriginalHeight/4,src_top=Original_V_Shift,src_left=Original_C_Shift,order=order) Video=SelectOdd(v) Yo=ConvertToY8(Video).DeBilinearResizeMT(OriginalWidth,OriginalHeight/2,src_top=-Original_V_Shift) Uo=UToY8(Video).DeBilinearResizeMT(OriginalWidth/2,OriginalHeight/4,src_top=-Original_V_Shift,src_left=Original_C_Shift,order=order) Vo=VToY8(Video).DeBilinearResizeMT(OriginalWidth/2,OriginalHeight/4,src_top=-Original_V_Shift,src_left=Original_C_Shift,order=order) Y=Interleave(Ye,Yo) U=Interleave(Ue,Uo) V=Interleave(Ve,Vo) YToUV(U,V,Y).Weave() } a=AVISource("Your_720x480i_video.avi",FALSE,"YV12") b=IBilinearYV12(a,1920,1080) IDeBilinearYV12(b,720,480) I don't know what format professionnals use as master and work with. Theres is also possibility that master was 4:4:4 or 4:2:2, upscaled, and ther afterward converted to YV12. So to figure out the best desampling option, a lot of tests and investigations has to be done, considering a lot of possibility of "upscaling method" (with and without shift when upscaling, play with the order parameter of Debilinear, upscale was done on 4:4:4 and then converted to YV12, etc...) Last edited by jpsdr; 7th November 2017 at 13:46. |
7th November 2017, 16:03 | #14 | Link |
Registered User
Join Date: Jan 2012
Location: Mesopotamia
Posts: 2,587
|
yes, it work now, I was think of I must did some reverse in shift, thanks to your editions of IResize give me the incentive after test your script
and now it even successfully work with FAIRY TAIL S1 anime TV sample I have Code:
IResize(720,480,resifilter="resizex",res_params=""",desampling=true,kernel="Bilinear"""")
__________________
See My Avisynth Stuff |
3rd May 2018, 01:22 | #15 | Link |
Registered User
Join Date: Jan 2012
Location: Mesopotamia
Posts: 2,587
|
can these desampling functions used in undownscale nowdays DVD anime OVA/OAD that has halos? Of course we can't get the details back, but I ask for this to dehalo these sources in more details and more clean output than old dehalo methods
__________________
See My Avisynth Stuff |
3rd May 2018, 11:46 | #16 | Link |
Registered User
Join Date: Oct 2002
Location: France
Posts: 2,309
|
I don't know if it will work.
You can reverse upscale, because mathematicaly, in a certain way, you kept all the informations. Basicaly, you added pixels, so you can say that you've "only" added information, and all the original information may still be retrieved. Downscale, basicaly you remove pixels, so information is loss. I was even thinking of forbid reverse downscale, but it wasn't realy easy to make accurate test, because of possible akward croping cases. I thought i add, but a quick look on the code, it seems i didn't. You still can try, but you may encounter cases of matrix not being reversible, and i don't know what it can produce (well case of matrix not reversible should theoricaly be handled and produce an error message). But if by any luck it produces good result...
__________________
My github. |
24th March 2021, 23:36 | #17 | Link | |
Registered User
Join Date: Jan 2012
Location: Mesopotamia
Posts: 2,587
|
Quote:
I did some test with this yahr2 Code:
Dither_convert_8_to_16() Dither_resize16(854,Height()/2,invksh=true, kernel="spline36") Dither_resize16(720,480, kernel="bilinear") Ditherpost() it seems do something
__________________
See My Avisynth Stuff Last edited by real.finder; 25th March 2021 at 02:11. |
|
Thread Tools | Search this Thread |
Display Modes | |
|
|