summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorwjia@chromium.org <wjia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-01 20:06:11 +0000
committerwjia@chromium.org <wjia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-01 20:06:11 +0000
commit012121b869fa52d73cec9954fa7500c514f39e88 (patch)
tree73882675949a430a6953ac70a2d3ecaeb3816ed1 /media
parent9d2c63ed047b99c4ad950aa4338a6c55c0eb8e91 (diff)
downloadchromium_src-012121b869fa52d73cec9954fa7500c514f39e88.zip
chromium_src-012121b869fa52d73cec9954fa7500c514f39e88.tar.gz
chromium_src-012121b869fa52d73cec9954fa7500c514f39e88.tar.bz2
Work around camera color issue on some Android devices which do not support YV12 correctly.
On some Android device, the camera delivers incorrect color format when YV12 is requested. Need to request NV21 which is always supported. BUG=252513 R=bulach@chromium.org, qinmin@chromium.org Review URL: https://codereview.chromium.org/21269004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@215096 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/base/android/java/src/org/chromium/media/VideoCapture.java55
1 files changed, 52 insertions, 3 deletions
diff --git a/media/base/android/java/src/org/chromium/media/VideoCapture.java b/media/base/android/java/src/org/chromium/media/VideoCapture.java
index 8d67f5e..f055f35 100644
--- a/media/base/android/java/src/org/chromium/media/VideoCapture.java
+++ b/media/base/android/java/src/org/chromium/media/VideoCapture.java
@@ -31,9 +31,35 @@ public class VideoCapture implements PreviewCallback, OnFrameAvailableListener {
public int mDesiredFps = 0;
}
+ // Some devices with OS older than JELLY_BEAN don't support YV12 format correctly.
+ // Some devices don't support YV12 format correctly even with JELLY_BEAN or newer OS.
+ // To work around the issues on those devices, we'd have to request NV21.
+ // This is a temporary hack till device manufacturers fix the problem or
+ // we don't need to support those devices any more.
+ private static class DeviceImageFormatHack {
+ private static final String[] sBUGGY_DEVICE_LIST = {
+ "SAMSUNG-SGH-I747",
+ };
+
+ static int getImageFormat() {
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
+ return ImageFormat.NV21;
+ }
+
+ for (String buggyDevice : sBUGGY_DEVICE_LIST) {
+ if (buggyDevice.contentEquals(android.os.Build.MODEL)) {
+ return ImageFormat.NV21;
+ }
+ }
+
+ return ImageFormat.YV12;
+ }
+ }
+
private Camera mCamera;
public ReentrantLock mPreviewBufferLock = new ReentrantLock();
- private int mPixelFormat = ImageFormat.YV12;
+ private int mImageFormat = ImageFormat.YV12;
+ private byte[] mColorPlane = null;
private Context mContext = null;
// True when native code has started capture.
private boolean mIsRunning = false;
@@ -147,8 +173,10 @@ public class VideoCapture implements PreviewCallback, OnFrameAvailableListener {
Log.d(TAG, "allocate: matched width=" + matchedWidth +
", height=" + matchedHeight);
+ calculateImageFormat(matchedWidth, matchedHeight);
+
parameters.setPreviewSize(matchedWidth, matchedHeight);
- parameters.setPreviewFormat(mPixelFormat);
+ parameters.setPreviewFormat(mImageFormat);
parameters.setPreviewFpsRange(fpsMin, fpsMax);
mCamera.setParameters(parameters);
@@ -174,7 +202,7 @@ public class VideoCapture implements PreviewCallback, OnFrameAvailableListener {
mCamera.setPreviewTexture(mSurfaceTexture);
int bufSize = matchedWidth * matchedHeight *
- ImageFormat.getBitsPerPixel(mPixelFormat) / 8;
+ ImageFormat.getBitsPerPixel(mImageFormat) / 8;
for (int i = 0; i < NUM_CAPTURE_BUFFERS; i++) {
byte[] buffer = new byte[bufSize];
mCamera.addCallbackBuffer(buffer);
@@ -291,6 +319,9 @@ public class VideoCapture implements PreviewCallback, OnFrameAvailableListener {
} else {
rotation = (mCameraOrientation - rotation + 360) % 360;
}
+ if (mImageFormat == ImageFormat.NV21) {
+ convertNV21ToYV12(data);
+ }
nativeOnFrameAvailable(mNativeVideoCaptureDeviceAndroid,
data, mExpectedFrameSize,
rotation, flipVertical, flipHorizontal);
@@ -377,4 +408,22 @@ public class VideoCapture implements PreviewCallback, OnFrameAvailableListener {
}
return orientation;
}
+
+ private void calculateImageFormat(int width, int height) {
+ mImageFormat = DeviceImageFormatHack.getImageFormat();
+ if (mImageFormat == ImageFormat.NV21) {
+ mColorPlane = new byte[width * height / 4];
+ }
+ }
+
+ private void convertNV21ToYV12(byte[] data) {
+ final int ySize = mCurrentCapability.mWidth * mCurrentCapability.mHeight;
+ final int uvSize = ySize / 4;
+ for (int i = 0; i < uvSize; i++) {
+ final int index = ySize + i * 2;
+ data[ySize + i] = data[index];
+ mColorPlane[i] = data[index + 1];
+ }
+ System.arraycopy(mColorPlane, 0, data, ySize + uvSize, uvSize);
+ }
}