@ -63,6 +63,7 @@ class Camera1 extends CameraImpl {
private ConstantMapper . MapperImpl mMapper = new ConstantMapper . Mapper1 ( ) ;
private ConstantMapper . MapperImpl mMapper = new ConstantMapper . Mapper1 ( ) ;
private boolean mIsSetup = false ;
private boolean mIsSetup = false ;
private boolean mIsCapturingImage = false ;
private boolean mIsCapturingImage = false ;
private boolean mIsCapturingVideo = false ;
private final Object mLock = new Object ( ) ;
private final Object mLock = new Object ( ) ;
@ -360,57 +361,62 @@ class Camera1 extends CameraImpl {
void captureImage ( ) {
void captureImage ( ) {
if ( mIsCapturingImage ) return ;
if ( mIsCapturingImage ) return ;
if ( ! isCameraOpened ( ) ) return ;
if ( ! isCameraOpened ( ) ) return ;
switch ( mSessionType ) {
if ( mIsCapturingVideo | | mSessionType = = SESSION_TYPE_VIDEO ) {
case SESSION_TYPE_PICTURE :
captureSnapshot ( ) ;
// Set boolean to wait for image callback
return ;
mIsCapturingImage = true ;
}
synchronized ( mLock ) {
Camera . Parameters parameters = mCamera . getParameters ( ) ;
// Set boolean to wait for image callback
parameters . setRotation ( computeExifOrientation ( ) ) ;
mIsCapturingImage = true ;
mCamera . setParameters ( parameters ) ;
synchronized ( mLock ) {
}
Camera . Parameters parameters = mCamera . getParameters ( ) ;
mCamera . takePicture ( null , null , null ,
parameters . setRotation ( computeExifRotation ( ) ) ;
new Camera . PictureCallback ( ) {
// TODO: add flipping
@Override
mCamera . setParameters ( parameters ) ;
public void onPictureTaken ( byte [ ] data , Camera camera ) {
}
mCameraListener . onPictureTaken ( data ) ;
mCamera . takePicture ( null , null , null ,
mIsCapturingImage = false ;
new Camera . PictureCallback ( ) {
camera . startPreview ( ) ; // This is needed, read somewhere in the docs.
}
} ) ;
break ;
case SESSION_TYPE_VIDEO :
// If we are in a video session, camera captures are fast captures coming
// from the preview stream.
// TODO: will this work while recording a video? test...
mIsCapturingImage = true ;
mCamera . setOneShotPreviewCallback ( new Camera . PreviewCallback ( ) {
@Override
@Override
public void onPreviewFrame ( final byte [ ] data , Camera camera ) {
public void onPictureTaken ( byte [ ] data , Camera camera ) {
// Got to rotate the preview frame, since byte[] data here does not include
mCameraListener . onPictureTaken ( data ) ;
// EXIF tags automatically set by camera. So either we add EXIF, or we rotate.
mIsCapturingImage = false ;
Camera . Parameters params = mCamera . getParameters ( ) ;
camera . startPreview ( ) ; // This is needed, read somewhere in the docs.
final int rotation = computeExifOrientation ( ) ;
final boolean flip = rotation % 180 ! = 0 ;
final int preWidth = mPreviewSize . getWidth ( ) ;
final int preHeight = mPreviewSize . getHeight ( ) ;
final int postWidth = flip ? preHeight : preWidth ;
final int postHeight = flip ? preWidth : preHeight ;
final int format = params . getPreviewFormat ( ) ;
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
byte [ ] rotatedData = RotationHelper . rotate ( data , preWidth , preHeight , rotation ) ;
YuvImage yuv = new YuvImage ( rotatedData , format , postWidth , postHeight , null ) ;
mCameraListener . processYuvImage ( yuv ) ;
mIsCapturingImage = false ;
}
} ) . start ( ) ;
}
}
} ) ;
} ) ;
break ;
}
}
@Override
void captureSnapshot ( ) {
if ( mIsCapturingImage ) return ;
if ( ! isCameraOpened ( ) ) return ;
// TODO: will this work while recording a video? test...
mIsCapturingImage = true ;
mCamera . setOneShotPreviewCallback ( new Camera . PreviewCallback ( ) {
@Override
public void onPreviewFrame ( final byte [ ] data , Camera camera ) {
// Got to rotate the preview frame, since byte[] data here does not include
// EXIF tags automatically set by camera. So either we add EXIF, or we rotate.
// TODO: add exif, and also care about flipping.
Camera . Parameters params = mCamera . getParameters ( ) ;
final int rotation = computeExifRotation ( ) ;
final boolean flip = rotation % 180 ! = 0 ;
final int preWidth = mPreviewSize . getWidth ( ) ;
final int preHeight = mPreviewSize . getHeight ( ) ;
final int postWidth = flip ? preHeight : preWidth ;
final int postHeight = flip ? preWidth : preHeight ;
final int format = params . getPreviewFormat ( ) ;
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
byte [ ] rotatedData = RotationHelper . rotate ( data , preWidth , preHeight , rotation ) ;
YuvImage yuv = new YuvImage ( rotatedData , format , postWidth , postHeight , null ) ;
mCameraListener . processYuvImage ( yuv ) ;
mIsCapturingImage = false ;
}
} ) . start ( ) ;
}
} ) ;
}
}
@Override
@Override
@ -458,8 +464,9 @@ class Camera1 extends CameraImpl {
/ * *
/ * *
* Returns the orientation to be set as a exif tag . This is already managed by
* Returns the orientation to be set as a exif tag . This is already managed by
* the camera APIs as long as you call { @link Camera . Parameters # setRotation ( int ) } .
* the camera APIs as long as you call { @link Camera . Parameters # setRotation ( int ) } .
* This ignores flipping for facing camera .
* /
* /
private int computeExifOrien tation ( ) {
private int computeExifRo tation ( ) {
return ( mDeviceOrientation + mSensorOffset ) % 360 ;
return ( mDeviceOrientation + mSensorOffset ) % 360 ;
}
}
@ -507,7 +514,10 @@ class Camera1 extends CameraImpl {
@Override
@Override
void startVideo ( @NonNull File videoFile ) {
void startVideo ( @NonNull File videoFile ) {
mVideoFile = videoFile ;
mVideoFile = videoFile ;
if ( mIsCapturingVideo ) return ;
if ( ! isCameraOpened ( ) ) return ;
if ( mSessionType = = SESSION_TYPE_VIDEO ) {
if ( mSessionType = = SESSION_TYPE_VIDEO ) {
mIsCapturingVideo = true ;
initMediaRecorder ( ) ;
initMediaRecorder ( ) ;
try {
try {
mMediaRecorder . prepare ( ) ;
mMediaRecorder . prepare ( ) ;
@ -525,6 +535,7 @@ class Camera1 extends CameraImpl {
@Override
@Override
void endVideo ( ) {
void endVideo ( ) {
mIsCapturingVideo = false ;
mMediaRecorder . stop ( ) ;
mMediaRecorder . stop ( ) ;
mMediaRecorder . release ( ) ;
mMediaRecorder . release ( ) ;
mMediaRecorder = null ;
mMediaRecorder = null ;