1c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong/* 2c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong * Copyright (C) 2010 The Android Open Source Project 3c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong * 4c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong * Licensed under the Apache License, Version 2.0 (the "License"); 5c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong * you may not use this file except in compliance with the License. 6c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong * You may obtain a copy of the License at 7c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong * 8c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong * http://www.apache.org/licenses/LICENSE-2.0 9c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong * 10c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong * Unless required by applicable law or agreed to in writing, software 11c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong * distributed under the License is distributed on an "AS IS" BASIS, 12c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong * See the License for the specific language governing permissions and 14c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong * limitations under the License. 15c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong */ 16c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 17c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong//#define LOG_NDEBUG 0 18c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong#define LOG_TAG "MediaProfilesJNI" 19c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong#include <utils/Log.h> 20c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 21c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong#include <stdio.h> 22c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong#include <utils/threads.h> 23c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 24c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong#include "jni.h" 25c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong#include "JNIHelp.h" 26c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong#include "android_runtime/AndroidRuntime.h" 27c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong#include <media/MediaProfiles.h> 28c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 29c371194e4e0651c328f1870a90bbfd4e217c747bJames Dongusing namespace android; 30c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 31c371194e4e0651c328f1870a90bbfd4e217c747bJames Dongstatic Mutex sLock; 32c371194e4e0651c328f1870a90bbfd4e217c747bJames DongMediaProfiles *sProfiles = NULL; 33c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 34c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong// This function is called from a static block in MediaProfiles.java class, 35c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong// which won't run until the first time an instance of this class is used. 36c371194e4e0651c328f1870a90bbfd4e217c747bJames Dongstatic void 375a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_init(JNIEnv* /* env */) 38c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong{ 3971f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_init"); 40c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong Mutex::Autolock lock(sLock); 41c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 42c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong if (sProfiles == NULL) { 43c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong sProfiles = MediaProfiles::getInstance(); 44c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong } 45c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong} 46c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 47d32fba411f2710ad66681466674c8243f2ca3454James Dongstatic jint 485a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_get_num_file_formats(JNIEnv* /* env */, jobject /* thiz */) 49c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong{ 5071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_get_num_file_formats"); 51075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) sProfiles->getOutputFileFormats().size(); 52c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong} 53c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 54d32fba411f2710ad66681466674c8243f2ca3454James Dongstatic jint 555a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_get_file_format(JNIEnv *env, jobject /* thiz */, jint index) 56c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong{ 5771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_get_file_format: %d", index); 58c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong Vector<output_format> formats = sProfiles->getOutputFileFormats(); 59c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int nSize = formats.size(); 60c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong if (index < 0 || index >= nSize) { 61c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary"); 62c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong return -1; 63c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong } 64d32fba411f2710ad66681466674c8243f2ca3454James Dong return static_cast<jint>(formats[index]); 65c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong} 66c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 67d32fba411f2710ad66681466674c8243f2ca3454James Dongstatic jint 685a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_get_num_video_encoders(JNIEnv* /* env */, jobject /* thiz */) 69c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong{ 7071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_get_num_video_encoders"); 71c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong return sProfiles->getVideoEncoders().size(); 72c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong} 73c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 74c371194e4e0651c328f1870a90bbfd4e217c747bJames Dongstatic jobject 755a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_get_video_encoder_cap(JNIEnv *env, jobject /* thiz */, 765a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe jint index) 77c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong{ 7871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_get_video_encoder_cap: %d", index); 79c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong Vector<video_encoder> encoders = sProfiles->getVideoEncoders(); 80c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int nSize = encoders.size(); 81c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong if (index < 0 || index >= nSize) { 82c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary"); 83c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong return NULL; 84c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong } 85c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 86c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong video_encoder encoder = encoders[index]; 87c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int minBitRate = sProfiles->getVideoEncoderParamByName("enc.vid.bps.min", encoder); 88c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int maxBitRate = sProfiles->getVideoEncoderParamByName("enc.vid.bps.max", encoder); 89c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int minFrameRate = sProfiles->getVideoEncoderParamByName("enc.vid.fps.min", encoder); 90c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int maxFrameRate = sProfiles->getVideoEncoderParamByName("enc.vid.fps.max", encoder); 91c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int minFrameWidth = sProfiles->getVideoEncoderParamByName("enc.vid.width.min", encoder); 92c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int maxFrameWidth = sProfiles->getVideoEncoderParamByName("enc.vid.width.max", encoder); 93c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int minFrameHeight = sProfiles->getVideoEncoderParamByName("enc.vid.height.min", encoder); 94c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int maxFrameHeight = sProfiles->getVideoEncoderParamByName("enc.vid.height.max", encoder); 95c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 96c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong // Check on the values retrieved 97c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong if ((minBitRate == -1 || maxBitRate == -1) || 98c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong (minFrameRate == -1 || maxFrameRate == -1) || 99c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong (minFrameWidth == -1 || maxFrameWidth == -1) || 100c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong (minFrameHeight == -1 || maxFrameHeight == -1)) { 101c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 102c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong jniThrowException(env, "java/lang/RuntimeException", "Error retrieving video encoder capability params"); 103c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong return NULL; 104c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong } 105c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 106c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong // Construct an instance of the VideoEncoderCap and set its member variables 107c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong jclass videoEncoderCapClazz = env->FindClass("android/media/EncoderCapabilities$VideoEncoderCap"); 108c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong jmethodID videoEncoderCapConstructorMethodID = env->GetMethodID(videoEncoderCapClazz, "<init>", "(IIIIIIIII)V"); 109c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong jobject cap = env->NewObject(videoEncoderCapClazz, 110c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong videoEncoderCapConstructorMethodID, 111c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong static_cast<int>(encoder), 112c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong minBitRate, maxBitRate, 113c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong minFrameRate, maxFrameRate, 114c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong minFrameWidth, maxFrameWidth, 115c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong minFrameHeight, maxFrameHeight); 116c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong return cap; 117c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong} 118c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 119d32fba411f2710ad66681466674c8243f2ca3454James Dongstatic jint 1205a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_get_num_audio_encoders(JNIEnv* /* env */, jobject /* thiz */) 121c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong{ 12271f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_get_num_audio_encoders"); 123075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) sProfiles->getAudioEncoders().size(); 124c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong} 125c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 126c371194e4e0651c328f1870a90bbfd4e217c747bJames Dongstatic jobject 1275a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_get_audio_encoder_cap(JNIEnv *env, jobject /* thiz */, 1285a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe jint index) 129c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong{ 13071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_get_audio_encoder_cap: %d", index); 131c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong Vector<audio_encoder> encoders = sProfiles->getAudioEncoders(); 132c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int nSize = encoders.size(); 133c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong if (index < 0 || index >= nSize) { 134c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary"); 135c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong return NULL; 136c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong } 137c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 138c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong audio_encoder encoder = encoders[index]; 139c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int minBitRate = sProfiles->getAudioEncoderParamByName("enc.aud.bps.min", encoder); 140c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int maxBitRate = sProfiles->getAudioEncoderParamByName("enc.aud.bps.max", encoder); 141c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int minSampleRate = sProfiles->getAudioEncoderParamByName("enc.aud.hz.min", encoder); 142c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int maxSampleRate = sProfiles->getAudioEncoderParamByName("enc.aud.hz.max", encoder); 143c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int minChannels = sProfiles->getAudioEncoderParamByName("enc.aud.ch.min", encoder); 144c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong int maxChannels = sProfiles->getAudioEncoderParamByName("enc.aud.ch.max", encoder); 145c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 146c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong // Check on the values retrieved 147c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong if ((minBitRate == -1 || maxBitRate == -1) || 148c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong (minSampleRate == -1 || maxSampleRate == -1) || 149c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong (minChannels == -1 || maxChannels == -1)) { 150c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 151c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong jniThrowException(env, "java/lang/RuntimeException", "Error retrieving video encoder capability params"); 152c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong return NULL; 153c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong } 154c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 155c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong jclass audioEncoderCapClazz = env->FindClass("android/media/EncoderCapabilities$AudioEncoderCap"); 156c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong jmethodID audioEncoderCapConstructorMethodID = env->GetMethodID(audioEncoderCapClazz, "<init>", "(IIIIIII)V"); 157c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong jobject cap = env->NewObject(audioEncoderCapClazz, 158c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong audioEncoderCapConstructorMethodID, 159c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong static_cast<int>(encoder), 160c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong minBitRate, maxBitRate, 161c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong minSampleRate, maxSampleRate, 162c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong minChannels, maxChannels); 163c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong return cap; 164c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong} 165c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 16607b9ae33127212fd9e15f96fa89b7d4cab81e55eJames Dongstatic bool isCamcorderQualityKnown(int quality) 16707b9ae33127212fd9e15f96fa89b7d4cab81e55eJames Dong{ 16807b9ae33127212fd9e15f96fa89b7d4cab81e55eJames Dong return ((quality >= CAMCORDER_QUALITY_LIST_START && 16907b9ae33127212fd9e15f96fa89b7d4cab81e55eJames Dong quality <= CAMCORDER_QUALITY_LIST_END) || 17007b9ae33127212fd9e15f96fa89b7d4cab81e55eJames Dong (quality >= CAMCORDER_QUALITY_TIME_LAPSE_LIST_START && 171f7badff8bbcbd45939c2f60cfcc88c6d3b07c6b2Zhijun He quality <= CAMCORDER_QUALITY_TIME_LAPSE_LIST_END) || 172f7badff8bbcbd45939c2f60cfcc88c6d3b07c6b2Zhijun He (quality >= CAMCORDER_QUALITY_HIGH_SPEED_LIST_START && 173f7badff8bbcbd45939c2f60cfcc88c6d3b07c6b2Zhijun He quality <= CAMCORDER_QUALITY_HIGH_SPEED_LIST_END)); 17407b9ae33127212fd9e15f96fa89b7d4cab81e55eJames Dong} 17507b9ae33127212fd9e15f96fa89b7d4cab81e55eJames Dong 176e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dongstatic jobject 1775a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject /* thiz */, jint id, 1785a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe jint quality) 179e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong{ 18071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_get_camcorder_profile: %d %d", id, quality); 18107b9ae33127212fd9e15f96fa89b7d4cab81e55eJames Dong if (!isCamcorderQualityKnown(quality)) { 182e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong jniThrowException(env, "java/lang/RuntimeException", "Unknown camcorder profile quality"); 183e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong return NULL; 184e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong } 185e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong 186e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong camcorder_quality q = static_cast<camcorder_quality>(quality); 18709b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang int duration = sProfiles->getCamcorderProfileParamByName("duration", id, q); 18809b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang int fileFormat = sProfiles->getCamcorderProfileParamByName("file.format", id, q); 18909b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang int videoCodec = sProfiles->getCamcorderProfileParamByName("vid.codec", id, q); 19009b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang int videoBitRate = sProfiles->getCamcorderProfileParamByName("vid.bps", id, q); 19109b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang int videoFrameRate = sProfiles->getCamcorderProfileParamByName("vid.fps", id, q); 19209b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang int videoFrameWidth = sProfiles->getCamcorderProfileParamByName("vid.width", id, q); 19309b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang int videoFrameHeight = sProfiles->getCamcorderProfileParamByName("vid.height", id, q); 19409b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang int audioCodec = sProfiles->getCamcorderProfileParamByName("aud.codec", id, q); 19509b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang int audioBitRate = sProfiles->getCamcorderProfileParamByName("aud.bps", id, q); 19609b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang int audioSampleRate = sProfiles->getCamcorderProfileParamByName("aud.hz", id, q); 19709b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang int audioChannels = sProfiles->getCamcorderProfileParamByName("aud.ch", id, q); 198e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong 199e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong // Check on the values retrieved 2009b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong if (duration == -1 || fileFormat == -1 || videoCodec == -1 || audioCodec == -1 || 201e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong videoBitRate == -1 || videoFrameRate == -1 || videoFrameWidth == -1 || videoFrameHeight == -1 || 202e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong audioBitRate == -1 || audioSampleRate == -1 || audioChannels == -1) { 203e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong 204e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong jniThrowException(env, "java/lang/RuntimeException", "Error retrieving camcorder profile params"); 205e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong return NULL; 206e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong } 207e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong 208e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong jclass camcorderProfileClazz = env->FindClass("android/media/CamcorderProfile"); 2099b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong jmethodID camcorderProfileConstructorMethodID = env->GetMethodID(camcorderProfileClazz, "<init>", "(IIIIIIIIIIII)V"); 210e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong return env->NewObject(camcorderProfileClazz, 211e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong camcorderProfileConstructorMethodID, 2129b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong duration, 213e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong quality, 214e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong fileFormat, 215e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong videoCodec, 216e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong videoBitRate, 217e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong videoFrameRate, 218e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong videoFrameWidth, 219e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong videoFrameHeight, 220e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong audioCodec, 221e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong audioBitRate, 222e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong audioSampleRate, 223e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong audioChannels); 224e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong} 225e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong 2269d619542bea7d4c376a5a8b4a55c795a796adef3Nipun Kwatrastatic jboolean 2275a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_has_camcorder_profile(JNIEnv* /* env */, jobject /* thiz */, 2285a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe jint id, jint quality) 2299d619542bea7d4c376a5a8b4a55c795a796adef3Nipun Kwatra{ 23071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_has_camcorder_profile: %d %d", id, quality); 23107b9ae33127212fd9e15f96fa89b7d4cab81e55eJames Dong if (!isCamcorderQualityKnown(quality)) { 232075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return JNI_FALSE; 2339d619542bea7d4c376a5a8b4a55c795a796adef3Nipun Kwatra } 2349d619542bea7d4c376a5a8b4a55c795a796adef3Nipun Kwatra 2359d619542bea7d4c376a5a8b4a55c795a796adef3Nipun Kwatra camcorder_quality q = static_cast<camcorder_quality>(quality); 236075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return sProfiles->hasCamcorderProfile(id, q) ? JNI_TRUE : JNI_FALSE; 2379d619542bea7d4c376a5a8b4a55c795a796adef3Nipun Kwatra} 2389d619542bea7d4c376a5a8b4a55c795a796adef3Nipun Kwatra 239d32fba411f2710ad66681466674c8243f2ca3454James Dongstatic jint 2405a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_get_num_video_decoders(JNIEnv* /* env */, jobject /* thiz */) 241d32fba411f2710ad66681466674c8243f2ca3454James Dong{ 24271f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_get_num_video_decoders"); 243075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) sProfiles->getVideoDecoders().size(); 244d32fba411f2710ad66681466674c8243f2ca3454James Dong} 245d32fba411f2710ad66681466674c8243f2ca3454James Dong 246d32fba411f2710ad66681466674c8243f2ca3454James Dongstatic jint 2475a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_get_video_decoder_type(JNIEnv *env, jobject /* thiz */, 2485a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe jint index) 249d32fba411f2710ad66681466674c8243f2ca3454James Dong{ 25071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_get_video_decoder_type: %d", index); 251d32fba411f2710ad66681466674c8243f2ca3454James Dong Vector<video_decoder> decoders = sProfiles->getVideoDecoders(); 252d32fba411f2710ad66681466674c8243f2ca3454James Dong int nSize = decoders.size(); 253d32fba411f2710ad66681466674c8243f2ca3454James Dong if (index < 0 || index >= nSize) { 254d32fba411f2710ad66681466674c8243f2ca3454James Dong jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary"); 255d32fba411f2710ad66681466674c8243f2ca3454James Dong return -1; 256d32fba411f2710ad66681466674c8243f2ca3454James Dong } 257d32fba411f2710ad66681466674c8243f2ca3454James Dong 258d32fba411f2710ad66681466674c8243f2ca3454James Dong return static_cast<jint>(decoders[index]); 259d32fba411f2710ad66681466674c8243f2ca3454James Dong} 260d32fba411f2710ad66681466674c8243f2ca3454James Dong 261d32fba411f2710ad66681466674c8243f2ca3454James Dongstatic jint 2625a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_get_num_audio_decoders(JNIEnv* /* env */, jobject /* thiz */) 263d32fba411f2710ad66681466674c8243f2ca3454James Dong{ 26471f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_get_num_audio_decoders"); 265075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) sProfiles->getAudioDecoders().size(); 266d32fba411f2710ad66681466674c8243f2ca3454James Dong} 267d32fba411f2710ad66681466674c8243f2ca3454James Dong 268d32fba411f2710ad66681466674c8243f2ca3454James Dongstatic jint 2695a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_get_audio_decoder_type(JNIEnv *env, jobject /* thiz */, 2705a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe jint index) 271d32fba411f2710ad66681466674c8243f2ca3454James Dong{ 27271f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_get_audio_decoder_type: %d", index); 273d32fba411f2710ad66681466674c8243f2ca3454James Dong Vector<audio_decoder> decoders = sProfiles->getAudioDecoders(); 274d32fba411f2710ad66681466674c8243f2ca3454James Dong int nSize = decoders.size(); 275d32fba411f2710ad66681466674c8243f2ca3454James Dong if (index < 0 || index >= nSize) { 276d32fba411f2710ad66681466674c8243f2ca3454James Dong jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary"); 277d32fba411f2710ad66681466674c8243f2ca3454James Dong return -1; 278d32fba411f2710ad66681466674c8243f2ca3454James Dong } 279d32fba411f2710ad66681466674c8243f2ca3454James Dong 280d32fba411f2710ad66681466674c8243f2ca3454James Dong return static_cast<jint>(decoders[index]); 281d32fba411f2710ad66681466674c8243f2ca3454James Dong} 282d32fba411f2710ad66681466674c8243f2ca3454James Dong 2839b433f0b654d32530b0b48a7a653216ae0bb94d8James Dongstatic jint 2845a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_get_num_image_encoding_quality_levels(JNIEnv* /* env */, 2855a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe jobject /* thiz */, 2865a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe jint cameraId) 2879b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong{ 28871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_get_num_image_encoding_quality_levels"); 289075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) sProfiles->getImageEncodingQualityLevels(cameraId).size(); 2909b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong} 2919b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong 2929b433f0b654d32530b0b48a7a653216ae0bb94d8James Dongstatic jint 2935a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampeandroid_media_MediaProfiles_native_get_image_encoding_quality_level(JNIEnv *env, jobject /* thiz */, 2945a15d0d31b877ef512b3379eac033c6bb041c86aAndreas Gampe jint cameraId, jint index) 2959b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong{ 29671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("native_get_image_encoding_quality_level"); 29709b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang Vector<int> levels = sProfiles->getImageEncodingQualityLevels(cameraId); 298075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat if (index < 0 || index >= (jint) levels.size()) { 2999b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary"); 3009b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong return -1; 3019b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong } 3029b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong return static_cast<jint>(levels[index]); 3039b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong} 30476f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethodsForEncoderCapabilitiesClass[] = { 305c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong {"native_init", "()V", (void *)android_media_MediaProfiles_native_init}, 306c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong {"native_get_num_file_formats", "()I", (void *)android_media_MediaProfiles_native_get_num_file_formats}, 307c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong {"native_get_file_format", "(I)I", (void *)android_media_MediaProfiles_native_get_file_format}, 308c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong {"native_get_num_video_encoders", "()I", (void *)android_media_MediaProfiles_native_get_num_video_encoders}, 309c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong {"native_get_num_audio_encoders", "()I", (void *)android_media_MediaProfiles_native_get_num_audio_encoders}, 310c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 311c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong {"native_get_video_encoder_cap", "(I)Landroid/media/EncoderCapabilities$VideoEncoderCap;", 312c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong (void *)android_media_MediaProfiles_native_get_video_encoder_cap}, 313c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 314c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong {"native_get_audio_encoder_cap", "(I)Landroid/media/EncoderCapabilities$AudioEncoderCap;", 315c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong (void *)android_media_MediaProfiles_native_get_audio_encoder_cap}, 316c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong}; 317c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 31876f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethodsForCamcorderProfileClass[] = { 319e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong {"native_init", "()V", (void *)android_media_MediaProfiles_native_init}, 32009b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang {"native_get_camcorder_profile", "(II)Landroid/media/CamcorderProfile;", 321e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong (void *)android_media_MediaProfiles_native_get_camcorder_profile}, 3229d619542bea7d4c376a5a8b4a55c795a796adef3Nipun Kwatra {"native_has_camcorder_profile", "(II)Z", 3239d619542bea7d4c376a5a8b4a55c795a796adef3Nipun Kwatra (void *)android_media_MediaProfiles_native_has_camcorder_profile}, 324e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong}; 325e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong 32676f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethodsForDecoderCapabilitiesClass[] = { 327d32fba411f2710ad66681466674c8243f2ca3454James Dong {"native_init", "()V", (void *)android_media_MediaProfiles_native_init}, 328d32fba411f2710ad66681466674c8243f2ca3454James Dong {"native_get_num_video_decoders", "()I", (void *)android_media_MediaProfiles_native_get_num_video_decoders}, 329d32fba411f2710ad66681466674c8243f2ca3454James Dong {"native_get_num_audio_decoders", "()I", (void *)android_media_MediaProfiles_native_get_num_audio_decoders}, 330d32fba411f2710ad66681466674c8243f2ca3454James Dong {"native_get_video_decoder_type", "(I)I", (void *)android_media_MediaProfiles_native_get_video_decoder_type}, 331d32fba411f2710ad66681466674c8243f2ca3454James Dong {"native_get_audio_decoder_type", "(I)I", (void *)android_media_MediaProfiles_native_get_audio_decoder_type}, 332d32fba411f2710ad66681466674c8243f2ca3454James Dong}; 333d32fba411f2710ad66681466674c8243f2ca3454James Dong 33476f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethodsForCameraProfileClass[] = { 3359b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong {"native_init", "()V", (void *)android_media_MediaProfiles_native_init}, 3369b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong {"native_get_num_image_encoding_quality_levels", 33709b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang "(I)I", (void *)android_media_MediaProfiles_native_get_num_image_encoding_quality_levels}, 33809b9005769f2b717f637131578ce6cfa6bd62bd9Chih-Chung Chang {"native_get_image_encoding_quality_level","(II)I", (void *)android_media_MediaProfiles_native_get_image_encoding_quality_level}, 3399b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong}; 3409b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong 341e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dongstatic const char* const kEncoderCapabilitiesClassPathName = "android/media/EncoderCapabilities"; 342d32fba411f2710ad66681466674c8243f2ca3454James Dongstatic const char* const kDecoderCapabilitiesClassPathName = "android/media/DecoderCapabilities"; 343e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dongstatic const char* const kCamcorderProfileClassPathName = "android/media/CamcorderProfile"; 3449b433f0b654d32530b0b48a7a653216ae0bb94d8James Dongstatic const char* const kCameraProfileClassPathName = "android/media/CameraProfile"; 345c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong 346c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong// This function only registers the native methods, and is called from 347c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong// JNI_OnLoad in android_media_MediaPlayer.cpp 348c371194e4e0651c328f1870a90bbfd4e217c747bJames Dongint register_android_media_MediaProfiles(JNIEnv *env) 349c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong{ 350e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong int ret1 = AndroidRuntime::registerNativeMethods(env, 351e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong kEncoderCapabilitiesClassPathName, 352e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong gMethodsForEncoderCapabilitiesClass, 353e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong NELEM(gMethodsForEncoderCapabilitiesClass)); 354e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong 355e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong int ret2 = AndroidRuntime::registerNativeMethods(env, 356e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong kCamcorderProfileClassPathName, 357e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong gMethodsForCamcorderProfileClass, 358e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong NELEM(gMethodsForCamcorderProfileClass)); 359e7038ace44ed6e6cd27be35b003e6dd0412e936fJames Dong 360d32fba411f2710ad66681466674c8243f2ca3454James Dong int ret3 = AndroidRuntime::registerNativeMethods(env, 361d32fba411f2710ad66681466674c8243f2ca3454James Dong kDecoderCapabilitiesClassPathName, 362d32fba411f2710ad66681466674c8243f2ca3454James Dong gMethodsForDecoderCapabilitiesClass, 363d32fba411f2710ad66681466674c8243f2ca3454James Dong NELEM(gMethodsForDecoderCapabilitiesClass)); 364d32fba411f2710ad66681466674c8243f2ca3454James Dong 3659b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong int ret4 = AndroidRuntime::registerNativeMethods(env, 3669b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong kCameraProfileClassPathName, 3679b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong gMethodsForCameraProfileClass, 3689b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong NELEM(gMethodsForCameraProfileClass)); 3699b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong 3709b433f0b654d32530b0b48a7a653216ae0bb94d8James Dong // Success if all return values from above are 0 371e0e77cb5bb2885aea3da6823daebf40e06b073bdLajos Molnar return (ret1 || ret2 || ret3 || ret4); 372c371194e4e0651c328f1870a90bbfd4e217c747bJames Dong} 373