Chromium Code Reviews| Index: webrtc/sdk/android/src/java/org/webrtc/I420BufferImpl.java |
| diff --git a/webrtc/sdk/android/src/java/org/webrtc/I420BufferImpl.java b/webrtc/sdk/android/src/java/org/webrtc/I420BufferImpl.java |
| index 87fc202ecea6e88d34a5e31aac3230e5c6113bd0..5fe7b94843a283046be54b51ea8768034bdb8ee6 100644 |
| --- a/webrtc/sdk/android/src/java/org/webrtc/I420BufferImpl.java |
| +++ b/webrtc/sdk/android/src/java/org/webrtc/I420BufferImpl.java |
| @@ -15,21 +15,44 @@ import org.webrtc.VideoFrame.I420Buffer; |
| /** Implementation of an I420 VideoFrame buffer. */ |
| class I420BufferImpl implements VideoFrame.I420Buffer { |
| + private final ByteBuffer buffer; |
| private final int width; |
| private final int height; |
| - private final int strideUV; |
| - private final ByteBuffer y; |
| - private final ByteBuffer u; |
| - private final ByteBuffer v; |
| + private final int chromaHeight; |
| + private final int yPos; |
| + private final int strideY; |
| + private final int uPos; |
| + private final int strideU; |
| + private final int vPos; |
| + private final int strideV; |
| + private final ReleaseCallback releaseCallback; |
| - I420BufferImpl(int width, int height) { |
| + private int refCount; |
| + |
| + /** Allocates an I420Buffer backed by existing data. */ |
| + I420BufferImpl(ByteBuffer buffer, int width, int height, int yPos, int strideY, int uPos, |
|
sakal
2017/07/17 13:44:56
I would prefer to just have a constructor that is
mellem
2017/07/17 21:57:15
Changed the second constructor to an allocate() me
|
| + int strideU, int vPos, int strideV, ReleaseCallback releaseCallback) { |
| + this.buffer = buffer; |
| this.width = width; |
| this.height = height; |
| - this.strideUV = (width + 1) / 2; |
| - int halfHeight = (height + 1) / 2; |
| - this.y = ByteBuffer.allocateDirect(width * height); |
| - this.u = ByteBuffer.allocateDirect(strideUV * halfHeight); |
| - this.v = ByteBuffer.allocateDirect(strideUV * halfHeight); |
| + this.chromaHeight = half(height); |
| + this.yPos = yPos; |
| + this.strideY = strideY; |
| + this.uPos = uPos; |
| + this.strideU = strideU; |
| + this.vPos = vPos; |
| + this.strideV = strideV; |
| + this.releaseCallback = releaseCallback; |
| + |
| + this.refCount = 1; |
| + } |
| + |
| + /** Allocates an empty I420Buffer suitable for an image of the given width and height. */ |
| + I420BufferImpl(int width, int height) { |
| + this(ByteBuffer.allocateDirect(size(width, height)), width, height, 0 /* yPos */, |
| + width /* strideY */, width * height /* uPos */, half(width) /* strideU */, |
| + width * height + half(width) * half(height) /* vPos */, half(width) /* strideV */, |
| + null /* releaseCallback */); |
| } |
| @Override |
| @@ -44,32 +67,41 @@ class I420BufferImpl implements VideoFrame.I420Buffer { |
| @Override |
| public ByteBuffer getDataY() { |
| - return y; |
| + ByteBuffer data = buffer.slice(); |
| + data.position(yPos); |
| + data.limit(yPos + getStrideY() * height); |
| + return data; |
| } |
| @Override |
| public ByteBuffer getDataU() { |
| - return u; |
| + ByteBuffer data = buffer.slice(); |
| + data.position(uPos); |
| + data.limit(uPos + strideU * chromaHeight); |
| + return data; |
| } |
| @Override |
| public ByteBuffer getDataV() { |
| - return v; |
| + ByteBuffer data = buffer.slice(); |
| + data.position(vPos); |
| + data.limit(vPos + strideV * chromaHeight); |
| + return data; |
| } |
| @Override |
| public int getStrideY() { |
| - return width; |
| + return strideY; |
| } |
| @Override |
| public int getStrideU() { |
| - return strideUV; |
| + return strideU; |
| } |
| @Override |
| public int getStrideV() { |
| - return strideUV; |
| + return strideV; |
| } |
| @Override |
| @@ -78,8 +110,28 @@ class I420BufferImpl implements VideoFrame.I420Buffer { |
| } |
| @Override |
| - public void retain() {} |
| + public void retain() { |
| + ++refCount; |
| + } |
| @Override |
| - public void release() {} |
| + public void release() { |
| + if (--refCount == 0 && releaseCallback != null) { |
| + releaseCallback.onRelease(); |
| + } |
| + } |
| + |
| + // Callback called when the frame is no longer referenced. |
| + interface ReleaseCallback { |
| + // Called when the frame is no longer referenced. |
| + void onRelease(); |
| + } |
| + |
| + private static int half(int num) { |
| + return (num + 1) / 2; |
| + } |
| + |
| + private static int size(int width, int height) { |
| + return width * height + half(width) * half(height) * 2; |
| + } |
| } |