Le 2014-08-24 15:18, Luca Barbato a écrit :
Feature matching x11grab.
---
configure | 11 +
libavdevice/Makefile | 1 +
libavdevice/alldevices.c | 1 +
libavdevice/xcbgrab.c | 646
+++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 659 insertions(+)
create mode 100644 libavdevice/xcbgrab.c
diff --git a/configure b/configure
index 22b699f..60aa3ca 100755
--- a/configure
+++ b/configure
@@ -213,6 +213,7 @@ External library support:
native MPEG-4/Xvid encoder exists [no]
--enable-openssl enable openssl [no]
--enable-x11grab enable X11 grabbing [no]
+ --enable-xcbgrab enable xcb grabbing [no]
--enable-zlib enable zlib [autodetect]
Toolchain options:
@@ -1172,6 +1173,7 @@ EXTERNAL_LIBRARY_LIST="
libxvid
openssl
x11grab
+ xcbgrab
zlib
"
@@ -1390,6 +1392,7 @@ HEADERS_LIST="
sys_param_h
sys_resource_h
sys_select_h
+ sys_shm_h
sys_soundcard_h
sys_time_h
sys_un_h
@@ -2093,6 +2096,7 @@ v4l2_indev_deps_any="linux_videodev2_h
sys_videoio_h"
vfwcap_indev_deps="capCreateCaptureWindow vfwcap_defines"
vfwcap_indev_extralibs="-lavicap32"
x11grab_indev_deps="x11grab XShmCreateImage"
+xcbgrab_indev_deps="xcbgrab"
# protocols
ffrtmpcrypt_protocol_deps="!librtmp_protocol"
@@ -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 &&
I don't see where you need that.
+require_pkg_config xcb-event xcb/xcb_event.h
xcb_event_get_error_label &&
I am not familiar with that one, but I don see where it's needed
either.
+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
diff --git a/libavdevice/xcbgrab.c b/libavdevice/xcbgrab.c
new file mode 100644
index 0000000..a671554
+static int xcbgrab_frame_shm(AVFormatContext *s, AVPacket *pkt)
+{
+ XCBGrabContext *g = s->priv_data;
+ xcb_shm_get_image_cookie_t iq;
+ xcb_shm_get_image_reply_t *img;
+ xcb_drawable_t drawable = g->screen->root;
+ uint8_t *data;
+ int size = g->frame_size + FF_INPUT_BUFFER_PADDING_SIZE;
+ int id = shmget(IPC_PRIVATE, size, IPC_CREAT | 0777);
+ xcb_generic_error_t *e = NULL;
+
+ if (id == -1) {
+ char errbuf[1024];
+ av_strerror(AVERROR(errno), errbuf, sizeof(errbuf));
+ av_log(s, AV_LOG_ERROR, "shmget %d failed: %s\n", size,
errbuf);
+ return AVERROR(ENOMEM);
+ }
+
+ xcb_shm_attach(g->conn, g->segment, id, 0);
+
+ iq = xcb_shm_get_image(g->conn, drawable,
+ g->x, g->y, g->width, g->height, ~0,
+ XCB_IMAGE_FORMAT_Z_PIXMAP, g->segment,
0);
+
+ 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);
Swapping the two calls above would spare one RTT.
+ xcb_flush(g->conn);
+
+ if (!img) {
+ shmctl(id, IPC_RMID, 0);
+ return AVERROR(ENOMEM);
+ }
+ free(img);
+
+
+ data = shmat(id, NULL, 0);
+ shmctl(id, IPC_RMID, 0);
+
+ if ((intptr_t)data == -1)
+ return AVERROR(ENOMEM);
+
+ pkt->buf = av_buffer_create(data, size, dealloc_shm, NULL, 0);
+
+ if (!pkt->buf) {
+ shmdt(data);
+ return AVERROR(ENOMEM);
+ }
+
+ pkt->data = pkt->buf->data;
+ pkt->size = g->frame_size;
+
+ return 0;
+}
--
Rémi Denis-Courmont
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel