| OLD | NEW |
| 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.content.Context; | 7 import android.content.Context; |
| 8 import android.graphics.ImageFormat; | 8 import android.graphics.ImageFormat; |
| 9 import android.util.Log; | 9 import android.util.Log; |
| 10 | 10 |
| 11 import java.util.ArrayList; | 11 import java.util.ArrayList; |
| 12 import java.util.List; | 12 import java.util.List; |
| 13 | 13 |
| 14 /** | 14 /** |
| 15 * This class extends the VideoCapture base class for manipulating normal video | 15 * This class extends the VideoCaptureCamera base class for manipulating normal |
| 16 * capture devices in Android, including receiving copies of preview frames via | 16 * video capture devices in Android, including receiving copies of preview |
| 17 * Java-allocated buffers. It also includes class BuggyDeviceHack to deal with | 17 * frames via Java-allocated buffers. It also includes class BuggyDeviceHack to |
| 18 * troublesome devices. | 18 * deal with troublesome devices. |
| 19 **/ | 19 **/ |
| 20 @SuppressWarnings("deprecation") | 20 @SuppressWarnings("deprecation") |
| 21 public class VideoCaptureAndroid extends VideoCapture { | 21 public class VideoCaptureAndroid extends VideoCaptureCamera { |
| 22 | 22 |
| 23 // Some devices don't support YV12 format correctly, even with JELLY_BEAN or | 23 // Some devices don't support YV12 format correctly, even with JELLY_BEAN or |
| 24 // newer OS. To work around the issues on those devices, we have to request | 24 // newer OS. To work around the issues on those devices, we have to request |
| 25 // NV21. Some other devices have troubles with certain capture resolutions | 25 // NV21. Some other devices have troubles with certain capture resolutions |
| 26 // under a given one: for those, the resolution is swapped with a known | 26 // under a given one: for those, the resolution is swapped with a known |
| 27 // good. Both are supposed to be temporary hacks. | 27 // good. Both are supposed to be temporary hacks. |
| 28 private static class BuggyDeviceHack { | 28 private static class BuggyDeviceHack { |
| 29 private static class IdAndSizes { | 29 private static class IdAndSizes { |
| 30 IdAndSizes(String model, String device, int minWidth, int minHeight)
{ | 30 IdAndSizes(String model, String device, int minWidth, int minHeight)
{ |
| 31 mModel = model; | 31 mModel = model; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 44 }; | 44 }; |
| 45 | 45 |
| 46 private static final String[] COLORSPACE_BUGGY_DEVICE_LIST = { | 46 private static final String[] COLORSPACE_BUGGY_DEVICE_LIST = { |
| 47 "SAMSUNG-SGH-I747", | 47 "SAMSUNG-SGH-I747", |
| 48 "ODROID-U2", | 48 "ODROID-U2", |
| 49 }; | 49 }; |
| 50 | 50 |
| 51 static void applyMinDimensions(CaptureFormat format) { | 51 static void applyMinDimensions(CaptureFormat format) { |
| 52 // NOTE: this can discard requested aspect ratio considerations. | 52 // NOTE: this can discard requested aspect ratio considerations. |
| 53 for (IdAndSizes buggyDevice : CAPTURESIZE_BUGGY_DEVICE_LIST) { | 53 for (IdAndSizes buggyDevice : CAPTURESIZE_BUGGY_DEVICE_LIST) { |
| 54 if (buggyDevice.mModel.contentEquals(android.os.Build.MODEL) && | 54 if (buggyDevice.mModel.contentEquals(android.os.Build.MODEL) |
| 55 buggyDevice.mDevice.contentEquals(android.os.Build.DEVIC
E)) { | 55 && buggyDevice.mDevice.contentEquals(android.os.Build.DE
VICE)) { |
| 56 format.mWidth = (buggyDevice.mMinWidth > format.mWidth) | 56 format.mWidth = (buggyDevice.mMinWidth > format.mWidth) |
| 57 ? buggyDevice.mMinWidth : format.mWidth; | 57 ? buggyDevice.mMinWidth : format.mWidth; |
| 58 format.mHeight = (buggyDevice.mMinHeight > format.mHeight) | 58 format.mHeight = (buggyDevice.mMinHeight > format.mHeight) |
| 59 ? buggyDevice.mMinHeight : format.mHeight; | 59 ? buggyDevice.mMinHeight : format.mHeight; |
| 60 } | 60 } |
| 61 } | 61 } |
| 62 } | 62 } |
| 63 | 63 |
| 64 static int getImageFormat() { | 64 static int getImageFormat() { |
| 65 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODE
S.JELLY_BEAN) { | 65 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODE
S.JELLY_BEAN) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 77 | 77 |
| 78 private int mExpectedFrameSize; | 78 private int mExpectedFrameSize; |
| 79 private static final int NUM_CAPTURE_BUFFERS = 3; | 79 private static final int NUM_CAPTURE_BUFFERS = 3; |
| 80 private static final String TAG = "VideoCaptureAndroid"; | 80 private static final String TAG = "VideoCaptureAndroid"; |
| 81 | 81 |
| 82 static int getNumberOfCameras() { | 82 static int getNumberOfCameras() { |
| 83 return android.hardware.Camera.getNumberOfCameras(); | 83 return android.hardware.Camera.getNumberOfCameras(); |
| 84 } | 84 } |
| 85 | 85 |
| 86 static String getName(int id) { | 86 static String getName(int id) { |
| 87 android.hardware.Camera.CameraInfo cameraInfo = VideoCapture.getCameraIn
fo(id); | 87 android.hardware.Camera.CameraInfo cameraInfo = VideoCaptureCamera.getCa
meraInfo(id); |
| 88 if (cameraInfo == null) return null; | 88 if (cameraInfo == null) return null; |
| 89 return "camera " + id + ", facing " + (cameraInfo.facing == | 89 return "camera " + id + ", facing " + (cameraInfo.facing |
| 90 android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT ? "front"
: "back"); | 90 == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT ? "fro
nt" : "back"); |
| 91 } | 91 } |
| 92 | 92 |
| 93 static CaptureFormat[] getDeviceSupportedFormats(int id) { | 93 static CaptureFormat[] getDeviceSupportedFormats(int id) { |
| 94 android.hardware.Camera camera; | 94 android.hardware.Camera camera; |
| 95 try { | 95 try { |
| 96 camera = android.hardware.Camera.open(id); | 96 camera = android.hardware.Camera.open(id); |
| 97 } catch (RuntimeException ex) { | 97 } catch (RuntimeException ex) { |
| 98 Log.e(TAG, "Camera.open: " + ex); | 98 Log.e(TAG, "Camera.open: " + ex); |
| 99 return null; | 99 return null; |
| 100 } | 100 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 android.hardware.Camera.Parameters cameraParameters) { | 165 android.hardware.Camera.Parameters cameraParameters) { |
| 166 mCaptureFormat = new CaptureFormat( | 166 mCaptureFormat = new CaptureFormat( |
| 167 width, height, frameRate, BuggyDeviceHack.getImageFormat()); | 167 width, height, frameRate, BuggyDeviceHack.getImageFormat()); |
| 168 // Hack to avoid certain capture resolutions under a minimum one, | 168 // Hack to avoid certain capture resolutions under a minimum one, |
| 169 // see http://crbug.com/305294. | 169 // see http://crbug.com/305294. |
| 170 BuggyDeviceHack.applyMinDimensions(mCaptureFormat); | 170 BuggyDeviceHack.applyMinDimensions(mCaptureFormat); |
| 171 } | 171 } |
| 172 | 172 |
| 173 @Override | 173 @Override |
| 174 protected void allocateBuffers() { | 174 protected void allocateBuffers() { |
| 175 mExpectedFrameSize = mCaptureFormat.mWidth * mCaptureFormat.mHeight * | 175 mExpectedFrameSize = mCaptureFormat.mWidth * mCaptureFormat.mHeight |
| 176 ImageFormat.getBitsPerPixel(mCaptureFormat.mPixelFormat) / 8; | 176 * ImageFormat.getBitsPerPixel(mCaptureFormat.mPixelFormat) / 8; |
| 177 for (int i = 0; i < NUM_CAPTURE_BUFFERS; i++) { | 177 for (int i = 0; i < NUM_CAPTURE_BUFFERS; i++) { |
| 178 byte[] buffer = new byte[mExpectedFrameSize]; | 178 byte[] buffer = new byte[mExpectedFrameSize]; |
| 179 mCamera.addCallbackBuffer(buffer); | 179 mCamera.addCallbackBuffer(buffer); |
| 180 } | 180 } |
| 181 } | 181 } |
| 182 | 182 |
| 183 @Override | 183 @Override |
| 184 protected void setPreviewCallback(android.hardware.Camera.PreviewCallback cb
) { | 184 protected void setPreviewCallback(android.hardware.Camera.PreviewCallback cb
) { |
| 185 mCamera.setPreviewCallbackWithBuffer(cb); | 185 mCamera.setPreviewCallbackWithBuffer(cb); |
| 186 } | 186 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 208 mPreviewBufferLock.unlock(); | 208 mPreviewBufferLock.unlock(); |
| 209 if (camera != null) { | 209 if (camera != null) { |
| 210 camera.addCallbackBuffer(data); | 210 camera.addCallbackBuffer(data); |
| 211 } | 211 } |
| 212 } | 212 } |
| 213 } | 213 } |
| 214 | 214 |
| 215 // TODO(wjia): investigate whether reading from texture could give better | 215 // TODO(wjia): investigate whether reading from texture could give better |
| 216 // performance and frame rate, using onFrameAvailable(). | 216 // performance and frame rate, using onFrameAvailable(). |
| 217 } | 217 } |
| OLD | NEW |