From: Brad Smith Subject: Re: VLC; 7.6-beta AMD64 Sept. 17th To: Byron Campbell - WA4GEG , ports@openbsd.org Cc: sthen@openbsd.org Date: Mon, 23 Sep 2024 00:14:24 -0400 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; + }