Log in

View Full Version : SelectEven() slows down to 1 fps!


vie2233hil
10th June 2004, 01:42
Hello,

I tried that in 2.54 and 2.55. Whenever I add SelectEven or SelectOdd to the script, enconding speed drops from 15-20 to 1 fps! What gives?
Any other way to cut hdtv 59.940 fps in half?

Thanks

kassandro
10th June 2004, 03:45
I think your problem is related to mpeg2dec3. If you only request every second frame, then mpeg2dec3 treats such a request as a random request, which is extremely slow compared with sequential requests. There are two ways out of this problem. Firstly one may fix mpeg2dec3 or secondly one may fix selecteven, selectodd and selectevery. The first solution will always be insufficient. It always will fail, if selectevery is used with a sufficiently high period. Hence, I prefer to fix selecteven etc.. These functions should simply request any frame sequentially. The drawback of this approach is that the avisynth cache is exhausted more quickly.

By the way, if you simply use selecteven for frame rate reduction, you should put it at the very end of the script. If temporal filters are used, this results in better quality and the above problem may even disappear, because all frames are requested.

vie2233hil
10th June 2004, 04:57
kassandro, thanks

I put FluxSmooth() before SelectEven() and it worked. However, I don't do any filters besides undot() (HDTV source) Can I write a script to request every frame and only return every other frame?
Or apply null temporal filter or something?
something like

a=last
a.read_and_discard()
return a.selecteven()


Thanks

stickboy
10th June 2004, 06:01
Originally posted by kassandro
The first solution will always be insufficient. It always will fail, if selectevery is used with a sufficiently high period.But isn't there some period where the cost of requesting all of the unused, sequential frames is greater than the cost of the random access? If so, then there can be an upper bound to the period that mpeg2dec should handle, right?

vie2233hil
10th June 2004, 06:04
I tried dgencode - works fine

kassandro
10th June 2004, 08:55
Originally posted by stickboy
But isn't there some period where the cost of requesting all of the unused, sequential frames is greater than the cost of the random access? If so, then there can be an upper bound to the period that mpeg2dec should handle, right?

I have to withdraw from my earlier statement. To find the optimal solution, one has to

recall how mpeg2dec3 handles random requests. If mpeg2dec3 receives such a request, then

it jumps to the last I-frame before the requested frame. Then it decodes all the

P-frames after this I-frame until it has both P-frames surrounding the requested frame

and finally it processes sequentially all the B-frames starting from the P-frame

immediately before the requested frame until it finally arrives at the requested frame.

Thus not all frames between the I-frame and the requested frame have to processed, which

would be necessary if SelectEvery requests all the frames sequentially. Actually having

many B-frames improves random access. Thus the optimal strategy for mpeg2dec3 would be

to process all frames sequentially starting from the last processed frame, if there is no I-frame between (again not all B-frames have to processed) the last processed frame and the requested frame. DGdecode hopefully implements this strategy. However, when I tried it had severe problems with the last frames, that I to switch back. Before I switch again to DGdecode, it must so stable that there has not been any new version for at least a month. On the other hand, all codecs should embrace this strategy. If they don't, you will have the same problems with avisource.

scharfis_brain
10th June 2004, 09:00
uhhhh, altering select...()'s behaviour isn't a good idea with my scripts....
If select...() would request every frame, my scripts would became more than four times slower

kassandro
10th June 2004, 10:55
Originally posted by scharfis_brain
uhhhh, altering select...()'s behaviour isn't a good idea with my scripts....
If select...() would request every frame, my scripts would became more than four times slower
I strongly doubt that. B-frames aside mpeg2dec3 has to render all frames until the last I-frame anyway. The problem is with the avisynth cache. If you use SelectEvery with a large period that problem may become very painful, but then even an optimal mpeg2dec3 will be very slow. The builtin filter Reverse is even worse. If you want to watch a video backward, I recommend to encode first with lossless jpeg and then to process this "big" clip, because lossless jpeg has the advantage that any frame is an I-frame.

scharfis_brain
10th June 2004, 12:18
I do not talk about MPEG-Decoding here.
I mean time cosuming processing of frames (ie supersampling, spatial processing etc.).
So a selection without requesting non needed frames is clever. (current behaviour of select...() )

