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
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user