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:
@ -43,8 +43,6 @@
|
||||
'java/jni/androidnetworkmonitor_jni.h',
|
||||
'java/jni/androidvideocapturer_jni.cc',
|
||||
'java/jni/androidvideocapturer_jni.h',
|
||||
'java/jni/eglbase_jni.cc',
|
||||
'java/jni/eglbase_jni.h',
|
||||
'java/jni/surfacetexturehelper_jni.cc',
|
||||
'java/jni/surfacetexturehelper_jni.h',
|
||||
'java/jni/classreferenceholder.cc',
|
||||
|
||||
@ -843,7 +843,8 @@ void MediaCodecVideoDecoder::OnMessage(rtc::Message* msg) {
|
||||
codec_thread_->PostDelayed(kMediaCodecPollMs, this);
|
||||
}
|
||||
|
||||
MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory() {
|
||||
MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory()
|
||||
: egl_context_(nullptr) {
|
||||
ALOGD << "MediaCodecVideoDecoderFactory ctor";
|
||||
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(jni);
|
||||
@ -886,13 +887,19 @@ MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory() {
|
||||
|
||||
MediaCodecVideoDecoderFactory::~MediaCodecVideoDecoderFactory() {
|
||||
ALOGD << "MediaCodecVideoDecoderFactory dtor";
|
||||
if (egl_context_) {
|
||||
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||
jni->DeleteGlobalRef(egl_context_);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaCodecVideoDecoderFactory::SetEGLContext(
|
||||
JNIEnv* jni, jobject render_egl_context) {
|
||||
JNIEnv* jni, jobject egl_context) {
|
||||
ALOGD << "MediaCodecVideoDecoderFactory::SetEGLContext";
|
||||
if (!egl_.CreateEglBase(jni, render_egl_context)) {
|
||||
ALOGW << "Invalid EGL context - HW surface decoding is disabled.";
|
||||
RTC_DCHECK(!egl_context_);
|
||||
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) {
|
||||
ALOGD << "Create HW video decoder for type " << (int)type;
|
||||
return new MediaCodecVideoDecoder(AttachCurrentThreadIfNeeded(), type,
|
||||
egl_.egl_base_context());
|
||||
egl_context_);
|
||||
}
|
||||
}
|
||||
ALOGW << "Can not find HW video decoder for type " << (int)type;
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
#ifndef 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"
|
||||
|
||||
namespace webrtc_jni {
|
||||
@ -32,7 +32,7 @@ class MediaCodecVideoDecoderFactory
|
||||
void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) override;
|
||||
|
||||
private:
|
||||
EglBase egl_;
|
||||
jobject egl_context_;
|
||||
std::vector<webrtc::VideoCodecType> supported_codec_types_;
|
||||
};
|
||||
|
||||
|
||||
@ -1164,7 +1164,8 @@ const char* MediaCodecVideoEncoder::ImplementationName() const {
|
||||
return "MediaCodec";
|
||||
}
|
||||
|
||||
MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory() {
|
||||
MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory()
|
||||
: egl_context_(nullptr) {
|
||||
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||
ScopedLocalRefFrame local_ref_frame(jni);
|
||||
jclass j_encoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoEncoder");
|
||||
@ -1203,13 +1204,19 @@ MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory() {
|
||||
|
||||
MediaCodecVideoEncoderFactory::~MediaCodecVideoEncoderFactory() {
|
||||
ALOGD << "MediaCodecVideoEncoderFactory dtor";
|
||||
if (egl_context_) {
|
||||
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||
jni->DeleteGlobalRef(egl_context_);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaCodecVideoEncoderFactory::SetEGLContext(
|
||||
JNIEnv* jni, jobject render_egl_context) {
|
||||
JNIEnv* jni, jobject egl_context) {
|
||||
ALOGD << "MediaCodecVideoEncoderFactory::SetEGLContext";
|
||||
if (!egl_base_.CreateEglBase(jni, render_egl_context)) {
|
||||
ALOGW << "Invalid EGL context - HW surface encoding is disabled.";
|
||||
RTC_DCHECK(!egl_context_);
|
||||
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 <<
|
||||
" (" << it->name << ").";
|
||||
return new MediaCodecVideoEncoder(AttachCurrentThreadIfNeeded(), type,
|
||||
egl_base_.egl_base_context());
|
||||
egl_context_);
|
||||
}
|
||||
}
|
||||
ALOGW << "Can not find HW video encoder for type " << (int)type;
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/api/java/jni/eglbase_jni.h"
|
||||
#include "webrtc/api/java/jni/jni_helpers.h"
|
||||
#include "webrtc/media/engine/webrtcvideoencoderfactory.h"
|
||||
|
||||
namespace webrtc_jni {
|
||||
@ -25,7 +25,7 @@ class MediaCodecVideoEncoderFactory
|
||||
MediaCodecVideoEncoderFactory();
|
||||
virtual ~MediaCodecVideoEncoderFactory();
|
||||
|
||||
void SetEGLContext(JNIEnv* jni, jobject render_egl_context);
|
||||
void SetEGLContext(JNIEnv* jni, jobject egl_context);
|
||||
|
||||
// WebRtcVideoEncoderFactory implementation.
|
||||
webrtc::VideoEncoder* CreateVideoEncoder(webrtc::VideoCodecType type)
|
||||
@ -34,7 +34,7 @@ class MediaCodecVideoEncoderFactory
|
||||
void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override;
|
||||
|
||||
private:
|
||||
EglBase egl_base_;
|
||||
jobject egl_context_;
|
||||
|
||||
// Empty if platform support is lacking, const after ctor returns.
|
||||
std::vector<VideoCodec> supported_codecs_;
|
||||
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -26,6 +26,8 @@ public class PeerConnectionFactory {
|
||||
private final long nativeFactory;
|
||||
private static Thread workerThread;
|
||||
private static Thread signalingThread;
|
||||
private EglBase localEglbase;
|
||||
private EglBase remoteEglbase;
|
||||
|
||||
public static class Options {
|
||||
// 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.
|
||||
*
|
||||
* @param localEGLContext An instance of EglBase.Context.
|
||||
* Must be the same as used by VideoCapturerAndroid and any local
|
||||
* video renderer.
|
||||
* @param remoteEGLContext An instance of EglBase.Context.
|
||||
* Must be the same as used by any remote video renderer.
|
||||
* @param localEglContext Must be the same as used by VideoCapturerAndroid and any local video
|
||||
* renderer.
|
||||
* @param remoteEglContext Must be the same as used by any remote video renderer.
|
||||
*/
|
||||
public void setVideoHwAccelerationOptions(Object localEGLContext, Object remoteEGLContext) {
|
||||
nativeSetVideoHwAccelerationOptions(nativeFactory, localEGLContext, remoteEGLContext);
|
||||
public void setVideoHwAccelerationOptions(EglBase.Context localEglContext,
|
||||
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() {
|
||||
nativeFreeFactory(nativeFactory);
|
||||
signalingThread = null;
|
||||
workerThread = null;
|
||||
if (localEglbase != null)
|
||||
localEglbase.release();
|
||||
if (remoteEglbase != null)
|
||||
remoteEglbase.release();
|
||||
}
|
||||
|
||||
public void threadsCallbacks() {
|
||||
|
||||
@ -400,19 +400,6 @@ public class PeerConnectionClientTest extends InstrumentationTestCase
|
||||
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
|
||||
// released before the Video codecs are created. The HW encoder and decoder is setup to use
|
||||
// textures.
|
||||
@ -423,7 +410,7 @@ public class PeerConnectionClientTest extends InstrumentationTestCase
|
||||
}
|
||||
|
||||
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 remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE_RENDERER_NAME);
|
||||
pcClient = createPeerConnectionClient(
|
||||
|
||||
Reference in New Issue
Block a user