maybe a passthrough filter should be added to avisynth, that requests all frames in a linear way, no matter whether they are requested by a following filter, or not..

Guest
10th June 2004, 17:32
Changing the subject back.

DGMPGDec 1.0.12 is a good stable version with no problems at the end of file. If you wait for a month without a new version, you'll wait forever. I am always adding new features.

That version avoids using random access unless the period is greater than 7.

kassandro
10th June 2004, 23:12
Originally posted by neuron2
That version avoids using random access unless the period is greater than 7.
Why this limitation? As explained above, I think the optimal strategy is to check whether there is an I-frame between the last processed frame and the requested frame. If so, I start - as usual - decoding from the I-frame before the requested frame. If there is no I-frame in between, I continue with the current decoding context until I arrive at the requested frame. That is always faster than jumping back to the I-frame. Of course this only works if the requested frame has a higher frame number than the last processed frame. If not, then one always has to go back to the I-frame (internal caching of DGdecode would be too costly). On the hand, if the requested frame is only 7 frames behind the last processed frame, then the request is usually caught by the Avisynth cache and it won't arrive at all at DGdecode.

Guest
11th June 2004, 01:41
Because it's much easier to implement and it works very well. That doesn't mean I concede that your idea is optimal; it just means I don't consider it worth thinking about. :)

Your idea as stated is broken in any case, because decoding from the preceding I frame is not always enough. Sometimes you have to go back an extra GOP.

Finally, it's not so easy as you think to determine whether there is an I frame in-between.

sh0dan
11th June 2004, 09:22
On the original subject: ChangeFPS has recently got a feature where it doesn't skip less than 10 frames ("linear" parameter) - I guess implementing it in selectevery would also be a good idea...

Bidoche
11th June 2004, 09:22
That version avoids using random access unless the period is greater than 7.I am not sure I understand that statement.

Does that mean that if your filter has 7 clients (parents filters) each requesting frames linearly, everything is well.
But if an 8th comes up, they all get random acces.
Or is it something else ?


Supposing you had access to the cache, could you use it to provide the linear access ?
Then the cache size would be the limit, not 7.

stickboy
11th June 2004, 12:38
Originally posted by sh0dan
On the original subject: ChangeFPS has recently got a feature where it doesn't skip less than 10 frames ("linear" parameter) - I guess implementing it in selectevery would also be a good idea...I don't think this sort of thing belongs at the level of SelectEvery. Shouldn't it be handled by the source filter (which knows more about the decoding characteristics) or, as scharfis_brain suggested, a configurable pass-through filter that linearizes access?

Guest
11th June 2004, 13:05
@Bidoche

We're talking apples and oranges. I have one filter, an MPEG decoder. Suppose we have decoded and displayed a frame. Now suppose we get a request to navigate to a new frame that is later than the current one. I can either just start decoding linearly from the current frame and stop when I reach the requested one (linear access), or I can jump into the stream and back off to the required I frame and start linear play from there (random access).

The random access carries extra overhead due to the need to back off. That is especially obvious when we want to skip two frames forward. With linear play we can just decode two frames. With random access, we might go back and have to decode as many as two GOPs depending on the frame type of the requested frame and whether its GOP is closed.

My strategy is that if the request is within 7 frames I just play linearly, else I use random access. It is simple (and therefore safer) and works very well.

Bidoche
11th June 2004, 14:58
@neuron2

Seems I misunderstood :p
Must have been confused by the period word.


Anyway the second part of my post remains valid :

I guess you keep the last frame rendered cached so you can restart decoding from it.
But if two parents (or more) are concurrently making requests, you may never manage a single linear access, the cached frame being poisoned by the effect of the other filter.

So my question : would searching the Avisynth Cache (supposing it's possible) for a frame to start from, work ?

kassandro
11th June 2004, 15:45
Originally posted by Bidoche
So my question : would searching the Avisynth Cache (supposing it's possible) for a frame to start from, work ?
I think the frame content alone is not sufficient. You probably need the entire decoder state at the time, when the frame was created. If the frame was a B-frame, then it is even theoretically impossible to start decoding from this frame. There may be some adaptive decoding going on, tha even P-frames are useless, but I am not an mpeg2 expert.