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

Unified Diff: media/base/android/java/src/org/chromium/media/VideoCapture.java

Issue 135213005: Add GetDeviceSupportedFormats to Android VideoCapture.java. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: bulach@ comments Created 6 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: media/base/android/java/src/org/chromium/media/VideoCapture.java
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 7e53b7c0232ede40ed0b8d59e77a50816ffeebdd..2cf67f7b7f46ecf6a3af35f4d85b20dd73c91a5a 100644
--- a/media/base/android/java/src/org/chromium/media/VideoCapture.java
+++ b/media/base/android/java/src/org/chromium/media/VideoCapture.java
@@ -18,7 +18,7 @@ import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import java.io.IOException;
-import java.util.Iterator;
+import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
@@ -30,10 +30,34 @@ import java.util.concurrent.locks.ReentrantLock;
**/
@JNINamespace("media")
public class VideoCapture implements PreviewCallback {
- static class CaptureCapability {
+ static class CaptureFormat {
+ public CaptureFormat(
+ int width, int height, int framerate, int pixelformat) {
+ mWidth = width;
+ mHeight = height;
+ mFramerate = framerate;
+ mPixelFormat = pixelformat;
+ }
public int mWidth;
public int mHeight;
- public int mDesiredFps;
+ public final int mFramerate;
+ public final int mPixelFormat;
+ @CalledByNative("CaptureFormat")
+ public int getWidth() {
+ return mWidth;
+ }
+ @CalledByNative("CaptureFormat")
+ public int getHeight() {
+ return mHeight;
+ }
+ @CalledByNative("CaptureFormat")
+ public int getFramerate() {
+ return mFramerate;
+ }
+ @CalledByNative("CaptureFormat")
+ public int getPixelFormat() {
+ return mPixelFormat;
+ }
}
// Some devices don't support YV12 format correctly, even with JELLY_BEAN or
@@ -63,17 +87,17 @@ public class VideoCapture implements PreviewCallback {
"ODROID-U2",
};
- static void applyMinDimensions(CaptureCapability capability) {
+ static void applyMinDimensions(CaptureFormat format) {
// NOTE: this can discard requested aspect ratio considerations.
for (IdAndSizes buggyDevice : s_CAPTURESIZE_BUGGY_DEVICE_LIST) {
if (buggyDevice.mModel.contentEquals(android.os.Build.MODEL) &&
buggyDevice.mDevice.contentEquals(android.os.Build.DEVICE)) {
- capability.mWidth = (buggyDevice.mMinWidth > capability.mWidth)
+ format.mWidth = (buggyDevice.mMinWidth > format.mWidth)
? buggyDevice.mMinWidth
- : capability.mWidth;
- capability.mHeight = (buggyDevice.mMinHeight > capability.mHeight)
+ : format.mWidth;
+ format.mHeight = (buggyDevice.mMinHeight > format.mHeight)
? buggyDevice.mMinHeight
- : capability.mHeight;
+ : format.mHeight;
}
}
}
@@ -94,7 +118,6 @@ public class VideoCapture implements PreviewCallback {
private Camera mCamera;
public ReentrantLock mPreviewBufferLock = new ReentrantLock();
- private int mImageFormat = ImageFormat.YV12;
private Context mContext = null;
// True when native code has started capture.
private boolean mIsRunning = false;
@@ -112,7 +135,7 @@ public class VideoCapture implements PreviewCallback {
private int mCameraFacing = 0;
private int mDeviceOrientation = 0;
- CaptureCapability mCurrentCapability = null;
+ CaptureFormat mCaptureFormat = null;
private static final String TAG = "VideoCapture";
@CalledByNative
@@ -121,6 +144,44 @@ public class VideoCapture implements PreviewCallback {
return new VideoCapture(context, id, nativeVideoCaptureDeviceAndroid);
}
+ @CalledByNative
+ public static CaptureFormat[] getDeviceSupportedFormats(int id) {
+ Camera camera;
+ try {
+ camera = Camera.open(id);
+ } catch (RuntimeException ex) {
+ Log.e(TAG, "Camera.open: " + ex);
+ return null;
+ }
+ Camera.Parameters parameters = camera.getParameters();
+
+ ArrayList<CaptureFormat> formatList = new ArrayList<CaptureFormat>();
+ int pixelFormat = AndroidImageFormatList.ANDROID_IMAGEFORMAT_UNKNOWN;
bulach 2014/02/13 14:08:23 nit: looks like this can be moved to 164, inside t
mcasas 2014/02/14 11:28:39 Done.
+ // getSupportedPreview{Formats,FpsRange,PreviewSizes}() returns Lists
+ // with at least one element.
+ List<Integer> pixelFormats = parameters.getSupportedPreviewFormats();
wjia(left Chromium) 2014/02/12 23:13:20 sanity check. see below.
mcasas 2014/02/14 11:28:39 Done. On the sanity checks, please note that the
+ for (Integer previewFormat : pixelFormats) {
+ if (previewFormat == ImageFormat.YV12)
wjia(left Chromium) 2014/02/12 23:13:20 add {} for "if" unless both condition and body fit
mcasas 2014/02/14 11:28:39 Done.
+ pixelFormat = AndroidImageFormatList.ANDROID_IMAGEFORMAT_YV12;
+ else if (previewFormat == ImageFormat.NV21)
+ pixelFormat = AndroidImageFormatList.ANDROID_IMAGEFORMAT_NV21;
wjia(left Chromium) 2014/02/12 23:13:20 Any reason to expose NV21 format? We always pass I
mcasas 2014/02/14 11:28:39 CaptureFormats contains the camera supported data
wjia(left Chromium) 2014/02/14 18:33:00 Sounds like adding NV21 is for possible "future" d
+ else
+ pixelFormat = AndroidImageFormatList.ANDROID_IMAGEFORMAT_UNKNOWN;
+
+ List<int[]> listFpsRange = parameters.getSupportedPreviewFpsRange();
wjia(left Chromium) 2014/02/12 23:13:20 sanity check.
mcasas 2014/02/14 11:28:39 Done.
+ for (int[] fpsRange : listFpsRange) {
+ List<Camera.Size> supportedSizes =
+ parameters.getSupportedPreviewSizes();
+ for (Camera.Size size : supportedSizes) {
+ formatList.add(new CaptureFormat(size.width, size.height,
+ (fpsRange[0] + 999 ) / 1000, pixelFormat));
+ }
+ }
+ }
wjia(left Chromium) 2014/02/12 23:13:20 Are you sure all combined results are supported?
mcasas 2014/02/14 11:28:39 Indeed. The TestingCam App allows to experiment wi
+ camera.release();
+ return formatList.toArray(new CaptureFormat[formatList.size()]);
+ }
+
public VideoCapture(
Context context, int id, long nativeVideoCaptureDeviceAndroid) {
mContext = context;
@@ -136,7 +197,7 @@ public class VideoCapture implements PreviewCallback {
try {
mCamera = Camera.open(mId);
} catch (RuntimeException ex) {
- Log.e(TAG, "allocate:Camera.open: " + ex);
+ Log.e(TAG, "allocate: Camera.open: " + ex);
return false;
}
@@ -150,25 +211,16 @@ public class VideoCapture implements PreviewCallback {
Camera.Parameters parameters = mCamera.getParameters();
- // Calculate fps.
+ // Calculate fps. getSupportedPreviewFpsRange() returns a List with at
+ // least one element.
List<int[]> listFpsRange = parameters.getSupportedPreviewFpsRange();
wjia(left Chromium) 2014/02/12 23:13:20 The sanity check shouldn't be removed. Refer to ht
mcasas 2014/02/14 11:28:39 Done. Added some comment about why the sanity chec
- if (listFpsRange == null || listFpsRange.size() == 0) {
- Log.e(TAG, "allocate: no fps range found");
- return false;
- }
int frameRateInMs = frameRate * 1000;
- Iterator itFpsRange = listFpsRange.iterator();
- int[] fpsRange = (int[]) itFpsRange.next();
// Use the first range as default.
- int fpsMin = fpsRange[0];
- int fpsMax = fpsRange[1];
- int newFrameRate = (fpsMin + 999) / 1000;
- while (itFpsRange.hasNext()) {
- fpsRange = (int[]) itFpsRange.next();
- if (fpsRange[0] <= frameRateInMs &&
- frameRateInMs <= fpsRange[1]) {
- fpsMin = fpsRange[0];
- fpsMax = fpsRange[1];
+ int[] fpsMinMax = listFpsRange.get(0);
+ int newFrameRate = (fpsMinMax[0] + 999) / 1000;
+ for (int[] fpsRange : listFpsRange) {
+ if (fpsRange[0] <= frameRateInMs && frameRateInMs <= fpsRange[1]) {
+ fpsMinMax = fpsRange;
newFrameRate = frameRate;
break;
}
@@ -176,21 +228,16 @@ public class VideoCapture implements PreviewCallback {
frameRate = newFrameRate;
Log.d(TAG, "allocate: fps set to " + frameRate);
- mCurrentCapability = new CaptureCapability();
- mCurrentCapability.mDesiredFps = frameRate;
-
// Calculate size.
List<Camera.Size> listCameraSize =
parameters.getSupportedPreviewSizes();
int minDiff = Integer.MAX_VALUE;
int matchedWidth = width;
int matchedHeight = height;
- Iterator itCameraSize = listCameraSize.iterator();
- while (itCameraSize.hasNext()) {
- Camera.Size size = (Camera.Size) itCameraSize.next();
+ for (Camera.Size size : listCameraSize) {
int diff = Math.abs(size.width - width) +
Math.abs(size.height - height);
- Log.d(TAG, "allocate: support resolution (" +
+ Log.d(TAG, "allocate: supported (" +
size.width + ", " + size.height + "), diff=" + diff);
// TODO(wjia): Remove this hack (forcing width to be multiple
// of 32) by supporting stride in video frame buffer.
@@ -206,16 +253,15 @@ public class VideoCapture implements PreviewCallback {
Log.e(TAG, "allocate: can not find a multiple-of-32 resolution");
return false;
}
- mCurrentCapability.mWidth = matchedWidth;
- mCurrentCapability.mHeight = matchedHeight;
+
+ mCaptureFormat = new CaptureFormat(
+ matchedWidth, matchedHeight, frameRate,
+ BuggyDeviceHack.getImageFormat());
// Hack to avoid certain capture resolutions under a minimum one,
// see http://crbug.com/305294
- BuggyDeviceHack.applyMinDimensions(mCurrentCapability);
-
- Log.d(TAG, "allocate: matched (" + mCurrentCapability.mWidth + "x" +
- mCurrentCapability.mHeight + ")");
-
- mImageFormat = BuggyDeviceHack.getImageFormat();
+ BuggyDeviceHack.applyMinDimensions(mCaptureFormat);
+ Log.d(TAG, "allocate: matched (" + mCaptureFormat.mWidth + "x" +
+ mCaptureFormat.mHeight + ")");
if (parameters.isVideoStabilizationSupported()) {
Log.d(TAG, "Image stabilization supported, currently: "
@@ -224,11 +270,10 @@ public class VideoCapture implements PreviewCallback {
} else {
Log.d(TAG, "Image stabilization not supported.");
}
-
- parameters.setPreviewSize(mCurrentCapability.mWidth,
- mCurrentCapability.mHeight);
- parameters.setPreviewFormat(mImageFormat);
- parameters.setPreviewFpsRange(fpsMin, fpsMax);
+ parameters.setPreviewSize(mCaptureFormat.mWidth,
+ mCaptureFormat.mHeight);
+ parameters.setPreviewFormat(mCaptureFormat.mPixelFormat);
+ parameters.setPreviewFpsRange(fpsMinMax[0], fpsMinMax[1]);
mCamera.setParameters(parameters);
// Set SurfaceTexture. Android Capture needs a SurfaceTexture even if
@@ -258,9 +303,10 @@ public class VideoCapture implements PreviewCallback {
return false;
}
- int bufSize = mCurrentCapability.mWidth *
- mCurrentCapability.mHeight *
- ImageFormat.getBitsPerPixel(mImageFormat) / 8;
+ int bufSize = mCaptureFormat.mWidth *
+ mCaptureFormat.mHeight *
+ ImageFormat.getBitsPerPixel(
+ mCaptureFormat.mPixelFormat) / 8;
for (int i = 0; i < NUM_CAPTURE_BUFFERS; i++) {
byte[] buffer = new byte[bufSize];
mCamera.addCallbackBuffer(buffer);
@@ -272,22 +318,22 @@ public class VideoCapture implements PreviewCallback {
@CalledByNative
public int queryWidth() {
- return mCurrentCapability.mWidth;
+ return mCaptureFormat.mWidth;
}
@CalledByNative
public int queryHeight() {
- return mCurrentCapability.mHeight;
+ return mCaptureFormat.mHeight;
}
@CalledByNative
public int queryFrameRate() {
- return mCurrentCapability.mDesiredFps;
+ return mCaptureFormat.mFramerate;
}
@CalledByNative
public int getColorspace() {
- switch (mImageFormat) {
+ switch (mCaptureFormat.mPixelFormat) {
case ImageFormat.YV12:
return AndroidImageFormatList.ANDROID_IMAGEFORMAT_YV12;
case ImageFormat.NV21:
@@ -351,7 +397,7 @@ public class VideoCapture implements PreviewCallback {
mCamera.setPreviewTexture(null);
if (mGlTextures != null)
GLES20.glDeleteTextures(1, mGlTextures, 0);
- mCurrentCapability = null;
+ mCaptureFormat = null;
mCamera.release();
mCamera = null;
} catch (IOException ex) {

Powered by Google App Engine
This is Rietveld 408576698