diff options
| -rw-r--r-- | include/media/MediaProfiles.h | 17 | ||||
| -rw-r--r-- | media/java/android/media/CamcorderProfile.java | 13 | ||||
| -rw-r--r-- | media/java/android/media/CameraProfile.java | 52 | ||||
| -rw-r--r-- | media/jni/android_media_MediaProfiles.cpp | 42 | ||||
| -rw-r--r-- | media/libmedia/MediaProfiles.cpp | 24 |
5 files changed, 143 insertions, 5 deletions
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h index 3f253f9..eb96d20 100644 --- a/include/media/MediaProfiles.h +++ b/include/media/MediaProfiles.h @@ -52,6 +52,7 @@ public: * or -1 if error. * * Supported param name are: + * duration - the recording duration. * file.format - output file format. see mediarecorder.h for details * vid.codec - video encoder. see mediarecorder.h for details. * aud.codec - audio encoder. see mediarecorder.h for details. @@ -120,6 +121,16 @@ public: */ Vector<audio_decoder> getAudioDecoders() const; + /** + * Returns the number of image encoding quality levels supported. + */ + Vector<int> getImageEncodingQualityLevels() const; + + /** + * Returns the maximum amount of memory in bytes we can use for decoding a JPEG file. + */ + int getImageDecodingMaxMemory() const; + private: MediaProfiles& operator=(const MediaProfiles&); // Don't call me MediaProfiles(const MediaProfiles&); // Don't call me @@ -257,6 +268,8 @@ private: static VideoEncoderCap* createVideoEncoderCap(const char **atts); static AudioEncoderCap* createAudioEncoderCap(const char **atts); static CamcorderProfile* createCamcorderProfile(const char **atts); + static int getImageEncodingQualityLevel(const char **atts); + static int getImageDecodingMaxMemory(const char **atts); // Customized element tag handler for parsing the xml configuration file. static void startElementHandler(void *userData, const char *name, const char **atts); @@ -271,6 +284,8 @@ private: static void createDefaultVideoDecoders(MediaProfiles *profiles); static void createDefaultAudioDecoders(MediaProfiles *profiles); static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles); + static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles); + static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles); static VideoEncoderCap* createDefaultH263VideoEncoderCap(); static VideoEncoderCap* createDefaultM4vVideoEncoderCap(); static AudioEncoderCap* createDefaultAmrNBEncoderCap(); @@ -295,6 +310,8 @@ private: Vector<AudioDecoderCap*> mAudioDecoders; Vector<VideoDecoderCap*> mVideoDecoders; Vector<output_format> mEncoderOutputFileFormats; + Vector<int> mImageEncodingQualityLevels; + int mImageDecodingMaxMemory; }; }; // namespace android diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java index ce56443..eade680 100644 --- a/media/java/android/media/CamcorderProfile.java +++ b/media/java/android/media/CamcorderProfile.java @@ -38,6 +38,7 @@ package android.media; */ public class CamcorderProfile { + private final int mDuration; // Recording duration in seconds /** * The Quality class represents the quality level of each CamcorderProfile. @@ -56,6 +57,14 @@ public class CamcorderProfile }; /** + * Returns the recording duration in seconds for LOW quality CamcorderProfile + * used by the MMS application. + */ + public static final int getMmsRecordingDurationInSeconds() { + return get(Quality.LOW).mDuration; + } + + /** * The quality level of the camcorder profile * @see android.media.CamcorderProfile.Quality */ @@ -129,7 +138,8 @@ public class CamcorderProfile } // Private constructor called by JNI - private CamcorderProfile(int quality, + private CamcorderProfile(int duration, + int quality, int fileFormat, int videoCodec, int videoBitRate, @@ -141,6 +151,7 @@ public class CamcorderProfile int audioSampleRate, int audioChannels) { + mDuration = duration; mQuality = Quality.values()[quality]; mFileFormat = fileFormat; mVideoCodec = videoCodec; diff --git a/media/java/android/media/CameraProfile.java b/media/java/android/media/CameraProfile.java new file mode 100644 index 0000000..9685e7e --- /dev/null +++ b/media/java/android/media/CameraProfile.java @@ -0,0 +1,52 @@ +/* + * 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. + */ + +package android.media; + +/** + * The CameraProfile class is used to retrieve the pre-defined still image + * capture (jpeg) quality levels (0-100) used for low, medium, and high + * quality settings in the Camera application. + * + * {@hide} + */ +public class CameraProfile +{ + /** + * Returns a list of the pre-defined still image capture (jpeg) quality levels + * used for low, medium and high quality settings in the Camera application. + */ + public static int[] getImageEncodingQualityLevels() { + int nLevels = native_get_num_image_encoding_quality_levels(); + if (nLevels == 0) return null; + + int[] levels = new int[nLevels]; + for (int i = 0; i < nLevels; ++i) { + levels[i] = native_get_image_encoding_quality_level(i); + } + return levels; + } + + static { + System.loadLibrary("media_jni"); + native_init(); + } + + // 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); +} diff --git a/media/jni/android_media_MediaProfiles.cpp b/media/jni/android_media_MediaProfiles.cpp index 19132c5..7d7533a 100644 --- a/media/jni/android_media_MediaProfiles.cpp +++ b/media/jni/android_media_MediaProfiles.cpp @@ -171,6 +171,7 @@ android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject th } 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); @@ -183,7 +184,7 @@ android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject th int audioChannels = sProfiles->getCamcorderProfileParamByName("aud.ch", q); // Check on the values retrieved - if (fileFormat == -1 || videoCodec == -1 || audioCodec == -1 || + if (duration == -1 || fileFormat == -1 || videoCodec == -1 || audioCodec == -1 || videoBitRate == -1 || videoFrameRate == -1 || videoFrameWidth == -1 || videoFrameHeight == -1 || audioBitRate == -1 || audioSampleRate == -1 || audioChannels == -1) { @@ -192,9 +193,10 @@ android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject th } jclass camcorderProfileClazz = env->FindClass("android/media/CamcorderProfile"); - jmethodID camcorderProfileConstructorMethodID = env->GetMethodID(camcorderProfileClazz, "<init>", "(IIIIIIIIIII)V"); + jmethodID camcorderProfileConstructorMethodID = env->GetMethodID(camcorderProfileClazz, "<init>", "(IIIIIIIIIIII)V"); return env->NewObject(camcorderProfileClazz, camcorderProfileConstructorMethodID, + duration, quality, fileFormat, videoCodec, @@ -250,6 +252,25 @@ android_media_MediaProfiles_native_get_audio_decoder_type(JNIEnv *env, jobject t return static_cast<jint>(decoders[index]); } +static jint +android_media_MediaProfiles_native_get_num_image_encoding_quality_levels(JNIEnv *env, jobject thiz) +{ + LOGV("native_get_num_image_encoding_quality_levels"); + return sProfiles->getImageEncodingQualityLevels().size(); +} + +static jint +android_media_MediaProfiles_native_get_image_encoding_quality_level(JNIEnv *env, jobject thiz, jint index) +{ + LOGV("native_get_image_encoding_quality_level"); + Vector<int> levels = sProfiles->getImageEncodingQualityLevels(); + if (index < 0 || index >= levels.size()) { + jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary"); + return -1; + } + return static_cast<jint>(levels[index]); +} + static 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}, @@ -278,9 +299,17 @@ static JNINativeMethod gMethodsForDecoderCapabilitiesClass[] = { {"native_get_audio_decoder_type", "(I)I", (void *)android_media_MediaProfiles_native_get_audio_decoder_type}, }; +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}, +}; + 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 @@ -301,6 +330,11 @@ int register_android_media_MediaProfiles(JNIEnv *env) gMethodsForDecoderCapabilitiesClass, NELEM(gMethodsForDecoderCapabilitiesClass)); - // Success if ret1 == 0 && ret2 == 0 && ret3 == 0 - return (ret1 || ret2 || ret3); + int ret4 = AndroidRuntime::registerNativeMethods(env, + kCameraProfileClassPathName, + gMethodsForCameraProfileClass, + NELEM(gMethodsForCameraProfileClass)); + + // Success if all return values from above are 0 + return (ret1 || ret2 || ret3 || ret4); } diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp index 0efade1..1263373 100644 --- a/media/libmedia/MediaProfiles.cpp +++ b/media/libmedia/MediaProfiles.cpp @@ -293,6 +293,13 @@ MediaProfiles::createCamcorderProfile(const char **atts) return profile; } +/*static*/ int +MediaProfiles::getImageEncodingQualityLevel(const char** atts) +{ + CHECK(!strcmp("quality", atts[0])); + return atoi(atts[1]); +} + /*static*/ void MediaProfiles::startElementHandler(void *userData, const char *name, const char **atts) { @@ -317,6 +324,8 @@ MediaProfiles::startElementHandler(void *userData, const char *name, const char profiles->mEncoderOutputFileFormats.add(createEncoderOutputFileFormat(atts)); } else if (strcmp("EncoderProfile", name) == 0) { profiles->mCamcorderProfiles.add(createCamcorderProfile(atts)); + } else if (strcmp("ImageEncoding", name) == 0) { + profiles->mImageEncodingQualityLevels.add(getImageEncodingQualityLevel(atts)); } } @@ -446,6 +455,14 @@ MediaProfiles::createDefaultAmrNBEncoderCap() AUDIO_ENCODER_AMR_NB, 5525, 12200, 8000, 8000, 1, 1); } +/*static*/ void +MediaProfiles::createDefaultImageEncodingQualityLevels(MediaProfiles *profiles) +{ + profiles->mImageEncodingQualityLevels.add(70); + profiles->mImageEncodingQualityLevels.add(80); + profiles->mImageEncodingQualityLevels.add(90); +} + /*static*/ MediaProfiles* MediaProfiles::createDefaultInstance() { @@ -456,6 +473,7 @@ MediaProfiles::createDefaultInstance() createDefaultVideoDecoders(profiles); createDefaultAudioDecoders(profiles); createDefaultEncoderOutputFileFormats(profiles); + createDefaultImageEncodingQualityLevels(profiles); sIsInitialized = true; return profiles; } @@ -627,6 +645,7 @@ int MediaProfiles::getCamcorderProfileParamByName(const char *name, camcorder_qu return -1; } + if (!strcmp("duration", name)) return mCamcorderProfiles[index]->mDuration; if (!strcmp("file.format", name)) return mCamcorderProfiles[index]->mFileFormat; if (!strcmp("vid.codec", name)) return mCamcorderProfiles[index]->mVideoCodec->mCodec; if (!strcmp("vid.width", name)) return mCamcorderProfiles[index]->mVideoCodec->mFrameWidth; @@ -642,6 +661,11 @@ int MediaProfiles::getCamcorderProfileParamByName(const char *name, camcorder_qu return -1; } +Vector<int> MediaProfiles::getImageEncodingQualityLevels() const +{ + return mImageEncodingQualityLevels; // copy out +} + MediaProfiles::~MediaProfiles() { CHECK("destructor should never be called" == 0); |
