Share

ffdshow

Tracker: Patches

5 Improved AviSynth Buffering - ID: 1676882
Last Update: Comment added ( kurt_pruenner )

Here's my patch for ffdshow's AviSynth filter that implements buffering to
allow AviSynth access to more than just the current frame. It also allows
an AviSynth script to adjust the number of frames, as long as this happens
evenly distributed across the whole video.

I've added 4 new controls to the AviSynth page:

* Buffer back: number of previous frames to keep around, i.e. the number of
frames AviSynth can look back.

* Buffer current: a top limit for the number of frames that will be
buffered for a single output frame; the actual value for this is calculated
by dividing the number of frames going in by the number of frames going out
- but if your video is a million frames and you request only one, without a
limit one million frames would be buffered, which would probably just crash
the player... :)

* Buffer ahead: number of frames to buffer ahead before feeding anything to
AviSynth, i.e. the number of frames AviSynth can look ahead.

* Apply pulldown: applies a 3:2 pulldown to the video according to the
interlace flags that the frames coming in have. Should be activated for
IVTC, bobbing and other stuff that drops or adds frames. Deactivate it if
you want progressive frames straight from a DVD, unless it was flagged
incorrectly.

If you get jerky video, that most of the time means the buffering values
are to small.

For example, the following script needs to buffer 1 frame back and 10
ahead:

TFM(order=1)
TDecimate(mode=1,hybrid=1)

The default 10/10/10 is probably a good compromise; and keeping more back
buffers only uses more memory but doesn't slow things down. Also, you
should probably use something like SetMemoryMax(16) in your script to limit
the amount of memory AviSynth uses.


I've also made a minor modification to the libmpeg2 codec to flag sequence
starts and ends as fieldtype flags so the filter can flush what's left at
the end of a sequence - without that, you'd lose several frames at the end
of the video, which wouldn't be so bad, but static DVD menus that are only
1 frame long would never get displayed without this.

In other news, I'm probably blowing the AviSynth environment away a bit too
often, but that was the only way I could think of to clear AviSynth's cache
- with some modifications at least seeking could probably be made to avoid
this.

Also, I probably should check out how to change the reported FPS value in
the video headers, but it does work as long as the timestamps are
correct...

np: Boards Of Canada - Everything You Do Is A Balloon (Skampler)


Leak ( kurt_pruenner ) - 2007-03-09 00:19

5

Closed

None

Nobody/Anonymous

None

None

Public


Comments ( 45 )

Date: 2007-05-24 16:03
Sender: kurt_pruennerProject Admin


Committed into SVN as revision 1194.


Date: 2007-05-23 22:01
Sender: kurt_pruennerProject Admin


Another update, hopefully the last before checking this into SVN:

* Fix aspect ratio handling (i.e. actually handle AR where it really
matters)
* Don't create a new AviSynth clip in setOutFmt if frame size and AR are
still the same
* Reset the "Enable buffering" checkbox when resetting the filter
settings
* Quench aspect ratio DPRINTF spam

File Added: Improved_AviSynth_Buffering_14.diff


Date: 2007-05-21 07:16
Sender: kurt_pruennerProject Admin


> Can you please add a .patch not .diff?
> I can't use it.It can't find .../vendor/ffdshow-tryouts/rev1186/trunk.

Ummm... the attached files *are* patches (aka diffs), produced directly
from my local SVN repository.

Just checkout rev. 1186 (to be sure the patch applies cleanly) from

https://ffdshow-tryout.svn.sourceforge.net/svnroot/ffdshow-tryout/trunk

into some directory (C:\Temp\ffdshow in my case when I tested it just now)
then download the diff/patch, cd into the directory you checked ffdshow out
to and run

patch -p0 < ../Improved_AviSynth_Buffering_13.diff

which produces:

patching file src/ffdshow_constants.h
patching file src/Tinfo.cpp
patching file src/settings/filters/TavisynthSettings.cpp
etc.

Could it be that you forgot to specify -p0 when using patch, so patch
silently drops all path information?

What did you use for patching? I'm usually using TortoiseSVN's "Apply
patch..." context menu command for patching a second checkout before doing
my release builds, and it works just as well...


Date: 2007-05-21 05:30
Sender: nobody

Logged In: NO

Can you please add a .patch not .diff?
I can't use it.It can't find .../vendor/ffdshow-tryouts/rev1186/trunk.
Thanks!


Date: 2007-05-20 20:21
Sender: kurt_pruennerProject Admin


Another update:

* Add a checkbox for en-/disabling all buffering
* Add tooltips to buffer edit fields
* Properly clear the frame that is returned to AviSynth if no frames are
buffered (to prevent green frames from popping up in YUY2)
* Fix missing video if script is empty
* Reorder some controls and IDs for better readability
* Slightly tweak the config dialog layout

File Added: Improved_AviSynth_Buffering_13.diff


Date: 2007-05-14 20:39
Sender: kurt_pruennerProject Admin


File Added: avisynth_config.png


Date: 2007-05-14 20:38
Sender: kurt_pruennerProject Admin


Yay for updates:

