Skip to content
This repository has been archived by the owner on Dec 29, 2022. It is now read-only.

Preview callback #174

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

buildscript {
repositories {
jcenter()

}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0'
classpath 'com.android.tools.build:gradle:2.3.3'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand All @@ -14,7 +14,7 @@ buildscript {

allprojects {
repositories {
jcenter()
flatDir{ dirs "../test-libs" }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.media.Image;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
Expand Down Expand Up @@ -235,7 +237,11 @@ private Handler getBackgroundHandler() {
}

private CameraView.Callback mCallback
= new CameraView.Callback() {
= new CameraView.Callback()
{
@Override
public void onPreviewFrame(CameraView cameraView, byte[] data, int width, int height, int format) {
}

@Override
public void onCameraOpened(CameraView cameraView) {
Expand Down
4 changes: 3 additions & 1 deletion demo/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:background="@android:color/black"/>
android:background="@android:color/black"
app:preferredPreviewFormat="NV21"
/>

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
Expand Down
6 changes: 6 additions & 0 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,18 @@ android {
}
}


dependencies {
compile "com.android.support:support-annotations:$supportLibraryVersion"
compile "com.android.support:support-v4:$supportLibraryVersion"


// Tests
testCompile 'org.hamcrest:hamcrest-core:1.3'
testCompile 'junit:junit:4.12'

androidTestCompile 'org.hamcrest:hamcrest-core:1.3'
androidTestCompile 'junit:junit:4.12'
androidTestCompile('com.android.support.test:runner:0.5') {
exclude module: 'support-annotations'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v4.util.SparseArrayCompat;
import android.util.Log;
import android.view.SurfaceHolder;

import java.io.IOException;
Expand All @@ -36,6 +38,7 @@ class Camera1 extends CameraViewImpl {
private static final int INVALID_CAMERA_ID = -1;

private static final SparseArrayCompat<String> FLASH_MODES = new SparseArrayCompat<>();
private static final String TAG = "Camera1";

static {
FLASH_MODES.put(Constants.FLASH_OFF, Camera.Parameters.FLASH_MODE_OFF);
Expand Down Expand Up @@ -70,15 +73,37 @@ class Camera1 extends CameraViewImpl {
private int mFlash;

private int mDisplayOrientation;
private int mPreviewFormat;

Camera1(Callback callback, PreviewImpl preview) {
Camera.PreviewCallback mPreviewCallback;


Camera1(final Callback callback, PreviewImpl preview) {
super(callback, preview);

mPreviewCallback = new Camera.PreviewCallback() {
@Override public void onPreviewFrame(byte[] data, Camera camera)
{
callback.onPreviewFrame( data,
mCameraParameters.getPreviewSize().width,
mCameraParameters.getPreviewSize().height,
mCameraParameters.getPreviewFormat());
}
};


preview.setCallback(new PreviewImpl.Callback() {
@Override
public void onSurfaceChanged() {
if (mCamera != null) {
setUpPreview();
adjustCameraParameters();

mCamera.setPreviewCallback(mPreviewCallback);
}
else
{
Log.d(TAG, "Cannot set preview callback because mCamera == null");
}
}
});
Expand All @@ -99,16 +124,21 @@ boolean start() {
@Override
void stop() {
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
}

mShowingPreview = false;
releaseCamera();
}



// Suppresses Camera#setPreviewTexture
@SuppressLint("NewApi")
void setUpPreview() {
try {

if (mPreview.getOutputClass() == SurfaceHolder.class) {
final boolean needsToStopPreview = mShowingPreview && Build.VERSION.SDK_INT < 14;
if (needsToStopPreview) {
Expand All @@ -131,6 +161,24 @@ boolean isCameraOpened() {
return mCamera != null;
}


@Override
void setPreferredPreviewFormat(int imageFormat) {
if (mPreviewFormat == imageFormat) {
return;
}
mPreviewFormat = imageFormat;
if (isCameraOpened()) {
stop();
start();
}
}

@Override
public int getPreferredPreviewFormat() {
return mPreviewFormat;
}

@Override
void setFacing(int facing) {
if (mFacing == facing) {
Expand Down Expand Up @@ -334,6 +382,10 @@ void adjustCameraParameters() {
if (mShowingPreview) {
mCamera.stopPreview();
}

if(mCameraParameters.getSupportedPreviewFormats().contains(getPreferredPreviewFormat())) {
mCameraParameters.setPreviewFormat(getPreferredPreviewFormat());
}
mCameraParameters.setPreviewSize(size.getWidth(), size.getHeight());
mCameraParameters.setPictureSize(pictureSize.getWidth(), pictureSize.getHeight());
mCameraParameters.setRotation(calcCameraRotation(mDisplayOrientation));
Expand Down
101 changes: 96 additions & 5 deletions library/src/main/api21/com/google/android/cameraview/Camera2.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
import android.util.SparseIntArray;
import android.view.Surface;

import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Set;
import java.util.SortedSet;
Expand Down Expand Up @@ -151,10 +153,44 @@ public void onReady() {

};

private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
private final ImageReader.OnImageAvailableListener mOnPreviewAvailableListener
= new ImageReader.OnImageAvailableListener() {

@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireLatestImage();
if (image != null) {
try {
ArrayList<byte[]> buffers = new ArrayList<>();
Image.Plane[] planes = image.getPlanes();
if(planes.length == 0)
{return;}

//concatenate planes into a single byte array to be compatible with Camera1
for (int i = 0; i < planes.length; i++) {
ByteBuffer buffer = planes[i].getBuffer();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
buffers.add(data);
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
for (int i = 0; i < buffers.size(); i++) {
outputStream.write(buffers.get(i), 0, buffers.get(i).length);
}

mCallback.onPreviewFrame(
outputStream.toByteArray(), image.getWidth(), image.getHeight(), image.getFormat()
);
} finally {
image.close();
}
}
}
};

private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
= new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
try (Image image = reader.acquireNextImage()) {
Image.Plane[] planes = image.getPlanes();
Expand Down Expand Up @@ -182,6 +218,8 @@ public void onImageAvailable(ImageReader reader) {

private ImageReader mImageReader;

private ImageReader mPreviewReader;

private final SizeMap mPreviewSizes = new SizeMap();

private final SizeMap mPictureSizes = new SizeMap();
Expand All @@ -196,6 +234,9 @@ public void onImageAvailable(ImageReader reader) {

private int mDisplayOrientation;

private int mPreviewFormat = ImageFormat.YUV_420_888;
private int[] mOutputFormats;

Camera2(Callback callback, PreviewImpl preview, Context context) {
super(callback, preview);
mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
Expand Down Expand Up @@ -232,6 +273,12 @@ void stop() {
mImageReader.close();
mImageReader = null;
}

if(mPreviewReader != null)
{
mPreviewReader.close();
mPreviewReader = null;
}
}

@Override
Expand All @@ -256,6 +303,24 @@ int getFacing() {
return mFacing;
}

@Override
void setPreferredPreviewFormat(int imageFormat) {
if (mPreviewFormat == imageFormat) {
return;
}

mPreviewFormat = imageFormat;
if (isCameraOpened()) {
stop();
start();
}
}

@Override
public int getPreferredPreviewFormat() {
return mPreviewFormat;
}

@Override
Set<AspectRatio> getSupportedAspectRatios() {
return mPreviewSizes.ratios();
Expand Down Expand Up @@ -382,8 +447,7 @@ private boolean chooseCameraIdByFacing() {
mCameraCharacteristics = mCameraManager.getCameraCharacteristics(mCameraId);
Integer level = mCameraCharacteristics.get(
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
if (level == null ||
level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
if (level == null ) {
return false;
}
Integer internal = mCameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
Expand Down Expand Up @@ -435,6 +499,8 @@ private void collectCameraInfo() {
if (!mPreviewSizes.ratios().contains(mAspectRatio)) {
mAspectRatio = mPreviewSizes.ratios().iterator().next();
}

mOutputFormats = map.getOutputFormats();
}

protected void collectPictureSizes(SizeMap sizes, StreamConfigurationMap map) {
Expand All @@ -451,6 +517,29 @@ private void prepareImageReader() {
mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
ImageFormat.JPEG, /* maxImages */ 2);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);


if (mPreviewReader != null) {
mPreviewReader.close();
}
Size previewSize = mPreviewSizes.sizes(mAspectRatio).last();

int fmt = ImageFormat.YUV_420_888;
if (mOutputFormats != null) {
for (int format : mOutputFormats) {
if (format == getPreferredPreviewFormat()) {
fmt = format;
break;
}
}
}

mPreviewReader = ImageReader.newInstance( previewSize.getWidth(),
previewSize.getHeight(),
fmt,
2);

mPreviewReader.setOnImageAvailableListener( mOnPreviewAvailableListener, null );
}

/**
Expand Down Expand Up @@ -478,9 +567,11 @@ void startCaptureSession() {
mPreview.setBufferSize(previewSize.getWidth(), previewSize.getHeight());
Surface surface = mPreview.getSurface();
try {
mPreviewRequestBuilder = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
mPreviewRequestBuilder.addTarget(surface);
mCamera.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
mPreviewRequestBuilder.addTarget(mPreviewReader.getSurface());

mCamera.createCaptureSession( Arrays.asList(surface, mImageReader.getSurface(), mPreviewReader.getSurface()),
mSessionCallback, null);
} catch (CameraAccessException e) {
throw new RuntimeException("Failed to start camera session");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.android.cameraview;

import android.media.Image;
import android.view.View;

import java.util.Set;
Expand Down Expand Up @@ -46,6 +47,9 @@ View getView() {

abstract void setFacing(int facing);

abstract void setPreferredPreviewFormat(int imageFormat);
abstract int getPreferredPreviewFormat();

abstract int getFacing();

abstract Set<AspectRatio> getSupportedAspectRatios();
Expand Down Expand Up @@ -77,6 +81,7 @@ interface Callback {

void onPictureTaken(byte[] data);

void onPreviewFrame(byte[] data, int width, int height, int format);
}

}
Loading