Replaced eglbase_jni with with holding a EglBase in PeerConnectionFactory.

Review URL: https://codereview.webrtc.org/1695763002

Cr-Commit-Position: refs/heads/master@{#11627}
This commit is contained in:
perkj
2016-02-15 06:28:36 -08:00
committed by Commit bot
parent 8259c2de02
commit 461121c67b
9 changed files with 48 additions and 152 deletions

View File

@ -43,8 +43,6 @@
'java/jni/androidnetworkmonitor_jni.h', 'java/jni/androidnetworkmonitor_jni.h',
'java/jni/androidvideocapturer_jni.cc', 'java/jni/androidvideocapturer_jni.cc',
'java/jni/androidvideocapturer_jni.h', 'java/jni/androidvideocapturer_jni.h',
'java/jni/eglbase_jni.cc',
'java/jni/eglbase_jni.h',
'java/jni/surfacetexturehelper_jni.cc', 'java/jni/surfacetexturehelper_jni.cc',
'java/jni/surfacetexturehelper_jni.h', 'java/jni/surfacetexturehelper_jni.h',
'java/jni/classreferenceholder.cc', 'java/jni/classreferenceholder.cc',

View File

@ -843,7 +843,8 @@ void MediaCodecVideoDecoder::OnMessage(rtc::Message* msg) {
codec_thread_->PostDelayed(kMediaCodecPollMs, this); codec_thread_->PostDelayed(kMediaCodecPollMs, this);
} }
MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory() { MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory()
: egl_context_(nullptr) {
ALOGD << "MediaCodecVideoDecoderFactory ctor"; ALOGD << "MediaCodecVideoDecoderFactory ctor";
JNIEnv* jni = AttachCurrentThreadIfNeeded(); JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(jni); ScopedLocalRefFrame local_ref_frame(jni);
@ -886,13 +887,19 @@ MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory() {
MediaCodecVideoDecoderFactory::~MediaCodecVideoDecoderFactory() { MediaCodecVideoDecoderFactory::~MediaCodecVideoDecoderFactory() {
ALOGD << "MediaCodecVideoDecoderFactory dtor"; ALOGD << "MediaCodecVideoDecoderFactory dtor";
if (egl_context_) {
JNIEnv* jni = AttachCurrentThreadIfNeeded();
jni->DeleteGlobalRef(egl_context_);
}
} }
void MediaCodecVideoDecoderFactory::SetEGLContext( void MediaCodecVideoDecoderFactory::SetEGLContext(
JNIEnv* jni, jobject render_egl_context) { JNIEnv* jni, jobject egl_context) {
ALOGD << "MediaCodecVideoDecoderFactory::SetEGLContext"; ALOGD << "MediaCodecVideoDecoderFactory::SetEGLContext";
if (!egl_.CreateEglBase(jni, render_egl_context)) { RTC_DCHECK(!egl_context_);
ALOGW << "Invalid EGL context - HW surface decoding is disabled."; egl_context_ = jni->NewGlobalRef(egl_context);
if (CheckException(jni)) {
ALOGE << "error calling NewGlobalRef for EGL Context.";
} }
} }
@ -906,7 +913,7 @@ webrtc::VideoDecoder* MediaCodecVideoDecoderFactory::CreateVideoDecoder(
if (codec_type == type) { if (codec_type == type) {
ALOGD << "Create HW video decoder for type " << (int)type; ALOGD << "Create HW video decoder for type " << (int)type;
return new MediaCodecVideoDecoder(AttachCurrentThreadIfNeeded(), type, return new MediaCodecVideoDecoder(AttachCurrentThreadIfNeeded(), type,
egl_.egl_base_context()); egl_context_);
} }
} }
ALOGW << "Can not find HW video decoder for type " << (int)type; ALOGW << "Can not find HW video decoder for type " << (int)type;

View File

@ -11,7 +11,7 @@
#ifndef WEBRTC_API_JAVA_JNI_ANDROIDMEDIADECODER_JNI_H_ #ifndef WEBRTC_API_JAVA_JNI_ANDROIDMEDIADECODER_JNI_H_
#define WEBRTC_API_JAVA_JNI_ANDROIDMEDIADECODER_JNI_H_ #define WEBRTC_API_JAVA_JNI_ANDROIDMEDIADECODER_JNI_H_
#include "webrtc/api/java/jni/eglbase_jni.h" #include "webrtc/api/java/jni/jni_helpers.h"
#include "webrtc/media/engine/webrtcvideodecoderfactory.h" #include "webrtc/media/engine/webrtcvideodecoderfactory.h"
namespace webrtc_jni { namespace webrtc_jni {
@ -32,7 +32,7 @@ class MediaCodecVideoDecoderFactory
void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) override; void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) override;
private: private:
EglBase egl_; jobject egl_context_;
std::vector<webrtc::VideoCodecType> supported_codec_types_; std::vector<webrtc::VideoCodecType> supported_codec_types_;
}; };