* Reset AviSynth only after deactivating the filter or when the image size
or the script changes
* Added a help webpage for the filter
* One additional pulldown option ("Smooth timestamps") to smooth out
alternating timestamps without duplicating fields - this should make
adding/dropping frames work on 24 FPS material, probably even on hybrid
material, but the output frame rate will vary proportional to the input
frame rate
* Global variables "ffdshow_dar_x" and "ffdshow_dar_y" now available to
the AviSynth script to get and/or set the aspect ratio and process images
differently depending on the aspec ratio

File Added: Improved_AviSynth_Buffering_12.diff


Date: 2007-05-01 15:18
Sender: kurt_pruennerProject Admin


2 Bugfixes:

* Fix crashes caused by still uninitialized buffer variables when AviSynth
filter instances requested frames right after being created
* fix bogus timestamps right after flushing/seeking

Documentation is still to be written... :/

File Added: Improved_AviSynth_Buffering_11.diff


Date: 2007-04-29 18:48
Sender: kurt_pruennerProject Admin


Yet another update, delayed a bit due to my TFT monitor's backlight
dying:

* Disable buffering when "Apply pulldown" is off and ahead and back
buffers are set to 0 (i.e. the old AviSynth filter behaviour)
* Use original timestamps when the number of frames isn't changed

I'd consider this version feature-complete; all that's left is adding a
help-file documenting the AviSynth filter settings and operation - but I
thought another release while I'm tackling that can't hurt...

File Added: Improved_AviSynth_Buffering_9.diff


Date: 2007-04-15 13:51
Sender: kurt_pruennerProject Admin


Another update:

* Added some comments to the code
* Don't always reallocate the buffers
* Debug-print the reason for a skipAhead call
* Fix b0rked code to get the decoder's filters in BeginFlush, since that's
not gonna work in the encoder, which will then likely crash or act
strangely
* Really make timestamps strictly increasing; frame durations in the last
version could start to oscillate, making playback a stutter-o-rama

Fizick, sorry about that - I confused you with someone else on the doom9
forums.

Anyway, please give this version a try; if the constant flushing should
happen again please add a "#debug" at the beginning of your script in the
encoder and tell me what DebugView prints for each frame; if there's some
external event that triggers the flushing it should print "onSeek",
"onSizeChange", "onFlush" or "onStop", although I can't really imagine one
of those happening when encoding - and building an encoding graph in
GraphEdit worked just fine on my end.

I've changed the skipping ahead part so at least 1000 frames are skipped
now (to make really sure nothing cached is used afterwards; there are 10
million frames so skipping 1000 is peanuts, plus the skip will go back to 0
after 5 million frames anyway - so please don't be alarmed. :)

I've still got to write the "no buffering" part, but I wanted to fix those
bugs first, and that was about all I could get done today.

File Added: Improved_AviSynth_Buffering_8.diff


Date: 2007-04-14 08:59
Sender: fizick


New test report with version 1094;
I encode with Ulead VideoStudio (directshow appication) from HUFYUV avi
(decoded by ffdshow) to Picvide MJPEG.
Used script:
Info

Sometimes I try secon script:
Addborders(256,0,0,0)
Info

Results:
1. There are no missed frames besides very last frame duplicates of
previous frames (5 duplicates for buffers ahead=5).
It is quite acceptable.
2. The is big slowdown of encoding speed (it is about 3 fps).
It is bad.
Without Avisynth - about 18 fps. With standard ffdshow version - about 12
fps.

Encoded frame numbers are crazy:
true (source hardcoder) / Info
0 / 61
1 / 107
2 / 153
3 / 199
and so on.
357 / 16483
357 / 16483
357 / 16483
357 / 16483
357 / 16483
357 / 16483

Seems, you kill avisynth cache and/or fill many unneeded buffers.

P.S. I never said about to re-initialization Avisynth or resetting.
Please read my posts more carefully.

Thanks for your efforts (I see you will try restore standard ffdshow
avisynth processing with some switch - it will be useful for pure spatial
filters).


Date: 2007-04-12 21:04
Sender: kurt_pruennerProject Admin


So the different frame numbers reported don't match up because they
measure different things - exactly how is that a problem?

If I remember correctly it was you (among other people) that said
re-initializing AviSynth and it's filters whenever there was discontinuity
in the stream (stop, seek, flush, whatever) which would be the cleanest
solution was taking too long... so now instead of resetting everything, I'm
making the AviSynth script seek ahead to get somewhere where AviSynth's
cache is very unlikely to get a cache hit - that is, I skip forward 4 times
the number of buffers used (ahead+back, i.e. 0 frames with a setting of
0/0, and 20 frames with a setting of 0/5), rounded up to some other value
depending on the input-to-output-frame ratio (which is 1:1 unless you add
or remove frames).

As far as AviSynth is concerned, it is always fed a clip that pretends to
be 10.8 million frames long, and there is now only one direction this is
going - forward. If I restarted at 0 every time without re-initializing
AviSynth, you'd get cached frames fed into your filter, messing up
everything big time since you'd get old frames out instead of new ones. Is
that so hard to understand?

Using your 5/0 setting as an example:

The number in the OSD (57) is the number of the frame that was just fed to
or decoded by ffdshow (i.e. the input), while the frame that is shown (52)
by the video renderer is my filter's output, which because of buffering is
delayed by the number of frames you have set up - and which is the whole
point of my patch. But it still is the 53rd frame returned by the filter,
which is all the next filter in the DirectShow graph cares about, as it was
not passed anything (and thus did nothing) while my filter was filling it's
buffers initially.

And finally, the discrepancy between the hardcoded frame number (52) and
the Info number (72) is caused by my filter skipping ahead once after the
first frame since I have to pass the first frame through or else a
DirectShow graph using the Overlay Mixer will hang forever, thus
incrementing AviSynth's position by 20.

In short:

* The OSD frame number comes from the decoder, and reflects the frame that
has just been decoded which IS NOT the frame that is processed unless you
set all buffer settings to 0
* The Info frame number is pretty much arbitrary and not really connected
to the OSD frame number
* The hardcoded frame number should be steadily counting up in steps of 1
starting at 0, unless you drop/add/rearrange frames via a filter

So, please - unless you either get jerky video while simply watching
something (i.e. not when starting playback or right after seeking) when
using my filter *or* if you're really missing frames from the result if
you're encoding video (and only, of course, if you're not using VfW for
encoding) *then* there's something wrong.

