View Full Version : Writing a DirectShow filter, where to get started?
Adion
9th August 2006, 14:48
Hi,
I am trying to create my own AmbiLight for watching movies (determining the color of the movie and sending it to an external colored light)
It is currently working successfully by getting pixels from the Desktop handle, as long as the movie is not played using overlays.
Now I also want to be able to watch the movies on the tv out, so I have to use overlays.
What I was thinking of to solve this is to create a DirectShow filter that would be able to get the input video's data and process it. (A filter that loads in the same way as VobSub would be excellent)
The problem is that I can't seem to find much information or maybe a very simple example that gets me the pixel data to get started with.
I have already downloaded the DirectX SDK, and there are some DirectShow examples, but when I tried to compile them, it didn't work since it required strmbasd.lib, which it could not find.
I then found how to compile this lib from the Platform SDK, but when I copy the lib to the path expected by the DirectShow examples, I get new linker errors.
Inc
10th August 2006, 13:36
The MSDN is your Friend:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directshow/htm/writingdirectshowfilters.asp
Nic
10th August 2006, 14:19
(and strmbase.lib is built by building the Samples\C++\DirectShow\BaseClasses project)
Adion
10th August 2006, 19:54
Thanks. I hadn't noticed there was simply a solution file in the BaseClasses folder.
Compiling it directly from there appeared to work, and I could now compile the directshow filter examples as well.
I even managed to use the the 'ezrgb24' example filter from within GraphEdit.
I didn't have any success yet adding this filter to Media Player Classic though. (I added it to the External Filters, and set it to 'Prefer', but it didn't show up)
I noticed that Graphedit automatically added a colour space convertor when I connected it to the output though, so maybe it will only get added automatically if input and output image formats are the same?
I'm also wondering if this means that you should write a common filter (such as vobsub for example) to support all formats, or that there is another way to handle this. I guess I still have a lot of reading to do...
Adion
13th August 2006, 13:54
I tried some more with GraphEdit, also been reading a bit on MSDN, but I'm still having problems getting it to work correctly and understanding what is happening.
I am now able to compile the example filter, install it, and add it either through graphedit or by adding it as an external filter to Media Player Classic.
The problem is though that it only works correctly on some movies, and not on others (mplayerc crashes in ffdshow.ax on these movies).
On another PC, no files make mplayerc crash, but all movies look wrong (green) which I think means that there's something wrong somewhere with the colour space being used.
As far as I can see from the example's source code, it would only succeed in connecting when both input and output support rgb24.
On the pc where the image is green/incorrect colour space, the graph when playing through mplayerc looks like this:
AVI -> DivX Decoder Filter -> Image Effects (this is the example filter I compiled) -> DirectVobSub (auto-loading version) -> AVI Decompressor -> Video Mixing Renderer 7
DivX outputs RGB24, DirectVobsub apparently converts this to YUY2 (subtitles also have wrong colors), and AVI Decompressor converts this to RGB32
On the pc where some movies work correctly, the graph with a correctly working movie looks like:
AVI -> AVI Splitter -> DivX Decoder Filter -> Image Effects -> ffdShow MPEG-4 Video Decoder -> DirectVobSub (auto-loading version) -> Video Renderer
DivX also outputs RGB24, ffdshow converts this to RGB565, and DirectVobSub also outputs RGB565.
I really don't understand why it crashes and why the colour conversions seem to be incorrect on one pc but not on the other.
So if anyone has any clues, I'd much appreciate it.
Edit: Small update: ffdshow will output YUY2 instead of RGB565 when working directly on the pc instead of over a remote desktop connection. The result is still the same though (it works on that pc on some files)
On the other pc, I now managed to get it working if I manually add a Color Space Converter between Image Effects and DirectVobSub, and then connect DirectVobSub directly to the renderer (without the AVI Decompressor)
Edit2: The computer that crashed on some files apparently had a very old version of ffdshow installed. Unregistering it to make sure that it didn't load now gives the same results as on the other pc (AVI Decompressor messes up colors, but adding a Color Space Convertor to mplayerc's prefered filters as well seems to give good results on all files)
So that still makes me wonder what I should do to make my filter work without having to manually add a color space convertor.
Sulik
13th August 2006, 18:39
Do your processing in YUY2 instead of RGB, it will avoid unnecessary colorspace conversions (DivX will output YUY2)
Inc
13th August 2006, 18:47
(DivX will output YUY2)DIVX,XVID,x264 = YV12
Adion
14th August 2006, 16:26
Ok, my main processing in RGB24 is working correctly now, but I still have some problems/questions.
1) Even though a conversion step is required when working in RGB24, I still don't understand why by default DirectShow doesn't appear to be able to find the correct connections, leading to the green image, and by manually adding the color space convertor it appears to be working fine.
The way the color space convertor is added by default even only makes it convert RGB24 to ARGB32, so it seems just some rgb formats are not very well supported.
2) Neither on MSDN or with Google I've been able to find much information about programming with YV12 color space, just some general info about what it is.
I found a description of how the data is formated on wikipedia (http://en.wikipedia.org/wiki/YUV_4:2:2) (YV12 = YUV 4:2:0 right?) but at first sight it doesn't really look easy to get the data for one pixel back together, so maybe there already are some processing functions available somewhere that make it easier to use YV12?
Adion
13th November 2006, 23:52
It has been a while, but it may be time for an update in case anyone else is looking for similar information.
I had quite some problems getting the filter to work in YV12 correctly, so I have used the filter in RGB lately, which probably makes it a bit slower, and makes it harder to install the filter (combinations of forcing DirectVobSub or ffdshow to output RGB, or adding a color space conversion to the external filters in mplayerc were necessary on different computers to get it working and get the colors right. Zooming in/out also produced some red/blue problems sometimes, probably due to bad resampling of the U and V planes by some filter)
Anyway, today I finally got the filter working in YV12.
Basically, it's just the Y plane first (width x height bytes), then the V plane (width x height / 4 bytes) and finally the U plane.
On this other wikipedia article about YV12 (http://en.wikipedia.org/wiki/YV12) it appears that they have switched U and V around. I'm not sure if the article is just wrong, or if there are situations where they are actually swapped.
Then, since I needed RGB data from some of the pixels, I had to convert from YUV to RGB, which seems another non-trivial task.
I found this page (http://www.fourcc.org/fccyvrgb.php), but neither of the functions produced correct results when directly applied to the Y, U and V bytes (maybe they expect a different input scale or something, but it doesn't appear to be explained clearly)
Finally I found the YV12 article on wikipedia, which has an integer function for converting to RGB, which appears to be giving me the expected results.
foxyshadis
14th November 2006, 01:10
YV12 = YVU, NV12 = YUV. NV12 is typically only used on nvidia cards that don't like YV12.
For speedy conversion of a buffer from YUY2<->RGB, you can also use avisynth or virtualdub sources. (I'm not sure if vdub has one-step YV12->RGB, but avisynth doesn't.) However, if it just works, that might not be worth messing with further. :p
Adion
14th November 2006, 10:36
Thanks for the info. Since I only need to get the average color of a frame, I currently only process 1/100th of the pixels, so I don't need to convert a full frame to rgb.
movax
14th November 2006, 16:03
You might not wanna hear this (I hate hearing that my work has already been done by someone else usually), but a few months ago, someone did this on Hack-A-Day (hey, if you're the same guy...kick-ass job, btw.), complete with DShow filter to do pretty much exactly what you described.
But yeah, DShow is like...uh...dunno, a steaming quagmire of code that only dried, soul-less husks of human beings return from. But enough about me-er, that.
Adion
14th November 2006, 16:17
Nope, that wasn't me.
My idea actually started while working on a bigger project of mine, named lightDecks (http://light.djdecks.be) to control disco-lighting.
Since I already had the hardware (usb interface and controllable led lights) and my own software to control it, the ambilight idea was not that for off.
For me it seems to work better than the original implementation Philips made. Where the original ambilight seems to be mainly background lighting (slow color fades only, never completely dark), mine is really getting you more into the experience (lightning/explosions that really brighten up the room, cool green colors in the jungle, beatiful blue skies on the beach :) )
I'll see if I can make some pictures or a small movie showing it :)
Adion
21st November 2006, 22:45
Ok, it seemed I was a bit early saying that everything is ok...
Most movies play perfectly now, but some give very strange results when used in overlay mode.
According to mplayerc the in/out mode of my filter is YV12, as with other movies that do work correctly.
If I set mplayerc not to use the overlay mixer, then all files play fine.
I've made a picture of how it looks like with my webcam, if anyone has any ideas what this could be, and how I could solve it that would be great.
http://adion.djdecks.be/images/overlay.png
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.