blob: cb8eb817670c6a569d4ce10612ddce421806217b [file] [log] [blame]
Sami Kalliomäkie2410e92017-06-02 14:46:12 +02001/*
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11package org.webrtc;
12
Artem Titarenko69540f42018-12-10 12:30:46 +010013import android.support.annotation.Nullable;
Magnus Jedvert1f2a3e72017-11-23 16:56:44 +010014import org.webrtc.EncodedImage;
15
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020016/**
17 * Interface for a video encoder that can be used with WebRTC. All calls will be made on the
Sami Kalliomäki5f5fc682017-10-19 11:34:08 +020018 * encoding thread. The encoder may be constructed on a different thread and changing thread after
19 * calling release is allowed.
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020020 */
21public interface VideoEncoder {
22 /** Settings passed to the encoder by WebRTC. */
23 public class Settings {
24 public final int numberOfCores;
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -070025 public final int width;
26 public final int height;
27 public final int startBitrate; // Kilobits per second.
28 public final int maxFramerate;
Rasmus Brandt85f20cb2018-08-23 13:52:45 +020029 public final int numberOfSimulcastStreams;
sakal07a3bd72017-09-04 03:57:21 -070030 public final boolean automaticResizeOn;
Elad Alon370f93a2019-06-11 14:57:57 +020031 public final Capabilities capabilities;
32
33 // TODO(bugs.webrtc.org/10720): Remove.
34 @Deprecated
35 public Settings(int numberOfCores, int width, int height, int startBitrate, int maxFramerate,
36 int numberOfSimulcastStreams, boolean automaticResizeOn) {
37 this(numberOfCores, width, height, startBitrate, maxFramerate, numberOfSimulcastStreams,
38 automaticResizeOn, new VideoEncoder.Capabilities(false /* lossNotification */));
39 }
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020040
Magnus Jedvert1f2a3e72017-11-23 16:56:44 +010041 @CalledByNative("Settings")
sakal07a3bd72017-09-04 03:57:21 -070042 public Settings(int numberOfCores, int width, int height, int startBitrate, int maxFramerate,
Elad Alon370f93a2019-06-11 14:57:57 +020043 int numberOfSimulcastStreams, boolean automaticResizeOn, Capabilities capabilities) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020044 this.numberOfCores = numberOfCores;
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -070045 this.width = width;
46 this.height = height;
47 this.startBitrate = startBitrate;
48 this.maxFramerate = maxFramerate;
Rasmus Brandt85f20cb2018-08-23 13:52:45 +020049 this.numberOfSimulcastStreams = numberOfSimulcastStreams;
sakal07a3bd72017-09-04 03:57:21 -070050 this.automaticResizeOn = automaticResizeOn;
Elad Alon370f93a2019-06-11 14:57:57 +020051 this.capabilities = capabilities;
52 }
53 }
54
55 /** Capabilities (loss notification, etc.) passed to the encoder by WebRTC. */
56 public class Capabilities {
57 /**
58 * The remote side has support for the loss notification RTCP feedback message format, and will
59 * be sending these feedback messages if necessary.
60 */
61 public final boolean lossNotification;
62
63 @CalledByNative("Capabilities")
64 public Capabilities(boolean lossNotification) {
65 this.lossNotification = lossNotification;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020066 }
67 }
68
69 /** Additional info for encoding. */
70 public class EncodeInfo {
71 public final EncodedImage.FrameType[] frameTypes;
72
Magnus Jedvert1f2a3e72017-11-23 16:56:44 +010073 @CalledByNative("EncodeInfo")
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020074 public EncodeInfo(EncodedImage.FrameType[] frameTypes) {
75 this.frameTypes = frameTypes;
76 }
77 }
78
79 // TODO(sakal): Add values to these classes as necessary.
80 /** Codec specific information about the encoded frame. */
81 public class CodecSpecificInfo {}
82
83 public class CodecSpecificInfoVP8 extends CodecSpecificInfo {}
84
85 public class CodecSpecificInfoVP9 extends CodecSpecificInfo {}
86
87 public class CodecSpecificInfoH264 extends CodecSpecificInfo {}
88
89 /**
90 * Represents bitrate allocated for an encoder to produce frames. Bitrate can be divided between
91 * spatial and temporal layers.
92 */
93 public class BitrateAllocation {
94 // First index is the spatial layer and second the temporal layer.
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -070095 public final int[][] bitratesBbs;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020096
97 /**
98 * Initializes the allocation with a two dimensional array of bitrates. The first index of the
99 * array is the spatial layer and the second index in the temporal layer.
100 */
Magnus Jedvert1f2a3e72017-11-23 16:56:44 +0100101 @CalledByNative("BitrateAllocation")
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -0700102 public BitrateAllocation(int[][] bitratesBbs) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200103 this.bitratesBbs = bitratesBbs;
104 }
105
106 /**
107 * Gets the total bitrate allocated for all layers.
108 */
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -0700109 public int getSum() {
110 int sum = 0;
111 for (int[] spatialLayer : bitratesBbs) {
112 for (int bitrate : spatialLayer) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200113 sum += bitrate;
114 }
115 }
116 return sum;
117 }
118 }
119
120 /** Settings for WebRTC quality based scaling. */
121 public class ScalingSettings {
122 public final boolean on;
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100123 @Nullable public final Integer low;
124 @Nullable public final Integer high;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200125
126 /**
Niels Möllerd0dd90b2018-02-08 10:15:34 +0100127 * Settings to disable quality based scaling.
128 */
129 public static final ScalingSettings OFF = new ScalingSettings();
130
131 /**
132 * Creates settings to enable quality based scaling.
133 *
134 * @param low Average QP at which to scale up the resolution.
135 * @param high Average QP at which to scale down the resolution.
136 */
137 public ScalingSettings(int low, int high) {
138 this.on = true;
139 this.low = low;
140 this.high = high;
141 }
142
143 private ScalingSettings() {
144 this.on = false;
145 this.low = null;
146 this.high = null;
147 }
148
149 // TODO(bugs.webrtc.org/8830): Below constructors are deprecated.
150 // Default thresholds are going away, so thresholds have to be set
151 // when scaling is on.
152 /**
sakal07a3bd72017-09-04 03:57:21 -0700153 * Creates quality based scaling setting.
154 *
155 * @param on True if quality scaling is turned on.
156 */
Niels Möllerd0dd90b2018-02-08 10:15:34 +0100157 @Deprecated
sakal07a3bd72017-09-04 03:57:21 -0700158 public ScalingSettings(boolean on) {
159 this.on = on;
160 this.low = null;
161 this.high = null;
162 }
163
164 /**
165 * Creates quality based scaling settings with custom thresholds.
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200166 *
167 * @param on True if quality scaling is turned on.
168 * @param low Average QP at which to scale up the resolution.
169 * @param high Average QP at which to scale down the resolution.
170 */
Niels Möllerd0dd90b2018-02-08 10:15:34 +0100171 @Deprecated
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200172 public ScalingSettings(boolean on, int low, int high) {
173 this.on = on;
174 this.low = low;
175 this.high = high;
176 }
Sami Kalliomäki8619e8a2018-04-17 14:44:36 +0200177
178 @Override
179 public String toString() {
180 return on ? "[ " + low + ", " + high + " ]" : "OFF";
181 }
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200182 }
183
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200184 /**
Sergey Silkin3d642f82019-07-03 15:09:33 +0200185 * Bitrate limits for resolution.
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200186 */
Sergey Silkin3d642f82019-07-03 15:09:33 +0200187 public class ResolutionBitrateLimits {
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200188 /**
Sergey Silkin3d642f82019-07-03 15:09:33 +0200189 * Maximum size of video frame, in pixels, the bitrate limits are intended for.
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200190 */
191 public final int frameSizePixels;
192
193 /**
194 * Recommended minimum bitrate to start encoding.
195 */
196 public final int minStartBitrateBps;
197
198 /**
199 * Recommended minimum bitrate.
200 */
201 public final int minBitrateBps;
202
203 /**
204 * Recommended maximum bitrate.
205 */
206 public final int maxBitrateBps;
207
Sergey Silkin3d642f82019-07-03 15:09:33 +0200208 public ResolutionBitrateLimits(
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200209 int frameSizePixels, int minStartBitrateBps, int minBitrateBps, int maxBitrateBps) {
210 this.frameSizePixels = frameSizePixels;
211 this.minStartBitrateBps = minStartBitrateBps;
212 this.minBitrateBps = minBitrateBps;
213 this.maxBitrateBps = maxBitrateBps;
214 }
215
Sergey Silkin3d642f82019-07-03 15:09:33 +0200216 @CalledByNative("ResolutionBitrateLimits")
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200217 public int getFrameSizePixels() {
218 return frameSizePixels;
219 }
220
Sergey Silkin3d642f82019-07-03 15:09:33 +0200221 @CalledByNative("ResolutionBitrateLimits")
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200222 public int getMinStartBitrateBps() {
223 return minStartBitrateBps;
224 }
225
Sergey Silkin3d642f82019-07-03 15:09:33 +0200226 @CalledByNative("ResolutionBitrateLimits")
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200227 public int getMinBitrateBps() {
228 return minBitrateBps;
229 }
230
Sergey Silkin3d642f82019-07-03 15:09:33 +0200231 @CalledByNative("ResolutionBitrateLimits")
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200232 public int getMaxBitrateBps() {
233 return maxBitrateBps;
234 }
235 }
236
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200237 public interface Callback {
Sami Kalliomäki11c51dd2018-02-07 12:50:47 +0100238 /**
Niels Möller67309ef2019-09-23 12:47:16 +0200239 * Old encoders assume that the byte buffer held by |frame| is not accessed after the call to
240 * this method returns. If the pipeline downstream needs to hold on to the buffer, it then has
241 * to make its own copy. We want to move to a model where no copying is needed, and instead use
242 * retain()/release() to signal to the encoder when it is safe to reuse the buffer.
243 *
244 * Over the transition, implementations of this class should use the maybeRetain() method if
245 * they want to keep a reference to the buffer, and fall back to copying if that method returns
246 * false.
Sami Kalliomäki11c51dd2018-02-07 12:50:47 +0100247 */
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200248 void onEncodedFrame(EncodedImage frame, CodecSpecificInfo info);
249 }
250
251 /**
Rasmus Brandt42a2fc92018-07-09 13:38:01 +0200252 * The encoder implementation backing this interface is either 1) a Java
253 * encoder (e.g., an Android platform encoder), or alternatively 2) a native
254 * encoder (e.g., a software encoder or a C++ encoder adapter).
255 *
256 * For case 1), createNativeVideoEncoder() should return zero.
257 * In this case, we expect the native library to call the encoder through
258 * JNI using the Java interface declared below.
259 *
260 * For case 2), createNativeVideoEncoder() should return a non-zero value.
261 * In this case, we expect the native library to treat the returned value as
262 * a raw pointer of type webrtc::VideoEncoder* (ownership is transferred to
263 * the caller). The native library should then directly call the
264 * webrtc::VideoEncoder interface without going through JNI. All calls to
265 * the Java interface methods declared below should thus throw an
266 * UnsupportedOperationException.
267 */
268 @CalledByNative
269 default long createNativeVideoEncoder() {
270 return 0;
271 }
272
273 /**
274 * Returns true if the encoder is backed by hardware.
275 */
276 @CalledByNative
277 default boolean isHardwareEncoder() {
278 return true;
279 }
280
281 /**
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200282 * Initializes the encoding process. Call before any calls to encode.
283 */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100284 @CalledByNative VideoCodecStatus initEncode(Settings settings, Callback encodeCallback);
285
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200286 /**
287 * Releases the encoder. No more calls to encode will be made after this call.
288 */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100289 @CalledByNative VideoCodecStatus release();
290
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200291 /**
292 * Requests the encoder to encode a frame.
293 */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100294 @CalledByNative VideoCodecStatus encode(VideoFrame frame, EncodeInfo info);
295
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200296 /** Sets the bitrate allocation and the target framerate for the encoder. */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100297 @CalledByNative VideoCodecStatus setRateAllocation(BitrateAllocation allocation, int framerate);
298
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200299 /** Any encoder that wants to use WebRTC provided quality scaler must implement this method. */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100300 @CalledByNative ScalingSettings getScalingSettings();
301
Sergey Silkin3d642f82019-07-03 15:09:33 +0200302 /** Returns the list of bitrate limits. */
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200303 @CalledByNative
Sergey Silkin3d642f82019-07-03 15:09:33 +0200304 default ResolutionBitrateLimits[] getResolutionBitrateLimits() {
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200305 // TODO(ssilkin): Update downstream projects and remove default implementation.
Sergey Silkin3d642f82019-07-03 15:09:33 +0200306 ResolutionBitrateLimits bitrate_limits[] = {};
307 return bitrate_limits;
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200308 }
309
Sami Kalliomäki5f5fc682017-10-19 11:34:08 +0200310 /**
311 * Should return a descriptive name for the implementation. Gets called once and cached. May be
312 * called from arbitrary thread.
313 */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100314 @CalledByNative String getImplementationName();
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200315}