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}
diff --git a/sdk/android/api/org/webrtc/VideoFrame.java b/sdk/android/api/org/webrtc/VideoFrame.java
index 6a92cc9..a131121 100644
--- a/sdk/android/api/org/webrtc/VideoFrame.java
+++ b/sdk/android/api/org/webrtc/VideoFrame.java
@@ -59,17 +59,20 @@
   public interface I420Buffer extends Buffer {
     /**
      * 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();
     /**
      * 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();
     /**
      * 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();
 
diff --git a/sdk/android/src/java/org/webrtc/I420BufferImpl.java b/sdk/android/src/java/org/webrtc/I420BufferImpl.java
index 2f545e9..48efc25 100644
--- a/sdk/android/src/java/org/webrtc/I420BufferImpl.java
+++ b/sdk/android/src/java/org/webrtc/I420BufferImpl.java
@@ -81,17 +81,20 @@
 
   @Override
   public ByteBuffer getDataY() {
-    return dataY;
+    // Return a slice to prevent relative reads from changing the position.
+    return dataY.slice();
   }
 
   @Override
   public ByteBuffer getDataU() {
-    return dataU;
+    // Return a slice to prevent relative reads from changing the position.
+    return dataU.slice();
   }
 
   @Override
   public ByteBuffer getDataV() {
-    return dataV;
+    // Return a slice to prevent relative reads from changing the position.
+    return dataV.slice();
   }
 
   @Override
diff --git a/sdk/android/src/java/org/webrtc/WrappedNativeI420Buffer.java b/sdk/android/src/java/org/webrtc/WrappedNativeI420Buffer.java
index 85d02e6..ba7f386 100644
--- a/sdk/android/src/java/org/webrtc/WrappedNativeI420Buffer.java
+++ b/sdk/android/src/java/org/webrtc/WrappedNativeI420Buffer.java
@@ -53,17 +53,20 @@
 
   @Override
   public ByteBuffer getDataY() {
-    return dataY;
+    // Return a slice to prevent relative reads from changing the position.
+    return dataY.slice();
   }
 
   @Override
   public ByteBuffer getDataU() {
-    return dataU;
+    // Return a slice to prevent relative reads from changing the position.
+    return dataU.slice();
   }
 
   @Override
   public ByteBuffer getDataV() {
-    return dataV;
+    // Return a slice to prevent relative reads from changing the position.
+    return dataV.slice();
   }
 
   @Override