diff options
author | Lajos Molnar <lajos@google.com> | 2021-04-30 16:31:24 -0700 |
---|---|---|
committer | Lajos Molnar <lajos@google.com> | 2021-05-03 23:27:42 -0700 |
commit | 973b2e89bdb8304045c5eb8b296f30100184e5d5 (patch) | |
tree | 3a3840d40fb866c7743b83446e547ba892af4581 | |
parent | eee1089cb541990f5e7ee988f0842b7dc297e4b8 (diff) |
media: pass full EncoderProfiles from XML
Get multiple audio/video codec profiles from MediaProfiles object
instead of just wrapping the old CamcorderProfiles objects.
Bug: 171673898
Test: atest CamcorderProfileTest
Change-Id: If56ac6c2a89992361f0491d8175af1f89dffd3d0
-rw-r--r-- | media/java/android/media/CamcorderProfile.java | 36 | ||||
-rw-r--r-- | media/java/android/media/EncoderProfiles.java | 4 | ||||
-rw-r--r-- | media/jni/android_media_MediaProfiles.cpp | 82 |
3 files changed, 87 insertions, 35 deletions
diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java index f6f0a590f054..b4fdcb9ba2cf 100644 --- a/media/java/android/media/CamcorderProfile.java +++ b/media/java/android/media/CamcorderProfile.java @@ -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); } /** @@ -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); } diff --git a/media/java/android/media/EncoderProfiles.java b/media/java/android/media/EncoderProfiles.java index d9eabbd4903f..ec8ce2960281 100644 --- a/media/java/android/media/EncoderProfiles.java +++ b/media/java/android/media/EncoderProfiles.java @@ -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 @@ -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() { diff --git a/media/jni/android_media_MediaProfiles.cpp b/media/jni/android_media_MediaProfiles.cpp index 5bc80925eca4..7e9b6c744086 100644 --- a/media/jni/android_media_MediaProfiles.cpp +++ b/media/jni/android_media_MediaProfiles.cpp @@ -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) @@ -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}, }; |