I'm going to write a help file for this filter when I find time, detailing
how it works, but in the meantime please read the above and try to
understand why the frame numbers differing is not a bug, but expected
behaviour...


Date: 2007-04-12 18:52
Sender: fizick


Somewhat is still even more strange with frame numbers in new version
ffdshow_AviSynth_rev1094_20070411.exe (I do not try previous one).
I set buffers back/ahead = 0/10
Avisynth script:

addborders(256,0,0,0)
info

xvid source with hardcoded subtitles (by avisynth info)
Switch OSD Frame numbers ON.

Typical results:
OSD number=57
new info number=87
true (old hardcoded) number=47.
(last 10 frames are not shown - skipped)

If I set buffers to 0/5, i got:
OSD number=57
new info number=72
true (old hardcoded) number=52.

If I set buffers to 0/1, i got:
OSD number=57
new info number=60
true (old hardcoded) number=56.

If I set buffers to 0/0, i got:
OSD number=57
new info number=57
true (old hardcoded) number=57.

Last result is fine. But these results are after SECOND pass of
MediaPlayerClassic. (after stop - play)
At very first play (after opening), I have got (with buffers 0/0):
OSD number=57
new info number=56
true (old hardcoded) number=57.


More: new frames numbers are incremented with every auto-repeat pass of
MPC (I use short clip 363 frames,
and I see frame number =728 and so on...)). OSD numbers are resetted
well.



Date: 2007-04-11 21:02
Sender: kurt_pruennerProject Admin


| I might remove the back buffers completely since the internal
| AviSynth cache does the same

Come to think of it - scratch that; if a filter always requests frame n-1
from the source to produce frame n then frame n-1 won't be cached in
AviSynth before it gets dropped out of the buffer my patch implements...

So I guess I'll keep the back buffer setting, but it should usually be 0.


Date: 2007-04-11 18:54
Sender: kurt_pruennerProject Admin


Here's a quick bugfix update:

* Fixed a division by zero due to an improperly initialized variable
(d'oh!)
* Reported number of back buffers after a seek was to high
* Script errors now actually produce a clip

It's now actually really difficult to get a number of back buffers other
than 0 due to the fix above - I might remove the back buffers completely
since the internal AviSynth cache does the same; that would leave exactly 2
new settings: number of buffers and "Apply pulldown"...


File Added: Improved_AviSynth_Buffering_7.diff


Date: 2007-04-09 15:23
Sender: kurt_pruennerProject Admin


Another update of my patch:

* Skip ahead in AviSynth instead of reinitializing everything when the
cache needs to be disregarded, that should prevent longer pauses when
seeking. Note that the filter of course still gets reinitialized when the
output format changes or playback is stopped.

* Make timestamps strictly increasing (Overlay Mixer is not too fond of
frames that end before they start)

* Removed "Current" buffer setting as it's been folded into the "ahead"
setting, especially when the correct setting for that can be gotten from
the OSD

* Added "Use Current" button to apply current max back/ahead buffers in
the config dialog for convenience


File Added: Improved_AviSynth_Buffering_6.diff


Date: 2007-04-05 10:35
Sender: h_yamagataSourceForge.net SubscriberProject Admin


Oops, I should have read the documentation of TFM/TDecimate.
Sorry for bothering you.


Date: 2007-04-04 14:39
Sender: kurt_pruennerProject Admin


Ummm... of course it plays jerky - that video is not telecined, it's
purely 50 FPS interlaced. You can't use TFM/TDecimate on it and expect it
to not be jerky - do the same thing in a normal AviSynth script and it'll
look exactly the same.

If it isn't jerky in clsid's build that's because TFM/TDecimate won't work
properly as they're always fed the same frame, not matter which one they
request, so any kind of analysis it does must fail...

Use a normal Deinterlacer or Bob filter with this material.


Date: 2007-04-04 13:17
Sender: h_yamagataSourceForge.net SubscriberProject Admin


With ffdshow_AviSynth_rev1074_20070325.exe, playback of pva_test.pva is
jerky.
ffdshow_rev1082_20070328_clsid.exe plays the sample smoothly.

pva_test.pva:
http://www.mytempdir.com/1282188

The script
SetMemoryMax(16) #optional
TFM(order=1)
TDecimate(mode=1,hybrid=1)

Buffers back/current/ahead 10/10/10
VMR7, YUY2


Date: 2007-03-26 19:14
Sender: kurt_pruennerProject Admin


Another small update - I've added "applying pulldown" to the OSD info when
pulldown is actually being applied.

I've also added debug printouts, which can be activated by starting the
Avisynth script with a "#debug" line. Those printouts can be logged with
utilities like Sysinternal's DebugView.

File Added: Improved_AviSynth_Buffering_5.diff


Date: 2007-03-25 17:29
Sender: kurt_pruennerProject Admin


I've added an AviSynth info item to ffdshow's OSD, which shows the number
of back and ahead buffers used since the last reset (i.e. stop, seek, size
change or similar); that should help a bit with finding the correct
settings. It also shows the input frame number that's considered "current"
for the generated frame and the frame numbers that were requested by the
AviSynth script to produce it.

The values can also be logged to a CSV file by checking "Save to" in
ffdshow's OSD options.

The defaults were changed to 0/10/0 and Apply Pulldown off for backwards
compatibility, but of course at those settings it also doesn't really
support random access... :)

