use of android.hardware.camera2.CameraCaptureSession.CaptureCallback in project android_frameworks_base by ResurrectionRemix.
the class CameraCaptureSessionImpl method captureBurst.
@Override
public synchronized int captureBurst(List<CaptureRequest> requests, CaptureCallback callback, Handler handler) throws CameraAccessException {
if (requests == null) {
throw new IllegalArgumentException("Requests must not be null");
} else if (requests.isEmpty()) {
throw new IllegalArgumentException("Requests must have at least one element");
}
for (CaptureRequest request : requests) {
if (request.isReprocess()) {
if (!isReprocessable()) {
throw new IllegalArgumentException("This capture session cannot handle " + "reprocess requests");
} else if (request.getReprocessableSessionId() != mId) {
throw new IllegalArgumentException("Capture request was created for another " + "session");
}
}
}
checkNotClosed();
handler = checkHandler(handler, callback);
if (DEBUG) {
CaptureRequest[] requestArray = requests.toArray(new CaptureRequest[0]);
Log.v(TAG, mIdString + "captureBurst - requests " + Arrays.toString(requestArray) + ", callback " + callback + " handler " + handler);
}
return addPendingSequence(mDeviceImpl.captureBurst(requests, createCaptureCallbackProxy(handler, callback), mDeviceHandler));
}
use of android.hardware.camera2.CameraCaptureSession.CaptureCallback in project android_frameworks_base by DirtyUnicorns.
the class Camera2ReprocessCaptureTest method testReprocessAbort.
/**
* Test aborting a burst reprocess capture and multiple single reprocess captures.
*/
private void testReprocessAbort(String cameraId, Size inputSize, int inputFormat, Size reprocessOutputSize, int reprocessOutputFormat) throws Exception {
if (VERBOSE) {
Log.v(TAG, "testReprocessAbort: cameraId: " + cameraId + " inputSize: " + inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " + reprocessOutputSize + " reprocessOutputFormat: " + reprocessOutputFormat);
}
try {
setupImageReaders(inputSize, inputFormat, reprocessOutputSize, reprocessOutputFormat, NUM_REPROCESS_CAPTURES);
setupReprocessableSession(/*previewSurface*/
null, NUM_REPROCESS_CAPTURES);
// Test two cases: submitting reprocess requests one by one and in a burst.
boolean[] submitInBursts = { false, true };
for (boolean submitInBurst : submitInBursts) {
// Prepare reprocess capture requests.
ArrayList<CaptureRequest> reprocessRequests = new ArrayList<>(NUM_REPROCESS_CAPTURES);
for (int i = 0; i < NUM_REPROCESS_CAPTURES; i++) {
TotalCaptureResult result = submitCaptureRequest(mFirstImageReader.getSurface(), /*inputResult*/
null);
mImageWriter.queueInputImage(mFirstImageReaderListener.getImage(CAPTURE_TIMEOUT_MS));
CaptureRequest.Builder builder = mCamera.createReprocessCaptureRequest(result);
builder.addTarget(getReprocessOutputImageReader().getSurface());
reprocessRequests.add(builder.build());
}
SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
// Submit reprocess capture requests.
if (submitInBurst) {
mSession.captureBurst(reprocessRequests, captureCallback, mHandler);
} else {
for (CaptureRequest request : reprocessRequests) {
mSession.capture(request, captureCallback, mHandler);
}
}
// Abort after getting the first result
TotalCaptureResult reprocessResult = captureCallback.getTotalCaptureResultForRequest(reprocessRequests.get(0), CAPTURE_TIMEOUT_FRAMES);
mSession.abortCaptures();
// Wait until the session is ready again.
mSessionListener.getStateWaiter().waitForState(BlockingSessionCallback.SESSION_READY, SESSION_CLOSE_TIMEOUT_MS);
// Gather all failed requests.
ArrayList<CaptureFailure> failures = captureCallback.getCaptureFailures(NUM_REPROCESS_CAPTURES - 1);
ArrayList<CaptureRequest> failedRequests = new ArrayList<>();
for (CaptureFailure failure : failures) {
failedRequests.add(failure.getRequest());
}
// For each request that didn't fail must have a valid result.
for (int i = 1; i < reprocessRequests.size(); i++) {
CaptureRequest request = reprocessRequests.get(i);
if (!failedRequests.contains(request)) {
captureCallback.getTotalCaptureResultForRequest(request, CAPTURE_TIMEOUT_FRAMES);
}
}
// Drain the image reader listeners.
mFirstImageReaderListener.drain();
if (!mShareOneImageReader) {
mSecondImageReaderListener.drain();
}
// Make sure all input surfaces are released.
for (int i = 0; i < NUM_REPROCESS_CAPTURES; i++) {
mImageWriterListener.waitForImageReleased(CAPTURE_TIMEOUT_MS);
}
}
} finally {
closeReprossibleSession();
closeImageReaders();
}
}
use of android.hardware.camera2.CameraCaptureSession.CaptureCallback in project android_frameworks_base by DirtyUnicorns.
the class Camera2ReprocessCaptureTest method submitMixedCaptureBurstRequest.
/**
* Submit a burst request mixed with regular and reprocess requests.
*
* @param outputs An array of output surfaces. One output surface will be used in one request
* so the length of the array is the number of requests in a burst request.
* @param inputResults An array of input results. If it's null, all requests are regular
* requests. If an element is null, that element represents a regular
* request. If an element if not null, that element represents a reprocess
* request.
*
*/
private TotalCaptureResult[] submitMixedCaptureBurstRequest(Surface[] outputs, TotalCaptureResult[] inputResults) throws Exception {
if (outputs == null || outputs.length <= 0) {
throw new IllegalArgumentException("outputs must have at least 1 surface");
} else if (inputResults != null && inputResults.length != outputs.length) {
throw new IllegalArgumentException("The lengths of outputs and inputResults " + "don't match");
}
int numReprocessCaptures = 0;
SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
ArrayList<CaptureRequest> captureRequests = new ArrayList<>(outputs.length);
// is based on inputResults array.
for (int i = 0; i < outputs.length; i++) {
CaptureRequest.Builder builder;
boolean isReprocess = (inputResults != null && inputResults[i] != null);
if (isReprocess) {
builder = mCamera.createReprocessCaptureRequest(inputResults[i]);
numReprocessCaptures++;
} else {
builder = mCamera.createCaptureRequest(CAPTURE_TEMPLATE);
}
builder.addTarget(outputs[i]);
CaptureRequest request = builder.build();
assertTrue("Capture request reprocess type " + request.isReprocess() + " is wrong.", request.isReprocess() == isReprocess);
captureRequests.add(request);
}
if (captureRequests.size() == 1) {
mSession.capture(captureRequests.get(0), captureCallback, mHandler);
} else {
mSession.captureBurst(captureRequests, captureCallback, mHandler);
}
TotalCaptureResult[] results;
if (numReprocessCaptures == 0 || numReprocessCaptures == outputs.length) {
results = new TotalCaptureResult[outputs.length];
// If the requests are not mixed, they should come in order.
for (int i = 0; i < results.length; i++) {
results[i] = captureCallback.getTotalCaptureResultForRequest(captureRequests.get(i), CAPTURE_TIMEOUT_FRAMES);
}
} else {
// If the requests are mixed, they may not come in order.
results = captureCallback.getTotalCaptureResultsForRequests(captureRequests, CAPTURE_TIMEOUT_FRAMES * captureRequests.size());
}
// make sure all input surfaces are released.
for (int i = 0; i < numReprocessCaptures; i++) {
mImageWriterListener.waitForImageReleased(CAPTURE_TIMEOUT_MS);
}
return results;
}
use of android.hardware.camera2.CameraCaptureSession.CaptureCallback in project android_frameworks_base by DirtyUnicorns.
the class Camera2ReprocessCaptureTest method testReprocessRequestKeys.
/**
* Test the following keys in reprocess results match the keys in reprocess requests:
* 1. EDGE_MODE
* 2. NOISE_REDUCTION_MODE
* 3. REPROCESS_EFFECTIVE_EXPOSURE_FACTOR (only for YUV reprocess)
*/
private void testReprocessRequestKeys(String cameraId, Size inputSize, int inputFormat, Size reprocessOutputSize, int reprocessOutputFormat) throws Exception {
if (VERBOSE) {
Log.v(TAG, "testReprocessRequestKeys: cameraId: " + cameraId + " inputSize: " + inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " + reprocessOutputSize + " reprocessOutputFormat: " + reprocessOutputFormat);
}
final Integer[] EDGE_MODES = { CaptureRequest.EDGE_MODE_FAST, CaptureRequest.EDGE_MODE_HIGH_QUALITY, CaptureRequest.EDGE_MODE_OFF, CaptureRequest.EDGE_MODE_ZERO_SHUTTER_LAG };
final Integer[] NR_MODES = { CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY, CaptureRequest.NOISE_REDUCTION_MODE_OFF, CaptureRequest.NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG, CaptureRequest.NOISE_REDUCTION_MODE_FAST };
final Float[] EFFECTIVE_EXP_FACTORS = { null, 1.0f, 2.5f, 4.0f };
int numFrames = EDGE_MODES.length;
try {
setupImageReaders(inputSize, inputFormat, reprocessOutputSize, reprocessOutputFormat, numFrames);
setupReprocessableSession(/*previewSurface*/
null, numFrames);
// Prepare reprocess capture requests.
ArrayList<CaptureRequest> reprocessRequests = new ArrayList<>(numFrames);
for (int i = 0; i < numFrames; i++) {
TotalCaptureResult result = submitCaptureRequest(mFirstImageReader.getSurface(), /*inputResult*/
null);
mImageWriter.queueInputImage(mFirstImageReaderListener.getImage(CAPTURE_TIMEOUT_MS));
CaptureRequest.Builder builder = mCamera.createReprocessCaptureRequest(result);
builder.addTarget(getReprocessOutputImageReader().getSurface());
// Set reprocess request keys
builder.set(CaptureRequest.EDGE_MODE, EDGE_MODES[i]);
builder.set(CaptureRequest.NOISE_REDUCTION_MODE, NR_MODES[i]);
if (inputFormat == ImageFormat.YUV_420_888) {
builder.set(CaptureRequest.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR, EFFECTIVE_EXP_FACTORS[i]);
}
reprocessRequests.add(builder.build());
}
// Submit reprocess requests.
SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
mSession.captureBurst(reprocessRequests, captureCallback, mHandler);
TotalCaptureResult[] reprocessResults = captureCallback.getTotalCaptureResultsForRequests(reprocessRequests, CAPTURE_TIMEOUT_FRAMES);
for (int i = 0; i < numFrames; i++) {
// Verify result's keys
Integer resultEdgeMode = reprocessResults[i].get(CaptureResult.EDGE_MODE);
Integer resultNoiseReductionMode = reprocessResults[i].get(CaptureResult.NOISE_REDUCTION_MODE);
assertEquals("Reprocess result edge mode (" + resultEdgeMode + ") doesn't match requested edge mode (" + EDGE_MODES[i] + ")", resultEdgeMode, EDGE_MODES[i]);
assertEquals("Reprocess result noise reduction mode (" + resultNoiseReductionMode + ") doesn't match requested noise reduction mode (" + NR_MODES[i] + ")", resultNoiseReductionMode, NR_MODES[i]);
if (inputFormat == ImageFormat.YUV_420_888) {
Float resultEffectiveExposureFactor = reprocessResults[i].get(CaptureResult.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR);
assertEquals("Reprocess effective exposure factor (" + resultEffectiveExposureFactor + ") doesn't match requested " + "effective exposure factor (" + EFFECTIVE_EXP_FACTORS[i] + ")", resultEffectiveExposureFactor, EFFECTIVE_EXP_FACTORS[i]);
}
}
} finally {
closeReprossibleSession();
closeImageReaders();
}
}
use of android.hardware.camera2.CameraCaptureSession.CaptureCallback in project android_frameworks_base by DirtyUnicorns.
the class Camera2ReprocessCaptureTest method testReprocessJpegExif.
/**
* Test JPEG tags for reprocess requests. Reprocess result's JPEG tags and JPEG image's tags
* match reprocess request's JPEG tags.
*/
private void testReprocessJpegExif(String cameraId, Size inputSize, int inputFormat, Size reprocessOutputSize) throws Exception {
if (VERBOSE) {
Log.v(TAG, "testReprocessJpegExif: cameraId: " + cameraId + " inputSize: " + inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " + reprocessOutputSize);
}
Size[] thumbnailSizes = mStaticInfo.getAvailableThumbnailSizesChecked();
Size[] testThumbnailSizes = new Size[EXIF_TEST_DATA.length];
Arrays.fill(testThumbnailSizes, thumbnailSizes[thumbnailSizes.length - 1]);
// Make sure thumbnail size (0, 0) is covered.
testThumbnailSizes[0] = new Size(0, 0);
try {
setupImageReaders(inputSize, inputFormat, reprocessOutputSize, ImageFormat.JPEG, EXIF_TEST_DATA.length);
setupReprocessableSession(/*previewSurface*/
null, EXIF_TEST_DATA.length);
// Prepare reprocess capture requests.
ArrayList<CaptureRequest> reprocessRequests = new ArrayList<>(EXIF_TEST_DATA.length);
for (int i = 0; i < EXIF_TEST_DATA.length; i++) {
TotalCaptureResult result = submitCaptureRequest(mFirstImageReader.getSurface(), /*inputResult*/
null);
mImageWriter.queueInputImage(mFirstImageReaderListener.getImage(CAPTURE_TIMEOUT_MS));
CaptureRequest.Builder builder = mCamera.createReprocessCaptureRequest(result);
builder.addTarget(getReprocessOutputImageReader().getSurface());
// set jpeg keys
setJpegKeys(builder, EXIF_TEST_DATA[i], testThumbnailSizes[i], mCollector);
reprocessRequests.add(builder.build());
}
// Submit reprocess requests.
SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
mSession.captureBurst(reprocessRequests, captureCallback, mHandler);
TotalCaptureResult[] reprocessResults = captureCallback.getTotalCaptureResultsForRequests(reprocessRequests, CAPTURE_TIMEOUT_FRAMES);
for (int i = 0; i < EXIF_TEST_DATA.length; i++) {
// Verify output image's and result's JPEG EXIF data.
Image image = getReprocessOutputImageReaderListener().getImage(CAPTURE_TIMEOUT_MS);
verifyJpegKeys(image, reprocessResults[i], reprocessOutputSize, testThumbnailSizes[i], EXIF_TEST_DATA[i], mStaticInfo, mCollector);
image.close();
}
} finally {
closeReprossibleSession();
closeImageReaders();
}
}
Aggregations