Hi again,

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.

Index: Makefile
===================================================================
RCS file: /local/cvs/ports/multimedia/mpv/Makefile,v
diff -u -p -u -r1.104 Makefile
--- Makefile    9 Aug 2024 15:49:42 -0000       1.104
+++ Makefile    15 Dec 2024 20:31:00 -0000
@@ -4,7 +4,7 @@ GH_ACCOUNT =            mpv-player
 GH_PROJECT =           mpv
 GH_TAGNAME =           v0.38.0
 USE_NOBTCFI =          Yes
-REVISION =             1
+REVISION =             2
 
 SHARED_LIBS +=         mpv             2.0
 
@@ -20,6 +20,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.9 patch-meson_build
--- patches/patch-meson_build   28 Jul 2024 06:51:13 -0000      1.9
+++ patches/patch-meson_build   15 Dec 2024 20:31:00 -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
@@ -34,3 +35,15 @@ Index: meson.build
  
  # macOS's pthread_setname_np is a special snowflake and differs from 
literally every other platform.
  features += {'mac-thread-name': darwin}
+@@ -1049,7 +1061,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    15 Dec 2024 20:31:00 -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     15 Dec 2024 20:31:00 -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