Add checks for buffer size in MediaCodecVideoEncoder.
This should help users of the library to more easily debug issues. Bug: None Change-Id: I85d8101d3b26ccbc34c8beded069461252e61293 Reviewed-on: https://webrtc-review.googlesource.com/4663 Reviewed-by: Magnus Jedvert <magjed@webrtc.org> Reviewed-by: Sami Kalliomäki <sakal@webrtc.org> Commit-Queue: Sami Kalliomäki <sakal@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20073}
This commit is contained in:
committed by
Commit Bot
parent
a58f231018
commit
e3044fe12e
@ -621,9 +621,24 @@ public class MediaCodecVideoEncoder {
|
||||
eglBase.swapBuffers(frame.getTimestampNs());
|
||||
} else {
|
||||
VideoFrame.I420Buffer i420Buffer = buffer.toI420();
|
||||
nativeFillBuffer(nativeEncoder, bufferIndex, i420Buffer.getDataY(), i420Buffer.getStrideY(),
|
||||
i420Buffer.getDataU(), i420Buffer.getStrideU(), i420Buffer.getDataV(),
|
||||
i420Buffer.getStrideV());
|
||||
final int chromaHeight = (height + 1) / 2;
|
||||
final ByteBuffer dataY = i420Buffer.getDataY();
|
||||
final ByteBuffer dataU = i420Buffer.getDataU();
|
||||
final ByteBuffer dataV = i420Buffer.getDataV();
|
||||
final int strideY = i420Buffer.getStrideY();
|
||||
final int strideU = i420Buffer.getStrideU();
|
||||
final int strideV = i420Buffer.getStrideV();
|
||||
if (dataY.capacity() < strideY * height) {
|
||||
throw new RuntimeException("Y-plane buffer size too small.");
|
||||
}
|
||||
if (dataU.capacity() < strideU * chromaHeight) {
|
||||
throw new RuntimeException("U-plane buffer size too small.");
|
||||
}
|
||||
if (dataV.capacity() < strideV * chromaHeight) {
|
||||
throw new RuntimeException("V-plane buffer size too small.");
|
||||
}
|
||||
nativeFillBuffer(
|
||||
nativeEncoder, bufferIndex, dataY, strideY, dataU, strideU, dataV, strideV);
|
||||
i420Buffer.release();
|
||||
// I420 consists of one full-resolution and two half-resolution planes.
|
||||
// 1 + 1 / 4 + 1 / 4 = 3 / 2
|
||||
|
||||
@ -58,21 +58,24 @@ public class VideoFrame {
|
||||
*/
|
||||
public interface I420Buffer extends Buffer {
|
||||
/**
|
||||
* Returns a direct ByteBuffer containing Y-plane data. The buffer size is at least getStrideY()
|
||||
* * getHeight() bytes. Callers may mutate the ByteBuffer (eg. through relative-read
|
||||
* operations), so implementations must return a new ByteBuffer or slice for each call.
|
||||
* Returns a direct ByteBuffer containing Y-plane data. The buffer capacity is at least
|
||||
* getStrideY() * getHeight() bytes. The position of the returned buffer is ignored and must
|
||||
* be 0. 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. Callers may mutate the ByteBuffer (eg. through relative-read
|
||||
* operations), so implementations must return a new ByteBuffer or slice for each call.
|
||||
* Returns a direct ByteBuffer containing U-plane data. The buffer capacity is at least
|
||||
* getStrideU() * ((getHeight() + 1) / 2) bytes. The position of the returned buffer is ignored
|
||||
* and must be 0. 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. Callers may mutate the ByteBuffer (eg. through relative-read
|
||||
* operations), so implementations must return a new ByteBuffer or slice for each call.
|
||||
* Returns a direct ByteBuffer containing V-plane data. The buffer capacity is at least
|
||||
* getStrideV() * ((getHeight() + 1) / 2) bytes. The position of the returned buffer is ignored
|
||||
* and must be 0. Callers may mutate the ByteBuffer (eg. through relative-read operations), so
|
||||
* implementations must return a new ByteBuffer or slice for each call.
|
||||
*/
|
||||
ByteBuffer getDataV();
|
||||
|
||||
|
||||
@ -1478,6 +1478,13 @@ JNI_FUNCTION_DECLARATION(void,
|
||||
uint8_t* buffer_v =
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer_v));
|
||||
|
||||
RTC_DCHECK(buffer_y) << "GetDirectBufferAddress returned null. Ensure that "
|
||||
"getDataY returns a direct ByteBuffer.";
|
||||
RTC_DCHECK(buffer_u) << "GetDirectBufferAddress returned null. Ensure that "
|
||||
"getDataU returns a direct ByteBuffer.";
|
||||
RTC_DCHECK(buffer_v) << "GetDirectBufferAddress returned null. Ensure that "
|
||||
"getDataV returns a direct ByteBuffer.";
|
||||
|
||||
reinterpret_cast<MediaCodecVideoEncoder*>(native_encoder)
|
||||
->FillInputBuffer(jni, input_buffer, buffer_y, stride_y, buffer_u,
|
||||
stride_u, buffer_v, stride_v);
|
||||
|
||||
Reference in New Issue
Block a user