blob: a95ca2c7719ff49c34bb6f9641987a88e4dadd87 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:251/*
phoglund@webrtc.org8bfee842012-02-17 09:32:482 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:253 *
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
Mirko Bonadei92ea95e2017-09-15 04:47:3111#ifndef COMMON_TYPES_H_
12#define COMMON_TYPES_H_
niklase@google.com470e71d2011-07-07 08:21:2513
pbos@webrtc.orgf577ae92014-03-19 08:43:5714#include <stddef.h>
mallinath@webrtc.org0209e562014-03-21 00:41:2815#include <string.h>
pbos@webrtc.org1e92b0a2014-05-15 09:35:0616#include <string>
pbos@webrtc.orgf577ae92014-03-19 08:43:5717#include <vector>
18
Mirko Bonadei92ea95e2017-09-15 04:47:3119#include "api/array_view.h"
Erik Språng566124a2018-04-23 10:32:2220// TODO(sprang): Remove this include when all usage includes it directly.
21#include "api/video/video_bitrate_allocation.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3122#include "rtc_base/checks.h"
23#include "rtc_base/deprecation.h"
niklase@google.com470e71d2011-07-07 08:21:2524
andrew@webrtc.org88b8b0d2012-08-14 00:05:5625#if defined(_MSC_VER)
26// Disable "new behavior: elements of array will be default initialized"
27// warning. Affects OverUseDetectorOptions.
solenberg634b86e2016-09-01 14:54:5328#pragma warning(disable : 4351)
andrew@webrtc.org88b8b0d2012-08-14 00:05:5629#endif
30
Peter Boström8b79b072016-02-26 15:31:3731#define RTP_PAYLOAD_NAME_SIZE 32u
henrika@webrtc.orgf75901f2012-01-16 08:45:4232
mallinath@webrtc.org0209e562014-03-21 00:41:2833#if defined(WEBRTC_WIN) || defined(WIN32)
andrew@webrtc.orgeda189b2013-09-09 17:50:1034// Compares two strings without regard to case.
35#define STR_CASE_CMP(s1, s2) ::_stricmp(s1, s2)
36// Compares characters of two strings without regard to case.
37#define STR_NCASE_CMP(s1, s2, n) ::_strnicmp(s1, s2, n)
38#else
39#define STR_CASE_CMP(s1, s2) ::strcasecmp(s1, s2)
40#define STR_NCASE_CMP(s1, s2, n) ::strncasecmp(s1, s2, n)
41#endif
42
niklase@google.com470e71d2011-07-07 08:21:2543namespace webrtc {
44
pbos22993e12015-10-19 09:39:0645enum FrameType {
46 kEmptyFrame = 0,
47 kAudioFrameSpeech = 1,
48 kAudioFrameCN = 2,
49 kVideoFrameKey = 3,
50 kVideoFrameDelta = 4,
sprang@webrtc.org71f055f2013-12-04 15:09:2751};
52
sprang@webrtc.orgdc50aae2013-11-20 16:47:0753// Statistics for an RTCP channel
sprang@webrtc.orgfe5d36b2013-10-28 09:21:0754struct RtcpStatistics {
sprang@webrtc.orgfe5d36b2013-10-28 09:21:0755 RtcpStatistics()
solenberg634b86e2016-09-01 14:54:5356 : fraction_lost(0),
srte186d9c32017-08-04 12:03:5357 packets_lost(0),
58 extended_highest_sequence_number(0),
solenberg634b86e2016-09-01 14:54:5359 jitter(0) {}
sprang@webrtc.orgfe5d36b2013-10-28 09:21:0760
61 uint8_t fraction_lost;
srte186d9c32017-08-04 12:03:5362 union {
Harald Alvestrandc7c41912017-12-08 08:59:3463 int32_t packets_lost; // Defined as a 24 bit signed integer in RTCP
srte186d9c32017-08-04 12:03:5364 RTC_DEPRECATED uint32_t cumulative_lost;
65 };
66 union {
67 uint32_t extended_highest_sequence_number;
68 RTC_DEPRECATED uint32_t extended_max_sequence_number;
69 };
sprang@webrtc.orgfe5d36b2013-10-28 09:21:0770 uint32_t jitter;
sprang@webrtc.orgfe5d36b2013-10-28 09:21:0771};
72
sprang@webrtc.orgdc50aae2013-11-20 16:47:0773class RtcpStatisticsCallback {
74 public:
75 virtual ~RtcpStatisticsCallback() {}
76
77 virtual void StatisticsUpdated(const RtcpStatistics& statistics,
78 uint32_t ssrc) = 0;
pbos@webrtc.orgce4e9a32014-12-18 13:50:1679 virtual void CNameChanged(const char* cname, uint32_t ssrc) = 0;
sprang@webrtc.orgdc50aae2013-11-20 16:47:0780};
81
asapersson@webrtc.org8098e072014-02-19 11:59:0282// Statistics for RTCP packet types.
83struct RtcpPacketTypeCounter {
84 RtcpPacketTypeCounter()
solenberg634b86e2016-09-01 14:54:5385 : first_packet_time_ms(-1),
86 nack_packets(0),
87 fir_packets(0),
88 pli_packets(0),
89 nack_requests(0),
90 unique_nack_requests(0) {}
asapersson@webrtc.org8098e072014-02-19 11:59:0291
92 void Add(const RtcpPacketTypeCounter& other) {
93 nack_packets += other.nack_packets;
94 fir_packets += other.fir_packets;
95 pli_packets += other.pli_packets;
asapersson@webrtc.org2dd31342014-10-29 12:42:3096 nack_requests += other.nack_requests;
97 unique_nack_requests += other.unique_nack_requests;
asapersson@webrtc.orgd08d3892014-12-16 12:03:1198 if (other.first_packet_time_ms != -1 &&
solenberg634b86e2016-09-01 14:54:5399 (other.first_packet_time_ms < first_packet_time_ms ||
100 first_packet_time_ms == -1)) {
asapersson@webrtc.orgd08d3892014-12-16 12:03:11101 // Use oldest time.
102 first_packet_time_ms = other.first_packet_time_ms;
103 }
104 }
105
sprang07fb9be2016-02-24 15:55:00106 void Subtract(const RtcpPacketTypeCounter& other) {
107 nack_packets -= other.nack_packets;
108 fir_packets -= other.fir_packets;
109 pli_packets -= other.pli_packets;
110 nack_requests -= other.nack_requests;
111 unique_nack_requests -= other.unique_nack_requests;
112 if (other.first_packet_time_ms != -1 &&
113 (other.first_packet_time_ms > first_packet_time_ms ||
114 first_packet_time_ms == -1)) {
115 // Use youngest time.
116 first_packet_time_ms = other.first_packet_time_ms;
117 }
118 }
119
asapersson@webrtc.orgd08d3892014-12-16 12:03:11120 int64_t TimeSinceFirstPacketInMs(int64_t now_ms) const {
121 return (first_packet_time_ms == -1) ? -1 : (now_ms - first_packet_time_ms);
asapersson@webrtc.org8098e072014-02-19 11:59:02122 }
123
asapersson@webrtc.org2dd31342014-10-29 12:42:30124 int UniqueNackRequestsInPercent() const {
125 if (nack_requests == 0) {
126 return 0;
127 }
solenberg634b86e2016-09-01 14:54:53128 return static_cast<int>((unique_nack_requests * 100.0f / nack_requests) +
129 0.5f);
asapersson@webrtc.org2dd31342014-10-29 12:42:30130 }
131
solenberg634b86e2016-09-01 14:54:53132 int64_t first_packet_time_ms; // Time when first packet is sent/received.
133 uint32_t nack_packets; // Number of RTCP NACK packets.
134 uint32_t fir_packets; // Number of RTCP FIR packets.
135 uint32_t pli_packets; // Number of RTCP PLI packets.
136 uint32_t nack_requests; // Number of NACKed RTP packets.
asapersson@webrtc.org2dd31342014-10-29 12:42:30137 uint32_t unique_nack_requests; // Number of unique NACKed RTP packets.
asapersson@webrtc.org8098e072014-02-19 11:59:02138};
139
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00140class RtcpPacketTypeCounterObserver {
141 public:
142 virtual ~RtcpPacketTypeCounterObserver() {}
143 virtual void RtcpPacketTypesCounterUpdated(
144 uint32_t ssrc,
145 const RtcpPacketTypeCounter& packet_counter) = 0;
146};
147
sprang@webrtc.orgdc50aae2013-11-20 16:47:07148// Callback, used to notify an observer whenever new rates have been estimated.
149class BitrateStatisticsObserver {
150 public:
151 virtual ~BitrateStatisticsObserver() {}
152
sprangcd349d92016-07-13 16:11:28153 virtual void Notify(uint32_t total_bitrate_bps,
154 uint32_t retransmit_bitrate_bps,
stefan@webrtc.org0bae1fa2014-11-05 14:05:29155 uint32_t ssrc) = 0;
sprang@webrtc.orgdc50aae2013-11-20 16:47:07156};
157
pbos@webrtc.orgce4e9a32014-12-18 13:50:16158struct FrameCounts {
159 FrameCounts() : key_frames(0), delta_frames(0) {}
160 int key_frames;
161 int delta_frames;
162};
163
asapersson@webrtc.orgd08d3892014-12-16 12:03:11164// Callback, used to notify an observer whenever frame counts have been updated.
sprang@webrtc.orgdc50aae2013-11-20 16:47:07165class FrameCountObserver {
166 public:
sprang@webrtc.org72964bd2013-11-21 09:09:54167 virtual ~FrameCountObserver() {}
pbos@webrtc.orgce4e9a32014-12-18 13:50:16168 virtual void FrameCountUpdated(const FrameCounts& frame_counts,
169 uint32_t ssrc) = 0;
sprang@webrtc.orgdc50aae2013-11-20 16:47:07170};
171
stefan@webrtc.org168f23f2014-07-11 13:44:02172// Callback, used to notify an observer whenever the send-side delay is updated.
173class SendSideDelayObserver {
174 public:
175 virtual ~SendSideDelayObserver() {}
176 virtual void SendSideDelayUpdated(int avg_delay_ms,
177 int max_delay_ms,
178 uint32_t ssrc) = 0;
179};
180
asapersson35151f32016-05-03 06:44:01181// Callback, used to notify an observer whenever a packet is sent to the
182// transport.
183// TODO(asapersson): This class will remove the need for SendSideDelayObserver.
184// Remove SendSideDelayObserver once possible.
185class SendPacketObserver {
186 public:
187 virtual ~SendPacketObserver() {}
188 virtual void OnSendPacket(uint16_t packet_id,
189 int64_t capture_time_ms,
190 uint32_t ssrc) = 0;
191};
192
michaelt4da30442016-11-17 09:38:43193// Callback, used to notify an observer when the overhead per packet
194// has changed.
195class OverheadObserver {
196 public:
197 virtual ~OverheadObserver() = default;
198 virtual void OnOverheadChanged(size_t overhead_bytes_per_packet) = 0;
199};
200
niklase@google.com470e71d2011-07-07 08:21:25201// ==================================================================
202// Voice specific types
203// ==================================================================
204
205// Each codec supported can be described by this structure.
mallinath@webrtc.org0209e562014-03-21 00:41:28206struct CodecInst {
207 int pltype;
208 char plname[RTP_PAYLOAD_NAME_SIZE];
209 int plfreq;
210 int pacsize;
Peter Kasting69558702016-01-13 00:26:35211 size_t channels;
mallinath@webrtc.org0209e562014-03-21 00:41:28212 int rate; // bits/sec unlike {start,min,max}Bitrate elsewhere in this file!
213
214 bool operator==(const CodecInst& other) const {
215 return pltype == other.pltype &&
216 (STR_CASE_CMP(plname, other.plname) == 0) &&
solenberg634b86e2016-09-01 14:54:53217 plfreq == other.plfreq && pacsize == other.pacsize &&
218 channels == other.channels && rate == other.rate;
mallinath@webrtc.org0209e562014-03-21 00:41:28219 }
220
solenberg634b86e2016-09-01 14:54:53221 bool operator!=(const CodecInst& other) const { return !(*this == other); }
niklase@google.com470e71d2011-07-07 08:21:25222};
223
niklase@google.com470e71d2011-07-07 08:21:25224// RTP
solenberg634b86e2016-09-01 14:54:53225enum { kRtpCsrcSize = 15 }; // RFC 3550 page 13
niklase@google.com470e71d2011-07-07 08:21:25226
solenberg634b86e2016-09-01 14:54:53227// NETEQ statistics.
228struct NetworkStatistics {
229 // current jitter buffer size in ms
230 uint16_t currentBufferSize;
231 // preferred (optimal) buffer size in ms
232 uint16_t preferredBufferSize;
233 // adding extra delay due to "peaky jitter"
234 bool jitterPeaksFound;
Gustaf Ullbergb0a02072017-10-02 10:00:34235 // Stats below correspond to similarly-named fields in the WebRTC stats spec.
236 // https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats
Steve Anton2dbc69f2017-08-25 00:15:13237 uint64_t totalSamplesReceived;
Steve Anton2dbc69f2017-08-25 00:15:13238 uint64_t concealedSamples;
Gustaf Ullberg9a2e9062017-09-18 07:28:20239 uint64_t concealmentEvents;
Gustaf Ullbergb0a02072017-10-02 10:00:34240 uint64_t jitterBufferDelayMs;
241 // Stats below DO NOT correspond directly to anything in the WebRTC stats
solenberg634b86e2016-09-01 14:54:53242 // Loss rate (network + late); fraction between 0 and 1, scaled to Q14.
243 uint16_t currentPacketLossRate;
244 // Late loss rate; fraction between 0 and 1, scaled to Q14.
minyue-webrtc0c3ca752017-08-23 13:59:38245 union {
246 RTC_DEPRECATED uint16_t currentDiscardRate;
247 };
solenberg634b86e2016-09-01 14:54:53248 // fraction (of original stream) of synthesized audio inserted through
249 // expansion (in Q14)
250 uint16_t currentExpandRate;
251 // fraction (of original stream) of synthesized speech inserted through
252 // expansion (in Q14)
253 uint16_t currentSpeechExpandRate;
254 // fraction of synthesized speech inserted through pre-emptive expansion
255 // (in Q14)
256 uint16_t currentPreemptiveRate;
257 // fraction of data removed through acceleration (in Q14)
258 uint16_t currentAccelerateRate;
259 // fraction of data coming from secondary decoding (in Q14)
260 uint16_t currentSecondaryDecodedRate;
minyue-webrtc0e320ec2017-08-28 11:51:27261 // Fraction of secondary data, including FEC and RED, that is discarded (in
262 // Q14). Discarding of secondary data can be caused by the reception of the
263 // primary data, obsoleting the secondary data. It can also be caused by early
264 // or late arrival of secondary data.
minyue-webrtc0c3ca752017-08-23 13:59:38265 uint16_t currentSecondaryDiscardedRate;
solenberg634b86e2016-09-01 14:54:53266 // clock-drift in parts-per-million (negative or positive)
267 int32_t clockDriftPPM;
268 // average packet waiting time in the jitter buffer (ms)
269 int meanWaitingTimeMs;
270 // median packet waiting time in the jitter buffer (ms)
271 int medianWaitingTimeMs;
272 // min packet waiting time in the jitter buffer (ms)
273 int minWaitingTimeMs;
274 // max packet waiting time in the jitter buffer (ms)
275 int maxWaitingTimeMs;
276 // added samples in off mode due to packet loss
277 size_t addedSamples;
niklase@google.com470e71d2011-07-07 08:21:25278};
279
wu@webrtc.org24301a62013-12-13 19:17:43280// Statistics for calls to AudioCodingModule::PlayoutData10Ms().
281struct AudioDecodingCallStats {
282 AudioDecodingCallStats()
283 : calls_to_silence_generator(0),
284 calls_to_neteq(0),
285 decoded_normal(0),
286 decoded_plc(0),
287 decoded_cng(0),
henrik.lundin63489782016-09-20 08:47:12288 decoded_plc_cng(0),
289 decoded_muted_output(0) {}
wu@webrtc.org24301a62013-12-13 19:17:43290
291 int calls_to_silence_generator; // Number of calls where silence generated,
292 // and NetEq was disengaged from decoding.
solenberg634b86e2016-09-01 14:54:53293 int calls_to_neteq; // Number of calls to NetEq.
wu@webrtc.org24301a62013-12-13 19:17:43294 int decoded_normal; // Number of calls where audio RTP packet decoded.
solenberg634b86e2016-09-01 14:54:53295 int decoded_plc; // Number of calls resulted in PLC.
wu@webrtc.org24301a62013-12-13 19:17:43296 int decoded_cng; // Number of calls where comfort noise generated due to DTX.
Yves Gerey665174f2018-06-19 13:03:05297 int decoded_plc_cng; // Number of calls resulted where PLC faded to CNG.
henrik.lundin63489782016-09-20 08:47:12298 int decoded_muted_output; // Number of calls returning a muted state output.
wu@webrtc.org24301a62013-12-13 19:17:43299};
300
niklase@google.com470e71d2011-07-07 08:21:25301// ==================================================================
302// Video specific types
303// ==================================================================
304
nisseeb44b392017-04-28 14:18:05305// TODO(nisse): Delete, and switch to fourcc values everywhere?
306// Supported video types.
307enum class VideoType {
308 kUnknown,
309 kI420,
310 kIYUV,
311 kRGB24,
312 kABGR,
313 kARGB,
314 kARGB4444,
315 kRGB565,
316 kARGB1555,
317 kYUY2,
318 kYV12,
319 kUYVY,
320 kMJPEG,
321 kNV21,
322 kNV12,
323 kBGRA,
niklase@google.com470e71d2011-07-07 08:21:25324};
325
magjede69a1a92016-11-25 18:06:31326// TODO(magjed): Move this and other H264 related classes out to their own file.
327namespace H264 {
328
329enum Profile {
330 kProfileConstrainedBaseline,
331 kProfileBaseline,
332 kProfileMain,
333 kProfileConstrainedHigh,
334 kProfileHigh,
335};
336
337} // namespace H264
338
niklase@google.com470e71d2011-07-07 08:21:25339// Video codec types
marpan@webrtc.org5b883172014-11-01 06:10:48340enum VideoCodecType {
Niels Möller520ca4e2018-06-04 09:14:38341 // There are various memset(..., 0, ...) calls in the code that rely on
342 // kVideoCodecUnknown being zero.
343 kVideoCodecUnknown = 0,
marpan@webrtc.org5b883172014-11-01 06:10:48344 kVideoCodecVP8,
345 kVideoCodecVP9,
346 kVideoCodecH264,
347 kVideoCodecI420,
marpan@webrtc.org5b883172014-11-01 06:10:48348 kVideoCodecGeneric,
Emircan Uysalerd7ae3c32018-01-25 21:01:09349 kVideoCodecMultiplex,
Niels Möller520ca4e2018-06-04 09:14:38350
351 // TODO(nisse): Deprecated aliases, for code expecting RtpVideoCodecTypes.
352 kRtpVideoNone = kVideoCodecUnknown,
353 kRtpVideoGeneric = kVideoCodecGeneric,
354 kRtpVideoVp8 = kVideoCodecVP8,
355 kRtpVideoVp9 = kVideoCodecVP9,
356 kRtpVideoH264 = kVideoCodecH264,
niklase@google.com470e71d2011-07-07 08:21:25357};
358
Erik Språng08127a92016-11-16 15:41:30359// Translates from name of codec to codec type and vice versa.
kthelgason1cdddc92017-08-24 10:52:48360const char* CodecTypeToPayloadString(VideoCodecType type);
361VideoCodecType PayloadStringToCodecType(const std::string& name);
Erik Språng08127a92016-11-16 15:41:30362
Sergey Silkin13e74342018-03-02 11:28:00363struct SpatialLayer {
Niels Möllerdef1ef52018-03-19 12:48:44364 bool operator==(const SpatialLayer& other) const;
365 bool operator!=(const SpatialLayer& other) const { return !(*this == other); }
366
solenberg634b86e2016-09-01 14:54:53367 unsigned short width;
368 unsigned short height;
369 unsigned char numberOfTemporalLayers;
370 unsigned int maxBitrate; // kilobits/sec.
371 unsigned int targetBitrate; // kilobits/sec.
372 unsigned int minBitrate; // kilobits/sec.
373 unsigned int qpMax; // minimum quality
Seth Hampsonf6464c92018-01-17 21:55:14374 bool active; // encoded and sent.
pwestin@webrtc.org1da1ce02011-10-13 15:19:55375};
376
Sergey Silkin13e74342018-03-02 11:28:00377// Simulcast is when the same stream is encoded multiple times with different
378// settings such as resolution.
379typedef SpatialLayer SimulcastStream;
sprangce4aef12015-11-02 15:23:20380
Erik Språng566124a2018-04-23 10:32:22381// TODO(sprang): Remove this when downstream projects have been updated.
382using BitrateAllocation = VideoBitrateAllocation;
Erik Språng08127a92016-11-16 15:41:30383
stefan64c0a0a2015-11-27 09:02:31384// Bandwidth over-use detector options. These are used to drive
385// experimentation with bandwidth estimation parameters.
386// See modules/remote_bitrate_estimator/overuse_detector.h
terelius84f83f82016-12-27 18:43:01387// TODO(terelius): This is only used in overuse_estimator.cc, and only in the
388// default constructed state. Can we move the relevant variables into that
389// class and delete this? See also disabled warning at line 27
stefan64c0a0a2015-11-27 09:02:31390struct OverUseDetectorOptions {
391 OverUseDetectorOptions()
solenberg634b86e2016-09-01 14:54:53392 : initial_slope(8.0 / 512.0),
stefan64c0a0a2015-11-27 09:02:31393 initial_offset(0),
394 initial_e(),
395 initial_process_noise(),
396 initial_avg_noise(0.0),
397 initial_var_noise(50) {
398 initial_e[0][0] = 100;
399 initial_e[1][1] = 1e-1;
400 initial_e[0][1] = initial_e[1][0] = 0;
401 initial_process_noise[0] = 1e-13;
stefan1069cac2016-03-10 13:13:21402 initial_process_noise[1] = 1e-3;
stefan64c0a0a2015-11-27 09:02:31403 }
404 double initial_slope;
405 double initial_offset;
406 double initial_e[2][2];
407 double initial_process_noise[2];
408 double initial_avg_noise;
409 double initial_var_noise;
410};
411
Niels Möller70082872018-08-07 09:03:12412// TODO(nisse): This struct is phased out, delete as soon as down stream code is
413// updated.
414
wu@webrtc.orga9890802013-12-13 00:21:03415// This structure will have the information about when packet is actually
416// received by socket.
417struct PacketTime {
henrike@webrtc.org82d3cb62014-04-29 17:50:47418 PacketTime() : timestamp(-1), not_before(-1) {}
419 PacketTime(int64_t timestamp, int64_t not_before)
solenberg634b86e2016-09-01 14:54:53420 : timestamp(timestamp), not_before(not_before) {}
wu@webrtc.orga9890802013-12-13 00:21:03421
henrike@webrtc.org82d3cb62014-04-29 17:50:47422 int64_t timestamp; // Receive time after socket delivers the data.
423 int64_t not_before; // Earliest possible time the data could have arrived,
424 // indicating the potential error in the |timestamp|
425 // value,in case the system is busy.
426 // For example, the time of the last select() call.
427 // If unknown, this value will be set to zero.
wu@webrtc.orga9890802013-12-13 00:21:03428};
429
isheriff6b4b5f32016-06-08 07:24:21430// Minimum and maximum playout delay values from capture to render.
431// These are best effort values.
432//
433// A value < 0 indicates no change from previous valid value.
434//
435// min = max = 0 indicates that the receiver should try and render
436// frame as soon as possible.
437//
438// min = x, max = y indicates that the receiver is free to adapt
439// in the range (x, y) based on network jitter.
440//
441// Note: Given that this gets embedded in a union, it is up-to the owner to
442// initialize these values.
443struct PlayoutDelay {
444 int min_ms;
445 int max_ms;
446};
447
niklase@google.com470e71d2011-07-07 08:21:25448} // namespace webrtc
andrew@webrtc.orgeda189b2013-09-09 17:50:10449
Mirko Bonadei92ea95e2017-09-15 04:47:31450#endif // COMMON_TYPES_H_