Search in sources :

Example 1 with Size

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];
}
Also used : Size(android.util.Size)

Example 2 with Size

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();
    }
}
Also used : Plane(android.media.Image.Plane) Size(android.util.Size) ByteBuffer(java.nio.ByteBuffer)

Example 3 with Size

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);
    }
}
Also used : Size(android.util.Size) ExifInterface(android.media.ExifInterface)

Example 4 with Size

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);
    }
}
Also used : Size(android.util.Size) CamcorderProfile(android.media.CamcorderProfile) Range(android.util.Range) SimpleCaptureCallback(com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleCaptureCallback)

Example 5 with Size

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();
        }
    }
}
Also used : Size(android.util.Size) StreamConfigurationMap(android.hardware.camera2.params.StreamConfigurationMap) MediaRecorder(android.media.MediaRecorder) Range(android.util.Range) SimpleCaptureCallback(com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleCaptureCallback)

Aggregations

Size (android.util.Size)320 ArrayList (java.util.ArrayList)66 StreamConfigurationMap (android.hardware.camera2.params.StreamConfigurationMap)41 Rect (android.graphics.Rect)40 CaptureRequest (android.hardware.camera2.CaptureRequest)40 Range (android.util.Range)40 Surface (android.view.Surface)35 SimpleCaptureCallback (com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleCaptureCallback)35 Camera (android.hardware.Camera)30 CameraCharacteristics (android.hardware.camera2.CameraCharacteristics)26 Point (android.graphics.Point)22 Image (android.media.Image)21 SimpleImageReaderListener (com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleImageReaderListener)20 MeteringRectangle (android.hardware.camera2.params.MeteringRectangle)15 CamcorderProfile (android.media.CamcorderProfile)15 Pair (android.util.Pair)15 CameraTestUtils.getDataFromImage (com.android.mediaframeworktest.helpers.CameraTestUtils.getDataFromImage)15 SurfaceTexture (android.graphics.SurfaceTexture)10 Parameters (android.hardware.Camera.Parameters)10 CaptureResult (android.hardware.camera2.CaptureResult)10