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