diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
new file mode 100644
index 0000000..be928ec
--- /dev/null
+++ b/include/media/MediaProfiles.h
@@ -0,0 +1,303 @@
+/*
+ **
+ ** Copyright 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.
+ */
+
+#ifndef ANDROID_MEDIAPROFILES_H
+#define ANDROID_MEDIAPROFILES_H
+
+#include <utils/threads.h>
+#include <media/mediarecorder.h>
+
+namespace android {
+
+enum camcorder_quality {
+    CAMCORDER_QUALITY_HIGH = 0,
+    CAMCORDER_QUALITY_LOW  = 1
+};
+
+enum video_decoder {
+    VIDEO_DECODER_WMV,
+};
+
+enum audio_decoder {
+    AUDIO_DECODER_WMA,
+};
+
+
+class MediaProfiles
+{
+public:
+
+    /**
+     * Returns the singleton instance for subsequence queries.
+     * or NULL if error.
+     */
+    static MediaProfiles* getInstance();
+
+    /**
+     * Returns the value for the given param name at the given quality level,
+     * or -1 if error.
+     *
+     * 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.width - video frame width
+     * vid.height - video frame height
+     * vid.fps - video frame rate
+     * vid.bps - video bit rate
+     * aud.bps - audio bit rate
+     * aud.hz - audio sample rate
+     * aud.ch - number of audio channels
+     */
+    int getCamcorderProfileParamByName(const char *name, camcorder_quality quality) const;
+
+    /**
+     * Returns the output file formats supported.
+     */
+    Vector<output_format> getOutputFileFormats() const;
+
+    /**
+     * Returns the video encoders supported.
+     */
+    Vector<video_encoder> getVideoEncoders() const;
+
+    /**
+     * Returns the value for the given param name for the given video encoder
+     * returned from getVideoEncoderByIndex or -1 if error.
+     *
+     * Supported param name are:
+     * enc.vid.width.min - min video frame width
+     * enc.vid.width.max - max video frame width
+     * enc.vid.height.min - min video frame height
+     * enc.vid.height.max - max video frame height
+     * enc.vid.bps.min - min bit rate in bits per second
+     * enc.vid.bps.max - max bit rate in bits per second
+     * enc.vid.fps.min - min frame rate in frames per second
+     * enc.vid.fps.max - max frame rate in frames per second
+     */
+    int getVideoEncoderParamByName(const char *name, video_encoder codec) const;
+
+    /**
+     * Returns the audio encoders supported.
+     */
+    Vector<audio_encoder> getAudioEncoders() const;
+
+    /**
+     * Returns the value for the given param name for the given audio encoder
+     * returned from getAudioEncoderByIndex or -1 if error.
+     *
+     * Supported param name are:
+     * enc.aud.ch.min - min number of channels
+     * enc.aud.ch.max - max number of channels
+     * enc.aud.bps.min - min bit rate in bits per second
+     * enc.aud.bps.max - max bit rate in bits per second
+     * enc.aud.hz.min - min sample rate in samples per second
+     * enc.aud.hz.max - max sample rate in samples per second
+     */
+    int getAudioEncoderParamByName(const char *name, audio_encoder codec) const;
+
+    /**
+      * Returns the video decoders supported.
+      */
+    Vector<video_decoder> getVideoDecoders() const;
+
+     /**
+      * Returns the audio decoders supported.
+      */
+    Vector<audio_decoder> getAudioDecoders() const;
+
+private:
+    MediaProfiles& operator=(const MediaProfiles&);  // Don't call me
+    MediaProfiles(const MediaProfiles&);             // Don't call me
+    MediaProfiles() {}                               // Dummy default constructor
+    ~MediaProfiles();                                // Don't delete me
+
+    struct VideoCodec {
+        VideoCodec(video_encoder codec, int bitRate, int frameWidth, int frameHeight, int frameRate)
+            : mCodec(codec),
+              mBitRate(bitRate),
+              mFrameWidth(frameWidth),
+              mFrameHeight(frameHeight),
+              mFrameRate(frameRate) {}
+
+        ~VideoCodec() {}
+
+        video_encoder mCodec;
+        int mBitRate;
+        int mFrameWidth;
+        int mFrameHeight;
+        int mFrameRate;
+    };
+
+    struct AudioCodec {
+        AudioCodec(audio_encoder codec, int bitRate, int sampleRate, int channels)
+            : mCodec(codec),
+              mBitRate(bitRate),
+              mSampleRate(sampleRate),
+              mChannels(channels) {}
+
+        ~AudioCodec() {}
+
+        audio_encoder mCodec;
+        int mBitRate;
+        int mSampleRate;
+        int mChannels;
+    };
+
+    struct CamcorderProfile {
+        CamcorderProfile()
+            : mFileFormat(OUTPUT_FORMAT_THREE_GPP),
+              mQuality(CAMCORDER_QUALITY_HIGH),
+              mDuration(0),
+              mVideoCodec(0),
+              mAudioCodec(0) {}
+
+        ~CamcorderProfile() {
+            delete mVideoCodec;
+            delete mAudioCodec;
+        }
+
+        output_format mFileFormat;
+        camcorder_quality mQuality;
+        int mDuration;
+        VideoCodec *mVideoCodec;
+        AudioCodec *mAudioCodec;
+    };
+
+    struct VideoEncoderCap {
+        // Ugly constructor
+        VideoEncoderCap(video_encoder codec,
+                        int minBitRate, int maxBitRate,
+                        int minFrameWidth, int maxFrameWidth,
+                        int minFrameHeight, int maxFrameHeight,
+                        int minFrameRate, int maxFrameRate)
+            : mCodec(codec),
+              mMinBitRate(minBitRate), mMaxBitRate(maxBitRate),
+              mMinFrameWidth(minFrameWidth), mMaxFrameWidth(maxFrameWidth),
+              mMinFrameHeight(minFrameHeight), mMaxFrameHeight(maxFrameHeight),
+              mMinFrameRate(minFrameRate), mMaxFrameRate(maxFrameRate) {}
+
+         ~VideoEncoderCap() {}
+
+        video_encoder mCodec;
+        int mMinBitRate, mMaxBitRate;
+        int mMinFrameWidth, mMaxFrameWidth;
+        int mMinFrameHeight, mMaxFrameHeight;
+        int mMinFrameRate, mMaxFrameRate;
+    };
+
+    struct AudioEncoderCap {
+        // Ugly constructor
+        AudioEncoderCap(audio_encoder codec,
+                        int minBitRate, int maxBitRate,
+                        int minSampleRate, int maxSampleRate,
+                        int minChannels, int maxChannels)
+            : mCodec(codec),
+              mMinBitRate(minBitRate), mMaxBitRate(maxBitRate),
+              mMinSampleRate(minSampleRate), mMaxSampleRate(maxSampleRate),
+              mMinChannels(minChannels), mMaxChannels(maxChannels) {}
+
+        ~AudioEncoderCap() {}
+
+        audio_encoder mCodec;
+        int mMinBitRate, mMaxBitRate;
+        int mMinSampleRate, mMaxSampleRate;
+        int mMinChannels, mMaxChannels;
+    };
+
+    struct VideoDecoderCap {
+        VideoDecoderCap(video_decoder codec): mCodec(codec) {}
+        ~VideoDecoderCap() {}
+
+        video_decoder mCodec;
+    };
+
+    struct AudioDecoderCap {
+        AudioDecoderCap(audio_decoder codec): mCodec(codec) {}
+        ~AudioDecoderCap() {}
+
+        audio_decoder mCodec;
+    };
+
+    struct NameToTagMap {
+        const char* name;
+        int tag;
+    };
+
+    // Debug
+    static void logVideoCodec(const VideoCodec& codec);
+    static void logAudioCodec(const AudioCodec& codec);
+    static void logVideoEncoderCap(const VideoEncoderCap& cap);
+    static void logAudioEncoderCap(const AudioEncoderCap& cap);
+    static void logVideoDecoderCap(const VideoDecoderCap& cap);
+    static void logAudioDecoderCap(const AudioDecoderCap& cap);
+
+    // If the xml configuration file does exist, use the settings
+    // from the xml
+    static MediaProfiles* createInstanceFromXmlFile(const char *xml);
+    static output_format createEncoderOutputFileFormat(const char **atts);
+    static VideoCodec* createVideoCodec(const char **atts, MediaProfiles *profiles);
+    static AudioCodec* createAudioCodec(const char **atts, MediaProfiles *profiles);
+    static AudioDecoderCap* createAudioDecoderCap(const char **atts);
+    static VideoDecoderCap* createVideoDecoderCap(const char **atts);
+    static VideoEncoderCap* createVideoEncoderCap(const char **atts);
+    static AudioEncoderCap* createAudioEncoderCap(const char **atts);
+    static CamcorderProfile* createCamcorderProfile(const char **atts);
+
+    // Customized element tag handler for parsing the xml configuration file.
+    static void startElementHandler(void *userData, const char *name, const char **atts);
+
+    // If the xml configuration file does not exist, use hard-coded values
+    static MediaProfiles* createDefaultInstance();
+    static CamcorderProfile *createDefaultCamcorderLowProfile();
+    static CamcorderProfile *createDefaultCamcorderHighProfile();
+    static void createDefaultCamcorderProfiles(MediaProfiles *profiles);
+    static void createDefaultVideoEncoders(MediaProfiles *profiles);
+    static void createDefaultAudioEncoders(MediaProfiles *profiles);
+    static void createDefaultVideoDecoders(MediaProfiles *profiles);
+    static void createDefaultAudioDecoders(MediaProfiles *profiles);
+    static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles);
+    static VideoEncoderCap* createDefaultH263VideoEncoderCap();
+    static VideoEncoderCap* createDefaultM4vVideoEncoderCap();
+    static AudioEncoderCap* createDefaultAmrNBEncoderCap();
+
+    static int findTagForName(const NameToTagMap *map, size_t nMappings, const char *name);
+
+    // Mappings from name (for instance, codec name) to enum value
+    static const NameToTagMap sVideoEncoderNameMap[];
+    static const NameToTagMap sAudioEncoderNameMap[];
+    static const NameToTagMap sFileFormatMap[];
+    static const NameToTagMap sVideoDecoderNameMap[];
+    static const NameToTagMap sAudioDecoderNameMap[];
+    static const NameToTagMap sCamcorderQualityNameMap[];
+
+    static bool sIsInitialized;
+    static MediaProfiles *sInstance;
+    static Mutex sLock;
+
+    Vector<CamcorderProfile*> mCamcorderProfiles;
+    Vector<AudioEncoderCap*>  mAudioEncoders;
+    Vector<VideoEncoderCap*>  mVideoEncoders;
+    Vector<AudioDecoderCap*>  mAudioDecoders;
+    Vector<VideoDecoderCap*>  mVideoDecoders;
+    Vector<output_format>     mEncoderOutputFileFormats;
+};
+
+}; // namespace android
+
+#endif // ANDROID_MEDIAPROFILES_H
+
diff --git a/media/java/android/media/EncoderCapabilities.java b/media/java/android/media/EncoderCapabilities.java
new file mode 100644
index 0000000..71cb1b3
--- /dev/null
+++ b/media/java/android/media/EncoderCapabilities.java
@@ -0,0 +1,164 @@
+/*
+ * 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;
+
+import java.util.List;
+import java.util.ArrayList;
+import android.util.Log;
+
+/**
+ * The EncoderCapabilities class is used to retrieve the
+ * capabilities for different video and audio
+ * encoders supported on a specific Android platform.
+ * {@hide}
+ */
+public class EncoderCapabilities
+{
+    private static final String TAG = "EncoderCapabilities";
+
+    /**
+     * The VideoEncoderCap class represents a video encoder's
+     * supported parameter range in:
+     *
+     * <ul>
+     * <li>Resolution: the frame size (width/height) in pixels;
+     * <li>Bit rate: the compressed output bit rate in bits per second;
+     * <li>Frame rate: the output number of frames per second.
+     * </ul>
+     *
+     */
+    static public class VideoEncoderCap {
+        // These are not modifiable externally, thus are public accessible
+        public final int mCodec;                                 // @see android.media.MediaRecorder.VideoEncoder
+        public final int mMinBitRate, mMaxBitRate;               // min and max bit rate (bps)
+        public final int mMinFrameRate, mMaxFrameRate;           // min and max frame rate (fps)
+        public final int mMinFrameWidth, mMaxFrameWidth;         // min and max frame width (pixel)
+        public final int mMinFrameHeight, mMaxFrameHeight;       // minn and max frame height (pixel)
+
+        // Private constructor called by JNI
+        private VideoEncoderCap(int codec,
+                                int minBitRate, int maxBitRate,
+                                int minFrameRate, int maxFrameRate,
+                                int minFrameWidth, int maxFrameWidth,
+                                int minFrameHeight, int maxFrameHeight) {
+            mCodec = codec;
+            mMinBitRate = minBitRate;
+            mMaxBitRate = maxBitRate;
+            mMinFrameRate = minFrameRate;
+            mMaxFrameRate = maxFrameRate;
+            mMinFrameWidth = minFrameWidth;
+            mMaxFrameWidth = maxFrameWidth;
+            mMinFrameHeight = minFrameHeight;
+            mMaxFrameHeight = maxFrameHeight;
+        }
+    };
+
+    /**
+     * The AudioEncoderCap class represents an audio encoder's
+     * parameter range in:
+     *
+     * <ul>
+     * <li>Bit rate: the compressed output bit rate in bits per second;
+     * <li>Sample rate: the sampling rate used for recording the audio in samples per second;
+     * <li>Number of channels: the number of channels the audio is recorded.
+     * </ul>
+     *
+     */
+    static public class AudioEncoderCap {
+        // These are not modifiable externally, thus are public accessible
+        public final int mCodec;                         // @see android.media.MediaRecorder.AudioEncoder
+        public final int mMinChannels, mMaxChannels;     // min and max number of channels
+        public final int mMinSampleRate, mMaxSampleRate; // min and max sample rate (hz)
+        public final int mMinBitRate, mMaxBitRate;       // min and max bit rate (bps)
+
+        // Private constructor called by JNI
+        private AudioEncoderCap(int codec,
+                                int minBitRate, int maxBitRate,
+                                int minSampleRate, int maxSampleRate,
+                                int minChannels, int maxChannels) {
+           mCodec = codec;
+           mMinBitRate = minBitRate;
+           mMaxBitRate = maxBitRate;
+           mMinSampleRate = minSampleRate;
+           mMaxSampleRate = maxSampleRate;
+           mMinChannels = minChannels;
+           mMaxChannels = maxChannels;
+       }
+    };
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    /**
+     * Returns the array of supported output file formats.
+     * @see android.media.MediaRecorder.OutputFormat
+     */
+    public static int[] getOutputFileFormats() {
+        int nFormats = native_get_num_file_formats();
+        if (nFormats == 0) return null;
+
+        int[] formats = new int[nFormats];
+        for (int i = 0; i < nFormats; ++i) {
+            formats[i] = native_get_file_format(i);
+        }
+        return formats;
+    }
+
+    /**
+     * Returns the capabilities of the supported video encoders.
+     * @see android.media.EncoderCapabilities.VideoEncoderCap
+     */
+    public static List<VideoEncoderCap> getVideoEncoders() {
+        int nEncoders = native_get_num_video_encoders();
+        if (nEncoders == 0) return null;
+
+        List<VideoEncoderCap> encoderList = new ArrayList<VideoEncoderCap>();
+        for (int i = 0; i < nEncoders; ++i) {
+            encoderList.add(native_get_video_encoder_cap(i));
+        }
+        return encoderList;
+    }
+
+    /**
+     * Returns the capabilities of the supported audio encoders.
+     * @see android.media.EncoderCapabilities.AudioEncoderCap
+     */
+    public static List<AudioEncoderCap> getAudioEncoders() {
+        int nEncoders = native_get_num_audio_encoders();
+        if (nEncoders == 0) return null;
+
+        List<AudioEncoderCap> encoderList = new ArrayList<AudioEncoderCap>();
+        for (int i = 0; i < nEncoders; ++i) {
+            encoderList.add(native_get_audio_encoder_cap(i));
+        }
+        return encoderList;
+    }
+
+
+    private EncoderCapabilities() {}  // Don't call me
+
+    // Implemented by JNI
+    private static native final void native_init();
+    private static native final int native_get_num_file_formats();
+    private static native final int native_get_file_format(int index);
+    private static native final int native_get_num_video_encoders();
+    private static native final VideoEncoderCap native_get_video_encoder_cap(int index);
+    private static native final int native_get_num_audio_encoders();
+    private static native final AudioEncoderCap native_get_audio_encoder_cap(int index);
+}
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 1d82e32..d83f493 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -10,7 +10,8 @@
     android_media_MediaRecorder.cpp \
     android_media_MediaScanner.cpp \
     android_media_MediaMetadataRetriever.cpp \
