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;
|
package org.webrtc;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -53,11 +54,11 @@ public class EncodedImage {
|
|||||||
public final FrameType frameType;
|
public final FrameType frameType;
|
||||||
public final int rotation;
|
public final int rotation;
|
||||||
public final boolean completeFrame;
|
public final boolean completeFrame;
|
||||||
public final Integer qp;
|
public final @Nullable Integer qp;
|
||||||
|
|
||||||
@CalledByNative
|
@CalledByNative
|
||||||
private EncodedImage(ByteBuffer buffer, int encodedWidth, int encodedHeight, long captureTimeNs,
|
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.buffer = buffer;
|
||||||
this.encodedWidth = encodedWidth;
|
this.encodedWidth = encodedWidth;
|
||||||
this.encodedHeight = encodedHeight;
|
this.encodedHeight = encodedHeight;
|
||||||
@ -69,6 +70,46 @@ public class EncodedImage {
|
|||||||
this.qp = qp;
|
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() {
|
public static Builder builder() {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
@ -81,7 +122,7 @@ public class EncodedImage {
|
|||||||
private EncodedImage.FrameType frameType;
|
private EncodedImage.FrameType frameType;
|
||||||
private int rotation;
|
private int rotation;
|
||||||
private boolean completeFrame;
|
private boolean completeFrame;
|
||||||
private Integer qp;
|
private @Nullable Integer qp;
|
||||||
|
|
||||||
private Builder() {}
|
private Builder() {}
|
||||||
|
|
||||||
@ -126,7 +167,7 @@ public class EncodedImage {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setQp(Integer qp) {
|
public Builder setQp(@Nullable Integer qp) {
|
||||||
this.qp = qp;
|
this.qp = qp;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,13 +38,10 @@ class VideoEncoderWrapper {
|
|||||||
|
|
||||||
@CalledByNative
|
@CalledByNative
|
||||||
static VideoEncoder.Callback createEncoderCallback(final long nativeEncoder) {
|
static VideoEncoder.Callback createEncoderCallback(final long nativeEncoder) {
|
||||||
return (EncodedImage frame, VideoEncoder.CodecSpecificInfo info)
|
return (EncodedImage frame,
|
||||||
-> nativeOnEncodedFrame(nativeEncoder, frame.buffer, frame.encodedWidth,
|
VideoEncoder.CodecSpecificInfo info) -> nativeOnEncodedFrame(nativeEncoder, frame);
|
||||||
frame.encodedHeight, frame.captureTimeNs, frame.frameType.getNative(),
|
|
||||||
frame.rotation, frame.completeFrame, frame.qp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native void nativeOnEncodedFrame(long nativeVideoEncoderWrapper, ByteBuffer buffer,
|
private static native void nativeOnEncodedFrame(
|
||||||
int encodedWidth, int encodedHeight, long captureTimeNs, int frameType, int rotation,
|
long nativeVideoEncoderWrapper, EncodedImage frame);
|
||||||
boolean completeFrame, Integer qp);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,5 +49,40 @@ ScopedJavaLocalRef<jobjectArray> NativeToJavaFrameTypeArray(
|
|||||||
&NativeToJavaFrameType);
|
&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 jni
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -32,6 +32,13 @@ ScopedJavaLocalRef<jobjectArray> NativeToJavaFrameTypeArray(
|
|||||||
JNIEnv* env,
|
JNIEnv* env,
|
||||||
const std::vector<VideoFrameType>& frame_types);
|
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 jni
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
|||||||
@ -214,38 +214,18 @@ VideoEncoderWrapper::GetScalingSettingsInternal(JNIEnv* jni) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoEncoderWrapper::OnEncodedFrame(JNIEnv* jni,
|
void VideoEncoderWrapper::OnEncodedFrame(
|
||||||
|
JNIEnv* jni,
|
||||||
const JavaRef<jobject>& j_caller,
|
const JavaRef<jobject>& j_caller,
|
||||||
const JavaRef<jobject>& j_buffer,
|
const JavaRef<jobject>& j_encoded_image) {
|
||||||
jint encoded_width,
|
EncodedImage frame = JavaToNativeEncodedImage(jni, j_encoded_image);
|
||||||
jint encoded_height,
|
int64_t capture_time_ns =
|
||||||
jlong capture_time_ns,
|
GetJavaEncodedImageCaptureTimeNs(jni, j_encoded_image);
|
||||||
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;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
rtc::CritScope lock(&encoder_queue_crit_);
|
rtc::CritScope lock(&encoder_queue_crit_);
|
||||||
if (encoder_queue_ != nullptr) {
|
if (encoder_queue_ != nullptr) {
|
||||||
encoder_queue_->PostTask(ToQueuedTask([this, frame, qp,
|
encoder_queue_->PostTask(ToQueuedTask([this, frame, capture_time_ns]() {
|
||||||
capture_time_ns]() {
|
|
||||||
// Encoded frames are delivered in the order received, but some of them
|
// Encoded frames are delivered in the order received, but some of them
|
||||||
// may be dropped, so remove records of frames older than the current
|
// may be dropped, so remove records of frames older than the current
|
||||||
// one.
|
// one.
|
||||||
@ -284,7 +264,9 @@ void VideoEncoderWrapper::OnEncodedFrame(JNIEnv* jni,
|
|||||||
capture_time_ns / rtc::kNumNanosecsPerMillisec;
|
capture_time_ns / rtc::kNumNanosecsPerMillisec;
|
||||||
|
|
||||||
RTPFragmentationHeader header = ParseFragmentationHeader(frame);
|
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));
|
CodecSpecificInfo info(ParseCodecSpecificInfo(frame));
|
||||||
|
|
||||||
callback_->OnEncodedImage(frame_copy, &info, &header);
|
callback_->OnEncodedImage(frame_copy, &info, &header);
|
||||||
|
|||||||
@ -51,14 +51,7 @@ class VideoEncoderWrapper : public VideoEncoder {
|
|||||||
// Should only be called by JNI.
|
// Should only be called by JNI.
|
||||||
void OnEncodedFrame(JNIEnv* jni,
|
void OnEncodedFrame(JNIEnv* jni,
|
||||||
const JavaRef<jobject>& j_caller,
|
const JavaRef<jobject>& j_caller,
|
||||||
const JavaRef<jobject>& j_buffer,
|
const JavaRef<jobject>& j_encoded_image);
|
||||||
jint encoded_width,
|
|
||||||
jint encoded_height,
|
|
||||||
jlong capture_time_ms,
|
|
||||||
jint frame_type,
|
|
||||||
jint rotation,
|
|
||||||
jboolean complete_frame,
|
|
||||||
const JavaRef<jobject>& j_qp);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct FrameExtraInfo {
|
struct FrameExtraInfo {
|
||||||
|
|||||||
Reference in New Issue
Block a user