Merge "Camcorder profile Java API support - Use Enum for Quality instead of int - Use static values() method from Enum, rather than if-else"
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index be928ec..3f253f9 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -53,8 +53,8 @@
      *
      * Supported param name are:
      * file.format - output file format. see mediarecorder.h for details
-     * codec.vid - video encoder. see mediarecorder.h for details.
-     * codec.aud - audio encoder. see mediarecorder.h for details.
+     * vid.codec - video encoder. see mediarecorder.h for details.
+     * aud.codec - audio encoder. see mediarecorder.h for details.
      * vid.width - video frame width
      * vid.height - video frame height
      * vid.fps - video frame rate
diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java
new file mode 100644
index 0000000..ce56443
--- /dev/null
+++ b/media/java/android/media/CamcorderProfile.java
@@ -0,0 +1,160 @@
+/*
+ * 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 CamcorderProfile class is used to retrieve the
+ * predefined camcorder profile settings for camcorder applications.
+ * The compressed output from a recording session with a given
+ * CamcorderProfile contains two tracks: one for auido and one for video.
+ *
+ * <p>Each profile specifies the following set of parameters:
+ * <ul>
+ * <li> The file output format, @see android.media.MediaRecorder.OutputFormat
+ * <li> Video codec format, @see android.media.MediaRecorder.VideoEncoder
+ * <li> Video bit rate in bits per second
+ * <li> Video frame rate in frames per second
+ * <li> Video frame width and height,
+ * <li> Audio codec format, @see android.media.MediaRecorder.AudioEncoder
+ * <li> Audio bit rate in bits per second,
+ * <li> Audio sample rate
+ * <li> Number of audio channels for recording.
+ * </ul>
+ * {@hide}
+ */
+public class CamcorderProfile
+{
+
+    /**
+     * The Quality class represents the quality level of each CamcorderProfile.
+     *
+     * The output from recording sessions with high quality level usually may have
+     * larger output bit rate, better video and/or audio recording quality, and
+     * laerger video frame resolution and higher audio sampling rate, etc, than those
+     * with low quality level.
+     */
+    public enum Quality {
+       /* Do not change these values/ordinals without updating their counterpart
+        * in include/media/MediaProfiles.h!
+        */
+        HIGH,
+        LOW
+    };
+
+    /**
+     * The quality level of the camcorder profile
+     * @see android.media.CamcorderProfile.Quality
+     */
+    public final Quality mQuality;
+
+    /**
+     * The file output format of the camcorder profile
+     * @see android.media.MediaRecorder.OutputFormat
+     */
+    public final int mFileFormat;
+
+    /**
+     * The video encoder being used for the video track
+     * @see android.media.MediaRecorder.VideoEncoder
+     */
+    public final int mVideoCodec;
+
+    /**
+     * The target video output bit rate in bits per second
+     */
+    public final int mVideoBitRate;
+
+    /**
+     * The target video frame rate in frames per second
+     */
+    public final int mVideoFrameRate;
+
+    /**
+     * The target video frame width in pixels
+     */
+    public final int mVideoFrameWidth;
+
+    /**
+     * The target video frame height in pixels
+     */
+    public final int mVideoFrameHeight;
+
+    /**
+     * The audio encoder being used for the audio track.
+     * @see android.media.MediaRecorder.AudioEncoder
+     */
+    public final int mAudioCodec;
+
+    /**
+     * The target audio output bit rate in bits per second
+     */
+    public final int mAudioBitRate;
+
+    /**
+     * The audio sampling rate used for the audio track
+     */
+    public final int mAudioSampleRate;
+
+    /**
+     * The number of audio channels used for the audio track
+     */
+    public final int mAudioChannels;
+
+    /**
+     * Returns the camcorder profile for the given quality.
+     * @param quality the target quality level for the camcorder profile
+     * @see android.media.CamcorderProfile.Quality
+     */
+    public static CamcorderProfile get(Quality quality) {
+        return native_get_camcorder_profile(quality.ordinal());
+    }
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    // Private constructor called by JNI
+    private CamcorderProfile(int quality,
+                             int fileFormat,
+                             int videoCodec,
+                             int videoBitRate,
+                             int videoFrameRate,
+                             int videoWidth,
+                             int videoHeight,
+                             int audioCodec,
+                             int audioBitRate,
+                             int audioSampleRate,
+                             int audioChannels) {
+
+        mQuality          = Quality.values()[quality];
+        mFileFormat       = fileFormat;
+        mVideoCodec       = videoCodec;
+        mVideoBitRate     = videoBitRate;
+        mVideoFrameRate   = videoFrameRate;
+        mVideoFrameWidth  = videoWidth;
+        mVideoFrameHeight = videoHeight;
+        mAudioCodec       = audioCodec;
+        mAudioBitRate     = audioBitRate;
+        mAudioSampleRate  = audioSampleRate;
+        mAudioChannels    = audioChannels;
+    }
+
+    // Methods implemented by JNI
+    private static native final void native_init();
+    private static native final CamcorderProfile native_get_camcorder_profile(int quality);
+}
diff --git a/media/jni/android_media_MediaProfiles.cpp b/media/jni/android_media_MediaProfiles.cpp
index cd3ad88..50380c1 100644
--- a/media/jni/android_media_MediaProfiles.cpp
+++ b/media/jni/android_media_MediaProfiles.cpp
@@ -162,7 +162,54 @@
     return cap;
 }
 