I've also added some code to reset AviSynth on a BeginFlush on the
DirectShow input pin to work around a DVD Navigator bug where seeking
doesn't cause an onSeek event, and without knowing that the stream was
seeked the frames that were buffered before the seek get processed and
played after the seek at full tilt, which looks weird and eats extra CPU
time.

Another thing I've added is an onFlush method in Tfilters and Tfilter,
since that is the easiest and probably cleanest way to handle this,
although doing anything more in them other than flagging that there was a
flush is probably a bad idea due to race conditions that may occur then.
File Added: Improved_AviSynth_Buffering_4.diff


Date: 2007-03-23 16:43
Sender: fizick


Forget to say, that I know something about debugview, xvid, b-frames, etc,

and I use Athlon XP 1800+ o.c. to 2040Mhz with 100Mhz SDR Dimm


Date: 2007-03-23 15:31
Sender: fizick


Please make "pulldown" option disabled by default.
If somebody need in pulldown, he will know what he doing, and will switch
it on.


Date: 2007-03-21 21:32
Sender: kurt_pruennerProject Admin


> 2. I see a code fragment:
>
> input.numBuffers=numBuffers=buffersNeeded+bufferBack+
> (applyPulldown ? 1 : 0);
> applyPulldown=!!oldcfg.applyPulldown;
>
> Seems ApplyPulldown is not initialized in first line.

Eeek, you're right... that slipped through. But even if applyPulldown was
0 when it should have been 1 it only means that there would be one less
back buffer if and only if applying the pulldown meant buffering 2 frames
from 1 input frame because the ring buffer I'm using is one element too
small; i.e. nothing that could cause a frame to be duplicated. Oh, and that
an extra buffer gets allocated later on when applyPulldown is true is not a
bug - that's an extra buffer just beyond the ring buffer I use for keeping
the fields from the last frame.

Anyway, I'll add some debugging statements tomorrow afternoon and build a
version that dumps which frames get buffered and which get pushed out by
the filter via debug prints - I assume you know how to use Sysinternals'
DebugView?

Some more questions:

Are you sure that you have the grab filter right behind the AviSynth
filter in the filter chain? (You can drag filters up and down in the filter
list)

Are all other filters deactivated? And even then some filters might get
included in the filter queue even though they're deactivated (resize comes
to mind, if the AR is being changed), and if some other filter is causing
duplicates I can't do much. Oh, and be sure to turn off "drop frame on
delay" in the Decoder Options as well as "Queue output samples" just to be
on the safe side.

Have you set ffdshow to actually decode the XviD file? Or are you using
the XviD decoder and have set ffdshow to process raw video?

Also, make sure the XviD file doesn't contain B frames as the extra hoops
you have to jump through to reorder those _might_ cause some padding frames
to be added at the start...

As for the 100% CPU usage at the start - that's the decoder running at
full tilt to produce the frames that are being buffered, which is the
desired effect. Can't say I notice much of it here with one core of an AMD
Athlon 64 X2 4400+ - what are you using?

And as far as the filenames produced by the grab filter are concerned -
that's the number of the decoded frame, which is getting incremented while
frames are being buffered.


Date: 2007-03-21 19:46
Sender: fizick


More info:
When set buffers to 10,10,10 and GRAB mode,
I have got a captured files (at first pass, same script):
grab0000.jpg (info frame number 10810799, original 0)
grab0001.jpg (info frame number 10810799, original 1)
grab0012.jpg (info frame number 1, original 2)
grab0013.jpg (info frame number 3, original 3)
grab0014.jpg (info frame number 3, original 3)
...


2. I see a code fragment:

input.numBuffers=numBuffers=buffersNeeded+bufferBack+(applyPulldown ? 1
: 0);
applyPulldown=!!oldcfg.applyPulldown;

Seems ApplyPulldown is not initialized in first line.


