• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.media;
18 
19 import android.annotation.NonNull;
20 
21 import java.util.Arrays;
22 import java.util.Collections;
23 import java.util.List;
24 
25 /**
26  * Describes a set of encoding profiles for a given media (audio and/or video) profile.
27  * These settings are read-only.
28  *
29  * <p>Currently, this is used to describe camera recording profile with more detail than {@link
30  * CamcorderProfile}, by providing encoding parameters for more than just the default audio
31  * and/or video codec.
32  *
33  * <p>The compressed output from a camera recording session contains two tracks:
34  * one for audio and one for video.
35  * <p>In the future audio-only recording profiles may be defined.
36  *
37  * <p>Each media profile specifies a set of audio and a set of video specific settings.
38  * <ul>
39  * <li> The file output format
40  * <li> Default file duration
41  * <p>Video-specific settings are:
42  * <li> Video codec format
43  * <li> Video bit rate in bits per second
44  * <li> Video frame rate in frames per second
45  * <li> Video frame width and height,
46  * <li> Video encoder profile.
47  * <p>Audio-specific settings are:
48  * <li> Audio codec format
49  * <li> Audio bit rate in bits per second,
50  * <li> Audio sample rate
51  * <li> Number of audio channels for recording.
52  * </ul>
53  */
54 public final class EncoderProfiles
55 {
56     /**
57      * Default recording duration in seconds before the session is terminated.
58      * This is useful for applications like MMS that have a limited file size requirement.
59      * This could be 0 if there is no default recording duration.
60      */
getDefaultDurationSeconds()61     public int getDefaultDurationSeconds() {
62         return durationSecs;
63     }
64 
65     /**
66      * Recommended output file format
67      * @see android.media.MediaRecorder.OutputFormat
68      */
getRecommendedFileFormat()69     public @MediaRecorder.OutputFormatValues int getRecommendedFileFormat() {
70         return fileFormat;
71     }
72 
73     /**
74      * Configuration for a video encoder.
75      */
76     public final static class VideoProfile {
77         /**
78          * The video encoder being used for the video track
79          * @see android.media.MediaRecorder.VideoEncoder
80          */
getCodec()81         public @MediaRecorder.VideoEncoderValues int getCodec() {
82             return codec;
83         }
84 
85         /**
86          * The media type of the video encoder being used for the video track
87          * @see android.media.MediaFormat#KEY_MIME
88          */
getMediaType()89         public @NonNull String getMediaType() {
90             if (codec == MediaRecorder.VideoEncoder.H263) {
91                 return MediaFormat.MIMETYPE_VIDEO_H263;
92             } else if (codec == MediaRecorder.VideoEncoder.H264) {
93                 return MediaFormat.MIMETYPE_VIDEO_AVC;
94             } else if (codec == MediaRecorder.VideoEncoder.MPEG_4_SP) {
95                 return MediaFormat.MIMETYPE_VIDEO_MPEG4;
96             } else if (codec == MediaRecorder.VideoEncoder.VP8) {
97                 return MediaFormat.MIMETYPE_VIDEO_VP8;
98             } else if (codec == MediaRecorder.VideoEncoder.HEVC) {
99                 return MediaFormat.MIMETYPE_VIDEO_HEVC;
100             }
101             // we should never be here
102             throw new RuntimeException("Unknown codec");
103         }
104 
105         /**
106          * The target video output bitrate in bits per second
107          * <p>
108          * This is the target recorded video output bitrate if the application configures the video
109          * recording via {@link MediaRecorder#setProfile} without specifying any other
110          * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles
111          * (from {@link CamcorderProfile#QUALITY_HIGH_SPEED_LOW} to {@link
112          * CamcorderProfile#QUALITY_HIGH_SPEED_2160P}), this is the bitrate where the video is
113          * recorded with. If the application intends to record slow motion videos with the high
114          * speed quality profiles, it must set a different video bitrate that is corresponding to
115          * the desired recording output bit rate (i.e., the encoded video bitrate during normal
116          * playback) via {@link MediaRecorder#setVideoEncodingBitRate}. For example, if {@link
117          * CamcorderProfile#QUALITY_HIGH_SPEED_720P} advertises 240fps {@link #getFrameRate} and
118          * 64Mbps {@link #getBitrate} in the high speed VideoProfile, and the application
119          * intends to record 1/8 factor slow motion recording videos, the application must set 30fps
120          * via {@link MediaRecorder#setVideoFrameRate} and 8Mbps ( {@link #getBitrate} * slow motion
121          * factor) via {@link MediaRecorder#setVideoEncodingBitRate}. Failing to do so will result
122          * in videos with unexpected frame rate and bit rate, or {@link MediaRecorder} error if the
123          * output bit rate exceeds the encoder limit. If the application intends to do the video
124          * recording with {@link MediaCodec} encoder, it must set each individual field of {@link
125          * MediaFormat} similarly according to this VideoProfile.
126          * </p>
127          *
128          * @see #getFrameRate
129          * @see MediaRecorder
130          * @see MediaCodec
131          * @see MediaFormat
132          */
getBitrate()133         public int getBitrate() {
134             return bitrate;
135         }
136 
137         /**
138          * The target video frame rate in frames per second.
139          * <p>
140          * This is the target recorded video output frame rate per second if the application
141          * configures the video recording via {@link MediaRecorder#setProfile} without specifying
142          * any other {@link MediaRecorder} encoding parameters. For example, for high speed quality
143          * profiles (from {@link CamcorderProfile#QUALITY_HIGH_SPEED_LOW} to {@link
144          * CamcorderProfile#QUALITY_HIGH_SPEED_2160P}), this is the frame rate where the video is
145          * recorded and played back with. If the application intends to create slow motion use case
146          * with the high speed quality profiles, it must set a different video frame rate that is
147          * corresponding to the desired output (playback) frame rate via {@link
148          * MediaRecorder#setVideoFrameRate}. For example, if {@link
149          * CamcorderProfile#QUALITY_HIGH_SPEED_720P} advertises 240fps {@link #getFrameRate}
150          * in the VideoProfile, and the application intends to create 1/8 factor slow motion
151          * recording videos, the application must set 30fps via {@link
152          * MediaRecorder#setVideoFrameRate}. Failing to do so will result in high speed videos with
153          * normal speed playback frame rate (240fps for above example). If the application intends
154          * to do the video recording with {@link MediaCodec} encoder, it must set each individual
155          * field of {@link MediaFormat} similarly according to this VideoProfile.
156          * </p>
157          *
158          * @see #getBitrate
159          * @see MediaRecorder
160          * @see MediaCodec
161          * @see MediaFormat
162          */
getFrameRate()163         public int getFrameRate() {
164             return frameRate;
165         }
166 
167         /**
168          * The target video frame width in pixels
169          */
getWidth()170         public int getWidth() {
171             return width;
172         }
173 
174         /**
175          * The target video frame height in pixels
176          */
getHeight()177         public int getHeight() {
178             return height;
179         }
180 
181         /**
182          * The video encoder profile being used for the video track.
183          * <p>
184          * This value is negative if there is no profile defined for the video codec.
185          *
186          * @see MediaRecorder#setVideoEncodingProfileLevel
187          * @see MediaFormat#KEY_PROFILE
188          */
getProfile()189         public int getProfile() {
190             return profile;
191         }
192 
193         // Constructor called by JNI and CamcorderProfile
VideoProfile(int codec, int width, int height, int frameRate, int bitrate, int profile)194         /* package private */ VideoProfile(int codec,
195                              int width,
196                              int height,
197                              int frameRate,
198                              int bitrate,
199                              int profile) {
200             this.codec = codec;
201             this.width = width;
202             this.height = height;
203             this.frameRate = frameRate;
204             this.bitrate = bitrate;
205             this.profile = profile;
206         }
207 
208         private int codec;
209         private int width;
210         private int height;
211         private int frameRate;
212         private int bitrate;
213         private int profile;
214     }
215 
216     /**
217      * Returns the defined audio encoder profiles.
218      * <p>
219      * The list may be empty. This means there are no audio encoder
220      * profiles defined. Otherwise, the first profile is the default
221      * audio profile.
222      */
getAudioProfiles()223     public @NonNull List<AudioProfile> getAudioProfiles() {
224         return audioProfiles;
225     }
226 
227     /**
228      * Returns the defined video encoder profiles.
229      * <p>
230      * The list may be empty. This means there are no video encoder
231      * profiles defined. Otherwise, the first profile is the default
232      * video profile.
233      */
getVideoProfiles()234     public @NonNull List<VideoProfile> getVideoProfiles() {
235         return videoProfiles;
236     }
237 
238     /**
239      * Configuration for an audio encoder.
240      */
241     public final static class AudioProfile {
242         /**
243          * The audio encoder being used for the audio track.
244          * @see android.media.MediaRecorder.AudioEncoder
245          */
getCodec()246         public @MediaRecorder.AudioEncoderValues int getCodec() {
247             return codec;
248         }
249 
250         /**
251          * The media type of the audio encoder being used for the video track
252          * @see android.media.MediaFormat#KEY_MIME
253          */
getMediaType()254         public @NonNull String getMediaType() {
255             if (codec == MediaRecorder.AudioEncoder.AMR_NB) {
256                 return MediaFormat.MIMETYPE_AUDIO_AMR_NB;
257             } else if (codec == MediaRecorder.AudioEncoder.AMR_WB) {
258                 return MediaFormat.MIMETYPE_AUDIO_AMR_WB;
259             } else if (codec == MediaRecorder.AudioEncoder.AAC
260                     || codec == MediaRecorder.AudioEncoder.HE_AAC
261                     || codec == MediaRecorder.AudioEncoder.AAC_ELD) {
262                 return MediaFormat.MIMETYPE_AUDIO_AAC;
263             } else if (codec == MediaRecorder.AudioEncoder.VORBIS) {
264                 return MediaFormat.MIMETYPE_AUDIO_VORBIS;
265             } else if (codec == MediaRecorder.AudioEncoder.OPUS) {
266                 return MediaFormat.MIMETYPE_AUDIO_OPUS;
267             }
268             // we should never be here
269             throw new RuntimeException("Unknown codec");
270         }
271 
272         /**
273          * The target audio output bitrate in bits per second
274          */
getBitrate()275         public int getBitrate() {
276             return bitrate;
277         }
278 
279         /**
280          * The audio sampling rate used for the audio track
281          */
getSampleRate()282         public int getSampleRate() {
283             return sampleRate;
284         }
285 
286         /**
287          * The number of audio channels used for the audio track
288          */
getChannels()289         public int getChannels() {
290             return channels;
291         }
292 
293         /**
294          * The audio encoder profile being used for the audio track
295          * <p>
296          * This value is negative if there is no profile defined for the audio codec.
297          * @see MediaFormat#KEY_PROFILE
298          */
getProfile()299         public int getProfile() {
300             if (codec == MediaRecorder.AudioEncoder.AAC) {
301                 return MediaCodecInfo.CodecProfileLevel.AACObjectMain;
302             } else if (codec == MediaRecorder.AudioEncoder.HE_AAC) {
303                 return MediaCodecInfo.CodecProfileLevel.AACObjectHE;
304             } else if (codec == MediaRecorder.AudioEncoder.AAC_ELD) {
305                 return MediaCodecInfo.CodecProfileLevel.AACObjectELD;
306             }
307             return profile;
308         }
309 
310 
311         // Constructor called by JNI and CamcorderProfile
AudioProfile( int codec, int channels, int sampleRate, int bitrate, int profile)312         /* package private */ AudioProfile(
313                 int codec,
314                 int channels,
315                 int sampleRate,
316                 int bitrate,
317                 int profile) {
318             this.codec = codec;
319             this.channels = channels;
320             this.sampleRate = sampleRate;
321             this.bitrate = bitrate;
322             this.profile = profile;
323         }
324 
325         private int codec;
326         private int channels;
327         private int sampleRate;
328         private int bitrate;
329         private int profile;  // this contains the profile if codec itself does not
330     }
331 
332     private int durationSecs;
333     private int fileFormat;
334     // non-modifiable lists
335     private @NonNull List<AudioProfile> audioProfiles;
336     private @NonNull List<VideoProfile> videoProfiles;
337 
338     // Constructor called by JNI and CamcorderProfile
EncoderProfiles( int duration, int fileFormat, VideoProfile[] videoProfiles, AudioProfile[] audioProfiles)339     /* package private */ EncoderProfiles(
340             int duration,
341             int fileFormat,
342             VideoProfile[] videoProfiles,
343             AudioProfile[] audioProfiles) {
344         this.durationSecs     = duration;
345         this.fileFormat       = fileFormat;
346         this.videoProfiles    = Collections.unmodifiableList(Arrays.asList(videoProfiles));
347         this.audioProfiles    = Collections.unmodifiableList(Arrays.asList(audioProfiles));
348     }
349 }
350