PreviewProcessor.java
/*
* Copyright 2022 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.extensions.internal.sessionprocessor;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
import android.hardware.camera2.TotalCaptureResult;
import android.util.Size;
import android.view.Surface;
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.camera.core.Logger;
import androidx.camera.extensions.impl.PreviewImageProcessorImpl;
/**
* A preview processor that is responsible for invoking OEM's PreviewImageProcessorImpl and
* output to the given PRIVATE surface.
*
* <p>To start the processing, invoke {@link #start()} and then feed {@link ImageReference} and
* {@link TotalCaptureResult} instances by {@link #notifyImage(ImageReference)} and
* {@link #notifyCaptureResult(TotalCaptureResult)} respectively. The output will be written to the
* given output surface. Invoke {@link #close()} to close the processor and reclaim the resources.
*
* <p>Please note that output preview surface must be closed AFTER this processor is closed.
*/
@RequiresApi(21)
class PreviewProcessor {
private static final String TAG = "PreviewProcessor";
@NonNull
final PreviewImageProcessorImpl mPreviewImageProcessor;
@NonNull
final CaptureResultImageMatcher mCaptureResultImageMatcher = new CaptureResultImageMatcher();
final Object mLock = new Object();
@GuardedBy("mLock")
boolean mIsClosed = false;
PreviewProcessor(@NonNull PreviewImageProcessorImpl previewImageProcessor,
@NonNull Surface previewOutputSurface, @NonNull Size surfaceSize) {
mPreviewImageProcessor = previewImageProcessor;
mPreviewImageProcessor.onResolutionUpdate(surfaceSize);
mPreviewImageProcessor.onOutputSurface(previewOutputSurface, PixelFormat.RGBA_8888);
mPreviewImageProcessor.onImageFormatUpdate(ImageFormat.YUV_420_888);
}
void start() {
mCaptureResultImageMatcher.setImageReferenceListener(
(imageReference, totalCaptureResult, captureStageId) -> {
synchronized (mLock) {
if (mIsClosed) {
imageReference.decrement();
Logger.d(TAG, "Ignore image in closed state");
return;
}
mPreviewImageProcessor.process(imageReference.get(),
totalCaptureResult);
imageReference.decrement();
}
});
}
void notifyCaptureResult(@NonNull TotalCaptureResult captureResult) {
mCaptureResultImageMatcher.captureResultIncoming(captureResult);
}
void notifyImage(@NonNull ImageReference imageReference) {
mCaptureResultImageMatcher.imageIncoming(imageReference);
}
/**
* Close the processor. Please note that output preview surface must be closed AFTER this
* processor is closed.
*/
void close() {
synchronized (mLock) {
mIsClosed = true;
mCaptureResultImageMatcher.clear();
mCaptureResultImageMatcher.clearImageReferenceListener();
}
}
}