View File

@ -1164,7 +1164,8 @@ const char* MediaCodecVideoEncoder::ImplementationName() const {
return "MediaCodec"; return "MediaCodec";
} }
MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory() { MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory()
: egl_context_(nullptr) {
JNIEnv* jni = AttachCurrentThreadIfNeeded(); JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(jni); ScopedLocalRefFrame local_ref_frame(jni);
jclass j_encoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoEncoder"); jclass j_encoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoEncoder");
@ -1203,13 +1204,19 @@ MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory() {
MediaCodecVideoEncoderFactory::~MediaCodecVideoEncoderFactory() { MediaCodecVideoEncoderFactory::~MediaCodecVideoEncoderFactory() {
ALOGD << "MediaCodecVideoEncoderFactory dtor"; ALOGD << "MediaCodecVideoEncoderFactory dtor";
if (egl_context_) {
JNIEnv* jni = AttachCurrentThreadIfNeeded();
jni->DeleteGlobalRef(egl_context_);
}
} }
void MediaCodecVideoEncoderFactory::SetEGLContext( void MediaCodecVideoEncoderFactory::SetEGLContext(
JNIEnv* jni, jobject render_egl_context) { JNIEnv* jni, jobject egl_context) {
ALOGD << "MediaCodecVideoEncoderFactory::SetEGLContext"; ALOGD << "MediaCodecVideoEncoderFactory::SetEGLContext";
if (!egl_base_.CreateEglBase(jni, render_egl_context)) { RTC_DCHECK(!egl_context_);
ALOGW << "Invalid EGL context - HW surface encoding is disabled."; egl_context_ = jni->NewGlobalRef(egl_context);
if (CheckException(jni)) {
ALOGE << "error calling NewGlobalRef for EGL Context.";
} }
} }
@ -1225,7 +1232,7 @@ webrtc::VideoEncoder* MediaCodecVideoEncoderFactory::CreateVideoEncoder(
ALOGD << "Create HW video encoder for type " << (int)type << ALOGD << "Create HW video encoder for type " << (int)type <<
" (" << it->name << ")."; " (" << it->name << ").";
return new MediaCodecVideoEncoder(AttachCurrentThreadIfNeeded(), type, return new MediaCodecVideoEncoder(AttachCurrentThreadIfNeeded(), type,
egl_base_.egl_base_context()); egl_context_);
} }
} }
ALOGW << "Can not find HW video encoder for type " << (int)type; ALOGW << "Can not find HW video encoder for type " << (int)type;

View File

