diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/java/android/media/CamcorderProfile.java | 18 | ||||
-rw-r--r-- | media/java/android/media/CameraProfile.java | 38 | ||||
-rw-r--r-- | media/jni/android_media_MediaProfiles.cpp | 40 | ||||
-rw-r--r-- | media/libmedia/MediaProfiles.cpp | 81 |
4 files changed, 129 insertions, 48 deletions
diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java index 64d6460..a27df57 100644 --- a/media/java/android/media/CamcorderProfile.java +++ b/media/java/android/media/CamcorderProfile.java @@ -119,15 +119,26 @@ public class CamcorderProfile public int audioChannels; /** - * Returns the camcorder profile for the given quality level. + * Returns the camcorder profile for the default camera at the given + * quality level. * @param quality the target quality level for the camcorder profile */ public static CamcorderProfile get(int quality) { + return get(0, quality); + } + + /** + * Returns the camcorder profile for the given camera at the given + * quality level. + * @param cameraId the id for the camera + * @param quality the target quality level for the camcorder profile + */ + public static CamcorderProfile get(int cameraId, int quality) { if (quality < QUALITY_LOW || quality > QUALITY_HIGH) { String errMessage = "Unsupported quality level: " + quality; throw new IllegalArgumentException(errMessage); } - return native_get_camcorder_profile(quality); + return native_get_camcorder_profile(cameraId, quality); } static { @@ -165,5 +176,6 @@ public class CamcorderProfile // Methods implemented by JNI private static native final void native_init(); - private static native final CamcorderProfile native_get_camcorder_profile(int quality); + private static native final CamcorderProfile native_get_camcorder_profile( + int cameraId, int quality); } diff --git a/media/java/android/media/CameraProfile.java b/media/java/android/media/CameraProfile.java index f8d3935..6a0be08 100644 --- a/media/java/android/media/CameraProfile.java +++ b/media/java/android/media/CameraProfile.java @@ -17,6 +17,7 @@ package android.media; import java.util.Arrays; +import java.util.HashMap; /** * The CameraProfile class is used to retrieve the pre-defined still image @@ -40,36 +41,55 @@ public class CameraProfile /* * Cache the Jpeg encoding quality parameters */ - private static final int[] sJpegEncodingQualityParameters; + private static final HashMap<Integer, int[]> sCache = new HashMap<Integer, int[]>(); /** * Returns a pre-defined still image capture (jpeg) quality level - * used for the given quality level in the Camera application. + * used for the given quality level in the Camera application for + * the default camera. * * @param quality The target quality level */ public static int getJpegEncodingQualityParameter(int quality) { + return getJpegEncodingQualityParameter(0, quality); + } + + /** + * Returns a pre-defined still image capture (jpeg) quality level + * used for the given quality level in the Camera application for + * the specified camera. + * + * @param cameraId The id of the camera + * @param quality The target quality level + */ + public static int getJpegEncodingQualityParameter(int cameraId, int quality) { if (quality < QUALITY_LOW || quality > QUALITY_HIGH) { throw new IllegalArgumentException("Unsupported quality level: " + quality); } - return sJpegEncodingQualityParameters[quality]; + synchronized (sCache) { + int[] levels = sCache.get(cameraId); + if (levels == null) { + levels = getImageEncodingQualityLevels(cameraId); + sCache.put(cameraId, levels); + } + return levels[quality]; + } } static { System.loadLibrary("media_jni"); native_init(); - sJpegEncodingQualityParameters = getImageEncodingQualityLevels(); } - private static int[] getImageEncodingQualityLevels() { - int nLevels = native_get_num_image_encoding_quality_levels(); + private static int[] getImageEncodingQualityLevels(int cameraId) { + int nLevels = native_get_num_image_encoding_quality_levels(cameraId); if (nLevels != QUALITY_HIGH + 1) { throw new RuntimeException("Unexpected Jpeg encoding quality levels " + nLevels); } int[] levels = new int[nLevels]; for (int i = 0; i < nLevels; ++i) { - levels[i] = native_get_image_encoding_quality_level(i); + levels[i] = native_get_image_encoding_quality_level(cameraId, i); } Arrays.sort(levels); // Lower quality level ALWAYS comes before higher one return levels; @@ -77,6 +97,6 @@ public class CameraProfile // Methods implemented by JNI private static native final void native_init(); - private static native final int native_get_num_image_encoding_quality_levels(); - private static native final int native_get_image_encoding_quality_level(int index); + private static native final int native_get_num_image_encoding_quality_levels(int cameraId); + private static native final int native_get_image_encoding_quality_level(int cameraId, int index); } diff --git a/media/jni/android_media_MediaProfiles.cpp b/media/jni/android_media_MediaProfiles.cpp index 7d7533a..cce9fd0 100644 --- a/media/jni/android_media_MediaProfiles.cpp +++ b/media/jni/android_media_MediaProfiles.cpp @@ -162,26 +162,26 @@ android_media_MediaProfiles_native_get_audio_encoder_cap(JNIEnv *env, jobject th } static jobject -android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject thiz, jint quality) +android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject thiz, jint id, jint quality) { - LOGV("native_get_camcorder_profile: %d", quality); + LOGV("native_get_camcorder_profile: %d %d", id, quality); if (quality != CAMCORDER_QUALITY_HIGH && quality != CAMCORDER_QUALITY_LOW) { jniThrowException(env, "java/lang/RuntimeException", "Unknown camcorder profile quality"); return NULL; } camcorder_quality q = static_cast<camcorder_quality>(quality); - int duration = sProfiles->getCamcorderProfileParamByName("duration", q); - int fileFormat = sProfiles->getCamcorderProfileParamByName("file.format", q); - int videoCodec = sProfiles->getCamcorderProfileParamByName("vid.codec", q); - int videoBitRate = sProfiles->getCamcorderProfileParamByName("vid.bps", q); - int videoFrameRate = sProfiles->getCamcorderProfileParamByName("vid.fps", q); - int videoFrameWidth = sProfiles->getCamcorderProfileParamByName("vid.width", q); - int videoFrameHeight = sProfiles->getCamcorderProfileParamByName("vid.height", q); - int audioCodec = sProfiles->getCamcorderProfileParamByName("aud.codec", q); - int audioBitRate = sProfiles->getCamcorderProfileParamByName("aud.bps", q); - int audioSampleRate = sProfiles->getCamcorderProfileParamByName("aud.hz", q); - int audioChannels = sProfiles->getCamcorderProfileParamByName("aud.ch", q); + 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 || @@ -253,17 +253,17 @@ android_media_MediaProfiles_native_get_audio_decoder_type(JNIEnv *env, jobject t } static jint -android_media_MediaProfiles_native_get_num_image_encoding_quality_levels(JNIEnv *env, jobject thiz) +android_media_MediaProfiles_native_get_num_image_encoding_quality_levels(JNIEnv *env, jobject thiz, jint cameraId) { LOGV("native_get_num_image_encoding_quality_levels"); - return sProfiles->getImageEncodingQualityLevels().size(); + return sProfiles->getImageEncodingQualityLevels(cameraId).size(); } static jint -android_media_MediaProfiles_native_get_image_encoding_quality_level(JNIEnv *env, jobject thiz, jint index) +android_media_MediaProfiles_native_get_image_encoding_quality_level(JNIEnv *env, jobject thiz, jint cameraId, jint index) { LOGV("native_get_image_encoding_quality_level"); - Vector<int> levels = sProfiles->getImageEncodingQualityLevels(); + Vector<int> levels = sProfiles->getImageEncodingQualityLevels(cameraId); if (index < 0 || index >= levels.size()) { jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary"); return -1; @@ -287,7 +287,7 @@ static JNINativeMethod gMethodsForEncoderCapabilitiesClass[] = { static JNINativeMethod gMethodsForCamcorderProfileClass[] = { {"native_init", "()V", (void *)android_media_MediaProfiles_native_init}, - {"native_get_camcorder_profile", "(I)Landroid/media/CamcorderProfile;", + {"native_get_camcorder_profile", "(II)Landroid/media/CamcorderProfile;", (void *)android_media_MediaProfiles_native_get_camcorder_profile}, }; @@ -302,8 +302,8 @@ static JNINativeMethod gMethodsForDecoderCapabilitiesClass[] = { static JNINativeMethod gMethodsForCameraProfileClass[] = { {"native_init", "()V", (void *)android_media_MediaProfiles_native_init}, {"native_get_num_image_encoding_quality_levels", - "()I", (void *)android_media_MediaProfiles_native_get_num_image_encoding_quality_levels}, - {"native_get_image_encoding_quality_level","(I)I", (void *)android_media_MediaProfiles_native_get_image_encoding_quality_level}, + "(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"; diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp index 1263373..3869389 100644 --- a/media/libmedia/MediaProfiles.cpp +++ b/media/libmedia/MediaProfiles.cpp @@ -272,7 +272,7 @@ MediaProfiles::createEncoderOutputFileFormat(const char **atts) } /*static*/ MediaProfiles::CamcorderProfile* -MediaProfiles::createCamcorderProfile(const char **atts) +MediaProfiles::createCamcorderProfile(int cameraId, const char **atts) { CHECK(!strcmp("quality", atts[0]) && !strcmp("fileFormat", atts[2]) && @@ -287,16 +287,47 @@ MediaProfiles::createCamcorderProfile(const char **atts) CHECK(fileFormat != -1); MediaProfiles::CamcorderProfile *profile = new MediaProfiles::CamcorderProfile; + profile->mCameraId = cameraId; profile->mFileFormat = static_cast<output_format>(fileFormat); profile->mQuality = static_cast<camcorder_quality>(quality); profile->mDuration = atoi(atts[5]); return profile; } -/*static*/ int -MediaProfiles::getImageEncodingQualityLevel(const char** atts) +MediaProfiles::ImageEncodingQualityLevels* +MediaProfiles::findImageEncodingQualityLevels(int cameraId) const +{ + int n = mImageEncodingQualityLevels.size(); + for (int i = 0; i < n; i++) { + ImageEncodingQualityLevels *levels = mImageEncodingQualityLevels[i]; + if (levels->mCameraId == cameraId) { + return levels; + } + } + return NULL; +} + +void MediaProfiles::addImageEncodingQualityLevel(int cameraId, const char** atts) { CHECK(!strcmp("quality", atts[0])); + int quality = atoi(atts[1]); + LOGV("%s: cameraId=%d, quality=%d\n", __func__, cameraId, quality); + ImageEncodingQualityLevels *levels = findImageEncodingQualityLevels(cameraId); + + if (levels == NULL) { + levels = new ImageEncodingQualityLevels(); + levels->mCameraId = cameraId; + mImageEncodingQualityLevels.add(levels); + } + + levels->mLevels.add(quality); +} + +/*static*/ int +MediaProfiles::getCameraId(const char** atts) +{ + if (!atts[0]) return 0; // default cameraId = 0 + CHECK(!strcmp("cameraId", atts[0])); return atoi(atts[1]); } @@ -322,10 +353,13 @@ MediaProfiles::startElementHandler(void *userData, const char *name, const char profiles->mAudioDecoders.add(createAudioDecoderCap(atts)); } else if (strcmp("EncoderOutputFileFormat", name) == 0) { profiles->mEncoderOutputFileFormats.add(createEncoderOutputFileFormat(atts)); + } else if (strcmp("CamcorderProfiles", name) == 0) { + profiles->mCurrentCameraId = getCameraId(atts); } else if (strcmp("EncoderProfile", name) == 0) { - profiles->mCamcorderProfiles.add(createCamcorderProfile(atts)); + profiles->mCamcorderProfiles.add( + createCamcorderProfile(profiles->mCurrentCameraId, atts)); } else if (strcmp("ImageEncoding", name) == 0) { - profiles->mImageEncodingQualityLevels.add(getImageEncodingQualityLevel(atts)); + profiles->addImageEncodingQualityLevel(profiles->mCurrentCameraId, atts); } } @@ -383,7 +417,8 @@ MediaProfiles::createDefaultCamcorderHighProfile() new MediaProfiles::VideoCodec(VIDEO_ENCODER_H263, 360000, 352, 288, 20); AudioCodec *audioCodec = new AudioCodec(AUDIO_ENCODER_AMR_NB, 12200, 8000, 1); - CamcorderProfile *profile = new CamcorderProfile; + CamcorderProfile *profile = new MediaProfiles::CamcorderProfile; + profile->mCameraId = 0; profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP; profile->mQuality = CAMCORDER_QUALITY_HIGH; profile->mDuration = 60; @@ -402,6 +437,7 @@ MediaProfiles::createDefaultCamcorderLowProfile() new MediaProfiles::AudioCodec(AUDIO_ENCODER_AMR_NB, 12200, 8000, 1); MediaProfiles::CamcorderProfile *profile = new MediaProfiles::CamcorderProfile; + profile->mCameraId = 0; profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP; profile->mQuality = CAMCORDER_QUALITY_LOW; profile->mDuration = 30; @@ -458,9 +494,12 @@ MediaProfiles::createDefaultAmrNBEncoderCap() /*static*/ void MediaProfiles::createDefaultImageEncodingQualityLevels(MediaProfiles *profiles) { - profiles->mImageEncodingQualityLevels.add(70); - profiles->mImageEncodingQualityLevels.add(80); - profiles->mImageEncodingQualityLevels.add(90); + ImageEncodingQualityLevels *levels = new ImageEncodingQualityLevels(); + levels->mCameraId = 0; + levels->mLevels.add(70); + levels->mLevels.add(80); + levels->mLevels.add(90); + profiles->mImageEncodingQualityLevels.add(levels); } /*static*/ MediaProfiles* @@ -629,19 +668,24 @@ Vector<audio_decoder> MediaProfiles::getAudioDecoders() const return decoders; // copy out } -int MediaProfiles::getCamcorderProfileParamByName(const char *name, camcorder_quality quality) const +int MediaProfiles::getCamcorderProfileParamByName(const char *name, + int cameraId, + camcorder_quality quality) const { - LOGV("getCamcorderProfileParamByName: %s for quality %d", name, quality); + LOGV("getCamcorderProfileParamByName: %s for camera %d, quality %d", + name, cameraId, quality); int index = -1; for (size_t i = 0, n = mCamcorderProfiles.size(); i < n; ++i) { - if (mCamcorderProfiles[i]->mQuality == quality) { + if (mCamcorderProfiles[i]->mCameraId == cameraId && + mCamcorderProfiles[i]->mQuality == quality) { index = i; break; } } if (index == -1) { - LOGE("The given camcorder profile quality %d is not found", quality); + LOGE("The given camcorder profile camera %d quality %d is not found", + cameraId, quality); return -1; } @@ -657,13 +701,18 @@ int MediaProfiles::getCamcorderProfileParamByName(const char *name, camcorder_qu if (!strcmp("aud.ch", name)) return mCamcorderProfiles[index]->mAudioCodec->mChannels; if (!strcmp("aud.hz", name)) return mCamcorderProfiles[index]->mAudioCodec->mSampleRate; - LOGE("The given camcorder profile param name %s is not found", name); + LOGE("The given camcorder profile param id %d name %s is not found", cameraId, name); return -1; } -Vector<int> MediaProfiles::getImageEncodingQualityLevels() const +Vector<int> MediaProfiles::getImageEncodingQualityLevels(int cameraId) const { - return mImageEncodingQualityLevels; // copy out + Vector<int> result; + ImageEncodingQualityLevels *levels = findImageEncodingQualityLevels(cameraId); + if (levels != NULL) { + result = levels->mLevels; // copy out + } + return result; } MediaProfiles::~MediaProfiles() |