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 {
InitRTPVideoHeaderH263RTPVideoHeaderH26345     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 {
InitRTPVideoHeaderVP8RTPVideoHeaderVP859     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:
RTPFragmentationHeader()132     RTPFragmentationHeader() :
133         fragmentationVectorSize(0),
134         fragmentationOffset(NULL),
135         fragmentationLength(NULL),
136         fragmentationTimeDiff(NULL),
137         fragmentationPlType(NULL)
138     {};
139 
~RTPFragmentationHeader()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     }
VerifyAndAllocateFragmentationHeader(const WebRtc_UWord16 size)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:
EncodedVideoData()305     EncodedVideoData() :
306         completeFrame(false),
307         missingFrame(false),
308         payloadData(NULL),
309         payloadSize(0),
310         bufferSize(0)
311     {};
312 
EncodedVideoData(const EncodedVideoData & data)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 
~EncodedVideoData()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     };
VerifyAndAllocate(const WebRtc_UWord32 size)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 {
VideoContentMetricsVideoContentMetrics400     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) {   }
ResetVideoContentMetrics404     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     */
SetTimeStamp(const WebRtc_UWord32 timeStamp)476     void SetTimeStamp(const WebRtc_UWord32 timeStamp) {_timeStamp = timeStamp;}
477     /**
478     *   Get pointer to frame buffer
479     */
Buffer()480     WebRtc_UWord8*    Buffer() const {return _buffer;}
481 
Buffer()482     WebRtc_UWord8*&   Buffer() {return _buffer;}
483 
484     /**
485     *   Get allocated buffer size
486     */
Size()487     WebRtc_UWord32    Size() const {return _bufferSize;}
488     /**
489     *   Get frame length
490     */
Length()491     WebRtc_UWord32    Length() const {return _bufferLength;}
492     /**
493     *   Get frame timestamp (90kHz)
494     */
TimeStamp()495     WebRtc_UWord32    TimeStamp() const {return _timeStamp;}
496     /**
497     *   Get frame width
498     */
Width()499     WebRtc_UWord32    Width() const {return _width;}
500     /**
501     *   Get frame height
502     */
Height()503     WebRtc_UWord32    Height() const {return _height;}
504     /**
505     *   Set frame width
506     */
SetWidth(const WebRtc_UWord32 width)507     void   SetWidth(const WebRtc_UWord32 width)  {_width = width;}
508     /**
509     *   Set frame height
510     */
SetHeight(const WebRtc_UWord32 height)511     void  SetHeight(const WebRtc_UWord32 height) {_height = height;}
512     /**
513     *   Set render time in miliseconds
514     */
SetRenderTime(const WebRtc_Word64 renderTimeMs)515     void SetRenderTime(const WebRtc_Word64 renderTimeMs) {_renderTimeMs = renderTimeMs;}
516     /**
517     *  Get render time in miliseconds
518     */
RenderTimeMs()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
VideoFrame()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
~VideoFrame()550 VideoFrame::~VideoFrame()
551 {
552     if(_buffer)
553     {
554         delete [] _buffer;
555         _buffer = NULL;
556     }
557 }
558 
559 
560 inline
561 WebRtc_Word32
VerifyAndAllocate(const WebRtc_UWord32 minimumSize)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
SetLength(const WebRtc_UWord32 newLength)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
SwapFrame(VideoFrame & videoFrame)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
Swap(WebRtc_UWord8 * & newMemory,WebRtc_UWord32 & newLength,WebRtc_UWord32 & newSize)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
CopyFrame(WebRtc_UWord32 length,const WebRtc_UWord8 * sourceBuffer)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
CopyFrame(const VideoFrame & videoFrame)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
Free()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
AudioFrame()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
~AudioFrame()786 AudioFrame::~AudioFrame()
787 {
788 }
789 
790 inline
791 WebRtc_Word32
UpdateFrame(const WebRtc_Word32 id,const WebRtc_UWord32 timeStamp,const WebRtc_Word16 * payloadData,const WebRtc_UWord16 payloadDataLengthInSamples,const int frequencyInHz,const SpeechType speechType,const VADActivity vadActivity,const WebRtc_UWord8 audioChannel,const WebRtc_Word32 volume,const WebRtc_Word32 energy)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
Mute()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&
Append(const AudioFrame & rhs)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