• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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 com.google.android.exoplayer2.transformer;
18 
19 import static com.google.android.exoplayer2.util.Assertions.checkArgument;
20 import static java.lang.annotation.ElementType.TYPE_USE;
21 
22 import android.annotation.SuppressLint;
23 import android.media.MediaCodecInfo;
24 import android.media.MediaFormat;
25 import androidx.annotation.IntDef;
26 import androidx.annotation.Nullable;
27 import androidx.annotation.VisibleForTesting;
28 import com.google.android.exoplayer2.Format;
29 import java.lang.annotation.Documented;
30 import java.lang.annotation.Retention;
31 import java.lang.annotation.RetentionPolicy;
32 import java.lang.annotation.Target;
33 
34 /** Represents the video encoder settings. */
35 public final class VideoEncoderSettings {
36 
37   /** A value for various fields to indicate that the field's value is unknown or not applicable. */
38   public static final int NO_VALUE = Format.NO_VALUE;
39   /** The default encoding color profile. */
40   public static final int DEFAULT_COLOR_PROFILE =
41       MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
42   /** The default I-frame interval in seconds. */
43   public static final float DEFAULT_I_FRAME_INTERVAL_SECONDS = 1.0f;
44 
45   /** A default {@link VideoEncoderSettings}. */
46   public static final VideoEncoderSettings DEFAULT = new Builder().build();
47 
48   /**
49    * The allowed values for {@code bitrateMode}, one of
50    *
51    * <ul>
52    *   <li>Constant quality: {@link MediaCodecInfo.EncoderCapabilities#BITRATE_MODE_CQ}.
53    *   <li>Variable bitrate: {@link MediaCodecInfo.EncoderCapabilities#BITRATE_MODE_VBR}.
54    *   <li>Constant bitrate: {@link MediaCodecInfo.EncoderCapabilities#BITRATE_MODE_CBR}.
55    *   <li>Constant bitrate with frame drops: {@link
56    *       MediaCodecInfo.EncoderCapabilities#BITRATE_MODE_CBR_FD}, available from API31.
57    * </ul>
58    */
59   @SuppressLint("InlinedApi")
60   @Documented
61   @Retention(RetentionPolicy.SOURCE)
62   @Target(TYPE_USE)
63   @IntDef({
64     MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ,
65     MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR,
66     MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR,
67     MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR_FD
68   })
69   public @interface BitrateMode {}
70 
71   /** Builds {@link VideoEncoderSettings} instances. */
72   public static final class Builder {
73     private int bitrate;
74     private @BitrateMode int bitrateMode;
75     private int profile;
76     private int level;
77     private int colorProfile;
78     private float iFrameIntervalSeconds;
79     private int operatingRate;
80     private int priority;
81 
82     /** Creates a new instance. */
Builder()83     public Builder() {
84       this.bitrate = NO_VALUE;
85       this.bitrateMode = MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR;
86       this.profile = NO_VALUE;
87       this.level = NO_VALUE;
88       this.colorProfile = DEFAULT_COLOR_PROFILE;
89       this.iFrameIntervalSeconds = DEFAULT_I_FRAME_INTERVAL_SECONDS;
90       this.operatingRate = NO_VALUE;
91       this.priority = NO_VALUE;
92     }
93 
Builder(VideoEncoderSettings videoEncoderSettings)94     private Builder(VideoEncoderSettings videoEncoderSettings) {
95       this.bitrate = videoEncoderSettings.bitrate;
96       this.bitrateMode = videoEncoderSettings.bitrateMode;
97       this.profile = videoEncoderSettings.profile;
98       this.level = videoEncoderSettings.level;
99       this.colorProfile = videoEncoderSettings.colorProfile;
100       this.iFrameIntervalSeconds = videoEncoderSettings.iFrameIntervalSeconds;
101       this.operatingRate = videoEncoderSettings.operatingRate;
102       this.priority = videoEncoderSettings.priority;
103     }
104 
105     /**
106      * Sets {@link VideoEncoderSettings#bitrate}. The default value is {@link #NO_VALUE}.
107      *
108      * @param bitrate The {@link VideoEncoderSettings#bitrate}.
109      * @return This builder.
110      */
setBitrate(int bitrate)111     public Builder setBitrate(int bitrate) {
112       this.bitrate = bitrate;
113       return this;
114     }
115 
116     /**
117      * Sets {@link VideoEncoderSettings#bitrateMode}. The default value is {@code
118      * MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR}.
119      *
120      * <p>Only {@link MediaCodecInfo.EncoderCapabilities#BITRATE_MODE_VBR} and {@link
121      * MediaCodecInfo.EncoderCapabilities#BITRATE_MODE_CBR} are allowed.
122      *
123      * @param bitrateMode The {@link VideoEncoderSettings#bitrateMode}.
124      * @return This builder.
125      */
setBitrateMode(@itrateMode int bitrateMode)126     public Builder setBitrateMode(@BitrateMode int bitrateMode) {
127       checkArgument(
128           bitrateMode == MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR
129               || bitrateMode == MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR);
130       this.bitrateMode = bitrateMode;
131       return this;
132     }
133 
134     /**
135      * Sets {@link VideoEncoderSettings#profile} and {@link VideoEncoderSettings#level}. The default
136      * values are both {@link #NO_VALUE}.
137      *
138      * <p>The value must be one of the values defined in {@link MediaCodecInfo.CodecProfileLevel},
139      * or {@link #NO_VALUE}.
140      *
141      * <p>Profile and level settings will be ignored when using {@link DefaultEncoderFactory} and
142      * encoding to H264.
143      *
144      * @param encodingProfile The {@link VideoEncoderSettings#profile}.
145      * @param encodingLevel The {@link VideoEncoderSettings#level}.
146      * @return This builder.
147      */
setEncodingProfileLevel(int encodingProfile, int encodingLevel)148     public Builder setEncodingProfileLevel(int encodingProfile, int encodingLevel) {
149       this.profile = encodingProfile;
150       this.level = encodingLevel;
151       return this;
152     }
153 
154     /**
155      * Sets {@link VideoEncoderSettings#colorProfile}. The default value is {@link
156      * #DEFAULT_COLOR_PROFILE}.
157      *
158      * <p>The value must be one of the {@code COLOR_*} constants defined in {@link
159      * MediaCodecInfo.CodecCapabilities}.
160      *
161      * @param colorProfile The {@link VideoEncoderSettings#colorProfile}.
162      * @return This builder.
163      */
setColorProfile(int colorProfile)164     public Builder setColorProfile(int colorProfile) {
165       this.colorProfile = colorProfile;
166       return this;
167     }
168 
169     /**
170      * Sets {@link VideoEncoderSettings#iFrameIntervalSeconds}. The default value is {@link
171      * #DEFAULT_I_FRAME_INTERVAL_SECONDS}.
172      *
173      * @param iFrameIntervalSeconds The {@link VideoEncoderSettings#iFrameIntervalSeconds}.
174      * @return This builder.
175      */
setiFrameIntervalSeconds(float iFrameIntervalSeconds)176     public Builder setiFrameIntervalSeconds(float iFrameIntervalSeconds) {
177       this.iFrameIntervalSeconds = iFrameIntervalSeconds;
178       return this;
179     }
180 
181     /**
182      * Sets encoding operating rate and priority. The default values are {@link #NO_VALUE}.
183      *
184      * @param operatingRate The {@link MediaFormat#KEY_OPERATING_RATE operating rate}.
185      * @param priority The {@link MediaFormat#KEY_PRIORITY priority}.
186      * @return This builder.
187      */
188     @VisibleForTesting
setEncoderPerformanceParameters(int operatingRate, int priority)189     public Builder setEncoderPerformanceParameters(int operatingRate, int priority) {
190       this.operatingRate = operatingRate;
191       this.priority = priority;
192       return this;
193     }
194 
195     /** Builds the instance. */
build()196     public VideoEncoderSettings build() {
197       return new VideoEncoderSettings(
198           bitrate,
199           bitrateMode,
200           profile,
201           level,
202           colorProfile,
203           iFrameIntervalSeconds,
204           operatingRate,
205           priority);
206     }
207   }
208 
209   /** The encoding bitrate. */
210   public final int bitrate;
211   /** One of {@linkplain BitrateMode the allowed modes}. */
212   public final @BitrateMode int bitrateMode;
213   /** The encoding profile. */
214   public final int profile;
215   /** The encoding level. */
216   public final int level;
217   /** The encoding color profile. */
218   public final int colorProfile;
219   /** The encoding I-Frame interval in seconds. */
220   public final float iFrameIntervalSeconds;
221   /** The encoder {@link MediaFormat#KEY_OPERATING_RATE operating rate}. */
222   public final int operatingRate;
223   /** The encoder {@link MediaFormat#KEY_PRIORITY priority}. */
224   public final int priority;
225 
VideoEncoderSettings( int bitrate, int bitrateMode, int profile, int level, int colorProfile, float iFrameIntervalSeconds, int operatingRate, int priority)226   private VideoEncoderSettings(
227       int bitrate,
228       int bitrateMode,
229       int profile,
230       int level,
231       int colorProfile,
232       float iFrameIntervalSeconds,
233       int operatingRate,
234       int priority) {
235     this.bitrate = bitrate;
236     this.bitrateMode = bitrateMode;
237     this.profile = profile;
238     this.level = level;
239     this.colorProfile = colorProfile;
240     this.iFrameIntervalSeconds = iFrameIntervalSeconds;
241     this.operatingRate = operatingRate;
242     this.priority = priority;
243   }
244 
245   /**
246    * Returns a {@link VideoEncoderSettings.Builder} initialized with the values of this instance.
247    */
buildUpon()248   public Builder buildUpon() {
249     return new Builder(this);
250   }
251 
252   @Override
equals(@ullable Object o)253   public boolean equals(@Nullable Object o) {
254     if (this == o) {
255       return true;
256     }
257     if (!(o instanceof VideoEncoderSettings)) {
258       return false;
259     }
260     VideoEncoderSettings that = (VideoEncoderSettings) o;
261     return bitrate == that.bitrate
262         && bitrateMode == that.bitrateMode
263         && profile == that.profile
264         && level == that.level
265         && colorProfile == that.colorProfile
266         && iFrameIntervalSeconds == that.iFrameIntervalSeconds
267         && operatingRate == that.operatingRate
268         && priority == that.priority;
269   }
270 
271   @Override
hashCode()272   public int hashCode() {
273     int result = 7;
274     result = 31 * result + bitrate;
275     result = 31 * result + bitrateMode;
276     result = 31 * result + profile;
277     result = 31 * result + level;
278     result = 31 * result + colorProfile;
279     result = 31 * result + Float.floatToIntBits(iFrameIntervalSeconds);
280     result = 31 * result + operatingRate;
281     result = 31 * result + priority;
282     return result;
283   }
284 }
285