Make VideoFrame.Buffer implementations lock-free.

Replaces lock-based implementation with AtomicInteger.

Bug: webrtc:7749
Change-Id: I226093b0af2090c080dfd4f87ed8f33a3f9efbd8
Reviewed-on: https://webrtc-review.googlesource.com/64162
Commit-Queue: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22798}
This commit is contained in:
Sami Kalliomäki
2018-04-09 17:51:19 +02:00
committed by Commit Bot
parent 11bf2fa43c
commit 61db3fd77f
8 changed files with 115 additions and 71 deletions

View File

@ -11,6 +11,7 @@
package org.webrtc;
import java.nio.ByteBuffer;
import javax.annotation.Nullable;
@JNINamespace("webrtc::jni")
public class NV12Buffer implements VideoFrame.Buffer {
@ -19,21 +20,16 @@ public class NV12Buffer implements VideoFrame.Buffer {
private final int stride;
private final int sliceHeight;
private final ByteBuffer buffer;
private final Runnable releaseCallback;
private final Object refCountLock = new Object();
private int refCount;
private final RefCountDelegate refCountDelegate;
public NV12Buffer(int width, int height, int stride, int sliceHeight, ByteBuffer buffer,
Runnable releaseCallback) {
@Nullable Runnable releaseCallback) {
this.width = width;
this.height = height;
this.stride = stride;
this.sliceHeight = sliceHeight;
this.buffer = buffer;
this.releaseCallback = releaseCallback;
refCount = 1;
this.refCountDelegate = new RefCountDelegate(releaseCallback);
}
@Override
@ -53,18 +49,12 @@ public class NV12Buffer implements VideoFrame.Buffer {
@Override
public void retain() {
synchronized (refCountLock) {
++refCount;
}
refCountDelegate.retain();
}
@Override
public void release() {
synchronized (refCountLock) {
if (--refCount == 0 && releaseCallback != null) {
releaseCallback.run();
}
}
refCountDelegate.release();
}
@Override

View File

@ -11,22 +11,21 @@
package org.webrtc;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
@JNINamespace("webrtc::jni")
public class NV21Buffer implements VideoFrame.Buffer {
private final byte[] data;
private final int width;
private final int height;
private final Runnable releaseCallback;
private final Object refCountLock = new Object();
private final RefCountDelegate refCountDelegate;
private int refCount = 1;
public NV21Buffer(byte[] data, int width, int height, Runnable releaseCallback) {
public NV21Buffer(byte[] data, int width, int height, @Nullable Runnable releaseCallback) {
this.data = data;
this.width = width;
this.height = height;
this.releaseCallback = releaseCallback;
this.refCountDelegate = new RefCountDelegate(releaseCallback);
}
@Override
@ -48,18 +47,12 @@ public class NV21Buffer implements VideoFrame.Buffer {
@Override
public void retain() {
synchronized (refCountLock) {
++refCount;
}
refCountDelegate.retain();
}
@Override
public void release() {
synchronized (refCountLock) {
if (--refCount == 0 && releaseCallback != null) {
releaseCallback.run();
}
}
refCountDelegate.release();
}
@Override

View File

@ -0,0 +1,41 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
package org.webrtc;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
/**
* Implementation of RefCounted that executes a Runnable once the ref count reaches zero.
*/
class RefCountDelegate implements RefCounted {
private final AtomicInteger refCount = new AtomicInteger(1);
private final @Nullable Runnable releaseCallback;
/**
* @param releaseCallback Callback that will be executed once the ref count reaches zero.
*/
public RefCountDelegate(@Nullable Runnable releaseCallback) {
this.releaseCallback = releaseCallback;
}
@Override
public void retain() {
refCount.incrementAndGet();
}
@Override
public void release() {
if (refCount.decrementAndGet() == 0 && releaseCallback != null) {
releaseCallback.run();
}
}
}

View File

@ -12,6 +12,8 @@ package org.webrtc;
import android.graphics.Matrix;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
/**
* Android texture buffer backed by a SurfaceTextureHelper's texture. The buffer calls
@ -24,20 +26,17 @@ class TextureBufferImpl implements VideoFrame.TextureBuffer {
private final int id;
private final Matrix transformMatrix;
private final SurfaceTextureHelper surfaceTextureHelper;
private final Runnable releaseCallback;
private final Object refCountLock = new Object();
private int refCount;
private final RefCountDelegate refCountDelegate;
public TextureBufferImpl(int width, int height, Type type, int id, Matrix transformMatrix,
SurfaceTextureHelper surfaceTextureHelper, Runnable releaseCallback) {
SurfaceTextureHelper surfaceTextureHelper, @Nullable Runnable releaseCallback) {
this.width = width;
this.height = height;
this.type = type;
this.id = id;
this.transformMatrix = transformMatrix;
this.surfaceTextureHelper = surfaceTextureHelper;
this.releaseCallback = releaseCallback;
this.refCount = 1; // Creator implicitly holds a reference.
this.refCountDelegate = new RefCountDelegate(releaseCallback);
}
@Override
@ -72,18 +71,12 @@ class TextureBufferImpl implements VideoFrame.TextureBuffer {
@Override
public void retain() {
synchronized (refCountLock) {
++refCount;
}
refCountDelegate.retain();
}
@Override
public void release() {
synchronized (refCountLock) {
if (--refCount == 0 && releaseCallback != null) {
releaseCallback.run();
}
}
refCountDelegate.release();
}
@Override