ImageWriterCompat.java
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.camera.core.internal.compat;
import android.media.Image;
import android.media.ImageWriter;
import android.os.Build;
import android.view.Surface;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
/**
* Helper for accessing features of {@link ImageWriter} in a backwards compatible fashion.
*/
@RequiresApi(23)
public final class ImageWriterCompat {
/**
* <p>
* Create a new ImageWriter with given number of max Images and format.
* </p>
* <p>
* The {@code maxImages} parameter determines the maximum number of
* {@link android.media.Image} objects that can be be dequeued from the
* {@code ImageWriter} simultaneously. Requesting more buffers will use up
* more memory, so it is important to use only the minimum number necessary.
* </p>
* <p>
* The format specifies the image format of this ImageWriter. The format
* from the {@code surface} will be overridden with this format. For example,
* if the surface is obtained from a {@link android.graphics.SurfaceTexture}, the default
* format may be {@link android.graphics.PixelFormat#RGBA_8888}. If the application creates an
* ImageWriter with this surface and {@link android.graphics.ImageFormat#PRIVATE}, this
* ImageWriter will be able to operate with {@link android.graphics.ImageFormat#PRIVATE} Images.
* </p>
* <p>
* Note that the consumer end-point may or may not be able to support Images with different
* format, for such case, the application should only use this method if the consumer is able
* to consume such images.
* </p>
* <p>
* The input Image size depends on the Surface that is provided by
* the downstream consumer end-point.
* </p>
*
* @param surface The destination Surface this writer produces Image data
* into.
* @param maxImages The maximum number of Images the user will want to
* access simultaneously for producing Image data. This should be
* as small as possible to limit memory use. Once maxImages
* Images are dequeued by the user, one of them has to be queued
* back before a new Image can be dequeued for access via
* {@link ImageWriter#dequeueInputImage()}.
* @param format The format of this ImageWriter. It can be any valid format specified by
* {@link android.graphics.ImageFormat} or {@link android.graphics.PixelFormat}.
*
* @return a new ImageWriter instance.
*/
@NonNull
public static ImageWriter newInstance(@NonNull Surface surface,
@IntRange(from = 1) int maxImages, int format) {
if (Build.VERSION.SDK_INT >= 29) {
return ImageWriterCompatApi29Impl.newInstance(surface, maxImages, format);
} else if (Build.VERSION.SDK_INT >= 26) {
return ImageWriterCompatApi26Impl.newInstance(surface, maxImages, format);
}
throw new RuntimeException(
"Unable to call newInstance(Surface, int, int) on API " + Build.VERSION.SDK_INT
+ ". Version 26 or higher required.");
}
/**
* <p>
* Create a new ImageWriter with given number of max Images and format.
* </p>
* <p>
* The {@code maxImages} parameter determines the maximum number of
* {@link android.media.Image} objects that can be be dequeued from the
* {@code ImageWriter} simultaneously. Requesting more buffers will use up
* more memory, so it is important to use only the minimum number necessary.
* </p>
*
* @param surface The destination Surface this writer produces Image data
* into.
* @param maxImages The maximum number of Images the user will want to
* access simultaneously for producing Image data. This should be
* as small as possible to limit memory use. Once maxImages
* Images are dequeued by the user, one of them has to be queued
* back before a new Image can be dequeued for access via
* {@link ImageWriter#dequeueInputImage()}.
*
* @return a new ImageWriter instance.
*/
@NonNull
public static ImageWriter newInstance(@NonNull Surface surface,
@IntRange(from = 1) int maxImages) {
if (Build.VERSION.SDK_INT >= 23) {
return ImageWriterCompatApi23Impl.newInstance(surface, maxImages);
}
throw new RuntimeException(
"Unable to call newInstance(Surface, int) on API " + Build.VERSION.SDK_INT
+ ". Version 23 or higher required.");
}
/**
* <p>
* Dequeue an image from image writer.
* </p>
*
* @param imageWriter image writer instance.
* @return image from image writer
*/
@NonNull
public static Image dequeueInputImage(@NonNull ImageWriter imageWriter) {
if (Build.VERSION.SDK_INT >= 23) {
return ImageWriterCompatApi23Impl.dequeueInputImage(imageWriter);
}
throw new RuntimeException(
"Unable to call dequeueInputImage() on API " + Build.VERSION.SDK_INT
+ ". Version 23 or higher required.");
}
/**
* <p>
* Queue an image to image writer.
* </p>
*
* @param imageWriter image writer instance.
* @param image image to image writer.
*/
public static void queueInputImage(@NonNull ImageWriter imageWriter, @NonNull Image image) {
if (Build.VERSION.SDK_INT >= 23) {
ImageWriterCompatApi23Impl.queueInputImage(imageWriter, image);
return;
}
throw new RuntimeException(
"Unable to call queueInputImage() on API " + Build.VERSION.SDK_INT
+ ". Version 23 or higher required.");
}
/**
* Close the existing ImageWriter instance.
*
* @param imageWriter ImageWriter instance.
*/
public static void close(@NonNull ImageWriter imageWriter) {
if (Build.VERSION.SDK_INT >= 23) {
ImageWriterCompatApi23Impl.close(imageWriter);
return;
}
throw new RuntimeException(
"Unable to call close() on API " + Build.VERSION.SDK_INT
+ ". Version 23 or higher required.");
}
// Class should not be instantiated.
private ImageWriterCompat() {
}
}