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}
diff --git a/sdk/android/api/org/webrtc/EncodedImage.java b/sdk/android/api/org/webrtc/EncodedImage.java
index 84c72b1..f8de3d2 100644
--- a/sdk/android/api/org/webrtc/EncodedImage.java
+++ b/sdk/android/api/org/webrtc/EncodedImage.java
@@ -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 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 @@
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 @@
private EncodedImage.FrameType frameType;
private int rotation;
private boolean completeFrame;
- private Integer qp;
+ private @Nullable Integer qp;
private Builder() {}
@@ -126,7 +167,7 @@
return this;
}
- public Builder setQp(Integer qp) {
+ public Builder setQp(@Nullable Integer qp) {
this.qp = qp;
return this;
}
diff --git a/sdk/android/src/java/org/webrtc/VideoEncoderWrapper.java b/sdk/android/src/java/org/webrtc/VideoEncoderWrapper.java
index e167b89..03676b1 100644
--- a/sdk/android/src/java/org/webrtc/VideoEncoderWrapper.java
+++ b/sdk/android/src/java/org/webrtc/VideoEncoderWrapper.java
@@ -38,13 +38,10 @@
@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);
}
diff --git a/sdk/android/src/jni/encoded_image.cc b/sdk/android/src/jni/encoded_image.cc
index b288d36..328aa7c 100644
--- a/sdk/android/src/jni/encoded_image.cc
+++ b/sdk/android/src/jni/encoded_image.cc
@@ -49,5 +49,40 @@
&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
diff --git a/sdk/android/src/jni/encoded_image.h b/sdk/android/src/jni/encoded_image.h
index 2078830..fc6d062 100644
--- a/sdk/android/src/jni/encoded_image.h
+++ b/sdk/android/src/jni/encoded_image.h
@@ -32,6 +32,13 @@
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
diff --git a/sdk/android/src/jni/video_encoder_wrapper.cc b/sdk/android/src/jni/video_encoder_wrapper.cc
index e051b77..ebf6aad 100644
--- a/sdk/android/src/jni/video_encoder_wrapper.cc
+++ b/sdk/android/src/jni/video_encoder_wrapper.cc
@@ -214,38 +214,18 @@
}
}
-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 @@
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);
diff --git a/sdk/android/src/jni/video_encoder_wrapper.h b/sdk/android/src/jni/video_encoder_wrapper.h
index 43d1f6f..685c6da 100644
--- a/sdk/android/src/jni/video_encoder_wrapper.h
+++ b/sdk/android/src/jni/video_encoder_wrapper.h
@@ -51,14 +51,7 @@
// 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 {