• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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