On Sun, Aug 24, 2014 at 02:18:22PM +0200, Luca Barbato wrote:
> Feature matching x11grab.

Matches the x11grab screen capture by features.

IMO this thing should deprecate the x11grab screen capture.

> --- a/configure
> +++ b/configure
> @@ -4257,6 +4261,13 @@ require Xext X11/extensions/XShm.h XShmCreateImage 
> -lXext &&
>  require Xfixes X11/extensions/Xfixes.h XFixesGetCursorImage -lXfixes &&
>  { enabled xlib || die "ERROR: Xlib not found"; }
>  
> +enabled xcbgrab &&
> +require_pkg_config xcb-composite xcb/composite.h 
> xcb_composite_name_window_pixmap &&
> +require_pkg_config xcb-event xcb/xcb_event.h xcb_event_get_error_label &&
> +require_pkg_config xcb-xfixes xcb/xfixes.h xcb_xfixes_get_cursor_image &&
> +require_pkg_config xcb-shm xcb/shm.h xcb_shm_attach &&
> +check_header sys/shm.h
> +
>  enabled vdpau &&
>      check_cpp_condition vdpau/vdpau.h "defined 
> VDP_DECODER_PROFILE_MPEG4_PART2_ASP" ||
>      disable vdpau

Indent like the vdpau block below.

Do you really need to check all those things separately?  Do configurations
exist where one part is available w/o the others?

