Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b433f0b authored by James Dong's avatar James Dong
Browse files

Image encoding settings java API through xml configuration file

- I decided to completely remove jpeg decoding related stuff from this change
  I think that setting is better off if it is specified by the system properties.
  We don't have to include MediaProfiles.h header in skia files
parent 9a56aaf1
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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
+12 −1
Original line number Diff line number Diff line
@@ -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.
@@ -55,6 +56,14 @@ public class CamcorderProfile
        LOW
    };

    /**
     * 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;
+52 −0
Original line number Diff line number Diff line
/*
 * 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);
}
+38 −4
Original line number Diff line number Diff line
@@ -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);
}
+24 −0
Original line number Diff line number Diff line
@@ -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);