1 // Copyright 2019 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // #define LOG_NDEBUG 0
6 #define LOG_TAG "E2E_JNI"
7 
8 #include <jni.h>
9 #include <pthread.h>
10 #include <sstream>
11 
12 #include <android/native_window_jni.h>
13 #include <log/log.h>
14 
15 #include "e2e_test_jni.h"
16 #include "mediacodec_decoder.h"
17 
18 #define UNUSED(x) ((void)x)
19 
20 namespace {
21 
22 class JniConfigureCallback : public android::ConfigureCallback {
23 public:
JniConfigureCallback(JNIEnv * env,jobject thiz)24     JniConfigureCallback(JNIEnv* env, jobject thiz) : env_(env), thiz_(thiz) {}
25 
26     static constexpr char* kClassName = "org/chromium/c2/test/E2eTestActivity";
27 
OnCodecReady(void * codec)28     void OnCodecReady(void* codec) override {
29         jclass cls = env_->FindClass(kClassName);
30         jmethodID methodid = env_->GetMethodID(cls, "onCodecReady", "(J)V");
31         env_->CallVoidMethod(thiz_, methodid, (jlong)codec);
32     }
33 
OnSizeChanged(int width,int height)34     void OnSizeChanged(int width, int height) override {
35         jclass cls = env_->FindClass(kClassName);
36         jmethodID methodid = env_->GetMethodID(cls, "onSizeChanged", "(II)V");
37         env_->CallVoidMethod(thiz_, methodid, width, height);
38     }
39 
40 private:
41     JNIEnv* env_;
42     jobject thiz_;
43 };
44 
45 }  // namespace
46 
47 extern "C" {
48 
Java_org_chromium_c2_test_E2eTestActivity_c2VideoTest(JNIEnv * env,jobject thiz,jboolean encode,jobjectArray test_args,int test_args_count,jobject surface,jstring tmp_file_path)49 JNIEXPORT jint JNICALL Java_org_chromium_c2_test_E2eTestActivity_c2VideoTest(
50         JNIEnv* env, jobject thiz, jboolean encode, jobjectArray test_args, int test_args_count,
51         jobject surface, jstring tmp_file_path) {
52     const char* log_path = env->GetStringUTFChars(tmp_file_path, nullptr);
53     if (freopen(log_path, "a+", stdout) == NULL) {
54         env->ReleaseStringUTFChars(tmp_file_path, log_path);
55         ALOGE("Failed to redirect stream to file: %s: %s\n", log_path, strerror(errno));
56         return JNI_ERR;
57     }
58     ALOGI("Saving gtest output to %s\n", log_path);
59     env->ReleaseStringUTFChars(tmp_file_path, log_path);
60 
61     char** args = new char*[test_args_count];
62     for (int i = 0; i < test_args_count; i++) {
63         jstring string = (jstring)env->GetObjectArrayElement(test_args, i);
64         const char* c_str = env->GetStringUTFChars(string, nullptr);
65         int len = env->GetStringUTFLength(string);
66 
67         args[i] = new char[len + 1];
68         memcpy(args[i], c_str, len);
69         args[i][len] = '\0';
70 
71         env->ReleaseStringUTFChars(string, c_str);
72     }
73 
74     char** final_args = new char*[test_args_count + 1];
75     final_args[0] = "e2e_test_jni";
76     memcpy(final_args + 1, args, sizeof(args[0]) * test_args_count);
77 
78     ANativeWindow* native_window = ANativeWindow_fromSurface(env, surface);
79 
80     int res;
81     JniConfigureCallback cb(env, thiz);
82     if (encode) {
83         res = RunEncoderTests(final_args, test_args_count + 1, &cb);
84     } else {
85         res = RunDecoderTests(final_args, test_args_count + 1, native_window, &cb);
86     }
87     delete[] final_args;
88 
89     for (int i = 0; i < test_args_count; i++) {
90         delete[] args[i];
91     }
92     delete[] args;
93     ANativeWindow_release(native_window);
94 
95     fflush(stdout);
96     fclose(stdout);
97 
98     return res;
99 }
100 
Java_org_chromium_c2_test_E2eTestActivity_stopDecoderLoop(JNIEnv * env,jobject thiz,jlong decoderPtr)101 JNIEXPORT void JNICALL Java_org_chromium_c2_test_E2eTestActivity_stopDecoderLoop(JNIEnv* env,
102                                                                                  jobject thiz,
103                                                                                  jlong decoderPtr) {
104     UNUSED(env);
105     UNUSED(thiz);
106     reinterpret_cast<android::MediaCodecDecoder*>(decoderPtr)->StopLooping();
107 }
108 
109 }
110