Directshow: YUY2 output does not work with Video Renderer filter

I have a basic avstream driver (based on the avshws sample).

When testing the YUY2 output I get different results based on which renderer I use:

Video Renderer: blank image
VMR-7: scrambled image (due to the renderer using a buffer with a larger stride)
VMR-9: perfect render

I dont know why the basic video renderer (used by amcap) wont work. I have examined the graph of a webcam outputting the same format and I cannot see any difference apart from the renderer output.

On Jan 20, 2015, at 7:59 PM, xxxxx@gmail.com wrote:

I have a basic avstream driver (based on the avshws sample).

When testing the YUY2 output I get different results based on which renderer I use:

Video Renderer: blank image
VMR-7: scrambled image (due to the renderer using a buffer with a larger stride)
VMR-9: perfect render

I dont know why the basic video renderer (used by amcap) wont work. I have examined the graph of a webcam outputting the same format and I cannot see any difference apart from the renderer output.

It’s quite possible that you do not have a YUY2 decoder on your system. Windows doesn’t ship with one. VMR7 uses an overlay, and VMR9 uses a 3D texture, both of which commonly support YUY2. The base Video Renderer has to use software decoding.

BTW, it is YOUR responsibility to handle the stride change in VMR7. VMR7 doesn’t commit to the overlay surface until the first (poster) frame is displayed. Only at that point does it know what the hardware’s stride will be. It sends you a new format after you are already running, and you are REQUIRED to accept it. It doesn’t even check the return code; even if you return an error, it still uses the new stride.

Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

>It?s quite possible that you do not have a YUY2 decoder on your system.

A filter called AVI Decompressor gets inserted in between which converts from YUY2 to RGB32. This works for another webcam I have.

Unmodified avshws code works with YUY2 and Video Renderer. It stopped working after I removed the scatter/gather and DMA stuff. I changed it so that the pin process dispatch just returns STATUS_PENDING, and when the fake hardware timer fires it fills out a pending video buffer and restarts processing (KsPinGetLeadingEdgeStreamPointer, copy memory, KsStreamPointerUnlock(eject=true), KsPinAttemptProcessing). This works in RGB24 mode but not YUY2…

BTW, it is YOUR responsibility to handle the stride change in VMR7

I see the extra calls to SetFormat, they have a larger width and a negative height value (512 x -240 instead of 320 x 240). I think I just need to fill out the first 320 pixels of the 512 length line, do I render bottom up if the height is negative?

Thanks for the feedback Tim.

I have figured out the problem. I was missing one line to update the
remaining bytes in the stream pointer structure:

Leading->OffsetOut.Remaining = 0;

This caused certain filters to drop my samples (AVI/MJPEG Decompressor,
Dump) which meant that certain graph configurations would simply not render
anything.

I got a clue to add this line by reading some advice that Tim had given to
another user so thanks Tim! =)

xxxxx@gmail.com wrote:

> BTW, it is YOUR responsibility to handle the stride change in VMR7
I see the extra calls to SetFormat, they have a larger width and a negative height value (512 x -240 instead of 320 x 240). I think I just need to fill out the first 320 pixels of the 512 length line, do I render bottom up if the height is negative?

The only thing that will change is the stride, so yes, you render from
the left and ignore the rest.

A negative height means top-down rendering. A POSITIVE height means
bottom-up, although that convention is ignored for non-RGB formats.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.