1 /*
2 * Copyright (c) 2012 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
11 #ifndef MODULE_COMMON_TYPES_H
12 #define MODULE_COMMON_TYPES_H
13
14 #include <assert.h>
15 #include <string.h> // memcpy
16
17 #include <algorithm>
18
19 #include "webrtc/base/constructormagic.h"
20 #include "webrtc/common_types.h"
21 #include "webrtc/typedefs.h"
22
23 namespace webrtc {
24
25 struct RTPAudioHeader {
26 uint8_t numEnergy; // number of valid entries in arrOfEnergy
27 uint8_t arrOfEnergy[kRtpCsrcSize]; // one energy byte (0-9) per channel
28 bool isCNG; // is this CNG
29 uint8_t channel; // number of channels 2 = stereo
30 };
31
32 const int16_t kNoPictureId = -1;
33 const int16_t kNoTl0PicIdx = -1;
34 const uint8_t kNoTemporalIdx = 0xFF;
35 const int kNoKeyIdx = -1;
36
37 struct RTPVideoHeaderVP8 {
InitRTPVideoHeaderVP8RTPVideoHeaderVP838 void InitRTPVideoHeaderVP8() {
39 nonReference = false;
40 pictureId = kNoPictureId;
41 tl0PicIdx = kNoTl0PicIdx;
42 temporalIdx = kNoTemporalIdx;
43 layerSync = false;
44 keyIdx = kNoKeyIdx;
45 partitionId = 0;
46 beginningOfPartition = false;
47 }
48
49 bool nonReference; // Frame is discardable.
50 int16_t pictureId; // Picture ID index, 15 bits;
51 // kNoPictureId if PictureID does not exist.
52 int16_t tl0PicIdx; // TL0PIC_IDX, 8 bits;
53 // kNoTl0PicIdx means no value provided.
54 uint8_t temporalIdx; // Temporal layer index, or kNoTemporalIdx.
55 bool layerSync; // This frame is a layer sync frame.
56 // Disabled if temporalIdx == kNoTemporalIdx.
57 int keyIdx; // 5 bits; kNoKeyIdx means not used.
58 int partitionId; // VP8 partition ID
59 bool beginningOfPartition; // True if this packet is the first
60 // in a VP8 partition. Otherwise false
61 };
62
63 struct RTPVideoHeaderH264 {
64 bool stap_a;
65 bool single_nalu;
66 };
67
68 union RTPVideoTypeHeader {
69 RTPVideoHeaderVP8 VP8;
70 RTPVideoHeaderH264 H264;
71 };
72
73 enum RtpVideoCodecTypes {
74 kRtpVideoNone,
75 kRtpVideoGeneric,
76 kRtpVideoVp8,
77 kRtpVideoH264
78 };
79 struct RTPVideoHeader {
80 uint16_t width; // size
81 uint16_t height;
82
83 bool isFirstPacket; // first packet in frame
84 uint8_t simulcastIdx; // Index if the simulcast encoder creating
85 // this frame, 0 if not using simulcast.
86 RtpVideoCodecTypes codec;
87 RTPVideoTypeHeader codecHeader;
88 };
89 union RTPTypeHeader {
90 RTPAudioHeader Audio;
91 RTPVideoHeader Video;
92 };
93
94 struct WebRtcRTPHeader {
95 RTPHeader header;
96 FrameType frameType;
97 RTPTypeHeader type;
98 // NTP time of the capture time in local timebase in milliseconds.
99 int64_t ntp_time_ms;
100 };
101
102 class RTPFragmentationHeader {
103 public:
RTPFragmentationHeader()104 RTPFragmentationHeader()
105 : fragmentationVectorSize(0),
106 fragmentationOffset(NULL),
107 fragmentationLength(NULL),
108 fragmentationTimeDiff(NULL),
109 fragmentationPlType(NULL) {};
110
~RTPFragmentationHeader()111 ~RTPFragmentationHeader() {
112 delete[] fragmentationOffset;
113 delete[] fragmentationLength;
114 delete[] fragmentationTimeDiff;
115 delete[] fragmentationPlType;
116 }
117
CopyFrom(const RTPFragmentationHeader & src)118 void CopyFrom(const RTPFragmentationHeader& src) {
119 if (this == &src) {
120 return;
121 }
122
123 if (src.fragmentationVectorSize != fragmentationVectorSize) {
124 // new size of vectors
125
126 // delete old
127 delete[] fragmentationOffset;
128 fragmentationOffset = NULL;
129 delete[] fragmentationLength;
130 fragmentationLength = NULL;
131 delete[] fragmentationTimeDiff;
132 fragmentationTimeDiff = NULL;
133 delete[] fragmentationPlType;
134 fragmentationPlType = NULL;
135
136 if (src.fragmentationVectorSize > 0) {
137 // allocate new
138 if (src.fragmentationOffset) {
139 fragmentationOffset = new uint32_t[src.fragmentationVectorSize];
140 }
141 if (src.fragmentationLength) {
142 fragmentationLength = new uint32_t[src.fragmentationVectorSize];
143 }
144 if (src.fragmentationTimeDiff) {
145 fragmentationTimeDiff = new uint16_t[src.fragmentationVectorSize];
146 }
147 if (src.fragmentationPlType) {
148 fragmentationPlType = new uint8_t[src.fragmentationVectorSize];
149 }
150 }
151 // set new size
152 fragmentationVectorSize = src.fragmentationVectorSize;
153 }
154
155 if (src.fragmentationVectorSize > 0) {
156 // copy values
157 if (src.fragmentationOffset) {
158 memcpy(fragmentationOffset, src.fragmentationOffset,
159 src.fragmentationVectorSize * sizeof(uint32_t));
160 }
161 if (src.fragmentationLength) {
162 memcpy(fragmentationLength, src.fragmentationLength,
163 src.fragmentationVectorSize * sizeof(uint32_t));
164 }
165 if (src.fragmentationTimeDiff) {
166 memcpy(fragmentationTimeDiff, src.fragmentationTimeDiff,
167 src.fragmentationVectorSize * sizeof(uint16_t));
168 }
169 if (src.fragmentationPlType) {
170 memcpy(fragmentationPlType, src.fragmentationPlType,
171 src.fragmentationVectorSize * sizeof(uint8_t));
172 }
173 }
174 }
175
VerifyAndAllocateFragmentationHeader(const uint16_t size)176 void VerifyAndAllocateFragmentationHeader(const uint16_t size) {
177 if (fragmentationVectorSize < size) {
178 uint16_t oldVectorSize = fragmentationVectorSize;
179 {
180 // offset
181 uint32_t* oldOffsets = fragmentationOffset;
182 fragmentationOffset = new uint32_t[size];
183 memset(fragmentationOffset + oldVectorSize, 0,
184 sizeof(uint32_t) * (size - oldVectorSize));
185 // copy old values
186 memcpy(fragmentationOffset, oldOffsets,
187 sizeof(uint32_t) * oldVectorSize);
188 delete[] oldOffsets;
189 }
190 // length
191 {
192 uint32_t* oldLengths = fragmentationLength;
193 fragmentationLength = new uint32_t[size];
194 memset(fragmentationLength + oldVectorSize, 0,
195 sizeof(uint32_t) * (size - oldVectorSize));
196 memcpy(fragmentationLength, oldLengths,
197 sizeof(uint32_t) * oldVectorSize);
198 delete[] oldLengths;
199 }
200 // time diff
201 {
202 uint16_t* oldTimeDiffs = fragmentationTimeDiff;
203 fragmentationTimeDiff = new uint16_t[size];
204 memset(fragmentationTimeDiff + oldVectorSize, 0,
205 sizeof(uint16_t) * (size - oldVectorSize));
206 memcpy(fragmentationTimeDiff, oldTimeDiffs,
207 sizeof(uint16_t) * oldVectorSize);
208 delete[] oldTimeDiffs;
209 }
210 // payload type
211 {
212 uint8_t* oldTimePlTypes = fragmentationPlType;
213 fragmentationPlType = new uint8_t[size];
214 memset(fragmentationPlType + oldVectorSize, 0,
215 sizeof(uint8_t) * (size - oldVectorSize));
216 memcpy(fragmentationPlType, oldTimePlTypes,
217 sizeof(uint8_t) * oldVectorSize);
218 delete[] oldTimePlTypes;
219 }
220 fragmentationVectorSize = size;
221 }
222 }
223
224 uint16_t fragmentationVectorSize; // Number of fragmentations
225 uint32_t* fragmentationOffset; // Offset of pointer to data for each fragm.
226 uint32_t* fragmentationLength; // Data size for each fragmentation
227 uint16_t* fragmentationTimeDiff; // Timestamp difference relative "now" for
228 // each fragmentation
229 uint8_t* fragmentationPlType; // Payload type of each fragmentation
230
231 private:
232 DISALLOW_COPY_AND_ASSIGN(RTPFragmentationHeader);
233 };
234
235 struct RTCPVoIPMetric {
236 // RFC 3611 4.7
237 uint8_t lossRate;
238 uint8_t discardRate;
239 uint8_t burstDensity;
240 uint8_t gapDensity;
241 uint16_t burstDuration;
242 uint16_t gapDuration;
243 uint16_t roundTripDelay;
244 uint16_t endSystemDelay;
245 uint8_t signalLevel;
246 uint8_t noiseLevel;
247 uint8_t RERL;
248 uint8_t Gmin;
249 uint8_t Rfactor;
250 uint8_t extRfactor;
251 uint8_t MOSLQ;
252 uint8_t MOSCQ;
253 uint8_t RXconfig;
254 uint16_t JBnominal;
255 uint16_t JBmax;
256 uint16_t JBabsMax;
257 };
258
259 // Types for the FEC packet masks. The type |kFecMaskRandom| is based on a
260 // random loss model. The type |kFecMaskBursty| is based on a bursty/consecutive
261 // loss model. The packet masks are defined in
262 // modules/rtp_rtcp/fec_private_tables_random(bursty).h
263 enum FecMaskType {
264 kFecMaskRandom,
265 kFecMaskBursty,
266 };
267
268 // Struct containing forward error correction settings.
269 struct FecProtectionParams {
270 int fec_rate;
271 bool use_uep_protection;
272 int max_fec_frames;
273 FecMaskType fec_mask_type;
274 };
275
276 // Interface used by the CallStats class to distribute call statistics.
277 // Callbacks will be triggered as soon as the class has been registered to a
278 // CallStats object using RegisterStatsObserver.
279 class CallStatsObserver {
280 public:
281 virtual void OnRttUpdate(uint32_t rtt_ms) = 0;
282
~CallStatsObserver()283 virtual ~CallStatsObserver() {}
284 };
285
286 // class describing a complete, or parts of an encoded frame.
287 class EncodedVideoData {
288 public:
EncodedVideoData()289 EncodedVideoData()
290 : payloadType(0),
291 timeStamp(0),
292 renderTimeMs(0),
293 encodedWidth(0),
294 encodedHeight(0),
295 completeFrame(false),
296 missingFrame(false),
297 payloadData(NULL),
298 payloadSize(0),
299 bufferSize(0),
300 fragmentationHeader(),
301 frameType(kVideoFrameDelta),
302 codec(kVideoCodecUnknown) {};
303
EncodedVideoData(const EncodedVideoData & data)304 EncodedVideoData(const EncodedVideoData& data) {
305 payloadType = data.payloadType;
306 timeStamp = data.timeStamp;
307 renderTimeMs = data.renderTimeMs;
308 encodedWidth = data.encodedWidth;
309 encodedHeight = data.encodedHeight;
310 completeFrame = data.completeFrame;
311 missingFrame = data.missingFrame;
312 payloadSize = data.payloadSize;
313 fragmentationHeader.CopyFrom(data.fragmentationHeader);
314 frameType = data.frameType;
315 codec = data.codec;
316 if (data.payloadSize > 0) {
317 payloadData = new uint8_t[data.payloadSize];
318 memcpy(payloadData, data.payloadData, data.payloadSize);
319 } else {
320 payloadData = NULL;
321 }
322 }
323
~EncodedVideoData()324 ~EncodedVideoData() {
325 delete[] payloadData;
326 };
327
328 EncodedVideoData& operator=(const EncodedVideoData& data) {
329 if (this == &data) {
330 return *this;
331 }
332 payloadType = data.payloadType;
333 timeStamp = data.timeStamp;
334 renderTimeMs = data.renderTimeMs;
335 encodedWidth = data.encodedWidth;
336 encodedHeight = data.encodedHeight;
337 completeFrame = data.completeFrame;
338 missingFrame = data.missingFrame;
339 payloadSize = data.payloadSize;
340 fragmentationHeader.CopyFrom(data.fragmentationHeader);
341 frameType = data.frameType;
342 codec = data.codec;
343 if (data.payloadSize > 0) {
344 delete[] payloadData;
345 payloadData = new uint8_t[data.payloadSize];
346 memcpy(payloadData, data.payloadData, data.payloadSize);
347 bufferSize = data.payloadSize;
348 }
349 return *this;
350 };
VerifyAndAllocate(const uint32_t size)351 void VerifyAndAllocate(const uint32_t size) {
352 if (bufferSize < size) {
353 uint8_t* oldPayload = payloadData;
354 payloadData = new uint8_t[size];
355 memcpy(payloadData, oldPayload, sizeof(uint8_t) * payloadSize);
356
357 bufferSize = size;
358 delete[] oldPayload;
359 }
360 }
361
362 uint8_t payloadType;
363 uint32_t timeStamp;
364 int64_t renderTimeMs;
365 uint32_t encodedWidth;
366 uint32_t encodedHeight;
367 bool completeFrame;
368 bool missingFrame;
369 uint8_t* payloadData;
370 uint32_t payloadSize;
371 uint32_t bufferSize;
372 RTPFragmentationHeader fragmentationHeader;
373 FrameType frameType;
374 VideoCodecType codec;
375 };
376
377 struct VideoContentMetrics {
VideoContentMetricsVideoContentMetrics378 VideoContentMetrics()
379 : motion_magnitude(0.0f),
380 spatial_pred_err(0.0f),
381 spatial_pred_err_h(0.0f),
382 spatial_pred_err_v(0.0f) {}
383
ResetVideoContentMetrics384 void Reset() {
385 motion_magnitude = 0.0f;
386 spatial_pred_err = 0.0f;
387 spatial_pred_err_h = 0.0f;
388 spatial_pred_err_v = 0.0f;
389 }
390 float motion_magnitude;
391 float spatial_pred_err;
392 float spatial_pred_err_h;
393 float spatial_pred_err_v;
394 };
395
396 /*************************************************
397 *
398 * VideoFrame class
399 *
400 * The VideoFrame class allows storing and
401 * handling of video frames.
402 *
403 *
404 *************************************************/
405 class VideoFrame {
406 public:
407 VideoFrame();
408 ~VideoFrame();
409 /**
410 * Verifies that current allocated buffer size is larger than or equal to the
411 * input size.
412 * If the current buffer size is smaller, a new allocation is made and the old
413 * buffer data
414 * is copied to the new buffer.
415 * Buffer size is updated to minimumSize.
416 */
417 int32_t VerifyAndAllocate(const uint32_t minimumSize);
418 /**
419 * Update length of data buffer in frame. Function verifies that new length
420 * is less or
421 * equal to allocated size.
422 */
423 int32_t SetLength(const uint32_t newLength);
424 /*
425 * Swap buffer and size data
426 */
427 int32_t Swap(uint8_t*& newMemory, uint32_t& newLength, uint32_t& newSize);
428 /*
429 * Swap buffer and size data
430 */
431 int32_t SwapFrame(VideoFrame& videoFrame);
432 /**
433 * Copy buffer: If newLength is bigger than allocated size, a new buffer of
434 * size length
435 * is allocated.
436 */
437 int32_t CopyFrame(const VideoFrame& videoFrame);
438 /**
439 * Copy buffer: If newLength is bigger than allocated size, a new buffer of
440 * size length
441 * is allocated.
442 */
443 int32_t CopyFrame(uint32_t length, const uint8_t* sourceBuffer);
444 /**
445 * Delete VideoFrame and resets members to zero
446 */
447 void Free();
448 /**
449 * Set frame timestamp (90kHz)
450 */
SetTimeStamp(const uint32_t timeStamp)451 void SetTimeStamp(const uint32_t timeStamp) { _timeStamp = timeStamp; }
452 /**
453 * Get pointer to frame buffer
454 */
Buffer()455 uint8_t* Buffer() const { return _buffer; }
456
Buffer()457 uint8_t*& Buffer() { return _buffer; }
458
459 /**
460 * Get allocated buffer size
461 */
Size()462 uint32_t Size() const { return _bufferSize; }
463 /**
464 * Get frame length
465 */
Length()466 uint32_t Length() const { return _bufferLength; }
467 /**
468 * Get frame timestamp (90kHz)
469 */
TimeStamp()470 uint32_t TimeStamp() const { return _timeStamp; }
471 /**
472 * Get frame width
473 */
Width()474 uint32_t Width() const { return _width; }
475 /**
476 * Get frame height
477 */
Height()478 uint32_t Height() const { return _height; }
479 /**
480 * Set frame width
481 */
SetWidth(const uint32_t width)482 void SetWidth(const uint32_t width) { _width = width; }
483 /**
484 * Set frame height
485 */
SetHeight(const uint32_t height)486 void SetHeight(const uint32_t height) { _height = height; }
487 /**
488 * Set render time in miliseconds
489 */
SetRenderTime(const int64_t renderTimeMs)490 void SetRenderTime(const int64_t renderTimeMs) {
491 _renderTimeMs = renderTimeMs;
492 }
493 /**
494 * Get render time in miliseconds
495 */
RenderTimeMs()496 int64_t RenderTimeMs() const { return _renderTimeMs; }
497
498 private:
499 void Set(uint8_t* buffer, uint32_t size, uint32_t length, uint32_t timeStamp);
500
501 uint8_t* _buffer; // Pointer to frame buffer
502 uint32_t _bufferSize; // Allocated buffer size
503 uint32_t _bufferLength; // Length (in bytes) of buffer
504 uint32_t _timeStamp; // Timestamp of frame (90kHz)
505 uint32_t _width;
506 uint32_t _height;
507 int64_t _renderTimeMs;
508 }; // end of VideoFrame class declaration
509
510 // inline implementation of VideoFrame class:
VideoFrame()511 inline VideoFrame::VideoFrame()
512 : _buffer(0),
513 _bufferSize(0),
514 _bufferLength(0),
515 _timeStamp(0),
516 _width(0),
517 _height(0),
518 _renderTimeMs(0) {
519 //
520 }
~VideoFrame()521 inline VideoFrame::~VideoFrame() {
522 if (_buffer) {
523 delete[] _buffer;
524 _buffer = NULL;
525 }
526 }
527
VerifyAndAllocate(const uint32_t minimumSize)528 inline int32_t VideoFrame::VerifyAndAllocate(const uint32_t minimumSize) {
529 if (minimumSize < 1) {
530 return -1;
531 }
532 if (minimumSize > _bufferSize) {
533 // create buffer of sufficient size
534 uint8_t* newBufferBuffer = new uint8_t[minimumSize];
535 if (_buffer) {
536 // copy old data
537 memcpy(newBufferBuffer, _buffer, _bufferSize);
538 delete[] _buffer;
539 } else {
540 memset(newBufferBuffer, 0, minimumSize * sizeof(uint8_t));
541 }
542 _buffer = newBufferBuffer;
543 _bufferSize = minimumSize;
544 }
545 return 0;
546 }
547
SetLength(const uint32_t newLength)548 inline int32_t VideoFrame::SetLength(const uint32_t newLength) {
549 if (newLength > _bufferSize) { // can't accomodate new value
550 return -1;
551 }
552 _bufferLength = newLength;
553 return 0;
554 }
555
SwapFrame(VideoFrame & videoFrame)556 inline int32_t VideoFrame::SwapFrame(VideoFrame& videoFrame) {
557 uint32_t tmpTimeStamp = _timeStamp;
558 uint32_t tmpWidth = _width;
559 uint32_t tmpHeight = _height;
560 int64_t tmpRenderTime = _renderTimeMs;
561
562 _timeStamp = videoFrame._timeStamp;
563 _width = videoFrame._width;
564 _height = videoFrame._height;
565 _renderTimeMs = videoFrame._renderTimeMs;
566
567 videoFrame._timeStamp = tmpTimeStamp;
568 videoFrame._width = tmpWidth;
569 videoFrame._height = tmpHeight;
570 videoFrame._renderTimeMs = tmpRenderTime;
571
572 return Swap(videoFrame._buffer, videoFrame._bufferLength,
573 videoFrame._bufferSize);
574 }
575
Swap(uint8_t * & newMemory,uint32_t & newLength,uint32_t & newSize)576 inline int32_t VideoFrame::Swap(uint8_t*& newMemory, uint32_t& newLength,
577 uint32_t& newSize) {
578 uint8_t* tmpBuffer = _buffer;
579 uint32_t tmpLength = _bufferLength;
580 uint32_t tmpSize = _bufferSize;
581 _buffer = newMemory;
582 _bufferLength = newLength;
583 _bufferSize = newSize;
584 newMemory = tmpBuffer;
585 newLength = tmpLength;
586 newSize = tmpSize;
587 return 0;
588 }
589
CopyFrame(uint32_t length,const uint8_t * sourceBuffer)590 inline int32_t VideoFrame::CopyFrame(uint32_t length,
591 const uint8_t* sourceBuffer) {
592 if (length > _bufferSize) {
593 int32_t ret = VerifyAndAllocate(length);
594 if (ret < 0) {
595 return ret;
596 }
597 }
598 memcpy(_buffer, sourceBuffer, length);
599 _bufferLength = length;
600 return 0;
601 }
602
CopyFrame(const VideoFrame & videoFrame)603 inline int32_t VideoFrame::CopyFrame(const VideoFrame& videoFrame) {
604 if (CopyFrame(videoFrame.Length(), videoFrame.Buffer()) != 0) {
605 return -1;
606 }
607 _timeStamp = videoFrame._timeStamp;
608 _width = videoFrame._width;
609 _height = videoFrame._height;
610 _renderTimeMs = videoFrame._renderTimeMs;
611 return 0;
612 }
613
Free()614 inline void VideoFrame::Free() {
615 _timeStamp = 0;
616 _bufferLength = 0;
617 _bufferSize = 0;
618 _height = 0;
619 _width = 0;
620 _renderTimeMs = 0;
621
622 if (_buffer) {
623 delete[] _buffer;
624 _buffer = NULL;
625 }
626 }
627
628 /* This class holds up to 60 ms of super-wideband (32 kHz) stereo audio. It
629 * allows for adding and subtracting frames while keeping track of the resulting
630 * states.
631 *
632 * Notes
633 * - The total number of samples in |data_| is
634 * samples_per_channel_ * num_channels_
635 *
636 * - Stereo data is interleaved starting with the left channel.
637 *
638 * - The +operator assume that you would never add exactly opposite frames when
639 * deciding the resulting state. To do this use the -operator.
640 */
641 class AudioFrame {
642 public:
643 // Stereo, 32 kHz, 60 ms (2 * 32 * 60)
644 static const int kMaxDataSizeSamples = 3840;
645
646 enum VADActivity {
647 kVadActive = 0,
648 kVadPassive = 1,
649 kVadUnknown = 2
650 };
651 enum SpeechType {
652 kNormalSpeech = 0,
653 kPLC = 1,
654 kCNG = 2,
655 kPLCCNG = 3,
656 kUndefined = 4
657 };
658
659 AudioFrame();
~AudioFrame()660 virtual ~AudioFrame() {}
661
662 // Resets all members to their default state (except does not modify the
663 // contents of |data_|).
664 void Reset();
665
666 // |interleaved_| is not changed by this method.
667 void UpdateFrame(int id, uint32_t timestamp, const int16_t* data,
668 int samples_per_channel, int sample_rate_hz,
669 SpeechType speech_type, VADActivity vad_activity,
670 int num_channels = 1, uint32_t energy = -1);
671
672 AudioFrame& Append(const AudioFrame& rhs);
673
674 void CopyFrom(const AudioFrame& src);
675
676 void Mute();
677
678 AudioFrame& operator>>=(const int rhs);
679 AudioFrame& operator+=(const AudioFrame& rhs);
680 AudioFrame& operator-=(const AudioFrame& rhs);
681
682 int id_;
683 // RTP timestamp of the first sample in the AudioFrame.
684 uint32_t timestamp_;
685 // Time since the first frame in milliseconds.
686 // -1 represents an uninitialized value.
687 int64_t elapsed_time_ms_;
688 // NTP time of the estimated capture time in local timebase in milliseconds.
689 // -1 represents an uninitialized value.
690 int64_t ntp_time_ms_;
691 int16_t data_[kMaxDataSizeSamples];
692 int samples_per_channel_;
693 int sample_rate_hz_;
694 int num_channels_;
695 SpeechType speech_type_;
696 VADActivity vad_activity_;
697 // Note that there is no guarantee that |energy_| is correct. Any user of this
698 // member must verify that the value is correct.
699 // TODO(henrike) Remove |energy_|.
700 // See https://code.google.com/p/webrtc/issues/detail?id=3315.
701 uint32_t energy_;
702 bool interleaved_;
703
704 private:
705 DISALLOW_COPY_AND_ASSIGN(AudioFrame);
706 };
707
AudioFrame()708 inline AudioFrame::AudioFrame()
709 : data_() {
710 Reset();
711 }
712
Reset()713 inline void AudioFrame::Reset() {
714 id_ = -1;
715 // TODO(wu): Zero is a valid value for |timestamp_|. We should initialize
716 // to an invalid value, or add a new member to indicate invalidity.
717 timestamp_ = 0;
718 elapsed_time_ms_ = -1;
719 ntp_time_ms_ = -1;
720 samples_per_channel_ = 0;
721 sample_rate_hz_ = 0;
722 num_channels_ = 0;
723 speech_type_ = kUndefined;
724 vad_activity_ = kVadUnknown;
725 energy_ = 0xffffffff;
726 interleaved_ = true;
727 }
728
UpdateFrame(int id,uint32_t timestamp,const int16_t * data,int samples_per_channel,int sample_rate_hz,SpeechType speech_type,VADActivity vad_activity,int num_channels,uint32_t energy)729 inline void AudioFrame::UpdateFrame(int id, uint32_t timestamp,
730 const int16_t* data,
731 int samples_per_channel, int sample_rate_hz,
732 SpeechType speech_type,
733 VADActivity vad_activity, int num_channels,
734 uint32_t energy) {
735 id_ = id;
736 timestamp_ = timestamp;
737 samples_per_channel_ = samples_per_channel;
738 sample_rate_hz_ = sample_rate_hz;
739 speech_type_ = speech_type;
740 vad_activity_ = vad_activity;
741 num_channels_ = num_channels;
742 energy_ = energy;
743
744 const int length = samples_per_channel * num_channels;
745 assert(length <= kMaxDataSizeSamples && length >= 0);
746 if (data != NULL) {
747 memcpy(data_, data, sizeof(int16_t) * length);
748 } else {
749 memset(data_, 0, sizeof(int16_t) * length);
750 }
751 }
752
CopyFrom(const AudioFrame & src)753 inline void AudioFrame::CopyFrom(const AudioFrame& src) {
754 if (this == &src) return;
755
756 id_ = src.id_;
757 timestamp_ = src.timestamp_;
758 elapsed_time_ms_ = src.elapsed_time_ms_;
759 ntp_time_ms_ = src.ntp_time_ms_;
760 samples_per_channel_ = src.samples_per_channel_;
761 sample_rate_hz_ = src.sample_rate_hz_;
762 speech_type_ = src.speech_type_;
763 vad_activity_ = src.vad_activity_;
764 num_channels_ = src.num_channels_;
765 energy_ = src.energy_;
766 interleaved_ = src.interleaved_;
767
768 const int length = samples_per_channel_ * num_channels_;
769 assert(length <= kMaxDataSizeSamples && length >= 0);
770 memcpy(data_, src.data_, sizeof(int16_t) * length);
771 }
772
Mute()773 inline void AudioFrame::Mute() {
774 memset(data_, 0, samples_per_channel_ * num_channels_ * sizeof(int16_t));
775 }
776
777 inline AudioFrame& AudioFrame::operator>>=(const int rhs) {
778 assert((num_channels_ > 0) && (num_channels_ < 3));
779 if ((num_channels_ > 2) || (num_channels_ < 1)) return *this;
780
781 for (int i = 0; i < samples_per_channel_ * num_channels_; i++) {
782 data_[i] = static_cast<int16_t>(data_[i] >> rhs);
783 }
784 return *this;
785 }
786
Append(const AudioFrame & rhs)787 inline AudioFrame& AudioFrame::Append(const AudioFrame& rhs) {
788 // Sanity check
789 assert((num_channels_ > 0) && (num_channels_ < 3));
790 assert(interleaved_ == rhs.interleaved_);
791 if ((num_channels_ > 2) || (num_channels_ < 1)) return *this;
792 if (num_channels_ != rhs.num_channels_) return *this;
793
794 if ((vad_activity_ == kVadActive) || rhs.vad_activity_ == kVadActive) {
795 vad_activity_ = kVadActive;
796 } else if (vad_activity_ == kVadUnknown || rhs.vad_activity_ == kVadUnknown) {
797 vad_activity_ = kVadUnknown;
798 }
799 if (speech_type_ != rhs.speech_type_) {
800 speech_type_ = kUndefined;
801 }
802
803 int offset = samples_per_channel_ * num_channels_;
804 for (int i = 0; i < rhs.samples_per_channel_ * rhs.num_channels_; i++) {
805 data_[offset + i] = rhs.data_[i];
806 }
807 samples_per_channel_ += rhs.samples_per_channel_;
808 return *this;
809 }
810
811 inline AudioFrame& AudioFrame::operator+=(const AudioFrame& rhs) {
812 // Sanity check
813 assert((num_channels_ > 0) && (num_channels_ < 3));
814 assert(interleaved_ == rhs.interleaved_);
815 if ((num_channels_ > 2) || (num_channels_ < 1)) return *this;
816 if (num_channels_ != rhs.num_channels_) return *this;
817
818 bool noPrevData = false;
819 if (samples_per_channel_ != rhs.samples_per_channel_) {
820 if (samples_per_channel_ == 0) {
821 // special case we have no data to start with
822 samples_per_channel_ = rhs.samples_per_channel_;
823 noPrevData = true;
824 } else {
825 return *this;
826 }
827 }
828
829 if ((vad_activity_ == kVadActive) || rhs.vad_activity_ == kVadActive) {
830 vad_activity_ = kVadActive;
831 } else if (vad_activity_ == kVadUnknown || rhs.vad_activity_ == kVadUnknown) {
832 vad_activity_ = kVadUnknown;
833 }
834
835 if (speech_type_ != rhs.speech_type_) speech_type_ = kUndefined;
836
837 if (noPrevData) {
838 memcpy(data_, rhs.data_,
839 sizeof(int16_t) * rhs.samples_per_channel_ * num_channels_);
840 } else {
841 // IMPROVEMENT this can be done very fast in assembly
842 for (int i = 0; i < samples_per_channel_ * num_channels_; i++) {
843 int32_t wrapGuard =
844 static_cast<int32_t>(data_[i]) + static_cast<int32_t>(rhs.data_[i]);
845 if (wrapGuard < -32768) {
846 data_[i] = -32768;
847 } else if (wrapGuard > 32767) {
848 data_[i] = 32767;
849 } else {
850 data_[i] = (int16_t)wrapGuard;
851 }
852 }
853 }
854 energy_ = 0xffffffff;
855 return *this;
856 }
857
858 inline AudioFrame& AudioFrame::operator-=(const AudioFrame& rhs) {
859 // Sanity check
860 assert((num_channels_ > 0) && (num_channels_ < 3));
861 assert(interleaved_ == rhs.interleaved_);
862 if ((num_channels_ > 2) || (num_channels_ < 1)) return *this;
863
864 if ((samples_per_channel_ != rhs.samples_per_channel_) ||
865 (num_channels_ != rhs.num_channels_)) {
866 return *this;
867 }
868 if ((vad_activity_ != kVadPassive) || rhs.vad_activity_ != kVadPassive) {
869 vad_activity_ = kVadUnknown;
870 }
871 speech_type_ = kUndefined;
872
873 for (int i = 0; i < samples_per_channel_ * num_channels_; i++) {
874 int32_t wrapGuard =
875 static_cast<int32_t>(data_[i]) - static_cast<int32_t>(rhs.data_[i]);
876 if (wrapGuard < -32768) {
877 data_[i] = -32768;
878 } else if (wrapGuard > 32767) {
879 data_[i] = 32767;
880 } else {
881 data_[i] = (int16_t)wrapGuard;
882 }
883 }
884 energy_ = 0xffffffff;
885 return *this;
886 }
887
IsNewerSequenceNumber(uint16_t sequence_number,uint16_t prev_sequence_number)888 inline bool IsNewerSequenceNumber(uint16_t sequence_number,
889 uint16_t prev_sequence_number) {
890 return sequence_number != prev_sequence_number &&
891 static_cast<uint16_t>(sequence_number - prev_sequence_number) < 0x8000;
892 }
893
IsNewerTimestamp(uint32_t timestamp,uint32_t prev_timestamp)894 inline bool IsNewerTimestamp(uint32_t timestamp, uint32_t prev_timestamp) {
895 return timestamp != prev_timestamp &&
896 static_cast<uint32_t>(timestamp - prev_timestamp) < 0x80000000;
897 }
898
LatestSequenceNumber(uint16_t sequence_number1,uint16_t sequence_number2)899 inline uint16_t LatestSequenceNumber(uint16_t sequence_number1,
900 uint16_t sequence_number2) {
901 return IsNewerSequenceNumber(sequence_number1, sequence_number2)
902 ? sequence_number1
903 : sequence_number2;
904 }
905
LatestTimestamp(uint32_t timestamp1,uint32_t timestamp2)906 inline uint32_t LatestTimestamp(uint32_t timestamp1, uint32_t timestamp2) {
907 return IsNewerTimestamp(timestamp1, timestamp2) ? timestamp1 : timestamp2;
908 }
909
910 } // namespace webrtc
911
912 #endif // MODULE_COMMON_TYPES_H
913