Welcome Guest ( Log In | Register )


Important

The forums will be closing permanently the weekend of March 15th. Please see the notice in the announcements forum for details.

Pages: (20) [1] 2 3 ... Last » ( Go to first unread post )
Directshow Input Driver, 0.1
« Next Oldest | Next Newest » Track this topic | Email this topic | Print this topic
phaeron
Posted: Jan 10 2008, 05:09 AM


Virtualdub Developer


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



Been sick this past week with a cold, and when I'm sick, I do things that I wouldn't ordinarily do. Therefore:

http://www.virtualdub.org/beta/DShowInputD...Driver-0.93.zip
http://www.virtualdub.org/beta/DShowInputD...er-0.93-src.zip

Move release/DShowInputDriver.vdplugin in plugins32 folder under VirtualDub program directory if you're running 32-bit VirtualDub, or x64/release/DShowInputDriver.vdplugin in plugins64 folder if you're running 64-bit VirtualDub.

A few notes about this:

  • DirectShow sucks. You would think that for a primary video API on Windows that the task "extract frames and audio from a file" would be slightly easier than "a complete pain in the &#*($."
  • This input driver plugin works with both VirtualDub 1.7.6+ and 1.7.X test releases.
  • Direct stream copy is not possible. Both video and audio are always decompressed.
  • Video format switching does work (RGB24/RGB32/UYVY/YUY2/YV12/YVU9).
  • The plugin never auto-detects a file, so you will need to choose "DirectShow input driver" from the file type drop-down in the Open File dialog. I'm thinking about ways to solve this.
  • It's pretty raw, so it may hang or glitch sometimes. I have gotten it to work on AVI, MPEG-1, WMV, and MKV files. The error reporting sucks.
  • If the file does not natively have a frames per second associated with its video stream, it currently assumes 30 fps.
  • Only one audio stream is currently extracted. Haven't figured out how to reliably get access to alternate audio streams when building the DirectShow graph yet.


Update:
v0.3 is posted. This now scans the DirectShow file type extension list, so it'll automatically pick up extensions that VirtualDub wouldn't otherwise support. You'll still have to override the driver selection for a file format that's already supported, like AVI.

Update (2):
v0.4 is posted. This fixes a bug with the video stream read() call that caused filter preview to break in 1.8.0.

Update by stephanV
v0.5 can be found on this page.

64 bit version is on this page.

Yet another update:
0.6 fixes a problem with file opens taking a long time.

Update^N:
0.7 adds a configuration dialog via File > File Information to manually add file extensions.

Version 0.8:
Fixes detection bug.

Version 0.9:

  • Added a real file information dialog which displays some information on the splitters and decoders in use. The configuration parameters are now on a Config button.
  • Added About dialog and version block.
  • The audio path now defaults to selecting a standard mono/stereo 8/16 bit PCM audio format from the decoder if it is available. This avoids situations where you end up with 5.1 or 7.1 audio and VirtualDub can't process or preview it. There is an option in the configuration dialog to disable this behavior if 5.1/7.1 is desired.
  • Fixed a filter graph leak in the audio path; this was keeping the input file and associated decoders locked even after the file had been closed.
  • Rewrote sample grabber algorithms to better handle erratic timestamps, particularly those from the Microsoft DTV-DVD decoder that activates for MPEG-2 and MPEG-4 decoding in Windows 7. There can still be glitches when the timestamps are jittery but this should have improved results. There is a small speed penalty however, since I had to copy all of the video frames (ffdshow's filter allocator only gives one buffer even if the input pin requires more). In some cases, there will be a significant speed boost as the previous algorithm may have had to reseek repeatedly.
  • Added logic to detect late seeks and retry with a seek farther back, which is needed for splitters that do imprecise seeks like the MPEG-2 splitter.
  • Fixed the source aspect ratio -- it was sending DAR as PAR.


Version 0.91:

  • Fix for one cause of hangs near the end of a file.


Version 0.92:

  • Corrected another issue with hangs at the end of a file (missed EndOfStream events).
  • The workaround in 0.91 is now removed by default. It can be re-enabled in the configuration dialog.
  • The plugin can now be configured directly without loading a file with the latest VirtualDub 1.10.2 test releases.


Version 0.93:

  • Corrected version issue that prevented loading on older versions of VirtualDub.



This post has been edited by phaeron on Apr 21 2012, 11:06 PM
 
    Top
squid_80
Posted: Jan 10 2008, 05:55 AM


Advanced Member


Group: Members
Posts: 594
Member No.: 13813
Joined: 22-January 05



"Unable to render audio stream: hr=80004005"

That'd be because there's no audio stream in the source file, then.
 
     Top
phaeron
Posted: Jan 10 2008, 07:09 AM


Virtualdub Developer


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



Whoops... uploaded v0.2.

Were you able to get it working on any file?
 
    Top
squid_80
Posted: Jan 10 2008, 07:41 AM


Advanced Member


Group: Members
Posts: 594
Member No.: 13813
Joined: 22-January 05



Seems to work on everything I've tried except cineform avi files (cineform's DS decoder is a lot quicker than their vfw one thanks to multithreading), on which it reports "Unable to seek DirectShow graph: error code 80004001" then crashes when trying to close the file (if I load something else or exit).

