blob: e1984fa83ca7a8e4fa9fe315026c8104f00b3442 [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
Sami Kalliomäkie7592d82018-03-22 13:32:44 +010013import javax.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;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020031
Magnus Jedvert1f2a3e72017-11-23 16:56:44 +010032 @CalledByNative("Settings")
sakal07a3bd72017-09-04 03:57:21 -070033 public Settings(int numberOfCores, int width, int height, int startBitrate, int maxFramerate,
Rasmus Brandt85f20cb2018-08-23 13:52:45 +020034 int numberOfSimulcastStreams, boolean automaticResizeOn) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020035 this.numberOfCores = numberOfCores;
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -070036 this.width = width;
37 this.height = height;
38 this.startBitrate = startBitrate;
39 this.maxFramerate = maxFramerate;
Rasmus Brandt85f20cb2018-08-23 13:52:45 +020040 this.numberOfSimulcastStreams = numberOfSimulcastStreams;
sakal07a3bd72017-09-04 03:57:21 -070041 this.automaticResizeOn = automaticResizeOn;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020042 }
Rasmus Brandt85f20cb2018-08-23 13:52:45 +020043
44 // TODO(http://bugs.webrtc.org/9646): Remove when downstream clients have been updated.
45 public Settings(int numberOfCores, int width, int height, int startBitrate, int maxFramerate,
46 boolean automaticResizeOn) {
47 this(numberOfCores, width, height, startBitrate, maxFramerate, 1, automaticResizeOn);
48 }
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020049 }
50
51 /** Additional info for encoding. */
52 public class EncodeInfo {
53 public final EncodedImage.FrameType[] frameTypes;
54
Magnus Jedvert1f2a3e72017-11-23 16:56:44 +010055 @CalledByNative("EncodeInfo")
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020056 public EncodeInfo(EncodedImage.FrameType[] frameTypes) {
57 this.frameTypes = frameTypes;
58 }
59 }
60
61 // TODO(sakal): Add values to these classes as necessary.
62 /** Codec specific information about the encoded frame. */
63 public class CodecSpecificInfo {}
64
65 public class CodecSpecificInfoVP8 extends CodecSpecificInfo {}
66
67 public class CodecSpecificInfoVP9 extends CodecSpecificInfo {}
68
69 public class CodecSpecificInfoH264 extends CodecSpecificInfo {}
70
71 /**
72 * Represents bitrate allocated for an encoder to produce frames. Bitrate can be divided between
73 * spatial and temporal layers.
74 */
75 public class BitrateAllocation {
76 // First index is the spatial layer and second the temporal layer.
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -070077 public final int[][] bitratesBbs;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020078
79 /**
80 * Initializes the allocation with a two dimensional array of bitrates. The first index of the
81 * array is the spatial layer and the second index in the temporal layer.
82 */
Magnus Jedvert1f2a3e72017-11-23 16:56:44 +010083 @CalledByNative("BitrateAllocation")
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -070084 public BitrateAllocation(int[][] bitratesBbs) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020085 this.bitratesBbs = bitratesBbs;
86 }
87
88 /**
89 * Gets the total bitrate allocated for all layers.
90 */
Bjorn Mellem5c4eebb2017-06-12 09:21:03 -070091 public int getSum() {
92 int sum = 0;
93 for (int[] spatialLayer : bitratesBbs) {
94 for (int bitrate : spatialLayer) {
Sami Kalliomäkie2410e92017-06-02 14:46:12 +020095 sum += bitrate;
96 }
97 }
98 return sum;
99 }
100 }
101
102 /** Settings for WebRTC quality based scaling. */
103 public class ScalingSettings {
104 public final boolean on;
Sami Kalliomäkie7592d82018-03-22 13:32:44 +0100105 @Nullable public final Integer low;
106 @Nullable public final Integer high;
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200107
108 /**
Niels Möllerd0dd90b2018-02-08 10:15:34 +0100109 * Settings to disable quality based scaling.
110 */
111 public static final ScalingSettings OFF = new ScalingSettings();
112
113 /**
114 * Creates settings to enable quality based scaling.
115 *
116 * @param low Average QP at which to scale up the resolution.
117 * @param high Average QP at which to scale down the resolution.
118 */
119 public ScalingSettings(int low, int high) {
120 this.on = true;
121 this.low = low;
122 this.high = high;
123 }
124
125 private ScalingSettings() {
126 this.on = false;
127 this.low = null;
128 this.high = null;
129 }
130
131 // TODO(bugs.webrtc.org/8830): Below constructors are deprecated.
132 // Default thresholds are going away, so thresholds have to be set
133 // when scaling is on.
134 /**
sakal07a3bd72017-09-04 03:57:21 -0700135 * Creates quality based scaling setting.
136 *
137 * @param on True if quality scaling is turned on.
138 */
Niels Möllerd0dd90b2018-02-08 10:15:34 +0100139 @Deprecated
sakal07a3bd72017-09-04 03:57:21 -0700140 public ScalingSettings(boolean on) {
141 this.on = on;
142 this.low = null;
143 this.high = null;
144 }
145
146 /**
147 * Creates quality based scaling settings with custom thresholds.
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200148 *
149 * @param on True if quality scaling is turned on.
150 * @param low Average QP at which to scale up the resolution.
151 * @param high Average QP at which to scale down the resolution.
152 */
Niels Möllerd0dd90b2018-02-08 10:15:34 +0100153 @Deprecated
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200154 public ScalingSettings(boolean on, int low, int high) {
155 this.on = on;
156 this.low = low;
157 this.high = high;
158 }
Sami Kalliomäki8619e8a2018-04-17 14:44:36 +0200159
160 @Override
161 public String toString() {
162 return on ? "[ " + low + ", " + high + " ]" : "OFF";
163 }
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200164 }
165
166 public interface Callback {
Sami Kalliomäki11c51dd2018-02-07 12:50:47 +0100167 /**
168 * Call to return an encoded frame. It is safe to assume the byte buffer held by |frame| is not
169 * accessed after the call to this method returns.
170 */
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200171 void onEncodedFrame(EncodedImage frame, CodecSpecificInfo info);
172 }
173
174 /**
Rasmus Brandt42a2fc92018-07-09 13:38:01 +0200175 * The encoder implementation backing this interface is either 1) a Java
176 * encoder (e.g., an Android platform encoder), or alternatively 2) a native
177 * encoder (e.g., a software encoder or a C++ encoder adapter).
178 *
179 * For case 1), createNativeVideoEncoder() should return zero.
180 * In this case, we expect the native library to call the encoder through
181 * JNI using the Java interface declared below.
182 *
183 * For case 2), createNativeVideoEncoder() should return a non-zero value.
184 * In this case, we expect the native library to treat the returned value as
185 * a raw pointer of type webrtc::VideoEncoder* (ownership is transferred to
186 * the caller). The native library should then directly call the
187 * webrtc::VideoEncoder interface without going through JNI. All calls to
188 * the Java interface methods declared below should thus throw an
189 * UnsupportedOperationException.
190 */
191 @CalledByNative
192 default long createNativeVideoEncoder() {
193 return 0;
194 }
195
196 /**
197 * Returns true if the encoder is backed by hardware.
198 */
199 @CalledByNative
200 default boolean isHardwareEncoder() {
201 return true;
202 }
203
204 /**
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200205 * Initializes the encoding process. Call before any calls to encode.
206 */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100207 @CalledByNative VideoCodecStatus initEncode(Settings settings, Callback encodeCallback);
208
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200209 /**
210 * Releases the encoder. No more calls to encode will be made after this call.
211 */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100212 @CalledByNative VideoCodecStatus release();
213
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200214 /**
215 * Requests the encoder to encode a frame.
216 */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100217 @CalledByNative VideoCodecStatus encode(VideoFrame frame, EncodeInfo info);
218
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200219 /**
220 * Informs the encoder of the packet loss and the round-trip time of the network.
221 *
222 * @param packetLoss How many packets are lost on average per 255 packets.
223 * @param roundTripTimeMs Round-trip time of the network in milliseconds.
224 */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100225 @CalledByNative VideoCodecStatus setChannelParameters(short packetLoss, long roundTripTimeMs);
226
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200227 /** Sets the bitrate allocation and the target framerate for the encoder. */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100228 @CalledByNative VideoCodecStatus setRateAllocation(BitrateAllocation allocation, int framerate);
229
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200230 /** Any encoder that wants to use WebRTC provided quality scaler must implement this method. */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100231 @CalledByNative ScalingSettings getScalingSettings();
232
Sami Kalliomäki5f5fc682017-10-19 11:34:08 +0200233 /**
234 * Should return a descriptive name for the implementation. Gets called once and cached. May be
235 * called from arbitrary thread.
236 */
Magnus Jedvert56231d02017-10-31 17:47:06 +0100237 @CalledByNative String getImplementationName();
Sami Kalliomäkie2410e92017-06-02 14:46:12 +0200238}