|
|
| jpsdr |
| Posted: Nov 28 2011, 09:23 AM |
 |
|
Advanced Member
  
Group: Members
Posts: 335
Member No.: 20490
Joined: 23-December 06

|
Hello.
I've very recently updated some of my filters to replace the LAG parameters, using prefetch2 and fa->mpSourceFrames[]->mpPixmap and fa->mpOutputFrames[]->mpPixmap instead. Principaly my IVTC filter.
I've a long time ago created a filter wich remove frames, using prefetch2. This one worked perfectly.
Now, the problem i have : a : If i run my new IVTC filter, save the result in a file, and then afterward run my remove frame filter, everything worked fine and as expected. b : If i run in the same process, my new IVTC filter followed by the remove frame filter, result is not the expected one (not the same it was in a), and even can result in a crash ! c : My old IVTC filter followed by the remove frame filter in the same process work perfectly fine.
I've put the source and filters here : http://dl.free.fr/b5pAivE8o
It's the IVTC v5.0.0 follwed by the Remove Frame v1.2.2 (well, code for this one is very simple...). If you can take a look, maybe i'm not using properly the cached frames or anything else. If you want me to provide a sample file wich crash in case b but not in case a, i can, tell me (around 500MB).
Edit : So either i somehow trig an hidden problem in Vdub, either i'm doing something "not allowed" in the way i'm using prefetch2, but i don't know what. |
 |
| jpsdr |
| Posted: Nov 30 2011, 02:28 PM |
 |
|
Advanced Member
  
Group: Members
Posts: 335
Member No.: 20490
Joined: 23-December 06

|
I've investigated more.
My remove frame filter contain the following :
| CODE | // Case of IVTC (Exemple) // Offset=0 => [0-3]=>[1-4] // Offset=1 => [0]=>[0], [1-3]=>[2-4] // Offset=2 => [0-1]=>[0-1], [2-3]=>[3-4] // Offset=3 => [0-2]=>[0-2], [3]=>[4] // Offset=4 => [0-3]=>[0-3] bool JPSDR_RemoveFrames::Prefetch2(sint64 frame, IVDXVideoPrefetcher *prefetcher) { sint64 frame_low,frame_high;
frame_high=(frame/(mData.frame_period-mData.frames_removed))*mData.frame_period; frame_low=frame%(mData.frame_period-mData.frames_removed); if (frame_low>=mData.offset_frame) frame_low+=mData.frames_removed;
prefetcher->PrefetchFrame(0,frame_high+frame_low,0);
return(true); }
|
I've put in my IVTC code the following :
| CODE | fprintf(fic2,"Image : %u\n",pxsrc.mFrameNumber); fprintf(fic2,"Process : %X\n\n",data_out[index_out]);
|
Result, with only my IVTC filter :
| QUOTE | Image : 0 Process : 101
Image : 1 Process : 102
Image : 2 Process : 103
Image : 3 Process : 104
Image : 4 Process : 104
Image : 5 Process : 106
Image : 6 Process : 107
Image : 7 Process : 108
Image : 8 Process : 9
Image : 9 Process : 9
Image : 10 Process : 101
|
result putting the remove frame after the IVTC filter :
| QUOTE | Image : 0 Process : 101
Image : 1 Process : 102
Image : 2 Process : 103
Image : 4 Process : 104
Image : 5 Process : 104
Image : 6 Process : 106
Image : 7 Process : 107
Image : 9 Process : 108
Image : 10 Process : 9
Image : 11 Process : 9
Image : 12 Process : 101
|
The information reported by pxsrc.mFrameNumber is incorrect in the filter when the remove frame filter is after it. IVTC filter beleived it's frame number 12 when in reality it's frame number 10... I need this information accurate in my filter, is this behavior "normal", in that case, i have to switch back to what i used to do before : Manualy increment a counter each time i enter the run procedure, to be sure to have the correct frame number, or is it a bug ? Or is there another structure field wich will provide me the right information ?
Edit : Using a counter didn't work, behavior was the same. |
 |