EDIT: had to rename it to .vdplugin instead of .dll to get it to load, too. Dunno if this is something you've changed in the source since I'm using one of the earlier 1.7.X test sources for my build.
 
     Top
phaeron
Posted: Jan 10 2008, 09:49 AM


Virtualdub Developer


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



Heh... yeah, I forgot to change the output file name. That was dumb. Didn't faze me because I always launch it via VirtualDub /F, which doesn't care about the extension.

The CineForm HD issue is an interesting one. It's failing because the sample grabber can't connect to the CineForm decoder filter, but for some strange reason I ended up with S_OK from the RenderStream() call. My guess is that this is due to bugs in my custom sample grabber filter -- after my experiences with the real Sample Grabber filter in the DirectShow capture code I decided that I really needed to write a custom one to get past some of the more annoying restrictions, most notably that the Sample Grabber cannot accept VIDEOINFOHEADER2 (used for aspect ratio and interlacing). For legal reasons I avoid using the DirectShow Base Class Library, so for this endeavor I started writing a DirectShow transform filter from scratch. I'd already tried doing this once years ago, but failed because my C++-fu and COM-fu was not up to snuff. Things are turning out a little better this time.

Amusingly, I've found a number of bugs in third-party modules while doing this that I'm trying to get resolved:

  • ffdshow spews to the debug output a LOT. It got bad enough that I hacked code into 1.7.X that allows OutputDebugString() to be intercepted and filtered by calling DLL. I submitted a bug on this and it looks like it already got assigned.
  • ffdshow causes AppVerifier to throw asserts about invalid critical section usage. Filed a bug on this too, no response yet.
  • Some DirectShow filter is creating a BITMAPINFOHEADER with YUY2 format that says it has 117 palette entries (biClrUsed=117). This causes a crash in the AVI Decompressor when I have XP's Page Heap enabled, which caught the read overrun. I have no idea who's doing this yet.
  • Avisynth's DirectShowSource() uses PulseEvent(). This is a no-no, as PulseEvent() has known bugs in the Windows kernel with losing wakeups if a kernel APC happens at the wrong time. Thought I'd told someone about this, but I guess it couldn't hurt to go file a bug.


This makes me wonder if I should open the SourceForge bug database for the VirtualDub project again. I'd have to filter through all of the chaff submitted, but the gems might be worth it. ffdshow has a higher profile than I do and thus probably a higher ratio of clueless to clueful users, but they seem to be getting some good submissions.

 
    Top
squid_80
Posted: Jan 10 2008, 10:14 AM


Advanced Member


Group: Members
Posts: 594
Member No.: 13813
Joined: 22-January 05



You wrote your own sample grabber? ph34r.gif Actually it doesn't seem that hard, thinking about it... But that's normally the kind of thinking that leads to me swearing and thumping the desk 5 hours later. Will it be added to capture mode? Any plans to do anything with the aspect ratio/interlacing information?

Agreed on ffdshow's debug spewing. I add virtualdub.exe to ffdshow's blacklist so it doesn't try and jump into the capture graph all the time. Did you file the bug at ffdshow or ffdshow-tryouts?

What about just adding a Bug Report line to VirtualDub online in the help menu and linking it to the forum here? I'm just thinking it would be best if all bug-reports could be in one place so people don't have to check multiple places to see if it's been reported.
 
     Top
phaeron
Posted: Jan 10 2008, 11:00 AM


Virtualdub Developer


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



