diff options
Diffstat (limited to 'media/java/android/media/EncoderProfiles.java')
-rw-r--r-- | media/java/android/media/EncoderProfiles.java | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/media/java/android/media/EncoderProfiles.java b/media/java/android/media/EncoderProfiles.java new file mode 100644 index 000000000000..ca3daefbdd53 --- /dev/null +++ b/media/java/android/media/EncoderProfiles.java @@ -0,0 +1,351 @@ +/* + * Copyright (C) 2021 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 android.annotation.NonNull; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Describes a set of encoding profiles for a given media (audio and/or video) profile. + * These settings are read-only. + * + * <p>Currently, this is used to describe camera recording profile with more detail than {@link + * CamcorderProfile}, by providing encoding parameters for more than just the default audio + * and/or video codec. + * + * <p>The compressed output from a camera recording session contains two tracks: + * one for audio and one for video. + * <p>In the future audio-only recording profiles may be defined. + * + * <p>Each media profile specifies a set of audio and a set of video specific settings. + * <ul> + * <li> The file output format + * <li> Default file duration + * <p>Video-specific settings are: + * <li> Video codec format + * <li> Video bit rate in bits per second + * <li> Video frame rate in frames per second + * <li> Video frame width and height, + * <li> Video encoder profile. + * <p>Audio-specific settings are: + * <li> Audio codec format + * <li> Audio bit rate in bits per second, + * <li> Audio sample rate + * <li> Number of audio channels for recording. + * </ul> + */ +public class EncoderProfiles +{ + /** + * Default recording duration in seconds before the session is terminated. + * This is useful for applications like MMS has limited file size requirement. + * This could be 0 if there is no default recording duration. + */ + public int getDurationSeconds() { + return durationSecs; + } + + /** + * Recommended output file format + * @see android.media.MediaRecorder.OutputFormat + */ + public int getFileFormat() { + return fileFormat; + } + + /** + * Configuration for a video encoder. + */ + public static class VideoProfile { + /** + * The video encoder being used for the video track + * @see android.media.MediaRecorder.VideoEncoder + */ + public int getCodec() { + return codec; + } + + /** + * The media type of the video encoder being used for the video track + * @see android.media.MediaFormat#KEY_MIME + */ + public @NonNull String getMediaType() { + if (codec == MediaRecorder.VideoEncoder.H263) { + return MediaFormat.MIMETYPE_VIDEO_H263; + } else if (codec == MediaRecorder.VideoEncoder.H264) { + return MediaFormat.MIMETYPE_VIDEO_AVC; + } else if (codec == MediaRecorder.VideoEncoder.MPEG_4_SP) { + return MediaFormat.MIMETYPE_VIDEO_MPEG4; + } else if (codec == MediaRecorder.VideoEncoder.VP8) { + return MediaFormat.MIMETYPE_VIDEO_VP8; + } else if (codec == MediaRecorder.VideoEncoder.HEVC) { + return MediaFormat.MIMETYPE_VIDEO_HEVC; + } + // we should never be here + throw new RuntimeException("Unknown codec"); + } + + /** + * The target video output bitrate in bits per second + * <p> + * This is the target recorded video output bitrate if the application configures the video + * recording via {@link MediaRecorder#setProfile} without specifying any other + * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles + * (from {@link CamcorderProfile#QUALITY_HIGH_SPEED_LOW} to {@link + * CamcorderProfile#QUALITY_HIGH_SPEED_2160P}), this is the bitrate where the video is + * recorded with. If the application intends to record slow motion videos with the high + * speed quality profiles, it must set a different video bitrate that is corresponding to + * the desired recording output bit rate (i.e., the encoded video bitrate during normal + * playback) via {@link MediaRecorder#setVideoEncodingBitRate}. For example, if {@link + * CamcorderProfile#QUALITY_HIGH_SPEED_720P} advertises 240fps {@link #getFrameRate} and + * 64Mbps {@link #getBitrate} in the high speed VideoProfile, and the application + * intends to record 1/8 factor slow motion recording videos, the application must set 30fps + * via {@link MediaRecorder#setVideoFrameRate} and 8Mbps ( {@link #getBitrate} * slow motion + * factor) via {@link MediaRecorder#setVideoEncodingBitRate}. Failing to do so will result + * in videos with unexpected frame rate and bit rate, or {@link MediaRecorder} error if the + * output bit rate exceeds the encoder limit. If the application intends to do the video + * recording with {@link MediaCodec} encoder, it must set each individual field of {@link + * MediaFormat} similarly according to this VideoProfile. + * </p> + * + * @see #getFrameRate + * @see MediaRecorder + * @see MediaCodec + * @see MediaFormat + */ + public int getBitrate() { + return bitrate; + } + + /** + * The target video frame rate in frames per second. + * <p> + * This is the target recorded video output frame rate per second if the application + * configures the video recording via {@link MediaRecorder#setProfile} without specifying + * any other {@link MediaRecorder} encoding parameters. For example, for high speed quality + * profiles (from {@link CamcorderProfile#QUALITY_HIGH_SPEED_LOW} to {@link + * CamcorderProfile#QUALITY_HIGH_SPEED_2160P}), this is the frame rate where the video is + * recorded and played back with. If the application intends to create slow motion use case + * with the high speed quality profiles, it must set a different video frame rate that is + * corresponding to the desired output (playback) frame rate via {@link + * MediaRecorder#setVideoFrameRate}. For example, if {@link + * CamcorderProfile#QUALITY_HIGH_SPEED_720P} advertises 240fps {@link #getFrameRate} + * in the VideoProfile, and the application intends to create 1/8 factor slow motion + * recording videos, the application must set 30fps via {@link + * MediaRecorder#setVideoFrameRate}. Failing to do so will result in high speed videos with + * normal speed playback frame rate (240fps for above example). If the application intends + * to do the video recording with {@link MediaCodec} encoder, it must set each individual + * field of {@link MediaFormat} similarly according to this VideoProfile. + * </p> + * + * @see #getBitrate + * @see MediaRecorder + * @see MediaCodec + * @see MediaFormat + */ + public int getFrameRate() { + return frameRate; + } + + /** + * The target video frame width in pixels + */ + public int getWidth() { + return width; + } + + /** + * The target video frame height in pixels + */ + public int getHeight() { + return height; + } + + /** + * 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. + * + * @see MediaRecorder#setVideoEncodingProfileLevel + * @see MediaFormat#KEY_PROFILE + */ + public int getProfile() { + return profile; + } + + // Constructor called by JNI and CamcorderProfile + /* package private */ VideoProfile(int codec, + int width, + int height, + int frameRate, + int bitrate, + int profile) { + this.codec = codec; + this.width = width; + this.height = height; + this.frameRate = frameRate; + this.bitrate = bitrate; + this.profile = profile; + } + + private int codec; + private int width; + private int height; + private int frameRate; + private int bitrate; + private int profile; + } + + /** + * Returns the defined audio encoder profiles. + * <p> + * The list may be empty. This means there are no audio encoder + * profiles defined. Otherwise, the first profile is the default + * audio profile. + */ + public @NonNull List<AudioProfile> getAudioProfiles() { + return audioProfiles; + } + + /** + * Returns the defined video encoder profiles. + * <p> + * The list may be empty. This means there are no video encoder + * profiles defined. Otherwise, the first profile is the default + * video profile. + */ + public @NonNull List<VideoProfile> getVideoProfiles() { + return videoProfiles; + } + + /** + * Configuration for an audio encoder. + */ + public static class AudioProfile { + /** + * The audio encoder being used for the audio track. + * @see android.media.MediaRecorder.AudioEncoder + */ + public int getCodec() { + return codec; + } + + /** + * The media type of the audio encoder being used for the video track + * @see android.media.MediaFormat#KEY_MIME + */ + public @NonNull String getMediaType() { + if (codec == MediaRecorder.AudioEncoder.AMR_NB) { + return MediaFormat.MIMETYPE_AUDIO_AMR_NB; + } else if (codec == MediaRecorder.AudioEncoder.AMR_WB) { + return MediaFormat.MIMETYPE_AUDIO_AMR_WB; + } else if (codec == MediaRecorder.AudioEncoder.AAC + || codec == MediaRecorder.AudioEncoder.HE_AAC + || codec == MediaRecorder.AudioEncoder.AAC_ELD) { + return MediaFormat.MIMETYPE_AUDIO_AAC; + } else if (codec == MediaRecorder.AudioEncoder.VORBIS) { + return MediaFormat.MIMETYPE_AUDIO_VORBIS; + } else if (codec == MediaRecorder.AudioEncoder.OPUS) { + return MediaFormat.MIMETYPE_AUDIO_OPUS; + } + // we should never be here + throw new RuntimeException("Unknown codec"); + } + + /** + * The target audio output bitrate in bits per second + */ + public int getBitrate() { + return bitrate; + } + + /** + * The audio sampling rate used for the audio track + */ + public int getSampleRate() { + return sampleRate; + } + + /** + * The number of audio channels used for the audio track + */ + public int getChannels() { + return channels; + } + + /** + * 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. + * @see MediaFormat#KEY_PROFILE + */ + public int getProfile() { + if (codec == MediaRecorder.AudioEncoder.AAC) { + return MediaCodecInfo.CodecProfileLevel.AACObjectMain; + } else if (codec == MediaRecorder.AudioEncoder.HE_AAC) { + return MediaCodecInfo.CodecProfileLevel.AACObjectHE; + } else if (codec == MediaRecorder.AudioEncoder.AAC_ELD) { + return MediaCodecInfo.CodecProfileLevel.AACObjectELD; + } + return 0; + } + + + // Constructor called by JNI and CamcorderProfile + /* package private */ AudioProfile( + int codec, + int channels, + int sampleRate, + int bitrate) { + this.codec = codec; + this.channels = channels; + this.sampleRate = sampleRate; + this.bitrate = bitrate; + } + + private int codec; + private int channels; + private int sampleRate; + private int bitrate; + } + + //static { + // System.loadLibrary("media_jni"); + //native_init(); + //} + + private int durationSecs; + private int fileFormat; + // non-modifiable lists + private @NonNull List<AudioProfile> audioProfiles; + private @NonNull List<VideoProfile> videoProfiles; + + // Constructor called by JNI and CamcorderProfile + /* package private */ EncoderProfiles( + int duration, + int fileFormat, + VideoProfile[] videoProfiles, + AudioProfile[] audioProfiles) { + this.durationSecs = duration; + this.fileFormat = fileFormat; + this.videoProfiles = Collections.unmodifiableList(Arrays.asList(videoProfiles)); + this.audioProfiles = Collections.unmodifiableList(Arrays.asList(audioProfiles)); + } +} |