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