Android: Fix leaking software video codec instances.

Previously, wrapped native codec instances would leak the native object
if it was never used. This change fixes it by changing getNative method
to createNative.

Also fixes "Video codec hardware acceleration" setting in AppRTCMobile.

Bug: webrtc:7925
Change-Id: I53f6dc1dd5e37dea8d14278423122dede17719c5
Reviewed-on: https://webrtc-review.googlesource.com/24881
Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
Commit-Queue: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20859}
This commit is contained in:
Sami Kalliomäki
2017-11-23 14:42:21 +01:00
committed by Commit Bot
parent 2a9dbe6e7e
commit aea1d1ad3f
12 changed files with 57 additions and 58 deletions

View File

@ -49,9 +49,13 @@ import org.webrtc.RtpReceiver;
import org.webrtc.RtpSender;
import org.webrtc.SdpObserver;
import org.webrtc.SessionDescription;
import org.webrtc.SoftwareVideoDecoderFactory;
import org.webrtc.SoftwareVideoEncoderFactory;
import org.webrtc.StatsObserver;
import org.webrtc.StatsReport;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoDecoderFactory;
import org.webrtc.VideoEncoderFactory;
import org.webrtc.VideoRenderer;
import org.webrtc.VideoSink;
import org.webrtc.VideoSource;
@ -520,10 +524,19 @@ public class PeerConnectionClient {
}
final boolean enableH264HighProfile =
VIDEO_CODEC_H264_HIGH.equals(peerConnectionParameters.videoCodec);
factory = new PeerConnectionFactory(options,
new DefaultVideoEncoderFactory(rootEglBase.getEglBaseContext(),
true /* enableIntelVp8Encoder */, enableH264HighProfile),
new DefaultVideoDecoderFactory(rootEglBase.getEglBaseContext()));
final VideoEncoderFactory encoderFactory;
final VideoDecoderFactory decoderFactory;
if (peerConnectionParameters.videoCodecHwAcceleration) {
encoderFactory = new DefaultVideoEncoderFactory(
rootEglBase.getEglBaseContext(), true /* enableIntelVp8Encoder */, enableH264HighProfile);
decoderFactory = new DefaultVideoDecoderFactory(rootEglBase.getEglBaseContext());
} else {
encoderFactory = new SoftwareVideoEncoderFactory();
decoderFactory = new SoftwareVideoDecoderFactory();
}
factory = new PeerConnectionFactory(options, encoderFactory, decoderFactory);
Log.d(TAG, "Peer connection factory created.");
}

View File

