Return slices of ByteBuffers from getDataY/U/V() in I420Buffers.

I420Buffer implementations (I420BufferImpl and WrappedNativeI420Buffer) rely on
the 'position' of the underlying ByteBuffers to indicate the start of Y, U, and
V channels.  Returning slices prevents callers from altering the state of the
I420Buffer by changing the position.

ByteBuffers are especially prone to accidentally moving the position: relative
read operations (such as get()) increment the position by the size of data read.

BUG=webrtc:8303

Change-Id: I52edce8a3bf46a6c41980ff5110a9480f021f22f
Reviewed-on: https://webrtc-review.googlesource.com/4521
Commit-Queue: Bjorn Mellem <mellem@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20050}
This commit is contained in:
Bjorn Mellem
2017-09-29 11:33:52 -07:00
committed by Commit Bot
parent b5261580bc
commit d629314396
3 changed files with 18 additions and 9 deletions

View File

@ -59,17 +59,20 @@ public class VideoFrame {
public interface I420Buffer extends Buffer { public interface I420Buffer extends Buffer {
/** /**
* Returns a direct ByteBuffer containing Y-plane data. The buffer size is at least getStrideY() * Returns a direct ByteBuffer containing Y-plane data. The buffer size is at least getStrideY()
* * getHeight() bytes. * * getHeight() bytes. Callers may mutate the ByteBuffer (eg. through relative-read
* operations), so implementations must return a new ByteBuffer or slice for each call.
*/ */
ByteBuffer getDataY(); ByteBuffer getDataY();
/** /**
* Returns a direct ByteBuffer containing U-plane data. The buffer size is at least getStrideU() * Returns a direct ByteBuffer containing U-plane data. The buffer size is at least getStrideU()
* * ((getHeight() + 1) / 2) bytes. * * ((getHeight() + 1) / 2) bytes. Callers may mutate the ByteBuffer (eg. through relative-read
* operations), so implementations must return a new ByteBuffer or slice for each call.
*/ */
ByteBuffer getDataU(); ByteBuffer getDataU();
/** /**
* Returns a direct ByteBuffer containing V-plane data. The buffer size is at least getStrideV() * Returns a direct ByteBuffer containing V-plane data. The buffer size is at least getStrideV()
* * ((getHeight() + 1) / 2) bytes. * * ((getHeight() + 1) / 2) bytes. Callers may mutate the ByteBuffer (eg. through relative-read
* operations), so implementations must return a new ByteBuffer or slice for each call.
*/ */
ByteBuffer getDataV(); ByteBuffer getDataV();

View File

@ -81,17 +81,20 @@ class I420BufferImpl implements VideoFrame.I420Buffer {
@Override @Override
public ByteBuffer getDataY() { public ByteBuffer getDataY() {
return dataY; // Return a slice to prevent relative reads from changing the position.
return dataY.slice();
} }
@Override @Override
public ByteBuffer getDataU() { public ByteBuffer getDataU() {
return dataU; // Return a slice to prevent relative reads from changing the position.
return dataU.slice();
} }
@Override @Override
public ByteBuffer getDataV() { public ByteBuffer getDataV() {
return dataV; // Return a slice to prevent relative reads from changing the position.
return dataV.slice();
} }
@Override @Override

View File

@ -53,17 +53,20 @@ class WrappedNativeI420Buffer implements VideoFrame.I420Buffer {
@Override @Override
public ByteBuffer getDataY() { public ByteBuffer getDataY() {
return dataY; // Return a slice to prevent relative reads from changing the position.
return dataY.slice();
} }
@Override @Override
public ByteBuffer getDataU() { public ByteBuffer getDataU() {
return dataU; // Return a slice to prevent relative reads from changing the position.
return dataU.slice();
} }
@Override @Override
public ByteBuffer getDataV() { public ByteBuffer getDataV() {
return dataV; // Return a slice to prevent relative reads from changing the position.
return dataV.slice();
} }
@Override @Override