blob: cfc131f5c14bdf1f3902cde63fea39b6cfdc9e19 [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;
Sergey Silkinbe0adee2019-06-26 14:11:03 +020014import java.util.Collections;
15import java.util.List;
Magnus Jedvert1f2a3e72017-11-23 16:56:44 +010016import org.webrtc.EncodedImage;
17
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020018/**
19 * 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 +020020 * encoding thread. The encoder may be constructed on a different thread and changing thread after
21 * calling release is allowed.
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020022 */
23public interface VideoEncoder {
24 /** Settings passed to the encoder by WebRTC. */
25 public class Settings {
26 public final int numberOfCores;
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -070027 public final int width;
28 public final int height;
29 public final int startBitrate; // Kilobits per second.
30 public final int maxFramerate;
Rasmus Brandt85f20cb2018-08-23 13:52:45 +020031 public final int numberOfSimulcastStreams;
sakal07a3bd72017-09-04 03:57:21 -070032 public final boolean automaticResizeOn;
Elad Alon370f93a2019-06-11 14:57:57 +020033 public final Capabilities capabilities;
34
35 // TODO(bugs.webrtc.org/10720): Remove.
36 @Deprecated
37 public Settings(int numberOfCores, int width, int height, int startBitrate, int maxFramerate,
38 int numberOfSimulcastStreams, boolean automaticResizeOn) {
39 this(numberOfCores, width, height, startBitrate, maxFramerate, numberOfSimulcastStreams,
40 automaticResizeOn, new VideoEncoder.Capabilities(false /* lossNotification */));
41 }
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020042
Magnus Jedvert1f2a3e72017-11-23 16:56:44 +010043 @CalledByNative("Settings")
sakal07a3bd72017-09-04 03:57:21 -070044 public Settings(int numberOfCores, int width, int height, int startBitrate, int maxFramerate,
Elad Alon370f93a2019-06-11 14:57:57 +020045 int numberOfSimulcastStreams, boolean automaticResizeOn, Capabilities capabilities) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020046 this.numberOfCores = numberOfCores;
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -070047 this.width = width;
48 this.height = height;
49 this.startBitrate = startBitrate;
50 this.maxFramerate = maxFramerate;
Rasmus Brandt85f20cb2018-08-23 13:52:45 +020051 this.numberOfSimulcastStreams = numberOfSimulcastStreams;
sakal07a3bd72017-09-04 03:57:21 -070052 this.automaticResizeOn = automaticResizeOn;
Elad Alon370f93a2019-06-11 14:57:57 +020053 this.capabilities = capabilities;
54 }
55 }
56
57 /** Capabilities (loss notification, etc.) passed to the encoder by WebRTC. */
58 public class Capabilities {
59 /**
60 * The remote side has support for the loss notification RTCP feedback message format, and will
61 * be sending these feedback messages if necessary.
62 */
63 public final boolean lossNotification;
64
65 @CalledByNative("Capabilities")
66 public Capabilities(boolean lossNotification) {
67 this.lossNotification = lossNotification;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020068 }
69 }
70
71 /** Additional info for encoding. */
72 public class EncodeInfo {
73 public final EncodedImage.FrameType[] frameTypes;
74
Magnus Jedvert1f2a3e72017-11-23 16:56:44 +010075 @CalledByNative("EncodeInfo")
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020076 public EncodeInfo(EncodedImage.FrameType[] frameTypes) {
77 this.frameTypes = frameTypes;
78 }
79 }
80
81 // TODO(sakal): Add values to these classes as necessary.
82 /** Codec specific information about the encoded frame. */
83 public class CodecSpecificInfo {}
84
85 public class CodecSpecificInfoVP8 extends CodecSpecificInfo {}
86
87 public class CodecSpecificInfoVP9 extends CodecSpecificInfo {}
88
89 public class CodecSpecificInfoH264 extends CodecSpecificInfo {}
90
91 /**
92 * Represents bitrate allocated for an encoder to produce frames. Bitrate can be divided between
93 * spatial and temporal layers.
94 */
95 public class BitrateAllocation {
96 // First index is the spatial layer and second the temporal layer.
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -070097 public final int[][] bitratesBbs;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020098
99 /**
100 * Initializes the allocation with a two dimensional array of bitrates. The first index of the
101 * array is the spatial layer and the second index in the temporal layer.
102 */
Magnus Jedvert1f2a3e72017-11-23 16:56:44 +0100103 @CalledByNative("BitrateAllocation")
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -0700104 public BitrateAllocation(int[][] bitratesBbs) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200105 this.bitratesBbs = bitratesBbs;
106 }
107
108 /**
109 * Gets the total bitrate allocated for all layers.
110 */
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -0700111 public int getSum() {
112 int sum = 0;
113 for (int[] spatialLayer : bitratesBbs) {
114 for (int bitrate : spatialLayer) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200115 sum += bitrate;
116 }
117 }
118 return sum;
119 }
120 }
121
122 /** Settings for WebRTC quality based scaling. */
123 public class ScalingSettings {
124 public final boolean on;
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100125 @Nullable public final Integer low;
126 @Nullable public final Integer high;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200127
128 /**
Niels Möllerd0dd90b2018-02-08 10:15:34 +0100129 * Settings to disable quality based scaling.
130 */
131 public static final ScalingSettings OFF = new ScalingSettings();
132
133 /**
134 * Creates settings to enable quality based scaling.
135 *
136 * @param low Average QP at which to scale up the resolution.
137 * @param high Average QP at which to scale down the resolution.
138 */
139 public ScalingSettings(int low, int high) {
140 this.on = true;
141 this.low = low;
142 this.high = high;
143 }
144
145 private ScalingSettings() {
146 this.on = false;
147 this.low = null;
148 this.high = null;
149 }
150
151 // TODO(bugs.webrtc.org/8830): Below constructors are deprecated.
152 // Default thresholds are going away, so thresholds have to be set
153 // when scaling is on.
154 /**
sakal07a3bd72017-09-04 03:57:21 -0700155 * Creates quality based scaling setting.
156 *
157 * @param on True if quality scaling is turned on.
158 */
Niels Möllerd0dd90b2018-02-08 10:15:34 +0100159 @Deprecated
sakal07a3bd72017-09-04 03:57:21 -0700160 public ScalingSettings(boolean on) {
161 this.on = on;
162 this.low = null;
163 this.high = null;
164 }
165
166 /**
167 * Creates quality based scaling settings with custom thresholds.
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200168 *
169 * @param on True if quality scaling is turned on.
170 * @param low Average QP at which to scale up the resolution.
171 * @param high Average QP at which to scale down the resolution.
172 */
Niels Möllerd0dd90b2018-02-08 10:15:34 +0100173 @Deprecated
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200174 public ScalingSettings(boolean on, int low, int high) {
175 this.on = on;
176 this.low = low;
177 this.high = high;
178 }
Sami Kalliomäki8619e8a2018-04-17 14:44:36 +0200179
180 @Override
181 public String toString() {
182 return on ? "[ " + low + ", " + high + " ]" : "OFF";
183 }
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200184 }
185
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200186 /**
Sergey Silkin3d642f82019-07-03 15:09:33 +0200187 * Bitrate limits for resolution.
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200188 */
Sergey Silkin3d642f82019-07-03 15:09:33 +0200189 public class ResolutionBitrateLimits {
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200190 /**
Sergey Silkin3d642f82019-07-03 15:09:33 +0200191 * Maximum size of video frame, in pixels, the bitrate limits are intended for.
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200192 */
193 public final int frameSizePixels;
194
195 /**
196 * Recommended minimum bitrate to start encoding.
197 */
198 public final int minStartBitrateBps;
199
200 /**
201 * Recommended minimum bitrate.
202 */
203 public final int minBitrateBps;
204
205 /**
206 * Recommended maximum bitrate.
207 */
208 public final int maxBitrateBps;
209
Sergey Silkin3d642f82019-07-03 15:09:33 +0200210 public ResolutionBitrateLimits(
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200211 int frameSizePixels, int minStartBitrateBps, int minBitrateBps, int maxBitrateBps) {
212 this.frameSizePixels = frameSizePixels;
213 this.minStartBitrateBps = minStartBitrateBps;
214 this.minBitrateBps = minBitrateBps;
215 this.maxBitrateBps = maxBitrateBps;
216 }
217
Sergey Silkin3d642f82019-07-03 15:09:33 +0200218 @CalledByNative("ResolutionBitrateLimits")
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200219 public int getFrameSizePixels() {
220 return frameSizePixels;
221 }
222
Sergey Silkin3d642f82019-07-03 15:09:33 +0200223 @CalledByNative("ResolutionBitrateLimits")
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200224 public int getMinStartBitrateBps() {
225 return minStartBitrateBps;
226 }
227
Sergey Silkin3d642f82019-07-03 15:09:33 +0200228 @CalledByNative("ResolutionBitrateLimits")
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200229 public int getMinBitrateBps() {
230 return minBitrateBps;
231 }
232
Sergey Silkin3d642f82019-07-03 15:09:33 +0200233 @CalledByNative("ResolutionBitrateLimits")
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200234 public int getMaxBitrateBps() {
235 return maxBitrateBps;
236 }
237 }
238
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200239 public interface Callback {
Sami Kalliomäki11c51dd2018-02-07 12:50:47 +0100240 /**
Niels Möller67309ef2019-09-23 12:47:16 +0200241 * Old encoders assume that the byte buffer held by |frame| is not accessed after the call to
242 * this method returns. If the pipeline downstream needs to hold on to the buffer, it then has
243 * to make its own copy. We want to move to a model where no copying is needed, and instead use
244 * retain()/release() to signal to the encoder when it is safe to reuse the buffer.
245 *
246 * Over the transition, implementations of this class should use the maybeRetain() method if
247 * they want to keep a reference to the buffer, and fall back to copying if that method returns
248 * false.
Sami Kalliomäki11c51dd2018-02-07 12:50:47 +0100249 */
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200250 void onEncodedFrame(EncodedImage frame, CodecSpecificInfo info);
251 }
252
253 /**
Rasmus Brandt42a2fc92018-07-09 13:38:01 +0200254 * The encoder implementation backing this interface is either 1) a Java
255 * encoder (e.g., an Android platform encoder), or alternatively 2) a native
256 * encoder (e.g., a software encoder or a C++ encoder adapter).
257 *
258 * For case 1), createNativeVideoEncoder() should return zero.
259 * In this case, we expect the native library to call the encoder through
260 * JNI using the Java interface declared below.
261 *
262 * For case 2), createNativeVideoEncoder() should return a non-zero value.
263 * In this case, we expect the native library to treat the returned value as
264 * a raw pointer of type webrtc::VideoEncoder* (ownership is transferred to
265 * the caller). The native library should then directly call the
266 * webrtc::VideoEncoder interface without going through JNI. All calls to
267 * the Java interface methods declared below should thus throw an
268 * UnsupportedOperationException.
269 */
270 @CalledByNative
271 default long createNativeVideoEncoder() {
272 return 0;
273 }
274
275 /**
276 * Returns true if the encoder is backed by hardware.
277 */
278 @CalledByNative
279 default boolean isHardwareEncoder() {
280 return true;
281 }
282
283 /**
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200284 * Initializes the encoding process. Call before any calls to encode.
285 */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100286 @CalledByNative VideoCodecStatus initEncode(Settings settings, Callback encodeCallback);
287
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200288 /**
289 * Releases the encoder. No more calls to encode will be made after this call.
290 */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100291 @CalledByNative VideoCodecStatus release();
292
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200293 /**
294 * Requests the encoder to encode a frame.
295 */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100296 @CalledByNative VideoCodecStatus encode(VideoFrame frame, EncodeInfo info);
297
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200298 /** Sets the bitrate allocation and the target framerate for the encoder. */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100299 @CalledByNative VideoCodecStatus setRateAllocation(BitrateAllocation allocation, int framerate);
300
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200301 /** Any encoder that wants to use WebRTC provided quality scaler must implement this method. */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100302 @CalledByNative ScalingSettings getScalingSettings();
303
Sergey Silkin3d642f82019-07-03 15:09:33 +0200304 /** Returns the list of bitrate limits. */
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200305 @CalledByNative
Sergey Silkin3d642f82019-07-03 15:09:33 +0200306 default ResolutionBitrateLimits[] getResolutionBitrateLimits() {
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200307 // TODO(ssilkin): Update downstream projects and remove default implementation.
Sergey Silkin3d642f82019-07-03 15:09:33 +0200308 ResolutionBitrateLimits bitrate_limits[] = {};
309 return bitrate_limits;
Sergey Silkinbe0adee2019-06-26 14:11:03 +0200310 }
311
Sami Kalliomäki5f5fc682017-10-19 11:34:08 +0200312 /**
313 * Should return a descriptive name for the implementation. Gets called once and cached. May be
314 * called from arbitrary thread.
315 */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100316 @CalledByNative String getImplementationName();
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200317}