@ -13,7 +13,7 @@
#include <vector> #include <vector>
#include "webrtc/api/java/jni/eglbase_jni.h" #include "webrtc/api/java/jni/jni_helpers.h"
#include "webrtc/media/engine/webrtcvideoencoderfactory.h" #include "webrtc/media/engine/webrtcvideoencoderfactory.h"
namespace webrtc_jni { namespace webrtc_jni {
@ -25,7 +25,7 @@ class MediaCodecVideoEncoderFactory
MediaCodecVideoEncoderFactory(); MediaCodecVideoEncoderFactory();
virtual ~MediaCodecVideoEncoderFactory(); virtual ~MediaCodecVideoEncoderFactory();
void SetEGLContext(JNIEnv* jni, jobject render_egl_context); void SetEGLContext(JNIEnv* jni, jobject egl_context);
// WebRtcVideoEncoderFactory implementation. // WebRtcVideoEncoderFactory implementation.
webrtc::VideoEncoder* CreateVideoEncoder(webrtc::VideoCodecType type) webrtc::VideoEncoder* CreateVideoEncoder(webrtc::VideoCodecType type)
@ -34,7 +34,7 @@ class MediaCodecVideoEncoderFactory
void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override; void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override;
private: private:
EglBase egl_base_; jobject egl_context_;
// Empty if platform support is lacking, const after ctor returns. // Empty if platform support is lacking, const after ctor returns.
std::vector<VideoCodec> supported_codecs_; std::vector<VideoCodec> supported_codecs_;

View File

@ -1,72 +0,0 @@
/*
* Copyright 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/api/java/jni/eglbase_jni.h"
#include "webrtc/api/java/jni/androidmediacodeccommon.h"
#include "webrtc/api/java/jni/classreferenceholder.h"
#include "webrtc/api/java/jni/jni_helpers.h"
namespace webrtc_jni {
EglBase::EglBase() {
}
EglBase::~EglBase() {
if (egl_base_) {
JNIEnv* jni = AttachCurrentThreadIfNeeded();
jni->DeleteGlobalRef(egl_base_context_);
egl_base_context_ = nullptr;
jni->CallVoidMethod(egl_base_,
GetMethodID(jni,
FindClass(jni, "org/webrtc/EglBase"),
"release", "()V"));
jni->DeleteGlobalRef(egl_base_);
}
}
bool EglBase::CreateEglBase(JNIEnv* jni, jobject egl_context) {
if (egl_base_) {
jni->DeleteGlobalRef(egl_base_context_);
egl_base_context_ = nullptr;
jni->CallVoidMethod(egl_base_,
GetMethodID(jni,
FindClass(jni, "org/webrtc/EglBase"),
"release", "()V"));
jni->DeleteGlobalRef(egl_base_);
egl_base_ = nullptr;
}
if (IsNull(jni, egl_context))
return false;
jobject egl_base = jni->CallStaticObjectMethod(
FindClass(jni, "org/webrtc/EglBase"),
GetStaticMethodID(jni,
FindClass(jni, "org/webrtc/EglBase"),
"create",
"(Lorg/webrtc/EglBase$Context;)Lorg/webrtc/EglBase;"),
egl_context);
if (CheckException(jni))
return false;
egl_base_ = jni->NewGlobalRef(egl_base);
egl_base_context_ = jni->NewGlobalRef(
jni->CallObjectMethod(
egl_base_,
GetMethodID(jni,
FindClass(jni, "org/webrtc/EglBase"),
"getEglBaseContext",
"()Lorg/webrtc/EglBase$Context;")));
RTC_CHECK(egl_base_context_);
return true;
}
} // namespace webrtc_jni

View File

@ -1,42 +0,0 @@
/*
* Copyright 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_API_JAVA_JNI_EGLBASE_JNI_H_
#define WEBRTC_API_JAVA_JNI_EGLBASE_JNI_H_
#include <jni.h>
#include "webrtc/base/constructormagic.h"
namespace webrtc_jni {
// Helper class used for creating a Java instance of org/webrtc/EglBase.
class EglBase {
public:
EglBase();
~EglBase();
// Creates an new java EglBase instance. |egl_base_context| must be a valid
// EglBase$Context.
// Returns false if |egl_base_context| is a null Java object or if an
// exception occur in Java.
bool CreateEglBase(JNIEnv* jni, jobject egl_base_context);
jobject egl_base_context() const { return egl_base_context_; }
private:
jobject egl_base_ = nullptr; // instance of org/webrtc/EglBase
jobject egl_base_context_ = nullptr; // instance of EglBase$Context
RTC_DISALLOW_COPY_AND_ASSIGN(EglBase);
};
} // namespace webrtc_jni
#endif // WEBRTC_API_JAVA_JNI_EGLBASE_JNI_H_

View File

@ -26,6 +26,8 @@ public class PeerConnectionFactory {
private final long nativeFactory; private final long nativeFactory;
private static Thread workerThread; private static Thread workerThread;
private static Thread signalingThread; private static Thread signalingThread;
private EglBase localEglbase;
private EglBase remoteEglbase;
public static class Options { public static class Options {
// Keep in sync with webrtc/base/network.h! // Keep in sync with webrtc/base/network.h!
@ -163,20 +165,29 @@ public class PeerConnectionFactory {
/** Set the EGL context used by HW Video encoding and decoding. /** Set the EGL context used by HW Video encoding and decoding.
* *
* @param localEGLContext An instance of EglBase.Context. * @param localEglContext Must be the same as used by VideoCapturerAndroid and any local video
* Must be the same as used by VideoCapturerAndroid and any local * renderer.
* video renderer. * @param remoteEglContext Must be the same as used by any remote video renderer.
* @param remoteEGLContext An instance of EglBase.Context.
* Must be the same as used by any remote video renderer.
*/ */
public void setVideoHwAccelerationOptions(Object localEGLContext, Object remoteEGLContext) { public void setVideoHwAccelerationOptions(EglBase.Context localEglContext,
nativeSetVideoHwAccelerationOptions(nativeFactory, localEGLContext, remoteEGLContext); EglBase.Context remoteEglContext) {
if (localEglbase != null || remoteEglbase != null) {
throw new IllegalStateException("Egl context already set.");
}
localEglbase = EglBase.create(localEglContext);
remoteEglbase = EglBase.create(remoteEglContext);
nativeSetVideoHwAccelerationOptions(nativeFactory, localEglbase.getEglBaseContext(),
remoteEglbase.getEglBaseContext());
} }
public void dispose() { public void dispose() {
nativeFreeFactory(nativeFactory); nativeFreeFactory(nativeFactory);
signalingThread = null; signalingThread = null;
workerThread = null; workerThread = null;
if (localEglbase != null)
localEglbase.release();
if (remoteEglbase != null)
remoteEglbase.release();
} }
public void threadsCallbacks() { public void threadsCallbacks() {

View File

@ -400,19 +400,6 @@ public class PeerConnectionClientTest extends InstrumentationTestCase
doLoopbackTest(createParametersForVideoCall(VIDEO_CODEC_VP8, true), true); doLoopbackTest(createParametersForVideoCall(VIDEO_CODEC_VP8, true), true);
} }
// Test that a call can be setup even if a released EGL context is used during setup.
// The HW encoder and decoder will fallback to encode and decode from byte buffers.
public void testLoopbackEglContextReleasedBeforeSetup() throws InterruptedException {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
Log.i(TAG, "Decode to textures is not supported, requires SDK version 19.");
return;
}
eglBase.release();
doLoopbackTest(createParametersForVideoCall(VIDEO_CODEC_VP8, false), true);
eglBase = null;
}
// Test that a call can be setup even if the EGL context used during initialization is // Test that a call can be setup even if the EGL context used during initialization is
// released before the Video codecs are created. The HW encoder and decoder is setup to use // released before the Video codecs are created. The HW encoder and decoder is setup to use
// textures. // textures.
@ -423,7 +410,7 @@ public class PeerConnectionClientTest extends InstrumentationTestCase
} }
loopback = true; loopback = true;
PeerConnectionParameters parameters = createParametersForVideoCall(VIDEO_CODEC_VP8, false); PeerConnectionParameters parameters = createParametersForVideoCall(VIDEO_CODEC_VP8, true);
MockRenderer localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME); MockRenderer localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
MockRenderer remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE_RENDERER_NAME); MockRenderer remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE_RENDERER_NAME);
pcClient = createPeerConnectionClient( pcClient = createPeerConnectionClient(