⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 x11grab.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 2 页
字号:
        }        *x = -1;        *y = -1;    }}/** * Mouse painting helper function that applies an 'and' and 'or' mask pair to * '*dst' pixel. It actually draws a mouse pointer pixel to grabbed frame. * * @param dst Destination pixel * @param and Part of the mask that must be applied using a bitwise 'and' *            operator * @param or  Part of the mask that must be applied using a bitwise 'or' *            operator * @param bits_per_pixel Bits per pixel used in the grabbed image */static void inlineapply_masks(uint8_t *dst, int and, int or, int bits_per_pixel){    switch (bits_per_pixel) {    case 32:        *(uint32_t*)dst = (*(uint32_t*)dst & and) | or;        break;    case 16:        *(uint16_t*)dst = (*(uint16_t*)dst & and) | or;        break;    case 8:        *dst = !!or;        break;    }}/** * Paints a mouse pointer in an X11 image. * * @param image Image where to paint the mouse pointer * @param s context used to retrieve original grabbing rectangle *          coordinates * @param x Mouse pointer coordinate * @param y Mouse pointer coordinate */static voidpaint_mouse_pointer(XImage *image, x11_grab_t *s, int x, int y){    /* 16x20x1bpp bitmap for the black channel of the mouse pointer */    static const uint16_t const mousePointerBlack[] =        {            0x0000, 0x0003, 0x0005, 0x0009, 0x0011,            0x0021, 0x0041, 0x0081, 0x0101, 0x0201,            0x03c1, 0x0049, 0x0095, 0x0093, 0x0120,            0x0120, 0x0240, 0x0240, 0x0380, 0x0000        };    /* 16x20x1bpp bitmap for the white channel of the mouse pointer */    static const uint16_t const mousePointerWhite[] =        {            0x0000, 0x0000, 0x0002, 0x0006, 0x000e,            0x001e, 0x003e, 0x007e, 0x00fe, 0x01fe,            0x003e, 0x0036, 0x0062, 0x0060, 0x00c0,            0x00c0, 0x0180, 0x0180, 0x0000, 0x0000        };    int x_off = s->x_off;    int y_off = s->y_off;    int width = s->width;    int height = s->height;    if (   x - x_off >= 0 && x < width + x_off        && y - y_off >= 0 && y < height + y_off) {        uint8_t *im_data = (uint8_t*)image->data;        int bytes_per_pixel;        int line;        int masks;        /* Select correct masks and pixel size */        if (image->bits_per_pixel == 8) {            masks = 1;        } else {            masks = (image->red_mask|image->green_mask|image->blue_mask);        }        bytes_per_pixel = image->bits_per_pixel>>3;        /* Shift to right line */        im_data += image->bytes_per_line * (y - y_off);        /* Shift to right pixel in the line */        im_data += bytes_per_pixel * (x - x_off);        /* Draw the cursor - proper loop */        for (line = 0; line < FFMIN(20, (y_off + height) - y); line++) {            uint8_t *cursor = im_data;            int column;            uint16_t bm_b;            uint16_t bm_w;            bm_b = mousePointerBlack[line];            bm_w = mousePointerWhite[line];            for (column = 0; column < FFMIN(16, (x_off + width) - x); column++) {                apply_masks(cursor, ~(masks*(bm_b&1)), masks*(bm_w&1),                            image->bits_per_pixel);                cursor += bytes_per_pixel;                bm_b >>= 1;                bm_w >>= 1;            }            im_data += image->bytes_per_line;        }    }}/** * Reads new data in the image structure. * * @param dpy X11 display to grab from * @param d * @param image Image where the grab will be put * @param x Top-Left grabbing rectangle horizontal coordinate * @param y Top-Left grabbing rectangle vertical coordinate * @return 0 if error, !0 if successful */static intxget_zpixmap(Display *dpy, Drawable d, XImage *image, int x, int y){    xGetImageReply rep;    xGetImageReq *req;    long nbytes;    if (!image) {        return 0;    }    LockDisplay(dpy);    GetReq(GetImage, req);    /* First set up the standard stuff in the request */    req->drawable = d;    req->x = x;    req->y = y;    req->width = image->width;    req->height = image->height;    req->planeMask = (unsigned int)AllPlanes;    req->format = ZPixmap;    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.length) {        UnlockDisplay(dpy);        SyncHandle();        return 0;    }    nbytes = (long)rep.length << 2;    _XReadPad(dpy, image->data, nbytes);    UnlockDisplay(dpy);    SyncHandle();    return 1;}/** * Grabs a frame from x11 (public device demuxer API). * * @param s1 Context from avformat core * @param pkt Packet holding the brabbed frame * @return frame size in bytes */static intx11grab_read_packet(AVFormatContext *s1, AVPacket *pkt){    x11_grab_t *s = s1->priv_data;    Display *dpy = s->dpy;    XImage *image = s->image;    int x_off = s->x_off;    int y_off = s->y_off;    int64_t curtime, delay;    struct timespec ts;    /* Calculate the time of the next frame */    s->time_frame += INT64_C(1000000);    /* wait based on the frame rate */    for(;;) {        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_frame += INT64_C(1000000);            }            break;        }        ts.tv_sec = delay / 1000000;        ts.tv_nsec = (delay % 1000000) * 1000;        nanosleep(&ts, NULL);    }    if (av_new_packet(pkt, s->frame_size) < 0) {        return AVERROR(EIO);    }    pkt->pts = curtime;    if(s->use_shm) {        if (!XShmGetImage(dpy, RootWindow(dpy, DefaultScreen(dpy)), image, x_off, y_off, AllPlanes)) {            av_log (s1, AV_LOG_INFO, "XShmGetImage() failed\n");        }    } else {        if (!xget_zpixmap(dpy, RootWindow(dpy, DefaultScreen(dpy)), image, x_off, y_off)) {            av_log (s1, AV_LOG_INFO, "XGetZPixmap() failed\n");        }    }    {        int pointer_x, pointer_y;        get_pointer_coordinates(&pointer_x, &pointer_y, dpy, s1);        paint_mouse_pointer(image, s, pointer_x, pointer_y);    }    /* XXX: avoid memcpy */    memcpy(pkt->data, image->data, s->frame_size);    return s->frame_size;}/** * Closes x11 frame grabber (public device demuxer API). * * @param s1 Context from avformat core * @return 0 success, !0 failure */static intx11grab_read_close(AVFormatContext *s1){    x11_grab_t *x11grab = s1->priv_data;    /* Detach cleanly from shared mem */    if (x11grab->use_shm) {        XShmDetach(x11grab->dpy, &x11grab->shminfo);        shmdt(x11grab->shminfo.shmaddr);        shmctl(x11grab->shminfo.shmid, IPC_RMID, NULL);    }    /* Destroy X11 image */    if (x11grab->image) {        XDestroyImage(x11grab->image);        x11grab->image = NULL;    }    /* Free X11 display */    XCloseDisplay(x11grab->dpy);    return 0;}/** x11 grabber device demuxer declaration */AVInputFormat x11_grab_device_demuxer ={    "x11grab",    "X11grab",    sizeof(x11_grab_t),    NULL,    x11grab_read_header,    x11grab_read_packet,    x11grab_read_close,    .flags = AVFMT_NOFILE,};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -