Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Questions about PRIMARYSURFACE screen capture with DirectDraw

95 views
Skip to first unread message

Infinitesimal

unread,
Oct 2, 2007, 5:31:10 PM10/2/07
to
I've implemented a screen capture function using DirectDraw which
obtains the video memory pointer by locking the primary surface (code
below) and I have some questions regarding the behaviour I am seeing.

First off, the memcpy that I am doing to move data off the surface's
data pointer is pretty slow -- a 1280x800 memcpy takes nearly 600ms.
Even a 300x300 window takes at least 100ms. Compared to GDI-based
bitblt this is very slow and compared to a standard memcpy is
painful....

Question: Is this due to my video hardware ? What is the memory
model of this operation ?

Another puzzle is that many different media player's (some Windows
Media Player content and other players like VNC) content still comes
up black. I had thought that by using the primary surface based
capture I was getting a hold of the direct video memory that the
screen is drawn on to before being painted by the video hardware.
Clearly I am missing something.

Question: What is the model for video sources and windows being
painted on the desktop and displayed via the video card ? Is there
actually a final video memory buffer that contains all of this that I
can get a pointer to somehow ? If so is it reasonably efficient ?

A kind of related oddity is a failure trying to capture a "magnifier"
type of control. Its a pretty simple GDI based control that creates a
window with the WS_EX_TOPMOST style. With the GDI-based method I
ended up having to enumerate through all the windows with this style
and blit it over the desktop screenshot in order to capture it
properly. Unfortunately I am seeing the same issue with the DirectDraw
approach in that its not appearing in the data copied from the primary
surface.

Again -- This behaviour suggests that the primary surface buffer isn't
a final video buffer that the desktop is being drawn into before
display... so what's the model and what am I missing ?

Thanks!

Code:

LPDIRECTDRAW7 lpDD;
LPDIRECTDRAWSURFACE7 lpDDSPrimary;

DirectDrawCreateEx(NULL, (LPVOID*)&lpDD, IID_IDirectDraw7, NULL);

lpDD->SetCooperativeLevel(NULL, DDSCL_NORMAL);

DDSURFACEDESC2 ddsd;
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);

lpDDSPrimary->Lock(NULL, &ddsd, DDLOCK_READONLY, NULL);

// memcpy the data from 'ddsd.lpSurface'

lpDDSPrimary->Unlock(NULL);

Michel Roujansky - DirectShow Consultant and Trainer

unread,
Oct 7, 2007, 9:18:05 PM10/7/07
to
On Oct 2, 11:31 pm, Infinitesimal <fire.w...@gmail.com> wrote:
> Question: Is this due to my video hardware ? What is the memory
> model of this operation ?

I am not a specialist on DirectDraw (so I only answer part of your
question), but my experience wiht D3D is similar. This is caused by
older hardware limiting the read access to video memory.
You should be able to get the same performance as GDI capture by
copying your primary surface to an offscreen surface and then doing
the memcopy from this offscreen surface. This is much faster than
direct memcopy from the primary surface.

> Question: What is the model for video sources and windows being
> painted on the desktop and displayed via the video card ? Is there
> actually a final video memory buffer that contains all of this that I
> can get a pointer to somehow ? If so is it reasonably efficient ?

You are definitely not going to capture D3D surfaces (typically used
by WMP anbd other tools that use the VMR9 for rendering).

0 new messages