From 8e41da395a7bb8ec24510a4e009fb50de41c6d42 Mon Sep 17 00:00:00 2001 From: William Candillon Date: Wed, 17 Apr 2024 06:42:14 +0200 Subject: [PATCH] =?UTF-8?q?fix(=F0=9F=91=BE):=20use=20PixelBuffer=20instea?= =?UTF-8?q?d=20of=20SampleBuffer=20on=20iOS=20(#2374)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package/cpp/rnskia/RNSkPlatformContext.h | 4 +-- .../ios/RNSkia-iOS/RNSkiOSPlatformContext.mm | 34 +++---------------- .../ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h | 2 +- .../ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm | 10 ++---- package/src/skia/types/Image/ImageFactory.ts | 2 +- 5 files changed, 10 insertions(+), 42 deletions(-) diff --git a/package/cpp/rnskia/RNSkPlatformContext.h b/package/cpp/rnskia/RNSkPlatformContext.h index 7f03215cf9..53b38dc4f2 100644 --- a/package/cpp/rnskia/RNSkPlatformContext.h +++ b/package/cpp/rnskia/RNSkPlatformContext.h @@ -134,8 +134,8 @@ class RNSkPlatformContext { virtual sk_sp makeOffscreenSurface(int width, int height) = 0; /** - * Creates an image from a native buffer. - * - On iOS, this is a `CMSampleBuffer` + * Creates an image from a native buffer. (for testing purposes only) + * - On iOS, this is a `CVPixelBufferRef*` * - On Android, this is a `AHardwareBuffer*` * @param buffer The native platform buffer. * @return sk_sp diff --git a/package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm b/package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm index 644cbf731e..c53f0831dc 100644 --- a/package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +++ b/package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm @@ -143,34 +143,8 @@ std::to_string(result)); } - // 6. Create CMSampleBuffer base information - CMFormatDescriptionRef formatDescription = nullptr; - CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, - &formatDescription); - CMSampleTimingInfo timingInfo = {0}; - timingInfo.duration = kCMTimeInvalid; - timingInfo.presentationTimeStamp = kCMTimeZero; - timingInfo.decodeTimeStamp = kCMTimeInvalid; - - // 7. Wrap the CVPixelBuffer in a CMSampleBuffer - CMSampleBufferRef sampleBuffer = nullptr; - OSStatus status = CMSampleBufferCreateReadyWithImageBuffer( - kCFAllocatorDefault, pixelBuffer, formatDescription, &timingInfo, - &sampleBuffer); - if (status != noErr) { - if (formatDescription) { - CFRelease(formatDescription); - } - if (pixelBuffer) { - CFRelease(pixelBuffer); - } - throw std::runtime_error( - "Failed to wrap CVPixelBuffer in CMSampleBuffer! Return value: " + - std::to_string(status)); - } - - // 8. Return CMsampleBuffer casted to uint64_t - return reinterpret_cast(sampleBuffer); + // 8. Return CVPixelBuffer casted to uint64_t + return reinterpret_cast(pixelBuffer); } void RNSkiOSPlatformContext::raiseError(const std::exception &err) { @@ -183,8 +157,8 @@ } sk_sp RNSkiOSPlatformContext::makeImageFromNativeBuffer(void *buffer) { - CMSampleBufferRef sampleBuffer = (CMSampleBufferRef)buffer; - return SkiaMetalSurfaceFactory::makeTextureFromCMSampleBuffer(sampleBuffer); + CVPixelBufferRef sampleBuffer = (CVPixelBufferRef)buffer; + return SkiaMetalSurfaceFactory::makeTextureFromCVPixelBuffer(sampleBuffer); } sk_sp RNSkiOSPlatformContext::createFontMgr() { diff --git a/package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h b/package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h index 4b98b21c31..e40a0a1941 100644 --- a/package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +++ b/package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h @@ -27,7 +27,7 @@ class SkiaMetalSurfaceFactory { static sk_sp makeOffscreenSurface(int width, int height); static sk_sp - makeTextureFromCMSampleBuffer(CMSampleBufferRef sampleBuffer); + makeTextureFromCVPixelBuffer(CVPixelBufferRef pixelBuffer); private: static id device; diff --git a/package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm b/package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm index 180e6d46a5..fa1f6b877a 100644 --- a/package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +++ b/package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm @@ -107,20 +107,14 @@ return surface; } -sk_sp SkiaMetalSurfaceFactory::makeTextureFromCMSampleBuffer( - CMSampleBufferRef sampleBuffer) { +sk_sp SkiaMetalSurfaceFactory::makeTextureFromCVPixelBuffer( + CVPixelBufferRef pixelBuffer) { if (!SkiaMetalSurfaceFactory::createSkiaDirectContextIfNecessary( &ThreadContextHolder::ThreadSkiaMetalContext)) [[unlikely]] { throw std::runtime_error("Failed to create Skia Context for this Thread!"); } const SkiaMetalContext &context = ThreadContextHolder::ThreadSkiaMetalContext; - if (!CMSampleBufferIsValid(sampleBuffer)) [[unlikely]] { - throw std::runtime_error("The given CMSampleBuffer is not valid!"); - } - - CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); - SkiaCVPixelBufferUtils::CVPixelBufferBaseFormat format = SkiaCVPixelBufferUtils::getCVPixelBufferBaseFormat(pixelBuffer); switch (format) { diff --git a/package/src/skia/types/Image/ImageFactory.ts b/package/src/skia/types/Image/ImageFactory.ts index 938770a0b5..2e6fe1643b 100644 --- a/package/src/skia/types/Image/ImageFactory.ts +++ b/package/src/skia/types/Image/ImageFactory.ts @@ -61,7 +61,7 @@ export interface ImageFactory { * to render a Skia Camera preview. * * - On Android; This is an `AHardwareBuffer*` - * - On iOS, this is a `CMSampleBufferRef` + * - On iOS, this is a `CVPixelBufferRef` * @param nativeBuffer A strong `uintptr_t` pointer to the native platform buffer * @throws Throws an error if the Image could not be created, for example when the given * platform buffer is invalid.