Re: Not understanding some issue in DirectShow
- From: Jamie Faye Fenton <jamiefaye@xxxxxxxxx>
- Date: Fri, 3 Oct 2008 09:45:10 -0700 (PDT)
On Oct 3, 8:51 am, Loren Rogers <loren.rog...@xxxxxxxxx> wrote:
Hey gang,
I've written a CTransformFilter-inherited filter that sits in between
a USB vid cap device and the Default Vid Renderer. My input filter
format is YUY2, 320x240. My filter output pin format seems to be
512x240 YUY2. So I calculate a stride in MyFilter::GetMediaType and
reset the bitmap info header (stride is 640). Now what I am seeing
is this:
In my renderer window I see 2 of the same perfectly clear images on
the top half of the window, and green on the bottom half. I have no
clue what is going on here, but if I take my filter out and just
connect capture to renderer 320x240 YUY2 I don't have any problems.
I'm using DirectX 9.0c. Thanks for your help
/Loren
It is pretty common for video display hardware to "round upward" the
width of a surface to the next-higher power of two, and to hand-you-
back a bitmap with a stride that is greater than that of your image.
( |Stride| >= Image Width, but it can have the opposite sign ).
Sometimes you can go farther than that, and pack a second image into
the left-over space, and reclaim the wasted capacity. Or you can set
up the stride sizes and directions to pack 4 images, each from a
security camera, into one 2x2 arrangement for recording.
My guess is that your case, which spoofs the system into thinking your
bitmap is twice as wide, shows two versions side by side, where each
one is "every other" scan line, and the green image could be part of
the surface following, a Z buffer, or possibly a wrap-around effect.
The fact that they appear to be correctly proportioned is because the
horizontal doubling causes a vertical halving.
If this doesn't sound like an explanation, post more detail data such
as the media type details from the property pages, and a code snippet
and chances are some of the MVPs around here can chime in.
There is a standard routine people use for figuring this stuff out. I
have attached a copy. The original came from Mark Russinovich and
Bryce Cogswell's www.sysinternals.com web site.
-- Jamie
//----------------------------------------------------------------------------
// GetVideoInfoParameters
//
// Helper function to get the important information out of a
VIDEOINFOHEADER
//
//-----------------------------------------------------------------------------
void GetVideoInfoParameters(
const VIDEOINFOHEADER *pvih, // Pointer to the format header.
BYTE * const pbData, // Pointer to the first address in the
buffer.
DWORD *pdwWidth, // Returns the width in pixels.
DWORD *pdwHeight, // Returns the height in pixels.
LONG *plStrideInBytes, // Add this to a row to get the new row
down
BYTE **ppbTop, // Returns pointer to the first byte in the top
row of pixels.
bool bYuv
)
{
LONG lStride;
// For 'normal' formats, biWidth is in pixels.
// Expand to bytes and round up to a multiple of 4.
if (pvih->bmiHeader.biBitCount != 0 &&
0 == (7 & pvih->bmiHeader.biBitCount))
{
lStride = (pvih->bmiHeader.biWidth * (pvih-
bmiHeader.biBitCount / 8) + 3) & ~3;}
else // Otherwise, biWidth is in bytes.
{
lStride = pvih->bmiHeader.biWidth;
}
// If rcTarget is empty, use the whole image.
if (IsRectEmpty(&pvih->rcTarget))
{
*pdwWidth = (DWORD)pvih->bmiHeader.biWidth;
*pdwHeight = (DWORD)(abs(pvih->bmiHeader.biHeight));
if (pvih->bmiHeader.biHeight < 0 || bYuv) // Top-down
bitmap.
{
*plStrideInBytes = lStride; // Stride goes "down"
*ppbTop = pbData; // Top row is first.
}
else // Bottom-up bitmap
{
*plStrideInBytes = -lStride; // Stride goes "up"
*ppbTop = pbData + lStride * (*pdwHeight - 1); // Bottom
row is first.
}
}
else // rcTarget is NOT empty. Use a sub-rectangle in the image.
{
*pdwWidth = (DWORD)(pvih->rcTarget.right - pvih-
rcTarget.left);*pdwHeight = (DWORD)(pvih->rcTarget.bottom - pvih-
rcTarget.top);
if (pvih->bmiHeader.biHeight < 0 || bYuv) // Top-down
bitmap.
{
// Same stride as above, but first pixel is modified down
// and and over by the target rectangle.
*plStrideInBytes = lStride;
*ppbTop = pbData +
lStride * pvih->rcTarget.top +
(pvih->bmiHeader.biBitCount * pvih-
rcTarget.left) / 8;}
else // Bottom-up bitmap.
{
*plStrideInBytes = -lStride;
*ppbTop = pbData +
lStride * (pvih->bmiHeader.biHeight - pvih-
rcTarget.top - 1) +(pvih->bmiHeader.biBitCount * pvih-
rcTarget.left) / 8;}
}
}
.
- Follow-Ups:
- Re: Not understanding some issue in DirectShow
- From: Loren Rogers
- Re: Not understanding some issue in DirectShow
- References:
- Not understanding some issue in DirectShow
- From: Loren Rogers
- Not understanding some issue in DirectShow
- Prev by Date: Re: Video frame resizing and the IPP libraries
- Next by Date: Re: Video capture XPE problems
- Previous by thread: Not understanding some issue in DirectShow
- Next by thread: Re: Not understanding some issue in DirectShow
- Index(es):
Relevant Pages
|