| jpsdr |
| Posted: Dec 1 2011, 08:41 AM |
 |
|
Advanced Member
  
Group: Members
Posts: 335
Member No.: 20490
Joined: 23-December 06

|
Last test i've made, using internal counter instead of pxsrc.mFrameNumber is to compare result between : a: Using my IVTC filter alone, saving result in a file, then, afterward, process this file with my remove frame filter. b: Using IVTC and remove frame in the same process.
To test i've used an YV12 telecine "RGB cube", to have the number in each frame.
For input frame 0 to 20, result is : X/Y mean frame reconstructed from X & Y frames.
a: Good result, frames in the final result file are : 0 1 3 4 5 6 8 9 10 11 13 14 15 16/17 18 19 20
b: Bad result, frames in the final result file are : 0 1 3 5 5 6 7 10 11 11 12 14 16 17 17 20 21
I'm totaly lost, i've no idea what's happening. I need help on this... |
 |
| jpsdr |
| Posted: Dec 4 2011, 08:12 AM |
 |
|
Advanced Member
  
Group: Members
Posts: 335
Member No.: 20490
Joined: 23-December 06

|
All of this is with version 1.10.1-test16 |
 |
| phaeron |
| Posted: Dec 11 2011, 08:59 PM |
 |
|

Virtualdub Developer
  
Group: Administrator
Posts: 7773
Member No.: 61
Joined: 30-July 02

|
I think I see what's going on.
What's happening is that the remove frame filter is only requesting some of the frames that the IVTC filter would produce. This results in gaps in the frame list that the IVTC filter is being asked to produce. Your filter needs to deal with this -- it cannot assume that frames are requested in order or expect an output frame number that increments without gaps. What your IVTC filter is seeing is the same that you would get if you deleted the frames manually on the timeline in the same way that the Remove Filters frame does. |
 |
| jpsdr |
| Posted: Dec 12 2011, 09:06 AM |
 |
|
Advanced Member
  
Group: Members
Posts: 335
Member No.: 20490
Joined: 23-December 06

|
... i don't understand very well. My old IVTC filter works perfectly fine with remove frame, both, the old and the new have the same algorithm and are doing things the same way. The only difference between them it's that the old uses an internal buffer and LAG function, the new uses the new process you had implemented, using prefetch2 and fa->mpSourceFrames[]->mpPixmap. Only source of input changes... ............................................... hmmmmmmmmmm................
That means that when i'm not using prefetch2, the input is all the frames in the correct order, but when i'm using prefetch2, i ask specific frame, using the frame parameter, and this is what produce problems, because the frame value may not be the same value asked previously +1. And even if remove frame is after IVTC, it has an effect before it ?
...... I think i've a little troubles to realy understand, and i'll stay with my old method, using new present too much risks and troubles and high uncompatibility risks with what i'm doing.
Or i must include the remove frame part inside the IVTC filter, for the new process. That means also that i must use internal counters inside filters, because value reported by pxsrc.mFrameNumber is not realiable to make things like "doing this on the 1000th frame processed".
Whatever version i use of VDub, if input is 20000 frames, and if i put the following filters, in this oder : Filter A IVTC Remove frame Filter B
How many frames Filter A and IVTC will see and process ? 20000 or 16000 ? Filter B should see only 16000 frames. |
 |
| jpsdr |
| Posted: Dec 12 2011, 11:56 AM |
 |
|
Advanced Member
  
Group: Members
Posts: 335
Member No.: 20490
Joined: 23-December 06

