Home | History | Annotate | Download | only in interface
      1 #ifndef MODULE_COMMON_TYPES_H
      2 #define MODULE_COMMON_TYPES_H
      3 
      4 #include <cstring> // memcpy
      5 #include <assert.h>
      6 
      7 #include "typedefs.h"
      8 #include "common_types.h"
      9 
     10 #ifdef _WIN32
     11     #pragma warning(disable:4351)       // remove warning "new behavior: elements of array
     12                                         // 'array' will be default initialized"
     13 #endif
     14 
     15 namespace webrtc
     16 {
     17 struct RTPHeader
     18 {
     19     bool           markerBit;
     20     WebRtc_UWord8  payloadType;
     21     WebRtc_UWord16 sequenceNumber;
     22     WebRtc_UWord32 timestamp;
     23     WebRtc_UWord32 ssrc;
     24     WebRtc_UWord8  numCSRCs;
     25     WebRtc_UWord32 arrOfCSRCs[kRtpCsrcSize];
     26     WebRtc_UWord8  paddingLength;
     27     WebRtc_UWord16 headerLength;
     28 };
     29 
     30 struct RTPAudioHeader
     31 {
     32     WebRtc_UWord8  numEnergy;                         // number of valid entries in arrOfEnergy
     33     WebRtc_UWord8  arrOfEnergy[kRtpCsrcSize];   // one energy byte (0-9) per channel
     34     bool           isCNG;                             // is this CNG
     35     WebRtc_UWord8  channel;                           // number of channels 2 = stereo
     36 };
     37 
     38 struct RTPVideoHeaderH263
     39 {
     40     bool independentlyDecodable;  // H.263-1998 if no P bit it's not independently decodable
     41     bool bits;                    // H.263 mode B, Xor the lasy byte of previus packet with the
     42                                   // first byte of this packet
     43 };
     44 enum {kNoPictureId = -1};
     45 struct RTPVideoHeaderVP8
     46 {
     47     bool           startBit;        // Start of partition.
     48     bool           stopBit;         // Stop of partition.
     49     WebRtc_Word16  pictureId;       // Picture ID index, 15 bits;
     50                                     // kNoPictureId if PictureID does not exist.
     51     bool           nonReference;    // Frame is discardable.
     52 };
     53 union RTPVideoTypeHeader
     54 {
     55     RTPVideoHeaderH263      H263;
     56     RTPVideoHeaderVP8       VP8;
     57 };
     58 
     59 enum RTPVideoCodecTypes
     60 {
     61     kRTPVideoGeneric  = 0,
     62     kRTPVideoH263     = 1,
     63     kRTPVideoMPEG4    = 5,
     64     kRTPVideoVP8      = 8,
     65     kRTPVideoNoVideo  = 10,
     66     kRTPVideoFEC      = 11,
     67     kRTPVideoI420     = 12
     68 };
     69 struct RTPVideoHeader
     70 {
     71     WebRtc_UWord16          width;                  // size
     72     WebRtc_UWord16          height;
     73 
     74     bool                    isFirstPacket;   // first packet in frame
     75     RTPVideoCodecTypes      codec;
     76     RTPVideoTypeHeader      codecHeader;
     77 };
     78 union RTPTypeHeader
     79 {
     80     RTPAudioHeader  Audio;
     81     RTPVideoHeader  Video;
     82 };
     83 
     84 struct WebRtcRTPHeader
     85 {
     86     RTPHeader       header;
     87     FrameType       frameType;
     88     RTPTypeHeader   type;
     89 };
     90 
     91 class RTPFragmentationHeader
     92 {
     93 public:
     94     RTPFragmentationHeader() :
     95         fragmentationVectorSize(0),
     96         fragmentationOffset(NULL),
     97         fragmentationLength(NULL),
     98         fragmentationTimeDiff(NULL),
     99         fragmentationPlType(NULL)
    100     {};
    101 
    102     ~RTPFragmentationHeader()
    103     {
    104         delete [] fragmentationOffset;
    105         delete [] fragmentationLength;
    106         delete [] fragmentationTimeDiff;
    107         delete [] fragmentationPlType;
    108     }
    109 
    110     RTPFragmentationHeader& operator=(const RTPFragmentationHeader& header)
    111     {
    112         if(this == &header)
    113         {
    114             return *this;
    115         }
    116 
    117         if(header.fragmentationVectorSize != fragmentationVectorSize)
    118         {
    119             // new size of vectors
    120 
    121             // delete old
    122             delete [] fragmentationOffset;
    123             fragmentationOffset = NULL;
    124             delete [] fragmentationLength;
    125             fragmentationLength = NULL;
    126             delete [] fragmentationTimeDiff;
    127             fragmentationTimeDiff = NULL;
    128             delete [] fragmentationPlType;
    129             fragmentationPlType = NULL;
    130 
    131             if(header.fragmentationVectorSize > 0)
    132             {
    133                 // allocate new
    134                 if(header.fragmentationOffset)
    135                 {
    136                     fragmentationOffset = new WebRtc_UWord32[header.fragmentationVectorSize];
    137                 }
    138                 if(header.fragmentationLength)
    139                 {
    140                     fragmentationLength = new WebRtc_UWord32[header.fragmentationVectorSize];
    141                 }
    142                 if(header.fragmentationTimeDiff)
    143                 {
    144                     fragmentationTimeDiff = new WebRtc_UWord16[header.fragmentationVectorSize];
    145                 }
    146                 if(header.fragmentationPlType)
    147                 {
    148                     fragmentationPlType = new WebRtc_UWord8[header.fragmentationVectorSize];
    149                 }
    150             }
    151             // set new size
    152             fragmentationVectorSize =   header.fragmentationVectorSize;
    153         }
    154 
    155         if(header.fragmentationVectorSize > 0)
    156         {
    157             // copy values
    158             if(header.fragmentationOffset)
    159             {
    160                 memcpy(fragmentationOffset, header.fragmentationOffset,
    161                         header.fragmentationVectorSize * sizeof(WebRtc_UWord32));
    162             }
    163             if(header.fragmentationLength)
    164             {
    165                 memcpy(fragmentationLength, header.fragmentationLength,
    166                         header.fragmentationVectorSize * sizeof(WebRtc_UWord32));
    167             }
    168             if(header.fragmentationTimeDiff)
    169             {
    170                 memcpy(fragmentationTimeDiff, header.fragmentationTimeDiff,
    171                         header.fragmentationVectorSize * sizeof(WebRtc_UWord16));
    172             }
    173             if(header.fragmentationPlType)
    174             {
    175                 memcpy(fragmentationPlType, header.fragmentationPlType,
    176                         header.fragmentationVectorSize * sizeof(WebRtc_UWord8));
    177             }
    178         }
    179         return *this;
    180     }
    181     void VerifyAndAllocateFragmentationHeader( const WebRtc_UWord16 size)
    182     {
    183         if( fragmentationVectorSize < size)
    184         {
    185             WebRtc_UWord16 oldVectorSize = fragmentationVectorSize;
    186             {
    187                 // offset
    188                 WebRtc_UWord32* oldOffsets = fragmentationOffset;
    189                 fragmentationOffset = new WebRtc_UWord32[size];
    190                 memset(fragmentationOffset+oldVectorSize, 0,
    191                        sizeof(WebRtc_UWord32)*(size-oldVectorSize));
    192                 // copy old values
    193                 memcpy(fragmentationOffset,oldOffsets, sizeof(WebRtc_UWord32) * oldVectorSize);
    194                 delete[] oldOffsets;
    195             }
    196             // length
    197             {
    198                 WebRtc_UWord32* oldLengths = fragmentationLength;
    199                 fragmentationLength = new WebRtc_UWord32[size];
    200                 memset(fragmentationLength+oldVectorSize, 0,
    201                        sizeof(WebRtc_UWord32) * (size- oldVectorSize));
    202                 memcpy(fragmentationLength, oldLengths,
    203                        sizeof(WebRtc_UWord32) * oldVectorSize);
    204                 delete[] oldLengths;
    205             }
    206             // time diff
    207             {
    208                 WebRtc_UWord16* oldTimeDiffs = fragmentationTimeDiff;
    209                 fragmentationTimeDiff = new WebRtc_UWord16[size];
    210                 memset(fragmentationTimeDiff+oldVectorSize, 0,
    211                        sizeof(WebRtc_UWord16) * (size- oldVectorSize));
    212                 memcpy(fragmentationTimeDiff, oldTimeDiffs,
    213                        sizeof(WebRtc_UWord16) * oldVectorSize);
    214                 delete[] oldTimeDiffs;
    215             }
    216             // payload type
    217             {
    218                 WebRtc_UWord8* oldTimePlTypes = fragmentationPlType;
    219                 fragmentationPlType = new WebRtc_UWord8[size];
    220                 memset(fragmentationPlType+oldVectorSize, 0,
    221                        sizeof(WebRtc_UWord8) * (size- oldVectorSize));
    222                 memcpy(fragmentationPlType, oldTimePlTypes,
    223                        sizeof(WebRtc_UWord8) * oldVectorSize);
    224                 delete[] oldTimePlTypes;
    225             }
    226             fragmentationVectorSize = size;
    227         }
    228     }
    229 
    230     WebRtc_UWord16    fragmentationVectorSize;    // Number of fragmentations
    231     WebRtc_UWord32*   fragmentationOffset;        // Offset of pointer to data for each fragm.
    232     WebRtc_UWord32*   fragmentationLength;        // Data size for each fragmentation
    233     WebRtc_UWord16*   fragmentationTimeDiff;      // Timestamp difference relative "now" for
    234                                                   // each fragmentation
    235     WebRtc_UWord8*    fragmentationPlType;        // Payload type of each fragmentation
    236 };
    237 
    238 struct RTCPVoIPMetric
    239 {
    240     // RFC 3611 4.7
    241     WebRtc_UWord8     lossRate;
    242     WebRtc_UWord8     discardRate;
    243     WebRtc_UWord8     burstDensity;
    244     WebRtc_UWord8     gapDensity;
    245     WebRtc_UWord16    burstDuration;
    246     WebRtc_UWord16    gapDuration;
    247     WebRtc_UWord16    roundTripDelay;
    248     WebRtc_UWord16    endSystemDelay;
    249     WebRtc_UWord8     signalLevel;
    250     WebRtc_UWord8     noiseLevel;
    251     WebRtc_UWord8     RERL;
    252     WebRtc_UWord8     Gmin;
    253     WebRtc_UWord8     Rfactor;
    254     WebRtc_UWord8     extRfactor;
    255     WebRtc_UWord8     MOSLQ;
    256     WebRtc_UWord8     MOSCQ;
    257     WebRtc_UWord8     RXconfig;
    258     WebRtc_UWord16    JBnominal;
    259     WebRtc_UWord16    JBmax;
    260     WebRtc_UWord16    JBabsMax;
    261 };
    262 
    263 // class describing a complete, or parts of an encoded frame.
    264 class EncodedVideoData
    265 {
    266 public:
    267     EncodedVideoData() :
    268         completeFrame(false),
    269         missingFrame(false),
    270         payloadData(NULL),
    271         payloadSize(0),
    272         bufferSize(0)
    273     {};
    274 
    275     EncodedVideoData(const EncodedVideoData& data)
    276     {
    277         payloadType         = data.payloadType;
    278         timeStamp           = data.timeStamp;
    279         renderTimeMs        = data.renderTimeMs;
    280         encodedWidth        = data.encodedWidth;
    281         encodedHeight       = data.encodedHeight;
    282         completeFrame       = data.completeFrame;
    283         missingFrame        = data.missingFrame;
    284         payloadSize         = data.payloadSize;
    285         fragmentationHeader = data.fragmentationHeader;
    286         frameType           = data.frameType;
    287         codec               = data.codec;
    288         if (data.payloadSize > 0)
    289         {
    290             payloadData = new WebRtc_UWord8[data.payloadSize];
    291             memcpy(payloadData, data.payloadData, data.payloadSize);
    292         }
    293         else
    294         {
    295             payloadData = NULL;
    296         }
    297     }
    298 
    299 
    300     ~EncodedVideoData()
    301     {
    302         delete [] payloadData;
    303     };
    304 
    305     EncodedVideoData& operator=(const EncodedVideoData& data)
    306     {
    307         if (this == &data)
    308         {
    309             return *this;
    310         }
    311         payloadType         = data.payloadType;
    312         timeStamp           = data.timeStamp;
    313         renderTimeMs        = data.renderTimeMs;
    314         encodedWidth        = data.encodedWidth;
    315         encodedHeight       = data.encodedHeight;
    316         completeFrame       = data.completeFrame;
    317         missingFrame        = data.missingFrame;
    318         payloadSize         = data.payloadSize;
    319         fragmentationHeader = data.fragmentationHeader;
    320         frameType           = data.frameType;
    321         codec               = data.codec;
    322         if (data.payloadSize > 0)
    323         {
    324             delete [] payloadData;
    325             payloadData = new WebRtc_UWord8[data.payloadSize];
    326             memcpy(payloadData, data.payloadData, data.payloadSize);
    327             bufferSize = data.payloadSize;
    328         }
    329         return *this;
    330     };
    331     void VerifyAndAllocate( const WebRtc_UWord32 size)
    332     {
    333         if (bufferSize < size)
    334         {
    335             WebRtc_UWord8* oldPayload = payloadData;
    336             payloadData = new WebRtc_UWord8[size];
    337             memcpy(payloadData, oldPayload, sizeof(WebRtc_UWord8) * payloadSize);
    338 
    339             bufferSize = size;
    340             delete[] oldPayload;
    341         }
    342     }
    343 
    344     WebRtc_UWord8               payloadType;
    345     WebRtc_UWord32              timeStamp;
    346     WebRtc_Word64               renderTimeMs;
    347     WebRtc_UWord32              encodedWidth;
    348     WebRtc_UWord32              encodedHeight;
    349     bool                        completeFrame;
    350     bool                        missingFrame;
    351     WebRtc_UWord8*              payloadData;
    352     WebRtc_UWord32              payloadSize;
    353     WebRtc_UWord32              bufferSize;
    354     RTPFragmentationHeader      fragmentationHeader;
    355     FrameType                   frameType;
    356     VideoCodecType              codec;
    357 };
    358 
    359 // Video Content Metrics
    360 struct VideoContentMetrics
    361 {
    362     VideoContentMetrics(): motionMagnitudeNZ(0), sizeZeroMotion(0), spatialPredErr(0),
    363             spatialPredErrH(0), spatialPredErrV(0), motionPredErr(0),
    364             motionHorizontalness(0), motionClusterDistortion(0),
    365             nativeWidth(0), nativeHeight(0), contentChange(false) {   }
    366     void Reset(){ motionMagnitudeNZ = 0; sizeZeroMotion = 0; spatialPredErr = 0;
    367             spatialPredErrH = 0; spatialPredErrV = 0; motionPredErr = 0;
    368             motionHorizontalness = 0; motionClusterDistortion = 0;
    369             nativeWidth = 0; nativeHeight = 0; contentChange = false; }
    370 
    371     float            motionMagnitudeNZ;
    372     float            sizeZeroMotion;
    373     float            spatialPredErr;
    374     float            spatialPredErrH;
    375     float            spatialPredErrV;
    376     float            motionPredErr;
    377     float            motionHorizontalness;
    378     float            motionClusterDistortion;
    379     WebRtc_UWord32   nativeWidth;
    380     WebRtc_UWord32   nativeHeight;
    381     WebRtc_UWord32   nativeFrameRate;
    382     bool             contentChange;
    383 };
    384 
    385 /*************************************************
    386  *
    387  * VideoFrame class
    388  *
    389  * The VideoFrame class allows storing and
    390  * handling of video frames.
    391  *
    392  *
    393  *************************************************/
    394 class VideoFrame
    395 {
    396 public:
    397     VideoFrame();
    398     ~VideoFrame();
    399     /**
    400     * Verifies that current allocated buffer size is larger than or equal to the input size.
    401     * If the current buffer size is smaller, a new allocation is made and the old buffer data
    402     * is copied to the new buffer.
    403     * Buffer size is updated to minimumSize.
    404     */
    405     WebRtc_Word32 VerifyAndAllocate(const WebRtc_UWord32 minimumSize);
    406     /**
    407     *    Update length of data buffer in frame. Function verifies that new length is less or
    408     *    equal to allocated size.
    409     */
    410     WebRtc_Word32 SetLength(const WebRtc_UWord32 newLength);
    411     /*
    412     *    Swap buffer and size data
    413     */
    414     WebRtc_Word32 Swap(WebRtc_UWord8*& newMemory,
    415                        WebRtc_UWord32& newLength,
    416                        WebRtc_UWord32& newSize);
    417     /*
    418     *    Swap buffer and size data
    419     */
    420     WebRtc_Word32 SwapFrame(VideoFrame& videoFrame);
    421     /**
    422     *    Copy buffer: If newLength is bigger than allocated size, a new buffer of size length
    423     *    is allocated.
    424     */
    425     WebRtc_Word32 CopyFrame(const VideoFrame& videoFrame);
    426     /**
    427     *    Copy buffer: If newLength is bigger than allocated size, a new buffer of size length
    428     *    is allocated.
    429     */
    430     WebRtc_Word32 CopyFrame(WebRtc_UWord32 length, const WebRtc_UWord8* sourceBuffer);
    431     /**
    432     *    Delete VideoFrame and resets members to zero
    433     */
    434     void Free();
    435     /**
    436     *   Set frame timestamp (90kHz)
    437     */
    438     void SetTimeStamp(const WebRtc_UWord32 timeStamp) {_timeStamp = timeStamp;}
    439     /**
    440     *   Get pointer to frame buffer
    441     */
    442     WebRtc_UWord8*    Buffer() const {return _buffer;}
    443 
    444     WebRtc_UWord8*&   Buffer() {return _buffer;}
    445 
    446     /**
    447     *   Get allocated buffer size
    448     */
    449     WebRtc_UWord32    Size() const {return _bufferSize;}
    450     /**
    451     *   Get frame length
    452     */
    453     WebRtc_UWord32    Length() const {return _bufferLength;}
    454     /**
    455     *   Get frame timestamp (90kHz)
    456     */
    457     WebRtc_UWord32    TimeStamp() const {return _timeStamp;}
    458     /**
    459     *   Get frame width
    460     */
    461     WebRtc_UWord32    Width() const {return _width;}
    462     /**
    463     *   Get frame height
    464     */
    465     WebRtc_UWord32    Height() const {return _height;}
    466     /**
    467     *   Set frame width
    468     */
    469     void   SetWidth(const WebRtc_UWord32 width)  {_width = width;}
    470     /**
    471     *   Set frame height
    472     */
    473     void  SetHeight(const WebRtc_UWord32 height) {_height = height;}
    474     /**
    475     *   Set render time in miliseconds
    476     */
    477     void SetRenderTime(const WebRtc_Word64 renderTimeMs) {_renderTimeMs = renderTimeMs;}
    478     /**
    479     *  Get render time in miliseconds
    480     */
    481     WebRtc_Word64    RenderTimeMs() const {return _renderTimeMs;}
    482 
    483 private:
    484     void Set(WebRtc_UWord8* buffer,
    485              WebRtc_UWord32 size,
    486              WebRtc_UWord32 length,
    487              WebRtc_UWord32 timeStamp);
    488 
    489     WebRtc_UWord8*          _buffer;          // Pointer to frame buffer
    490     WebRtc_UWord32          _bufferSize;      // Allocated buffer size
    491     WebRtc_UWord32          _bufferLength;    // Length (in bytes) of buffer
    492     WebRtc_UWord32          _timeStamp;       // Timestamp of frame (90kHz)
    493     WebRtc_UWord32          _width;
    494     WebRtc_UWord32          _height;
    495     WebRtc_Word64           _renderTimeMs;
    496 }; // end of VideoFrame class declaration
    497 
    498 // inline implementation of VideoFrame class:
    499 inline
    500 VideoFrame::VideoFrame():
    501     _buffer(0),
    502     _bufferSize(0),
    503     _bufferLength(0),
    504     _timeStamp(0),
    505     _width(0),
    506     _height(0),
    507     _renderTimeMs(0)
    508 {
    509     //
    510 }
    511 inline
    512 VideoFrame::~VideoFrame()
    513 {
    514     if(_buffer)
    515     {
    516         delete [] _buffer;
    517         _buffer = NULL;
    518     }
    519 }
    520 
    521 
    522 inline
    523 WebRtc_Word32
    524 VideoFrame::VerifyAndAllocate(const WebRtc_UWord32 minimumSize)
    525 {
    526     if (minimumSize < 1)
    527     {
    528         return -1;
    529     }
    530     if(minimumSize > _bufferSize)
    531     {
    532         // create buffer of sufficient size
    533         WebRtc_UWord8* newBufferBuffer = new WebRtc_UWord8[minimumSize];
    534         if(_buffer)
    535         {
    536             // copy old data
    537             memcpy(newBufferBuffer, _buffer, _bufferSize);
    538             delete [] _buffer;
    539         }
    540         _buffer = newBufferBuffer;
    541         _bufferSize = minimumSize;
    542     }
    543      return 0;
    544 }
    545 
    546 inline
    547 WebRtc_Word32
    548 VideoFrame::SetLength(const WebRtc_UWord32 newLength)
    549 {
    550     if (newLength >_bufferSize )
    551     { // can't accomodate new value
    552         return -1;
    553     }
    554      _bufferLength = newLength;
    555      return 0;
    556 }
    557 
    558 inline
    559 WebRtc_Word32
    560 VideoFrame::SwapFrame(VideoFrame& videoFrame)
    561 {
    562     WebRtc_UWord32 tmpTimeStamp  = _timeStamp;
    563     WebRtc_UWord32 tmpWidth      = _width;
    564     WebRtc_UWord32 tmpHeight     = _height;
    565     WebRtc_Word64  tmpRenderTime = _renderTimeMs;
    566 
    567     _timeStamp = videoFrame._timeStamp;
    568     _width = videoFrame._width;
    569     _height = videoFrame._height;
    570     _renderTimeMs = videoFrame._renderTimeMs;
    571 
    572     videoFrame._timeStamp = tmpTimeStamp;
    573     videoFrame._width = tmpWidth;
    574     videoFrame._height = tmpHeight;
    575     videoFrame._renderTimeMs = tmpRenderTime;
    576 
    577     return Swap(videoFrame._buffer, videoFrame._bufferLength, videoFrame._bufferSize);
    578 }
    579 
    580 inline
    581 WebRtc_Word32
    582 VideoFrame::Swap(WebRtc_UWord8*& newMemory, WebRtc_UWord32& newLength, WebRtc_UWord32& newSize)
    583 {
    584     WebRtc_UWord8* tmpBuffer = _buffer;
    585     WebRtc_UWord32 tmpLength = _bufferLength;
    586     WebRtc_UWord32 tmpSize = _bufferSize;
    587     _buffer = newMemory;
    588     _bufferLength = newLength;
    589     _bufferSize = newSize;
    590     newMemory = tmpBuffer;
    591     newLength = tmpLength;
    592     newSize = tmpSize;
    593     return 0;
    594 }
    595 
    596 inline
    597 WebRtc_Word32
    598 VideoFrame::CopyFrame(WebRtc_UWord32 length, const WebRtc_UWord8* sourceBuffer)
    599 {
    600     if (length > _bufferSize)
    601     {
    602         WebRtc_Word32 ret = VerifyAndAllocate(length);
    603         if (ret < 0)
    604         {
    605             return ret;
    606         }
    607     }
    608      memcpy(_buffer, sourceBuffer, length);
    609     _bufferLength = length;
    610     return 0;
    611 }
    612 
    613 inline
    614 WebRtc_Word32
    615 VideoFrame::CopyFrame(const VideoFrame& videoFrame)
    616 {
    617     if(CopyFrame(videoFrame.Length(), videoFrame.Buffer()) != 0)
    618     {
    619         return -1;
    620     }
    621     _timeStamp = videoFrame._timeStamp;
    622     _width = videoFrame._width;
    623     _height = videoFrame._height;
    624     _renderTimeMs = videoFrame._renderTimeMs;
    625     return 0;
    626 }
    627 
    628 inline
    629 void
    630 VideoFrame::Free()
    631 {
    632     _timeStamp = 0;
    633     _bufferLength = 0;
    634     _bufferSize = 0;
    635     _height = 0;
    636     _width = 0;
    637     _renderTimeMs = 0;
    638 
    639     if(_buffer)
    640     {
    641         delete [] _buffer;
    642         _buffer = NULL;
    643     }
    644 }
    645 
    646 
    647 /*************************************************
    648  *
    649  * AudioFrame class
    650  *
    651  * The AudioFrame class holds up to 60 ms wideband
    652  * audio. It allows for adding and subtracting frames
    653  * while keeping track of the resulting states.
    654  *
    655  * Note
    656  * - The +operator assume that you would never add
    657  *   exact opposite frames when deciding the resulting
    658  *   state. To do this use the -operator.
    659  *
    660  * - _audioChannel of 1 indicated mono, and 2
    661  *   indicates stereo.
    662  *
    663  * - _payloadDataLengthInSamples is the number of
    664  *   samples per channel. Therefore, the total
    665  *   number of samples in _payloadData is
    666  *   (_payloadDataLengthInSamples * _audioChannel).
    667  *
    668  * - Stereo data is stored in interleaved fashion
    669  *   starting with the left channel.
    670  *
    671  *************************************************/
    672 class AudioFrame
    673 {
    674 public:
    675     enum{kMaxAudioFrameSizeSamples = 3840}; // stereo 32KHz 60ms 2*32*60
    676 
    677     enum VADActivity
    678     {
    679         kVadActive  = 0,
    680         kVadPassive = 1,
    681         kVadUnknown = 2
    682     };
    683     enum SpeechType
    684     {
    685         kNormalSpeech = 0,
    686         kPLC          = 1,
    687         kCNG          = 2,
    688         kPLCCNG       = 3,
    689         kUndefined    = 4
    690     };
    691 
    692     AudioFrame();
    693     virtual ~AudioFrame();
    694 
    695     WebRtc_Word32 UpdateFrame(
    696         const WebRtc_Word32  id,
    697         const WebRtc_UWord32 timeStamp,
    698         const WebRtc_Word16* payloadData,
    699         const WebRtc_UWord16 payloadDataLengthInSamples,
    700         const WebRtc_UWord32 frequencyInHz,
    701         const SpeechType     speechType,
    702         const VADActivity    vadActivity,
    703         const WebRtc_UWord8  audioChannel = 1,
    704         const WebRtc_Word32  volume = -1,
    705         const WebRtc_Word32  energy = -1);
    706 
    707     AudioFrame& Append(const AudioFrame& rhs);
    708 
    709     void Mute() const;
    710 
    711     AudioFrame& operator=(const AudioFrame& rhs);
    712     AudioFrame& operator>>=(const WebRtc_Word32 rhs);
    713     AudioFrame& operator+=(const AudioFrame& rhs);
    714     AudioFrame& operator-=(const AudioFrame& rhs);
    715 
    716     WebRtc_Word32  _id;
    717     WebRtc_UWord32 _timeStamp;
    718 
    719     // Supporting Stereo, stereo samples are interleaved
    720     mutable WebRtc_Word16 _payloadData[kMaxAudioFrameSizeSamples];
    721     WebRtc_UWord16 _payloadDataLengthInSamples;
    722     WebRtc_UWord32 _frequencyInHz;
    723     WebRtc_UWord8  _audioChannel;
    724     SpeechType   _speechType;
    725     VADActivity  _vadActivity;
    726 
    727     WebRtc_UWord32 _energy;
    728     WebRtc_Word32  _volume;
    729 };
    730 
    731 inline
    732 AudioFrame::AudioFrame()
    733     :
    734     _id(-1),
    735     _timeStamp(0),
    736     _payloadData(),
    737     _payloadDataLengthInSamples(0),
    738     _frequencyInHz(0),
    739     _audioChannel(1),
    740     _speechType(kUndefined),
    741     _vadActivity(kVadUnknown),
    742     _energy(0xffffffff),
    743     _volume(0xffffffff)
    744 {
    745 }
    746 
    747 inline
    748 AudioFrame::~AudioFrame()
    749 {
    750 }
    751 
    752 inline
    753 WebRtc_Word32
    754 AudioFrame::UpdateFrame(
    755     const WebRtc_Word32  id,
    756     const WebRtc_UWord32 timeStamp,
    757     const WebRtc_Word16* payloadData,
    758     const WebRtc_UWord16 payloadDataLengthInSamples,
    759     const WebRtc_UWord32 frequencyInHz,
    760     const SpeechType     speechType,
    761     const VADActivity    vadActivity,
    762     const WebRtc_UWord8  audioChannel,
    763     const WebRtc_Word32  volume,
    764     const WebRtc_Word32  energy)
    765 {
    766     _id            = id;
    767     _timeStamp     = timeStamp;
    768     _frequencyInHz = frequencyInHz;
    769     _speechType    = speechType;
    770     _vadActivity   = vadActivity;
    771     _volume        = volume;
    772     _audioChannel  = audioChannel;
    773     _energy        = energy;
    774 
    775     if((payloadDataLengthInSamples > kMaxAudioFrameSizeSamples) ||
    776         (audioChannel > 2) || (audioChannel < 1))
    777     {
    778         _payloadDataLengthInSamples = 0;
    779         return -1;
    780     }
    781     _payloadDataLengthInSamples = payloadDataLengthInSamples;
    782     if(payloadData != NULL)
    783     {
    784         memcpy(_payloadData, payloadData, sizeof(WebRtc_Word16) *
    785             payloadDataLengthInSamples * _audioChannel);
    786     }
    787     else
    788     {
    789         memset(_payloadData,0,sizeof(WebRtc_Word16) *
    790             payloadDataLengthInSamples * _audioChannel);
    791     }
    792     return 0;
    793 }
    794 
    795 inline
    796 void
    797 AudioFrame::Mute() const
    798 {
    799   memset(_payloadData, 0, _payloadDataLengthInSamples * sizeof(WebRtc_Word16));
    800 }
    801 
    802 inline
    803 AudioFrame&
    804 AudioFrame::operator=(const AudioFrame& rhs)
    805 {
    806     // Sanity Check
    807     if((rhs._payloadDataLengthInSamples > kMaxAudioFrameSizeSamples) ||
    808         (rhs._audioChannel > 2) ||
    809         (rhs._audioChannel < 1))
    810     {
    811         return *this;
    812     }
    813     if(this == &rhs)
    814     {
    815         return *this;
    816     }
    817     _id               = rhs._id;
    818     _timeStamp        = rhs._timeStamp;
    819     _frequencyInHz    = rhs._frequencyInHz;
    820     _speechType       = rhs._speechType;
    821     _vadActivity      = rhs._vadActivity;
    822     _volume           = rhs._volume;
    823     _audioChannel     = rhs._audioChannel;
    824     _energy           = rhs._energy;
    825 
    826     _payloadDataLengthInSamples = rhs._payloadDataLengthInSamples;
    827     memcpy(_payloadData, rhs._payloadData,
    828         sizeof(WebRtc_Word16) * rhs._payloadDataLengthInSamples * _audioChannel);
    829 
    830     return *this;
    831 }
    832 
    833 inline
    834 AudioFrame&
    835 AudioFrame::operator>>=(const WebRtc_Word32 rhs)
    836 {
    837     assert((_audioChannel > 0) && (_audioChannel < 3));
    838     if((_audioChannel > 2) ||
    839         (_audioChannel < 1))
    840     {
    841         return *this;
    842     }
    843     for(WebRtc_UWord16 i = 0; i < _payloadDataLengthInSamples * _audioChannel; i++)
    844     {
    845         _payloadData[i] = WebRtc_Word16(_payloadData[i] >> rhs);
    846     }
    847     return *this;
    848 }
    849 
    850 inline
    851 AudioFrame&
    852 AudioFrame::Append(const AudioFrame& rhs)
    853 {
    854     // Sanity check
    855     assert((_audioChannel > 0) && (_audioChannel < 3));
    856     if((_audioChannel > 2) ||
    857         (_audioChannel < 1))
    858     {
    859         return *this;
    860     }
    861     if(_audioChannel != rhs._audioChannel)
    862     {
    863         return *this;
    864     }
    865     if((_vadActivity == kVadActive) ||
    866         rhs._vadActivity == kVadActive)
    867     {
    868         _vadActivity = kVadActive;
    869     }
    870     else if((_vadActivity == kVadUnknown) ||
    871         rhs._vadActivity == kVadUnknown)
    872     {
    873         _vadActivity = kVadUnknown;
    874     }
    875     if(_speechType != rhs._speechType)
    876     {
    877         _speechType = kUndefined;
    878     }
    879 
    880     WebRtc_UWord16 offset = _payloadDataLengthInSamples * _audioChannel;
    881     for(WebRtc_UWord16 i = 0;
    882         i < rhs._payloadDataLengthInSamples * rhs._audioChannel;
    883         i++)
    884     {
    885         _payloadData[offset+i] = rhs._payloadData[i];
    886     }
    887     _payloadDataLengthInSamples += rhs._payloadDataLengthInSamples;
    888     return *this;
    889 }
    890 
    891 // merge vectors
    892 inline
    893 AudioFrame&
    894 AudioFrame::operator+=(const AudioFrame& rhs)
    895 {
    896     // Sanity check
    897     assert((_audioChannel > 0) && (_audioChannel < 3));
    898     if((_audioChannel > 2) ||
    899         (_audioChannel < 1))
    900     {
    901         return *this;
    902     }
    903     if(_audioChannel != rhs._audioChannel)
    904     {
    905         return *this;
    906     }
    907     bool noPrevData = false;
    908     if(_payloadDataLengthInSamples != rhs._payloadDataLengthInSamples)
    909     {
    910         if(_payloadDataLengthInSamples == 0)
    911         {
    912             // special case we have no data to start with
    913             _payloadDataLengthInSamples = rhs._payloadDataLengthInSamples;
    914             noPrevData = true;
    915         } else
    916         {
    917           return *this;
    918         }
    919     }
    920 
    921     if((_vadActivity == kVadActive) ||
    922         rhs._vadActivity == kVadActive)
    923     {
    924         _vadActivity = kVadActive;
    925     }
    926     else if((_vadActivity == kVadUnknown) ||
    927         rhs._vadActivity == kVadUnknown)
    928     {
    929         _vadActivity = kVadUnknown;
    930     }
    931 
    932     if(_speechType != rhs._speechType)
    933     {
    934         _speechType = kUndefined;
    935     }
    936 
    937     if(noPrevData)
    938     {
    939         memcpy(_payloadData, rhs._payloadData,
    940           sizeof(WebRtc_Word16) * rhs._payloadDataLengthInSamples * _audioChannel);
    941     } else
    942     {
    943       // IMPROVEMENT this can be done very fast in assembly
    944       for(WebRtc_UWord16 i = 0; i < _payloadDataLengthInSamples * _audioChannel; i++)
    945       {
    946           WebRtc_Word32 wrapGuard = (WebRtc_Word32)_payloadData[i] +
    947                   (WebRtc_Word32)rhs._payloadData[i];
    948           if(wrapGuard < -32768)
    949           {
    950               _payloadData[i] = -32768;
    951           }else if(wrapGuard > 32767)
    952           {
    953               _payloadData[i] = 32767;
    954           }else
    955           {
    956               _payloadData[i] = (WebRtc_Word16)wrapGuard;
    957           }
    958       }
    959     }
    960     _energy = 0xffffffff;
    961     _volume = 0xffffffff;
    962     return *this;
    963 }
    964 
    965 inline
    966 AudioFrame&
    967 AudioFrame::operator-=(const AudioFrame& rhs)
    968 {
    969     // Sanity check
    970     assert((_audioChannel > 0) && (_audioChannel < 3));
    971     if((_audioChannel > 2)||
    972         (_audioChannel < 1))
    973     {
    974         return *this;
    975     }
    976     if((_payloadDataLengthInSamples != rhs._payloadDataLengthInSamples) ||
    977         (_audioChannel != rhs._audioChannel))
    978     {
    979         return *this;
    980     }
    981     if((_vadActivity != kVadPassive) ||
    982         rhs._vadActivity != kVadPassive)
    983     {
    984         _vadActivity = kVadUnknown;
    985     }
    986     _speechType = kUndefined;
    987 
    988     for(WebRtc_UWord16 i = 0; i < _payloadDataLengthInSamples * _audioChannel; i++)
    989     {
    990         WebRtc_Word32 wrapGuard = (WebRtc_Word32)_payloadData[i] -
    991                 (WebRtc_Word32)rhs._payloadData[i];
    992         if(wrapGuard < -32768)
    993         {
    994             _payloadData[i] = -32768;
    995         }
    996         else if(wrapGuard > 32767)
    997         {
    998             _payloadData[i] = 32767;
    999         }
   1000         else
   1001         {
   1002             _payloadData[i] = (WebRtc_Word16)wrapGuard;
   1003         }
   1004     }
   1005     _energy = 0xffffffff;
   1006     _volume = 0xffffffff;
   1007     return *this;
   1008 }
   1009 
   1010 } // namespace webrtc
   1011 
   1012 #endif // MODULE_COMMON_TYPES_H
   1013