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: 94 RTPFragmentationHeader() : 95 fragmentationVectorSize(0), 96 fragmentationOffset(NULL), 97 fragmentationLength(NULL), 98 fragmentationTimeDiff(NULL), 99 fragmentationPlType(NULL) 100 {}; 101 102 ~RTPFragmentationHeader() 103 { 104 delete [] fragmentationOffset; 105 delete [] fragmentationLength; 106 delete [] fragmentationTimeDiff; 107 delete [] fragmentationPlType; 108 } 109 110 RTPFragmentationHeader& operator=(const RTPFragmentationHeader& header) 111 { 112 if(this == &header) 113 { 114 return *this; 115 } 116 117 if(header.fragmentationVectorSize != fragmentationVectorSize) 118 { 119 // new size of vectors 120 121 // delete old 122 delete [] fragmentationOffset; 123 fragmentationOffset = NULL; 124 delete [] fragmentationLength; 125 fragmentationLength = NULL; 126 delete [] fragmentationTimeDiff; 127 fragmentationTimeDiff = NULL; 128 delete [] fragmentationPlType; 129 fragmentationPlType = NULL; 130 131 if(header.fragmentationVectorSize > 0) 132 { 133 // allocate new 134 if(header.fragmentationOffset) 135 { 136 fragmentationOffset = new WebRtc_UWord32[header.fragmentationVectorSize]; 137 } 138 if(header.fragmentationLength) 139 { 140 fragmentationLength = new WebRtc_UWord32[header.fragmentationVectorSize]; 141 } 142 if(header.fragmentationTimeDiff) 143 { 144 fragmentationTimeDiff = new WebRtc_UWord16[header.fragmentationVectorSize]; 145 } 146 if(header.fragmentationPlType) 147 { 148 fragmentationPlType = new WebRtc_UWord8[header.fragmentationVectorSize]; 149 } 150 } 151 // set new size 152 fragmentationVectorSize = header.fragmentationVectorSize; 153 } 154 155 if(header.fragmentationVectorSize > 0) 156 { 157 // copy values 158 if(header.fragmentationOffset) 159 { 160 memcpy(fragmentationOffset, header.fragmentationOffset, 161 header.fragmentationVectorSize * sizeof(WebRtc_UWord32)); 162 } 163 if(header.fragmentationLength) 164 { 165 memcpy(fragmentationLength, header.fragmentationLength, 166 header.fragmentationVectorSize * sizeof(WebRtc_UWord32)); 167 } 168 if(header.fragmentationTimeDiff) 169 { 170 memcpy(fragmentationTimeDiff, header.fragmentationTimeDiff, 171 header.fragmentationVectorSize * sizeof(WebRtc_UWord16)); 172 } 173 if(header.fragmentationPlType) 174 { 175 memcpy(fragmentationPlType, header.fragmentationPlType, 176 header.fragmentationVectorSize * sizeof(WebRtc_UWord8)); 177 } 178 } 179 return *this; 180 } 181 void VerifyAndAllocateFragmentationHeader( const WebRtc_UWord16 size) 182 { 183 if( fragmentationVectorSize < size) 184 { 185 WebRtc_UWord16 oldVectorSize = fragmentationVectorSize; 186 { 187 // offset 188 WebRtc_UWord32* oldOffsets = fragmentationOffset; 189 fragmentationOffset = new WebRtc_UWord32[size]; 190 memset(fragmentationOffset+oldVectorSize, 0, 191 sizeof(WebRtc_UWord32)*(size-oldVectorSize)); 192 // copy old values 193 memcpy(fragmentationOffset,oldOffsets, sizeof(WebRtc_UWord32) * oldVectorSize); 194 delete[] oldOffsets; 195 } 196 // length 197 { 198 WebRtc_UWord32* oldLengths = fragmentationLength; 199 fragmentationLength = new WebRtc_UWord32[size]; 200 memset(fragmentationLength+oldVectorSize, 0, 201 sizeof(WebRtc_UWord32) * (size- oldVectorSize)); 202 memcpy(fragmentationLength, oldLengths, 203 sizeof(WebRtc_UWord32) * oldVectorSize); 204 delete[] oldLengths; 205 } 206 // time diff 207 { 208 WebRtc_UWord16* oldTimeDiffs = fragmentationTimeDiff; 209 fragmentationTimeDiff = new WebRtc_UWord16[size]; 210 memset(fragmentationTimeDiff+oldVectorSize, 0, 211 sizeof(WebRtc_UWord16) * (size- oldVectorSize)); 212 memcpy(fragmentationTimeDiff, oldTimeDiffs, 213 sizeof(WebRtc_UWord16) * oldVectorSize); 214 delete[] oldTimeDiffs; 215 } 216 // payload type 217 { 218 WebRtc_UWord8* oldTimePlTypes = fragmentationPlType; 219 fragmentationPlType = new WebRtc_UWord8[size]; 220 memset(fragmentationPlType+oldVectorSize, 0, 221 sizeof(WebRtc_UWord8) * (size- oldVectorSize)); 222 memcpy(fragmentationPlType, oldTimePlTypes, 223 sizeof(WebRtc_UWord8) * oldVectorSize); 224 delete[] oldTimePlTypes; 225 } 226 fragmentationVectorSize = size; 227 } 228 } 229 230 WebRtc_UWord16 fragmentationVectorSize; // Number of fragmentations 231 WebRtc_UWord32* fragmentationOffset; // Offset of pointer to data for each fragm. 232 WebRtc_UWord32* fragmentationLength; // Data size for each fragmentation 233 WebRtc_UWord16* fragmentationTimeDiff; // Timestamp difference relative "now" for 234 // each fragmentation 235 WebRtc_UWord8* fragmentationPlType; // Payload type of each fragmentation 236 }; 237 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: 267 EncodedVideoData() : 268 completeFrame(false), 269 missingFrame(false), 270 payloadData(NULL), 271 payloadSize(0), 272 bufferSize(0) 273 {}; 274 275 EncodedVideoData(const EncodedVideoData& data) 276 { 277 payloadType = data.payloadType; 278 timeStamp = data.timeStamp; 279 renderTimeMs = data.renderTimeMs; 280 encodedWidth = data.encodedWidth; 281 encodedHeight = data.encodedHeight; 282 completeFrame = data.completeFrame; 283 missingFrame = data.missingFrame; 284 payloadSize = data.payloadSize; 285 fragmentationHeader = data.fragmentationHeader; 286 frameType = data.frameType; 287 codec = data.codec; 288 if (data.payloadSize > 0) 289 { 290 payloadData = new WebRtc_UWord8[data.payloadSize]; 291 memcpy(payloadData, data.payloadData, data.payloadSize); 292 } 293 else 294 { 295 payloadData = NULL; 296 } 297 } 298 299 300 ~EncodedVideoData() 301 { 302 delete [] payloadData; 303 }; 304 305 EncodedVideoData& operator=(const EncodedVideoData& data) 306 { 307 if (this == &data) 308 { 309 return *this; 310 } 311 payloadType = data.payloadType; 312 timeStamp = data.timeStamp; 313 renderTimeMs = data.renderTimeMs; 314 encodedWidth = data.encodedWidth; 315 encodedHeight = data.encodedHeight; 316 completeFrame = data.completeFrame; 317 missingFrame = data.missingFrame; 318 payloadSize = data.payloadSize; 319 fragmentationHeader = data.fragmentationHeader; 320 frameType = data.frameType; 321 codec = data.codec; 322 if (data.payloadSize > 0) 323 { 324 delete [] payloadData; 325 payloadData = new WebRtc_UWord8[data.payloadSize]; 326 memcpy(payloadData, data.payloadData, data.payloadSize); 327 bufferSize = data.payloadSize; 328 } 329 return *this; 330 }; 331 void VerifyAndAllocate( const WebRtc_UWord32 size) 332 { 333 if (bufferSize < size) 334 { 335 WebRtc_UWord8* oldPayload = payloadData; 336 payloadData = new WebRtc_UWord8[size]; 337 memcpy(payloadData, oldPayload, sizeof(WebRtc_UWord8) * payloadSize); 338 339 bufferSize = size; 340 delete[] oldPayload; 341 } 342 } 343 344 WebRtc_UWord8 payloadType; 345 WebRtc_UWord32 timeStamp; 346 WebRtc_Word64 renderTimeMs; 347 WebRtc_UWord32 encodedWidth; 348 WebRtc_UWord32 encodedHeight; 349 bool completeFrame; 350 bool missingFrame; 351 WebRtc_UWord8* payloadData; 352 WebRtc_UWord32 payloadSize; 353 WebRtc_UWord32 bufferSize; 354 RTPFragmentationHeader fragmentationHeader; 355 FrameType frameType; 356 VideoCodecType codec; 357 }; 358 359 // Video Content Metrics 360 struct VideoContentMetrics 361 { 362 VideoContentMetrics(): motionMagnitudeNZ(0), sizeZeroMotion(0), spatialPredErr(0), 363 spatialPredErrH(0), spatialPredErrV(0), motionPredErr(0), 364 motionHorizontalness(0), motionClusterDistortion(0), 365 nativeWidth(0), nativeHeight(0), contentChange(false) { } 366 void Reset(){ motionMagnitudeNZ = 0; sizeZeroMotion = 0; spatialPredErr = 0; 367 spatialPredErrH = 0; spatialPredErrV = 0; motionPredErr = 0; 368 motionHorizontalness = 0; motionClusterDistortion = 0; 369 nativeWidth = 0; nativeHeight = 0; contentChange = false; } 370 371 float motionMagnitudeNZ; 372 float sizeZeroMotion; 373 float spatialPredErr; 374 float spatialPredErrH; 375 float spatialPredErrV; 376 float motionPredErr; 377 float motionHorizontalness; 378 float motionClusterDistortion; 379 WebRtc_UWord32 nativeWidth; 380 WebRtc_UWord32 nativeHeight; 381 WebRtc_UWord32 nativeFrameRate; 382 bool contentChange; 383 }; 384 385 /************************************************* 386 * 387 * VideoFrame class 388 * 389 * The VideoFrame class allows storing and 390 * handling of video frames. 391 * 392 * 393 *************************************************/ 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 */ 438 void SetTimeStamp(const WebRtc_UWord32 timeStamp) {_timeStamp = timeStamp;} 439 /** 440 * Get pointer to frame buffer 441 */ 442 WebRtc_UWord8* Buffer() const {return _buffer;} 443 444 WebRtc_UWord8*& Buffer() {return _buffer;} 445 446 /** 447 * Get allocated buffer size 448 */ 449 WebRtc_UWord32 Size() const {return _bufferSize;} 450 /** 451 * Get frame length 452 */ 453 WebRtc_UWord32 Length() const {return _bufferLength;} 454 /** 455 * Get frame timestamp (90kHz) 456 */ 457 WebRtc_UWord32 TimeStamp() const {return _timeStamp;} 458 /** 459 * Get frame width 460 */ 461 WebRtc_UWord32 Width() const {return _width;} 462 /** 463 * Get frame height 464 */ 465 WebRtc_UWord32 Height() const {return _height;} 466 /** 467 * Set frame width 468 */ 469 void SetWidth(const WebRtc_UWord32 width) {_width = width;} 470 /** 471 * Set frame height 472 */ 473 void SetHeight(const WebRtc_UWord32 height) {_height = height;} 474 /** 475 * Set render time in miliseconds 476 */ 477 void SetRenderTime(const WebRtc_Word64 renderTimeMs) {_renderTimeMs = renderTimeMs;} 478 /** 479 * Get render time in miliseconds 480 */ 481 WebRtc_Word64 RenderTimeMs() const {return _renderTimeMs;} 482 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 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 512 VideoFrame::~VideoFrame() 513 { 514 if(_buffer) 515 { 516 delete [] _buffer; 517 _buffer = NULL; 518 } 519 } 520 521 522 inline 523 WebRtc_Word32 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 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 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 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 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 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 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 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 748 AudioFrame::~AudioFrame() 749 { 750 } 751 752 inline 753 WebRtc_Word32 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 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& 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