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