Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / interface / module_common_types.h
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/common_types.h"
20 #include "webrtc/system_wrappers/interface/constructor_magic.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 {
54   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:
112   RTPFragmentationHeader()
113       : fragmentationVectorSize(0),
114         fragmentationOffset(NULL),
115         fragmentationLength(NULL),
116         fragmentationTimeDiff(NULL),
117         fragmentationPlType(NULL) {};
118
119   ~RTPFragmentationHeader() {
120     delete[] fragmentationOffset;
121     delete[] fragmentationLength;
122     delete[] fragmentationTimeDiff;
123     delete[] fragmentationPlType;
124   }
125
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
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
291   virtual ~CallStatsObserver() {}
292 };
293
294 // class describing a complete, or parts of an encoded frame.
295 class EncodedVideoData {
296  public:
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
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
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   };
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 {
386   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
392   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   */
459   void SetTimeStamp(const uint32_t timeStamp) { _timeStamp = timeStamp; }
460   /**
461   *   Get pointer to frame buffer
462   */
463   uint8_t* Buffer() const { return _buffer; }
464
465   uint8_t*& Buffer() { return _buffer; }
466
467   /**
468   *   Get allocated buffer size
469   */
470   uint32_t Size() const { return _bufferSize; }
471   /**
472   *   Get frame length
473   */
474   uint32_t Length() const { return _bufferLength; }
475   /**
476   *   Get frame timestamp (90kHz)
477   */
478   uint32_t TimeStamp() const { return _timeStamp; }
479   /**
480   *   Get frame width
481   */
482   uint32_t Width() const { return _width; }
483   /**
484   *   Get frame height
485   */
486   uint32_t Height() const { return _height; }
487   /**
488   *   Set frame width
489   */
490   void SetWidth(const uint32_t width) { _width = width; }
491   /**
492   *   Set frame height
493   */
494   void SetHeight(const uint32_t height) { _height = height; }
495   /**
496   *   Set render time in miliseconds
497   */
498   void SetRenderTime(const int64_t renderTimeMs) {
499     _renderTimeMs = renderTimeMs;
500   }
501   /**
502   *  Get render time in miliseconds
503   */
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:
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 }
529 inline VideoFrame::~VideoFrame() {
530   if (_buffer) {
531     delete[] _buffer;
532     _buffer = NULL;
533   }
534 }
535
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
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
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
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
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
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
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();
668   virtual ~AudioFrame() {}
669
670   // |interleaved_| is not changed by this method.
671   void UpdateFrame(int id, uint32_t timestamp, const int16_t* data,
672                    int samples_per_channel, int sample_rate_hz,
673                    SpeechType speech_type, VADActivity vad_activity,
674                    int num_channels = 1, uint32_t energy = -1);
675
676   AudioFrame& Append(const AudioFrame& rhs);
677
678   void CopyFrom(const AudioFrame& src);
679
680   void Mute();
681
682   AudioFrame& operator>>=(const int rhs);
683   AudioFrame& operator+=(const AudioFrame& rhs);
684   AudioFrame& operator-=(const AudioFrame& rhs);
685
686   int id_;
687   uint32_t timestamp_;
688   int16_t data_[kMaxDataSizeSamples];
689   int samples_per_channel_;
690   int sample_rate_hz_;
691   int num_channels_;
692   SpeechType speech_type_;
693   VADActivity vad_activity_;
694   uint32_t energy_;
695   bool interleaved_;
696
697  private:
698   DISALLOW_COPY_AND_ASSIGN(AudioFrame);
699 };
700
701 inline AudioFrame::AudioFrame()
702     : id_(-1),
703       timestamp_(0),
704       data_(),
705       samples_per_channel_(0),
706       sample_rate_hz_(0),
707       num_channels_(1),
708       speech_type_(kUndefined),
709       vad_activity_(kVadUnknown),
710       energy_(0xffffffff),
711       interleaved_(true) {}
712
713 inline void AudioFrame::UpdateFrame(int id, uint32_t timestamp,
714                                     const int16_t* data,
715                                     int samples_per_channel, int sample_rate_hz,
716                                     SpeechType speech_type,
717                                     VADActivity vad_activity, int num_channels,
718                                     uint32_t energy) {
719   id_ = id;
720   timestamp_ = timestamp;
721   samples_per_channel_ = samples_per_channel;
722   sample_rate_hz_ = sample_rate_hz;
723   speech_type_ = speech_type;
724   vad_activity_ = vad_activity;
725   num_channels_ = num_channels;
726   energy_ = energy;
727
728   const int length = samples_per_channel * num_channels;
729   assert(length <= kMaxDataSizeSamples && length >= 0);
730   if (data != NULL) {
731     memcpy(data_, data, sizeof(int16_t) * length);
732   } else {
733     memset(data_, 0, sizeof(int16_t) * length);
734   }
735 }
736
737 inline void AudioFrame::CopyFrom(const AudioFrame& src) {
738   if (this == &src) return;
739
740   id_ = src.id_;
741   timestamp_ = src.timestamp_;
742   samples_per_channel_ = src.samples_per_channel_;
743   sample_rate_hz_ = src.sample_rate_hz_;
744   speech_type_ = src.speech_type_;
745   vad_activity_ = src.vad_activity_;
746   num_channels_ = src.num_channels_;
747   energy_ = src.energy_;
748   interleaved_ = src.interleaved_;
749
750   const int length = samples_per_channel_ * num_channels_;
751   assert(length <= kMaxDataSizeSamples && length >= 0);
752   memcpy(data_, src.data_, sizeof(int16_t) * length);
753 }
754
755 inline void AudioFrame::Mute() {
756   memset(data_, 0, samples_per_channel_ * num_channels_ * sizeof(int16_t));
757 }
758
759 inline AudioFrame& AudioFrame::operator>>=(const int rhs) {
760   assert((num_channels_ > 0) && (num_channels_ < 3));
761   if ((num_channels_ > 2) || (num_channels_ < 1)) return *this;
762
763   for (int i = 0; i < samples_per_channel_ * num_channels_; i++) {
764     data_[i] = static_cast<int16_t>(data_[i] >> rhs);
765   }
766   return *this;
767 }
768
769 inline AudioFrame& AudioFrame::Append(const AudioFrame& rhs) {
770   // Sanity check
771   assert((num_channels_ > 0) && (num_channels_ < 3));
772   assert(interleaved_ == rhs.interleaved_);
773   if ((num_channels_ > 2) || (num_channels_ < 1)) return *this;
774   if (num_channels_ != rhs.num_channels_) return *this;
775
776   if ((vad_activity_ == kVadActive) || rhs.vad_activity_ == kVadActive) {
777     vad_activity_ = kVadActive;
778   } else if (vad_activity_ == kVadUnknown || rhs.vad_activity_ == kVadUnknown) {
779     vad_activity_ = kVadUnknown;
780   }
781   if (speech_type_ != rhs.speech_type_) {
782     speech_type_ = kUndefined;
783   }
784
785   int offset = samples_per_channel_ * num_channels_;
786   for (int i = 0; i < rhs.samples_per_channel_ * rhs.num_channels_; i++) {
787     data_[offset + i] = rhs.data_[i];
788   }
789   samples_per_channel_ += rhs.samples_per_channel_;
790   return *this;
791 }
792
793 inline AudioFrame& AudioFrame::operator+=(const AudioFrame& rhs) {
794   // Sanity check
795   assert((num_channels_ > 0) && (num_channels_ < 3));
796   assert(interleaved_ == rhs.interleaved_);
797   if ((num_channels_ > 2) || (num_channels_ < 1)) return *this;
798   if (num_channels_ != rhs.num_channels_) return *this;
799
800   bool noPrevData = false;
801   if (samples_per_channel_ != rhs.samples_per_channel_) {
802     if (samples_per_channel_ == 0) {
803       // special case we have no data to start with
804       samples_per_channel_ = rhs.samples_per_channel_;
805       noPrevData = true;
806     } else {
807       return *this;
808     }
809   }
810
811   if ((vad_activity_ == kVadActive) || rhs.vad_activity_ == kVadActive) {
812     vad_activity_ = kVadActive;
813   } else if (vad_activity_ == kVadUnknown || rhs.vad_activity_ == kVadUnknown) {
814     vad_activity_ = kVadUnknown;
815   }
816
817   if (speech_type_ != rhs.speech_type_) speech_type_ = kUndefined;
818
819   if (noPrevData) {
820     memcpy(data_, rhs.data_,
821            sizeof(int16_t) * rhs.samples_per_channel_ * num_channels_);
822   } else {
823     // IMPROVEMENT this can be done very fast in assembly
824     for (int i = 0; i < samples_per_channel_ * num_channels_; i++) {
825       int32_t wrapGuard =
826           static_cast<int32_t>(data_[i]) + static_cast<int32_t>(rhs.data_[i]);
827       if (wrapGuard < -32768) {
828         data_[i] = -32768;
829       } else if (wrapGuard > 32767) {
830         data_[i] = 32767;
831       } else {
832         data_[i] = (int16_t)wrapGuard;
833       }
834     }
835   }
836   energy_ = 0xffffffff;
837   return *this;
838 }
839
840 inline AudioFrame& AudioFrame::operator-=(const AudioFrame& rhs) {
841   // Sanity check
842   assert((num_channels_ > 0) && (num_channels_ < 3));
843   assert(interleaved_ == rhs.interleaved_);
844   if ((num_channels_ > 2) || (num_channels_ < 1)) return *this;
845
846   if ((samples_per_channel_ != rhs.samples_per_channel_) ||
847       (num_channels_ != rhs.num_channels_)) {
848     return *this;
849   }
850   if ((vad_activity_ != kVadPassive) || rhs.vad_activity_ != kVadPassive) {
851     vad_activity_ = kVadUnknown;
852   }
853   speech_type_ = kUndefined;
854
855   for (int i = 0; i < samples_per_channel_ * num_channels_; i++) {
856     int32_t wrapGuard =
857         static_cast<int32_t>(data_[i]) - static_cast<int32_t>(rhs.data_[i]);
858     if (wrapGuard < -32768) {
859       data_[i] = -32768;
860     } else if (wrapGuard > 32767) {
861       data_[i] = 32767;
862     } else {
863       data_[i] = (int16_t)wrapGuard;
864     }
865   }
866   energy_ = 0xffffffff;
867   return *this;
868 }
869
870 inline bool IsNewerSequenceNumber(uint16_t sequence_number,
871                                   uint16_t prev_sequence_number) {
872   return sequence_number != prev_sequence_number &&
873          static_cast<uint16_t>(sequence_number - prev_sequence_number) < 0x8000;
874 }
875
876 inline bool IsNewerTimestamp(uint32_t timestamp, uint32_t prev_timestamp) {
877   return timestamp != prev_timestamp &&
878          static_cast<uint32_t>(timestamp - prev_timestamp) < 0x80000000;
879 }
880
881 inline uint16_t LatestSequenceNumber(uint16_t sequence_number1,
882                                      uint16_t sequence_number2) {
883   return IsNewerSequenceNumber(sequence_number1, sequence_number2)
884              ? sequence_number1
885              : sequence_number2;
886 }
887
888 inline uint32_t LatestTimestamp(uint32_t timestamp1, uint32_t timestamp2) {
889   return IsNewerTimestamp(timestamp1, timestamp2) ? timestamp1 : timestamp2;
890 }
891
892 }  // namespace webrtc
893
894 #endif  // MODULE_COMMON_TYPES_H