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