module_common_types.h revision e48d5845c8b35de2ab73ea055c18a61fa3a9f0be
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
15namespace webrtc
16{
17struct 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
30struct 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
38struct 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};
44enum {kNoPictureId = -1};
45struct 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};
53union RTPVideoTypeHeader
54{
55    RTPVideoHeaderH263      H263;
56    RTPVideoHeaderVP8       VP8;
57};
58
59enum RTPVideoCodecTypes
60{
61    kRTPVideoGeneric  = 0,
62    kRTPVideoH263     = 1,
63    kRTPVideoMPEG4    = 5,
64    kRTPVideoVP8      = 8,
65    kRTPVideoNoVideo  = 10,
66    kRTPVideoFEC      = 11,
67    kRTPVideoI420     = 12
68};
69struct 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};
78union RTPTypeHeader
79{
80    RTPAudioHeader  Audio;
81    RTPVideoHeader  Video;
82};
83
84struct WebRtcRTPHeader
85{
86    RTPHeader       header;
87    FrameType       frameType;
88    RTPTypeHeader   type;
89};
90
91class RTPFragmentationHeader
92{
93public:
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
238struct 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.
264class EncodedVideoData
265{
266public:
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
360struct 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 *************************************************/
394class VideoFrame
395{
396public:
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
483private:
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:
499inline
500VideoFrame::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}
511inline
512VideoFrame::~VideoFrame()
513{
514    if(_buffer)
515    {
516        delete [] _buffer;
517        _buffer = NULL;
518    }
519}
520
521
522inline
523WebRtc_Word32
524VideoFrame::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
546inline
547WebRtc_Word32
548VideoFrame::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
558inline
559WebRtc_Word32
560VideoFrame::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
580inline
581WebRtc_Word32
582VideoFrame::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
596inline
597WebRtc_Word32
598VideoFrame::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
613inline
614WebRtc_Word32
615VideoFrame::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
628inline
629void
630VideoFrame::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 *************************************************/
672class AudioFrame
673{
674public:
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
731inline
732AudioFrame::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
747inline
748AudioFrame::~AudioFrame()
749{
750}
751
752inline
753WebRtc_Word32
754AudioFrame::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
795inline
796void
797AudioFrame::Mute() const
798{
799  memset(_payloadData, 0, _payloadDataLengthInSamples * sizeof(WebRtc_Word16));
800}
801
802inline
803AudioFrame&
804AudioFrame::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
833inline
834AudioFrame&
835AudioFrame::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
850inline
851AudioFrame&
852AudioFrame::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
892inline
893AudioFrame&
894AudioFrame::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
965inline
966AudioFrame&
967AudioFrame::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