Fix a bug in video_encoder_wrapper where int array was not freed properly.

JNI_COMMIT doesn't actually free the buffer.

From JNI docs:
0: copy back the content and free the elems buffer
JNI_COMMIT: copy back the content but do not free the elems buffer
JNI_ABORT: free the buffer without copying back the possible changes

Also introduces helper methods to help avoid this problem in the
future.

Bug: webrtc:10132
Change-Id: I769df286d3bd186fdf39ee2363e9002f36454509
Reviewed-on: https://webrtc-review.googlesource.com/c/120600
Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
Commit-Queue: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26529}
This commit is contained in:
Sami Kalliomäki
2019-02-04 13:42:11 +01:00
committed by Commit Bot
parent eee110dea2
commit ee61f9440a
7 changed files with 110 additions and 21 deletions

View File

@ -99,23 +99,19 @@ static rtc::AdapterType AdapterTypeFromNetworkType(NetworkType network_type) {
static rtc::IPAddress JavaToNativeIpAddress(
JNIEnv* jni,
const JavaRef<jobject>& j_ip_address) {
ScopedJavaLocalRef<jbyteArray> j_addresses =
Java_IPAddress_getAddress(jni, j_ip_address);
size_t address_length = jni->GetArrayLength(j_addresses.obj());
jbyte* addr_array = jni->GetByteArrayElements(j_addresses.obj(), nullptr);
CHECK_EXCEPTION(jni) << "Error during JavaToNativeIpAddress";
std::vector<int8_t> address =
JavaToNativeByteArray(jni, Java_IPAddress_getAddress(jni, j_ip_address));
size_t address_length = address.size();
if (address_length == 4) {
// IP4
struct in_addr ip4_addr;
memcpy(&ip4_addr.s_addr, addr_array, 4);
jni->ReleaseByteArrayElements(j_addresses.obj(), addr_array, JNI_ABORT);
memcpy(&ip4_addr.s_addr, address.data(), 4);
return rtc::IPAddress(ip4_addr);
}
// IP6
RTC_CHECK(address_length == 16);
struct in6_addr ip6_addr;
memcpy(ip6_addr.s6_addr, addr_array, address_length);
jni->ReleaseByteArrayElements(j_addresses.obj(), addr_array, JNI_ABORT);
memcpy(ip6_addr.s6_addr, address.data(), address_length);
return rtc::IPAddress(ip6_addr);
}

View File

@ -146,10 +146,9 @@ static jboolean JNI_DataChannel_Send(JNIEnv* jni,
const JavaParamRef<jobject>& j_dc,
const JavaParamRef<jbyteArray>& data,
jboolean binary) {
jbyte* bytes = jni->GetByteArrayElements(data.obj(), nullptr);
bool ret = ExtractNativeDC(jni, j_dc)->Send(DataBuffer(
rtc::CopyOnWriteBuffer(bytes, jni->GetArrayLength(data.obj())), binary));
jni->ReleaseByteArrayElements(data.obj(), bytes, JNI_ABORT);
std::vector<int8_t> buffer = JavaToNativeByteArray(jni, data);
bool ret = ExtractNativeDC(jni, j_dc)->Send(
DataBuffer(rtc::CopyOnWriteBuffer(buffer.data(), buffer.size()), binary));
return ret;
}

View File

@ -421,17 +421,13 @@ ScopedJavaLocalRef<jobject> VideoEncoderWrapper::ToJavaBitrateAllocation(
jni, jni->NewObjectArray(kMaxSpatialLayers, int_array_class_.obj(),
nullptr /* initial */));
for (int spatial_i = 0; spatial_i < kMaxSpatialLayers; ++spatial_i) {
ScopedJavaLocalRef<jintArray> j_array_spatial_layer(
jni, jni->NewIntArray(kMaxTemporalStreams));
jint* array_spatial_layer = jni->GetIntArrayElements(
j_array_spatial_layer.obj(), nullptr /* isCopy */);
std::array<int32_t, kMaxTemporalStreams> spatial_layer;
for (int temporal_i = 0; temporal_i < kMaxTemporalStreams; ++temporal_i) {
array_spatial_layer[temporal_i] =
allocation.GetBitrate(spatial_i, temporal_i);
spatial_layer[temporal_i] = allocation.GetBitrate(spatial_i, temporal_i);
}
jni->ReleaseIntArrayElements(j_array_spatial_layer.obj(),
array_spatial_layer, JNI_COMMIT);
ScopedJavaLocalRef<jintArray> j_array_spatial_layer =
NativeToJavaIntArray(jni, spatial_layer);
jni->SetObjectArrayElement(j_allocation_array.obj(), spatial_i,
j_array_spatial_layer.obj());
}