3. more comments later. Thanks.


Date: 2007-03-21 13:40
Sender: kurt_pruennerProject Admin


> frame 10810799 of 10810800 ( really old frame 0)
> frame 10810799 of 10810800 ( realle old frame 1) interesting,
> frames with same number are NOT duplicates.
> frame 1 of 10810800 ( really old frame 2)

The frame number AviSynth reports is totally meaningless - it is reset to
zero everytime the filter resets AviSynth and thus throws out anything it
had buffered until that point, which happens on a number of occasions.

Some of those occasions are when the stream gets seeked, when it gets
stopped and restarted, when the end of an MPEG2 segment is encountered and
when any property of the input frames or the filter's configuration
changes.

So unless the resulting frames are really duplicates everything is working
as designed. Also, keep in mind that I meant this filter to be used while
playing back something where dropping a few frames is better than playback
lagging behind; i.e. if you seek in a DVD or stop it it doesn't make any
sense to show the remaining frames when playback resumes.

The "!!oldcfg.applyPulldown" is just a run-off-the-mill trick to convert
an integer into a bool value without the compiler throwing a warning, which
is used throughout ffdshow's code.


Date: 2007-03-20 21:16
Sender: fizick


Sorry for disturb.
No, I did not use frame step.

Here is my method used:
1. I created short xvid video clip with hardcoded framenumbers by
avisynth info(), save as xvidn.avi. PAL 720x576, 25fps. Tried also 360x288.
Tried also Huffyuv.
2. Setup ffdshow Avisynth options as buffers 0,1,0 (or 10,10,10) ,
pulldown OFF, script:

crop(24,0,0,0).info()

