You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
6.4 KiB

/*
* Copyright 2018, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ANDROID_MEDIA_AUDIOPRESENTATION_H_
#define _ANDROID_MEDIA_AUDIOPRESENTATION_H_
#include "jni.h"
#include <media/stagefright/foundation/ADebug.h> // CHECK
#include <media/stagefright/foundation/AudioPresentationInfo.h>
#include <nativehelper/ScopedLocalRef.h>
namespace android {
struct JAudioPresentationInfo {
struct fields_t {
jclass clazz = NULL;
jmethodID constructID;
// list parameters
jclass listClazz = NULL;
jmethodID listConstructId;
jmethodID listAddId;
// hashmap parameters
jclass hashMapClazz = NULL;
jmethodID hashMapConstructID;
jmethodID hashMapPutID;
// ulocale parameters
jclass ulocaleClazz = NULL;
jmethodID ulocaleConstructID;
void init(JNIEnv *env) {
jclass lclazz = env->FindClass("android/media/AudioPresentation");
CHECK(lclazz != NULL);
clazz = (jclass)env->NewGlobalRef(lclazz);
CHECK(clazz != NULL);
constructID = env->GetMethodID(clazz, "<init>",
"(IILandroid/icu/util/ULocale;IZZZLjava/util/Map;)V");
CHECK(constructID != NULL);
// list objects
jclass llistClazz = env->FindClass("java/util/ArrayList");
CHECK(llistClazz != NULL);
listClazz = static_cast<jclass>(env->NewGlobalRef(llistClazz));
CHECK(listClazz != NULL);
listConstructId = env->GetMethodID(listClazz, "<init>", "()V");
CHECK(listConstructId != NULL);
listAddId = env->GetMethodID(listClazz, "add", "(Ljava/lang/Object;)Z");
CHECK(listAddId != NULL);
// hashmap objects
jclass lhashMapClazz = env->FindClass("java/util/HashMap");
CHECK(lhashMapClazz != NULL);
hashMapClazz = (jclass)env->NewGlobalRef(lhashMapClazz);
CHECK(hashMapClazz != NULL);
hashMapConstructID = env->GetMethodID(hashMapClazz, "<init>", "()V");
CHECK(hashMapConstructID != NULL);
hashMapPutID = env->GetMethodID(
hashMapClazz,
"put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
CHECK(hashMapPutID != NULL);
jclass lulocaleClazz = env->FindClass("android/icu/util/ULocale");
CHECK(lulocaleClazz != NULL);
ulocaleClazz = (jclass)env->NewGlobalRef(lulocaleClazz);
CHECK(ulocaleClazz != NULL);
ulocaleConstructID = env->GetMethodID(ulocaleClazz, "<init>", "(Ljava/lang/String;)V");
CHECK(ulocaleConstructID != NULL);
}
void exit(JNIEnv *env) {
env->DeleteGlobalRef(clazz); clazz = NULL;
env->DeleteGlobalRef(listClazz); listClazz = NULL;
env->DeleteGlobalRef(hashMapClazz); hashMapClazz = NULL;
env->DeleteGlobalRef(ulocaleClazz); ulocaleClazz = NULL;
}
};
static jobject asJobject(JNIEnv *env, const fields_t& fields) {
return env->NewObject(fields.listClazz, fields.listConstructId);
}
static void addPresentations(JNIEnv *env, const fields_t& fields,
const AudioPresentationCollection& presentations, jobject presentationsJObj) {
for (const auto& ap : presentations) {
ScopedLocalRef<jobject> jLabelObject = convertLabelsToMap(env, fields, ap.mLabels);
if (jLabelObject == nullptr) return;
ScopedLocalRef<jstring> jLanguage(env, env->NewStringUTF(ap.mLanguage.c_str()));
if (jLanguage == nullptr) return;
ScopedLocalRef<jobject> jLocale(env, env->NewObject(
fields.ulocaleClazz, fields.ulocaleConstructID, jLanguage.get()));
ScopedLocalRef<jobject> jValueObj(env, env->NewObject(fields.clazz, fields.constructID,
static_cast<jint>(ap.mPresentationId),
static_cast<jint>(ap.mProgramId),
jLocale.get(),
static_cast<jint>(ap.mMasteringIndication),
static_cast<jboolean>((ap.mAudioDescriptionAvailable == 1) ? 1 : 0),
static_cast<jboolean>((ap.mSpokenSubtitlesAvailable == 1) ? 1 : 0),
static_cast<jboolean>((ap.mDialogueEnhancementAvailable == 1) ? 1 : 0),
jLabelObject.get()));
if (jValueObj != nullptr) {
env->CallBooleanMethod(presentationsJObj, fields.listAddId, jValueObj.get());
}
}
}
private:
static ScopedLocalRef<jobject> convertLabelsToMap(
JNIEnv *env, const fields_t& fields, const std::map<std::string, std::string> &labels) {
ScopedLocalRef<jobject> nullMap(env, nullptr);
ScopedLocalRef<jobject> hashMap(env, env->NewObject(
fields.hashMapClazz, fields.hashMapConstructID));
if (hashMap == nullptr) {
return nullMap;
}
for (const auto& label : labels) {
ScopedLocalRef<jstring> jLanguage(env, env->NewStringUTF(label.first.c_str()));
if (jLanguage == nullptr) return nullMap;
ScopedLocalRef<jobject> jLocale(env, env->NewObject(
fields.ulocaleClazz,
fields.ulocaleConstructID,
jLanguage.get()));
if (jLocale == nullptr) return nullMap;
ScopedLocalRef<jobject> jValue(env, env->NewStringUTF(label.second.c_str()));
if (jValue == nullptr) return nullMap;
env->CallObjectMethod(hashMap.get(), fields.hashMapPutID, jLocale.get(), jValue.get());
}
return hashMap;
}
};
} // namespace android
#endif // _ANDROID_MEDIA_AUDIO_PRESENTATION_H_