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();
}
} }
} }
@ -75,4 +80,4 @@ public class NV12Buffer implements VideoFrame.Buffer {
int scaleWidth, int scaleHeight, ByteBuffer src, int srcWidth, int srcHeight, int srcStride, int scaleWidth, int scaleHeight, ByteBuffer src, int srcWidth, int srcHeight, int srcStride,
int srcSliceHeight, ByteBuffer dstY, int dstStrideY, ByteBuffer dstU, int dstStrideU, int srcSliceHeight, ByteBuffer dstY, int dstStrideY, ByteBuffer dstU, int dstStrideU,
ByteBuffer dstV, int dstStrideV); ByteBuffer dstV, int dstStrideV);
} }

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();
}
} }
} }