or similar, to show both old and new frame numbers.
3. Open xvidn.avi in MPC by clicking or via File-open menu.
I see video with two vareing numbers : old and new. New is lesser by 1. We
can press Pause to see this too.
NOTE: If I pres Stop button, and than Play button in MPC, these frame
numbers become equal!
So, they are differ only at first pass.
If I re-open video, I see different numbers again.
It is not dependent on video player (WMP6.4, WMP9).
May be it is related to very high processor load (100%) at start of play
(than decrease to about 40 %.
May be you use have more fast system?

I also no tried your GRAB method.
here is results (for first pass):
frame 10810799 of 10810800 ( really old frame 0)
frame 10810799 of 10810800 ( realle old frame 1) interesting, frames with
same number are NOT duplicates.
frame 1 of 10810800 ( really old frame 2)
...



But when I use non-patched ffdshow build, these (old and new) frame
numbers are always equal.

Now I douwload FFDshow source from SVN, apply your patch and try look to
source and create binary.
I still did not understand all.
seems, this line must be at little above place:

applyPulldown=!!oldcfg.applyPulldown;

(but it is not related probably).





Date: 2007-03-20 07:51
Sender: kurt_pruennerProject Admin


Ummm... in case you're doing it the following way:

Open file
Click stop
Click pause
Hit cursor right to step forward a frame several times

This always gives me a duplicate first frame, no matter which file or
codec I'm using - try opening your XviD source in MPC using the XviD
decoder and you'll get the same...

Also, since audio and video are synced up using timestamps in DirectShow a
single duplicate frame (which, other than the above, I just can't
reproduce) is hardly a problem, so I honestly don't understand all this
fuss...

Moreover, please try this: drag ffdshow's "Grab" filter right below the
AviSynth filter. Set it up to capture the first few frames. If the
resulting images contain repeated frames then my filter is actually
producing them. If there isn't, they're caused by something else.


Date: 2007-03-19 22:57
Sender: fizick


I still have 1 frame number difference with new build for first prayback
MPC.
So, 0/1/0 fuferss is not equivalent to old versions.


Date: 2007-03-18 18:25
Sender: kurt_pruennerProject Admin


This latest patch should really do no buffering (but still some copying
that could be avoided) at all if you use 0/1/0 and uncheck "Apply
Pulldown". I tried it on a 100-frame XviD file that contained the output of
"Info()" and added a second "Info()" over that while encoding, and except
for the frame number of frame 0 (which, of course, was
10.8-million-and-a-bit) they were identical.

Of course, if you use a value bigger than 0 for the number of frames to
buffer ahead you will get a result that's missing this number of frames at
the end, as the filter isn't notified that it should flush the remaining
frames - but there were no duplicates at the beginning of the file.

Also, no matter what you do - always use as little buffering as
possible/neccessary: using 10/10/90 for normal playback in MPC makes VMR9
drop lots of frames - obviously there's only so much time it's willing to
wait for a frame before it gets dropped. It shouldn't matter for encoding,
though.

One change I forgot to mention was that I added some code to notify the
image filters that the graph was stopped when encoding ends, as I need to
reset everything if encoding should work more than once in a row.


Date: 2007-03-18 18:16
Sender: kurt_pruennerProject Admin


File Added: Improved_AviSynth_Buffering_3.diff


Date: 2007-03-16 21:33
Sender: fizick


Thanks.
I usully capture with directshow application like virtualVCR, etc.
As I wrote, I see similar delay (duplicates) in MPC (Directshow) too.
I now discover that is is partially dependent on CPU load (and format).
I test sort (363 frames) avi videofile 768x576 with hardcoded framenumbers
(info).
I test 10,10,90 frame buffer settings.
if i use avisynth scipt as "showframenumber()", its frame numbers are
different by 1 from hardcoded at first play (but sometimes they are
coincide at second repeat play).
OSD numbers are usually different by Ahead+1.
I wonder why 1 frame dif?
And why 0,0,0 settings produce 1 frame dif too at first play pass?
Probably it is a bug.
IMHO, this settings must reproduce old algo.

Generally, I agree, that some frames lag is permitted.

What about posting this topic to avisynth forum for more wide discussion?


Date: 2007-03-16 08:28
Sender: kurt_pruennerProject Admin


Having thought this over again, I can assure you that this is never going
to work without repeated frames when you use VfW (i.e. the ffvfw codec) to
encode a video and frames are being buffered - there's just nothing I can
do about it, since that's how VfW (which is ancient, technology-wise)
works:

The encoding application (which includes VirtualDub, I'm sorry to say)
hands the VfW codec an image and immediately expects to get an encoded
frame back that is then added to the output file. Since I don't return
frames for a while after the first frame, the old contents of the output
buffer are written to the file several times as there was no new frame to
replace them.

You absolutely positively *need* to either use AviSynth via an AVS file
and access your DirectShow source using DirectShowSource and a GraphEdit
graph file (as there is no such 1:1 restriction there), or you need to use
an encoding application that either directly supports using a DirectShow
graph as input or that completely uses a DirectShow graph to encode your
video - you can, for example, do that in GraphEdit.

I'll modify my filter so buffering can be turned off, but then it'll work
exactly like the current AviSynth filter without my patch, so using any
AviSynth filter that requests more than the current frame (like TIVTC,
Decomb or temporal filters) just plain won't work correctly.

Like I said - as long as you're using a VfW codec and encoding
application, there's nothing I can do; and that's my final answer, I'm
afraid - the only way to make this even remotely work with VfW would be
changing the encoding application to not store the repeated frames in the
file.


Date: 2007-03-16 04:56
Sender: fizick


If I play my Huff avi with previously hard-coded framenumbers (info),
I see same many duplicates of frame 0 with direstshow in MPClassic .
I use buffers 10-10-90, disabled pulldown, script:
BLUR(1.0)


Even if I decrease number of buffers to 0-0-0 I still have 1 extra
duplicate frame.





Date: 2007-03-15 22:16
Sender: kurt_pruennerProject Admin


I'm afraid I don't see any duplicates in MPC; I do see ffdshow's frame
count in the OSD jump from 1 to 12, though - but that's normal, as the
frame count is increased with every frame that's decoded.

I do see duplicates in VirtualDub, but those are definitely not generated
by ffdshow itself - if you look at the code, my filter works by taking the
first <buffer ahead> + <something> input frames and only sending a single
frame further up the filter chain on the first request. Until it has
buffered enough, it just returns without doing anything else.

Wherever the duplicates come from (probably a buffer in VirtualDub or the
ffvfw DLL that isn't overwritten if no frame is produced), I don't know.
But that's really out of the realm of my filter.

But then again, this kind of buffering really isn't meant for VfW - why
not use an AviSynth script directly with DirectShowSource and a GRF file?
(This is totally out of thin air, as I don't have anything I could capture
with...)

Still, ffdshow is a DirectShow filter, after all, and the ffvfw part can
only do so much to cover this up IMHO... of course, you can decrease the
number of buffers if you don't use temporal filtering, but I guess that's
what you're after.

Setting up an AVI Source -> ffdshow decoder -> ffdshow encoder -> AVI Mux
-> File Writer chain in GraphEdit with a 100 frame video produced the way
you wrote above produces a video with no duplicates at the beginning, but
with 11 frames missing at the end since for HuffYUV there's currently no
notification that the stream has ended as I added for MPEG2, but I guess
that's not really a problem for TV captures as those usually are longer
than they need to be.

In closing, I'm afraid the best solution I can offer to you would be
chopping off the repeated frames after encoding, as I really can't do much
against them when you're using VfW, and I' afraid I can't reproduce them
using DirectShow....


Date: 2007-03-15 21:56
Sender: fizick


thanks for details.
May be one-frame bug somewhere.

I try to use HUFFYUV codec (enabled in ffdshow) for testing. Details:
I take some video, open it with avisynth script with INFO(),
end encode it to HUFFYUV format. So I have hardcoded framenumbers.
Now I open this huff video with ffdshow wit internal avisynth script
BLUR(1) and pulldown disabled.
I see in VirtualDub or play in MediaPlayer.
(avisynth enabled in vfw or ds interface).
And I see 11 duplicates. Can you confirm?

I am interested in realtime capture with ffdshow MPEG2 in AVI codec from
my analog TV tuner. I want use fast avisynth filters in ffdshow for
preprocessing.



Date: 2007-03-15 20:48
Sender: fizick


thanks for details.
May be one-frame bug somewhere.

I try to use HUFFYUV codec (enabled in ffdshow) for testing. Details:
I take some video, open it with avisynth script with INFO(),
end encode it to HUFFYUV format. So I have hardcoded framenumbers.
Now I open this huff video with ffdshow wit internal avisynth script
BLUR(1) and pulldown disabled.
I see in VirtualDub or play in MediaPlayer.
(avisynth enabled in vfw or ds interface).
And I see 11 duplicates. Can you confirm?

I am interested in realtime capture with ffdshow MPEG2 in AVI codec from
my analog TV tuner. I want use fast avisynth filters in ffdshow for
preprocessing.



Date: 2007-03-15 16:43
Sender: kurt_pruennerProject Admin


Actually - if the frame size changes when playback starts or something
else happens that causes the filter to reset (and thus simply dumping the
buffered frames) I wouldn't be surprised that you get to see a first frame
a few times in a row, since the AviSynth instance and the buffers are torn
down and created anew in that case.

This also drops the frames that had been buffered by then as I need to
know beforehand that we've hit the end of something to flush the buffered
frames out - which currently only works with MPEG2 and libmpeg2 because I
modified it to return an end-of-stream marker on the last image.

But I'd rather first concentrate on the filter working reliable over the
course of a movie or series episode and then try to minimize the number of
times the filter gets reset - personally I'd rather have a smooth viewing
experience with the first and/or last few frames missing than having to put
up with telecine judder.

Watching a DVD with TIVTC I noticed that things got jerky after a few
minutes (or a few thousand frames) as if the buffered frames and the frames
AviSynth was requesting went out of sync, so I'm going to fix that first.


Date: 2007-03-15 11:50
Sender: kurt_pruennerProject Admin


I just tried this:

Using "Info()" as the AviSynth script, I turned on the AviSynth filter and
put ffdshow's "Grab" filter (which writes anything that gets passed into it
into image files) right next to it. Then I set it to grab frames 0 to 49
and to write them to BMP files in c:\Temp

That resulted in 31 files in c:\Temp; they didn't have consecutive frame
numbers (note: that's ffdshow's internal frame numbering, not mine) in the
beginning, so ffdshow might for some reason skip a few frames in the
beginning, but there wasn't a single duplicate image coming out of my
AviSynth filter in there.

I'll try something similar with graphedit and the dump DirectShow filter
when I get home. I've just noticed that ffdshow seems to skip every third
frame in the beginning with this XviD AVI file whether my filter is used or
not - maybe that's something to do with this, and why there were only 31
images captured.

I'll investigate this further...


Date: 2007-03-15 08:13
Sender: kurt_pruennerProject Admin


> first frames returns number 1071079 (not 0).

This is by design, and not a bug.

The filter works by buffering a number of frames before requesting frames
from AviSynth, so AviSynth can access more than just the current frame.

The problem with buffering is that to buffer frames, I have to take frames
coming in and not return a processed frame until I've buffered enough
frames, but several other DirectShow filters (including the Overlay Mixer)
won't change into running state unless they get a frame, which makes the
graph hang in this case.

To prevent that, I'm requesting a frame from AviSynth after buffering the
first frame (which means that no matter which frame AviSynth requests, it
will always get the single buffered frame) that I pass onwards. This is
done since the ffdshow AviSynth filter doesn't know what exactly the script
does, so I can't just pass the source frame through.

Since there's several filters that will start calculating metrics for
several of the following frames (like TDecimate), I can't just request
frame 0 as that will mess up the metric calculations for the next few
frames, so I'm requesting frame 10810800 , which is the frame beyond the
last frame of the "faked" ffdshow video source. I guess AviSynth clamps
this to 10810799, but that shouldn't really matter.

What matters is that the next frame requested will be number 1, which
should tell any filter that the metrics it has calculated when producing
the last frame are invalid and need to be recalculated. Sure, I could just
restart AviSynth, but that takes more time and I don't think it's worth
it.

> bug with new code: Extra frames in beginning (duplicates of first
frames)
> Number of extra very first frames= (buffer ahead)+1

I still can't think of a reason why this would happen, but I'll have a
look at it. Still, when just watching a video I think this would hardly be
noticed - and if you're encoding video do yourself a favour and use
AviSynth directly...


Date: 2007-03-14 18:21
Sender: fizick


bug with new code: Extra frames in beginning (duplicates of first frames)
Number of extra very first frames= (buffer ahead)+1

Try script:

showframenumber()

and load decoded ffdshow video in virtualDub.

first frames returns number 1071079 (not 0).


Date: 2007-03-10 20:11
Sender: kurt_pruennerProject Admin


(Ack. Sorry about the attachment mess - using the back button after
uploading a file probably isn't the way to go on SF...)

haruhiko_yamagata noticed that using the Overlay Renderer the graph
wouldn't run when ffdshow started buffering without delivering the first
frame, so I now just more or less pass the first frame through (that is,
I'm requesting a far away frame from AviSynth with just one frame buffered;
that will give about the same result as with the original, unpatched
implementation) and that makes the graph tick even with the Overlay
Renderer.

I've also made the filter reset AviSynth whenever it's disabled as it
doesn't make much sense to work on frames that have been long gone when the
filter is reactivated.


Date: 2007-03-10 20:08
Sender: kurt_pruennerProject Admin


File Added: Improved_AviSynth_Buffering_2.diff


Date: 2007-03-10 20:08
Sender: kurt_pruennerProject Admin


File Added: Improved_AviSynth_Buffering_2.diff


Date: 2007-03-10 20:07
Sender: kurt_pruennerProject Admin


File Added: Improved_AviSynth_Buffering_2.diff


Attached Files ( 14 )

Filename Description Download
Improved_AviSynth_Buffering_1.diff Patch against rev. 1007 Download
Improved_AviSynth_Buffering_2.diff Updated patch to fix problems with Overlay Renderer, still against rev. 1007 Download
Improved_AviSynth_Buffering_3.diff Updated patch to fix an off-by-one error, make 0/1/0 do no buffering and return the source fieldtype, against rev. 1048 Download
Improved_AviSynth_Buffering_4.diff Updated patch with AviSynth OSD info, defaults set to 0/10/0 and Apply Pulldown off, reset AviSynth on BeginFlush to work around DVD Navigator bug, against rev. 1074 Download
Improved_AviSynth_Buffering_5.diff Updated patch with additional OSD info whether pulldown is being applied or not, added debug printouts, agains Download
Improved_AviSynth_Buffering_6.diff Updated patch: Skip ahead in AviSynth instead of reinitializing everything, make timestamps strictly increasing, remove "Current" buffer setting, add "Use Current" button to apply current max back/ahead buffers, against rev. 1093 Download
Improved_AviSynth_Buffering_7.diff Updated patch: Fixed a division by zero crash, reported number of back buffers after a seek was to high, script errors now actually produce a clip, against rev. 1094 Download
Improved_AviSynth_Buffering_8.diff Updated patch: Added some comments, don't always reallocate the buffers, fixed possible crash in the encoder, really make timestamps strictly increasing, against rev. 1103 Download
Improved_AviSynth_Buffering_9.diff Updated patch: Disable buffering when "Apply pulldown" is off and ahead and back buffers are set to 0, use original timestamps when the number of frames isn't changed, against rev. 1125 Download
Improved_AviSynth_Buffering_11.diff Updated patch: Fix crashes caused by still uninitialized buffer variables when AviSynth filter instances requested frames right after being created, fix bogus timestamps right after flushing/seeking, against rev. 1126 Download
Improved_AviSynth_Buffering_12.diff Updated patch: reset AviSynth less, added a help page, one additional pulldown option, aspect ratio variables, against rev. 1167 Download
avisynth_config.png Filter screenshot for the help page Download
Improved_AviSynth_Buffering_13.diff Updated patch: checkbox to toggle all buffering on/off, tooltips for buffer edit fields, return a proper black frame if no frames are buffered, fix missing video if script is empty, tweak resources (IDs/dialog), against rev. 1186 Download
Improved_AviSynth_Buffering_14.diff Updated patch: Fix aspect ratio handling, don't create a new AviSynth clip in setOutFmt if frame size and AR are still the same, quench aspect ratio DPRINTF spam, reset the "Enable buffering" checkbox when resetting the filter settings, against rev. 1193 Download

Changes ( 20 )

Field Old Value Date By
status_id Open 2007-05-24 16:03 kurt_pruenner
close_date - 2007-05-24 16:03 kurt_pruenner
File Added 230308: Improved_AviSynth_Buffering_14.diff 2007-05-23 22:01 kurt_pruenner
File Added 229930: Improved_AviSynth_Buffering_13.diff 2007-05-20 20:21 kurt_pruenner
File Added 229152: avisynth_config.png 2007-05-14 20:39 kurt_pruenner
File Added 229151: Improved_AviSynth_Buffering_12.diff 2007-05-14 20:38 kurt_pruenner
File Added 227361: Improved_AviSynth_Buffering_11.diff 2007-05-01 15:18 kurt_pruenner
File Added 227128: Improved_AviSynth_Buffering_9.diff 2007-04-29 18:48 kurt_pruenner
File Added 225033: Improved_AviSynth_Buffering_8.diff 2007-04-15 13:51 kurt_pruenner
File Added 224588: Improved_AviSynth_Buffering_7.diff 2007-04-11 18:54 kurt_pruenner
File Added 224264: Improved_AviSynth_Buffering_6.diff 2007-04-09 15:23 kurt_pruenner
File Added 222370: Improved_AviSynth_Buffering_5.diff 2007-03-26 19:14 kurt_pruenner
File Added 222194: Improved_AviSynth_Buffering_4.diff 2007-03-25 17:29 kurt_pruenner
File Added 221128: Improved_AviSynth_Buffering_3.diff 2007-03-18 18:16 kurt_pruenner
File Deleted 219793: 2007-03-10 20:08 kurt_pruenner
File Added 219794: Improved_AviSynth_Buffering_2.diff 2007-03-10 20:08 kurt_pruenner
File Deleted 219792: 2007-03-10 20:08 kurt_pruenner
File Added 219793: Improved_AviSynth_Buffering_2.diff 2007-03-10 20:08 kurt_pruenner
File Added 219792: Improved_AviSynth_Buffering_2.diff 2007-03-10 20:07 kurt_pruenner
File Added 219519: Improved_AviSynth_Buffering_1.diff 2007-03-09 00:19 kurt_pruenner