Pass java EncodedImage over jni to VideoEncoderWrapper::OnEncodedFrame

Preparation for adding a release() method on java's EncodedImage, and
call that from C++.

Bug: webrtc:9378
Change-Id: I301f64b16684c535f45a3fc9cd9ae1543df59d92
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/141861
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28268}
This commit is contained in:
Niels Möller
2019-06-13 14:37:24 +02:00
committed by Commit Bot
parent f3f57700a8
commit 6fd67f086c
6 changed files with 103 additions and 48 deletions

View File

@ -10,6 +10,7 @@
package org.webrtc;
import android.support.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.concurrent.TimeUnit;
@ -53,11 +54,11 @@ public class EncodedImage {
public final FrameType frameType;
public final int rotation;
public final boolean completeFrame;
public final Integer qp;
public final @Nullable Integer qp;
@CalledByNative
private EncodedImage(ByteBuffer buffer, int encodedWidth, int encodedHeight, long captureTimeNs,
FrameType frameType, int rotation, boolean completeFrame, Integer qp) {
FrameType frameType, int rotation, boolean completeFrame, @Nullable Integer qp) {
this.buffer = buffer;
this.encodedWidth = encodedWidth;
this.encodedHeight = encodedHeight;
@ -69,6 +70,46 @@ public class EncodedImage {
this.qp = qp;
}
@CalledByNative
private ByteBuffer getBuffer() {
return buffer;
}
@CalledByNative
private int getEncodedWidth() {
return encodedWidth;
}
@CalledByNative
private int getEncodedHeight() {
return encodedHeight;
}
@CalledByNative
private long getCaptureTimeNs() {
return captureTimeNs;
}
@CalledByNative
private int getFrameType() {
return frameType.getNative();
}
@CalledByNative
private int getRotation() {
return rotation;
}
@CalledByNative
private boolean getCompleteFrame() {
return completeFrame;
}
@CalledByNative
private @Nullable Integer getQp() {
return qp;
}
public static Builder builder() {
return new Builder();
}
@ -81,7 +122,7 @@ public class EncodedImage {
private EncodedImage.FrameType frameType;
private int rotation;
private boolean completeFrame;
private Integer qp;
private @Nullable Integer qp;
private Builder() {}
@ -126,7 +167,7 @@ public class EncodedImage {
return this;
}
public Builder setQp(Integer qp) {
public Builder setQp(@Nullable Integer qp) {
this.qp = qp;
return this;
}

View File

@ -38,13 +38,10 @@ class VideoEncoderWrapper {
@CalledByNative
static VideoEncoder.Callback createEncoderCallback(final long nativeEncoder) {
return (EncodedImage frame, VideoEncoder.CodecSpecificInfo info)
-> nativeOnEncodedFrame(nativeEncoder, frame.buffer, frame.encodedWidth,
frame.encodedHeight, frame.captureTimeNs, frame.frameType.getNative(),
frame.rotation, frame.completeFrame, frame.qp);
return (EncodedImage frame,
VideoEncoder.CodecSpecificInfo info) -> nativeOnEncodedFrame(nativeEncoder, frame);
}
private static native void nativeOnEncodedFrame(long nativeVideoEncoderWrapper, ByteBuffer buffer,
int encodedWidth, int encodedHeight, long captureTimeNs, int frameType, int rotation,
boolean completeFrame, Integer qp);
private static native void nativeOnEncodedFrame(
long nativeVideoEncoderWrapper, EncodedImage frame);
}

View File

@ -49,5 +49,40 @@ ScopedJavaLocalRef<jobjectArray> NativeToJavaFrameTypeArray(
&NativeToJavaFrameType);
}
EncodedImage JavaToNativeEncodedImage(JNIEnv* env,
const JavaRef<jobject>& j_encoded_image) {
const JavaRef<jobject>& j_buffer =
Java_EncodedImage_getBuffer(env, j_encoded_image);
const uint8_t* buffer =
static_cast<uint8_t*>(env->GetDirectBufferAddress(j_buffer.obj()));
const size_t buffer_size = env->GetDirectBufferCapacity(j_buffer.obj());
EncodedImage frame;
frame.Allocate(buffer_size);
frame.set_size(buffer_size);
memcpy(frame.data(), buffer, buffer_size);
frame._encodedWidth = Java_EncodedImage_getEncodedWidth(env, j_encoded_image);
frame._encodedHeight =
Java_EncodedImage_getEncodedHeight(env, j_encoded_image);
frame.rotation_ =
(VideoRotation)Java_EncodedImage_getRotation(env, j_encoded_image);
frame._completeFrame =
Java_EncodedImage_getCompleteFrame(env, j_encoded_image);
frame.qp_ = JavaToNativeOptionalInt(
env, Java_EncodedImage_getQp(env, j_encoded_image))
.value_or(-1);
frame._frameType =
(VideoFrameType)Java_EncodedImage_getFrameType(env, j_encoded_image);
return frame;
}
int64_t GetJavaEncodedImageCaptureTimeNs(
JNIEnv* env,
const JavaRef<jobject>& j_encoded_image) {
return Java_EncodedImage_getCaptureTimeNs(env, j_encoded_image);
}
} // namespace jni
} // namespace webrtc

View File

@ -32,6 +32,13 @@ ScopedJavaLocalRef<jobjectArray> NativeToJavaFrameTypeArray(
JNIEnv* env,
const std::vector<VideoFrameType>& frame_types);
EncodedImage JavaToNativeEncodedImage(JNIEnv* env,
const JavaRef<jobject>& j_encoded_image);
int64_t GetJavaEncodedImageCaptureTimeNs(
JNIEnv* jni,
const JavaRef<jobject>& j_encoded_image);
} // namespace jni
} // namespace webrtc

