[FFmpeg-devel] [PATCH] Screen frame grabbing for Win32 platform (bump)

Ramiro Polla ramiro.polla
Thu Mar 25 17:14:15 CET 2010


On Tue, Mar 23, 2010 at 10:07 PM, Christophe Gisquet
<christophe.gisquet at gmail.com> wrote:
> 2010/3/24 Christophe Gisquet <christophe.gisquet at gmail.com>:
>> Best regards,
>> Kurosu
>
> Patch missing again... Third time's a charm?

I'll give a more thorough review during the weekend, but here are some
more issues you can work on in the meantime =)

[...]
> +/**
> + * Paints a mouse pointer in a Win32 image.
> + *
> + * @param s1 Context of the log information
> + * @param s  Current grad structure
> + */
> +static void paint_mouse_pointer(AVFormatContext *s1, gdi_grab *s)
> +{
> +    CURSORINFO ci;
> +
> +#define CURSOR_ERROR(str)                 \
> +    if (!s->printed) {                    \
> +        WIN32_API_ERROR(str);             \
> +        s->printed = 1;                   \
> +    }
> +
> +    ci.cbSize = sizeof(ci);
> +
> +    if (GetCursorInfo(&ci) && ci.flags == CURSOR_SHOWING) {
> +        HICON     icon = CopyIcon(ci.hCursor);
> +        ICONINFO  info;
> +        if(GetIconInfo(icon, &info)) {
> +            long int x = ci.ptScreenPos.x - info.xHotspot;
> +            long int y = ci.ptScreenPos.y - info.yHotspot;
> +
> +            if (s->window_handle) {
> +                RECT rect;
> +
> +                if (GetWindowRect(s->window_handle, &rect)) {
> +                    av_log(s1, AV_LOG_DEBUG, "Pos(%li,%li) -> (%li,%li)\n",
> +                           x, y, x - rect.left, y - rect.top);
> +                    x -= rect.left;
> +                    y -= rect.top;
> +                } else {
> +                    CURSOR_ERROR("Couldn't get icon rectangle");
> +                }
> +            }
> +
> +            if (!DrawIcon(s->window_hdc, x, y, icon))
> +                CURSOR_ERROR("Couldn't draw icon");
> +        } else {
> +            CURSOR_ERROR("Couldn't get cursor info");
> +        }
> +
> +        DestroyIcon(icon);
> +    } else {
> +        CURSOR_ERROR("Cursor not showing?");
> +    }
> +}

There's something wrong with the cursor position being calculated
here. Try opening an explorer window and capturing "title=Program
Files" or something similar. The cursor is off by some pixels.

> +/**
> + * Grabs a frame from gdi (public device demuxer API).
> + *
> + * @param s1 Context from avformat core
> + * @param pkt Packet holding the grabbed frame
> + * @return frame size in bytes
> + */
> +static int gdigrab_read_packet(AVFormatContext *s1, AVPacket *pkt)
> +{
> +    gdi_grab *s = s1->priv_data;
> +    int64_t    curtime, delay;
> +
> +    /* Calculate the time of the next frame */
> +    s->time_frame += INT64_C(1000000);
> +
> +    /* wait based on the frame rate */
> +    while (1) {
> +        curtime = av_gettime();
> +        delay = s->time_frame * av_q2d(s->time_base) - curtime;
> +        if (delay <= 0) {
> +            if (delay < INT64_C(-1000000) * av_q2d(s->time_base)) {

s->time_base is no longer being set in read_header. This leads to no
Sleep ever. For some strange reason, after 9990 frames being captured
this way (really quick), the call to GetCursorInfo() in the previous
function starts failing.

> +                s->time_frame += INT64_C(1000000);
> +            }
> +            break;
> +        }
> +        if (s1->flags & AVFMT_FLAG_NONBLOCK)
> +            return AVERROR(EAGAIN);
> +        else
> +            Sleep(delay/1000);
> +    }
[...]



More information about the ffmpeg-devel mailing list