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