QUOTE
You wrote your own sample grabber? Actually it doesn't seem that hard, thinking about it...


It's harder than you think, if you don't use Microsoft's libraries. One of the tricky parts is that you need to expose COM interfaces on the pins and on the filter. The problem is that it's legal for someone to hold the filter alive either by a pin or a filter. Your first instinct might be to have the pins and filter hold references on each other, but this creates a refcount loop that causes everything to leak. This is the problem I couldn't solve the first time. The solution is to aggregate the pins into the filter by having the pins delegate their AddRef() and Release() calls to the filter. I'm sure ATL has an easy way to solve this, but I don't use ATL.

There are also some stupidities in the filter interfaces, the dumbest one being that Microsoft didn't provide an implementation of MemAllocator that you can CoCreateInstance() -- it's baked into the static library and every library has it compiled in. If you don't use that library, you have to implement both it and a memory-based sample class yourself. The logic that arbitrates media formats and allocators also has to be reimplemented in the output pin's Connect() method. This is a horrible plugin API design, since it bakes a lot of critical logic into every filter shipped. Thanks to intelligent connect, this means that one filter installed in the system with screwed up connection code can f*ck up DirectShow graph building for every application in the system.

DirectShowSource() in Avisynth avoided some of this because it implements a sink filter with no output pins, and the connection logic is in the output pin. I didn't realize this when I tried this years ago and thought it was stupid that both input and output pins had to implement Connect(), but if you read the docs closely it says that input pins return E_UNEXPECTED for those methods. I did it anyway this time because I wanted to have a framework that would support transform filters. It turns out that was a good decision, because that means I can have a Null Renderer on the end, and then the methods on the filter graph manager that push events starting at the renderers also work. DSS instead pushes seek events directly into the graph through its input pins, which I think you're not supposed to do. Avisynth's DirectShow filter is private, though, so its behavior doesn't impact other applications like a registered filter can.

Threading in DirectShow is also a nightmare -- it's fiendishly easy to create deadlocks, and some of the ways the SDK tells you to write your filter are generally considered very risky programming practices, most notably calling external code while holding locks. The docs tell you to be aware of the difference between the application thread and streaming threads and give a few examples of what to avoid, but they largely don't document in specific methods which threads they're called on, and you're left guessing. I'm amazed that any DirectShow-based video players work reliably because most programmers aren't very good at threading and with this level of information it's very easy to get it wrong.

A specific threading case that gives problems when using the Microsoft Sample Grabber is when you want to capture a specific number of frames, and then stop the graph. The first way that comes to mind is to call IMediaFilter::Stop() on the filter manager. Well, this causes a deadlock because you're holding a sample when this happens. You have to work around this by setting a flag in your callback instead, posting a message to the main thread, and have it call Stop(). When you have your own sample grabber, there are simpler ways of doing this, such as sending EndOfStream() down the graph and letting the main thread receive EC_COMPLETE.

DirectX Media Objects (DMOs) looked promising, because they bake most of the guts into quartz.dll, and you only have to implement some basic transform logic. It only supports simple transform filters, but that's what most filters are anyway. The dumb part is that in order to support COM aggregation, it only accepts a CLSID, which means that you have to register your class in the Registry, which means you need a separate DLL and you need an installer. Screw that!

Suffice it to say, the level of Windows and C++ programming experience you need to navigate DirectShow is staggering, and the main reason I hate it.

Hmm, this turned out a lot longer than I had expected. Maybe I should recycle this for the blog.

QUOTE
But that's normally the kind of thinking that leads to me swearing and thumping the desk 5 hours later.


I think Ben Rudiak-Gould is responsible for this comment in Avisynth:

CODE

   // Prevent the graph from trying to run in "real time"
   // ... Disabled because it breaks ASF.  Now I know why
   // Avery swears so much.


QUOTE
Will it be added to capture mode? Any plans to do anything with the aspect ratio/interlacing information?


I might migrate it to capture mode, once I'm confident that I've worked out the bugs in the DirectShow interfacing logic. It's a lot riskier, though, because in capture mode I have a live renderer and I don't think I have the logic correct for propagating custom allocators across the filter.

Aspect ratio info, probably not. There's a field for it in the plugin API, but it's not used right now and the most I could do with it near-term is get the aspect of the preview panes correct. Interlacing, that's potentially more useful because I sometimes abuse capture mode as a TV and I could use that to auto-configure field polarity. I'm not sure I have any capture devices that actually use VIDEOINFOHEADER2, though. And I have at least 7 or 8 capture devices.