-static JNINativeMethod gMethods[] = {
+static jobject
+android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject thiz, jint quality)
+{
+    LOGV("native_get_camcorder_profile: %d", 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 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);
+
+    // Check on the values retrieved
+    if (fileFormat == -1 || videoCodec == -1 || audioCodec == -1 ||
+        videoBitRate == -1 || videoFrameRate == -1 || videoFrameWidth == -1 || videoFrameHeight == -1 ||
+        audioBitRate == -1 || audioSampleRate == -1 || audioChannels == -1) {
+
+        jniThrowException(env, "java/lang/RuntimeException", "Error retrieving camcorder profile params");
+        return NULL;
+    }
+
+    jclass camcorderProfileClazz = env->FindClass("android/media/CamcorderProfile");
+    jmethodID camcorderProfileConstructorMethodID = env->GetMethodID(camcorderProfileClazz, "<init>", "(IIIIIIIIIII)V");
+    return env->NewObject(camcorderProfileClazz,
+                          camcorderProfileConstructorMethodID,
+                          quality,
+                          fileFormat,
+                          videoCodec,
+                          videoBitRate,
+                          videoFrameRate,
+                          videoFrameWidth,
+                          videoFrameHeight,
+                          audioCodec,
+                          audioBitRate,
+                          audioSampleRate,
+                          audioChannels);
+}
+
+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},
     {"native_get_file_format",                 "(I)I",                   (void *)android_media_MediaProfiles_native_get_file_format},
@@ -176,12 +223,29 @@
                                                                          (void *)android_media_MediaProfiles_native_get_audio_encoder_cap},
 };
 
-static const char* const kClassPathName = "android/media/MediaProfiles";
+static JNINativeMethod gMethodsForCamcorderProfileClass[] = {
+    {"native_init",                            "()V",                    (void *)android_media_MediaProfiles_native_init},
+    {"native_get_camcorder_profile",           "(I)Landroid/media/CamcorderProfile;",
+                                                                         (void *)android_media_MediaProfiles_native_get_camcorder_profile},
+};
+
+static const char* const kEncoderCapabilitiesClassPathName = "android/media/EncoderCapabilities";
+static const char* const kCamcorderProfileClassPathName = "android/media/CamcorderProfile";
 
 // This function only registers the native methods, and is called from
 // JNI_OnLoad in android_media_MediaPlayer.cpp
 int register_android_media_MediaProfiles(JNIEnv *env)
 {
-    return AndroidRuntime::registerNativeMethods(env,
-                "android/media/EncoderCapabilities", gMethods, NELEM(gMethods));
+    int ret1 = AndroidRuntime::registerNativeMethods(env,
+               kEncoderCapabilitiesClassPathName,
+               gMethodsForEncoderCapabilitiesClass,
+               NELEM(gMethodsForEncoderCapabilitiesClass));
+
+    int ret2 = AndroidRuntime::registerNativeMethods(env,
+               kCamcorderProfileClassPathName,
+               gMethodsForCamcorderProfileClass,
+               NELEM(gMethodsForCamcorderProfileClass));
+
+    // Success if ret1 == 0 && ret2 == 0
+    return (ret1 || ret2);
 }