On Sun, Dec 15, 2024 at 09:34:04PM +0100, Matthieu Herrb wrote:
> Hi,
> 
> similarly to the mplayer patches I sent earlier, here is an
> implementation of XShm 1.2 for mpv when using x11 or xv backends.
> Note that the vaapi driver, available on supported platforms, doesn't
> make use of XShm and won't see any change.

Ping, patch rebased to 0.39.0:
The mplayer patch is now commited.

Index: Makefile
===================================================================
RCS file: /local/cvs/ports/multimedia/mpv/Makefile,v
diff -u -p -u -r1.106 Makefile
--- Makefile    10 Feb 2025 15:39:21 -0000      1.106
+++ Makefile    19 Feb 2025 06:16:33 -0000
@@ -19,6 +19,7 @@ WANTLIB += Xss Xv archive ass avcodec av
 WANTLIB += avutil bluray c cdio cdio_cdda cdio_paranoia drm dvdnav
 WANTLIB += iconv jpeg lcms2 m placebo pthread sndio swresample
 WANTLIB += swscale va va-drm va-x11 vulkan z zimg
+WANTLIB += X11-xcb xcb xcb-shm
 
 MODULES =              devel/meson \
                        lang/lua \
Index: patches/patch-meson_build
===================================================================
RCS file: /local/cvs/ports/multimedia/mpv/patches/patch-meson_build,v
diff -u -p -u -r1.10 patch-meson_build
--- patches/patch-meson_build   10 Feb 2025 15:39:21 -0000      1.10
+++ patches/patch-meson_build   19 Feb 2025 06:16:33 -0000
@@ -1,5 +1,6 @@
 fix over-zealous detection of libatomic (it was picked up at configure
 time if present at all, rather than only if needed)
+Support for xcb-shm
 
 Index: meson.build
 --- meson.build.orig