QUOTE
Agreed on ffdshow's debug spewing. I add virtualdub.exe to ffdshow's blacklist so it doesn't try and jump into the capture graph all the time. Did you file the bug at ffdshow or ffdshow-tryouts?


Tryouts. The original ffdshow project doesn't appear to have been updated in nearly six years.

I know that it's hard to make a DirectShow filter work reliably in all cases, but the extent to which ffdshow now relies on its blacklist to resolve compatibility issues worries me.

Incidentally, the silencing switch will go out in the next 1.7.X release as /blockDebugOutput, i.e. /blockDebugOutput -ffdshow,-xvidvfw.

QUOTE

What about just adding a Bug Report line to VirtualDub online in the help menu and linking it to the forum here? I'm just thinking it would be best if all bug-reports could be in one place so people don't have to check multiple places to see if it's been reported.


The forum requires registration, which isn't always convenient. It also doesn't have traditional bug report fields like category and version.

Another reason I'm thinking of reviving the bug database is that I'm tired of people sending me bug reports by email that I can't preview in Magic Mail Monitor, which displays raw email in Notepad. (Phishing emails written in HTML don't really affect me.) Some stupid email clients out there BASE64 encode crashinfo.txt even though it's a 7-bit clean text file. An alternative I've thought of but haven't looked into is just a regular web form.

This post has been edited by phaeron on Jan 10 2008, 11:05 AM
 
    Top
squid_80
Posted: Jan 10 2008, 12:05 PM


Advanced Member


Group: Members
Posts: 594
Member No.: 13813
Joined: 22-January 05



QUOTE
It's harder than you think, if you don't use Microsoft's libraries.
That's what I meant - I know it would be a lot harder than it sounds. Even writing transform filters using CTransformFilter from the baseclasses I end up implementing a lot more methods than just the pure virtuals. Typically I'll write the pins as well and most of the CTranformFilter methods end up being useless stubs.
QUOTE
I think Ben Rudiak-Gould is responsible for this comment in Avisynth:

CODE

   // Prevent the graph from trying to run in "real time"
   // ... Disabled because it breaks ASF.  Now I know why
   // Avery swears so much.
I'd attribute that comment to IanB: I remember him mentioning the ASF splitter fails if you try and pull samples from it before the previous sample time has elapsed. Very nasty work.
There are some DSS builds out there that accidentally have the debugging code left in and can be very chatty. Good to know your fix will be able to shut them up as well.

 
     Top
phaeron
Posted: Jan 11 2008, 06:56 AM


Virtualdub Developer


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



Posted a new version. The CineForm problem turned out to be a really weird bug -- I was tracking formats incorrectly and it blew up because the CineForm HD decoder ONLY supports YUY2 decoding. The plugin now also parses the DirectShow extensions registry and so now it'll catch file formats. I still have to figure out a way to adapt the file signatures, though.

BTW, looks like both of the ffdshow issues have been fixed already... should show up in the next set of nightlies. Woohoo!
 
    Top
Gromozeka
Posted: Jan 11 2008, 11:39 AM


Unregistered









Phaeron, thanks you for yours directshow plugin, but viewing of the image bad - shows only the first the staff

