Merge "media: add EncoderProfiles" into sc-dev
This commit is contained in:
@@ -20898,6 +20898,7 @@ package android.media {
|
||||
public class CamcorderProfile {
|
||||
method public static android.media.CamcorderProfile get(int);
|
||||
method public static android.media.CamcorderProfile get(int, int);
|
||||
method @Nullable public static android.media.EncoderProfiles getAll(@NonNull String, int);
|
||||
method public static boolean hasProfile(int);
|
||||
method public static boolean hasProfile(int, int);
|
||||
field public static final int QUALITY_1080P = 6; // 0x6
|
||||
@@ -20978,6 +20979,32 @@ package android.media {
|
||||
field @NonNull public final java.util.UUID uuid;
|
||||
}
|
||||
|
||||
public class EncoderProfiles {
|
||||
method @NonNull public java.util.List<android.media.EncoderProfiles.AudioProfile> getAudioProfiles();
|
||||
method public int getDurationSeconds();
|
||||
method public int getFileFormat();
|
||||
method @NonNull public java.util.List<android.media.EncoderProfiles.VideoProfile> getVideoProfiles();
|
||||
}
|
||||
|
||||
public static class EncoderProfiles.AudioProfile {
|
||||
method public int getBitrate();
|
||||
method public int getChannels();
|
||||
method public int getCodec();
|
||||
method @NonNull public String getMediaType();
|
||||
method public int getProfile();
|
||||
method public int getSampleRate();
|
||||
}
|
||||
|
||||
public static class EncoderProfiles.VideoProfile {
|
||||
method public int getBitrate();
|
||||
method public int getCodec();
|
||||
method public int getFrameRate();
|
||||
method public int getHeight();
|
||||
method @NonNull public String getMediaType();
|
||||
method public int getProfile();
|
||||
method public int getWidth();
|
||||
}
|
||||
|
||||
public class ExifInterface {
|
||||
ctor public ExifInterface(@NonNull java.io.File) throws java.io.IOException;
|
||||
ctor public ExifInterface(@NonNull String) throws java.io.IOException;
|
||||
@@ -22904,6 +22931,7 @@ package android.media {
|
||||
method public void setAudioChannels(int);
|
||||
method public void setAudioEncoder(int) throws java.lang.IllegalStateException;
|
||||
method public void setAudioEncodingBitRate(int);
|
||||
method public void setAudioProfile(@NonNull android.media.EncoderProfiles.AudioProfile);
|
||||
method public void setAudioSamplingRate(int);
|
||||
method public void setAudioSource(int) throws java.lang.IllegalStateException;
|
||||
method @Deprecated public void setCamera(android.hardware.Camera);
|
||||
@@ -22932,6 +22960,7 @@ package android.media {
|
||||
method public void setVideoEncodingBitRate(int);
|
||||
method public void setVideoEncodingProfileLevel(int, int);
|
||||
method public void setVideoFrameRate(int) throws java.lang.IllegalStateException;
|
||||
method public void setVideoProfile(@NonNull android.media.EncoderProfiles.VideoProfile);
|
||||
method public void setVideoSize(int, int) throws java.lang.IllegalStateException;
|
||||
method public void setVideoSource(int) throws java.lang.IllegalStateException;
|
||||
method public void start() throws java.lang.IllegalStateException;
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package android.media;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Camera.CameraInfo;
|
||||
@@ -23,6 +26,9 @@ import android.hardware.camera2.CameraManager;
|
||||
import android.hardware.camera2.CameraMetadata;
|
||||
import android.os.Build;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Retrieves the
|
||||
* predefined camcorder profile settings for camcorder applications.
|
||||
@@ -275,6 +281,53 @@ public class CamcorderProfile
|
||||
private static final int QUALITY_HIGH_SPEED_LIST_START = QUALITY_HIGH_SPEED_LOW;
|
||||
private static final int QUALITY_HIGH_SPEED_LIST_END = QUALITY_HIGH_SPEED_4KDCI;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@IntDef({
|
||||
QUALITY_LOW,
|
||||
QUALITY_HIGH,
|
||||
QUALITY_QCIF,
|
||||
QUALITY_CIF,
|
||||
QUALITY_480P,
|
||||
QUALITY_720P,
|
||||
QUALITY_1080P,
|
||||
QUALITY_QVGA,
|
||||
QUALITY_2160P,
|
||||
QUALITY_VGA,
|
||||
QUALITY_4KDCI,
|
||||
QUALITY_QHD,
|
||||
QUALITY_2K,
|
||||
QUALITY_8KUHD,
|
||||
|
||||
QUALITY_TIME_LAPSE_LOW ,
|
||||
QUALITY_TIME_LAPSE_HIGH,
|
||||
QUALITY_TIME_LAPSE_QCIF,
|
||||
QUALITY_TIME_LAPSE_CIF,
|
||||
QUALITY_TIME_LAPSE_480P,
|
||||
QUALITY_TIME_LAPSE_720P,
|
||||
QUALITY_TIME_LAPSE_1080P,
|
||||
QUALITY_TIME_LAPSE_QVGA,
|
||||
QUALITY_TIME_LAPSE_2160P,
|
||||
QUALITY_TIME_LAPSE_VGA,
|
||||
QUALITY_TIME_LAPSE_4KDCI,
|
||||
QUALITY_TIME_LAPSE_QHD,
|
||||
QUALITY_TIME_LAPSE_2K,
|
||||
QUALITY_TIME_LAPSE_8KUHD,
|
||||
|
||||
QUALITY_HIGH_SPEED_LOW,
|
||||
QUALITY_HIGH_SPEED_HIGH,
|
||||
QUALITY_HIGH_SPEED_480P,
|
||||
QUALITY_HIGH_SPEED_720P,
|
||||
QUALITY_HIGH_SPEED_1080P,
|
||||
QUALITY_HIGH_SPEED_2160P,
|
||||
QUALITY_HIGH_SPEED_CIF,
|
||||
QUALITY_HIGH_SPEED_VGA,
|
||||
QUALITY_HIGH_SPEED_4KDCI,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Quality {}
|
||||
|
||||
/**
|
||||
* Default recording duration in seconds before the session is terminated.
|
||||
* This is useful for applications like MMS has limited file size requirement.
|
||||
@@ -385,9 +438,8 @@ public class CamcorderProfile
|
||||
public int audioChannels;
|
||||
|
||||
/**
|
||||
* Returns the camcorder profile for the first back-facing camera on the
|
||||
* device at the given quality level. If the device has no back-facing
|
||||
* camera, this returns null.
|
||||
* Returns the default camcorder profile at the given quality level for the first back-facing
|
||||
* camera on the device. If the device has no back-facing camera, this returns null.
|
||||
* @param quality the target quality level for the camcorder profile
|
||||
* @see #get(int, int)
|
||||
*/
|
||||
@@ -404,8 +456,7 @@ public class CamcorderProfile
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the camcorder profile for the given camera at the given
|
||||
* quality level.
|
||||
* Returns the default camcorder profile for the given camera at the given quality level.
|
||||
*
|
||||
* Quality levels QUALITY_LOW, QUALITY_HIGH are guaranteed to be supported, while
|
||||
* other levels may or may not be supported. The supported levels can be checked using
|
||||
@@ -457,6 +508,7 @@ public class CamcorderProfile
|
||||
* @see #QUALITY_HIGH_SPEED_720P
|
||||
* @see #QUALITY_HIGH_SPEED_1080P
|
||||
* @see #QUALITY_HIGH_SPEED_2160P
|
||||
* @throws IllegalArgumentException if quality is not one of the defined QUALITY_ values.
|
||||
*/
|
||||
public static CamcorderProfile get(int cameraId, int quality) {
|
||||
if (!((quality >= QUALITY_LIST_START &&
|
||||
@@ -472,7 +524,119 @@ public class CamcorderProfile
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if camcorder profile exists for the first back-facing
|
||||
* Returns all encoder profiles of a camcorder profile for the given camera at
|
||||
* the given quality level.
|
||||
*
|
||||
* Quality levels QUALITY_LOW, QUALITY_HIGH are guaranteed to be supported, while
|
||||
* other levels may or may not be supported. The supported levels can be checked using
|
||||
* {@link #hasProfile(int, int)}.
|
||||
* QUALITY_LOW refers to the lowest quality available, while QUALITY_HIGH refers to
|
||||
* the highest quality available.
|
||||
* QUALITY_LOW/QUALITY_HIGH have to match one of qcif, cif, 480p, 720p, 1080p or 2160p.
|
||||
* E.g. if the device supports 480p, 720p, 1080p and 2160p, then low is 480p and high is
|
||||
* 2160p.
|
||||
*
|
||||
* The same is true for time lapse quality levels, i.e. QUALITY_TIME_LAPSE_LOW,
|
||||
* QUALITY_TIME_LAPSE_HIGH are guaranteed to be supported and have to match one of
|
||||
* qcif, cif, 480p, 720p, 1080p, or 2160p.
|
||||
*
|
||||
* For high speed quality levels, they may or may not be supported. If a subset of the levels
|
||||
* are supported, QUALITY_HIGH_SPEED_LOW and QUALITY_HIGH_SPEED_HIGH are guaranteed to be
|
||||
* supported and have to match one of 480p, 720p, or 1080p.
|
||||
*
|
||||
* A camcorder recording session with higher quality level usually has higher output
|
||||
* bit rate, better video and/or audio recording quality, larger video frame
|
||||
* resolution and higher audio sampling rate, etc, than those with lower quality
|
||||
* level.
|
||||
*
|
||||
* @param cameraId the id for the camera. Numeric camera ids parsed from the list received by
|
||||
* invoking {@link CameraManager#getCameraIdList} can be used as long as they
|
||||
* are {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE}
|
||||
* and not
|
||||
* {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL EXTERNAL}.
|
||||
* @param quality the target quality level for the camcorder profile.
|
||||
* @return null if there are no encoder profiles defined for the quality level for the
|
||||
* given camera.
|
||||
* @throws IllegalArgumentException if quality is not one of the defined QUALITY_ values.
|
||||
* @see #QUALITY_LOW
|
||||
* @see #QUALITY_HIGH
|
||||
* @see #QUALITY_QCIF
|
||||
* @see #QUALITY_CIF
|
||||
* @see #QUALITY_480P
|
||||
* @see #QUALITY_720P
|
||||
* @see #QUALITY_1080P
|
||||
* @see #QUALITY_2160P
|
||||
* @see #QUALITY_TIME_LAPSE_LOW
|
||||
* @see #QUALITY_TIME_LAPSE_HIGH
|
||||
* @see #QUALITY_TIME_LAPSE_QCIF
|
||||
* @see #QUALITY_TIME_LAPSE_CIF
|
||||
* @see #QUALITY_TIME_LAPSE_480P
|
||||
* @see #QUALITY_TIME_LAPSE_720P
|
||||
* @see #QUALITY_TIME_LAPSE_1080P
|
||||
* @see #QUALITY_TIME_LAPSE_2160P
|
||||
* @see #QUALITY_HIGH_SPEED_LOW
|
||||
* @see #QUALITY_HIGH_SPEED_HIGH
|
||||
* @see #QUALITY_HIGH_SPEED_480P
|
||||
* @see #QUALITY_HIGH_SPEED_720P
|
||||
* @see #QUALITY_HIGH_SPEED_1080P
|
||||
* @see #QUALITY_HIGH_SPEED_2160P
|
||||
*/
|
||||
@Nullable public static EncoderProfiles getAll(
|
||||
@NonNull String cameraId, @Quality int quality) {
|
||||
if (!((quality >= QUALITY_LIST_START &&
|
||||
quality <= QUALITY_LIST_END) ||
|
||||
(quality >= QUALITY_TIME_LAPSE_LIST_START &&
|
||||
quality <= QUALITY_TIME_LAPSE_LIST_END) ||
|
||||
(quality >= QUALITY_HIGH_SPEED_LIST_START &&
|
||||
quality <= QUALITY_HIGH_SPEED_LIST_END))) {
|
||||
String errMessage = "Unsupported quality level: " + quality;
|
||||
throw new IllegalArgumentException(errMessage);
|
||||
}
|
||||
|
||||
// TODO: get all profiles
|
||||
int id;
|
||||
try {
|
||||
id = Integer.valueOf(cameraId);
|
||||
} 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a camcorder profile exists for the first back-facing
|
||||
* camera at the given quality level.
|
||||
*
|
||||
* <p>
|
||||
@@ -507,7 +671,7 @@ public class CamcorderProfile
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if camcorder profile exists for the given camera at
|
||||
* Returns true if a camcorder profile exists for the given camera at
|
||||
* the given quality level.
|
||||
*
|
||||
* <p>
|
||||
|
||||
351
media/java/android/media/EncoderProfiles.java
Normal file
351
media/java/android/media/EncoderProfiles.java
Normal file
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -752,6 +752,47 @@ public class MediaRecorder implements AudioRouting,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the settings from an AudioProfile for recording.
|
||||
* <p>
|
||||
* This method should be called after the video AND audio sources are set, and before
|
||||
* setOutputFile().
|
||||
* <p>
|
||||
* This method can be used instead of {@link #setProfile} when using EncoderProfiles.
|
||||
*
|
||||
* @param profile the AudioProfile to use
|
||||
* @see android.media.EncoderProfiles
|
||||
* @see android.media.CamcorderProfile#getAll
|
||||
*/
|
||||
public void setAudioProfile(@NonNull EncoderProfiles.AudioProfile profile) {
|
||||
setAudioEncodingBitRate(profile.getBitrate());
|
||||
setAudioChannels(profile.getChannels());
|
||||
setAudioSamplingRate(profile.getSampleRate());
|
||||
setAudioEncoder(profile.getCodec());
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the settings from a VideoProfile object for recording.
|
||||
* <p>
|
||||
* This method should be called after the video AND audio sources are set, and before
|
||||
* setOutputFile().
|
||||
* <p>
|
||||
* This method can be used instead of {@link #setProfile} when using EncoderProfiles.
|
||||
*
|
||||
* @param profile the VideoProfile to use
|
||||
* @see android.media.EncoderProfiles
|
||||
* @see android.media.CamcorderProfile#getAll
|
||||
*/
|
||||
public void setVideoProfile(@NonNull EncoderProfiles.VideoProfile profile) {
|
||||
setVideoFrameRate(profile.getFrameRate());
|
||||
setVideoSize(profile.getWidth(), profile.getHeight());
|
||||
setVideoEncodingBitRate(profile.getBitrate());
|
||||
setVideoEncoder(profile.getCodec());
|
||||
if (profile.getProfile() > 0) {
|
||||
setVideoEncodingProfileLevel(profile.getProfile(), 0 /* level */);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set video frame capture rate. This can be used to set a different video frame capture
|
||||
* rate than the recorded video's playback rate. This method also sets the recording mode
|
||||
@@ -1961,4 +2002,3 @@ public class MediaRecorder implements AudioRouting,
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user