Support Java VideoFrames in MediaCodecVideoEncoder.
BUG=webrtc:7760 Review-Url: https://codereview.webrtc.org/2997663002 Cr-Commit-Position: refs/heads/master@{#19304}
This commit is contained in:
@ -11,6 +11,7 @@
|
||||
package org.webrtc;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.graphics.Matrix;
|
||||
import android.media.MediaCodec;
|
||||
import android.media.MediaCodecInfo;
|
||||
import android.media.MediaCodecInfo.CodecCapabilities;
|
||||
@ -598,6 +599,46 @@ public class MediaCodecVideoEncoder {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a new style VideoFrame. Called by JNI. |bufferIndex| is -1 if we are not encoding in
|
||||
* surface mode.
|
||||
*/
|
||||
boolean encodeFrame(long nativeEncoder, boolean isKeyframe, VideoFrame frame, int bufferIndex) {
|
||||
checkOnMediaCodecThread();
|
||||
try {
|
||||
long presentationTimestampUs = TimeUnit.NANOSECONDS.toMicros(frame.getTimestampNs());
|
||||
checkKeyFrameRequired(isKeyframe, presentationTimestampUs);
|
||||
|
||||
VideoFrame.Buffer buffer = frame.getBuffer();
|
||||
if (buffer instanceof VideoFrame.TextureBuffer) {
|
||||
VideoFrame.TextureBuffer textureBuffer = (VideoFrame.TextureBuffer) buffer;
|
||||
eglBase.makeCurrent();
|
||||
// TODO(perkj): glClear() shouldn't be necessary since every pixel is covered anyway,
|
||||
// but it's a workaround for bug webrtc:5147.
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
||||
drawer.drawOes(textureBuffer.getTextureId(),
|
||||
RendererCommon.convertMatrixFromAndroidGraphicsMatrix(
|
||||
textureBuffer.getTransformMatrix()),
|
||||
width, height, 0, 0, width, height);
|
||||
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());
|
||||
i420Buffer.release();
|
||||
// I420 consists of one full-resolution and two half-resolution planes.
|
||||
// 1 + 1 / 4 + 1 / 4 = 3 / 2
|
||||
int yuvSize = width * height * 3 / 2;
|
||||
mediaCodec.queueInputBuffer(bufferIndex, 0, yuvSize, presentationTimestampUs, 0);
|
||||
}
|
||||
return true;
|
||||
} catch (RuntimeException e) {
|
||||
Logging.e(TAG, "encodeFrame failed", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void release() {
|
||||
Logging.d(TAG, "Java releaseEncoder");
|
||||
checkOnMediaCodecThread();
|
||||
@ -881,4 +922,8 @@ public class MediaCodecVideoEncoder {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Fills an inputBuffer with the given index with data from the byte buffers. */
|
||||
private static native void nativeFillBuffer(long nativeEncoder, int inputBuffer, ByteBuffer dataY,
|
||||
int strideY, ByteBuffer dataU, int strideU, ByteBuffer dataV, int strideV);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user