Index | Thread | Search

From:
Brad Smith <brad@comstyle.com>
Subject:
Re: VLC; 7.6-beta AMD64 Sept. 17th
To:
Byron Campbell - WA4GEG <wa4geg@yahoo.com>, ports@openbsd.org
Cc:
sthen@openbsd.org
Date:
Mon, 23 Sep 2024 00:14:24 -0400

Download raw body.

Thread
On Fri, Sep 20, 2024 at 04:21:29PM +0100, Stuart Henderson wrote:
> On 2024/09/18 09:38, Byron Campbell - WA4GEG wrote:
> > 
> > Okay, launched VLC from terminal. Here's the output when attempting to play
> > an MP4, and audio plays but not the video portion:
> > 
> > $ vlc
> > VLC media player 3.0.20 Vetinari (revision 3.0.20-0-g6f0d0ab126b)
> > [00000d0660d53220] main libvlc: Running vlc with the default interface. Use
> > 'cvlc' to use vlc without interface.
> > [00000d0660d64ca0] main playlist: playlist is empty
> > libva info: VA-API version 1.22.0
> > libva info: Trying to open /usr/X11R6/lib/modules/dri/r600_drv_video.so
> > libva info: Found init function __vaDriverInit_1_22
> > libva info: va_openDriver() returns 0
> > [00000d06e842d060] avcodec decoder: Using Mesa Gallium driver 23.3.6 for AMD
> > CEDAR (DRM 2.50.0 / 7.6, LLVM 16.0.6) for hardware decoding
> ...
> > radeondrm0 at pci3 dev 0 function 0 "ATI Radeon HD 5450" rev 0x00
> > drm0 at radeondrm0
> > radeondrm0: msi
> 
> I only have machines with Intel graphics handy - in that case things
> are working fine for me with or without hardware decoding (to actually
> use it there requires the intel-media-driver package to be installed).
> 
> I'm not familiar with how it works with AMD and wasn't keeping a close
> eye when VA-API was brought in but based on your debug messages it seems
> that it's included directly in the driver in xenocara so that programs
> supporting it will try to use it automatically without installing any
> extra packages.
> 
> 
> On 2024/09/18 13:33, Byron Campbell - WA4GEG wrote:
> > 
> > Turns out that VLC had "hardware acceleration" set to automatic. I assume
> > that it is shipped that way, since I generally have no need to alter the
> > default settings. And the problem is indeed due to the VA-API stuff as
> > Stuart suspected.
> > 
> > I got it to work by going into VLC's settings > Tools, Prefs., Input/Codecs
> > tab, and set the "hardware acceleration" to disable. Then VLC stopped
> > seg-faulting and plays both MP4 files and one test DVD okay.
> > 
> > Interestingly, VLC with hardware acceleration set to automatic, works just
> > fine in my OpenBSD 7.5 box.
> 
> OpenBSD didn't support hardware acceleration VA-API until after 7.5.
> AFAIK it's currently enabled in FFmpeg, mpv and vlc and disabled in
> other ports where it was noticed that they might pick it up.
> 
> I think we could probably do with some kind of mention in the 7.6
> upgrade notes, both to help people track down problems like this,
> and to help them get it used on Intel systems (where it seems to work
> pretty well).

Looks like there are some VA-API bug fixes pending in the 3.0 branch
backported to fix issues specically mentioned with the AMD r600 Mesa
driver.


Index: Makefile
===================================================================
RCS file: /cvs/ports/x11/vlc/Makefile,v
retrieving revision 1.275
diff -u -p -u -p -r1.275 Makefile
--- Makefile	16 Aug 2024 16:40:31 -0000	1.275
+++ Makefile	22 Sep 2024 00:48:01 -0000
@@ -5,10 +5,10 @@ V=		3.0.20
 DISTNAME=	vlc-${V}
 PKGNAME-main=	${DISTNAME}
 PKGNAME-jack=	vlc-jack-${V}
+REVISION-main=	5
 CATEGORIES=	x11
 SITES=		https://download.videolan.org/pub/videolan/vlc/${V}/
 EXTRACT_SUFX=	.tar.xz
-REVISION-main=	4
 
 USE_NOBTCFI=	Yes
 
