Chromium Code Reviews| 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); |
| } |
| } |