Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java

Issue 2156003006: Android video capture: use new libyuv::Android420ToI420 API for format converting. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase with no code change Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.media; 5 package org.chromium.media;
6 6
7 import android.annotation.TargetApi; 7 import android.annotation.TargetApi;
8 import android.content.Context; 8 import android.content.Context;
9 import android.graphics.ImageFormat; 9 import android.graphics.ImageFormat;
10 import android.graphics.Rect; 10 import android.graphics.Rect;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 120
121 if (reader.getWidth() != image.getWidth() 121 if (reader.getWidth() != image.getWidth()
122 || reader.getHeight() != image.getHeight()) { 122 || reader.getHeight() != image.getHeight()) {
123 nativeOnError(mNativeVideoCaptureDeviceAndroid, "ImageReader size (" 123 nativeOnError(mNativeVideoCaptureDeviceAndroid, "ImageReader size ("
124 + reader.getWidth() + "x" + reader.getHeight() 124 + reader.getWidth() + "x" + reader.getHeight()
125 + ") did not match Image size (" + image.getWidth() + "x" 125 + ") did not match Image size (" + image.getWidth() + "x"
126 + image.getHeight() + ")"); 126 + image.getHeight() + ")");
127 throw new IllegalStateException(); 127 throw new IllegalStateException();
128 } 128 }
129 129
130 readImageIntoBuffer(image, mCapturedData); 130 nativeOnI420FrameAvailable(mNativeVideoCaptureDeviceAndroid,
131 nativeOnFrameAvailable(mNativeVideoCaptureDeviceAndroid, mCaptur edData, 131 image.getPlanes()[0].getBuffer(), image.getPlanes()[0].g etRowStride(),
132 mCapturedData.length, getCameraRotation()); 132 image.getPlanes()[1].getBuffer(), image.getPlanes()[2].g etBuffer(),
133 image.getPlanes()[1].getRowStride(), image.getPlanes()[1 ].getPixelStride(),
134 image.getWidth(), image.getHeight(), getCameraRotation() );
133 } catch (IllegalStateException ex) { 135 } catch (IllegalStateException ex) {
134 Log.e(TAG, "acquireLatestImage():", ex); 136 Log.e(TAG, "acquireLatestImage():", ex);
135 } 137 }
136 } 138 }
137 }; 139 };
138 140
139 // Inner class to extend a Photo Session state change listener. 141 // Inner class to extend a Photo Session state change listener.
140 // Error paths must signal notifyTakePhotoError(). 142 // Error paths must signal notifyTakePhotoError().
141 private class CrPhotoSessionListener extends CameraCaptureSession.StateCallb ack { 143 private class CrPhotoSessionListener extends CameraCaptureSession.StateCallb ack {
142 private final CaptureRequest mPhotoRequest; 144 private final CaptureRequest mPhotoRequest;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 } 220 }
219 }; 221 };
220 222
221 private static final double kNanoSecondsToFps = 1.0E-9; 223 private static final double kNanoSecondsToFps = 1.0E-9;
222 private static final String TAG = "VideoCapture"; 224 private static final String TAG = "VideoCapture";
223 225
224 private static enum CameraState { OPENING, CONFIGURING, STARTED, STOPPED } 226 private static enum CameraState { OPENING, CONFIGURING, STARTED, STOPPED }
225 227
226 private final Object mCameraStateLock = new Object(); 228 private final Object mCameraStateLock = new Object();
227 229
228 private byte[] mCapturedData;
229
230 private CameraDevice mCameraDevice; 230 private CameraDevice mCameraDevice;
231 private CameraCaptureSession mPreviewSession; 231 private CameraCaptureSession mPreviewSession;
232 private CaptureRequest mPreviewRequest; 232 private CaptureRequest mPreviewRequest;
233 233
234 private CameraState mCameraState = CameraState.STOPPED; 234 private CameraState mCameraState = CameraState.STOPPED;
235 private final float mMaxZoom; 235 private final float mMaxZoom;
236 private Rect mCropRect = new Rect(); 236 private Rect mCropRect = new Rect();
237 237
238 // Service function to grab CameraCharacteristics and handle exceptions. 238 // Service function to grab CameraCharacteristics and handle exceptions.
239 private static CameraCharacteristics getCameraCharacteristics(Context appCon text, int id) { 239 private static CameraCharacteristics getCameraCharacteristics(Context appCon text, int id) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 try { 305 try {
306 mCameraDevice.createCaptureSession(surfaceList, captureSessionListen er, null); 306 mCameraDevice.createCaptureSession(surfaceList, captureSessionListen er, null);
307 } catch (CameraAccessException | IllegalArgumentException | SecurityExce ption ex) { 307 } catch (CameraAccessException | IllegalArgumentException | SecurityExce ption ex) {
308 Log.e(TAG, "createCaptureSession: ", ex); 308 Log.e(TAG, "createCaptureSession: ", ex);
309 return false; 309 return false;
310 } 310 }
311 // Wait for trigger on CrPreviewSessionListener.onConfigured(); 311 // Wait for trigger on CrPreviewSessionListener.onConfigured();
312 return true; 312 return true;
313 } 313 }
314 314
315 private static void readImageIntoBuffer(Image image, byte[] data) {
316 final int imageWidth = image.getWidth();
317 final int imageHeight = image.getHeight();
318 final Image.Plane[] planes = image.getPlanes();
319
320 int offset = 0;
321 for (int plane = 0; plane < planes.length; ++plane) {
322 final ByteBuffer buffer = planes[plane].getBuffer();
323 final int rowStride = planes[plane].getRowStride();
324 // Experimentally, U and V planes have |pixelStride| = 2, which
325 // essentially means they are packed. That's silly, because we are
326 // forced to unpack here.
327 final int pixelStride = planes[plane].getPixelStride();
328 final int planeWidth = (plane == 0) ? imageWidth : imageWidth / 2;
329 final int planeHeight = (plane == 0) ? imageHeight : imageHeight / 2 ;
330
331 if (pixelStride == 1 && rowStride == planeWidth) {
332 // Copy whole plane from buffer into |data| at once.
333 buffer.get(data, offset, planeWidth * planeHeight);
334 offset += planeWidth * planeHeight;
335 } else {
336 // Copy pixels one by one respecting pixelStride and rowStride.
337 byte[] rowData = new byte[rowStride];
338 for (int row = 0; row < planeHeight - 1; ++row) {
339 buffer.get(rowData, 0, rowStride);
340 for (int col = 0; col < planeWidth; ++col) {
341 data[offset++] = rowData[col * pixelStride];
342 }
343 }
344
345 // Last row is special in some devices and may not contain the f ull
346 // |rowStride| bytes of data. See http://crbug.com/458701 and
347 // http://developer.android.com/reference/android/media/Image.Pl ane.html#getBuffer()
348 buffer.get(rowData, 0, Math.min(rowStride, buffer.remaining()));
349 for (int col = 0; col < planeWidth; ++col) {
350 data[offset++] = rowData[col * pixelStride];
351 }
352 }
353 }
354 }
355
356 private void changeCameraStateAndNotify(CameraState state) { 315 private void changeCameraStateAndNotify(CameraState state) {
357 synchronized (mCameraStateLock) { 316 synchronized (mCameraStateLock) {
358 mCameraState = state; 317 mCameraState = state;
359 mCameraStateLock.notifyAll(); 318 mCameraStateLock.notifyAll();
360 } 319 }
361 } 320 }
362 321
363 static boolean isLegacyDevice(Context appContext, int id) { 322 static boolean isLegacyDevice(Context appContext, int id) {
364 final CameraCharacteristics cameraCharacteristics = 323 final CameraCharacteristics cameraCharacteristics =
365 getCameraCharacteristics(appContext, id); 324 getCameraCharacteristics(appContext, id);
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 if (minDiff == Integer.MAX_VALUE) { 449 if (minDiff == Integer.MAX_VALUE) {
491 Log.e(TAG, "No supported resolutions."); 450 Log.e(TAG, "No supported resolutions.");
492 return false; 451 return false;
493 } 452 }
494 Log.d(TAG, "allocate: matched (%d x %d)", closestSupportedSize.getWidth( ), 453 Log.d(TAG, "allocate: matched (%d x %d)", closestSupportedSize.getWidth( ),
495 closestSupportedSize.getHeight()); 454 closestSupportedSize.getHeight());
496 455
497 // |mCaptureFormat| is also used to configure the ImageReader. 456 // |mCaptureFormat| is also used to configure the ImageReader.
498 mCaptureFormat = new VideoCaptureFormat(closestSupportedSize.getWidth(), 457 mCaptureFormat = new VideoCaptureFormat(closestSupportedSize.getWidth(),
499 closestSupportedSize.getHeight(), frameRate, ImageFormat.YUV_420 _888); 458 closestSupportedSize.getHeight(), frameRate, ImageFormat.YUV_420 _888);
500 int expectedFrameSize = mCaptureFormat.mWidth * mCaptureFormat.mHeight
501 * ImageFormat.getBitsPerPixel(mCaptureFormat.mPixelFormat) / 8;
502 mCapturedData = new byte[expectedFrameSize];
503 mCameraNativeOrientation = 459 mCameraNativeOrientation =
504 cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATI ON); 460 cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATI ON);
505 // TODO(mcasas): The following line is correct for N5 with prerelease Bu ild, 461 // TODO(mcasas): The following line is correct for N5 with prerelease Bu ild,
506 // but NOT for N7 with a dev Build. Figure out which one to support. 462 // but NOT for N7 with a dev Build. Figure out which one to support.
507 mInvertDeviceOrientationReadings = 463 mInvertDeviceOrientationReadings =
508 cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) 464 cameraCharacteristics.get(CameraCharacteristics.LENS_FACING)
509 == CameraCharacteristics.LENS_FACING_BACK; 465 == CameraCharacteristics.LENS_FACING_BACK;
510 return true; 466 return true;
511 } 467 }
512 468
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 return false; 607 return false;
652 } 608 }
653 return true; 609 return true;
654 } 610 }
655 611
656 @Override 612 @Override
657 public void deallocate() { 613 public void deallocate() {
658 Log.d(TAG, "deallocate"); 614 Log.d(TAG, "deallocate");
659 } 615 }
660 } 616 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698