Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions webrtc-jni/src/main/cpp/include/JNI_NativeI420Buffer.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion webrtc-jni/src/main/cpp/src/JNI_NativeI420Buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include "common_video/include/video_frame_buffer.h"
#include "libyuv/scale.h"

JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_video_NativeI420Buffer_allocate
JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_video_NativeI420Buffer_allocateBuffer
(JNIEnv * env, jclass caller, jint width, jint height)
{
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,31 @@ public NativeI420Buffer copy() {

/**
* Allocates an empty I420Buffer suitable for an image of the given dimensions.
*
* @param width The width of the image in pixels.
* @param height The height of the image in pixels.
*
* @return A new buffer of the given dimensions.
*
* @throws IllegalArgumentException if a dimension is not positive or all three planes together
* are larger than {@link Integer#MAX_VALUE} bytes.
*/
public static native NativeI420Buffer allocate(int width, int height);
public static NativeI420Buffer allocate(int width, int height) {
// WebRTC aborts the process on dimensions it cannot allocate, rather than failing the call.
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("Invalid buffer size " + width + "x" + height);
}

long chromaSize = ((width + 1L) / 2) * ((height + 1L) / 2);

if ((long) width * height + 2 * chromaSize > Integer.MAX_VALUE) {
throw new IllegalArgumentException("Buffer size " + width + "x" + height + " is too large");
}

return allocateBuffer(width, height);
}

private static native NativeI420Buffer allocateBuffer(int width, int height);

/**
* Creates a copy of an I420 buffer with the given dimensions and data.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,35 @@ void cropOutsideBuffer() {
source.release();
}

@Test
void allocateInvalidSize() {
assertThrows(IllegalArgumentException.class, () -> NativeI420Buffer.allocate(0, 8));
assertThrows(IllegalArgumentException.class, () -> NativeI420Buffer.allocate(8, 0));
assertThrows(IllegalArgumentException.class, () -> NativeI420Buffer.allocate(-8, 8));
assertThrows(IllegalArgumentException.class, () -> NativeI420Buffer.allocate(8, Integer.MIN_VALUE));
}

@Test
void allocateTooLarge() {
// The planes would exceed what WebRTC can address with an int.
assertThrows(IllegalArgumentException.class, () -> NativeI420Buffer.allocate(Integer.MAX_VALUE, Integer.MAX_VALUE));
assertThrows(IllegalArgumentException.class, () -> NativeI420Buffer.allocate(46341, 46341));
assertThrows(IllegalArgumentException.class, () -> NativeI420Buffer.allocate(Integer.MAX_VALUE, 1));
}

@Test
void allocateOddSize() {
NativeI420Buffer buffer = NativeI420Buffer.allocate(3, 1);

assertEquals(3, buffer.getWidth());
assertEquals(1, buffer.getHeight());
assertEquals(3, buffer.getDataY().capacity());
assertEquals(2, buffer.getDataU().capacity());
assertEquals(2, buffer.getDataV().capacity());

buffer.release();
}

@Test
void pushReleasedBuffer() {
CustomVideoSource videoSource = new CustomVideoSource();
Expand Down
Loading