Android: Use scoped java refs
We currently use raw jobject in our code mixed with sporadic ScopedLocalRefFrame. This CL moves every jobject into a scoped object, either local, global, or a parameter. Also, this CL uses the JNI generation script to generate declaration stubs for the Java->C++ functions so that it no longer becomes possible to mistype them without getting compilation errors. TBR=brandt@webrtc.org Bug: webrtc:8278,webrtc:6969 Change-Id: Ic7bac74a89c11180177d65041086d7db1cdfb516 Reviewed-on: https://webrtc-review.googlesource.com/34655 Commit-Queue: Magnus Jedvert <magjed@webrtc.org> Reviewed-by: Sami Kalliomäki <sakal@webrtc.org> Cr-Commit-Position: refs/heads/master@{#21387}
This commit is contained in:

committed by
Commit Bot

parent
ec22e3f503
commit
84d8ae5df7
@ -32,9 +32,9 @@ namespace jni {
|
||||
|
||||
static const int kMaxJavaEncoderResets = 3;
|
||||
|
||||
VideoEncoderWrapper::VideoEncoderWrapper(JNIEnv* jni, jobject j_encoder)
|
||||
: encoder_(jni, j_encoder),
|
||||
int_array_class_(jni, jni->FindClass("[I")) {
|
||||
VideoEncoderWrapper::VideoEncoderWrapper(JNIEnv* jni,
|
||||
const JavaRef<jobject>& j_encoder)
|
||||
: encoder_(jni, j_encoder), int_array_class_(GetClass(jni, "[I")) {
|
||||
implementation_name_ = GetImplementationName(jni);
|
||||
|
||||
initialized_ = false;
|
||||
@ -49,7 +49,6 @@ int32_t VideoEncoderWrapper::InitEncode(const VideoCodec* codec_settings,
|
||||
int32_t number_of_cores,
|
||||
size_t max_payload_size) {
|
||||
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(jni);
|
||||
|
||||
number_of_cores_ = number_of_cores;
|
||||
codec_settings_ = *codec_settings;
|
||||
@ -72,16 +71,17 @@ int32_t VideoEncoderWrapper::InitEncodeInternal(JNIEnv* jni) {
|
||||
automatic_resize_on = true;
|
||||
}
|
||||
|
||||
jobject settings = Java_Settings_Constructor(
|
||||
ScopedJavaLocalRef<jobject> settings = Java_Settings_Constructor(
|
||||
jni, number_of_cores_, codec_settings_.width, codec_settings_.height,
|
||||
codec_settings_.startBitrate, codec_settings_.maxFramerate,
|
||||
automatic_resize_on);
|
||||
|
||||
jobject callback = Java_VideoEncoderWrapper_createEncoderCallback(
|
||||
jni, jlongFromPointer(this));
|
||||
ScopedJavaLocalRef<jobject> callback =
|
||||
Java_VideoEncoderWrapper_createEncoderCallback(jni,
|
||||
jlongFromPointer(this));
|
||||
|
||||
jobject ret =
|
||||
Java_VideoEncoder_initEncode(jni, *encoder_, settings, callback);
|
||||
ScopedJavaLocalRef<jobject> ret =
|
||||
Java_VideoEncoder_initEncode(jni, encoder_, settings, callback);
|
||||
|
||||
if (JavaToNativeVideoCodecStatus(jni, ret) == WEBRTC_VIDEO_CODEC_OK) {
|
||||
initialized_ = true;
|
||||
@ -98,8 +98,7 @@ int32_t VideoEncoderWrapper::RegisterEncodeCompleteCallback(
|
||||
|
||||
int32_t VideoEncoderWrapper::Release() {
|
||||
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(jni);
|
||||
jobject ret = Java_VideoEncoder_release(jni, *encoder_);
|
||||
ScopedJavaLocalRef<jobject> ret = Java_VideoEncoder_release(jni, encoder_);
|
||||
frame_extra_infos_.clear();
|
||||
initialized_ = false;
|
||||
encoder_queue_ = nullptr;
|
||||
@ -116,28 +115,28 @@ int32_t VideoEncoderWrapper::Encode(
|
||||
}
|
||||
|
||||
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(jni);
|
||||
|
||||
// Construct encode info.
|
||||
jobjectArray j_frame_types = NativeToJavaFrameTypeArray(jni, *frame_types);
|
||||
jobject encode_info = Java_EncodeInfo_Constructor(jni, j_frame_types);
|
||||
ScopedJavaLocalRef<jobjectArray> j_frame_types =
|
||||
NativeToJavaFrameTypeArray(jni, *frame_types);
|
||||
ScopedJavaLocalRef<jobject> encode_info =
|
||||
Java_EncodeInfo_Constructor(jni, j_frame_types);
|
||||
|
||||
FrameExtraInfo info;
|
||||
info.capture_time_ns = frame.timestamp_us() * rtc::kNumNanosecsPerMicrosec;
|
||||
info.timestamp_rtp = frame.timestamp();
|
||||
frame_extra_infos_.push_back(info);
|
||||
|
||||
jobject ret = Java_VideoEncoder_encode(
|
||||
jni, *encoder_, NativeToJavaFrame(jni, frame), encode_info);
|
||||
ScopedJavaLocalRef<jobject> ret = Java_VideoEncoder_encode(
|
||||
jni, encoder_, NativeToJavaFrame(jni, frame), encode_info);
|
||||
return HandleReturnCode(jni, ret);
|
||||
}
|
||||
|
||||
int32_t VideoEncoderWrapper::SetChannelParameters(uint32_t packet_loss,
|
||||
int64_t rtt) {
|
||||
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(jni);
|
||||
jobject ret = Java_VideoEncoder_setChannelParameters(
|
||||
jni, *encoder_, (jshort)packet_loss, (jlong)rtt);
|
||||
ScopedJavaLocalRef<jobject> ret = Java_VideoEncoder_setChannelParameters(
|
||||
jni, encoder_, (jshort)packet_loss, (jlong)rtt);
|
||||
return HandleReturnCode(jni, ret);
|
||||
}
|
||||
|
||||
@ -145,20 +144,19 @@ int32_t VideoEncoderWrapper::SetRateAllocation(
|
||||
const BitrateAllocation& allocation,
|
||||
uint32_t framerate) {
|
||||
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(jni);
|
||||
|
||||
jobject j_bitrate_allocation = ToJavaBitrateAllocation(jni, allocation);
|
||||
jobject ret = Java_VideoEncoder_setRateAllocation(
|
||||
jni, *encoder_, j_bitrate_allocation, (jint)framerate);
|
||||
ScopedJavaLocalRef<jobject> j_bitrate_allocation =
|
||||
ToJavaBitrateAllocation(jni, allocation);
|
||||
ScopedJavaLocalRef<jobject> ret = Java_VideoEncoder_setRateAllocation(
|
||||
jni, encoder_, j_bitrate_allocation, (jint)framerate);
|
||||
return HandleReturnCode(jni, ret);
|
||||
}
|
||||
|
||||
VideoEncoderWrapper::ScalingSettings VideoEncoderWrapper::GetScalingSettings()
|
||||
const {
|
||||
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(jni);
|
||||
jobject j_scaling_settings =
|
||||
Java_VideoEncoder_getScalingSettings(jni, *encoder_);
|
||||
ScopedJavaLocalRef<jobject> j_scaling_settings =
|
||||
Java_VideoEncoder_getScalingSettings(jni, encoder_);
|
||||
bool isOn =
|
||||
Java_VideoEncoderWrapper_getScalingSettingsOn(jni, j_scaling_settings);
|
||||
|
||||
@ -178,18 +176,18 @@ const char* VideoEncoderWrapper::ImplementationName() const {
|
||||
}
|
||||
|
||||
void VideoEncoderWrapper::OnEncodedFrame(JNIEnv* jni,
|
||||
jobject j_caller,
|
||||
jobject j_buffer,
|
||||
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,
|
||||
jobject j_qp) {
|
||||
const JavaRef<jobject>& j_qp) {
|
||||
const uint8_t* buffer =
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer));
|
||||
const size_t buffer_size = jni->GetDirectBufferCapacity(j_buffer);
|
||||
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_buffer.obj()));
|
||||
const size_t buffer_size = jni->GetDirectBufferCapacity(j_buffer.obj());
|
||||
|
||||
std::vector<uint8_t> buffer_copy(buffer_size);
|
||||
memcpy(buffer_copy.data(), buffer, buffer_size);
|
||||
@ -236,7 +234,8 @@ void VideoEncoderWrapper::OnEncodedFrame(JNIEnv* jni,
|
||||
});
|
||||
}
|
||||
|
||||
int32_t VideoEncoderWrapper::HandleReturnCode(JNIEnv* jni, jobject code) {
|
||||
int32_t VideoEncoderWrapper::HandleReturnCode(JNIEnv* jni,
|
||||
const JavaRef<jobject>& code) {
|
||||
int32_t value = JavaToNativeVideoCodecStatus(jni, code);
|
||||
if (value < 0) { // Any errors are represented by negative values.
|
||||
// Try resetting the codec.
|
||||
@ -358,31 +357,33 @@ CodecSpecificInfo VideoEncoderWrapper::ParseCodecSpecificInfo(
|
||||
return info;
|
||||
}
|
||||
|
||||
jobject VideoEncoderWrapper::ToJavaBitrateAllocation(
|
||||
ScopedJavaLocalRef<jobject> VideoEncoderWrapper::ToJavaBitrateAllocation(
|
||||
JNIEnv* jni,
|
||||
const BitrateAllocation& allocation) {
|
||||
jobjectArray j_allocation_array = jni->NewObjectArray(
|
||||
kMaxSpatialLayers, *int_array_class_, nullptr /* initial */);
|
||||
ScopedJavaLocalRef<jobjectArray> j_allocation_array(
|
||||
jni, jni->NewObjectArray(kMaxSpatialLayers, int_array_class_.obj(),
|
||||
nullptr /* initial */));
|
||||
for (int spatial_i = 0; spatial_i < kMaxSpatialLayers; ++spatial_i) {
|
||||
jintArray j_array_spatial_layer = jni->NewIntArray(kMaxTemporalStreams);
|
||||
jint* array_spatial_layer =
|
||||
jni->GetIntArrayElements(j_array_spatial_layer, nullptr /* isCopy */);
|
||||
ScopedJavaLocalRef<jintArray> j_array_spatial_layer(
|
||||
jni, jni->NewIntArray(kMaxTemporalStreams));
|
||||
jint* array_spatial_layer = jni->GetIntArrayElements(
|
||||
j_array_spatial_layer.obj(), nullptr /* isCopy */);
|
||||
for (int temporal_i = 0; temporal_i < kMaxTemporalStreams; ++temporal_i) {
|
||||
array_spatial_layer[temporal_i] =
|
||||
allocation.GetBitrate(spatial_i, temporal_i);
|
||||
}
|
||||
jni->ReleaseIntArrayElements(j_array_spatial_layer, array_spatial_layer,
|
||||
JNI_COMMIT);
|
||||
jni->ReleaseIntArrayElements(j_array_spatial_layer.obj(),
|
||||
array_spatial_layer, JNI_COMMIT);
|
||||
|
||||
jni->SetObjectArrayElement(j_allocation_array, spatial_i,
|
||||
j_array_spatial_layer);
|
||||
jni->SetObjectArrayElement(j_allocation_array.obj(), spatial_i,
|
||||
j_array_spatial_layer.obj());
|
||||
}
|
||||
return Java_BitrateAllocation_Constructor(jni, j_allocation_array);
|
||||
}
|
||||
|
||||
std::string VideoEncoderWrapper::GetImplementationName(JNIEnv* jni) const {
|
||||
jstring jname = Java_VideoEncoder_getImplementationName(jni, *encoder_);
|
||||
return JavaToStdString(jni, jname);
|
||||
return JavaToStdString(
|
||||
jni, Java_VideoEncoder_getImplementationName(jni, encoder_));
|
||||
}
|
||||
|
||||
} // namespace jni
|
||||
|
Reference in New Issue
Block a user