rendered paste body--- libavformat/x11grab.c 2006-12-13 00:45:16.000000000 +0100+++ libavformat/x11grab.c 2006-12-13 00:55:24.000000000 +0100@@ -361,122 +361,156 @@ }-/*- * just read new data in the image structure, the image- * structure inclusive the data area must be allocated before+/**+ * 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 int-XGetZPixmap(Display *dpy, Drawable d, XImage *image, int x, int y)+xget_zpixmap(Display *dpy, Drawable d, XImage *image, int x, int y) {- xGetImageReply rep;- xGetImageReq *req;- long nbytes;-- if (!image)- return (False);- 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 = AllPlanes;- req->format = ZPixmap;-- if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == 0 ||- rep.length == 0) {+ 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 (False);- }-- nbytes = (long)rep.length << 2;- _XReadPad(dpy, image->data, nbytes);-- UnlockDisplay(dpy);- SyncHandle();- return (True);+ 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 int x11grab_read_packet(AVFormatContext *s1, AVPacket *pkt) {- X11Grab *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_t_C(1000000);-- /* wait based on the frame rate */- for(;;) {- curtime = av_gettime();- delay = s->time_frame * s->frame_rate_base / s->frame_rate - curtime;- if (delay <= 0) {- if (delay < int64_t_C(-1000000) * s->frame_rate_base / s->frame_rate) {- /* printf("grabbing is %d frames late (dropping)\n", (int) -(delay / 16666)); */- s->time_frame += int64_t_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_IO;-- pkt->pts = curtime & ((1LL << 48) - 1);-- if(s->use_shm) {- if (!XShmGetImage(dpy,- RootWindow(dpy, DefaultScreen(dpy)),- image, x_off, y_off, AllPlanes)) {- fprintf(stderr,"XShmGetImage() failed\n");- }- }- else {- XGetZPixmap(dpy,- RootWindow(dpy, DefaultScreen(dpy)),- image, x_off, y_off);- };- {- int pointer_x, pointer_y;- getCurrentPointer(s, &pointer_x, &pointer_y);- paintMousePointer(s, &pointer_x, &pointer_y, image);- }--#warning FIXME - avoid memcpy- memcpy(pkt->data, image->data, s->frame_size);- return s->frame_size;+ 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_t_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_t_C(-1000000) * av_q2d(s->time_base)) {+ s->time_frame += int64_t_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_IO;+ }++ 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 int x11grab_read_close(AVFormatContext *s1) {- X11Grab *x11grab = s1->priv_data;-- XCloseDisplay(x11grab->dpy);- return 0;+ 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; }-AVInputFormat x11_grab_device_demuxer = {- "x11grab",- "X11grab",- sizeof(X11Grab),- NULL,- x11grab_read_header,- x11grab_read_packet,- x11grab_read_close,- .flags = AVFMT_NOFILE,+/** 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, };