|
I've made some test, with my manual IVTC filter. Old version : Filter has LAG, internal buffer. New version : Using prefetch2.
Video input file : 200 frames. Number of frames processed : Number of time the run function has been called (and process a frame).
Old version alone : Number of frames processed by run function : 200 Old version + Remove frame : Number of frames processed by run function : 200 => GOOD. Correct behavior for me and the filter to work properly. New version alone : Number of frames processed by run function : 200 New version + Remove frame : Number of frames processed by run function : 160 => NOT GOOD.
I see a dead end for me, i can't use prefetch2 as i absolutely need all the frames to be processed at least in some filters before the remove frames... And apparently all the filters using prefetch2 are affected in the chain, and not only those after. Otherwise, there is no point to put the filter at a specific position. It acts as if it has been put on the top of the filters. |
 |
| jpsdr |
| Posted: Dec 13 2011, 02:43 PM |
 |
|
Advanced Member
  
Group: Members
Posts: 335
Member No.: 20490
Joined: 23-December 06

|
I've done more testing, result are, for a video input file of 200 frames, filters are listed on the order, within () is the number of frames processed. Note : my old IVTC has LAG, and is the only one with LAG on these tests.
Filter A : A filter i've made using prefetch2. Filter B : A filter i've made not using prefetch2.
Old IVTC (200) Remove Frame
Filter A (200) Old IVTC (200) Remove Frame
Old IVTC (200) Filter A (160) Remove Frame
Old IVTC (200) Filter A (160) null transform Remove Frame
Old IVTC (200) Filter A (160) Filter B Remove Frame
It seems, that what saved me is the fact that my filter have LAG, and so all fiters until it process the expected number of frames.
From what i see, if i have 3 A, B, C filters, no LAG, doing : A + B + C + Remove frame is the same as doing : Remove frame + A +B +C I don't think this it realy the behavior expected...
EDIT :
I've tried : Filter A (200) Your IVTC with reduce frame
Filter A (200) Your bob doubler
How do you manage to have no impact on filter before ? I haven't been able to find out in the code source of your filter what you're doing differently from what i'm doing in my filter. Your IVTC, when reducing frame rate, finaly do exactly what i'm doing in my remove frame : changing fa->dst.mFrameRateHi, fa->dst.mFrameRateLo and fa->dst.mFrameCount in GetParams, and in prefetch2 selecting the frames to output...
Can you take a look at my remove frame, and tells me why it has effect on filter before, and not your IVTC ? I've looked at your IVTC filter, and i absolutely have no idea what's the trick/difference between what you are doing and what i am doing, wich create the fact that my filter has effect on the filters before it, and not yours ! |
 |
| jpsdr |
Posted: Dec 14 2011, 12:17 PM |
 |
|
Advanced Member
  
Group: Members
Posts: 335
Member No.: 20490
Joined: 23-December 06

|
More tests :
Video input : A file YV12 color cube 3:2 TFF of 200 frames. Filter A Your IVTC with reduce frames. Frames processed by filter A : 200
Filter A My remove frame filter Frames processed by filter A : 160
I've tried everything i could see in the code of your IVTC filter, adding swap_buffer, having a little bit of code in Run() proc for not being empty, nothing changes, the filter before is always processing only 160 frames, i'm unable to get the same behavior of your IVTC filter.
Video input : Create an 3:2 TFF RGB cube in YV16 mode, cut it to 200 frames. Filter A My remove frame filter Frames processed by filter A : 160
Filter A Your IVTC with reduce frames. Frames processed by filter A : 204
Save the input video created to a file, remove all filters, close video and use the saved file as input. Filter A My remove frame filter Frames processed by filter A : 160
Filter A Your IVTC with reduce frames. Frames processed by filter A : 200
|
 |
| jpsdr |
| Posted: Dec 19 2011, 08:50 AM |
 |
|
Advanced Member
  
Group: Members
Posts: 335
Member No.: 20490
Joined: 23-December 06

|
So.... any idea why my remove frame filter afect also previous filters and not your IVTC ????? |
 |
| phaeron |
| Posted: Dec 19 2011, 06:52 PM |
 |
|

Virtualdub Developer
  
Group: Administrator
Posts: 7773
Member No.: 61
Joined: 30-July 02

|
Sorry for the delay in responding.
The reason for the difference is that VirtualDub's built-in IVTC filter does some unnecessary work when running in reduce rate mode with a manual offset: it still fetches a window of 11 frames. The overlap of these windows effectively causes all frames to be requested from the upstream filter. It could omit the window in which case you would see the same behavior as your filter, which is that some frames are skipped in the upstream.
You cannot assume that your filter will be called for a contiguous set of frames. This was never guaranteed with edits or the frame rate conversion option, and it is even less true with frame rate conversion being possible in filters. VirtualDub always attempts to fetch the minimal set of frames from the upstream filter, with caching used to reduce the number of duplicate frame requests. If the downstream filter only requests four out of every five frames, that is all that the upstream filter will be asked to produce. The reason that it does this when the lag flag is set is to avoid breaking such filters, but that carries a significant performance penalty when sparse frames are requested: a filter with a lag of M that is asked to produce N sparse frames will run M*N times. This is up to M times as expensive as a filter written to use prefetch2-style upstream windowing.
For your filter to work completely correctly in all cases, the rule you need to follow is as follows: the output produced by your filter must effectively be a pure function of the source frames and your constant filter data. You have to be careful about any cached data between frames to avoid introducing errors on seeks. The way that the internal IVTC filter works is that it prefetches all of the source frames it might need and internally caches data produced from these frames so that no extra work is done in sequential operation. However, should seeking occur, it is designed to always produce the same result regardless of the subset or order of frames requested. |
 |
| jpsdr |
| Posted: Dec 20 2011, 07:40 AM |
 |
|
Advanced Member
  
Group: Members
Posts: 335
Member No.: 20490
Joined: 23-December 06

