Home | History | Annotate | Download | only in interface
      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 {
     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   // 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 
    716 inline AudioFrame::AudioFrame()
    717     : data_() {
    718   Reset();
    719 }
    720 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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