use of android.util.Size in project material-camera by afollestad.
the class Camera2Fragment method chooseVideoSize.
private static Size chooseVideoSize(BaseCaptureInterface ci, Size[] choices) {
Size backupSize = null;
for (Size size : choices) {
if (size.getHeight() <= ci.videoPreferredHeight()) {
if (size.getWidth() == size.getHeight() * ci.videoPreferredAspect())
return size;
if (ci.videoPreferredHeight() >= size.getHeight())
backupSize = size;
}
}
if (backupSize != null)
return backupSize;
LOG(Camera2Fragment.class, "Couldn't find any suitable video size");
return choices[choices.length - 1];
}
use of android.util.Size in project platform_frameworks_base by android.
the class ImageUtils method imageCopy.
/**
* <p>
* Copy source image data to destination Image.
* </p>
* <p>
* Only support the copy between two non-{@link ImageFormat#PRIVATE PRIVATE} format
* images with same properties (format, size, etc.). The data from the
* source image will be copied to the byteBuffers from the destination Image
* starting from position zero, and the destination image will be rewound to
* zero after copy is done.
* </p>
*
* @param src The source image to be copied from.
* @param dst The destination image to be copied to.
* @throws IllegalArgumentException If the source and destination images
* have different format, or one of the images is not copyable.
*/
public static void imageCopy(Image src, Image dst) {
if (src == null || dst == null) {
throw new IllegalArgumentException("Images should be non-null");
}
if (src.getFormat() != dst.getFormat()) {
throw new IllegalArgumentException("Src and dst images should have the same format");
}
if (src.getFormat() == ImageFormat.PRIVATE || dst.getFormat() == ImageFormat.PRIVATE) {
throw new IllegalArgumentException("PRIVATE format images are not copyable");
}
if (src.getFormat() == ImageFormat.RAW_PRIVATE) {
throw new IllegalArgumentException("Copy of RAW_OPAQUE format has not been implemented");
}
if (!(dst.getOwner() instanceof ImageWriter)) {
throw new IllegalArgumentException("Destination image is not from ImageWriter. Only" + " the images from ImageWriter are writable");
}
Size srcSize = new Size(src.getWidth(), src.getHeight());
Size dstSize = new Size(dst.getWidth(), dst.getHeight());
if (!srcSize.equals(dstSize)) {
throw new IllegalArgumentException("source image size " + srcSize + " is different" + " with " + "destination image size " + dstSize);
}
Plane[] srcPlanes = src.getPlanes();
Plane[] dstPlanes = dst.getPlanes();
ByteBuffer srcBuffer = null;
ByteBuffer dstBuffer = null;
for (int i = 0; i < srcPlanes.length; i++) {
int srcRowStride = srcPlanes[i].getRowStride();
int dstRowStride = dstPlanes[i].getRowStride();
srcBuffer = srcPlanes[i].getBuffer();
dstBuffer = dstPlanes[i].getBuffer();
if (!(srcBuffer.isDirect() && dstBuffer.isDirect())) {
throw new IllegalArgumentException("Source and destination ByteBuffers must be" + " direct byteBuffer!");
}
if (srcPlanes[i].getPixelStride() != dstPlanes[i].getPixelStride()) {
throw new IllegalArgumentException("Source plane image pixel stride " + srcPlanes[i].getPixelStride() + " must be same as destination image pixel stride " + dstPlanes[i].getPixelStride());
}
int srcPos = srcBuffer.position();
srcBuffer.rewind();
dstBuffer.rewind();
if (srcRowStride == dstRowStride) {
// Fast path, just copy the content if the byteBuffer all together.
dstBuffer.put(srcBuffer);
} else {
// Source and destination images may have different alignment requirements,
// therefore may have different strides. Copy row by row for such case.
int srcOffset = srcBuffer.position();
int dstOffset = dstBuffer.position();
Size effectivePlaneSize = getEffectivePlaneSizeForImage(src, i);
int srcByteCount = effectivePlaneSize.getWidth() * srcPlanes[i].getPixelStride();
for (int row = 0; row < effectivePlaneSize.getHeight(); row++) {
if (row == effectivePlaneSize.getHeight() - 1) {
// Special case for NV21 backed YUV420_888: need handle the last row
// carefully to avoid memory corruption. Check if we have enough bytes to
// copy.
int remainingBytes = srcBuffer.remaining() - srcOffset;
if (srcByteCount > remainingBytes) {
srcByteCount = remainingBytes;
}
}
directByteBufferCopy(srcBuffer, srcOffset, dstBuffer, dstOffset, srcByteCount);
srcOffset += srcRowStride;
dstOffset += dstRowStride;
}
}
srcBuffer.position(srcPos);
dstBuffer.rewind();
}
}
use of android.util.Size in project platform_frameworks_base by android.
the class CameraTestUtils method verifyJpegKeys.
/**
* Verify the JPEG EXIF and JPEG related keys in a capture result are expected.
* - Capture request get values are same as were set.
* - capture result's exif data is the same as was set by
* the capture request.
* - new tags in the result set by the camera service are
* present and semantically correct.
*
* @param image The output JPEG image to verify.
* @param captureResult The capture result to verify.
* @param expectedSize The expected JPEG size.
* @param expectedThumbnailSize The expected thumbnail size.
* @param expectedExifData The expected EXIF data
* @param staticInfo The static metadata for the camera device.
* @param jpegFilename The filename to dump the jpeg to.
* @param collector The camera error collector to collect errors.
*/
public static void verifyJpegKeys(Image image, CaptureResult captureResult, Size expectedSize, Size expectedThumbnailSize, ExifTestData expectedExifData, StaticMetadata staticInfo, CameraErrorCollector collector) throws Exception {
basicValidateJpegImage(image, expectedSize);
byte[] jpegBuffer = getDataFromImage(image);
// Have to dump into a file to be able to use ExifInterface
String jpegFilename = DEBUG_FILE_NAME_BASE + "/verifyJpegKeys.jpeg";
dumpFile(jpegFilename, jpegBuffer);
ExifInterface exif = new ExifInterface(jpegFilename);
if (expectedThumbnailSize.equals(new Size(0, 0))) {
collector.expectTrue("Jpeg shouldn't have thumbnail when thumbnail size is (0, 0)", !exif.hasThumbnail());
} else {
collector.expectTrue("Jpeg must have thumbnail for thumbnail size " + expectedThumbnailSize, exif.hasThumbnail());
}
// Validate capture result vs. request
Size resultThumbnailSize = captureResult.get(CaptureResult.JPEG_THUMBNAIL_SIZE);
int orientationTested = expectedExifData.jpegOrientation;
// Legacy shim always doesn't rotate thumbnail size
if ((orientationTested == 90 || orientationTested == 270) && staticInfo.isHardwareLevelLimitedOrBetter()) {
int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, /*defaultValue*/
-1);
if (exifOrientation == ExifInterface.ORIENTATION_UNDEFINED) {
// Device physically rotated image+thumbnail data
// Expect thumbnail size to be also rotated
resultThumbnailSize = new Size(resultThumbnailSize.getHeight(), resultThumbnailSize.getWidth());
}
}
collector.expectEquals("JPEG thumbnail size result and request should match", expectedThumbnailSize, resultThumbnailSize);
if (collector.expectKeyValueNotNull(captureResult, CaptureResult.JPEG_GPS_LOCATION) != null) {
collector.expectTrue("GPS location result and request should match.", areGpsFieldsEqual(expectedExifData.gpsLocation, captureResult.get(CaptureResult.JPEG_GPS_LOCATION)));
}
collector.expectEquals("JPEG orientation result and request should match", expectedExifData.jpegOrientation, captureResult.get(CaptureResult.JPEG_ORIENTATION));
collector.expectEquals("JPEG quality result and request should match", expectedExifData.jpegQuality, captureResult.get(CaptureResult.JPEG_QUALITY));
collector.expectEquals("JPEG thumbnail quality result and request should match", expectedExifData.thumbnailQuality, captureResult.get(CaptureResult.JPEG_THUMBNAIL_QUALITY));
// Validate other exif tags for all non-legacy devices
if (!staticInfo.isHardwareLevelLegacy()) {
verifyJpegExifExtraTags(exif, expectedSize, captureResult, staticInfo, collector);
}
}
use of android.util.Size in project platform_frameworks_base by android.
the class Camera2RecordingTest method basicRecordingTestByCamera.
/**
* Test camera recording by using each available CamcorderProfile for a
* given camera. preview size is set to the video size.
*/
private void basicRecordingTestByCamera(int[] camcorderProfileList, boolean useVideoStab) throws Exception {
Size maxPreviewSize = mOrderedPreviewSizes.get(0);
List<Range<Integer>> fpsRanges = Arrays.asList(mStaticInfo.getAeAvailableTargetFpsRangesChecked());
int cameraId = Integer.parseInt(mCamera.getId());
int maxVideoFrameRate = -1;
for (int profileId : camcorderProfileList) {
if (!CamcorderProfile.hasProfile(cameraId, profileId) || allowedUnsupported(cameraId, profileId)) {
continue;
}
CamcorderProfile profile = CamcorderProfile.get(cameraId, profileId);
Size videoSz = new Size(profile.videoFrameWidth, profile.videoFrameHeight);
Range<Integer> fpsRange = new Range(profile.videoFrameRate, profile.videoFrameRate);
if (maxVideoFrameRate < profile.videoFrameRate) {
maxVideoFrameRate = profile.videoFrameRate;
}
if (mStaticInfo.isHardwareLevelLegacy() && (videoSz.getWidth() > maxPreviewSize.getWidth() || videoSz.getHeight() > maxPreviewSize.getHeight())) {
// Skip. Legacy mode can only do recording up to max preview size
continue;
}
assertTrue("Video size " + videoSz.toString() + " for profile ID " + profileId + " must be one of the camera device supported video size!", mSupportedVideoSizes.contains(videoSz));
assertTrue("Frame rate range " + fpsRange + " (for profile ID " + profileId + ") must be one of the camera device available FPS range!", fpsRanges.contains(fpsRange));
if (VERBOSE) {
Log.v(TAG, "Testing camera recording with video size " + videoSz.toString());
}
// Configure preview and recording surfaces.
mOutMediaFileName = VIDEO_FILE_PATH + "/test_video.mp4";
if (DEBUG_DUMP) {
mOutMediaFileName = VIDEO_FILE_PATH + "/test_video_" + cameraId + "_" + videoSz.toString() + ".mp4";
}
prepareRecordingWithProfile(profile);
// prepare preview surface by using video size.
updatePreviewSurfaceWithVideo(videoSz, profile.videoFrameRate);
// Start recording
SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
startRecording(/* useMediaRecorder */
true, resultListener, useVideoStab);
// Record certain duration.
SystemClock.sleep(RECORDING_DURATION_MS);
// Stop recording and preview
stopRecording(/* useMediaRecorder */
true);
// Convert number of frames camera produced into the duration in unit of ms.
int durationMs = (int) (resultListener.getTotalNumFrames() * 1000.0f / profile.videoFrameRate);
if (VERBOSE) {
Log.v(TAG, "video frame rate: " + profile.videoFrameRate + ", num of frames produced: " + resultListener.getTotalNumFrames());
}
// Validation.
validateRecording(videoSz, durationMs);
}
if (maxVideoFrameRate != -1) {
// At least one CamcorderProfile is present, check FPS
assertTrue("At least one CamcorderProfile must support >= 24 FPS", maxVideoFrameRate >= 24);
}
}
use of android.util.Size in project platform_frameworks_base by android.
the class Camera2RecordingTest method constrainedHighSpeedRecording.
private void constrainedHighSpeedRecording() throws Exception {
for (String id : mCameraIds) {
try {
Log.i(TAG, "Testing constrained high speed recording for camera " + id);
// Re-use the MediaRecorder object for the same camera device.
mMediaRecorder = new MediaRecorder();
openDevice(id);
if (!mStaticInfo.isConstrainedHighSpeedVideoSupported()) {
Log.i(TAG, "Camera " + id + " doesn't support high speed recording, skipping.");
continue;
}
// Test iteration starts...
for (int iteration = 0; iteration < getIterationCount(); ++iteration) {
Log.v(TAG, String.format("Constrained high speed recording: %d/%d", iteration + 1, getIterationCount()));
StreamConfigurationMap config = mStaticInfo.getValueFromKeyNonNull(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] highSpeedVideoSizes = config.getHighSpeedVideoSizes();
for (Size size : highSpeedVideoSizes) {
List<Range<Integer>> fixedFpsRanges = getHighSpeedFixedFpsRangeForSize(config, size);
mCollector.expectTrue("Unable to find the fixed frame rate fps range for " + "size " + size, fixedFpsRanges.size() > 0);
// Test recording for each FPS range
for (Range<Integer> fpsRange : fixedFpsRanges) {
int captureRate = fpsRange.getLower();
final int VIDEO_FRAME_RATE = 30;
// Skip the test if the highest recording FPS supported by CamcorderProfile
if (fpsRange.getUpper() > getFpsFromHighSpeedProfileForSize(size)) {
Log.w(TAG, "high speed recording " + size + "@" + captureRate + "fps" + " is not supported by CamcorderProfile");
continue;
}
mOutMediaFileName = VIDEO_FILE_PATH + "/test_cslowMo_video_" + captureRate + "fps_" + id + "_" + size.toString() + ".mp4";
prepareRecording(size, VIDEO_FRAME_RATE, captureRate);
// prepare preview surface by using video size.
updatePreviewSurfaceWithVideo(size, captureRate);
// Start recording
SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
startSlowMotionRecording(/*useMediaRecorder*/
true, VIDEO_FRAME_RATE, captureRate, fpsRange, resultListener, /*useHighSpeedSession*/
true);
// Record certain duration.
SystemClock.sleep(RECORDING_DURATION_MS);
// Stop recording and preview
stopRecording(/*useMediaRecorder*/
true);
// Convert number of frames camera produced into the duration in unit of ms.
int durationMs = (int) (resultListener.getTotalNumFrames() * 1000.0f / VIDEO_FRAME_RATE);
// Validation.
validateRecording(size, durationMs);
}
getResultPrinter().printStatus(getIterationCount(), iteration + 1, id);
Thread.sleep(getTestWaitIntervalMs());
}
}
} finally {
closeDevice();
releaseRecorder();
}
}
}
Aggregations