VideoCaptureAndroid: don't deliver frames after stopCapture().
Because stopCapture() and onPreviewFrame() are called on different threads, and are both synchronized, it's possible for onPreviewFrame() to commence execution after stopCapture() has completed, causing a SEGV because the native code is no longer prepared to accept frames. Clarify the contract around synchronized methods in this class to hopefully avoid similar bugs in future. BUG=2947 R=henrike@webrtc.org Review URL: https://webrtc-codereview.appspot.com/9339004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5639 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
be50ab645a
commit
7bd4a27502
@ -31,7 +31,9 @@ import android.view.SurfaceHolder.Callback;
|
||||
// the entry points to this class are all synchronized. This shouldn't present
|
||||
// a performance bottleneck because only onPreviewFrame() is called more than
|
||||
// once (and is called serially on a single thread), so the lock should be
|
||||
// uncontended.
|
||||
// uncontended. Note that each of these synchronized methods must check
|
||||
// |camera| for null to account for having possibly waited for stopCapture() to
|
||||
// complete.
|
||||
public class VideoCaptureAndroid implements PreviewCallback, Callback {
|
||||
private final static String TAG = "WEBRTC-JC";
|
||||
|
||||
@ -149,7 +151,13 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
|
||||
private native void ProvideCameraFrame(
|
||||
byte[] data, int length, long captureObject);
|
||||
|
||||
public synchronized void onPreviewFrame(byte[] data, Camera camera) {
|
||||
public synchronized void onPreviewFrame(byte[] data, Camera callbackCamera) {
|
||||
if (camera == null) {
|
||||
return;
|
||||
}
|
||||
if (camera != callbackCamera) {
|
||||
throw new RuntimeException("Unexpected camera in callback!");
|
||||
}
|
||||
ProvideCameraFrame(data, data.length, native_capturer);
|
||||
camera.addCallbackBuffer(data);
|
||||
}
|
||||
@ -184,10 +192,11 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
|
||||
|
||||
public synchronized void surfaceCreated(SurfaceHolder holder) {
|
||||
Log.d(TAG, "VideoCaptureAndroid::surfaceCreated");
|
||||
if (camera == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (camera != null) {
|
||||
camera.setPreviewDisplay(holder);
|
||||
}
|
||||
camera.setPreviewDisplay(holder);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@ -195,10 +204,11 @@ public class VideoCaptureAndroid implements PreviewCallback, Callback {
|
||||
|
||||
public synchronized void surfaceDestroyed(SurfaceHolder holder) {
|
||||
Log.d(TAG, "VideoCaptureAndroid::surfaceDestroyed");
|
||||
if (camera == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (camera != null) {
|
||||
camera.setPreviewDisplay(null);
|
||||
}
|
||||
camera.setPreviewDisplay(null);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user