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/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',
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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_;
|
||||||
|
|||||||
@ -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 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() {
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user