diff --git a/sdk/android/api/org/webrtc/EncodedImage.java b/sdk/android/api/org/webrtc/EncodedImage.java index 84c72b1db5..f8de3d24c2 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 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; } diff --git a/sdk/android/src/java/org/webrtc/VideoEncoderWrapper.java b/sdk/android/src/java/org/webrtc/VideoEncoderWrapper.java index e167b89616..03676b160a 100644 --- a/sdk/android/src/java/org/webrtc/VideoEncoderWrapper.java +++ b/sdk/android/src/java/org/webrtc/VideoEncoderWrapper.java @@ -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); } diff --git a/sdk/android/src/jni/encoded_image.cc b/sdk/android/src/jni/encoded_image.cc index b288d36c0c..328aa7c256 100644 --- a/sdk/android/src/jni/encoded_image.cc +++ b/sdk/android/src/jni/encoded_image.cc @@ -49,5 +49,40 @@ ScopedJavaLocalRef NativeToJavaFrameTypeArray( &NativeToJavaFrameType); } +EncodedImage JavaToNativeEncodedImage(JNIEnv* env, + const JavaRef& j_encoded_image) { + const JavaRef& j_buffer = + Java_EncodedImage_getBuffer(env, j_encoded_image); + const uint8_t* buffer = + static_cast(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& 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 2078830588..fc6d06243c 100644 --- a/sdk/android/src/jni/encoded_image.h +++ b/sdk/android/src/jni/encoded_image.h @@ -32,6 +32,13 @@ ScopedJavaLocalRef NativeToJavaFrameTypeArray( JNIEnv* env, const std::vector& frame_types); +EncodedImage JavaToNativeEncodedImage(JNIEnv* env, + const JavaRef& j_encoded_image); + +int64_t GetJavaEncodedImageCaptureTimeNs( + JNIEnv* jni, + const JavaRef& 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 e051b77e07..ebf6aadf90 100644 --- a/sdk/android/src/jni/video_encoder_wrapper.cc +++ b/sdk/android/src/jni/video_encoder_wrapper.cc @@ -214,38 +214,18 @@ VideoEncoderWrapper::GetScalingSettingsInternal(JNIEnv* jni) const { } } -void VideoEncoderWrapper::OnEncodedFrame(JNIEnv* jni, - const JavaRef& j_caller, - const JavaRef& j_buffer, - jint encoded_width, - jint encoded_height, - jlong capture_time_ns, - jint frame_type, - jint rotation, - jboolean complete_frame, - const JavaRef& j_qp) { - const uint8_t* buffer = - static_cast(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 qp = JavaToNativeOptionalInt(jni, j_qp); - - frame._frameType = (VideoFrameType)frame_type; +void VideoEncoderWrapper::OnEncodedFrame( + JNIEnv* jni, + const JavaRef& j_caller, + const JavaRef& 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); diff --git a/sdk/android/src/jni/video_encoder_wrapper.h b/sdk/android/src/jni/video_encoder_wrapper.h index 43d1f6fff3..685c6daab9 100644 --- a/sdk/android/src/jni/video_encoder_wrapper.h +++ b/sdk/android/src/jni/video_encoder_wrapper.h @@ -51,14 +51,7 @@ class VideoEncoderWrapper : public VideoEncoder { // Should only be called by JNI. void OnEncodedFrame(JNIEnv* jni, const JavaRef& j_caller, - const JavaRef& j_buffer, - jint encoded_width, - jint encoded_height, - jlong capture_time_ms, - jint frame_type, - jint rotation, - jboolean complete_frame, - const JavaRef& j_qp); + const JavaRef& j_encoded_image); private: struct FrameExtraInfo {