use of android.hardware.camera2.CaptureRequest in project platform_frameworks_base by android.
the class Camera2ReprocessCaptureTest method testReprocessTimestamps.
/**
* Test timestamps for reprocess requests. Reprocess request's shutter timestamp, result's
* sensor timestamp, and output image's timestamp should match the reprocess input's timestamp.
*/
private void testReprocessTimestamps(String cameraId, Size inputSize, int inputFormat, Size reprocessOutputSize, int reprocessOutputFormat) throws Exception {
if (VERBOSE) {
Log.v(TAG, "testReprocessTimestamps: 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);
// Prepare reprocess capture requests.
ArrayList<CaptureRequest> reprocessRequests = new ArrayList<>(NUM_REPROCESS_CAPTURES);
ArrayList<Long> expectedTimestamps = 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());
// Reprocess result's timestamp should match input image's timestamp.
expectedTimestamps.add(result.get(CaptureResult.SENSOR_TIMESTAMP));
}
// Submit reprocess requests.
SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
mSession.captureBurst(reprocessRequests, captureCallback, mHandler);
// Verify we get the expected timestamps.
for (int i = 0; i < reprocessRequests.size(); i++) {
captureCallback.waitForCaptureStart(reprocessRequests.get(i), expectedTimestamps.get(i), CAPTURE_TIMEOUT_FRAMES);
}
TotalCaptureResult[] reprocessResults = captureCallback.getTotalCaptureResultsForRequests(reprocessRequests, CAPTURE_TIMEOUT_FRAMES);
for (int i = 0; i < expectedTimestamps.size(); i++) {
// Verify the result timestamps match the input image's timestamps.
long expected = expectedTimestamps.get(i);
long timestamp = reprocessResults[i].get(CaptureResult.SENSOR_TIMESTAMP);
assertEquals("Reprocess result timestamp (" + timestamp + ") doesn't match input " + "image's timestamp (" + expected + ")", expected, timestamp);
// Verify the reprocess output image timestamps match the input image's timestamps.
Image image = getReprocessOutputImageReaderListener().getImage(CAPTURE_TIMEOUT_MS);
timestamp = image.getTimestamp();
image.close();
assertEquals("Reprocess output timestamp (" + timestamp + ") doesn't match input " + "image's timestamp (" + expected + ")", expected, timestamp);
}
// 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.CaptureRequest in project platform_frameworks_base by android.
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();
}
}
use of android.hardware.camera2.CaptureRequest in project platform_frameworks_base by android.
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.CaptureRequest in project platform_frameworks_base by android.
the class CameraDeviceImpl method submitCaptureRequest.
private int submitCaptureRequest(List<CaptureRequest> requestList, CaptureCallback callback, Handler handler, boolean repeating) throws CameraAccessException {
// Need a valid handler, or current thread needs to have a looper, if
// callback is valid
handler = checkHandler(handler, callback);
// Make sure that there all requests have at least 1 surface; all surfaces are non-null
for (CaptureRequest request : requestList) {
if (request.getTargets().isEmpty()) {
throw new IllegalArgumentException("Each request must have at least one Surface target");
}
for (Surface surface : request.getTargets()) {
if (surface == null) {
throw new IllegalArgumentException("Null Surface targets are not allowed");
}
}
}
synchronized (mInterfaceLock) {
checkIfCameraClosedOrInError();
if (repeating) {
stopRepeating();
}
SubmitInfo requestInfo;
CaptureRequest[] requestArray = requestList.toArray(new CaptureRequest[requestList.size()]);
requestInfo = mRemoteDevice.submitRequestList(requestArray, repeating);
if (DEBUG) {
Log.v(TAG, "last frame number " + requestInfo.getLastFrameNumber());
}
if (callback != null) {
mCaptureCallbackMap.put(requestInfo.getRequestId(), new CaptureCallbackHolder(callback, requestList, handler, repeating, mNextSessionId - 1));
} else {
if (DEBUG) {
Log.d(TAG, "Listen for request " + requestInfo.getRequestId() + " is null");
}
}
if (repeating) {
if (mRepeatingRequestId != REQUEST_ID_NONE) {
checkEarlyTriggerSequenceComplete(mRepeatingRequestId, requestInfo.getLastFrameNumber());
}
mRepeatingRequestId = requestInfo.getRequestId();
} else {
mRequestLastFrameNumbersList.add(new RequestLastFrameNumbersHolder(requestList, requestInfo));
}
if (mIdle) {
mDeviceHandler.post(mCallOnActive);
}
mIdle = false;
return requestInfo.getRequestId();
}
}
use of android.hardware.camera2.CaptureRequest in project platform_frameworks_base by android.
the class LegacyCameraDevice method submitRequestList.
/**
* Submit a burst of capture requests.
*
* @param requestList a list of capture requests to execute.
* @param repeating {@code true} if this burst is repeating.
* @return the submission info, including the new request id, and the last frame number, which
* contains either the frame number of the last frame that will be returned for this request,
* or the frame number of the last frame that will be returned for the current repeating
* request if this burst is set to be repeating.
*/
public SubmitInfo submitRequestList(CaptureRequest[] requestList, boolean repeating) {
if (requestList == null || requestList.length == 0) {
Log.e(TAG, "submitRequestList - Empty/null requests are not allowed");
throw new ServiceSpecificException(BAD_VALUE, "submitRequestList - Empty/null requests are not allowed");
}
List<Long> surfaceIds;
try {
surfaceIds = (mConfiguredSurfaces == null) ? new ArrayList<Long>() : getSurfaceIds(mConfiguredSurfaces);
} catch (BufferQueueAbandonedException e) {
throw new ServiceSpecificException(BAD_VALUE, "submitRequestList - configured surface is abandoned.");
}
// Make sure that there all requests have at least 1 surface; all surfaces are non-null
for (CaptureRequest request : requestList) {
if (request.getTargets().isEmpty()) {
Log.e(TAG, "submitRequestList - " + "Each request must have at least one Surface target");
throw new ServiceSpecificException(BAD_VALUE, "submitRequestList - " + "Each request must have at least one Surface target");
}
for (Surface surface : request.getTargets()) {
if (surface == null) {
Log.e(TAG, "submitRequestList - Null Surface targets are not allowed");
throw new ServiceSpecificException(BAD_VALUE, "submitRequestList - Null Surface targets are not allowed");
} else if (mConfiguredSurfaces == null) {
Log.e(TAG, "submitRequestList - must configure " + " device with valid surfaces before submitting requests");
throw new ServiceSpecificException(INVALID_OPERATION, "submitRequestList - must configure " + " device with valid surfaces before submitting requests");
} else if (!containsSurfaceId(surface, surfaceIds)) {
Log.e(TAG, "submitRequestList - cannot use a surface that wasn't configured");
throw new ServiceSpecificException(BAD_VALUE, "submitRequestList - cannot use a surface that wasn't configured");
}
}
}
// TODO: further validation of request here
mIdle.close();
return mRequestThreadManager.submitCaptureRequests(requestList, repeating);
}
Aggregations