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:
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user