Android: Fix synchronization problems in VideoFrame release.

Also fixes a small bug in EglRenderer where if it was passed a custom
frame, it would leak a reference.

BUG=b/64887218

Review-Url: https://codereview.webrtc.org/3003533002
Cr-Commit-Position: refs/heads/master@{#19432}
This commit is contained in:
sakal 2017-08-21 08:02:58 -07:00 committed by Commit Bot
parent 139cf38223
commit 2fe9dfae20
4 changed files with 26 additions and 11 deletions

View File

@ -639,7 +639,7 @@ public class EglRenderer implements VideoRenderer.Callbacks, VideoSink {
} }
notifyCallbacks(frame, isYuvBuffer, yuvTextures, shouldRenderFrame); notifyCallbacks(frame, isYuvBuffer, yuvTextures, shouldRenderFrame);
frame.release(); buffer.release();
} }
private void notifyCallbacks( private void notifyCallbacks(

View File

@ -24,6 +24,7 @@ class I420BufferImpl implements VideoFrame.I420Buffer {
private final int strideU; private final int strideU;
private final int strideV; private final int strideV;
private final Runnable releaseCallback; private final Runnable releaseCallback;
private final Object refCountLock = new Object();
private int refCount; private int refCount;
@ -116,13 +117,17 @@ class I420BufferImpl implements VideoFrame.I420Buffer {
@Override @Override
public void retain() { public void retain() {
++refCount; synchronized (refCountLock) {
++refCount;
}
} }
@Override @Override
public void release() { public void release() {
if (--refCount == 0 && releaseCallback != null) { synchronized (refCountLock) {
releaseCallback.run(); if (--refCount == 0 && releaseCallback != null) {
releaseCallback.run();
}
} }
} }

View File

@ -19,6 +19,7 @@ public class NV12Buffer implements VideoFrame.Buffer {
private final int sliceHeight; private final int sliceHeight;
private final ByteBuffer buffer; private final ByteBuffer buffer;
private final Runnable releaseCallback; private final Runnable releaseCallback;
private final Object refCountLock = new Object();
private int refCount; private int refCount;
@ -51,13 +52,17 @@ public class NV12Buffer implements VideoFrame.Buffer {
@Override @Override
public void retain() { public void retain() {
refCount++; synchronized (refCountLock) {
++refCount;
}
} }
@Override @Override
public void release() { public void release() {
if (--refCount == 0) { synchronized (refCountLock) {
releaseCallback.run(); if (--refCount == 0 && releaseCallback != null) {
releaseCallback.run();
}
} }
} }

View File

@ -25,6 +25,7 @@ class TextureBufferImpl implements VideoFrame.TextureBuffer {
private final Matrix transformMatrix; private final Matrix transformMatrix;
private final SurfaceTextureHelper surfaceTextureHelper; private final SurfaceTextureHelper surfaceTextureHelper;
private final Runnable releaseCallback; private final Runnable releaseCallback;
private final Object refCountLock = new Object();
private int refCount; private int refCount;
public TextureBufferImpl(int width, int height, Type type, int id, Matrix transformMatrix, public TextureBufferImpl(int width, int height, Type type, int id, Matrix transformMatrix,
@ -102,13 +103,17 @@ class TextureBufferImpl implements VideoFrame.TextureBuffer {
@Override @Override
public void retain() { public void retain() {
++refCount; synchronized (refCountLock) {
++refCount;
}
} }
@Override @Override
public void release() { public void release() {
if (--refCount == 0) { synchronized (refCountLock) {
releaseCallback.run(); if (--refCount == 0 && releaseCallback != null) {
releaseCallback.run();
}
} }
} }