-    android_media_ResampleInputStream.cpp
+    android_media_ResampleInputStream.cpp \
+    android_media_MediaProfiles.cpp
 
 LOCAL_SHARED_LIBRARIES := \
     libandroid_runtime \
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 27f5668..76d1674 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -739,6 +739,7 @@
 extern int register_android_media_MediaRecorder(JNIEnv *env);
 extern int register_android_media_MediaScanner(JNIEnv *env);
 extern int register_android_media_ResampleInputStream(JNIEnv *env);
+extern int register_android_media_MediaProfiles(JNIEnv *env);
 
 #ifndef NO_OPENCORE
 extern int register_android_media_AmrInputStream(JNIEnv *env);
@@ -787,6 +788,11 @@
         goto bail;
     }
 
+    if (register_android_media_MediaProfiles(env) < 0) {
+        LOGE("ERROR: MediaProfiles native registration failed");
+        goto bail;
+    }
+
     /* success -- return valid version number */
     result = JNI_VERSION_1_4;
 
diff --git a/media/jni/android_media_MediaProfiles.cpp b/media/jni/android_media_MediaProfiles.cpp
new file mode 100644
index 0000000..cd3ad88
--- /dev/null
+++ b/media/jni/android_media_MediaProfiles.cpp
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaProfilesJNI"
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <utils/threads.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+#include <media/MediaProfiles.h>
+
+using namespace android;
+
+static Mutex sLock;
+MediaProfiles *sProfiles = NULL;
+
+// This function is called from a static block in MediaProfiles.java class,
+// which won't run until the first time an instance of this class is used.
+static void
+android_media_MediaProfiles_native_init(JNIEnv *env)
+{
+    LOGV("native_init");
+    Mutex::Autolock lock(sLock);
+
+    if (sProfiles == NULL) {
+        sProfiles = MediaProfiles::getInstance();
+    }
+}
+
+static int
+android_media_MediaProfiles_native_get_num_file_formats(JNIEnv *env, jobject thiz)
+{
+    LOGV("native_get_num_file_formats");
+    return sProfiles->getOutputFileFormats().size();
+}
+
+static int
+android_media_MediaProfiles_native_get_file_format(JNIEnv *env, jobject thiz, jint index)
+{
+    LOGV("native_get_file_format: %d", index);
+    Vector<output_format> formats = sProfiles->getOutputFileFormats();
+    int nSize = formats.size();
+    if (index < 0 || index >= nSize) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
+        return -1;
+    }
+    int format = static_cast<int>(formats[index]);
+    return format;
+}
+
+static int
+android_media_MediaProfiles_native_get_num_video_encoders(JNIEnv *env, jobject thiz)
+{
+    LOGV("native_get_num_video_encoders");
+    return sProfiles->getVideoEncoders().size();
+}
+
+static jobject
+android_media_MediaProfiles_native_get_video_encoder_cap(JNIEnv *env, jobject thiz, jint index)
+{
+    LOGV("native_get_video_encoder_cap: %d", index);
+    Vector<video_encoder> encoders = sProfiles->getVideoEncoders();
+    int nSize = encoders.size();
+    if (index < 0 || index >= nSize) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
+        return NULL;
+    }
+
+    video_encoder encoder = encoders[index];
+    int minBitRate = sProfiles->getVideoEncoderParamByName("enc.vid.bps.min", encoder);
+    int maxBitRate = sProfiles->getVideoEncoderParamByName("enc.vid.bps.max", encoder);
+    int minFrameRate = sProfiles->getVideoEncoderParamByName("enc.vid.fps.min", encoder);
+    int maxFrameRate = sProfiles->getVideoEncoderParamByName("enc.vid.fps.max", encoder);
+    int minFrameWidth = sProfiles->getVideoEncoderParamByName("enc.vid.width.min", encoder);
+    int maxFrameWidth = sProfiles->getVideoEncoderParamByName("enc.vid.width.max", encoder);
+    int minFrameHeight = sProfiles->getVideoEncoderParamByName("enc.vid.height.min", encoder);
+    int maxFrameHeight = sProfiles->getVideoEncoderParamByName("enc.vid.height.max", encoder);
+
+    // Check on the values retrieved
+    if ((minBitRate == -1 || maxBitRate == -1) ||
+        (minFrameRate == -1 || maxFrameRate == -1) ||
+        (minFrameWidth == -1 || maxFrameWidth == -1) ||
+        (minFrameHeight == -1 || maxFrameHeight == -1)) {
+
+        jniThrowException(env, "java/lang/RuntimeException", "Error retrieving video encoder capability params");
+        return NULL;
+    }
+
+    // Construct an instance of the VideoEncoderCap and set its member variables
+    jclass videoEncoderCapClazz = env->FindClass("android/media/EncoderCapabilities$VideoEncoderCap");
+    jmethodID videoEncoderCapConstructorMethodID = env->GetMethodID(videoEncoderCapClazz, "<init>", "(IIIIIIIII)V");
+    jobject cap = env->NewObject(videoEncoderCapClazz,
+                                 videoEncoderCapConstructorMethodID,
+                                 static_cast<int>(encoder),
+                                 minBitRate, maxBitRate,
+                                 minFrameRate, maxFrameRate,
+                                 minFrameWidth, maxFrameWidth,
+                                 minFrameHeight, maxFrameHeight);
+    return cap;
+}
+
+static int
+android_media_MediaProfiles_native_get_num_audio_encoders(JNIEnv *env, jobject thiz)
+{
+    LOGV("native_get_num_audio_encoders");
+    return sProfiles->getAudioEncoders().size();
+}
+
+static jobject
+android_media_MediaProfiles_native_get_audio_encoder_cap(JNIEnv *env, jobject thiz, jint index)
+{
+    LOGV("native_get_audio_encoder_cap: %d", index);
+    Vector<audio_encoder> encoders = sProfiles->getAudioEncoders();
+    int nSize = encoders.size();
+    if (index < 0 || index >= nSize) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
+        return NULL;
+    }
+
+    audio_encoder encoder = encoders[index];
+    int minBitRate = sProfiles->getAudioEncoderParamByName("enc.aud.bps.min", encoder);
+    int maxBitRate = sProfiles->getAudioEncoderParamByName("enc.aud.bps.max", encoder);
+    int minSampleRate = sProfiles->getAudioEncoderParamByName("enc.aud.hz.min", encoder);
+    int maxSampleRate = sProfiles->getAudioEncoderParamByName("enc.aud.hz.max", encoder);
+    int minChannels = sProfiles->getAudioEncoderParamByName("enc.aud.ch.min", encoder);
+    int maxChannels = sProfiles->getAudioEncoderParamByName("enc.aud.ch.max", encoder);
+
+    // Check on the values retrieved
+    if ((minBitRate == -1 || maxBitRate == -1) ||
+        (minSampleRate == -1 || maxSampleRate == -1) ||
+        (minChannels == -1 || maxChannels == -1)) {
+
+        jniThrowException(env, "java/lang/RuntimeException", "Error retrieving video encoder capability params");
+        return NULL;
+    }
+
+    jclass audioEncoderCapClazz = env->FindClass("android/media/EncoderCapabilities$AudioEncoderCap");
+    jmethodID audioEncoderCapConstructorMethodID = env->GetMethodID(audioEncoderCapClazz, "<init>", "(IIIIIII)V");
+    jobject cap = env->NewObject(audioEncoderCapClazz,
+                                 audioEncoderCapConstructorMethodID,
+                                 static_cast<int>(encoder),
+                                 minBitRate, maxBitRate,
+                                 minSampleRate, maxSampleRate,
+                                 minChannels, maxChannels);
+    return cap;
+}
+
+static JNINativeMethod gMethods[] = {
+    {"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},
+    {"native_get_num_video_encoders",          "()I",                    (void *)android_media_MediaProfiles_native_get_num_video_encoders},
+    {"native_get_num_audio_encoders",          "()I",                    (void *)android_media_MediaProfiles_native_get_num_audio_encoders},
+
+    {"native_get_video_encoder_cap",           "(I)Landroid/media/EncoderCapabilities$VideoEncoderCap;",
+                                                                         (void *)android_media_MediaProfiles_native_get_video_encoder_cap},
+
+    {"native_get_audio_encoder_cap",           "(I)Landroid/media/EncoderCapabilities$AudioEncoderCap;",
+                                                                         (void *)android_media_MediaProfiles_native_get_audio_encoder_cap},
+};
+
+static const char* const kClassPathName = "android/media/MediaProfiles";
+
+// 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));
+}
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 4ae4ec9b..c59d323 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -25,10 +25,11 @@
     MediaScanner.cpp \
     MediaScannerClient.cpp \
     autodetect.cpp \
