[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