Replaced eglbase_jni with with holding a EglBase in PeerConnectionFactory.

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

Cr-Commit-Position: refs/heads/master@{#11627}
diff --git a/webrtc/api/api.gyp b/webrtc/api/api.gyp
index 34a75f6..061d9c1 100644
--- a/webrtc/api/api.gyp
+++ b/webrtc/api/api.gyp
@@ -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',
diff --git a/webrtc/api/java/jni/androidmediadecoder_jni.cc b/webrtc/api/java/jni/androidmediadecoder_jni.cc
index 93f253d..f7966cc 100644
--- a/webrtc/api/java/jni/androidmediadecoder_jni.cc
+++ b/webrtc/api/java/jni/androidmediadecoder_jni.cc
@@ -843,7 +843,8 @@
   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() {
   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 @@
     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;
diff --git a/webrtc/api/java/jni/androidmediadecoder_jni.h b/webrtc/api/java/jni/androidmediadecoder_jni.h
index 8ee23be..0719926 100644
--- a/webrtc/api/java/jni/androidmediadecoder_jni.h
+++ b/webrtc/api/java/jni/androidmediadecoder_jni.h
@@ -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 @@
   void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) override;
 
  private:
-  EglBase egl_;
+  jobject egl_context_;
   std::vector<webrtc::VideoCodecType> supported_codec_types_;
 };
 
diff --git a/webrtc/api/java/jni/androidmediaencoder_jni.cc b/webrtc/api/java/jni/androidmediaencoder_jni.cc
index 7acb73b..ddfa85a 100644
--- a/webrtc/api/java/jni/androidmediaencoder_jni.cc
+++ b/webrtc/api/java/jni/androidmediaencoder_jni.cc
@@ -1164,7 +1164,8 @@
   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() {
   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 @@
       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;
diff --git a/webrtc/api/java/jni/androidmediaencoder_jni.h b/webrtc/api/java/jni/androidmediaencoder_jni.h
index c0b5f02..4e50700 100644
--- a/webrtc/api/java/jni/androidmediaencoder_jni.h
+++ b/webrtc/api/java/jni/androidmediaencoder_jni.h
@@ -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 @@
   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 @@
   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_;
diff --git a/webrtc/api/java/jni/eglbase_jni.cc b/webrtc/api/java/jni/eglbase_jni.cc
deleted file mode 100644
index e146024..0000000
--- a/webrtc/api/java/jni/eglbase_jni.cc
+++ /dev/null
@@ -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
diff --git a/webrtc/api/java/jni/eglbase_jni.h b/webrtc/api/java/jni/eglbase_jni.h
deleted file mode 100644
index 983cc19..0000000
--- a/webrtc/api/java/jni/eglbase_jni.h
+++ /dev/null
@@ -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_
diff --git a/webrtc/api/java/src/org/webrtc/PeerConnectionFactory.java b/webrtc/api/java/src/org/webrtc/PeerConnectionFactory.java
index 96a161b..51e593e 100644
--- a/webrtc/api/java/src/org/webrtc/PeerConnectionFactory.java
+++ b/webrtc/api/java/src/org/webrtc/PeerConnectionFactory.java
@@ -26,6 +26,8 @@
   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 @@
 
   /** 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() {
diff --git a/webrtc/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java b/webrtc/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java
index f7a16ee..e5fd952 100644
--- a/webrtc/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java
+++ b/webrtc/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java
@@ -400,19 +400,6 @@
     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 @@
     }
 
     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(