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