123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- /*
- * Copyright (C) 2010 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.
- */
- //#define LOG_NDEBUG 0
- #define LOG_TAG "MediaProfilesJNI"
- #include <utils/Log.h>
- #include <stdio.h>
- #include <utils/threads.h>
- #include "jni.h"
- #include <nativehelper/JNIHelp.h>
- #include "android_runtime/AndroidRuntime.h"
- #include <media/MediaProfiles.h>
- using namespace android;
- static Mutex sLock;
- MediaProfiles *sProfiles = NULL;
- // This function is called from a static block in MediaProfiles.java class,
- // which won't run until the first time an instance of this class is used.
- static void
- android_media_MediaProfiles_native_init(JNIEnv* /* env */)
- {
- ALOGV("native_init");
- Mutex::Autolock lock(sLock);
- if (sProfiles == NULL) {
- sProfiles = MediaProfiles::getInstance();
- }
- }
- static jint
- android_media_MediaProfiles_native_get_num_file_formats(JNIEnv* /* env */, jobject /* thiz */)
- {
- ALOGV("native_get_num_file_formats");
- return (jint) sProfiles->getOutputFileFormats().size();
- }
- static jint
- android_media_MediaProfiles_native_get_file_format(JNIEnv *env, jobject /* thiz */, jint index)
- {
- ALOGV("native_get_file_format: %d", index);
- Vector<output_format> formats = sProfiles->getOutputFileFormats();
- int nSize = formats.size();
- if (index < 0 || index >= nSize) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
- return -1;
- }
- return static_cast<jint>(formats[index]);
- }
- static jint
- android_media_MediaProfiles_native_get_num_video_encoders(JNIEnv* /* env */, jobject /* thiz */)
- {
- ALOGV("native_get_num_video_encoders");
- return sProfiles->getVideoEncoders().size();
- }
- static jobject
- android_media_MediaProfiles_native_get_video_encoder_cap(JNIEnv *env, jobject /* thiz */,
- jint index)
- {
- ALOGV("native_get_video_encoder_cap: %d", index);
- Vector<video_encoder> encoders = sProfiles->getVideoEncoders();
- int nSize = encoders.size();
- if (index < 0 || index >= nSize) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
- return NULL;
- }
- video_encoder encoder = encoders[index];
- int minBitRate = sProfiles->getVideoEncoderParamByName("enc.vid.bps.min", encoder);
- int maxBitRate = sProfiles->getVideoEncoderParamByName("enc.vid.bps.max", encoder);
- int minFrameRate = sProfiles->getVideoEncoderParamByName("enc.vid.fps.min", encoder);
- int maxFrameRate = sProfiles->getVideoEncoderParamByName("enc.vid.fps.max", encoder);
- int minFrameWidth = sProfiles->getVideoEncoderParamByName("enc.vid.width.min", encoder);
- int maxFrameWidth = sProfiles->getVideoEncoderParamByName("enc.vid.width.max", encoder);
- int minFrameHeight = sProfiles->getVideoEncoderParamByName("enc.vid.height.min", encoder);
- int maxFrameHeight = sProfiles->getVideoEncoderParamByName("enc.vid.height.max", encoder);
- // Check on the values retrieved
- if ((minBitRate == -1 || maxBitRate == -1) ||
- (minFrameRate == -1 || maxFrameRate == -1) ||
- (minFrameWidth == -1 || maxFrameWidth == -1) ||
- (minFrameHeight == -1 || maxFrameHeight == -1)) {
- jniThrowException(env, "java/lang/RuntimeException", "Error retrieving video encoder capability params");
- return NULL;
- }
- // Construct an instance of the VideoEncoderCap and set its member variables
- jclass videoEncoderCapClazz = env->FindClass("android/media/EncoderCapabilities$VideoEncoderCap");
- jmethodID videoEncoderCapConstructorMethodID = env->GetMethodID(videoEncoderCapClazz, "<init>", "(IIIIIIIII)V");
- jobject cap = env->NewObject(videoEncoderCapClazz,
- videoEncoderCapConstructorMethodID,
- static_cast<int>(encoder),
- minBitRate, maxBitRate,
- minFrameRate, maxFrameRate,
- minFrameWidth, maxFrameWidth,
- minFrameHeight, maxFrameHeight);
- return cap;
- }
- static jint
- android_media_MediaProfiles_native_get_num_audio_encoders(JNIEnv* /* env */, jobject /* thiz */)
- {
- ALOGV("native_get_num_audio_encoders");
- return (jint) sProfiles->getAudioEncoders().size();
- }
- static jobject
- android_media_MediaProfiles_native_get_audio_encoder_cap(JNIEnv *env, jobject /* thiz */,
- jint index)
- {
- ALOGV("native_get_audio_encoder_cap: %d", index);
- Vector<audio_encoder> encoders = sProfiles->getAudioEncoders();
- int nSize = encoders.size();
- if (index < 0 || index >= nSize) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
- return NULL;
- }
- audio_encoder encoder = encoders[index];
- int minBitRate = sProfiles->getAudioEncoderParamByName("enc.aud.bps.min", encoder);
- int maxBitRate = sProfiles->getAudioEncoderParamByName("enc.aud.bps.max", encoder);
- int minSampleRate = sProfiles->getAudioEncoderParamByName("enc.aud.hz.min", encoder);
- int maxSampleRate = sProfiles->getAudioEncoderParamByName("enc.aud.hz.max", encoder);
- int minChannels = sProfiles->getAudioEncoderParamByName("enc.aud.ch.min", encoder);
- int maxChannels = sProfiles->getAudioEncoderParamByName("enc.aud.ch.max", encoder);
- // Check on the values retrieved
- if ((minBitRate == -1 || maxBitRate == -1) ||
- (minSampleRate == -1 || maxSampleRate == -1) ||
- (minChannels == -1 || maxChannels == -1)) {
- jniThrowException(env, "java/lang/RuntimeException", "Error retrieving video encoder capability params");
- return NULL;
- }
- jclass audioEncoderCapClazz = env->FindClass("android/media/EncoderCapabilities$AudioEncoderCap");
- jmethodID audioEncoderCapConstructorMethodID = env->GetMethodID(audioEncoderCapClazz, "<init>", "(IIIIIII)V");
- jobject cap = env->NewObject(audioEncoderCapClazz,
- audioEncoderCapConstructorMethodID,
- static_cast<int>(encoder),
- minBitRate, maxBitRate,
- minSampleRate, maxSampleRate,
- minChannels, maxChannels);
- return cap;
- }
- static bool isCamcorderQualityKnown(int quality)
- {
- return ((quality >= CAMCORDER_QUALITY_LIST_START &&
- quality <= CAMCORDER_QUALITY_LIST_END) ||
- (quality >= CAMCORDER_QUALITY_TIME_LAPSE_LIST_START &&
- quality <= CAMCORDER_QUALITY_TIME_LAPSE_LIST_END) ||
- (quality >= CAMCORDER_QUALITY_HIGH_SPEED_LIST_START &&
- quality <= CAMCORDER_QUALITY_HIGH_SPEED_LIST_END));
- }
- static jobject
- android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject /* thiz */, jint id,
- jint quality)
- {
- ALOGV("native_get_camcorder_profile: %d %d", id, quality);
- if (!isCamcorderQualityKnown(quality)) {
- jniThrowException(env, "java/lang/RuntimeException", "Unknown camcorder profile quality");
- return NULL;
- }
- camcorder_quality q = static_cast<camcorder_quality>(quality);
- int duration = sProfiles->getCamcorderProfileParamByName("duration", id, q);
- int fileFormat = sProfiles->getCamcorderProfileParamByName("file.format", id, q);
- int videoCodec = sProfiles->getCamcorderProfileParamByName("vid.codec", id, q);
- int videoBitRate = sProfiles->getCamcorderProfileParamByName("vid.bps", id, q);
- int videoFrameRate = sProfiles->getCamcorderProfileParamByName("vid.fps", id, q);
- int videoFrameWidth = sProfiles->getCamcorderProfileParamByName("vid.width", id, q);
- int videoFrameHeight = sProfiles->getCamcorderProfileParamByName("vid.height", id, q);
- int audioCodec = sProfiles->getCamcorderProfileParamByName("aud.codec", id, q);
- int audioBitRate = sProfiles->getCamcorderProfileParamByName("aud.bps", id, q);
- int audioSampleRate = sProfiles->getCamcorderProfileParamByName("aud.hz", id, q);
- int audioChannels = sProfiles->getCamcorderProfileParamByName("aud.ch", id, q);
- // Check on the values retrieved
- if (duration == -1 || fileFormat == -1 || videoCodec == -1 || audioCodec == -1 ||
- videoBitRate == -1 || videoFrameRate == -1 || videoFrameWidth == -1 || videoFrameHeight == -1 ||
- audioBitRate == -1 || audioSampleRate == -1 || audioChannels == -1) {
- jniThrowException(env, "java/lang/RuntimeException", "Error retrieving camcorder profile params");
- return NULL;
- }
- jclass camcorderProfileClazz = env->FindClass("android/media/CamcorderProfile");
- jmethodID camcorderProfileConstructorMethodID = env->GetMethodID(camcorderProfileClazz, "<init>", "(IIIIIIIIIIII)V");
- return env->NewObject(camcorderProfileClazz,
- camcorderProfileConstructorMethodID,
- duration,
- quality,
- fileFormat,
- videoCodec,
- videoBitRate,
- videoFrameRate,
- videoFrameWidth,
- videoFrameHeight,
- audioCodec,
- audioBitRate,
- audioSampleRate,
- audioChannels);
- }
- static jboolean
- android_media_MediaProfiles_native_has_camcorder_profile(JNIEnv* /* env */, jobject /* thiz */,
- jint id, jint quality)
- {
- ALOGV("native_has_camcorder_profile: %d %d", id, quality);
- if (!isCamcorderQualityKnown(quality)) {
- return JNI_FALSE;
- }
- camcorder_quality q = static_cast<camcorder_quality>(quality);
- return sProfiles->hasCamcorderProfile(id, q) ? JNI_TRUE : JNI_FALSE;
- }
- static jint
- android_media_MediaProfiles_native_get_num_video_decoders(JNIEnv* /* env */, jobject /* thiz */)
- {
- ALOGV("native_get_num_video_decoders");
- return (jint) sProfiles->getVideoDecoders().size();
- }
- static jint
- android_media_MediaProfiles_native_get_video_decoder_type(JNIEnv *env, jobject /* thiz */,
- jint index)
- {
- ALOGV("native_get_video_decoder_type: %d", index);
- Vector<video_decoder> decoders = sProfiles->getVideoDecoders();
- int nSize = decoders.size();
- if (index < 0 || index >= nSize) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
- return -1;
- }
- return static_cast<jint>(decoders[index]);
- }
- static jint
- android_media_MediaProfiles_native_get_num_audio_decoders(JNIEnv* /* env */, jobject /* thiz */)
- {
- ALOGV("native_get_num_audio_decoders");
- return (jint) sProfiles->getAudioDecoders().size();
- }
- static jint
- android_media_MediaProfiles_native_get_audio_decoder_type(JNIEnv *env, jobject /* thiz */,
- jint index)
- {
- ALOGV("native_get_audio_decoder_type: %d", index);
- Vector<audio_decoder> decoders = sProfiles->getAudioDecoders();
- int nSize = decoders.size();
- if (index < 0 || index >= nSize) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
- return -1;
- }
- return static_cast<jint>(decoders[index]);
- }
- static jint
- android_media_MediaProfiles_native_get_num_image_encoding_quality_levels(JNIEnv* /* env */,
- jobject /* thiz */,
- jint cameraId)
- {
- ALOGV("native_get_num_image_encoding_quality_levels");
- return (jint) sProfiles->getImageEncodingQualityLevels(cameraId).size();
- }
- static jint
- android_media_MediaProfiles_native_get_image_encoding_quality_level(JNIEnv *env, jobject /* thiz */,
- jint cameraId, jint index)
- {
- ALOGV("native_get_image_encoding_quality_level");
- Vector<int> levels = sProfiles->getImageEncodingQualityLevels(cameraId);
- if (index < 0 || index >= (jint) levels.size()) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
- return -1;
- }
- return static_cast<jint>(levels[index]);
- }
- static const JNINativeMethod gMethodsForEncoderCapabilitiesClass[] = {
- {"native_init", "()V", (void *)android_media_MediaProfiles_native_init},
- {"native_get_num_file_formats", "()I", (void *)android_media_MediaProfiles_native_get_num_file_formats},
- {"native_get_file_format", "(I)I", (void *)android_media_MediaProfiles_native_get_file_format},
- {"native_get_num_video_encoders", "()I", (void *)android_media_MediaProfiles_native_get_num_video_encoders},
- {"native_get_num_audio_encoders", "()I", (void *)android_media_MediaProfiles_native_get_num_audio_encoders},
- {"native_get_video_encoder_cap", "(I)Landroid/media/EncoderCapabilities$VideoEncoderCap;",
- (void *)android_media_MediaProfiles_native_get_video_encoder_cap},
- {"native_get_audio_encoder_cap", "(I)Landroid/media/EncoderCapabilities$AudioEncoderCap;",
- (void *)android_media_MediaProfiles_native_get_audio_encoder_cap},
- };
- static const JNINativeMethod gMethodsForCamcorderProfileClass[] = {
- {"native_init", "()V", (void *)android_media_MediaProfiles_native_init},
- {"native_get_camcorder_profile", "(II)Landroid/media/CamcorderProfile;",
- (void *)android_media_MediaProfiles_native_get_camcorder_profile},
- {"native_has_camcorder_profile", "(II)Z",
- (void *)android_media_MediaProfiles_native_has_camcorder_profile},
- };
- static const JNINativeMethod gMethodsForDecoderCapabilitiesClass[] = {
- {"native_init", "()V", (void *)android_media_MediaProfiles_native_init},
- {"native_get_num_video_decoders", "()I", (void *)android_media_MediaProfiles_native_get_num_video_decoders},
- {"native_get_num_audio_decoders", "()I", (void *)android_media_MediaProfiles_native_get_num_audio_decoders},
- {"native_get_video_decoder_type", "(I)I", (void *)android_media_MediaProfiles_native_get_video_decoder_type},
- {"native_get_audio_decoder_type", "(I)I", (void *)android_media_MediaProfiles_native_get_audio_decoder_type},
- };
- static const JNINativeMethod gMethodsForCameraProfileClass[] = {
- {"native_init", "()V", (void *)android_media_MediaProfiles_native_init},
- {"native_get_num_image_encoding_quality_levels",
- "(I)I", (void *)android_media_MediaProfiles_native_get_num_image_encoding_quality_levels},
- {"native_get_image_encoding_quality_level","(II)I", (void *)android_media_MediaProfiles_native_get_image_encoding_quality_level},
- };
- static const char* const kEncoderCapabilitiesClassPathName = "android/media/EncoderCapabilities";
- static const char* const kDecoderCapabilitiesClassPathName = "android/media/DecoderCapabilities";
- static const char* const kCamcorderProfileClassPathName = "android/media/CamcorderProfile";
- static const char* const kCameraProfileClassPathName = "android/media/CameraProfile";
- // This function only registers the native methods, and is called from
- // JNI_OnLoad in android_media_MediaPlayer.cpp
- int register_android_media_MediaProfiles(JNIEnv *env)
- {
- int ret1 = AndroidRuntime::registerNativeMethods(env,
- kEncoderCapabilitiesClassPathName,
- gMethodsForEncoderCapabilitiesClass,
- NELEM(gMethodsForEncoderCapabilitiesClass));
- int ret2 = AndroidRuntime::registerNativeMethods(env,
- kCamcorderProfileClassPathName,
- gMethodsForCamcorderProfileClass,
- NELEM(gMethodsForCamcorderProfileClass));
- int ret3 = AndroidRuntime::registerNativeMethods(env,
- kDecoderCapabilitiesClassPathName,
- gMethodsForDecoderCapabilitiesClass,
- NELEM(gMethodsForDecoderCapabilitiesClass));
- int ret4 = AndroidRuntime::registerNativeMethods(env,
- kCameraProfileClassPathName,
- gMethodsForCameraProfileClass,
- NELEM(gMethodsForCameraProfileClass));
- // Success if all return values from above are 0
- return (ret1 || ret2 || ret3 || ret4);
- }
|