From fb5cfd5204bdada4a1f2fbe08cec816b424fc513 Mon Sep 17 00:00:00 2001 From: Maxime Chapelet Date: Mon, 2 Oct 2023 10:45:33 +0200 Subject: [PATCH] codec: videotoolbox: Check wherever a metal device can be fetched on iOS Metal device is mandatory to handle P010 chroma on mobile/tv devices. The Metal device API can only be used in ObjC context hence a new ObjC source file had to be created to handle the device detection. --- modules/codec/Makefile.am | 6 +++--- modules/codec/videotoolbox/decoder.c | 14 +++++++++++++- modules/codec/vt_utils.h | 7 +++++++ modules/codec/vt_utils_native.m | 14 ++++++++++++++ modules/video_output/Makefile.am | 4 ++-- 5 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 modules/codec/vt_utils_native.m diff --git a/modules/codec/Makefile.am b/modules/codec/Makefile.am index 80c0e05450..806ea6c1b3 100644 --- a/modules/codec/Makefile.am +++ b/modules/codec/Makefile.am @@ -352,7 +352,7 @@ codec_LTLIBRARIES += $(LTLIBoggspots) libvideotoolbox_plugin_la_SOURCES = codec/videotoolbox/decoder.c libvideotoolbox_plugin_la_LIBADD = libchroma_copy.la libvlc_hxxxhelper.la libvlc_vtutils.la -libvideotoolbox_plugin_la_LDFLAGS = $(AM_LDFLAGS) -Wl,-framework,CoreFoundation -Wl,-framework,VideoToolbox -Wl,-framework,CoreMedia -Wl,-framework,CoreVideo +libvideotoolbox_plugin_la_LDFLAGS = $(AM_LDFLAGS) -Wl,-framework,CoreFoundation -Wl,-framework,VideoToolbox -Wl,-framework,CoreMedia -Wl,-framework,CoreVideo -Wl,-framework,Metal if HAVE_DARWIN codec_LTLIBRARIES += libvideotoolbox_plugin.la endif @@ -360,7 +360,7 @@ endif libvideotoolbox_enc_plugin_la_SOURCES = codec/videotoolbox/encoder.c libvideotoolbox_enc_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) # Trigger MODULE_NAME declaration libvideotoolbox_enc_plugin_la_LIBADD = libvlc_hxxxhelper.la libvlc_vtutils.la -libvideotoolbox_enc_plugin_la_LDFLAGS = $(AM_LDFLAGS) -Wl,-framework,CoreFoundation -Wl,-framework,VideoToolbox -Wl,-framework,CoreMedia -Wl,-framework,CoreVideo +libvideotoolbox_enc_plugin_la_LDFLAGS = $(AM_LDFLAGS) -Wl,-framework,CoreFoundation -Wl,-framework,VideoToolbox -Wl,-framework,CoreMedia -Wl,-framework,CoreVideo -Wl,-framework,Metal if HAVE_DARWIN if ENABLE_SOUT codec_LTLIBRARIES += libvideotoolbox_enc_plugin.la @@ -652,6 +652,6 @@ libhxxxhelper_testdec_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(codecdir)' libhxxxhelper_testdec_plugin_la_LIBADD = libvlc_hxxxhelper.la noinst_LTLIBRARIES += libhxxxhelper_testdec_plugin.la -libvlc_vtutils_la_SOURCES = codec/vt_utils.c codec/vt_utils.h +libvlc_vtutils_la_SOURCES = codec/vt_utils.c codec/vt_utils.h codec/vt_utils_native.m libvlc_vtutils_la_LDFLAGS = -static -no-undefined EXTRA_LTLIBRARIES += libvlc_vtutils.la diff --git a/modules/codec/videotoolbox/decoder.c b/modules/codec/videotoolbox/decoder.c index e1adb88f2d..97695eacb4 100644 --- a/modules/codec/videotoolbox/decoder.c +++ b/modules/codec/videotoolbox/decoder.c @@ -73,6 +73,7 @@ static void Drain(decoder_t *p_dec, bool flush); static void DecoderCallback(void *, void *, OSStatus, VTDecodeInfoFlags, CVPixelBufferRef, CMTime, CMTime); static Boolean deviceSupportsHEVC(); +static bool deviceSupports42010bitRendering(); static Boolean deviceSupportsAdvancedProfiles(); static Boolean deviceSupportsAdvancedLevels(); @@ -252,7 +253,7 @@ static OSType GetBestChroma(uint8_t i_chroma_format, uint8_t i_depth_luma, return kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; if (i_depth_luma == 10 && i_depth_chroma == 10) { - if (deviceSupportsHEVC()) /* 42010bit went with HEVC on macOS */ + if (deviceSupportsHEVC() && deviceSupports42010bitRendering()) return kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange; /* Force BGRA output (and let VT handle the tone mapping) since the @@ -1633,6 +1634,17 @@ static Boolean deviceSupportsHEVC() return false; } +static bool deviceSupports42010bitRendering() +{ +#if TARGET_OS_IPHONE + /* iPhone/iPad/aTV needs metal device to render 420 10bit */ + return cvpx_system_has_metal_device(); +#else + /* macOS can render 420 10bit with OpenGL and Metal */ + return true; +#endif +} + static Boolean deviceSupportsAdvancedProfiles() { #if TARGET_OS_IPHONE diff --git a/modules/codec/vt_utils.h b/modules/codec/vt_utils.h index 11bd9e0534..6b0802b809 100644 --- a/modules/codec/vt_utils.h +++ b/modules/codec/vt_utils.h @@ -129,6 +129,13 @@ bool cvpx_has_attachment(CVPixelBufferRef pixelBuffer, CFStringRef key); */ void cvpx_attach_mapped_color_properties(CVPixelBufferRef cvpx, const video_format_t *fmt); +/** + * @brief Check if current system has at least one metal GPU device + * + * @return true if there's at least one metal device available + * @return false if there's no metal device + */ +bool cvpx_system_has_metal_device(); enum cvpx_video_context_type { diff --git a/modules/codec/vt_utils_native.m b/modules/codec/vt_utils_native.m new file mode 100644 index 0000000000..b74265a0d0 --- /dev/null +++ b/modules/codec/vt_utils_native.m @@ -0,0 +1,14 @@ +#import "vt_utils.h" +#import +#import + +bool cvpx_system_has_metal_device() +{ +#if TARGET_OS_IPHONE + id device = MTLCreateSystemDefaultDevice(); + return device != nil; +#else + NSArray > *devices = MTLCopyAllDevices(); + return devices.count > 0; +#endif +} \ No newline at end of file diff --git a/modules/video_output/Makefile.am b/modules/video_output/Makefile.am index 02f9bec079..4621c495a1 100644 --- a/modules/video_output/Makefile.am +++ b/modules/video_output/Makefile.am @@ -37,7 +37,7 @@ libglinterop_cvpx_plugin_la_SOURCES = video_output/opengl/interop_cvpx.m \ video_output/opengl/interop.h libglinterop_cvpx_plugin_la_LIBADD = libvlc_vtutils.la libglinterop_cvpx_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)' \ - -Wl,-framework,Foundation,-framework,CoreVideo,-framework,IOSurface + -Wl,-framework,Foundation,-framework,CoreVideo,-framework,IOSurface,-framework,Metal libglinterop_cvpx_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) if HAVE_DARWIN if HAVE_OSX @@ -105,7 +105,7 @@ libcvpx_gl_plugin_la_SOURCES = video_output/apple/VLCCVOpenGLProvider.m libcvpx_gl_plugin_la_OBJCFLAGS = $(AM_OBJCFLAGS) -fobjc-arc libcvpx_gl_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -DGL_SILENCE_DEPRECATION libcvpx_gl_plugin_la_LDFLAGS = $(AM_LDFLAGS) \ - -Wl,-framework,Foundation,-framework,CoreFoundation,-framework,CoreVideo + -Wl,-framework,Foundation,-framework,CoreFoundation,-framework,CoreVideo,-framework,Metal libcvpx_gl_plugin_la_LIBADD = libvlc_vtutils.la if HAVE_DARWIN