summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml30
-rw-r--r--include/media/MediaProfiles.h35
-rw-r--r--media/java/android/media/CamcorderProfile.java18
-rw-r--r--media/java/android/media/CameraProfile.java38
-rw-r--r--media/jni/android_media_MediaProfiles.cpp40
-rw-r--r--media/libmedia/MediaProfiles.cpp81
6 files changed, 179 insertions, 63 deletions
diff --git a/api/current.xml b/api/current.xml
index 9145462..5d71cad 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -87294,6 +87294,21 @@
<parameter name="quality" type="int">
</parameter>
</method>
+<method name="get"
+ return="android.media.CamcorderProfile"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="cameraId" type="int">
+</parameter>
+<parameter name="quality" type="int">
+</parameter>
+</method>
<field name="QUALITY_HIGH"
type="int"
transient="false"
@@ -87466,6 +87481,21 @@
<parameter name="quality" type="int">
</parameter>
</method>
+<method name="getJpegEncodingQualityParameter"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="cameraId" type="int">
+</parameter>
+<parameter name="quality" type="int">
+</parameter>
+</method>
<field name="QUALITY_HIGH"
type="int"
transient="false"
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index a4eea2a..c3cd361 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -48,8 +48,8 @@ public:
static MediaProfiles* getInstance();
/**
- * Returns the value for the given param name at the given quality level,
- * or -1 if error.
+ * Returns the value for the given param name for the given camera at
+ * the given quality level, or -1 if error.
*
* Supported param name are:
* duration - the recording duration.
@@ -64,7 +64,8 @@ public:
* aud.hz - audio sample rate
* aud.ch - number of audio channels
*/
- int getCamcorderProfileParamByName(const char *name, camcorder_quality quality) const;
+ int getCamcorderProfileParamByName(const char *name, int cameraId,
+ camcorder_quality quality) const;
/**
* Returns the output file formats supported.
@@ -124,12 +125,7 @@ public:
/**
* 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;
+ Vector<int> getImageEncodingQualityLevels(int cameraId) const;
private:
MediaProfiles& operator=(const MediaProfiles&); // Don't call me
@@ -171,7 +167,8 @@ private:
struct CamcorderProfile {
CamcorderProfile()
- : mFileFormat(OUTPUT_FORMAT_THREE_GPP),
+ : mCameraId(0),
+ mFileFormat(OUTPUT_FORMAT_THREE_GPP),
mQuality(CAMCORDER_QUALITY_HIGH),
mDuration(0),
mVideoCodec(0),
@@ -182,6 +179,7 @@ private:
delete mAudioCodec;
}
+ int mCameraId;
output_format mFileFormat;
camcorder_quality mQuality;
int mDuration;
@@ -249,6 +247,11 @@ private:
int tag;
};
+ struct ImageEncodingQualityLevels {
+ int mCameraId;
+ Vector<int> mLevels;
+ };
+
// Debug
static void logVideoCodec(const VideoCodec& codec);
static void logAudioCodec(const AudioCodec& codec);
@@ -267,9 +270,11 @@ private:
static VideoDecoderCap* createVideoDecoderCap(const char **atts);
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);
+ static CamcorderProfile* createCamcorderProfile(int cameraId, const char **atts);
+ static int getCameraId(const char **atts);
+
+ ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const;
+ void addImageEncodingQualityLevel(int cameraId, const char** atts);
// Customized element tag handler for parsing the xml configuration file.
static void startElementHandler(void *userData, const char *name, const char **atts);
@@ -303,6 +308,7 @@ private:
static bool sIsInitialized;
static MediaProfiles *sInstance;
static Mutex sLock;
+ int mCurrentCameraId;
Vector<CamcorderProfile*> mCamcorderProfiles;
Vector<AudioEncoderCap*> mAudioEncoders;
@@ -310,8 +316,7 @@ private:
Vector<AudioDecoderCap*> mAudioDecoders;
Vector<VideoDecoderCap*> mVideoDecoders;
Vector<output_format> mEncoderOutputFileFormats;
- Vector<int> mImageEncodingQualityLevels;
- int mImageDecodingMaxMemory;
+ Vector<ImageEncodingQualityLevels *> mImageEncodingQualityLevels;
};
}; // namespace android
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()