Android: Make VideoCapturer an interface for all VideoCapturers to implement
This CL factors out the interface that AndroidVideoCapturerJni is using to communicate with the Java counterpart. This interface is moved into VideoCapturer. The interface is not touched in this CL, and a follow-up CL is planned to simplify and improve it. Another change is that the native part of VideoCapturer is created in PeerConnectionFactory.createVideoSource() instead of doing it immediately in the ctor. BUG=webrtc:5519 R=perkj@webrtc.org Review URL: https://codereview.webrtc.org/1696553003 . Cr-Commit-Position: refs/heads/master@{#11606}
This commit is contained in:
@ -50,9 +50,8 @@ public class CameraEnumerationAndroid {
|
||||
public final int height;
|
||||
public final int maxFramerate;
|
||||
public final int minFramerate;
|
||||
// TODO(hbos): If VideoCapturerAndroid.startCapture is updated to support
|
||||
// other image formats then this needs to be updated and
|
||||
// VideoCapturerAndroid.getSupportedFormats need to return CaptureFormats of
|
||||
// TODO(hbos): If VideoCapturer.startCapture is updated to support other image formats then this
|
||||
// needs to be updated and VideoCapturer.getSupportedFormats need to return CaptureFormats of
|
||||
// all imageFormats.
|
||||
public final int imageFormat = ImageFormat.NV21;
|
||||
|
||||
|
||||
@ -45,7 +45,8 @@ import java.util.concurrent.TimeUnit;
|
||||
// camera thread. The internal *OnCameraThread() methods must check |camera| for null to check if
|
||||
// the camera has been stopped.
|
||||
@SuppressWarnings("deprecation")
|
||||
public class VideoCapturerAndroid extends VideoCapturer implements
|
||||
public class VideoCapturerAndroid implements
|
||||
VideoCapturer,
|
||||
android.hardware.Camera.PreviewCallback,
|
||||
SurfaceTextureHelper.OnTextureFrameAvailableListener {
|
||||
private final static String TAG = "VideoCapturerAndroid";
|
||||
@ -196,12 +197,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements
|
||||
if (cameraId == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final VideoCapturerAndroid capturer = new VideoCapturerAndroid(cameraId, eventsHandler,
|
||||
sharedEglContext);
|
||||
capturer.setNativeCapturer(
|
||||
nativeCreateVideoCapturer(capturer, capturer.surfaceHelper));
|
||||
return capturer;
|
||||
return new VideoCapturerAndroid(cameraId, eventsHandler, sharedEglContext);
|
||||
}
|
||||
|
||||
public void printStackTrace() {
|
||||
@ -297,14 +293,14 @@ public class VideoCapturerAndroid extends VideoCapturer implements
|
||||
return isCapturingToTexture;
|
||||
}
|
||||
|
||||
// Called from native code.
|
||||
private String getSupportedFormatsAsJson() throws JSONException {
|
||||
@Override
|
||||
public String getSupportedFormatsAsJson() throws JSONException {
|
||||
return CameraEnumerationAndroid.getSupportedFormatsAsJson(getCurrentCameraId());
|
||||
}
|
||||
|
||||
// Called from native VideoCapturer_nativeCreateVideoCapturer.
|
||||
private VideoCapturerAndroid(int cameraId) {
|
||||
this(cameraId, null, null);
|
||||
@Override
|
||||
public SurfaceTextureHelper getSurfaceTextureHelper() {
|
||||
return surfaceHelper;
|
||||
}
|
||||
|
||||
private VideoCapturerAndroid(int cameraId, CameraEventsHandler eventsHandler,
|
||||
@ -347,11 +343,12 @@ public class VideoCapturerAndroid extends VideoCapturer implements
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Called by native code to quit the camera thread. This needs to be done manually, otherwise the
|
||||
// thread and handler will not be garbage collected.
|
||||
private void release() {
|
||||
// Quits the camera thread. This needs to be done manually, otherwise the thread and handler will
|
||||
// not be garbage collected.
|
||||
@Override
|
||||
public void dispose() {
|
||||
Logging.d(TAG, "release");
|
||||
if (isReleased()) {
|
||||
if (isDisposed()) {
|
||||
throw new IllegalStateException("Already released");
|
||||
}
|
||||
ThreadUtils.invokeUninterruptibly(cameraThreadHandler, new Runnable() {
|
||||
@ -367,15 +364,14 @@ public class VideoCapturerAndroid extends VideoCapturer implements
|
||||
}
|
||||
|
||||
// Used for testing purposes to check if release() has been called.
|
||||
public boolean isReleased() {
|
||||
public boolean isDisposed() {
|
||||
return (cameraThread == null);
|
||||
}
|
||||
|
||||
// Called by native code.
|
||||
//
|
||||
// Note that this actually opens the camera, and Camera callbacks run on the
|
||||
// thread that calls open(), so this is done on the CameraThread.
|
||||
void startCapture(
|
||||
@Override
|
||||
public void startCapture(
|
||||
final int width, final int height, final int framerate,
|
||||
final Context applicationContext, final CapturerObserver frameObserver) {
|
||||
Logging.d(TAG, "startCapture requested: " + width + "x" + height
|
||||
@ -548,8 +544,9 @@ public class VideoCapturerAndroid extends VideoCapturer implements
|
||||
camera.startPreview();
|
||||
}
|
||||
|
||||
// Called by native code. Returns true when camera is known to be stopped.
|
||||
void stopCapture() throws InterruptedException {
|
||||
// Blocks until camera is known to be stopped.
|
||||
@Override
|
||||
public void stopCapture() throws InterruptedException {
|
||||
Logging.d(TAG, "stopCapture");
|
||||
final CountDownLatch barrier = new CountDownLatch(1);
|
||||
cameraThreadHandler.post(new Runnable() {
|
||||
@ -702,75 +699,4 @@ public class VideoCapturerAndroid extends VideoCapturer implements
|
||||
frameObserver.onTextureFrameCaptured(captureFormat.width, captureFormat.height, oesTextureId,
|
||||
transformMatrix, rotation, timestampNs);
|
||||
}
|
||||
|
||||
// Interface used for providing callbacks to an observer.
|
||||
interface CapturerObserver {
|
||||
// Notify if the camera have been started successfully or not.
|
||||
// Called on a Java thread owned by VideoCapturerAndroid.
|
||||
abstract void onCapturerStarted(boolean success);
|
||||
|
||||
// Delivers a captured frame. Called on a Java thread owned by
|
||||
// VideoCapturerAndroid.
|
||||
abstract void onByteBufferFrameCaptured(byte[] data, int width, int height, int rotation,
|
||||
long timeStamp);
|
||||
|
||||
// Delivers a captured frame in a texture with id |oesTextureId|. Called on a Java thread
|
||||
// owned by VideoCapturerAndroid.
|
||||
abstract void onTextureFrameCaptured(
|
||||
int width, int height, int oesTextureId, float[] transformMatrix, int rotation,
|
||||
long timestamp);
|
||||
|
||||
// Requests an output format from the video capturer. Captured frames
|
||||
// by the camera will be scaled/or dropped by the video capturer.
|
||||
// Called on a Java thread owned by VideoCapturerAndroid.
|
||||
abstract void onOutputFormatRequest(int width, int height, int framerate);
|
||||
}
|
||||
|
||||
// An implementation of CapturerObserver that forwards all calls from
|
||||
// Java to the C layer.
|
||||
static class NativeObserver implements CapturerObserver {
|
||||
private final long nativeCapturer;
|
||||
|
||||
public NativeObserver(long nativeCapturer) {
|
||||
this.nativeCapturer = nativeCapturer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCapturerStarted(boolean success) {
|
||||
nativeCapturerStarted(nativeCapturer, success);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onByteBufferFrameCaptured(byte[] data, int width, int height,
|
||||
int rotation, long timeStamp) {
|
||||
nativeOnByteBufferFrameCaptured(nativeCapturer, data, data.length, width, height, rotation,
|
||||
timeStamp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextureFrameCaptured(
|
||||
int width, int height, int oesTextureId, float[] transformMatrix, int rotation,
|
||||
long timestamp) {
|
||||
nativeOnTextureFrameCaptured(nativeCapturer, width, height, oesTextureId, transformMatrix,
|
||||
rotation, timestamp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOutputFormatRequest(int width, int height, int framerate) {
|
||||
nativeOnOutputFormatRequest(nativeCapturer, width, height, framerate);
|
||||
}
|
||||
|
||||
private native void nativeCapturerStarted(long nativeCapturer,
|
||||
boolean success);
|
||||
private native void nativeOnByteBufferFrameCaptured(long nativeCapturer,
|
||||
byte[] data, int length, int width, int height, int rotation, long timeStamp);
|
||||
private native void nativeOnTextureFrameCaptured(long nativeCapturer, int width, int height,
|
||||
int oesTextureId, float[] transformMatrix, int rotation, long timestamp);
|
||||
private native void nativeOnOutputFormatRequest(long nativeCapturer,
|
||||
int width, int height, int framerate);
|
||||
}
|
||||
|
||||
private static native long nativeCreateVideoCapturer(
|
||||
VideoCapturerAndroid videoCapturer,
|
||||
SurfaceTextureHelper surfaceHelper);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user