[img=http://img142.imageshack.us/img142/5729/85714632gv2.th.jpg]

[img=http://img132.imageshack.us/img132/5066/81756516jo7.th.jpg]

P.S: When you realize a conclusion in a nested doll? cool.gif
 
  Top
IanB
  Posted: Jan 11 2008, 10:35 PM


Avisynth Team Member


Group: Members
Posts: 121
Member No.: 22295
Joined: 23-October 07



QUOTE
QUOTE
I think Ben Rudiak-Gould is responsible for this comment in Avisynth:
CODE
  // Prevent the graph from trying to run in "real time"
  // ... Disabled because it breaks ASF.  Now I know why
  // Avery swears so much.
I'd attribute that comment to IanB:
Not guilty, cool.gif I chased this comment back thru the CVS history and it is the initial checkin Richard did back in 2002, well before Sh0dan split out AVISource and DirectShowSource into separate modules.

avisynth2/avisynth/Attic/source.cpp,v revision 1.1
date: 2002/07/04 13:22:28; author: richardberg; state: Exp;
branches: 1.1.1;
Initial revision


Thanks for pointing out some of the many horror stories with directshow_source.cpp it needs all the help everyone can give it. rolleyes.gif

And any chance to sneek a peek at your source code for the driver. wink.gif
 
     Top
phaeron
Posted: Jan 12 2008, 12:55 AM


Virtualdub Developer


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



@Gromozeka:
There's something weird going on with this plugin and filter preview. I'll take a look into it.

@IanB:
http://www.virtualdub.org/beta/DShowInputD...ver-0.3-src.zip

It uses the system library from the bleeding edge 1.7.X source, so there's a chance it won't compile against the last 1.7.X test source I posted. If not, I'll post a new one.

Right now, I think Avisynth's DirectShowSource is generally more reliable than my plugin. I intend to narrow that gap as much as possible. smile.gif When I finally looked at the DSS source, though, I was surprised by how similar in architecture they turned out. I guess there aren't that many ways to pull samples out.
 
    Top
squid_80
Posted: Jan 12 2008, 03:18 PM


Advanced Member


Group: Members
Posts: 594
Member No.: 13813
Joined: 22-January 05



QUOTE (IanB @ Jan 12 2008, 08:35 AM)
Not guilty, cool.gif  I chased this comment back thru the CVS history and it is the initial checkin Richard did back in 2002, well before Sh0dan split out AVISource and DirectShowSource into separate modules.

Was I at least right about the ASF parser, or did I memory leak that as well?

Got something for both of you to puzzle over. The virtualdub-MKVOut build I whipped up (link) doesn't handle b-frames properly; output frames simply have consecutive timestamps so b-frame re-ordering means the output mkv files are bad. When they're played back with WMP or graphedit they appear jerky since the b-frames seem to get skipped. Same with Phaeron's directshow input plugin - the b-frames aren't there when a file is loaded, it just duplicates the p-frames. But surprisingly if the file is loaded through directshowsource, it comes up correct. All the individual frames are there (except for one or two at the end) and they're in the right order. Here's a sample file with frame numbers on the encoded frames to tell where they really belong.
So how is DSS getting it right and is this actually desirable behaviour?
 
     Top
IanB
Posted: Jan 12 2008, 09:00 PM


Avisynth Team Member


Group: Members
Posts: 121
Member No.: 22295
Joined: 23-October 07



@Phaeron,

Thanks for the source. Yes, implementing as a filter before the rendered is the way I would have done it to. biggrin.gif Man don't you just loath how much dross you have to write to just support the lousey environment DS is.

@Squid,

Yes I cursed Bill many times for the old ASF splitter timing behaviour, the current one doesn't seem to have the restriction but it now does not provide correct sample stop times, it just slackly returns start+1, Grrr!

As for the MKV, you may be tripping the "quality" callbacks from the real renderers. Theory goes if the renderer is getting behind it pokes a message back thru the chain saying "help, process faster, with less quality if necessary", implementation is component specific. I am guessing someone thinks dropping B frames might fit. Only a theory. unsure.gif

Do a run thru DSS with a logfile and logmask=2, to get the actual sample timestamps, do they make sense?
 
     Top
phaeron
Posted: Jan 12 2008, 10:33 PM


Virtualdub Developer


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



I don't implement IQualityControl, so all QC messages should be getting blocked before they reach the decoder.

The reason for the b-frame problem is that the ffdshow decoder is pushing out samples in decode order instead of presentation order, so the timestamps are out of order. WTF? Even the AVI Mux complains about this. The DirectShow input plugin then aborts and takes the next sample, assuming that there is a gap in the stream.

Update:
This is going to take longer than I'd thought. Turns out not only is ffdshow pushing out B-frames in reverse order -- which seems totally bogus to me -- but its output pin logic is also seriously screwy and whenever it connects to a filter other than Video Renderer or VMR7 it always overrides the allocator buffer count to 1 regardless of what I say in GetAllocatorRequirements(). This means I can't do a zero copy cache using samples and have to eat the cost of a full-frame memory copy. sad.gif


This post has been edited by phaeron on Jan 15 2008, 07:19 AM
 
    Top
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:
291 replies since Jan 10 2008, 05:09 AM Track this topic | Email this topic | Print this topic
Pages: (20) [1] 2 3 ... Last »
<< Back to VirtualDub Filters and Filter Development