|
You cannot assume that your filter will be called for a contiguous set of frames. ........ Veryyy troublesome... This is what my algorithm and the structure of the filter is is based on (pipeline structure), wich greatly increase speed... This breaks a looooot of things in the structure of my filter... And it may even be almost totaly uncompatible with... If, for now, i use as workarond a windows prefecth of 11 frames in my remove frames filters, will it work ? (I'll try and test this...)
Thanks for your answer. |
 |
| jpsdr |
| Posted: Dec 20 2011, 09:09 AM |
 |
|
Advanced Member
  
Group: Members
Posts: 335
Member No.: 20490
Joined: 23-December 06

|
A little more explaination.
I've (a long time ago...) tested several IVTC filters, without being convinced. When i've developped my filters, it was of course for anime wich telecine pattern change almost on every scene. At the time, all the filters seems to work on the same idea : Detect the 2 frames with higher correlation computation. I've tested another idea : Detect frames where doing IVTC significantly reduce correlation. At the time my filter worked at places where all others failled. So, i think i've been able to have something wich produce very good result. Feel free to test it (i insist... ) and even report what you think (link is in on the 1rst post, if web page is in french, click on Télécharger ce fichier). Note : There is a crash bug i've corrected in the new version, so, if you want to test (to see how good it is... ), use old version : Rename IVTC directory to IVTC_new, and IVTC_old to IVTC, and build project (leave paramaters to their default).
It wasn't the case in old days, because only RGB was avaible, but now, i'm working with, i'll not say YV12 but 4:2:0 interlaced data, source can be either DVD or Blu-Ray (from avisynth script with DGMPEG or DGIndexNV). My purpose is to try to have best result, so not upscalling 4:2:0 to 4:2:2 (if necessary) with interlaced content, only doing this when i'm sure all picture are progressive.
Even if i have good result on my filter, it's not perfect, sometimes it fails. This is why i have a manual mode, where you input a file wich will force manual pattern on some frames. For exemple, on an input video of 2000 frames, i'll tell : pattern is 3 for frames 894 to 902. Now, after the IVTC, some frames still may be interlaced. More commun reason : fading. Either black/white fading, wich was field made in these kind of anime, wich will always be interlaced, of fade between scene with different telecine pattern. Also sometimes some scene (very rare) where interlace doesn't follow any pattern. So, after IVTC, some few frames may need to be deinterlaced. This is why i have a manual mode for my deinterlace filter, using an input file wich will tell it wich frames should be deinterlaced. So, on the 1600 frames file result, i will use my deinterlace filter and say : Deinterlace only frames 19 to 32, 541 to 550 and 1580 to 1600 (standard black ending fade). Now, and only now, i can upscale my 4:2:0 video to 4:2:2 (if necessary), using a progressive method, because i'm sure that all my frames are progressive. I don't alway need to upscale to 4:2:2, sometimes, my whole process stay in 4:2:0.
Now, i have : Old IVTC filter, with LAG, wich can produce either a stable output telecine pattern of 2, or progressive output, creating always frame 3 duplicate of 2. Using an internal counter to count frames. My old deinterlace filter, without LAG, but use an internal counter to count frames. Before the possibility to reduce frames, i had 2 steps : - Saving a 4:2:0 file with stable telecine pattern of 2. - Opening this files with an avisynth scripts, with the correct doubleweave+pulldown pattern inside and deinterlacing it.
Still with old versions, introduce remove frame possibility. Great !! This will avoid me to create an intermediate file with the pattern of 2, and allow me to do everything in one step. More practical and faster. Just changed the default setting of my IVTC filter to create progressive output, and create a remove frame filter wich remove the 3rd frame every 5 frames. Now, my ITVC and remove filters are still the old version, but my chain is the following, and in that order. - Old ITVC filter, with manul file wich tell it to apply pattern of 3 to frame 894 to 902, number according the 2000 frames video input. - Remove frame - Old deinterlace, with manual file wich tell it to deinterlace only frames 19 to 32, 541 to 550 and 1580 to 1600, but now according the 1600 frames videos.
For now, this works fine.
Everything break down when i've tried to use prefetch2, but the rest of the story is tell here. But, with my manual frames settings options, and the fact my IVTC algorithm need contiguous inputs, at least, on it's level on the filter chain, i think you can see what my troubles are, and the fact i'm facing some kind of dead end... |
 |
| jpsdr |
| Posted: Dec 20 2011, 12:14 PM |
 |
|
Advanced Member
  
Group: Members
Posts: 335
Member No.: 20490
Joined: 23-December 06

|
My remove frame filter remove k frames each n frames.
I've first try to add in the prefetch2 a +/n windows frames. It worked, and after i've try better : a +/-k windows. Worked also. Why fetch +/5 frames if only +/-1 are enough, in standard 1 frame on 5 removed ? Made several tests with several values, seems to work fine.
More : for a 200 input files, all the filter before my remove frame process the 200 frames, and those after 160, and big things is that the .mFrameNumber field vary from 0 to 199 before, and 0 to 159 after. So, no need anymore of the internal counter, and manual setting will work fine.
Things behave properly, at least, from my point of view. If in the filter order A B C D E, i've put the remove frame C after B and before D, it's not for it having an effect on A and B, otherwise, i would have put it before A.
Here a link to all properly working : x86 version x64 version If page is in french, click on Telecharger ce fichier If after testing my IVTC filter you find it interesting, tell me... |
 |
| phaeron |
| Posted: Dec 20 2011, 09:35 PM |
 |
|

Virtualdub Developer
  
Group: Administrator
Posts: 7773
Member No.: 61
Joined: 30-July 02

|
This will work for now, but is highly likely to break in future versions. For instance, it would fail if VirtualDub fetched frames backwards. Simply put, if you are relying on the order in which frames are requested you are relying on unspecified behavior. You can still do pipelining in a way that doesn't require a specific order, namely by caching intermediate results. |
 |
|