-    IMediaDeathNotifier.cpp
+    IMediaDeathNotifier.cpp \
+    MediaProfiles.cpp
 
 LOCAL_SHARED_LIBRARIES := \
-	libui libcutils libutils libbinder libsonivox libicuuc
+	libui libcutils libutils libbinder libsonivox libicuuc libexpat
 
 LOCAL_MODULE:= libmedia
 
@@ -43,10 +44,11 @@
 LOCAL_C_INCLUDES := \
     $(JNI_H_INCLUDE) \
     $(call include-path-for, graphics corecg) \
-        $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
-        external/speex/include \
-        external/speex/libspeex \
-        external/icu4c/common
+    $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
+    external/speex/include \
+    external/speex/libspeex \
+    external/icu4c/common \
+    external/expat/lib
 
 LOCAL_STATIC_LIBRARIES := libspeex
 
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
new file mode 100644
index 0000000..0efade1
--- /dev/null
+++ b/media/libmedia/MediaProfiles.cpp
@@ -0,0 +1,675 @@
+/*
+**
+** Copyright 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.
+*/
+
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaProfiles"
+
+#include <stdlib.h>
+#include <utils/Log.h>
+#include <utils/Vector.h>
+#include <cutils/properties.h>
+#include <expat.h>
+#include <media/MediaProfiles.h>
+#include <media/stagefright/MediaDebug.h>
+
+namespace android {
+
+Mutex MediaProfiles::sLock;
+bool MediaProfiles::sIsInitialized = false;
+MediaProfiles *MediaProfiles::sInstance = NULL;
+
+const MediaProfiles::NameToTagMap MediaProfiles::sVideoEncoderNameMap[] = {
+    {"h263", VIDEO_ENCODER_H263},
+    {"h264", VIDEO_ENCODER_H264},
+    {"m4v",  VIDEO_ENCODER_MPEG_4_SP}
+};
+
+const MediaProfiles::NameToTagMap MediaProfiles::sAudioEncoderNameMap[] = {
+    {"amrnb", AUDIO_ENCODER_AMR_NB},
+    {"amrwb", AUDIO_ENCODER_AMR_WB},
+    {"aac",   AUDIO_ENCODER_AAC},
+};
+
+const MediaProfiles::NameToTagMap MediaProfiles::sFileFormatMap[] = {
+    {"3gp", OUTPUT_FORMAT_THREE_GPP},
+    {"mp4", OUTPUT_FORMAT_MPEG_4}
+};
+
+const MediaProfiles::NameToTagMap MediaProfiles::sVideoDecoderNameMap[] = {
+    {"wmv", VIDEO_DECODER_WMV}
+};
+
+const MediaProfiles::NameToTagMap MediaProfiles::sAudioDecoderNameMap[] = {
+    {"wma", AUDIO_DECODER_WMA}
+};
+
+const MediaProfiles::NameToTagMap MediaProfiles::sCamcorderQualityNameMap[] = {
+    {"high", CAMCORDER_QUALITY_HIGH},
+    {"low",  CAMCORDER_QUALITY_LOW}
+};
+
+/*static*/ void
+MediaProfiles::logVideoCodec(const MediaProfiles::VideoCodec& codec)
+{
+    LOGV("video codec:");
+    LOGV("codec = %d", codec.mCodec);
+    LOGV("bit rate: %d", codec.mBitRate);
+    LOGV("frame width: %d", codec.mFrameWidth);
+    LOGV("frame height: %d", codec.mFrameHeight);
+    LOGV("frame rate: %d", codec.mFrameRate);
+}
+
+/*static*/ void
+MediaProfiles::logAudioCodec(const MediaProfiles::AudioCodec& codec)
+{
+    LOGV("audio codec:");
+    LOGV("codec = %d", codec.mCodec);
+    LOGV("bit rate: %d", codec.mBitRate);
+    LOGV("sample rate: %d", codec.mSampleRate);
+    LOGV("number of channels: %d", codec.mChannels);
+}
+
+/*static*/ void
+MediaProfiles::logVideoEncoderCap(const MediaProfiles::VideoEncoderCap& cap)
+{
+    LOGV("video encoder cap:");
+    LOGV("codec = %d", cap.mCodec);
+    LOGV("bit rate: min = %d and max = %d", cap.mMinBitRate, cap.mMaxBitRate);
+    LOGV("frame width: min = %d and max = %d", cap.mMinFrameWidth, cap.mMaxFrameWidth);
+    LOGV("frame height: min = %d and max = %d", cap.mMinFrameHeight, cap.mMaxFrameHeight);
+    LOGV("frame rate: min = %d and max = %d", cap.mMinFrameRate, cap.mMaxFrameRate);
+}
+
+/*static*/ void
+MediaProfiles::logAudioEncoderCap(const MediaProfiles::AudioEncoderCap& cap)
+{
+    LOGV("audio encoder cap:");
+    LOGV("codec = %d", cap.mCodec);
+    LOGV("bit rate: min = %d and max = %d", cap.mMinBitRate, cap.mMaxBitRate);
+    LOGV("sample rate: min = %d and max = %d", cap.mMinSampleRate, cap.mMaxSampleRate);
+    LOGV("number of channels: min = %d and max = %d", cap.mMinChannels, cap.mMaxChannels);
+}
+
+/*static*/ void
+MediaProfiles::logVideoDecoderCap(const MediaProfiles::VideoDecoderCap& cap)
+{
+    LOGV("video decoder cap:");
+    LOGV("codec = %d", cap.mCodec);
+}
+
+/*static*/ void
+MediaProfiles::logAudioDecoderCap(const MediaProfiles::AudioDecoderCap& cap)
+{
+    LOGV("audio codec cap:");
+    LOGV("codec = %d", cap.mCodec);
+}
+
+/*static*/ int
+MediaProfiles::findTagForName(const MediaProfiles::NameToTagMap *map, size_t nMappings, const char *name)
+{
+    int tag = -1;
+    for (size_t i = 0; i < nMappings; ++i) {
+        if (!strcmp(map[i].name, name)) {
+            tag = map[i].tag;
+            break;
+        }
+    }
+    return tag;
+}
+
+/*static*/ MediaProfiles::VideoCodec*
+MediaProfiles::createVideoCodec(const char **atts, MediaProfiles *profiles)
+{
+    CHECK(!strcmp("codec",     atts[0]) &&
+          !strcmp("bitRate",   atts[2]) &&
+          !strcmp("width",     atts[4]) &&
+          !strcmp("height",    atts[6]) &&
+          !strcmp("frameRate", atts[8]));
+
+    const size_t nMappings = sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]);
+    const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]);
+    CHECK(codec != -1);
+
+    MediaProfiles::VideoCodec *videoCodec =
+        new MediaProfiles::VideoCodec(static_cast<video_encoder>(codec),
+            atoi(atts[3]), atoi(atts[5]), atoi(atts[7]), atoi(atts[9]));
+    logVideoCodec(*videoCodec);
+
+    size_t nCamcorderProfiles;
+    CHECK((nCamcorderProfiles = profiles->mCamcorderProfiles.size()) >= 1);
+    profiles->mCamcorderProfiles[nCamcorderProfiles - 1]->mVideoCodec = videoCodec;
+    return videoCodec;
+}
+
+/*static*/ MediaProfiles::AudioCodec*
+MediaProfiles::createAudioCodec(const char **atts, MediaProfiles *profiles)
+{
+    CHECK(!strcmp("codec",      atts[0]) &&
+          !strcmp("bitRate",    atts[2]) &&
+          !strcmp("sampleRate", atts[4]) &&
+          !strcmp("channels",   atts[6]));
+    const size_t nMappings = sizeof(sAudioEncoderNameMap)/sizeof(sAudioEncoderNameMap[0]);
+    const int codec = findTagForName(sAudioEncoderNameMap, nMappings, atts[1]);
+    CHECK(codec != -1);
+
+    MediaProfiles::AudioCodec *audioCodec =
+        new MediaProfiles::AudioCodec(static_cast<audio_encoder>(codec),
+            atoi(atts[3]), atoi(atts[5]), atoi(atts[7]));
+    logAudioCodec(*audioCodec);
+
+    size_t nCamcorderProfiles;
+    CHECK((nCamcorderProfiles = profiles->mCamcorderProfiles.size()) >= 1);
+    profiles->mCamcorderProfiles[nCamcorderProfiles - 1]->mAudioCodec = audioCodec;
+    return audioCodec;
+}
+/*static*/ MediaProfiles::AudioDecoderCap*
+MediaProfiles::createAudioDecoderCap(const char **atts)
+{
+    CHECK(!strcmp("name",    atts[0]) &&
+          !strcmp("enabled", atts[2]));
+
+    const size_t nMappings = sizeof(sAudioDecoderNameMap)/sizeof(sAudioDecoderNameMap[0]);
+    const int codec = findTagForName(sAudioDecoderNameMap, nMappings, atts[1]);
+    CHECK(codec != -1);
+
+    MediaProfiles::AudioDecoderCap *cap =
+        new MediaProfiles::AudioDecoderCap(static_cast<audio_decoder>(codec));
+    logAudioDecoderCap(*cap);
+    return cap;
+}
+
+/*static*/ MediaProfiles::VideoDecoderCap*
+MediaProfiles::createVideoDecoderCap(const char **atts)
+{
+    CHECK(!strcmp("name",    atts[0]) &&
+          !strcmp("enabled", atts[2]));
+
+    const size_t nMappings = sizeof(sVideoDecoderNameMap)/sizeof(sVideoDecoderNameMap[0]);
+    const int codec = findTagForName(sVideoDecoderNameMap, nMappings, atts[1]);
+    CHECK(codec != -1);
+
+    MediaProfiles::VideoDecoderCap *cap =
+        new MediaProfiles::VideoDecoderCap(static_cast<video_decoder>(codec));
+    logVideoDecoderCap(*cap);
+    return cap;
+}
+
+/*static*/ MediaProfiles::VideoEncoderCap*
+MediaProfiles::createVideoEncoderCap(const char **atts)
+{
+    CHECK(!strcmp("name",           atts[0])  &&
+          !strcmp("enabled",        atts[2])  &&
+          !strcmp("minBitRate",     atts[4])  &&
+          !strcmp("maxBitRate",     atts[6])  &&
+          !strcmp("minFrameWidth",  atts[8])  &&
+          !strcmp("maxFrameWidth",  atts[10]) &&
+          !strcmp("minFrameHeight", atts[12]) &&
+          !strcmp("maxFrameHeight", atts[14]) &&
+          !strcmp("minFrameRate",   atts[16]) &&
+          !strcmp("maxFrameRate",   atts[18]));
+
+    const size_t nMappings = sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]);
+    const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]);
+    CHECK(codec != -1);
+
+    MediaProfiles::VideoEncoderCap *cap =
+        new MediaProfiles::VideoEncoderCap(static_cast<video_encoder>(codec),
+            atoi(atts[5]), atoi(atts[7]), atoi(atts[9]), atoi(atts[11]), atoi(atts[13]),
+            atoi(atts[15]), atoi(atts[17]), atoi(atts[19]));
+    logVideoEncoderCap(*cap);
+    return cap;
+}
+
+/*static*/ MediaProfiles::AudioEncoderCap*
+MediaProfiles::createAudioEncoderCap(const char **atts)
+{
+    CHECK(!strcmp("name",          atts[0])  &&
+          !strcmp("enabled",       atts[2])  &&
+          !strcmp("minBitRate",    atts[4])  &&
+          !strcmp("maxBitRate",    atts[6])  &&
+          !strcmp("minSampleRate", atts[8])  &&
+          !strcmp("maxSampleRate", atts[10]) &&
+          !strcmp("minChannels",   atts[12]) &&
+          !strcmp("maxChannels",   atts[14]));
+
+    const size_t nMappings = sizeof(sAudioEncoderNameMap)/sizeof(sAudioEncoderNameMap[0]);
+    const int codec = findTagForName(sAudioEncoderNameMap, nMappings, atts[1]);
+    CHECK(codec != -1);
+
+    MediaProfiles::AudioEncoderCap *cap =
+        new MediaProfiles::AudioEncoderCap(static_cast<audio_encoder>(codec), atoi(atts[5]), atoi(atts[7]),
+            atoi(atts[9]), atoi(atts[11]), atoi(atts[13]),
+            atoi(atts[15]));
+    logAudioEncoderCap(*cap);
+    return cap;
+}
+
+/*static*/ output_format
+MediaProfiles::createEncoderOutputFileFormat(const char **atts)
+{
+    CHECK(!strcmp("name", atts[0]));
+
+    const size_t nMappings =sizeof(sFileFormatMap)/sizeof(sFileFormatMap[0]);
+    const int format = findTagForName(sFileFormatMap, nMappings, atts[1]);
+    CHECK(format != -1);
+
+    return static_cast<output_format>(format);
+}
+
+/*static*/ MediaProfiles::CamcorderProfile*
+MediaProfiles::createCamcorderProfile(const char **atts)
+{
+    CHECK(!strcmp("quality",    atts[0]) &&
+          !strcmp("fileFormat", atts[2]) &&
+          !strcmp("duration",   atts[4]));
+
+    const size_t nProfileMappings = sizeof(sCamcorderQualityNameMap)/sizeof(sCamcorderQualityNameMap[0]);
+    const int quality = findTagForName(sCamcorderQualityNameMap, nProfileMappings, atts[1]);
+    CHECK(quality != -1);
+
+    const size_t nFormatMappings = sizeof(sFileFormatMap)/sizeof(sFileFormatMap[0]);
+    const int fileFormat = findTagForName(sFileFormatMap, nFormatMappings, atts[3]);
+    CHECK(fileFormat != -1);
+
+    MediaProfiles::CamcorderProfile *profile = new MediaProfiles::CamcorderProfile;
+    profile->mFileFormat = static_cast<output_format>(fileFormat);
+    profile->mQuality = static_cast<camcorder_quality>(quality);
+    profile->mDuration = atoi(atts[5]);
+    return profile;
+}
+
+/*static*/ void
+MediaProfiles::startElementHandler(void *userData, const char *name, const char **atts)
+{
+    MediaProfiles *profiles = (MediaProfiles *) userData;
+    if (strcmp("Video", name) == 0) {
+        createVideoCodec(atts, profiles);
+    } else if (strcmp("Audio", name) == 0) {
+        createAudioCodec(atts, profiles);
+    } else if (strcmp("VideoEncoderCap", name) == 0 &&
+               strcmp("true", atts[3]) == 0) {
+        profiles->mVideoEncoders.add(createVideoEncoderCap(atts));
+    } else if (strcmp("AudioEncoderCap", name) == 0 &&
+               strcmp("true", atts[3]) == 0) {
+        profiles->mAudioEncoders.add(createAudioEncoderCap(atts));
+    } else if (strcmp("VideoDecoderCap", name) == 0 &&
+               strcmp("true", atts[3]) == 0) {
+        profiles->mVideoDecoders.add(createVideoDecoderCap(atts));
+    } else if (strcmp("AudioDecoderCap", name) == 0 &&
+               strcmp("true", atts[3]) == 0) {
+        profiles->mAudioDecoders.add(createAudioDecoderCap(atts));
+    } else if (strcmp("EncoderOutputFileFormat", name) == 0) {
+        profiles->mEncoderOutputFileFormats.add(createEncoderOutputFileFormat(atts));
+    } else if (strcmp("EncoderProfile", name) == 0) {
+        profiles->mCamcorderProfiles.add(createCamcorderProfile(atts));
+    }
+}
+
+/*static*/ MediaProfiles*
+MediaProfiles::getInstance()
+{
+    LOGV("getInstance");
+    Mutex::Autolock lock(sLock);
+    if (!sIsInitialized) {
+        char value[PROPERTY_VALUE_MAX];
+        if (property_get("media.settings.xml", value, NULL) <= 0) {
+            const char *defaultXmlFile = "/etc/media_profiles.xml";
+            FILE *fp = fopen(defaultXmlFile, "r");
+            if (fp == NULL) {
+                LOGW("could not find media config xml file");
+                sInstance = createDefaultInstance();
+            } else {
+                fclose(fp);  // close the file first.
+                sInstance = createInstanceFromXmlFile(defaultXmlFile);
+            }
+        } else {
+            sInstance = createInstanceFromXmlFile(value);
+        }
+    }
+
+    return sInstance;
+}
+
+/*static*/ MediaProfiles::VideoEncoderCap*
+MediaProfiles::createDefaultH263VideoEncoderCap()
+{
+    return new MediaProfiles::VideoEncoderCap(
+        VIDEO_ENCODER_H263, 192000, 420000, 176, 352, 144, 288, 1, 20);
+}
+
+/*static*/ MediaProfiles::VideoEncoderCap*
+MediaProfiles::createDefaultM4vVideoEncoderCap()
+{
+    return new MediaProfiles::VideoEncoderCap(
+        VIDEO_ENCODER_MPEG_4_SP, 192000, 420000, 176, 352, 144, 288, 1, 20);
+}
+
+
+/*static*/ void
+MediaProfiles::createDefaultVideoEncoders(MediaProfiles *profiles)
+{
+    profiles->mVideoEncoders.add(createDefaultH263VideoEncoderCap());
+    profiles->mVideoEncoders.add(createDefaultM4vVideoEncoderCap());
+}
+
+/*static*/ MediaProfiles::CamcorderProfile*
+MediaProfiles::createDefaultCamcorderHighProfile()
+{
+    MediaProfiles::VideoCodec *videoCodec =
+        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;
+    profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP;
+    profile->mQuality = CAMCORDER_QUALITY_HIGH;
+    profile->mDuration = 60;
+    profile->mVideoCodec = videoCodec;
+    profile->mAudioCodec = audioCodec;
+    return profile;
+}
+
+/*static*/ MediaProfiles::CamcorderProfile*
+MediaProfiles::createDefaultCamcorderLowProfile()
+{
+    MediaProfiles::VideoCodec *videoCodec =
+        new MediaProfiles::VideoCodec(VIDEO_ENCODER_H263, 192000, 176, 144, 20);
+
+    MediaProfiles::AudioCodec *audioCodec =
+        new MediaProfiles::AudioCodec(AUDIO_ENCODER_AMR_NB, 12200, 8000, 1);
+
+    MediaProfiles::CamcorderProfile *profile = new MediaProfiles::CamcorderProfile;
+    profile->mFileFormat = OUTPUT_FORMAT_THREE_GPP;
+    profile->mQuality = CAMCORDER_QUALITY_LOW;
+    profile->mDuration = 30;
+    profile->mVideoCodec = videoCodec;
+    profile->mAudioCodec = audioCodec;
+    return profile;
+}
+
+/*static*/ void
+MediaProfiles::createDefaultCamcorderProfiles(MediaProfiles *profiles)
+{
+    profiles->mCamcorderProfiles.add(createDefaultCamcorderHighProfile());
+    profiles->mCamcorderProfiles.add(createDefaultCamcorderLowProfile());
+}
+
+/*static*/ void
+MediaProfiles::createDefaultAudioEncoders(MediaProfiles *profiles)
+{
+    profiles->mAudioEncoders.add(createDefaultAmrNBEncoderCap());
+}
+
+/*static*/ void
+MediaProfiles::createDefaultVideoDecoders(MediaProfiles *profiles)
+{
+    MediaProfiles::VideoDecoderCap *cap =
+        new MediaProfiles::VideoDecoderCap(VIDEO_DECODER_WMV);
+
+    profiles->mVideoDecoders.add(cap);
+}
+
+/*static*/ void
+MediaProfiles::createDefaultAudioDecoders(MediaProfiles *profiles)
+{
+    MediaProfiles::AudioDecoderCap *cap =
+        new MediaProfiles::AudioDecoderCap(AUDIO_DECODER_WMA);
+
+    profiles->mAudioDecoders.add(cap);
+}
+
+/*static*/ void
+MediaProfiles::createDefaultEncoderOutputFileFormats(MediaProfiles *profiles)
+{
+    profiles->mEncoderOutputFileFormats.add(OUTPUT_FORMAT_THREE_GPP);
+    profiles->mEncoderOutputFileFormats.add(OUTPUT_FORMAT_MPEG_4);
+}
+
+/*static*/ MediaProfiles::AudioEncoderCap*
+MediaProfiles::createDefaultAmrNBEncoderCap()
+{
+    return new MediaProfiles::AudioEncoderCap(
+        AUDIO_ENCODER_AMR_NB, 5525, 12200, 8000, 8000, 1, 1);
+}
+
+/*static*/ MediaProfiles*
+MediaProfiles::createDefaultInstance()
+{
+    MediaProfiles *profiles = new MediaProfiles;
+    createDefaultCamcorderProfiles(profiles);
+    createDefaultVideoEncoders(profiles);
+    createDefaultAudioEncoders(profiles);
+    createDefaultVideoDecoders(profiles);
+    createDefaultAudioDecoders(profiles);
+    createDefaultEncoderOutputFileFormats(profiles);
+    sIsInitialized = true;
+    return profiles;
+}
+
+/*static*/ MediaProfiles*
+MediaProfiles::createInstanceFromXmlFile(const char *xml)
+{
+    FILE *fp = NULL;
+    CHECK((fp = fopen(xml, "r")));
+
+    XML_Parser parser = ::XML_ParserCreate(NULL);
+    CHECK(parser != NULL);
+
+    MediaProfiles *profiles = new MediaProfiles();
+    ::XML_SetUserData(parser, profiles);
+    ::XML_SetElementHandler(parser, startElementHandler, NULL);
+
+    /*
+      FIXME:
+      expat is not compiled with -DXML_DTD. We don't have DTD parsing support.
+
+      if (!::XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS)) {
+          LOGE("failed to enable DTD support in the xml file");
+          return UNKNOWN_ERROR;
+      }
+
+    */
+
+    const int BUFF_SIZE = 512;
+    for (;;) {
+        void *buff = ::XML_GetBuffer(parser, BUFF_SIZE);
+        if (buff == NULL) {
+            LOGE("failed to in call to XML_GetBuffer()");
+            delete profiles;
+            profiles = NULL;
+            goto exit;
+        }
+
+        int bytes_read = ::fread(buff, 1, BUFF_SIZE, fp);
+        if (bytes_read < 0) {
+            LOGE("failed in call to read");
+            delete profiles;
+            profiles = NULL;
+            goto exit;
+        }
+
+        CHECK(::XML_ParseBuffer(parser, bytes_read, bytes_read == 0));
+
+        if (bytes_read == 0) break;  // done parsing the xml file
+    }
+
+exit:
+    ::XML_ParserFree(parser);
+    ::fclose(fp);
+    if (profiles) {
+        sIsInitialized = true;
+    }
+    return profiles;
+}
+
+Vector<output_format> MediaProfiles::getOutputFileFormats() const
+{
+    return mEncoderOutputFileFormats;  // copy out
+}
+
+Vector<video_encoder> MediaProfiles::getVideoEncoders() const
+{
+    Vector<video_encoder> encoders;
+    for (size_t i = 0; i < mVideoEncoders.size(); ++i) {
+        encoders.add(mVideoEncoders[i]->mCodec);
+    }
+    return encoders;  // copy out
+}
+
+int MediaProfiles::getVideoEncoderParamByName(const char *name, video_encoder codec) const
+{
+    LOGV("getVideoEncoderParamByName: %s for codec %d", name, codec);
+    int index = -1;
+    for (size_t i = 0, n = mVideoEncoders.size(); i < n; ++i) {
+        if (mVideoEncoders[i]->mCodec == codec) {
+            index = i;
+            break;
+        }
+    }
+    if (index == -1) {
+        LOGE("The given video encoder %d is not found", codec);
+        return -1;
+    }
+
+    if (!strcmp("enc.vid.width.min", name)) return mVideoEncoders[index]->mMinFrameWidth;
+    if (!strcmp("enc.vid.width.max", name)) return mVideoEncoders[index]->mMaxFrameWidth;
+    if (!strcmp("enc.vid.height.min", name)) return mVideoEncoders[index]->mMinFrameHeight;
+    if (!strcmp("enc.vid.height.max", name)) return mVideoEncoders[index]->mMaxFrameHeight;
+    if (!strcmp("enc.vid.bps.min", name)) return mVideoEncoders[index]->mMinBitRate;
+    if (!strcmp("enc.vid.bps.max", name)) return mVideoEncoders[index]->mMaxBitRate;
+    if (!strcmp("enc.vid.fps.min", name)) return mVideoEncoders[index]->mMinFrameRate;
+    if (!strcmp("enc.vid.fps.max", name)) return mVideoEncoders[index]->mMaxFrameRate;
+
+    LOGE("The given video encoder param name %s is not found", name);
+    return -1;
+}
+
+Vector<audio_encoder> MediaProfiles::getAudioEncoders() const
+{
+    Vector<audio_encoder> encoders;
+    for (size_t i = 0; i < mAudioEncoders.size(); ++i) {
+        encoders.add(mAudioEncoders[i]->mCodec);
+    }
+    return encoders;  // copy out
+}
+
+int MediaProfiles::getAudioEncoderParamByName(const char *name, audio_encoder codec) const
+{
+    LOGV("getAudioEncoderParamByName: %s for codec %d", name, codec);
+    int index = -1;
+    for (size_t i = 0, n = mAudioEncoders.size(); i < n; ++i) {
+        if (mAudioEncoders[i]->mCodec == codec) {
+            index = i;
+            break;
+        }
+    }
+    if (index == -1) {
+        LOGE("The given audio encoder %d is not found", codec);
+        return -1;
+    }
+
+    if (!strcmp("enc.aud.ch.min", name)) return mAudioEncoders[index]->mMinChannels;
+    if (!strcmp("enc.aud.ch.max", name)) return mAudioEncoders[index]->mMaxChannels;
+    if (!strcmp("enc.aud.bps.min", name)) return mAudioEncoders[index]->mMinBitRate;
+    if (!strcmp("enc.aud.bps.max", name)) return mAudioEncoders[index]->mMaxBitRate;
+    if (!strcmp("enc.aud.hz.min", name)) return mAudioEncoders[index]->mMinSampleRate;
+    if (!strcmp("enc.aud.hz.max", name)) return mAudioEncoders[index]->mMaxSampleRate;
+
+    LOGE("The given audio encoder param name %s is not found", name);
+    return -1;
+}
+
+Vector<video_decoder> MediaProfiles::getVideoDecoders() const
+{
+    Vector<video_decoder> decoders;
+    for (size_t i = 0; i < mVideoDecoders.size(); ++i) {
+        decoders.add(mVideoDecoders[i]->mCodec);
+    }
+    return decoders;  // copy out
+}
+
+Vector<audio_decoder> MediaProfiles::getAudioDecoders() const
+{
+    Vector<audio_decoder> decoders;
+    for (size_t i = 0; i < mAudioDecoders.size(); ++i) {
+        decoders.add(mAudioDecoders[i]->mCodec);
+    }
+    return decoders;  // copy out
+}
+
+int MediaProfiles::getCamcorderProfileParamByName(const char *name, camcorder_quality quality) const
+{
+    LOGV("getCamcorderProfileParamByName: %s for quality %d", name, quality);
+
+    int index = -1;
+    for (size_t i = 0, n = mCamcorderProfiles.size(); i < n; ++i) {
+        if (mCamcorderProfiles[i]->mQuality == quality) {
+            index = i;
+            break;
+        }
+    }
+    if (index == -1) {
+        LOGE("The given camcorder profile quality %d is not found", quality);
+        return -1;
+    }
+
+    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;
+    if (!strcmp("vid.height", name)) return mCamcorderProfiles[index]->mVideoCodec->mFrameHeight;
+    if (!strcmp("vid.bps", name)) return mCamcorderProfiles[index]->mVideoCodec->mBitRate;
+    if (!strcmp("vid.fps", name)) return mCamcorderProfiles[index]->mVideoCodec->mFrameRate;
+    if (!strcmp("aud.codec", name)) return mCamcorderProfiles[index]->mAudioCodec->mCodec;
+    if (!strcmp("aud.bps", name)) return mCamcorderProfiles[index]->mAudioCodec->mBitRate;
+    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);
+    return -1;
+}
+
+MediaProfiles::~MediaProfiles()
+{
+    CHECK("destructor should never be called" == 0);
+#if 0
+    for (size_t i = 0; i < mAudioEncoders.size(); ++i) {
+        delete mAudioEncoders[i];
+    }
+    mAudioEncoders.clear();
+
+    for (size_t i = 0; i < mVideoEncoders.size(); ++i) {
+        delete mVideoEncoders[i];
+    }
+    mVideoEncoders.clear();
+
+    for (size_t i = 0; i < mVideoDecoders.size(); ++i) {
+        delete mVideoDecoders[i];
+    }
+    mVideoDecoders.clear();
+
+    for (size_t i = 0; i < mAudioDecoders.size(); ++i) {
+        delete mAudioDecoders[i];
+    }
+    mAudioDecoders.clear();
+
+    for (size_t i = 0; i < mCamcorderProfiles.size(); ++i) {
+        delete mCamcorderProfiles[i];
+    }
+    mCamcorderProfiles.clear();
+#endif
+}
+} // namespace android