> --- /dev/null
> +++ b/libavdevice/xcbgrab.c
> @@ -0,0 +1,646 @@
> +/*
> + * XCB input
> + * Copyright (c) 2014 Luca Barbato <[email protected]>

nit: (C)

> +#include "config.h"
> +
> +#include <stdlib.h>
> +#include <xcb/xcb.h>
> +#include <xcb/composite.h>
> +#include <xcb/xcb_event.h>
> +#include <xcb/xfixes.h>
> +#if HAVE_SYS_SHM_H
> +# include <sys/shm.h>
> +# include <xcb/shm.h>
> +#endif

Does it work w/o the shm headers?

> +static const AVOption options[] = {
> +    { "video_size", "A string describing frame size, such as 640x480 or 
> hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = "vga"}, 0, 0, D },
> +    { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = 
> "ntsc"}, 0, 0, D },
> +    { "draw_mouse", "Draw the mouse pointer.", OFFSET(draw_mouse), 
> AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, D },
> +    { "follow_mouse", "Move the grabbing region when the mouse pointer 
> reaches within specified amount of pixels to the edge of region.",
> +      OFFSET(follow_mouse), AV_OPT_TYPE_INT, { .i64 = 0},  FOLLOW_CENTER, 
> INT_MAX, D, "follow_mouse" },
> +    { "centered", "Keep the mouse pointer at the center of grabbing region 
> when following.", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, INT_MIN, INT_MAX, D, 
> "follow_mouse" },
> +    { "show_region", "Show the grabbing region.", OFFSET(show_region), 
> AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D },
> +    { "region_border", "Set the region border thickness.", 
> OFFSET(region_border), AV_OPT_TYPE_INT, { .i64 = 3 }, 1, 128, D },
> +    { NULL },

spaces inside {}

> +    } else {
> +        int left   = x + f;
> +        int right  = x + w - f;
> +        int top    = y + f;
> +        int bottom = y + h + f;
> +        if (p_x > right) {
> +            x += p_x - right;
> +        } else if (p_x < left) {
> +            x -= left - p_x;
> +        }
> +        if (p_y > bottom) {
> +            y += p_y - bottom;
> +        } else if (p_y < top) {
> +            y -= top - p_y;
> +        }
> +    }

nit: extra {}

> +    g->x = FFMIN(FFMAX(0, x), geo->width - w);
> +    g->y = FFMIN(FFMAX(0, y), geo->height - h);

nit: align -

> +static int xcbgrab_frame(AVFormatContext *s, AVPacket *pkt)
> +{
> +    XCBGrabContext *g = s->priv_data;
> +    xcb_get_image_cookie_t iq;
> +    xcb_get_image_reply_t *img;
> +    xcb_drawable_t drawable = g->screen->root;
> +    uint8_t *data;
> +    int length;
> +
> +    iq  = xcb_get_image(g->conn, XCB_IMAGE_FORMAT_Z_PIXMAP, drawable,
> +                        g->x, g->y, g->width, g->height, ~0);
> +    img = xcb_get_image_reply(g->conn, iq, NULL);

You could merge declaration and initialization here.

> +    data    = xcb_get_image_data(img);
> +    length = xcb_get_image_data_length(img);

align

> +#if HAVE_SYS_SHM_H
> +static void dealloc_shm(void *unused, uint8_t *data)
> +{
> +    (void)unused;
> +
> +    shmdt(data);
> +}

Is there a warning w/o the void cast?

> +    img = xcb_shm_get_image_reply(g->conn, iq, &e);
> +    if (e)
> +        av_log(s, AV_LOG_ERROR,
> +               "event_error: %s: response_type:%u error_code:%u "
> +               "sequence:%u resource_id:%u minor_code:%u major_code:%u\n",
> +               xcb_event_get_error_label(e->error_code), e->response_type,
> +               e->error_code, e->sequence, e->resource_id, e->minor_code,
> +               e->major_code);
> +
> +    xcb_shm_detach(g->conn, g->segment);
> +    xcb_flush(g->conn);
> +
> +    if (!img) {
> +        shmctl(id, IPC_RMID, 0);
> +        return AVERROR(ENOMEM);
> +    }

Doing something before the out-of-memory check looks very odd and error-prone.

> +    data = shmat(id, NULL, 0);
> +    shmctl(id, IPC_RMID, 0);
> +
> +    if ((intptr_t)data == -1)
> +        return AVERROR(ENOMEM);

IIUC shmat can return all sorts of errors and sets errno accordingly.

> +    pkt->data = pkt->buf->data;
> +    pkt->size = g->frame_size;
> +
> +    return 0;
> +}
> +#endif

Please comment the #endif.

> +static int xcbgrab_draw_mouse(AVFormatContext *s, AVPacket *pkt,
> +                              xcb_query_pointer_reply_t *p,
> +                              xcb_get_geometry_reply_t *geo)
> +{
> +    XCBGrabContext *gr = s->priv_data;
> +    uint32_t *cursor   = NULL;
> +    uint8_t *image     = pkt->data;
> +    int stride         = gr->bpp / 8;
> +    xcb_xfixes_get_cursor_image_cookie_t cc;
> +    xcb_xfixes_get_cursor_image_reply_t *ci;
> +    int cx, cy, x, y, w, h, c_off, i_off;
> +
> +    cc = xcb_xfixes_get_cursor_image(gr->conn);
> +    ci = xcb_xfixes_get_cursor_image_reply(gr->conn, cc, NULL);
> +    cursor = xcb_xfixes_get_cursor_image_cursor_image(ci);

First you set cursor to NULL, then you set it again, redundantly.

> +        cursor += ci->width - w - c_off;
> +        image  += (gr->width - w - i_off) * stride;

nit: align more

> +static int xcbgrab_read_close(AVFormatContext *s)
> +{
> +    XCBGrabContext *g = s->priv_data;

c or ctx sounds like a better variable name.

> +static int pixfmt_from_pixmap_format(AVFormatContext *s, int depth)
> +{
> +    while (length--) {
> +        if (fmt->depth == depth) {
> +            g->bpp = fmt->bits_per_pixel;
> +            switch (depth) {
> +            case 32:
> +                if (fmt->bits_per_pixel == 32) {
> +                    g->frame_size *= 4;
> +                    return AV_PIX_FMT_ARGB;
> +                }
> +                break;
> +            case 24:
> +                if (fmt->bits_per_pixel == 32) {
> +                    g->frame_size *= 4;
> +                    return AV_PIX_FMT_RGB32;
> +                } else if (fmt->bits_per_pixel == 24) {
> +                    g->frame_size *= 3;
> +                    return AV_PIX_FMT_RGB24;
> +                }
> +                break;
> +            case 16:
> +                if (fmt->bits_per_pixel == 16) {
> +                    g->frame_size *= 2;
> +                    return AV_PIX_FMT_RGB565;
> +                }
> +                break;
> +            case 15:
> +                if (fmt->bits_per_pixel == 16) {
> +                    g->frame_size *= 2;
> +                    return AV_PIX_FMT_RGB555;
> +                }
> +                break;
> +            case 8:
> +                if (fmt->bits_per_pixel == 8)
> +                    return AV_PIX_FMT_RGB8;
> +            }
> +        }
> +        fmt++;
> +    }
> +    av_log(s, AV_LOG_ERROR, "Pixmap format not mappable\n");
> +
> +    return AVERROR_PATCHWELCOME;
> +}

I think it would be cleaner if you returned enum AVPixelFormat.

> +av_cold static int xcbgrab_read_header(AVFormatContext *s)

static av_cold

Diego
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to