blob: 2988bf9f41a6fb8763cb31342217e24b4fe8d879 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
phoglund@webrtc.org8bfee842012-02-17 09:32:48 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
andrew@webrtc.orgeda189b2013-09-09 17:50:10 +000011#ifndef WEBRTC_COMMON_TYPES_H_
12#define WEBRTC_COMMON_TYPES_H_
niklase@google.com470e71d2011-07-07 08:21:25 +000013
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000014#include <stddef.h>
mallinath@webrtc.org0209e562014-03-21 00:41:28 +000015#include <string.h>
pbos@webrtc.org1e92b0a2014-05-15 09:35:06 +000016
17#include <string>
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000018#include <vector>
19
kwibergb890c95c2016-11-29 05:30:40 -080020#include "webrtc/base/checks.h"
Erik Språng08127a92016-11-16 16:41:30 +010021#include "webrtc/base/optional.h"
magjed71eb61c2016-09-08 03:24:58 -070022#include "webrtc/common_video/rotation.h"
andrew@webrtc.orgeda189b2013-09-09 17:50:10 +000023#include "webrtc/typedefs.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000024
andrew@webrtc.org88b8b0d2012-08-14 00:05:56 +000025#if defined(_MSC_VER)
26// Disable "new behavior: elements of array will be default initialized"
27// warning. Affects OverUseDetectorOptions.
solenberg634b86e2016-09-01 07:54:53 -070028#pragma warning(disable : 4351)
andrew@webrtc.org88b8b0d2012-08-14 00:05:56 +000029#endif
30
kwiberg77eab702016-09-28 17:42:01 -070031#if defined(WEBRTC_EXPORT)
andrew@webrtc.org88b8b0d2012-08-14 00:05:56 +000032#define WEBRTC_DLLEXPORT _declspec(dllexport)
kwiberg77eab702016-09-28 17:42:01 -070033#elif defined(WEBRTC_DLL)
andrew@webrtc.org88b8b0d2012-08-14 00:05:56 +000034#define WEBRTC_DLLEXPORT _declspec(dllimport)
niklase@google.com470e71d2011-07-07 08:21:25 +000035#else
andrew@webrtc.org88b8b0d2012-08-14 00:05:56 +000036#define WEBRTC_DLLEXPORT
niklase@google.com470e71d2011-07-07 08:21:25 +000037#endif
38
39#ifndef NULL
andrew@webrtc.org88b8b0d2012-08-14 00:05:56 +000040#define NULL 0
niklase@google.com470e71d2011-07-07 08:21:25 +000041#endif
42
Peter Boström8b79b072016-02-26 16:31:37 +010043#define RTP_PAYLOAD_NAME_SIZE 32u
henrika@webrtc.orgf75901f2012-01-16 08:45:42 +000044
mallinath@webrtc.org0209e562014-03-21 00:41:28 +000045#if defined(WEBRTC_WIN) || defined(WIN32)
andrew@webrtc.orgeda189b2013-09-09 17:50:10 +000046// Compares two strings without regard to case.
47#define STR_CASE_CMP(s1, s2) ::_stricmp(s1, s2)
48// Compares characters of two strings without regard to case.
49#define STR_NCASE_CMP(s1, s2, n) ::_strnicmp(s1, s2, n)
50#else
51#define STR_CASE_CMP(s1, s2) ::strcasecmp(s1, s2)
52#define STR_NCASE_CMP(s1, s2, n) ::strncasecmp(s1, s2, n)
53#endif
54
niklase@google.com470e71d2011-07-07 08:21:25 +000055namespace webrtc {
56
tommia6219cc2016-06-15 10:30:14 -070057class RewindableStream {
58 public:
59 virtual ~RewindableStream() {}
60 virtual int Rewind() = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000061};
62
tommia6219cc2016-06-15 10:30:14 -070063class InStream : public RewindableStream {
64 public:
65 // Reads |len| bytes from file to |buf|. Returns the number of bytes read
66 // or -1 on error.
67 virtual int Read(void* buf, size_t len) = 0;
68};
69
70class OutStream : public RewindableStream {
71 public:
72 // Writes |len| bytes from |buf| to file. The actual writing may happen
73 // some time later. Call Flush() to force a write.
74 virtual bool Write(const void* buf, size_t len) = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000075};
76
solenberg634b86e2016-09-01 07:54:53 -070077enum TraceModule {
78 kTraceUndefined = 0,
79 // not a module, triggered from the engine code
80 kTraceVoice = 0x0001,
81 // not a module, triggered from the engine code
82 kTraceVideo = 0x0002,
83 // not a module, triggered from the utility code
84 kTraceUtility = 0x0003,
85 kTraceRtpRtcp = 0x0004,
86 kTraceTransport = 0x0005,
87 kTraceSrtp = 0x0006,
88 kTraceAudioCoding = 0x0007,
89 kTraceAudioMixerServer = 0x0008,
90 kTraceAudioMixerClient = 0x0009,
91 kTraceFile = 0x000a,
92 kTraceAudioProcessing = 0x000b,
93 kTraceVideoCoding = 0x0010,
94 kTraceVideoMixer = 0x0011,
95 kTraceAudioDevice = 0x0012,
96 kTraceVideoRenderer = 0x0014,
97 kTraceVideoCapture = 0x0015,
98 kTraceRemoteBitrateEstimator = 0x0017,
niklase@google.com470e71d2011-07-07 08:21:25 +000099};
100
solenberg634b86e2016-09-01 07:54:53 -0700101enum TraceLevel {
102 kTraceNone = 0x0000, // no trace
103 kTraceStateInfo = 0x0001,
104 kTraceWarning = 0x0002,
105 kTraceError = 0x0004,
106 kTraceCritical = 0x0008,
107 kTraceApiCall = 0x0010,
108 kTraceDefault = 0x00ff,
niklase@google.com470e71d2011-07-07 08:21:25 +0000109
solenberg634b86e2016-09-01 07:54:53 -0700110 kTraceModuleCall = 0x0020,
111 kTraceMemory = 0x0100, // memory info
112 kTraceTimer = 0x0200, // timing info
113 kTraceStream = 0x0400, // "continuous" stream of data
niklase@google.com470e71d2011-07-07 08:21:25 +0000114
solenberg634b86e2016-09-01 07:54:53 -0700115 // used for debug purposes
116 kTraceDebug = 0x0800, // debug
117 kTraceInfo = 0x1000, // debug info
niklase@google.com470e71d2011-07-07 08:21:25 +0000118
solenberg634b86e2016-09-01 07:54:53 -0700119 // Non-verbose level used by LS_INFO of logging.h. Do not use directly.
120 kTraceTerseInfo = 0x2000,
andrew@webrtc.org655d8f52012-11-20 07:34:45 +0000121
solenberg634b86e2016-09-01 07:54:53 -0700122 kTraceAll = 0xffff
niklase@google.com470e71d2011-07-07 08:21:25 +0000123};
124
125// External Trace API
andrew@webrtc.org23ec30b2012-11-15 05:33:25 +0000126class TraceCallback {
127 public:
128 virtual void Print(TraceLevel level, const char* message, int length) = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000129
andrew@webrtc.org23ec30b2012-11-15 05:33:25 +0000130 protected:
131 virtual ~TraceCallback() {}
132 TraceCallback() {}
133};
niklase@google.com470e71d2011-07-07 08:21:25 +0000134
solenberg634b86e2016-09-01 07:54:53 -0700135enum FileFormats {
136 kFileFormatWavFile = 1,
137 kFileFormatCompressedFile = 2,
138 kFileFormatPreencodedFile = 4,
139 kFileFormatPcm16kHzFile = 7,
140 kFileFormatPcm8kHzFile = 8,
141 kFileFormatPcm32kHzFile = 9
niklase@google.com470e71d2011-07-07 08:21:25 +0000142};
143
solenberg634b86e2016-09-01 07:54:53 -0700144enum ProcessingTypes {
145 kPlaybackPerChannel = 0,
146 kPlaybackAllChannelsMixed,
147 kRecordingPerChannel,
148 kRecordingAllChannelsMixed,
149 kRecordingPreprocessing
niklase@google.com470e71d2011-07-07 08:21:25 +0000150};
151
pbos22993e12015-10-19 02:39:06 -0700152enum FrameType {
153 kEmptyFrame = 0,
154 kAudioFrameSpeech = 1,
155 kAudioFrameCN = 2,
156 kVideoFrameKey = 3,
157 kVideoFrameDelta = 4,
sprang@webrtc.org71f055f2013-12-04 15:09:27 +0000158};
159
sprang@webrtc.orgdc50aae2013-11-20 16:47:07 +0000160// Statistics for an RTCP channel
sprang@webrtc.orgfe5d36b2013-10-28 09:21:07 +0000161struct RtcpStatistics {
sprang@webrtc.orgfe5d36b2013-10-28 09:21:07 +0000162 RtcpStatistics()
solenberg634b86e2016-09-01 07:54:53 -0700163 : fraction_lost(0),
164 cumulative_lost(0),
165 extended_max_sequence_number(0),
166 jitter(0) {}
sprang@webrtc.orgfe5d36b2013-10-28 09:21:07 +0000167
168 uint8_t fraction_lost;
169 uint32_t cumulative_lost;
170 uint32_t extended_max_sequence_number;
171 uint32_t jitter;
sprang@webrtc.orgfe5d36b2013-10-28 09:21:07 +0000172};
173
sprang@webrtc.orgdc50aae2013-11-20 16:47:07 +0000174class RtcpStatisticsCallback {
175 public:
176 virtual ~RtcpStatisticsCallback() {}
177
178 virtual void StatisticsUpdated(const RtcpStatistics& statistics,
179 uint32_t ssrc) = 0;
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000180 virtual void CNameChanged(const char* cname, uint32_t ssrc) = 0;
sprang@webrtc.orgdc50aae2013-11-20 16:47:07 +0000181};
182
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000183// Statistics for RTCP packet types.
184struct RtcpPacketTypeCounter {
185 RtcpPacketTypeCounter()
solenberg634b86e2016-09-01 07:54:53 -0700186 : first_packet_time_ms(-1),
187 nack_packets(0),
188 fir_packets(0),
189 pli_packets(0),
190 nack_requests(0),
191 unique_nack_requests(0) {}
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000192
193 void Add(const RtcpPacketTypeCounter& other) {
194 nack_packets += other.nack_packets;
195 fir_packets += other.fir_packets;
196 pli_packets += other.pli_packets;
asapersson@webrtc.org2dd31342014-10-29 12:42:30 +0000197 nack_requests += other.nack_requests;
198 unique_nack_requests += other.unique_nack_requests;
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000199 if (other.first_packet_time_ms != -1 &&
solenberg634b86e2016-09-01 07:54:53 -0700200 (other.first_packet_time_ms < first_packet_time_ms ||
201 first_packet_time_ms == -1)) {
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000202 // Use oldest time.
203 first_packet_time_ms = other.first_packet_time_ms;
204 }
205 }
206
sprang07fb9be2016-02-24 07:55:00 -0800207 void Subtract(const RtcpPacketTypeCounter& other) {
208 nack_packets -= other.nack_packets;
209 fir_packets -= other.fir_packets;
210 pli_packets -= other.pli_packets;
211 nack_requests -= other.nack_requests;
212 unique_nack_requests -= other.unique_nack_requests;
213 if (other.first_packet_time_ms != -1 &&
214 (other.first_packet_time_ms > first_packet_time_ms ||
215 first_packet_time_ms == -1)) {
216 // Use youngest time.
217 first_packet_time_ms = other.first_packet_time_ms;
218 }
219 }
220
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000221 int64_t TimeSinceFirstPacketInMs(int64_t now_ms) const {
222 return (first_packet_time_ms == -1) ? -1 : (now_ms - first_packet_time_ms);
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000223 }
224
asapersson@webrtc.org2dd31342014-10-29 12:42:30 +0000225 int UniqueNackRequestsInPercent() const {
226 if (nack_requests == 0) {
227 return 0;
228 }
solenberg634b86e2016-09-01 07:54:53 -0700229 return static_cast<int>((unique_nack_requests * 100.0f / nack_requests) +
230 0.5f);
asapersson@webrtc.org2dd31342014-10-29 12:42:30 +0000231 }
232
solenberg634b86e2016-09-01 07:54:53 -0700233 int64_t first_packet_time_ms; // Time when first packet is sent/received.
234 uint32_t nack_packets; // Number of RTCP NACK packets.
235 uint32_t fir_packets; // Number of RTCP FIR packets.
236 uint32_t pli_packets; // Number of RTCP PLI packets.
237 uint32_t nack_requests; // Number of NACKed RTP packets.
asapersson@webrtc.org2dd31342014-10-29 12:42:30 +0000238 uint32_t unique_nack_requests; // Number of unique NACKed RTP packets.
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000239};
240
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000241class RtcpPacketTypeCounterObserver {
242 public:
243 virtual ~RtcpPacketTypeCounterObserver() {}
244 virtual void RtcpPacketTypesCounterUpdated(
245 uint32_t ssrc,
246 const RtcpPacketTypeCounter& packet_counter) = 0;
247};
248
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000249// Rate statistics for a stream.
sprang@webrtc.orgdc50aae2013-11-20 16:47:07 +0000250struct BitrateStatistics {
sprangcd349d92016-07-13 09:11:28 -0700251 BitrateStatistics() : bitrate_bps(0), packet_rate(0) {}
sprang@webrtc.orgdc50aae2013-11-20 16:47:07 +0000252
solenberg634b86e2016-09-01 07:54:53 -0700253 uint32_t bitrate_bps; // Bitrate in bits per second.
254 uint32_t packet_rate; // Packet rate in packets per second.
sprang@webrtc.orgdc50aae2013-11-20 16:47:07 +0000255};
256
257// Callback, used to notify an observer whenever new rates have been estimated.
258class BitrateStatisticsObserver {
259 public:
260 virtual ~BitrateStatisticsObserver() {}
261
sprangcd349d92016-07-13 09:11:28 -0700262 virtual void Notify(uint32_t total_bitrate_bps,
263 uint32_t retransmit_bitrate_bps,
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000264 uint32_t ssrc) = 0;
sprang@webrtc.orgdc50aae2013-11-20 16:47:07 +0000265};
266
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000267struct FrameCounts {
268 FrameCounts() : key_frames(0), delta_frames(0) {}
269 int key_frames;
270 int delta_frames;
271};
272
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000273// Callback, used to notify an observer whenever frame counts have been updated.
sprang@webrtc.orgdc50aae2013-11-20 16:47:07 +0000274class FrameCountObserver {
275 public:
sprang@webrtc.org72964bd2013-11-21 09:09:54 +0000276 virtual ~FrameCountObserver() {}
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000277 virtual void FrameCountUpdated(const FrameCounts& frame_counts,
278 uint32_t ssrc) = 0;
sprang@webrtc.orgdc50aae2013-11-20 16:47:07 +0000279};
280
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000281// Callback, used to notify an observer whenever the send-side delay is updated.
282class SendSideDelayObserver {
283 public:
284 virtual ~SendSideDelayObserver() {}
285 virtual void SendSideDelayUpdated(int avg_delay_ms,
286 int max_delay_ms,
287 uint32_t ssrc) = 0;
288};
289
asapersson35151f32016-05-02 23:44:01 -0700290// Callback, used to notify an observer whenever a packet is sent to the
291// transport.
292// TODO(asapersson): This class will remove the need for SendSideDelayObserver.
293// Remove SendSideDelayObserver once possible.
294class SendPacketObserver {
295 public:
296 virtual ~SendPacketObserver() {}
297 virtual void OnSendPacket(uint16_t packet_id,
298 int64_t capture_time_ms,
299 uint32_t ssrc) = 0;
300};
301
michaelt4da30442016-11-17 01:38:43 -0800302// Callback, used to notify an observer when the overhead per packet
303// has changed.
304class OverheadObserver {
305 public:
306 virtual ~OverheadObserver() = default;
307 virtual void OnOverheadChanged(size_t overhead_bytes_per_packet) = 0;
308};
309
niklase@google.com470e71d2011-07-07 08:21:25 +0000310// ==================================================================
311// Voice specific types
312// ==================================================================
313
314// Each codec supported can be described by this structure.
mallinath@webrtc.org0209e562014-03-21 00:41:28 +0000315struct CodecInst {
316 int pltype;
317 char plname[RTP_PAYLOAD_NAME_SIZE];
318 int plfreq;
319 int pacsize;
Peter Kasting69558702016-01-12 16:26:35 -0800320 size_t channels;
mallinath@webrtc.org0209e562014-03-21 00:41:28 +0000321 int rate; // bits/sec unlike {start,min,max}Bitrate elsewhere in this file!
322
323 bool operator==(const CodecInst& other) const {
324 return pltype == other.pltype &&
325 (STR_CASE_CMP(plname, other.plname) == 0) &&
solenberg634b86e2016-09-01 07:54:53 -0700326 plfreq == other.plfreq && pacsize == other.pacsize &&
327 channels == other.channels && rate == other.rate;
mallinath@webrtc.org0209e562014-03-21 00:41:28 +0000328 }
329
solenberg634b86e2016-09-01 07:54:53 -0700330 bool operator!=(const CodecInst& other) const { return !(*this == other); }
niklase@google.com470e71d2011-07-07 08:21:25 +0000331};
332
niklase@google.com470e71d2011-07-07 08:21:25 +0000333// RTP
solenberg634b86e2016-09-01 07:54:53 -0700334enum { kRtpCsrcSize = 15 }; // RFC 3550 page 13
niklase@google.com470e71d2011-07-07 08:21:25 +0000335
solenberg634b86e2016-09-01 07:54:53 -0700336enum PayloadFrequencies {
337 kFreq8000Hz = 8000,
338 kFreq16000Hz = 16000,
339 kFreq32000Hz = 32000
niklase@google.com470e71d2011-07-07 08:21:25 +0000340};
341
solenberg634b86e2016-09-01 07:54:53 -0700342// Degree of bandwidth reduction.
343enum VadModes {
344 kVadConventional = 0, // lowest reduction
345 kVadAggressiveLow,
346 kVadAggressiveMid,
347 kVadAggressiveHigh // highest reduction
niklase@google.com470e71d2011-07-07 08:21:25 +0000348};
349
solenberg634b86e2016-09-01 07:54:53 -0700350// NETEQ statistics.
351struct NetworkStatistics {
352 // current jitter buffer size in ms
353 uint16_t currentBufferSize;
354 // preferred (optimal) buffer size in ms
355 uint16_t preferredBufferSize;
356 // adding extra delay due to "peaky jitter"
357 bool jitterPeaksFound;
358 // Loss rate (network + late); fraction between 0 and 1, scaled to Q14.
359 uint16_t currentPacketLossRate;
360 // Late loss rate; fraction between 0 and 1, scaled to Q14.
361 uint16_t currentDiscardRate;
362 // fraction (of original stream) of synthesized audio inserted through
363 // expansion (in Q14)
364 uint16_t currentExpandRate;
365 // fraction (of original stream) of synthesized speech inserted through
366 // expansion (in Q14)
367 uint16_t currentSpeechExpandRate;
368 // fraction of synthesized speech inserted through pre-emptive expansion
369 // (in Q14)
370 uint16_t currentPreemptiveRate;
371 // fraction of data removed through acceleration (in Q14)
372 uint16_t currentAccelerateRate;
373 // fraction of data coming from secondary decoding (in Q14)
374 uint16_t currentSecondaryDecodedRate;
375 // clock-drift in parts-per-million (negative or positive)
376 int32_t clockDriftPPM;
377 // average packet waiting time in the jitter buffer (ms)
378 int meanWaitingTimeMs;
379 // median packet waiting time in the jitter buffer (ms)
380 int medianWaitingTimeMs;
381 // min packet waiting time in the jitter buffer (ms)
382 int minWaitingTimeMs;
383 // max packet waiting time in the jitter buffer (ms)
384 int maxWaitingTimeMs;
385 // added samples in off mode due to packet loss
386 size_t addedSamples;
niklase@google.com470e71d2011-07-07 08:21:25 +0000387};
388
wu@webrtc.org24301a62013-12-13 19:17:43 +0000389// Statistics for calls to AudioCodingModule::PlayoutData10Ms().
390struct AudioDecodingCallStats {
391 AudioDecodingCallStats()
392 : calls_to_silence_generator(0),
393 calls_to_neteq(0),
394 decoded_normal(0),
395 decoded_plc(0),
396 decoded_cng(0),
henrik.lundin63489782016-09-20 01:47:12 -0700397 decoded_plc_cng(0),
398 decoded_muted_output(0) {}
wu@webrtc.org24301a62013-12-13 19:17:43 +0000399
400 int calls_to_silence_generator; // Number of calls where silence generated,
401 // and NetEq was disengaged from decoding.
solenberg634b86e2016-09-01 07:54:53 -0700402 int calls_to_neteq; // Number of calls to NetEq.
wu@webrtc.org24301a62013-12-13 19:17:43 +0000403 int decoded_normal; // Number of calls where audio RTP packet decoded.
solenberg634b86e2016-09-01 07:54:53 -0700404 int decoded_plc; // Number of calls resulted in PLC.
wu@webrtc.org24301a62013-12-13 19:17:43 +0000405 int decoded_cng; // Number of calls where comfort noise generated due to DTX.
406 int decoded_plc_cng; // Number of calls resulted where PLC faded to CNG.
henrik.lundin63489782016-09-20 01:47:12 -0700407 int decoded_muted_output; // Number of calls returning a muted state output.
wu@webrtc.org24301a62013-12-13 19:17:43 +0000408};
409
solenberg634b86e2016-09-01 07:54:53 -0700410// Type of Noise Suppression.
411enum NsModes {
412 kNsUnchanged = 0, // previously set mode
413 kNsDefault, // platform default
414 kNsConference, // conferencing default
415 kNsLowSuppression, // lowest suppression
416 kNsModerateSuppression,
417 kNsHighSuppression,
418 kNsVeryHighSuppression, // highest suppression
niklase@google.com470e71d2011-07-07 08:21:25 +0000419};
420
solenberg634b86e2016-09-01 07:54:53 -0700421// Type of Automatic Gain Control.
422enum AgcModes {
423 kAgcUnchanged = 0, // previously set mode
424 kAgcDefault, // platform default
425 // adaptive mode for use when analog volume control exists (e.g. for
426 // PC softphone)
427 kAgcAdaptiveAnalog,
428 // scaling takes place in the digital domain (e.g. for conference servers
429 // and embedded devices)
430 kAgcAdaptiveDigital,
431 // can be used on embedded devices where the capture signal level
432 // is predictable
433 kAgcFixedDigital
niklase@google.com470e71d2011-07-07 08:21:25 +0000434};
435
solenberg634b86e2016-09-01 07:54:53 -0700436// Type of Echo Control.
437enum EcModes {
438 kEcUnchanged = 0, // previously set mode
439 kEcDefault, // platform default
440 kEcConference, // conferencing default (aggressive AEC)
441 kEcAec, // Acoustic Echo Cancellation
442 kEcAecm, // AEC mobile
niklase@google.com470e71d2011-07-07 08:21:25 +0000443};
444
solenberg634b86e2016-09-01 07:54:53 -0700445// Mode of AECM.
446enum AecmModes {
447 kAecmQuietEarpieceOrHeadset = 0,
448 // Quiet earpiece or headset use
449 kAecmEarpiece, // most earpiece use
450 kAecmLoudEarpiece, // Loud earpiece or quiet speakerphone use
451 kAecmSpeakerphone, // most speakerphone use (default)
452 kAecmLoudSpeakerphone // Loud speakerphone
niklase@google.com470e71d2011-07-07 08:21:25 +0000453};
454
solenbergbe5163c2016-08-31 14:48:53 -0700455// AGC configuration parameters
solenberg634b86e2016-09-01 07:54:53 -0700456struct AgcConfig {
457 unsigned short targetLeveldBOv;
458 unsigned short digitalCompressionGaindB;
459 bool limiterEnable;
solenbergbe5163c2016-08-31 14:48:53 -0700460};
niklase@google.com470e71d2011-07-07 08:21:25 +0000461
solenberg634b86e2016-09-01 07:54:53 -0700462enum StereoChannel { kStereoLeft = 0, kStereoRight, kStereoBoth };
niklase@google.com470e71d2011-07-07 08:21:25 +0000463
464// Audio device layers
solenberg634b86e2016-09-01 07:54:53 -0700465enum AudioLayers {
466 kAudioPlatformDefault = 0,
467 kAudioWindowsWave = 1,
468 kAudioWindowsCore = 2,
469 kAudioLinuxAlsa = 3,
470 kAudioLinuxPulse = 4
niklase@google.com470e71d2011-07-07 08:21:25 +0000471};
472
niklase@google.com470e71d2011-07-07 08:21:25 +0000473// ==================================================================
474// Video specific types
475// ==================================================================
476
477// Raw video types
solenberg634b86e2016-09-01 07:54:53 -0700478enum RawVideoType {
479 kVideoI420 = 0,
480 kVideoYV12 = 1,
481 kVideoYUY2 = 2,
482 kVideoUYVY = 3,
483 kVideoIYUV = 4,
484 kVideoARGB = 5,
485 kVideoRGB24 = 6,
486 kVideoRGB565 = 7,
487 kVideoARGB4444 = 8,
488 kVideoARGB1555 = 9,
489 kVideoMJPEG = 10,
490 kVideoNV12 = 11,
491 kVideoNV21 = 12,
492 kVideoBGRA = 13,
493 kVideoUnknown = 99
niklase@google.com470e71d2011-07-07 08:21:25 +0000494};
495
496// Video codec
solenberg634b86e2016-09-01 07:54:53 -0700497enum { kConfigParameterSize = 128 };
498enum { kPayloadNameSize = 32 };
499enum { kMaxSimulcastStreams = 4 };
sprangce4aef12015-11-02 07:23:20 -0800500enum { kMaxSpatialLayers = 5 };
solenberg634b86e2016-09-01 07:54:53 -0700501enum { kMaxTemporalStreams = 4 };
niklase@google.com470e71d2011-07-07 08:21:25 +0000502
solenberg634b86e2016-09-01 07:54:53 -0700503enum VideoCodecComplexity {
504 kComplexityNormal = 0,
505 kComplexityHigh = 1,
506 kComplexityHigher = 2,
507 kComplexityMax = 3
niklase@google.com470e71d2011-07-07 08:21:25 +0000508};
509
stefan@webrtc.orgefd0a482011-12-29 10:12:35 +0000510enum VP8ResilienceMode {
511 kResilienceOff, // The stream produced by the encoder requires a
512 // recovery frame (typically a key frame) to be
513 // decodable after a packet loss.
514 kResilientStream, // A stream produced by the encoder is resilient to
515 // packet losses, but packets within a frame subsequent
516 // to a loss can't be decoded.
517 kResilientFrames // Same as kResilientStream but with added resilience
518 // within a frame.
519};
520
Peter Boström7b971e72016-01-19 16:26:16 +0100521class TemporalLayersFactory;
niklase@google.com470e71d2011-07-07 08:21:25 +0000522// VP8 specific
mallinath@webrtc.org0209e562014-03-21 00:41:28 +0000523struct VideoCodecVP8 {
solenberg634b86e2016-09-01 07:54:53 -0700524 bool pictureLossIndicationOn;
525 bool feedbackModeOn;
mallinath@webrtc.org0209e562014-03-21 00:41:28 +0000526 VideoCodecComplexity complexity;
solenberg634b86e2016-09-01 07:54:53 -0700527 VP8ResilienceMode resilience;
528 unsigned char numberOfTemporalLayers;
529 bool denoisingOn;
530 bool errorConcealmentOn;
531 bool automaticResizeOn;
532 bool frameDroppingOn;
533 int keyFrameInterval;
Erik Språng08127a92016-11-16 16:41:30 +0100534 TemporalLayersFactory* tl_factory;
niklase@google.com470e71d2011-07-07 08:21:25 +0000535};
536
asaperssona9455ab2015-07-31 06:10:09 -0700537// VP9 specific.
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000538struct VideoCodecVP9 {
539 VideoCodecComplexity complexity;
solenberg634b86e2016-09-01 07:54:53 -0700540 int resilience;
541 unsigned char numberOfTemporalLayers;
542 bool denoisingOn;
543 bool frameDroppingOn;
544 int keyFrameInterval;
545 bool adaptiveQpMode;
546 bool automaticResizeOn;
547 unsigned char numberOfSpatialLayers;
548 bool flexibleMode;
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000549};
550
magjede69a1a92016-11-25 10:06:31 -0800551// TODO(magjed): Move this and other H264 related classes out to their own file.
552namespace H264 {
553
554enum Profile {
555 kProfileConstrainedBaseline,
556 kProfileBaseline,
557 kProfileMain,
558 kProfileConstrainedHigh,
559 kProfileHigh,
560};
561
562} // namespace H264
563
stefan@webrtc.orgb9f54532014-07-04 12:42:07 +0000564// H264 specific.
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000565struct VideoCodecH264 {
solenberg634b86e2016-09-01 07:54:53 -0700566 bool frameDroppingOn;
567 int keyFrameInterval;
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000568 // These are NULL/0 if not externally negotiated.
569 const uint8_t* spsData;
solenberg634b86e2016-09-01 07:54:53 -0700570 size_t spsLen;
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000571 const uint8_t* ppsData;
solenberg634b86e2016-09-01 07:54:53 -0700572 size_t ppsLen;
magjede69a1a92016-11-25 10:06:31 -0800573 H264::Profile profile;
stefan@webrtc.orgb9f54532014-07-04 12:42:07 +0000574};
575
niklase@google.com470e71d2011-07-07 08:21:25 +0000576// Video codec types
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000577enum VideoCodecType {
578 kVideoCodecVP8,
579 kVideoCodecVP9,
580 kVideoCodecH264,
581 kVideoCodecI420,
582 kVideoCodecRED,
583 kVideoCodecULPFEC,
brandtr87d7d772016-11-07 03:03:41 -0800584 kVideoCodecFlexfec,
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000585 kVideoCodecGeneric,
586 kVideoCodecUnknown
niklase@google.com470e71d2011-07-07 08:21:25 +0000587};
588
Erik Språng08127a92016-11-16 16:41:30 +0100589// Translates from name of codec to codec type and vice versa.
magjed10165ab2016-11-22 10:16:57 -0800590rtc::Optional<const char*> CodecTypeToPayloadName(VideoCodecType type);
Erik Språng08127a92016-11-16 16:41:30 +0100591rtc::Optional<VideoCodecType> PayloadNameToCodecType(const std::string& name);
592
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000593union VideoCodecUnion {
solenberg634b86e2016-09-01 07:54:53 -0700594 VideoCodecVP8 VP8;
595 VideoCodecVP9 VP9;
596 VideoCodecH264 H264;
niklase@google.com470e71d2011-07-07 08:21:25 +0000597};
598
phoglund@webrtc.org8bfee842012-02-17 09:32:48 +0000599// Simulcast is when the same stream is encoded multiple times with different
600// settings such as resolution.
mallinath@webrtc.org0209e562014-03-21 00:41:28 +0000601struct SimulcastStream {
solenberg634b86e2016-09-01 07:54:53 -0700602 unsigned short width;
603 unsigned short height;
604 unsigned char numberOfTemporalLayers;
605 unsigned int maxBitrate; // kilobits/sec.
606 unsigned int targetBitrate; // kilobits/sec.
607 unsigned int minBitrate; // kilobits/sec.
608 unsigned int qpMax; // minimum quality
pwestin@webrtc.org1da1ce02011-10-13 15:19:55 +0000609};
610
sprangce4aef12015-11-02 07:23:20 -0800611struct SpatialLayer {
612 int scaling_factor_num;
613 int scaling_factor_den;
614 int target_bitrate_bps;
615 // TODO(ivica): Add max_quantizer and min_quantizer?
616};
617
solenberg634b86e2016-09-01 07:54:53 -0700618enum VideoCodecMode { kRealtimeVideo, kScreensharing };
stefan@webrtc.orgeb917922013-02-18 14:40:18 +0000619
niklase@google.com470e71d2011-07-07 08:21:25 +0000620// Common video codec properties
hta257dc392016-10-25 09:05:06 -0700621class VideoCodec {
622 public:
623 VideoCodec();
624
625 // Public variables. TODO(hta): Make them private with accessors.
solenberg634b86e2016-09-01 07:54:53 -0700626 VideoCodecType codecType;
627 char plName[kPayloadNameSize];
628 unsigned char plType;
niklase@google.com470e71d2011-07-07 08:21:25 +0000629
solenberg634b86e2016-09-01 07:54:53 -0700630 unsigned short width;
631 unsigned short height;
niklase@google.com470e71d2011-07-07 08:21:25 +0000632
solenberg634b86e2016-09-01 07:54:53 -0700633 unsigned int startBitrate; // kilobits/sec.
634 unsigned int maxBitrate; // kilobits/sec.
635 unsigned int minBitrate; // kilobits/sec.
636 unsigned int targetBitrate; // kilobits/sec.
pbos@webrtc.org3c412b22014-03-24 12:36:52 +0000637
solenberg634b86e2016-09-01 07:54:53 -0700638 unsigned char maxFramerate;
niklase@google.com470e71d2011-07-07 08:21:25 +0000639
solenberg634b86e2016-09-01 07:54:53 -0700640 unsigned int qpMax;
641 unsigned char numberOfSimulcastStreams;
642 SimulcastStream simulcastStream[kMaxSimulcastStreams];
sprangce4aef12015-11-02 07:23:20 -0800643 SpatialLayer spatialLayers[kMaxSpatialLayers];
stefan@webrtc.orgeb917922013-02-18 14:40:18 +0000644
solenberg634b86e2016-09-01 07:54:53 -0700645 VideoCodecMode mode;
646 bool expect_encode_from_texture;
andresp@webrtc.org185bae42013-05-14 08:02:25 +0000647
Peter Boström7b971e72016-01-19 16:26:16 +0100648 bool operator==(const VideoCodec& other) const = delete;
649 bool operator!=(const VideoCodec& other) const = delete;
hta257dc392016-10-25 09:05:06 -0700650
651 // Accessors for codec specific information.
652 // There is a const version of each that returns a reference,
653 // and a non-const version that returns a pointer, in order
654 // to allow modification of the parameters.
655 VideoCodecVP8* VP8();
656 const VideoCodecVP8& VP8() const;
657 VideoCodecVP9* VP9();
658 const VideoCodecVP9& VP9() const;
659 VideoCodecH264* H264();
660 const VideoCodecH264& H264() const;
661
hta527d3472016-11-16 23:23:04 -0800662 private:
hta257dc392016-10-25 09:05:06 -0700663 // TODO(hta): Consider replacing the union with a pointer type.
664 // This will allow removing the VideoCodec* types from this file.
hta527d3472016-11-16 23:23:04 -0800665 VideoCodecUnion codec_specific_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000666};
astor@webrtc.orgbd7aeba2012-06-26 10:47:04 +0000667
Erik Språng08127a92016-11-16 16:41:30 +0100668class BitrateAllocation {
669 public:
670 static const uint32_t kMaxBitrateBps;
671 BitrateAllocation();
672
673 bool SetBitrate(size_t spatial_index,
674 size_t temporal_index,
675 uint32_t bitrate_bps);
676
677 uint32_t GetBitrate(size_t spatial_index, size_t temporal_index) const;
678
679 // Get the sum of all the temporal layer for a specific spatial layer.
680 uint32_t GetSpatialLayerSum(size_t spatial_index) const;
681
682 uint32_t get_sum_bps() const { return sum_; } // Sum of all bitrates.
683 uint32_t get_sum_kbps() const { return (sum_ + 500) / 1000; }
684
685 inline bool operator==(const BitrateAllocation& other) const {
686 return memcmp(bitrates_, other.bitrates_, sizeof(bitrates_)) == 0;
687 }
688 inline bool operator!=(const BitrateAllocation& other) const {
689 return !(*this == other);
690 }
691
692 private:
693 uint32_t sum_;
694 uint32_t bitrates_[kMaxSpatialLayers][kMaxTemporalStreams];
695};
696
stefan64c0a0a2015-11-27 01:02:31 -0800697// Bandwidth over-use detector options. These are used to drive
698// experimentation with bandwidth estimation parameters.
699// See modules/remote_bitrate_estimator/overuse_detector.h
700struct OverUseDetectorOptions {
701 OverUseDetectorOptions()
solenberg634b86e2016-09-01 07:54:53 -0700702 : initial_slope(8.0 / 512.0),
stefan64c0a0a2015-11-27 01:02:31 -0800703 initial_offset(0),
704 initial_e(),
705 initial_process_noise(),
706 initial_avg_noise(0.0),
707 initial_var_noise(50) {
708 initial_e[0][0] = 100;
709 initial_e[1][1] = 1e-1;
710 initial_e[0][1] = initial_e[1][0] = 0;
711 initial_process_noise[0] = 1e-13;
stefan1069cac2016-03-10 05:13:21 -0800712 initial_process_noise[1] = 1e-3;
stefan64c0a0a2015-11-27 01:02:31 -0800713 }
714 double initial_slope;
715 double initial_offset;
716 double initial_e[2][2];
717 double initial_process_noise[2];
718 double initial_avg_noise;
719 double initial_var_noise;
720};
721
wu@webrtc.orga9890802013-12-13 00:21:03 +0000722// This structure will have the information about when packet is actually
723// received by socket.
724struct PacketTime {
henrike@webrtc.org82d3cb62014-04-29 17:50:47 +0000725 PacketTime() : timestamp(-1), not_before(-1) {}
726 PacketTime(int64_t timestamp, int64_t not_before)
solenberg634b86e2016-09-01 07:54:53 -0700727 : timestamp(timestamp), not_before(not_before) {}
wu@webrtc.orga9890802013-12-13 00:21:03 +0000728
henrike@webrtc.org82d3cb62014-04-29 17:50:47 +0000729 int64_t timestamp; // Receive time after socket delivers the data.
730 int64_t not_before; // Earliest possible time the data could have arrived,
731 // indicating the potential error in the |timestamp|
732 // value,in case the system is busy.
733 // For example, the time of the last select() call.
734 // If unknown, this value will be set to zero.
wu@webrtc.orga9890802013-12-13 00:21:03 +0000735};
736
isheriff6b4b5f32016-06-08 00:24:21 -0700737// Minimum and maximum playout delay values from capture to render.
738// These are best effort values.
739//
740// A value < 0 indicates no change from previous valid value.
741//
742// min = max = 0 indicates that the receiver should try and render
743// frame as soon as possible.
744//
745// min = x, max = y indicates that the receiver is free to adapt
746// in the range (x, y) based on network jitter.
747//
748// Note: Given that this gets embedded in a union, it is up-to the owner to
749// initialize these values.
750struct PlayoutDelay {
751 int min_ms;
752 int max_ms;
753};
754
solenberg@webrtc.orgb1f50102014-03-24 10:38:25 +0000755struct RTPHeaderExtension {
sprang@webrtc.org30933902015-03-17 14:33:12 +0000756 RTPHeaderExtension();
solenberg@webrtc.orgb1f50102014-03-24 10:38:25 +0000757
758 bool hasTransmissionTimeOffset;
759 int32_t transmissionTimeOffset;
760 bool hasAbsoluteSendTime;
761 uint32_t absoluteSendTime;
sprang@webrtc.org30933902015-03-17 14:33:12 +0000762 bool hasTransportSequenceNumber;
763 uint16_t transportSequenceNumber;
solenberg@webrtc.orgb1f50102014-03-24 10:38:25 +0000764
765 // Audio Level includes both level in dBov and voiced/unvoiced bit. See:
766 // https://datatracker.ietf.org/doc/draft-lennox-avt-rtp-audio-level-exthdr/
767 bool hasAudioLevel;
Minyue4cee4192015-08-10 15:08:36 +0200768 bool voiceActivity;
solenberg@webrtc.orgb1f50102014-03-24 10:38:25 +0000769 uint8_t audioLevel;
guoweis@webrtc.org45362892015-03-04 22:55:15 +0000770
771 // For Coordination of Video Orientation. See
772 // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/
773 // ts_126114v120700p.pdf
774 bool hasVideoRotation;
magjed71eb61c2016-09-08 03:24:58 -0700775 VideoRotation videoRotation;
isheriff6b4b5f32016-06-08 00:24:21 -0700776
777 PlayoutDelay playout_delay = {-1, -1};
solenberg@webrtc.orgb1f50102014-03-24 10:38:25 +0000778};
779
780struct RTPHeader {
kwiberg@webrtc.orgac2d27d2015-02-26 13:59:22 +0000781 RTPHeader();
solenberg@webrtc.orgb1f50102014-03-24 10:38:25 +0000782
783 bool markerBit;
784 uint8_t payloadType;
785 uint16_t sequenceNumber;
786 uint32_t timestamp;
787 uint32_t ssrc;
788 uint8_t numCSRCs;
789 uint32_t arrOfCSRCs[kRtpCsrcSize];
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000790 size_t paddingLength;
791 size_t headerLength;
solenberg@webrtc.orgb1f50102014-03-24 10:38:25 +0000792 int payload_type_frequency;
793 RTPHeaderExtension extension;
794};
795
asapersson@webrtc.org44149392015-02-04 08:34:47 +0000796struct RtpPacketCounter {
797 RtpPacketCounter()
solenberg634b86e2016-09-01 07:54:53 -0700798 : header_bytes(0), payload_bytes(0), padding_bytes(0), packets(0) {}
asapersson@webrtc.org44149392015-02-04 08:34:47 +0000799
800 void Add(const RtpPacketCounter& other) {
801 header_bytes += other.header_bytes;
802 payload_bytes += other.payload_bytes;
803 padding_bytes += other.padding_bytes;
804 packets += other.packets;
805 }
806
Erik Språng22c2b482016-03-01 09:40:42 +0100807 void Subtract(const RtpPacketCounter& other) {
kwibergb890c95c2016-11-29 05:30:40 -0800808 RTC_DCHECK_GE(header_bytes, other.header_bytes);
Erik Språng22c2b482016-03-01 09:40:42 +0100809 header_bytes -= other.header_bytes;
kwibergb890c95c2016-11-29 05:30:40 -0800810 RTC_DCHECK_GE(payload_bytes, other.payload_bytes);
Erik Språng22c2b482016-03-01 09:40:42 +0100811 payload_bytes -= other.payload_bytes;
kwibergb890c95c2016-11-29 05:30:40 -0800812 RTC_DCHECK_GE(padding_bytes, other.padding_bytes);
Erik Språng22c2b482016-03-01 09:40:42 +0100813 padding_bytes -= other.padding_bytes;
kwibergb890c95c2016-11-29 05:30:40 -0800814 RTC_DCHECK_GE(packets, other.packets);
Erik Språng22c2b482016-03-01 09:40:42 +0100815 packets -= other.packets;
816 }
817
asapersson@webrtc.org44149392015-02-04 08:34:47 +0000818 void AddPacket(size_t packet_length, const RTPHeader& header) {
819 ++packets;
820 header_bytes += header.headerLength;
821 padding_bytes += header.paddingLength;
822 payload_bytes +=
823 packet_length - (header.headerLength + header.paddingLength);
824 }
825
826 size_t TotalBytes() const {
827 return header_bytes + payload_bytes + padding_bytes;
828 }
829
830 size_t header_bytes; // Number of bytes used by RTP headers.
831 size_t payload_bytes; // Payload bytes, excluding RTP headers and padding.
832 size_t padding_bytes; // Number of padding bytes.
833 uint32_t packets; // Number of packets.
834};
835
836// Data usage statistics for a (rtp) stream.
837struct StreamDataCounters {
kwiberg@webrtc.orgac2d27d2015-02-26 13:59:22 +0000838 StreamDataCounters();
asapersson@webrtc.org44149392015-02-04 08:34:47 +0000839
840 void Add(const StreamDataCounters& other) {
841 transmitted.Add(other.transmitted);
842 retransmitted.Add(other.retransmitted);
843 fec.Add(other.fec);
844 if (other.first_packet_time_ms != -1 &&
solenberg634b86e2016-09-01 07:54:53 -0700845 (other.first_packet_time_ms < first_packet_time_ms ||
846 first_packet_time_ms == -1)) {
asapersson@webrtc.org44149392015-02-04 08:34:47 +0000847 // Use oldest time.
848 first_packet_time_ms = other.first_packet_time_ms;
849 }
850 }
851
Erik Språng22c2b482016-03-01 09:40:42 +0100852 void Subtract(const StreamDataCounters& other) {
853 transmitted.Subtract(other.transmitted);
854 retransmitted.Subtract(other.retransmitted);
855 fec.Subtract(other.fec);
856 if (other.first_packet_time_ms != -1 &&
857 (other.first_packet_time_ms > first_packet_time_ms ||
858 first_packet_time_ms == -1)) {
859 // Use youngest time.
860 first_packet_time_ms = other.first_packet_time_ms;
861 }
862 }
863
asapersson@webrtc.org44149392015-02-04 08:34:47 +0000864 int64_t TimeSinceFirstPacketInMs(int64_t now_ms) const {
865 return (first_packet_time_ms == -1) ? -1 : (now_ms - first_packet_time_ms);
866 }
867
868 // Returns the number of bytes corresponding to the actual media payload (i.e.
869 // RTP headers, padding, retransmissions and fec packets are excluded).
870 // Note this function does not have meaning for an RTX stream.
871 size_t MediaPayloadBytes() const {
872 return transmitted.payload_bytes - retransmitted.payload_bytes -
873 fec.payload_bytes;
874 }
875
solenberg634b86e2016-09-01 07:54:53 -0700876 int64_t first_packet_time_ms; // Time when first packet is sent/received.
877 RtpPacketCounter transmitted; // Number of transmitted packets/bytes.
asapersson@webrtc.org44149392015-02-04 08:34:47 +0000878 RtpPacketCounter retransmitted; // Number of retransmitted packets/bytes.
solenberg634b86e2016-09-01 07:54:53 -0700879 RtpPacketCounter fec; // Number of redundancy packets/bytes.
asapersson@webrtc.org44149392015-02-04 08:34:47 +0000880};
881
882// Callback, called whenever byte/packet counts have been updated.
883class StreamDataCountersCallback {
884 public:
885 virtual ~StreamDataCountersCallback() {}
886
887 virtual void DataCountersUpdated(const StreamDataCounters& counters,
888 uint32_t ssrc) = 0;
889};
pbosda903ea2015-10-02 02:36:56 -0700890
891// RTCP mode to use. Compound mode is described by RFC 4585 and reduced-size
892// RTCP mode is described by RFC 5506.
893enum class RtcpMode { kOff, kCompound, kReducedSize };
894
pbos1ba8d392016-05-01 20:18:34 -0700895enum NetworkState {
896 kNetworkUp,
897 kNetworkDown,
898};
899
niklase@google.com470e71d2011-07-07 08:21:25 +0000900} // namespace webrtc
andrew@webrtc.orgeda189b2013-09-09 17:50:10 +0000901
902#endif // WEBRTC_COMMON_TYPES_H_