@ -14,8 +14,17 @@ package org.webrtc;
* A combined video decoder that falls back on a secondary decoder if the primary decoder fails.
*/
public class VideoDecoderFallback extends WrappedNativeVideoDecoder {
private final VideoDecoder fallback;
private final VideoDecoder primary;
public VideoDecoderFallback(VideoDecoder fallback, VideoDecoder primary) {
super(createNativeDecoder(fallback, primary));
this.fallback = fallback;
this.primary = primary;
}
@Override
long createNativeDecoder() {
return createNativeDecoder(fallback, primary);
}
private static native long createNativeDecoder(VideoDecoder fallback, VideoDecoder primary);

View File

@ -14,8 +14,17 @@ package org.webrtc;
* A combined video encoder that falls back on a secondary encoder if the primary encoder fails.
*/
public class VideoEncoderFallback extends WrappedNativeVideoEncoder {
private final VideoEncoder fallback;
private final VideoEncoder primary;
public VideoEncoderFallback(VideoEncoder fallback, VideoEncoder primary) {
super(createNativeEncoder(fallback, primary));
this.fallback = fallback;
this.primary = primary;
}
@Override
long createNativeEncoder() {
return createNativeEncoder(fallback, primary);
}
private static native long createNativeEncoder(VideoEncoder fallback, VideoEncoder primary);

View File

@ -11,9 +11,5 @@
package org.webrtc;
class VP8Decoder extends WrappedNativeVideoDecoder {
VP8Decoder() {
super(createNativeDecoder());
}
private static native long createNativeDecoder();
@Override native long createNativeDecoder();
}

View File

@ -11,9 +11,5 @@
package org.webrtc;
class VP8Encoder extends WrappedNativeVideoEncoder {
VP8Encoder() {
super(createNativeEncoder());
}
private static native long createNativeEncoder();
@Override native long createNativeEncoder();
}

View File

@ -11,11 +11,7 @@
package org.webrtc;
class VP9Decoder extends WrappedNativeVideoDecoder {
VP9Decoder() {
super(createNativeDecoder());
}
@Override native long createNativeDecoder();
static native boolean isSupported();
private static native long createNativeDecoder();
}

View File

@ -11,11 +11,7 @@
package org.webrtc;
class VP9Encoder extends WrappedNativeVideoEncoder {
VP9Encoder() {
super(createNativeEncoder());
}
@Override native long createNativeEncoder();
static native boolean isSupported();
private static native long createNativeEncoder();
}

View File

@ -13,17 +13,8 @@ package org.webrtc;
/**
* Wraps a native webrtc::VideoDecoder.
*/
class WrappedNativeVideoDecoder implements VideoDecoder {
private final long nativeDecoder;
WrappedNativeVideoDecoder(long nativeDecoder) {
this.nativeDecoder = nativeDecoder;
}
@CalledByNative
public long getNativeDecoder() {
return this.nativeDecoder;
}
abstract class WrappedNativeVideoDecoder implements VideoDecoder {
@CalledByNative abstract long createNativeDecoder();
@Override
public VideoCodecStatus initDecode(Settings settings, Callback decodeCallback) {

View File

@ -13,17 +13,8 @@ package org.webrtc;
/**
* Wraps a native webrtc::VideoEncoder.
*/
class WrappedNativeVideoEncoder implements VideoEncoder {
private final long nativeEncoder;
WrappedNativeVideoEncoder(long nativeEncoder) {
this.nativeEncoder = nativeEncoder;
}
@CalledByNative
public long getNativeEncoder() {
return this.nativeEncoder;
}
abstract class WrappedNativeVideoEncoder implements VideoEncoder {
@CalledByNative abstract long createNativeEncoder();
@Override
public VideoCodecStatus initEncode(Settings settings, Callback encodeCallback) {
@ -59,4 +50,9 @@ class WrappedNativeVideoEncoder implements VideoEncoder {
public String getImplementationName() {
throw new UnsupportedOperationException("Not implemented.");
}
@CalledByNative
static boolean isInstanceOf(VideoEncoder encoder) {
return encoder instanceof WrappedNativeVideoEncoder;
}
}

View File

@ -19,14 +19,14 @@ namespace jni {
JNI_FUNCTION_DECLARATION(jlong,
VP8Encoder_createNativeEncoder,
JNIEnv* jni,
jclass) {
jobject) {
return jlongFromPointer(VP8Encoder::Create().release());
}
JNI_FUNCTION_DECLARATION(jlong,
VP8Decoder_createNativeDecoder,
JNIEnv* jni,
jclass) {
jobject) {
return jlongFromPointer(VP8Decoder::Create().release());
}

View File

@ -19,7 +19,7 @@ namespace jni {
JNI_FUNCTION_DECLARATION(jlong,
VP9Encoder_createNativeEncoder,
JNIEnv* jni,
jclass) {
jobject) {
return jlongFromPointer(VP9Encoder::Create().release());
}
@ -33,7 +33,7 @@ JNI_FUNCTION_DECLARATION(jboolean,
JNI_FUNCTION_DECLARATION(jlong,
VP9Decoder_createNativeDecoder,
JNIEnv* jni,
jclass) {
jobject) {
return jlongFromPointer(VP9Decoder::Create().release());
}

View File

@ -28,7 +28,7 @@ std::unique_ptr<VideoDecoder> JavaToNativeVideoDecoder(JNIEnv* jni,
VideoDecoder* decoder;
if (jni->IsInstanceOf(j_decoder, wrapped_native_decoder_class)) {
jlong native_decoder =
Java_WrappedNativeVideoDecoder_getNativeDecoder(jni, j_decoder);
Java_WrappedNativeVideoDecoder_createNativeDecoder(jni, j_decoder);
decoder = reinterpret_cast<VideoDecoder*>(native_decoder);
} else {
decoder = new VideoDecoderWrapper(jni, j_decoder);
@ -39,13 +39,10 @@ std::unique_ptr<VideoDecoder> JavaToNativeVideoDecoder(JNIEnv* jni,
std::unique_ptr<VideoEncoder> JavaToNativeVideoEncoder(JNIEnv* jni,
jobject j_encoder) {
jclass wrapped_native_encoder_class =
GetClass(jni, "org/webrtc/WrappedNativeVideoEncoder");
VideoEncoder* encoder;
if (jni->IsInstanceOf(j_encoder, wrapped_native_encoder_class)) {
if (Java_WrappedNativeVideoEncoder_isInstanceOf(jni, j_encoder)) {
jlong native_encoder =
Java_WrappedNativeVideoEncoder_getNativeEncoder(jni, j_encoder);
Java_WrappedNativeVideoEncoder_createNativeEncoder(jni, j_encoder);
encoder = reinterpret_cast<VideoEncoder*>(native_encoder);
} else {
encoder = new VideoEncoderWrapper(jni, j_encoder);