• 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 #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