View File

@ -214,38 +214,18 @@ VideoEncoderWrapper::GetScalingSettingsInternal(JNIEnv* jni) const {
}
}
void VideoEncoderWrapper::OnEncodedFrame(JNIEnv* jni,
const JavaRef<jobject>& j_caller,
const JavaRef<jobject>& j_buffer,
jint encoded_width,
jint encoded_height,
jlong capture_time_ns,
jint frame_type,
jint rotation,
jboolean complete_frame,
const JavaRef<jobject>& j_qp) {
const uint8_t* buffer =
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer.obj()));
const size_t buffer_size = jni->GetDirectBufferCapacity(j_buffer.obj());
EncodedImage frame;
frame.Allocate(buffer_size);
frame.set_size(buffer_size);
memcpy(frame.data(), buffer, buffer_size);
frame._encodedWidth = encoded_width;
frame._encodedHeight = encoded_height;
frame.rotation_ = (VideoRotation)rotation;
frame._completeFrame = complete_frame;
const absl::optional<int> qp = JavaToNativeOptionalInt(jni, j_qp);
frame._frameType = (VideoFrameType)frame_type;
void VideoEncoderWrapper::OnEncodedFrame(
JNIEnv* jni,
const JavaRef<jobject>& j_caller,
const JavaRef<jobject>& j_encoded_image) {
EncodedImage frame = JavaToNativeEncodedImage(jni, j_encoded_image);
int64_t capture_time_ns =
GetJavaEncodedImageCaptureTimeNs(jni, j_encoded_image);
{
rtc::CritScope lock(&encoder_queue_crit_);
if (encoder_queue_ != nullptr) {
encoder_queue_->PostTask(ToQueuedTask([this, frame, qp,
capture_time_ns]() {
encoder_queue_->PostTask(ToQueuedTask([this, frame, capture_time_ns]() {
// Encoded frames are delivered in the order received, but some of them
// may be dropped, so remove records of frames older than the current
// one.
@ -284,7 +264,9 @@ void VideoEncoderWrapper::OnEncodedFrame(JNIEnv* jni,
capture_time_ns / rtc::kNumNanosecsPerMillisec;
RTPFragmentationHeader header = ParseFragmentationHeader(frame);
frame_copy.qp_ = qp ? *qp : ParseQp(frame);
if (frame_copy.qp_ < 0)
frame_copy.qp_ = ParseQp(frame);
CodecSpecificInfo info(ParseCodecSpecificInfo(frame));
callback_->OnEncodedImage(frame_copy, &info, &header);

View File

@ -51,14 +51,7 @@ class VideoEncoderWrapper : public VideoEncoder {
// Should only be called by JNI.
void OnEncodedFrame(JNIEnv* jni,
const JavaRef<jobject>& j_caller,
const JavaRef<jobject>& j_buffer,
jint encoded_width,
jint encoded_height,
jlong capture_time_ms,
jint frame_type,
jint rotation,
jboolean complete_frame,
const JavaRef<jobject>& j_qp);
const JavaRef<jobject>& j_encoded_image);
private:
struct FrameExtraInfo {