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