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

Unified Diff: talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java

Issue 1178703009: VideoCapturerAndroid: Add function to change capture format while camera is running (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 6 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: talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java
diff --git a/talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java b/talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java
index e40cd1ac29cb9afac7eea536fa6681692f365d81..1d4e181d872e06aec5268ff900dcf879b6601eb8 100644
--- a/talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java
+++ b/talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java
@@ -270,6 +270,18 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
return true;
}
+ public List<CaptureFormat> getSupportedFormats() {
+ return supportedFormats.get(id);
+ }
+
+ public void changeCaptureFormat(final int width, final int height, final int framerate) {
+ cameraThreadHandler.post(new Runnable() {
+ @Override public void run() {
+ changeCaptureFormatOnCameraThread(width, height, framerate);
+ }
+ });
+ }
+
private VideoCapturerAndroid() {
Log.d(TAG, "VideoCapturerAndroid");
}
@@ -334,7 +346,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
return getSupportedFormatsAsJson(id);
}
- static class CaptureFormat {
+ public static class CaptureFormat {
public final int width;
public final int height;
public final int maxFramerate;
@@ -578,6 +590,26 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
return;
}
+ private void changeCaptureFormatOnCameraThread(int width, int height, int framerate) {
hbos 2015/06/12 09:34:48 What if the capturer is currently not running? Wil
magjed_webrtc 2015/06/12 12:52:23 Done. Added checks.
hbos 2015/06/15 07:42:12 Add a comment to changeCaptureFormat that it can o
magjed_webrtc 2015/06/17 10:47:57 Done.
+ Log.d(TAG, "changeCaptureFormat requested: " + width + "x" + height + "@" + framerate);
+ this.width = width;
+ this.height = height;
+ this.framerate = framerate;
+ Camera.Parameters parameters = camera.getParameters();
+ int[] range = getFramerateRange(parameters, framerate * 1000);
+ if (range != null) {
+ parameters.setPreviewFpsRange(
+ range[Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
+ range[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]);
+ }
+ parameters.setPreviewSize(width, height);
+ camera.stopPreview();
+ camera.setParameters(parameters);
+ videoBuffers.queueCameraBuffers(width, height, ImageFormat.YV12, camera);
+ camera.setPreviewCallbackWithBuffer(this);
+ camera.startPreview();
+ }
+
// Called by native code. Returns true when camera is known to be stopped.
synchronized void stopCapture() throws InterruptedException {
if (cameraThreadHandler == null) {
@@ -716,7 +748,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
if (Thread.currentThread() != cameraThread) {
throw new RuntimeException("Camera callback not on camera thread?!?");
}
- if (camera == null) {
+ if (camera == null || data == null) {
return;
}
if (camera != callbackCamera) {
@@ -736,9 +768,12 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
// Mark the frame owning |data| as used.
// Note that since data is directBuffer,
// data.length >= videoBuffers.frameSize.
- videoBuffers.reserveByteBuffer(data, captureTimeNs);
- frameObserver.OnFrameCaptured(data, videoBuffers.frameSize, rotation,
- captureTimeNs);
+ if (videoBuffers.reserveByteBuffer(data, captureTimeNs)) {
+ frameObserver.OnFrameCaptured(data, videoBuffers.frameSize,
+ width, height, rotation, captureTimeNs);
+ } else {
+ Log.w(TAG, "reserveByteBuffer failed - dropping frame");
hbos 2015/06/12 09:34:48 cameraFramesCount-- or no?
magjed_webrtc 2015/06/12 12:52:23 Done. Moved 'cameraFramesCount++' into the same sc
+ }
}
// runCameraThreadUntilIdle make sure all posted messages to the cameraThread
@@ -798,9 +833,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
// Adds frames as callback buffers to |camera|. If a new frame size is
// required, new buffers are allocated and added.
void queueCameraBuffers(int width, int height, int format, Camera camera) {
- if (this.camera != null)
- throw new RuntimeException("camera already set.");
-
+ boolean cameraWasNull = (this.camera == null);
this.camera = camera;
int newFrameSize = CaptureFormat.frameSize(width, height, format);
@@ -814,7 +847,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
this.camera.addCallbackBuffer(frame.data());
}
numCaptureBuffersAvailable = numCaptureBuffers;
- } else {
+ } else if (cameraWasNull) {
// Add all frames that have been returned.
for (Frame frame : cameraFrames) {
if (frame.timeStamp < 0) {
@@ -822,6 +855,8 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
numCaptureBuffersAvailable++;
}
}
+ } else {
+ // Same framesize and camera is still running - no need to do anything.
}
frameSize = newFrameSize;
Log.d(TAG, "queueCameraBuffers enqued " + numCaptureBuffersAvailable
@@ -849,19 +884,24 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
}
- void reserveByteBuffer(byte[] data, long timeStamp) {
+ boolean reserveByteBuffer(byte[] data, long timeStamp) {
for (Frame frame : cameraFrames) {
if (data == frame.data()) {
if (frame.timeStamp > 0) {
throw new RuntimeException("Frame already in use !");
}
+ if (frame.frameSize != frameSize) {
+ Log.w(TAG, "Outdated framesize - removing byte buffer from pool");
+ cameraFrames.remove(frame);
hbos 2015/06/12 09:34:48 Ought we not re-queueCameraBuffers or the equivale
magjed_webrtc 2015/06/12 12:52:23 No, that shouldn't be possible. The function queue
+ return false;
+ }
frame.timeStamp = timeStamp;
numCaptureBuffersAvailable--;
if (numCaptureBuffersAvailable == 0) {
Log.v(TAG, "Camera is running out of capture buffers."
+ " Pending buffers: [" + pendingFramesTimeStamps() + "]");
}
- return;
+ return true;
}
}
throw new RuntimeException("unknown data buffer?!?");
@@ -917,8 +957,8 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
// Delivers a captured frame. Called on a Java thread owned by
// VideoCapturerAndroid.
- abstract void OnFrameCaptured(byte[] data, int length, int rotation,
- long timeStamp);
+ abstract void OnFrameCaptured(byte[] data, int length, int width, int height,
+ int rotation, long timeStamp);
}
// An implementation of CapturerObserver that forwards all calls from
@@ -936,14 +976,14 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
}
@Override
- public void OnFrameCaptured(byte[] data, int length, int rotation,
- long timeStamp) {
- nativeOnFrameCaptured(nativeCapturer, data, length, rotation, timeStamp);
+ public void OnFrameCaptured(byte[] data, int length, int width, int height,
+ int rotation, long timeStamp) {
+ nativeOnFrameCaptured(nativeCapturer, data, length, width, height, rotation, timeStamp);
}
private native void nativeCapturerStarted(long nativeCapturer,
boolean success);
private native void nativeOnFrameCaptured(long nativeCapturer,
- byte[] data, int length, int rotation, long timeStamp);
+ byte[] data, int length, int width, int height, int rotation, long timeStamp);
}
}

Powered by Google App Engine
This is Rietveld 408576698