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

📄 x11grab.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * X11 video grab interface * * This file is part of FFmpeg. * * FFmpeg integration: * Copyright (C) 2006 Clemens Fruhwirth <clemens@endorphin.org> *                    Edouard Gomez <ed.gomez@free.fr> * * This file contains code from grab.c: * Copyright (c) 2000-2001 Fabrice Bellard * * This file contains code from the xvidcap project: * Copyright (C) 1997-1998 Rasca, Berlin *               2003-2004 Karl H. Beckers, Frankfurt * * FFmpeg is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *//** * @file x11grab.c * X11 frame device demuxer by Clemens Fruhwirth <clemens@endorphin.org> * and Edouard Gomez <ed.gomez@free.fr>. */#include "avformat.h"#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <sys/time.h>#define _LINUX_TIME_H 1#include <time.h>#include <X11/X.h>#include <X11/Xlib.h>#include <X11/Xlibint.h>#include <X11/Xproto.h>#include <X11/Xutil.h>#include <sys/ipc.h>#include <sys/shm.h>#include <X11/extensions/XShm.h>/** * X11 Device Demuxer context */typedef struct x11_grab_s{    int frame_size;          /**< Size in bytes of a grabbed frame */    AVRational time_base;    /**< Time base */    int64_t time_frame;      /**< Current time */    int height;              /**< Height of the grab frame */    int width;               /**< Width of the grab frame */    int x_off;               /**< Horizontal top-left corner coordinate */    int y_off;               /**< Vertical top-left corner coordinate */    Display *dpy;            /**< X11 display from which x11grab grabs frames */    XImage *image;           /**< X11 image holding the grab */    int use_shm;             /**< !0 when using XShm extension */    XShmSegmentInfo shminfo; /**< When using XShm, keeps track of XShm infos */    int mouse_warning_shown;} x11_grab_t;/** * Initializes the x11 grab device demuxer (public device demuxer API). * * @param s1 Context from avformat core * @param ap Parameters from avformat core * @return <ul> *          <li>AVERROR(ENOMEM) no memory left</li> *          <li>AVERROR(EIO) other failure case</li> *          <li>0 success</li> *         </ul> */static intx11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap){    x11_grab_t *x11grab = s1->priv_data;    Display *dpy;    AVStream *st = NULL;    int input_pixfmt;    XImage *image;    int x_off = 0;    int y_off = 0;    int use_shm;    char *param, *offset;    param = av_strdup(s1->filename);    offset = strchr(param, '+');    if (offset) {        sscanf(offset, "%d,%d", &x_off, &y_off);        *offset= 0;    }    av_log(s1, AV_LOG_INFO, "device: %s -> display: %s x: %d y: %d width: %d height: %d\n", s1->filename, param, x_off, y_off, ap->width, ap->height);    dpy = XOpenDisplay(param);    if(!dpy) {        av_log(s1, AV_LOG_ERROR, "Could not open X display.\n");        return AVERROR(EIO);    }    if (!ap || ap->width <= 0 || ap->height <= 0 || ap->time_base.den <= 0) {        av_log(s1, AV_LOG_ERROR, "AVParameters don't have video size and/or rate. Use -s and -r.\n");        return AVERROR(EIO);    }    st = av_new_stream(s1, 0);    if (!st) {        return AVERROR(ENOMEM);    }    av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */    use_shm = XShmQueryExtension(dpy);    av_log(s1, AV_LOG_INFO, "shared memory extension %s found\n", use_shm ? "" : "not");    if(use_shm) {        int scr = XDefaultScreen(dpy);        image = XShmCreateImage(dpy,                                DefaultVisual(dpy, scr),                                DefaultDepth(dpy, scr),                                ZPixmap,                                NULL,                                &x11grab->shminfo,                                ap->width, ap->height);        x11grab->shminfo.shmid = shmget(IPC_PRIVATE,                                        image->bytes_per_line * image->height,                                        IPC_CREAT|0777);        if (x11grab->shminfo.shmid == -1) {            av_log(s1, AV_LOG_ERROR, "Fatal: Can't get shared memory!\n");            return AVERROR(ENOMEM);        }        x11grab->shminfo.shmaddr = image->data = shmat(x11grab->shminfo.shmid, 0, 0);        x11grab->shminfo.readOnly = False;        if (!XShmAttach(dpy, &x11grab->shminfo)) {            av_log(s1, AV_LOG_ERROR, "Fatal: Failed to attach shared memory!\n");            /* needs some better error subroutine :) */            return AVERROR(EIO);        }    } else {        image = XGetImage(dpy, RootWindow(dpy, DefaultScreen(dpy)),                          x_off,y_off,                          ap->width,ap->height,                          AllPlanes, ZPixmap);    }    switch (image->bits_per_pixel) {    case 8:        av_log (s1, AV_LOG_DEBUG, "8 bit palette\n");        input_pixfmt = PIX_FMT_PAL8;        break;    case 16:        if (       image->red_mask   == 0xf800 &&                   image->green_mask == 0x07e0 &&                   image->blue_mask  == 0x001f ) {            av_log (s1, AV_LOG_DEBUG, "16 bit RGB565\n");            input_pixfmt = PIX_FMT_RGB565;        } else if (image->red_mask   == 0x7c00 &&                   image->green_mask == 0x03e0 &&                   image->blue_mask  == 0x001f ) {            av_log(s1, AV_LOG_DEBUG, "16 bit RGB555\n");            input_pixfmt = PIX_FMT_RGB555;        } else {            av_log(s1, AV_LOG_ERROR, "RGB ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel);            av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask);            return AVERROR(EIO);        }        break;    case 24:        if (        image->red_mask   == 0xff0000 &&                    image->green_mask == 0x00ff00 &&                    image->blue_mask  == 0x0000ff ) {            input_pixfmt = PIX_FMT_BGR24;        } else if ( image->red_mask   == 0x0000ff &&                    image->green_mask == 0x00ff00 &&                    image->blue_mask  == 0xff0000 ) {            input_pixfmt = PIX_FMT_RGB24;        } else {            av_log(s1, AV_LOG_ERROR,"rgb ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel);            av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask);            return AVERROR(EIO);        }        break;    case 32:#if 0        GetColorInfo (image, &c_info);        if ( c_info.alpha_mask == 0xff000000 && image->green_mask == 0x0000ff00) {            /* byte order is relevant here, not endianness             * endianness is handled by avcodec, but atm no such thing             * as having ABGR, instead of ARGB in a word. Since we             * need this for Solaris/SPARC, but need to do the conversion             * for every frame we do it outside of this loop, cf. below             * this matches both ARGB32 and ABGR32 */            input_pixfmt = PIX_FMT_ARGB32;        }  else {            av_log(s1, AV_LOG_ERROR,"image depth %i not supported ... aborting\n", image->bits_per_pixel);            return AVERROR(EIO);        }#endif        input_pixfmt = PIX_FMT_RGB32;        break;    default:        av_log(s1, AV_LOG_ERROR, "image depth %i not supported ... aborting\n", image->bits_per_pixel);        return -1;    }    x11grab->frame_size = ap->width * ap->height * image->bits_per_pixel/8;    x11grab->dpy = dpy;    x11grab->width = ap->width;    x11grab->height = ap->height;    x11grab->time_base  = ap->time_base;    x11grab->time_frame = av_gettime() / av_q2d(ap->time_base);    x11grab->x_off = x_off;    x11grab->y_off = y_off;    x11grab->image = image;    x11grab->use_shm = use_shm;    x11grab->mouse_warning_shown = 0;    st->codec->codec_type = CODEC_TYPE_VIDEO;    st->codec->codec_id = CODEC_ID_RAWVIDEO;    st->codec->width = ap->width;    st->codec->height = ap->height;    st->codec->pix_fmt = input_pixfmt;    st->codec->time_base = ap->time_base;    st->codec->bit_rate = x11grab->frame_size * 1/av_q2d(ap->time_base) * 8;    return 0;}/** * Get pointer coordinates from X11. * * @param x Integer where horizontal coordinate will be returned * @param y Integer where vertical coordinate will be returned * @param dpy X11 display from where pointer coordinates are retrieved * @param s1 Context used for logging errors if necessary */static voidget_pointer_coordinates(int *x, int *y, Display *dpy, AVFormatContext *s1){    Window mrootwindow, childwindow;    int dummy;    mrootwindow = DefaultRootWindow(dpy);    if (XQueryPointer(dpy, mrootwindow, &mrootwindow, &childwindow,                      x, y, &dummy, &dummy, (unsigned int*)&dummy)) {    } else {        x11_grab_t *s = s1->priv_data;        if (!s->mouse_warning_shown) {            av_log(s1, AV_LOG_INFO, "couldn't find mouse pointer\n");            s->mouse_warning_shown = 1;

⌨️ 快捷键说明

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