| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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.graphics.SurfaceTexture; | 9 import android.graphics.SurfaceTexture; |
| 10 import android.graphics.SurfaceTexture.OnFrameAvailableListener; | 10 import android.graphics.SurfaceTexture.OnFrameAvailableListener; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 // To work around the issues on those devices, we'd have to request NV21. | 36 // To work around the issues on those devices, we'd have to request NV21. |
| 37 // This is a temporary hack till device manufacturers fix the problem or | 37 // This is a temporary hack till device manufacturers fix the problem or |
| 38 // we don't need to support those devices any more. | 38 // we don't need to support those devices any more. |
| 39 private static class DeviceImageFormatHack { | 39 private static class DeviceImageFormatHack { |
| 40 private static final String[] sBUGGY_DEVICE_LIST = { | 40 private static final String[] sBUGGY_DEVICE_LIST = { |
| 41 "SAMSUNG-SGH-I747", | 41 "SAMSUNG-SGH-I747", |
| 42 }; | 42 }; |
| 43 | 43 |
| 44 static int getImageFormat() { | 44 static int getImageFormat() { |
| 45 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODE
S.JELLY_BEAN) { | 45 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODE
S.JELLY_BEAN) { |
| 46 Log.d(TAG, "NV21 colorspace"); |
| 46 return ImageFormat.NV21; | 47 return ImageFormat.NV21; |
| 47 } | 48 } |
| 48 | 49 |
| 49 for (String buggyDevice : sBUGGY_DEVICE_LIST) { | 50 for (String buggyDevice : sBUGGY_DEVICE_LIST) { |
| 50 if (buggyDevice.contentEquals(android.os.Build.MODEL)) { | 51 if (buggyDevice.contentEquals(android.os.Build.MODEL)) { |
| 52 Log.d(TAG, "NV21 colorspace"); |
| 51 return ImageFormat.NV21; | 53 return ImageFormat.NV21; |
| 52 } | 54 } |
| 53 } | 55 } |
| 54 | 56 Log.d(TAG, "YV12 colorspace"); |
| 55 return ImageFormat.YV12; | 57 return ImageFormat.YV12; |
| 56 } | 58 } |
| 57 } | 59 } |
| 58 | 60 |
| 59 private Camera mCamera; | 61 private Camera mCamera; |
| 60 public ReentrantLock mPreviewBufferLock = new ReentrantLock(); | 62 public ReentrantLock mPreviewBufferLock = new ReentrantLock(); |
| 61 private int mImageFormat = ImageFormat.YV12; | 63 private int mImageFormat = ImageFormat.YV12; |
| 62 private byte[] mColorPlane = null; | 64 private byte[] mColorPlane = null; |
| 63 private Context mContext = null; | 65 private Context mContext = null; |
| 64 // True when native code has started capture. | 66 // True when native code has started capture. |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 public int queryHeight() { | 233 public int queryHeight() { |
| 232 return mCurrentCapability.mHeight; | 234 return mCurrentCapability.mHeight; |
| 233 } | 235 } |
| 234 | 236 |
| 235 @CalledByNative | 237 @CalledByNative |
| 236 public int queryFrameRate() { | 238 public int queryFrameRate() { |
| 237 return mCurrentCapability.mDesiredFps; | 239 return mCurrentCapability.mDesiredFps; |
| 238 } | 240 } |
| 239 | 241 |
| 240 @CalledByNative | 242 @CalledByNative |
| 243 public int getColorspace() { |
| 244 return mImageFormat; |
| 245 } |
| 246 |
| 247 @CalledByNative |
| 241 public int startCapture() { | 248 public int startCapture() { |
| 242 if (mCamera == null) { | 249 if (mCamera == null) { |
| 243 Log.e(TAG, "startCapture: camera is null"); | 250 Log.e(TAG, "startCapture: camera is null"); |
| 244 return -1; | 251 return -1; |
| 245 } | 252 } |
| 246 | 253 |
| 247 mPreviewBufferLock.lock(); | 254 mPreviewBufferLock.lock(); |
| 248 try { | 255 try { |
| 249 if (mIsRunning) { | 256 if (mIsRunning) { |
| 250 return 0; | 257 return 0; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 boolean flipVertical = false; | 325 boolean flipVertical = false; |
| 319 boolean flipHorizontal = false; | 326 boolean flipHorizontal = false; |
| 320 if (mCameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) { | 327 if (mCameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) { |
| 321 rotation = (mCameraOrientation + rotation) % 360; | 328 rotation = (mCameraOrientation + rotation) % 360; |
| 322 rotation = (360 - rotation) % 360; | 329 rotation = (360 - rotation) % 360; |
| 323 flipHorizontal = (rotation == 270 || rotation == 90); | 330 flipHorizontal = (rotation == 270 || rotation == 90); |
| 324 flipVertical = flipHorizontal; | 331 flipVertical = flipHorizontal; |
| 325 } else { | 332 } else { |
| 326 rotation = (mCameraOrientation - rotation + 360) % 360; | 333 rotation = (mCameraOrientation - rotation + 360) % 360; |
| 327 } | 334 } |
| 328 if (mImageFormat == ImageFormat.NV21) { | |
| 329 convertNV21ToYV12(data); | |
| 330 } | |
| 331 nativeOnFrameAvailable(mNativeVideoCaptureDeviceAndroid, | 335 nativeOnFrameAvailable(mNativeVideoCaptureDeviceAndroid, |
| 332 data, mExpectedFrameSize, | 336 data, mExpectedFrameSize, |
| 333 rotation, flipVertical, flipHorizontal); | 337 rotation, flipVertical, flipHorizontal); |
| 334 } | 338 } |
| 335 } finally { | 339 } finally { |
| 336 mPreviewBufferLock.unlock(); | 340 mPreviewBufferLock.unlock(); |
| 337 if (camera != null) { | 341 if (camera != null) { |
| 338 camera.addCallbackBuffer(data); | 342 camera.addCallbackBuffer(data); |
| 339 } | 343 } |
| 340 } | 344 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 default: | 414 default: |
| 411 orientation = 0; | 415 orientation = 0; |
| 412 break; | 416 break; |
| 413 } | 417 } |
| 414 } | 418 } |
| 415 return orientation; | 419 return orientation; |
| 416 } | 420 } |
| 417 | 421 |
| 418 private void calculateImageFormat(int width, int height) { | 422 private void calculateImageFormat(int width, int height) { |
| 419 mImageFormat = DeviceImageFormatHack.getImageFormat(); | 423 mImageFormat = DeviceImageFormatHack.getImageFormat(); |
| 420 if (mImageFormat == ImageFormat.NV21) { | |
| 421 mColorPlane = new byte[width * height / 4]; | |
| 422 } | |
| 423 } | |
| 424 | |
| 425 private void convertNV21ToYV12(byte[] data) { | |
| 426 final int ySize = mCurrentCapability.mWidth * mCurrentCapability.mHeight
; | |
| 427 final int uvSize = ySize / 4; | |
| 428 for (int i = 0; i < uvSize; i++) { | |
| 429 final int index = ySize + i * 2; | |
| 430 data[ySize + i] = data[index]; | |
| 431 mColorPlane[i] = data[index + 1]; | |
| 432 } | |
| 433 System.arraycopy(mColorPlane, 0, data, ySize + uvSize, uvSize); | |
| 434 } | 424 } |
| 435 } | 425 } |
| OLD | NEW |