1 /*
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/video_coding/codecs/test/android_codec_factory_helper.h"
12
13 #include <pthread.h>
14
15 #include <memory>
16
17 #include "rtc_base/checks.h"
18 #include "rtc_base/ignore_wundef.h"
19 #include "sdk/android/native_api/base/init.h"
20 #include "sdk/android/native_api/codecs/wrapper.h"
21 #include "sdk/android/native_api/jni/class_loader.h"
22 #include "sdk/android/native_api/jni/jvm.h"
23 #include "sdk/android/native_api/jni/scoped_java_ref.h"
24
25 // Note: this dependency is dangerous since it reaches into Chromium's base.
26 // There's a risk of e.g. macro clashes. This file may only be used in tests.
27 // Since we use Chrome's build system for creating the gtest binary, this should
28 // be fine.
29 RTC_PUSH_IGNORING_WUNDEF()
30 #include "base/android/jni_android.h"
31 RTC_POP_IGNORING_WUNDEF()
32
33 namespace webrtc {
34 namespace test {
35
36 namespace {
37
38 static pthread_once_t g_initialize_once = PTHREAD_ONCE_INIT;
39
40 // There can only be one JNI_OnLoad in each binary. So since this is a GTEST
41 // C++ runner binary, we want to initialize the same global objects we normally
42 // do if this had been a Java binary.
EnsureInitializedOnce()43 void EnsureInitializedOnce() {
44 RTC_CHECK(::base::android::IsVMInitialized());
45 JNIEnv* env = ::base::android::AttachCurrentThread();
46 JavaVM* jvm = nullptr;
47 RTC_CHECK_EQ(0, env->GetJavaVM(&jvm));
48
49 InitAndroid(jvm);
50 }
51
52 } // namespace
53
InitializeAndroidObjects()54 void InitializeAndroidObjects() {
55 RTC_CHECK_EQ(0, pthread_once(&g_initialize_once, &EnsureInitializedOnce));
56 }
57
CreateAndroidEncoderFactory()58 std::unique_ptr<VideoEncoderFactory> CreateAndroidEncoderFactory() {
59 JNIEnv* env = AttachCurrentThreadIfNeeded();
60 ScopedJavaLocalRef<jclass> factory_class =
61 GetClass(env, "org/webrtc/HardwareVideoEncoderFactory");
62 jmethodID factory_constructor = env->GetMethodID(
63 factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;ZZ)V");
64 ScopedJavaLocalRef<jobject> factory_object(
65 env, env->NewObject(factory_class.obj(), factory_constructor,
66 nullptr /* shared_context */,
67 false /* enable_intel_vp8_encoder */,
68 true /* enable_h264_high_profile */));
69 return JavaToNativeVideoEncoderFactory(env, factory_object.obj());
70 }
71
CreateAndroidDecoderFactory()72 std::unique_ptr<VideoDecoderFactory> CreateAndroidDecoderFactory() {
73 JNIEnv* env = AttachCurrentThreadIfNeeded();
74 ScopedJavaLocalRef<jclass> factory_class =
75 GetClass(env, "org/webrtc/HardwareVideoDecoderFactory");
76 jmethodID factory_constructor = env->GetMethodID(
77 factory_class.obj(), "<init>", "(Lorg/webrtc/EglBase$Context;)V");
78 ScopedJavaLocalRef<jobject> factory_object(
79 env, env->NewObject(factory_class.obj(), factory_constructor,
80 nullptr /* shared_context */));
81 return JavaToNativeVideoDecoderFactory(env, factory_object.obj());
82 }
83
84 } // namespace test
85 } // namespace webrtc
86