Loading media/java/android/media/CamcorderProfile.java +3 −33 Original line number Diff line number Diff line Loading @@ -602,39 +602,7 @@ public class CamcorderProfile } catch (NumberFormatException e) { return null; } CamcorderProfile cp = native_get_camcorder_profile(id, quality); if (cp == null) { return null; }; EncoderProfiles.AudioProfile[] audioProfiles; // timelapse profiles do not list audio profiles if (cp.quality >= QUALITY_TIME_LAPSE_LIST_START && cp.quality <= QUALITY_TIME_LAPSE_LIST_END) { audioProfiles = new EncoderProfiles.AudioProfile[] { }; } else { audioProfiles = new EncoderProfiles.AudioProfile[] { new EncoderProfiles.AudioProfile( cp.audioCodec, cp.audioChannels, cp.audioSampleRate, cp.audioBitRate) }; } return new EncoderProfiles( cp.duration, cp.fileFormat, new EncoderProfiles.VideoProfile[] { new EncoderProfiles.VideoProfile( cp.videoCodec, cp.videoFrameWidth, cp.videoFrameHeight, cp.videoFrameRate, cp.videoBitRate, 0 /* TODO: get profile */) }, audioProfiles); return native_get_camcorder_profiles(id, quality); } /** Loading Loading @@ -743,6 +711,8 @@ public class CamcorderProfile @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static native final CamcorderProfile native_get_camcorder_profile( int cameraId, int quality); private static native final EncoderProfiles native_get_camcorder_profiles( int cameraId, int quality); private static native final boolean native_has_camcorder_profile( int cameraId, int quality); } media/java/android/media/EncoderProfiles.java +2 −2 Original line number Diff line number Diff line Loading @@ -181,7 +181,7 @@ public final class EncoderProfiles /** * The video encoder profile being used for the video track. * <p> * This value is 0 if there is no profile defined for the video codec. * This value is negative if there is no profile defined for the video codec. * * @see MediaRecorder#setVideoEncodingProfileLevel * @see MediaFormat#KEY_PROFILE Loading Loading @@ -293,7 +293,7 @@ public final class EncoderProfiles /** * The audio encoder profile being used for the audio track * <p> * This value is 0 if there is no profile defined for the audio codec. * This value is negative if there is no profile defined for the audio codec. * @see MediaFormat#KEY_PROFILE */ public int getProfile() { Loading media/jni/android_media_MediaProfiles.cpp +82 −0 Original line number Diff line number Diff line Loading @@ -223,6 +223,86 @@ android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject /* audioChannels); } static jobject android_media_MediaProfiles_native_get_camcorder_profiles(JNIEnv *env, jobject /* thiz */, jint id, jint quality) { ALOGV("native_get_camcorder_profiles: %d %d", id, quality); if (!isCamcorderQualityKnown(quality)) { jniThrowException(env, "java/lang/RuntimeException", "Unknown camcorder profile quality"); return NULL; } camcorder_quality q = static_cast<camcorder_quality>(quality); const MediaProfiles::CamcorderProfile *cp = sProfiles->getCamcorderProfile(id, q); if (!cp) { jniThrowException(env, "java/lang/RuntimeException", "Error retrieving camcorder profile params"); return NULL; } int duration = cp->getDuration(); int fileFormat = cp->getFileFormat(); jclass encoderProfilesClazz = env->FindClass("android/media/EncoderProfiles"); jmethodID encoderProfilesConstructorMethodID = env->GetMethodID(encoderProfilesClazz, "<init>", "(II[Landroid/media/EncoderProfiles$VideoProfile;[Landroid/media/EncoderProfiles$AudioProfile;)V"); jclass videoProfileClazz = env->FindClass("android/media/EncoderProfiles$VideoProfile"); jmethodID videoProfileConstructorMethodID = env->GetMethodID(videoProfileClazz, "<init>", "(IIIIII)V"); jclass audioProfileClazz = env->FindClass("android/media/EncoderProfiles$AudioProfile"); jmethodID audioProfileConstructorMethodID = env->GetMethodID(audioProfileClazz, "<init>", "(IIII)V"); jobjectArray videoCodecs = (jobjectArray)env->NewObjectArray( cp->getVideoCodecs().size(), videoProfileClazz, nullptr); { int i = 0; for (const MediaProfiles::VideoCodec *vc : cp->getVideoCodecs()) { jobject videoCodec = env->NewObject(videoProfileClazz, videoProfileConstructorMethodID, vc->getCodec(), vc->getFrameWidth(), vc->getFrameHeight(), vc->getFrameRate(), vc->getBitrate(), -1 /* profile */); env->SetObjectArrayElement(videoCodecs, i++, videoCodec); } } jobjectArray audioCodecs; if (quality >= CAMCORDER_QUALITY_TIME_LAPSE_LIST_START && quality <= CAMCORDER_QUALITY_TIME_LAPSE_LIST_END) { // timelapse profiles do not have audio codecs audioCodecs = (jobjectArray)env->NewObjectArray(0, audioProfileClazz, nullptr); } else { audioCodecs = (jobjectArray)env->NewObjectArray( cp->getAudioCodecs().size(), audioProfileClazz, nullptr); int i = 0; for (const MediaProfiles::AudioCodec *ac : cp->getAudioCodecs()) { jobject audioCodec = env->NewObject(audioProfileClazz, audioProfileConstructorMethodID, ac->getCodec(), ac->getChannels(), ac->getSampleRate(), ac->getBitrate()); env->SetObjectArrayElement(audioCodecs, i++, audioCodec); } } return env->NewObject(encoderProfilesClazz, encoderProfilesConstructorMethodID, duration, fileFormat, videoCodecs, audioCodecs); } static jboolean android_media_MediaProfiles_native_has_camcorder_profile(JNIEnv* /* env */, jobject /* thiz */, jint id, jint quality) Loading Loading @@ -319,6 +399,8 @@ static const JNINativeMethod gMethodsForCamcorderProfileClass[] = { {"native_init", "()V", (void *)android_media_MediaProfiles_native_init}, {"native_get_camcorder_profile", "(II)Landroid/media/CamcorderProfile;", (void *)android_media_MediaProfiles_native_get_camcorder_profile}, {"native_get_camcorder_profiles", "(II)Landroid/media/EncoderProfiles;", (void *)android_media_MediaProfiles_native_get_camcorder_profiles}, {"native_has_camcorder_profile", "(II)Z", (void *)android_media_MediaProfiles_native_has_camcorder_profile}, }; Loading Loading
media/java/android/media/CamcorderProfile.java +3 −33 Original line number Diff line number Diff line Loading @@ -602,39 +602,7 @@ public class CamcorderProfile } catch (NumberFormatException e) { return null; } CamcorderProfile cp = native_get_camcorder_profile(id, quality); if (cp == null) { return null; }; EncoderProfiles.AudioProfile[] audioProfiles; // timelapse profiles do not list audio profiles if (cp.quality >= QUALITY_TIME_LAPSE_LIST_START && cp.quality <= QUALITY_TIME_LAPSE_LIST_END) { audioProfiles = new EncoderProfiles.AudioProfile[] { }; } else { audioProfiles = new EncoderProfiles.AudioProfile[] { new EncoderProfiles.AudioProfile( cp.audioCodec, cp.audioChannels, cp.audioSampleRate, cp.audioBitRate) }; } return new EncoderProfiles( cp.duration, cp.fileFormat, new EncoderProfiles.VideoProfile[] { new EncoderProfiles.VideoProfile( cp.videoCodec, cp.videoFrameWidth, cp.videoFrameHeight, cp.videoFrameRate, cp.videoBitRate, 0 /* TODO: get profile */) }, audioProfiles); return native_get_camcorder_profiles(id, quality); } /** Loading Loading @@ -743,6 +711,8 @@ public class CamcorderProfile @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private static native final CamcorderProfile native_get_camcorder_profile( int cameraId, int quality); private static native final EncoderProfiles native_get_camcorder_profiles( int cameraId, int quality); private static native final boolean native_has_camcorder_profile( int cameraId, int quality); }
media/java/android/media/EncoderProfiles.java +2 −2 Original line number Diff line number Diff line Loading @@ -181,7 +181,7 @@ public final class EncoderProfiles /** * The video encoder profile being used for the video track. * <p> * This value is 0 if there is no profile defined for the video codec. * This value is negative if there is no profile defined for the video codec. * * @see MediaRecorder#setVideoEncodingProfileLevel * @see MediaFormat#KEY_PROFILE Loading Loading @@ -293,7 +293,7 @@ public final class EncoderProfiles /** * The audio encoder profile being used for the audio track * <p> * This value is 0 if there is no profile defined for the audio codec. * This value is negative if there is no profile defined for the audio codec. * @see MediaFormat#KEY_PROFILE */ public int getProfile() { Loading
media/jni/android_media_MediaProfiles.cpp +82 −0 Original line number Diff line number Diff line Loading @@ -223,6 +223,86 @@ android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject /* audioChannels); } static jobject android_media_MediaProfiles_native_get_camcorder_profiles(JNIEnv *env, jobject /* thiz */, jint id, jint quality) { ALOGV("native_get_camcorder_profiles: %d %d", id, quality); if (!isCamcorderQualityKnown(quality)) { jniThrowException(env, "java/lang/RuntimeException", "Unknown camcorder profile quality"); return NULL; } camcorder_quality q = static_cast<camcorder_quality>(quality); const MediaProfiles::CamcorderProfile *cp = sProfiles->getCamcorderProfile(id, q); if (!cp) { jniThrowException(env, "java/lang/RuntimeException", "Error retrieving camcorder profile params"); return NULL; } int duration = cp->getDuration(); int fileFormat = cp->getFileFormat(); jclass encoderProfilesClazz = env->FindClass("android/media/EncoderProfiles"); jmethodID encoderProfilesConstructorMethodID = env->GetMethodID(encoderProfilesClazz, "<init>", "(II[Landroid/media/EncoderProfiles$VideoProfile;[Landroid/media/EncoderProfiles$AudioProfile;)V"); jclass videoProfileClazz = env->FindClass("android/media/EncoderProfiles$VideoProfile"); jmethodID videoProfileConstructorMethodID = env->GetMethodID(videoProfileClazz, "<init>", "(IIIIII)V"); jclass audioProfileClazz = env->FindClass("android/media/EncoderProfiles$AudioProfile"); jmethodID audioProfileConstructorMethodID = env->GetMethodID(audioProfileClazz, "<init>", "(IIII)V"); jobjectArray videoCodecs = (jobjectArray)env->NewObjectArray( cp->getVideoCodecs().size(), videoProfileClazz, nullptr); { int i = 0; for (const MediaProfiles::VideoCodec *vc : cp->getVideoCodecs()) { jobject videoCodec = env->NewObject(videoProfileClazz, videoProfileConstructorMethodID, vc->getCodec(), vc->getFrameWidth(), vc->getFrameHeight(), vc->getFrameRate(), vc->getBitrate(), -1 /* profile */); env->SetObjectArrayElement(videoCodecs, i++, videoCodec); } } jobjectArray audioCodecs; if (quality >= CAMCORDER_QUALITY_TIME_LAPSE_LIST_START && quality <= CAMCORDER_QUALITY_TIME_LAPSE_LIST_END) { // timelapse profiles do not have audio codecs audioCodecs = (jobjectArray)env->NewObjectArray(0, audioProfileClazz, nullptr); } else { audioCodecs = (jobjectArray)env->NewObjectArray( cp->getAudioCodecs().size(), audioProfileClazz, nullptr); int i = 0; for (const MediaProfiles::AudioCodec *ac : cp->getAudioCodecs()) { jobject audioCodec = env->NewObject(audioProfileClazz, audioProfileConstructorMethodID, ac->getCodec(), ac->getChannels(), ac->getSampleRate(), ac->getBitrate()); env->SetObjectArrayElement(audioCodecs, i++, audioCodec); } } return env->NewObject(encoderProfilesClazz, encoderProfilesConstructorMethodID, duration, fileFormat, videoCodecs, audioCodecs); } static jboolean android_media_MediaProfiles_native_has_camcorder_profile(JNIEnv* /* env */, jobject /* thiz */, jint id, jint quality) Loading Loading @@ -319,6 +399,8 @@ static const JNINativeMethod gMethodsForCamcorderProfileClass[] = { {"native_init", "()V", (void *)android_media_MediaProfiles_native_init}, {"native_get_camcorder_profile", "(II)Landroid/media/CamcorderProfile;", (void *)android_media_MediaProfiles_native_get_camcorder_profile}, {"native_get_camcorder_profiles", "(II)Landroid/media/EncoderProfiles;", (void *)android_media_MediaProfiles_native_get_camcorder_profiles}, {"native_has_camcorder_profile", "(II)Z", (void *)android_media_MediaProfiles_native_has_camcorder_profile}, }; Loading