@@ -25,3 +26,15 @@ Index: meson.build
  
  cplugins = get_option('cplugins').require(
      win32 or (features['libdl'] and cc.has_link_argument('-rdynamic')),
+@@ -1065,7 +1077,10 @@ x11 = {
+              dependency('xscrnsaver', version: '>= 1.0.0', required: x11_opt),
+              dependency('xext', version: '>= 1.0.0', required: x11_opt),
+              dependency('xpresent', version: '>= 1.0.0', required: x11_opt),
+-             dependency('xrandr', version: '>= 1.4.0', required: x11_opt)],
++             dependency('xrandr', version: '>= 1.4.0', required: x11_opt),
++             dependency('x11-xcb', version: '>= 1.8.9', required: x11_opt),
++             dependency('xcb-shm', version: '>= 1.16', required: x11_opt),
++             dependency('xcb', version: '>= 1.16', required: x11_opt),]
+ }
+ x11_deps = true
+ foreach dep: x11['deps']
Index: patches/patch-video_out_vo_x11_c
===================================================================
RCS file: patches/patch-video_out_vo_x11_c
diff -N patches/patch-video_out_vo_x11_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-video_out_vo_x11_c    19 Feb 2025 06:16:33 -0000
@@ -0,0 +1,99 @@
+Implement XShm 1.2
+
+Index: video/out/vo_x11.c
+--- video/out/vo_x11.c.orig
++++ video/out/vo_x11.c
+@@ -20,6 +20,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <unistd.h>
+ #include <sys/types.h>
+ 
+ #include <libswscale/swscale.h>
+@@ -38,7 +39,10 @@
+ 
+ #include <sys/ipc.h>
+ #include <sys/shm.h>
++#include <sys/mman.h>
+ #include <X11/extensions/XShm.h>
++#include <X11/Xlib-xcb.h>
++#include <xcb/shm.h>
+ 
+ #include "sub/osd.h"
+ #include "sub/draw_bmp.h"
+@@ -76,14 +80,26 @@ struct priv {
+ 
+     int Shmem_Flag;
+     XShmSegmentInfo Shminfo[2];
++    char shmname[128];
+     int Shm_Warned_Slow;
+ };
+ 
+ static bool resize(struct vo *vo);
+ 
++static Bool XShmAttachFd(Display *dpy, XShmSegmentInfo *shminfo)
++{
++    xcb_connection_t *xcb_conn = XGetXCBConnection(dpy);
++
++    shminfo->shmseg = xcb_generate_id(xcb_conn);
++    xcb_shm_attach_fd(xcb_conn, shminfo->shmseg,
++                   shminfo->shmid, shminfo->readOnly);
++    return 1;
++}
++
+ static bool getMyXImage(struct priv *p, int foo)
+ {
+     struct vo *vo = p->vo;
++    size_t len;
+     if (vo->x11->display_is_local && XShmQueryExtension(vo->x11->display)) {
+         p->Shmem_Flag = 1;
+         vo->x11->ShmCompletionEvent = XShmGetEventBase(vo->x11->display)
+@@ -102,16 +118,20 @@ static bool getMyXImage(struct priv *p, int foo)
+             MP_WARN(vo, "Shared memory error,disabling ( Ximage error )\n");
+             goto shmemerror;
+         }
+-        p->Shminfo[foo].shmid = shmget(IPC_PRIVATE,
+-                                       p->myximage[foo]->bytes_per_line *
+-                                       p->myximage[foo]->height,
+-                                       IPC_CREAT | 0777);
++      len = p->myximage[foo]->bytes_per_line * p->myximage[foo]->height;
++      memcpy(p->shmname, "/tmp/mpv-x11-XXXXXXXXXX",
++             sizeof(p->shmname));
++      p->Shminfo[foo].shmid = shm_mkstemp(p->shmname);
+         if (p->Shminfo[foo].shmid < 0) {
+             XDestroyImage(p->myximage[foo]);
+             MP_WARN(vo, "Shared memory error,disabling ( seg id error )\n");
+             goto shmemerror;
+         }
+-        p->Shminfo[foo].shmaddr = (char *) shmat(p->Shminfo[foo].shmid, 0, 0);
++        p->Shminfo[foo].shmaddr = mmap(NULL, len,
++                                     PROT_READ | PROT_WRITE,
++                                     MAP_SHARED | __MAP_NOFAULT,
++                                       p->Shminfo[foo].shmid, 0);
++        ftruncate(p->Shminfo[foo].shmid, len);
+ 
+         if (p->Shminfo[foo].shmaddr == ((char *) -1)) {
+             XDestroyImage(p->myximage[foo]);
+@@ -120,11 +140,11 @@ static bool getMyXImage(struct priv *p, int foo)
+         }
+         p->myximage[foo]->data = p->Shminfo[foo].shmaddr;
+         p->Shminfo[foo].readOnly = False;
+-        XShmAttach(vo->x11->display, &p->Shminfo[foo]);
++        XShmAttachFd(vo->x11->display, &p->Shminfo[foo]);
+ 
+         XSync(vo->x11->display, False);
+ 
+-        shmctl(p->Shminfo[foo].shmid, IPC_RMID, 0);
++      shm_unlink(p->shmname);
+     } else {
+ shmemerror:
+         p->Shmem_Flag = 0;
+@@ -151,6 +171,7 @@ static void freeMyXImage(struct priv *p, int foo)
+     if (p->Shmem_Flag) {
+         XShmDetach(vo->x11->display, &p->Shminfo[foo]);
+         XDestroyImage(p->myximage[foo]);
++      close(p->Shminfo[foo].shmid);
+         shmdt(p->Shminfo[foo].shmaddr);
+     } else {
+         if (p->myximage[foo]) {
Index: patches/patch-video_out_vo_xv_c
===================================================================
RCS file: patches/patch-video_out_vo_xv_c
diff -N patches/patch-video_out_vo_xv_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-video_out_vo_xv_c     19 Feb 2025 06:16:33 -0000
@@ -0,0 +1,86 @@
+Implment XShm 1.2
+
+Index: video/out/vo_xv.c
+--- video/out/vo_xv.c.orig
++++ video/out/vo_xv.c
+@@ -23,6 +23,7 @@
+ #include <string.h>
+ #include <stdint.h>
+ #include <stdbool.h>
++#include <unistd.h>
+ #include <errno.h>
+ #include <X11/Xlib.h>
+ #include <X11/Xutil.h>
+@@ -32,7 +33,10 @@
+ #include <sys/types.h>
+ #include <sys/ipc.h>
+ #include <sys/shm.h>
++#include <sys/mman.h>
+ #include <X11/extensions/XShm.h>
++#include <X11/Xlib-xcb.h>
++#include <xcb/shm.h>
+ 
+ // Note: depends on the inclusion of X11/extensions/XShm.h
+ #include <X11/extensions/Xv.h>
+@@ -91,6 +95,7 @@ struct xvctx {
+     GC vo_gc;   // used to paint video
+     int Shmem_Flag;
+     XShmSegmentInfo Shminfo[MAX_BUFFERS];
++    char shmname[128];
+     int Shm_Warned_Slow;
+     struct mp_image_params dst_params;
+ };
+@@ -126,6 +131,16 @@ static int find_xv_format(int imgfmt)
+     return 0;
+ }
+ 
++static Bool XShmAttachFd(Display *dpy, XShmSegmentInfo *shminfo)
++{
++    xcb_connection_t *xcb_conn = XGetXCBConnection(dpy);
++
++    shminfo->shmseg = xcb_generate_id(xcb_conn);
++    xcb_shm_attach_fd(xcb_conn, shminfo->shmseg,
++                  shminfo->shmid, shminfo->readOnly);
++    return 1;
++}
++
+ static int xv_find_atom(struct vo *vo, uint32_t xv_port, const char *name,
+                         bool get, int *min, int *max)
+ {
+@@ -561,18 +576,22 @@ static bool allocate_xvimage(struct vo *vo, int foo)
+         if (!ctx->xvimage[foo])
+             return false;
+ 
+-        ctx->Shminfo[foo].shmid = shmget(IPC_PRIVATE,
+-                                         ctx->xvimage[foo]->data_size,
+-                                         IPC_CREAT | 0777);
+-        ctx->Shminfo[foo].shmaddr = shmat(ctx->Shminfo[foo].shmid, 0, 0);
++      memcpy(ctx->shmname, "/tmp/mpv-xv-XXXXXXXXXX",
++             sizeof(ctx->shmname));
++      ctx->Shminfo[foo].shmid = shm_mkstemp(ctx->shmname);
++      ctx->Shminfo[foo].shmaddr = mmap(NULL, ctx->xvimage[foo]->data_size,
++                                       PROT_READ | PROT_WRITE,
++                                       MAP_SHARED | __MAP_NOFAULT,
++                                       ctx->Shminfo[foo].shmid, 0);
++      ftruncate(ctx->Shminfo[foo].shmid, ctx->xvimage[foo]->data_size);
+         if (ctx->Shminfo[foo].shmaddr == (void *)-1)
+             return false;
+         ctx->Shminfo[foo].readOnly = False;
+ 
+         ctx->xvimage[foo]->data = ctx->Shminfo[foo].shmaddr;
+-        XShmAttach(x11->display, &ctx->Shminfo[foo]);
++        XShmAttachFd(x11->display, &ctx->Shminfo[foo]);
+         XSync(x11->display, False);
+-        shmctl(ctx->Shminfo[foo].shmid, IPC_RMID, 0);
++      shm_unlink(ctx->shmname);
+     } else {
+         ctx->xvimage[foo] =
+             (XvImage *) XvCreateImage(x11->display, ctx->xv_port,
+@@ -605,6 +624,7 @@ static void deallocate_xvimage(struct vo *vo, int foo)
+     struct xvctx *ctx = vo->priv;
+     if (ctx->Shmem_Flag) {
+         XShmDetach(vo->x11->display, &ctx->Shminfo[foo]);
++      close(ctx->Shminfo[foo].shmid);
+         shmdt(ctx->Shminfo[foo].shmaddr);
+     } else {
+         av_free(ctx->xvimage[foo]->data);


-- 
Matthieu Herrb

Reply via email to