Index: patches/patch-modules_hw_vaapi_chroma_c
===================================================================
RCS file: patches/patch-modules_hw_vaapi_chroma_c
diff -N patches/patch-modules_hw_vaapi_chroma_c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-modules_hw_vaapi_chroma_c	22 Sep 2024 00:48:01 -0000
@@ -0,0 +1,54 @@
+- vaapi: chroma: Implement vaPutImage upload fallback
+  374ce3b5e1cdbdc94a2a8ea9714e9dfdbc1d2f9f
+
+Index: modules/hw/vaapi/chroma.c
+--- modules/hw/vaapi/chroma.c.orig
++++ modules/hw/vaapi/chroma.c
+@@ -252,18 +252,40 @@ UploadSurface(filter_t *filter, picture_t *src)
+     vlc_vaapi_PicAttachContext(dest_pic);
+     picture_CopyProperties(dest_pic, src);
+ 
+-    if (vlc_vaapi_DeriveImage(VLC_OBJECT(filter), va_dpy,
+-                              vlc_vaapi_PicGetSurface(dest_pic), &dest_img)
+-        || vlc_vaapi_MapBuffer(VLC_OBJECT(filter), va_dpy,
+-                               dest_img.buf, &dest_buf))
++    if (filter->p_sys->derive_failed ||
++        vlc_vaapi_DeriveImage(VLC_OBJECT(filter), va_dpy,
++                              vlc_vaapi_PicGetSurface(dest_pic), &dest_img))
++    {
++        if (filter->p_sys->image_fallback_failed)
++            goto error;
++
++        filter->p_sys->derive_failed = true;
++
++        if (CreateFallbackImage(filter, dest_pic, va_dpy, &dest_img))
++        {
++            filter->p_sys->image_fallback_failed = true;
++            goto error;
++        }
++    }
++
++    if (vlc_vaapi_MapBuffer(VLC_OBJECT(filter), va_dpy,
++                            dest_img.buf, &dest_buf))
+         goto error;
+ 
+     FillVAImageFromPicture(&dest_img, dest_buf, dest_pic,
+                            src, &filter->p_sys->cache);
+ 
+-    if (vlc_vaapi_UnmapBuffer(VLC_OBJECT(filter), va_dpy, dest_img.buf)
+-        || vlc_vaapi_DestroyImage(VLC_OBJECT(filter),
+-                                  va_dpy, dest_img.image_id))
++    if (vlc_vaapi_UnmapBuffer(VLC_OBJECT(filter), va_dpy, dest_img.buf))
++        goto error;
++
++    if (filter->p_sys->derive_failed &&
++        vaPutImage(va_dpy, vlc_vaapi_PicGetSurface(dest_pic), dest_img.image_id,
++                   0, 0, dest_pic->format.i_width, dest_pic->format.i_height,
++                   0, 0, dest_pic->format.i_width, dest_pic->format.i_height))
++        goto error;
++
++    if (vlc_vaapi_DestroyImage(VLC_OBJECT(filter),
++                               va_dpy, dest_img.image_id))
+         goto error;
+ 
+ ret:
Index: patches/patch-modules_video_output_opengl_converter_vaapi_c
===================================================================
RCS file: patches/patch-modules_video_output_opengl_converter_vaapi_c
diff -N patches/patch-modules_video_output_opengl_converter_vaapi_c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-modules_video_output_opengl_converter_vaapi_c	22 Sep 2024 00:48:01 -0000
@@ -0,0 +1,138 @@
+- converter_vaapi: Don't use DeriveImage with ExportSurfaceHandle
+  ea9463607f71fe4d094b99b8d0a6181452688228
+
+Index: modules/video_output/opengl/converter_vaapi.c
+--- modules/video_output/opengl/converter_vaapi.c.orig
++++ modules/video_output/opengl/converter_vaapi.c
+@@ -72,9 +72,10 @@ struct priv
+          * (GPU tiling, compression, etc...) */
+         VADRMPRIMESurfaceDescriptor va_surface_descriptor;
+ #else
++        VAImage                     va_image;
+         VABufferInfo                va_buffer_info;
+ #endif
+-        VAImage                     va_image;
++        unsigned                    num_planes;
+         void *                      egl_images[3];
+     } last;
+ };
+@@ -111,7 +112,7 @@ vaegl_release_last_pic(const opengl_tex_converter_t *t
+ {
+     vlc_object_t *o = VLC_OBJECT(tc->gl);
+ 
+-    for (unsigned i = 0; i < priv->last.va_image.num_planes; ++i)
++    for (unsigned i = 0; i < priv->last.num_planes; ++i)
+         vaegl_image_destroy(tc, priv->last.egl_images[i]);
+ 
+ #if VA_CHECK_VERSION(1, 1, 0)
+@@ -119,9 +120,9 @@ vaegl_release_last_pic(const opengl_tex_converter_t *t
+         close(priv->last.va_surface_descriptor.objects[i].fd);
+ #else
+     vlc_vaapi_ReleaseBufferHandle(o, priv->vadpy, priv->last.va_image.buf);
+-#endif
+ 
+     vlc_vaapi_DestroyImage(o, priv->vadpy, priv->last.va_image.image_id);
++#endif
+ 
+     picture_Release(priv->last.pic);
+ }
+@@ -182,26 +183,35 @@ tc_vaegl_update(const opengl_tex_converter_t *tc, GLui
+     (void) plane_offset;
+     struct priv *priv = tc->priv;
+     vlc_object_t *o = VLC_OBJECT(tc->gl);
+-    VAImage va_image;
+ #if VA_CHECK_VERSION(1, 1, 0)
+     VADRMPRIMESurfaceDescriptor va_surface_descriptor;
+ #else
++    VAImage va_image;
+     VABufferInfo va_buffer_info;
+ #endif
+     EGLImageKHR egl_images[3] = { };
+     bool release_image = false, release_buffer_info = false;
++    unsigned num_planes = 0;
+ 
+     if (pic == priv->last.pic)
+     {
+-        va_image = priv->last.va_image;
+ #if VA_CHECK_VERSION(1, 1, 0)
+         va_surface_descriptor = priv->last.va_surface_descriptor;
++#else
++        va_image = priv->last.va_image;
+ #endif
+-        for (unsigned i = 0; i < priv->last.va_image.num_planes; ++i)
++        for (unsigned i = 0; i < priv->last.num_planes; ++i)
+             egl_images[i] = priv->last.egl_images[i];
+     }
+     else
+     {
++#if VA_CHECK_VERSION(1, 1, 0)
++        if (vlc_vaapi_ExportSurfaceHandle(o, priv->vadpy, vlc_vaapi_PicGetSurface(pic),
++                                          VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, 0,
++                                          &va_surface_descriptor))
++            goto error;
++        release_image = true;
++#else
+         if (vlc_vaapi_DeriveImage(o, priv->vadpy, vlc_vaapi_PicGetSurface(pic),
+                                   &va_image))
+             goto error;
+@@ -209,12 +219,6 @@ tc_vaegl_update(const opengl_tex_converter_t *tc, GLui
+ 
+         assert(va_image.format.fourcc == priv->fourcc);
+ 
+-#if VA_CHECK_VERSION(1, 1, 0)
+-        if (vlc_vaapi_ExportSurfaceHandle(o, priv->vadpy, vlc_vaapi_PicGetSurface(pic),
+-                                          VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, 0,
+-                                          &va_surface_descriptor))
+-            goto error;
+-#else
+         va_buffer_info = (VABufferInfo) {
+             .mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME
+         };
+@@ -226,7 +230,8 @@ tc_vaegl_update(const opengl_tex_converter_t *tc, GLui
+     }
+ 
+ #if VA_CHECK_VERSION(1, 1, 0)
+-    for (unsigned i = 0; i < va_surface_descriptor.num_layers; ++i)
++    num_planes = va_surface_descriptor.num_layers;
++    for (unsigned i = 0; i < num_planes; ++i)
+     {
+         unsigned obj_idx = va_surface_descriptor.layers[i].object_index[0];
+ 
+@@ -251,7 +256,8 @@ tc_vaegl_update(const opengl_tex_converter_t *tc, GLui
+         priv->glEGLImageTargetTexture2DOES(tc->tex_target, egl_images[i]);
+     }
+ #else
+-    for (unsigned i = 0; i < va_image.num_planes; ++i)
++    num_planes = va_image.num_planes;
++    for (unsigned i = 0; i < num_planes; ++i)
+     {
+         egl_images[i] =
+             vaegl_image_create(tc, tex_width[i], tex_height[i],
+@@ -272,14 +278,15 @@ tc_vaegl_update(const opengl_tex_converter_t *tc, GLui
+         if (priv->last.pic != NULL)
+             vaegl_release_last_pic(tc, priv);
+         priv->last.pic = picture_Hold(pic);
+-        priv->last.va_image = va_image;
+ #if VA_CHECK_VERSION(1, 1, 0)
+         priv->last.va_surface_descriptor = va_surface_descriptor;
+ #else
++        priv->last.va_image = va_image;
+         priv->last.va_buffer_info = va_buffer_info;
+ #endif
++        priv->last.num_planes = num_planes;
+ 
+-        for (unsigned i = 0; i < va_image.num_planes; ++i)
++        for (unsigned i = 0; i < num_planes; ++i)
+             priv->last.egl_images[i] = egl_images[i];
+     }
+ 
+@@ -301,7 +308,9 @@ error:
+         for (unsigned i = 0; i < 3 && egl_images[i] != NULL; ++i)
+             vaegl_image_destroy(tc, egl_images[i]);
+ 
++#if !VA_CHECK_VERSION(1, 1, 0)
+         vlc_vaapi_DestroyImage(o, priv->vadpy, va_image.image_id);
++#endif
+     }
+     return VLC_EGENERIC;
+ }