diff --git a/package/android/src/main/java/com/mrousavy/camera/core/VideoPipeline.kt b/package/android/src/main/java/com/mrousavy/camera/core/VideoPipeline.kt index 99374cc..f45520c 100644 --- a/package/android/src/main/java/com/mrousavy/camera/core/VideoPipeline.kt +++ b/package/android/src/main/java/com/mrousavy/camera/core/VideoPipeline.kt @@ -9,7 +9,6 @@ import android.os.Build import android.util.Log import android.view.Surface import androidx.annotation.Keep -import androidx.annotation.RequiresApi import com.facebook.jni.HybridData import com.facebook.proguard.annotations.DoNotStrip import com.mrousavy.camera.frameprocessor.Frame @@ -79,15 +78,12 @@ class VideoPipeline( val format = getImageReaderFormat() Log.i(TAG, "Using ImageReader round-trip (format: #$format)") + imageReader = ImageReader.newInstance(width, height, format, MAX_IMAGES) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - Log.i(TAG, "Using API 29 for GPU ImageReader...") - val usageFlags = getRecommendedHardwareBufferFlags() - Log.i(TAG, "Using ImageReader flags: $usageFlags") - imageReader = ImageReader.newInstance(width, height, format, MAX_IMAGES, usageFlags) + Log.i(TAG, "Using ImageWriter with custom format (#$format)...") imageWriter = ImageWriter.newInstance(glSurface, MAX_IMAGES, format) } else { - Log.i(TAG, "Using legacy API for CPU ImageReader...") - imageReader = ImageReader.newInstance(width, height, format, MAX_IMAGES) + Log.i(TAG, "Using ImageWriter with default format...") imageWriter = ImageWriter.newInstance(glSurface, MAX_IMAGES) } imageReader!!.setOnImageAvailableListener({ reader -> @@ -185,56 +181,6 @@ class VideoPipeline( } } - /** - * Get the recommended HardwareBuffer flags for creating ImageReader instances with. - * - * Tries to use [HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE] if possible, [HardwareBuffer.USAGE_CPU_READ_OFTEN] - * or a combination of both flags if CPU access is needed ([enableFrameProcessor]), and [0] otherwise. - */ - @RequiresApi(Build.VERSION_CODES.Q) - @Suppress("LiftReturnOrAssignment") - private fun getRecommendedHardwareBufferFlags(): Long { - val cpuFlag = HardwareBuffer.USAGE_CPU_READ_OFTEN - val gpuFlag = HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE - val bothFlags = gpuFlag or cpuFlag - - if (format == PixelFormat.NATIVE) { - // We don't need CPU access, so we can use GPU optimized buffers - if (supportsHardwareBufferFlags(gpuFlag)) { - // We support GPU Buffers directly and - Log.i(TAG, "GPU HardwareBuffers are supported!") - return gpuFlag - } else { - // no flags are supported - fall back to default - return 0 - } - } else { - // We are using YUV or RGB formats, so we need CPU access on the Frame - if (supportsHardwareBufferFlags(bothFlags)) { - // We support both CPU and GPU flags! - Log.i(TAG, "GPU + CPU HardwareBuffers are supported!") - return bothFlags - } else if (supportsHardwareBufferFlags(cpuFlag)) { - // We only support a CPU read flag, that's fine - Log.i(TAG, "CPU HardwareBuffers are supported!") - return cpuFlag - } else { - // no flags are supported - fall back to default - return 0 - } - } - } - - @RequiresApi(Build.VERSION_CODES.Q) - private fun supportsHardwareBufferFlags(flags: Long): Boolean { - val hardwareBufferFormat = format.toHardwareBufferFormat() - try { - return HardwareBuffer.isSupported(width, height, hardwareBufferFormat, 1, flags) - } catch (_: Throwable) { - return false - } - } - private external fun getInputTextureId(): Int private external fun onBeforeFrame() private external fun onFrame(transformMatrix: FloatArray) diff --git a/package/android/src/main/java/com/mrousavy/camera/types/PixelFormat.kt b/package/android/src/main/java/com/mrousavy/camera/types/PixelFormat.kt index 697c53b..c4a7a3c 100644 --- a/package/android/src/main/java/com/mrousavy/camera/types/PixelFormat.kt +++ b/package/android/src/main/java/com/mrousavy/camera/types/PixelFormat.kt @@ -4,7 +4,6 @@ import android.graphics.ImageFormat import android.util.Log import com.mrousavy.camera.core.InvalidTypeScriptUnionError import com.mrousavy.camera.core.PixelFormatNotSupportedError -import com.mrousavy.camera.utils.HardwareBufferUtils import com.mrousavy.camera.utils.ImageFormatUtils enum class PixelFormat(override val unionValue: String) : JSUnionValue { @@ -20,11 +19,6 @@ enum class PixelFormat(override val unionValue: String) : JSUnionValue { else -> throw PixelFormatNotSupportedError(this.unionValue) } - fun toHardwareBufferFormat(): Int { - val imageFormat = toImageFormat() - return HardwareBufferUtils.getHardwareBufferFormat(imageFormat) - } - companion object : JSUnionValue.Companion { private const val TAG = "PixelFormat" fun fromImageFormat(imageFormat: Int): PixelFormat = diff --git a/package/android/src/main/java/com/mrousavy/camera/utils/HardwareBufferUtils.kt b/package/android/src/main/java/com/mrousavy/camera/utils/HardwareBufferUtils.kt deleted file mode 100644 index c1d5106..0000000 --- a/package/android/src/main/java/com/mrousavy/camera/utils/HardwareBufferUtils.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.mrousavy.camera.utils - -import android.graphics.ImageFormat -import android.hardware.HardwareBuffer -import android.media.ImageReader -import android.os.Build - -class HardwareBufferUtils { - companion object { - fun getHardwareBufferFormat(imageFormat: Int): Int { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - // Dynamically create an ImageReader with the target ImageFormat, and then - // get it's HardwareBuffer format to see what it uses underneath. - val imageReader = ImageReader.newInstance(1, 1, imageFormat, 1, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE) - val format = imageReader.hardwareBufferFormat - imageReader.close() - return format - } - - if (imageFormat == ImageFormat.PRIVATE) { - // PRIVATE formats are opaque, their actual equivalent HardwareBuffer format is unknown. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - // We can assume that YUV 4:2:0 or RGB is used. - return HardwareBuffer.YCBCR_420_888 - } else { - // Maybe assume we are on RGB if we're not on API R or above... - return HardwareBuffer.RGB_888 - } - } - - // According to PublicFormat.cpp in Android's codebase, the formats map 1:1 anyways.. - // https://cs.android.com/android/platform/superproject/main/+/main:frameworks/native/libs/ui/PublicFormat.cpp - return imageFormat - } - } -}