1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef MODULE_COMMON_TYPES_H 12 #define MODULE_COMMON_TYPES_H 13 14 #include <assert.h> 15 #include <string.h> // memcpy 16 17 #include <algorithm> 18 19 #include "webrtc/base/constructormagic.h" 20 #include "webrtc/common_types.h" 21 #include "webrtc/typedefs.h" 22 23 #ifdef _WIN32 24 // Remove warning "new behavior: elements of array will be default initialized". 25 #pragma warning(disable : 4351) 26 #endif 27 28 namespace webrtc { 29 30 struct RTPAudioHeader { 31 uint8_t numEnergy; // number of valid entries in arrOfEnergy 32 uint8_t arrOfEnergy[kRtpCsrcSize]; // one energy byte (0-9) per channel 33 bool isCNG; // is this CNG 34 uint8_t channel; // number of channels 2 = stereo 35 }; 36 37 enum { 38 kNoPictureId = -1 39 }; 40 enum { 41 kNoTl0PicIdx = -1 42 }; 43 enum { 44 kNoTemporalIdx = -1 45 }; 46 enum { 47 kNoKeyIdx = -1 48 }; 49 enum { 50 kNoSimulcastIdx = 0 51 }; 52 53 struct RTPVideoHeaderVP8 { 54 void InitRTPVideoHeaderVP8() { 55 nonReference = false; 56 pictureId = kNoPictureId; 57 tl0PicIdx = kNoTl0PicIdx; 58 temporalIdx = kNoTemporalIdx; 59 layerSync = false; 60 keyIdx = kNoKeyIdx; 61 partitionId = 0; 62 beginningOfPartition = false; 63 } 64 65 bool nonReference; // Frame is discardable. 66 int16_t pictureId; // Picture ID index, 15 bits; 67 // kNoPictureId if PictureID does not exist. 68 int16_t tl0PicIdx; // TL0PIC_IDX, 8 bits; 69 // kNoTl0PicIdx means no value provided. 70 int8_t temporalIdx; // Temporal layer index, or kNoTemporalIdx. 71 bool layerSync; // This frame is a layer sync frame. 72 // Disabled if temporalIdx == kNoTemporalIdx. 73 int keyIdx; // 5 bits; kNoKeyIdx means not used. 74 int partitionId; // VP8 partition ID 75 bool beginningOfPartition; // True if this packet is the first 76 // in a VP8 partition. Otherwise false 77 }; 78 union RTPVideoTypeHeader { 79 RTPVideoHeaderVP8 VP8; 80 }; 81 82 enum RtpVideoCodecTypes { 83 kRtpVideoNone, 84 kRtpVideoGeneric, 85 kRtpVideoVp8 86 }; 87 struct RTPVideoHeader { 88 uint16_t width; // size 89 uint16_t height; 90 91 bool isFirstPacket; // first packet in frame 92 uint8_t simulcastIdx; // Index if the simulcast encoder creating 93 // this frame, 0 if not using simulcast. 94 RtpVideoCodecTypes codec; 95 RTPVideoTypeHeader codecHeader; 96 }; 97 union RTPTypeHeader { 98 RTPAudioHeader Audio; 99 RTPVideoHeader Video; 100 }; 101 102 struct WebRtcRTPHeader { 103 RTPHeader header; 104 FrameType frameType; 105 RTPTypeHeader type; 106 // NTP time of the capture time in local timebase in milliseconds. 107 int64_t ntp_time_ms; 108 }; 109 110 class RTPFragmentationHeader { 111 public: 112 RTPFragmentationHeader() 113 : fragmentationVectorSize(0), 114 fragmentationOffset(NULL), 115 fragmentationLength(NULL), 116 fragmentationTimeDiff(NULL), 117 fragmentationPlType(NULL) {}; 118 119 ~RTPFragmentationHeader() { 120 delete[] fragmentationOffset; 121 delete[] fragmentationLength; 122 delete[] fragmentationTimeDiff; 123 delete[] fragmentationPlType; 124 } 125 126 void CopyFrom(const RTPFragmentationHeader& src) { 127 if (this == &src) { 128 return; 129 } 130 131 if (src.fragmentationVectorSize != fragmentationVectorSize) { 132 // new size of vectors 133 134 // delete old 135 delete[] fragmentationOffset; 136 fragmentationOffset = NULL; 137 delete[] fragmentationLength; 138 fragmentationLength = NULL; 139 delete[] fragmentationTimeDiff; 140 fragmentationTimeDiff = NULL; 141 delete[] fragmentationPlType; 142 fragmentationPlType = NULL; 143 144 if (src.fragmentationVectorSize > 0) { 145 // allocate new 146 if (src.fragmentationOffset) { 147 fragmentationOffset = new uint32_t[src.fragmentationVectorSize]; 148 } 149 if (src.fragmentationLength) { 150 fragmentationLength = new uint32_t[src.fragmentationVectorSize]; 151 } 152 if (src.fragmentationTimeDiff) { 153 fragmentationTimeDiff = new uint16_t[src.fragmentationVectorSize]; 154 } 155 if (src.fragmentationPlType) { 156 fragmentationPlType = new uint8_t[src.fragmentationVectorSize]; 157 } 158 } 159 // set new size 160 fragmentationVectorSize = src.fragmentationVectorSize; 161 } 162 163 if (src.fragmentationVectorSize > 0) { 164 // copy values 165 if (src.fragmentationOffset) { 166 memcpy(fragmentationOffset, src.fragmentationOffset, 167 src.fragmentationVectorSize * sizeof(uint32_t)); 168 } 169 if (src.fragmentationLength) { 170 memcpy(fragmentationLength, src.fragmentationLength, 171 src.fragmentationVectorSize * sizeof(uint32_t)); 172 } 173 if (src.fragmentationTimeDiff) { 174 memcpy(fragmentationTimeDiff, src.fragmentationTimeDiff, 175 src.fragmentationVectorSize * sizeof(uint16_t)); 176 } 177 if (src.fragmentationPlType) { 178 memcpy(fragmentationPlType, src.fragmentationPlType, 179 src.fragmentationVectorSize * sizeof(uint8_t)); 180 } 181 } 182 } 183 184 void VerifyAndAllocateFragmentationHeader(const uint16_t size) { 185 if (fragmentationVectorSize < size) { 186 uint16_t oldVectorSize = fragmentationVectorSize; 187 { 188 // offset 189 uint32_t* oldOffsets = fragmentationOffset; 190 fragmentationOffset = new uint32_t[size]; 191 memset(fragmentationOffset + oldVectorSize, 0, 192 sizeof(uint32_t) * (size - oldVectorSize)); 193 // copy old values 194 memcpy(fragmentationOffset, oldOffsets, 195 sizeof(uint32_t) * oldVectorSize); 196 delete[] oldOffsets; 197 } 198 // length 199 { 200 uint32_t* oldLengths = fragmentationLength; 201 fragmentationLength = new uint32_t[size]; 202 memset(fragmentationLength + oldVectorSize, 0, 203 sizeof(uint32_t) * (size - oldVectorSize)); 204 memcpy(fragmentationLength, oldLengths, 205 sizeof(uint32_t) * oldVectorSize); 206 delete[] oldLengths; 207 } 208 // time diff 209 { 210 uint16_t* oldTimeDiffs = fragmentationTimeDiff; 211 fragmentationTimeDiff = new uint16_t[size]; 212 memset(fragmentationTimeDiff + oldVectorSize, 0, 213 sizeof(uint16_t) * (size - oldVectorSize)); 214 memcpy(fragmentationTimeDiff, oldTimeDiffs, 215 sizeof(uint16_t) * oldVectorSize); 216 delete[] oldTimeDiffs; 217 } 218 // payload type 219 { 220 uint8_t* oldTimePlTypes = fragmentationPlType; 221 fragmentationPlType = new uint8_t[size]; 222 memset(fragmentationPlType + oldVectorSize, 0, 223 sizeof(uint8_t) * (size - oldVectorSize)); 224 memcpy(fragmentationPlType, oldTimePlTypes, 225 sizeof(uint8_t) * oldVectorSize); 226 delete[] oldTimePlTypes; 227 } 228 fragmentationVectorSize = size; 229 } 230 } 231 232 uint16_t fragmentationVectorSize; // Number of fragmentations 233 uint32_t* fragmentationOffset; // Offset of pointer to data for each fragm. 234 uint32_t* fragmentationLength; // Data size for each fragmentation 235 uint16_t* fragmentationTimeDiff; // Timestamp difference relative "now" for 236 // each fragmentation 237 uint8_t* fragmentationPlType; // Payload type of each fragmentation 238 239 private: 240 DISALLOW_COPY_AND_ASSIGN(RTPFragmentationHeader); 241 }; 242 243 struct RTCPVoIPMetric { 244 // RFC 3611 4.7 245 uint8_t lossRate; 246 uint8_t discardRate; 247 uint8_t burstDensity; 248 uint8_t gapDensity; 249 uint16_t burstDuration; 250 uint16_t gapDuration; 251 uint16_t roundTripDelay; 252 uint16_t endSystemDelay; 253 uint8_t signalLevel; 254 uint8_t noiseLevel; 255 uint8_t RERL; 256 uint8_t Gmin; 257 uint8_t Rfactor; 258 uint8_t extRfactor; 259 uint8_t MOSLQ; 260 uint8_t MOSCQ; 261 uint8_t RXconfig; 262 uint16_t JBnominal; 263 uint16_t JBmax; 264 uint16_t JBabsMax; 265 }; 266 267 // Types for the FEC packet masks. The type |kFecMaskRandom| is based on a 268 // random loss model. The type |kFecMaskBursty| is based on a bursty/consecutive 269 // loss model. The packet masks are defined in 270 // modules/rtp_rtcp/fec_private_tables_random(bursty).h 271 enum FecMaskType { 272 kFecMaskRandom, 273 kFecMaskBursty, 274 }; 275 276 // Struct containing forward error correction settings. 277 struct FecProtectionParams { 278 int fec_rate; 279 bool use_uep_protection; 280 int max_fec_frames; 281 FecMaskType fec_mask_type; 282 }; 283 284 // Interface used by the CallStats class to distribute call statistics. 285 // Callbacks will be triggered as soon as the class has been registered to a 286 // CallStats object using RegisterStatsObserver. 287 class CallStatsObserver { 288 public: 289 virtual void OnRttUpdate(uint32_t rtt_ms) = 0; 290 291 virtual ~CallStatsObserver() {} 292 }; 293 294 // class describing a complete, or parts of an encoded frame. 295 class EncodedVideoData { 296 public: 297 EncodedVideoData() 298 : payloadType(0), 299 timeStamp(0), 300 renderTimeMs(0), 301 encodedWidth(0), 302 encodedHeight(0), 303 completeFrame(false), 304 missingFrame(false), 305 payloadData(NULL), 306 payloadSize(0), 307 bufferSize(0), 308 fragmentationHeader(), 309 frameType(kVideoFrameDelta), 310 codec(kVideoCodecUnknown) {}; 311 312 EncodedVideoData(const EncodedVideoData& data) { 313 payloadType = data.payloadType; 314 timeStamp = data.timeStamp; 315 renderTimeMs = data.renderTimeMs; 316 encodedWidth = data.encodedWidth; 317 encodedHeight = data.encodedHeight; 318 completeFrame = data.completeFrame; 319 missingFrame = data.missingFrame; 320 payloadSize = data.payloadSize; 321 fragmentationHeader.CopyFrom(data.fragmentationHeader); 322 frameType = data.frameType; 323 codec = data.codec; 324 if (data.payloadSize > 0) { 325 payloadData = new uint8_t[data.payloadSize]; 326 memcpy(payloadData, data.payloadData, data.payloadSize); 327 } else { 328 payloadData = NULL; 329 } 330 } 331 332 ~EncodedVideoData() { 333 delete[] payloadData; 334 }; 335 336 EncodedVideoData& operator=(const EncodedVideoData& data) { 337 if (this == &data) { 338 return *this; 339 } 340 payloadType = data.payloadType; 341 timeStamp = data.timeStamp; 342 renderTimeMs = data.renderTimeMs; 343 encodedWidth = data.encodedWidth; 344 encodedHeight = data.encodedHeight; 345 completeFrame = data.completeFrame; 346 missingFrame = data.missingFrame; 347 payloadSize = data.payloadSize; 348 fragmentationHeader.CopyFrom(data.fragmentationHeader); 349 frameType = data.frameType; 350 codec = data.codec; 351 if (data.payloadSize > 0) { 352 delete[] payloadData; 353 payloadData = new uint8_t[data.payloadSize]; 354 memcpy(payloadData, data.payloadData, data.payloadSize); 355 bufferSize = data.payloadSize; 356 } 357 return *this; 358 }; 359 void VerifyAndAllocate(const uint32_t size) { 360 if (bufferSize < size) { 361 uint8_t* oldPayload = payloadData; 362 payloadData = new uint8_t[size]; 363 memcpy(payloadData, oldPayload, sizeof(uint8_t) * payloadSize); 364 365 bufferSize = size; 366 delete[] oldPayload; 367 } 368 } 369 370 uint8_t payloadType; 371 uint32_t timeStamp; 372 int64_t renderTimeMs; 373 uint32_t encodedWidth; 374 uint32_t encodedHeight; 375 bool completeFrame; 376 bool missingFrame; 377 uint8_t* payloadData; 378 uint32_t payloadSize; 379 uint32_t bufferSize; 380 RTPFragmentationHeader fragmentationHeader; 381 FrameType frameType; 382 VideoCodecType codec; 383 }; 384 385 struct VideoContentMetrics { 386 VideoContentMetrics() 387 : motion_magnitude(0.0f), 388 spatial_pred_err(0.0f), 389 spatial_pred_err_h(0.0f), 390 spatial_pred_err_v(0.0f) {} 391 392 void Reset() { 393 motion_magnitude = 0.0f; 394 spatial_pred_err = 0.0f; 395 spatial_pred_err_h = 0.0f; 396 spatial_pred_err_v = 0.0f; 397 } 398 float motion_magnitude; 399 float spatial_pred_err; 400 float spatial_pred_err_h; 401 float spatial_pred_err_v; 402 }; 403 404 /************************************************* 405 * 406 * VideoFrame class 407 * 408 * The VideoFrame class allows storing and 409 * handling of video frames. 410 * 411 * 412 *************************************************/ 413 class VideoFrame { 414 public: 415 VideoFrame(); 416 ~VideoFrame(); 417 /** 418 * Verifies that current allocated buffer size is larger than or equal to the 419 * input size. 420 * If the current buffer size is smaller, a new allocation is made and the old 421 * buffer data 422 * is copied to the new buffer. 423 * Buffer size is updated to minimumSize. 424 */ 425 int32_t VerifyAndAllocate(const uint32_t minimumSize); 426 /** 427 * Update length of data buffer in frame. Function verifies that new length 428 * is less or 429 * equal to allocated size. 430 */ 431 int32_t SetLength(const uint32_t newLength); 432 /* 433 * Swap buffer and size data 434 */ 435 int32_t Swap(uint8_t*& newMemory, uint32_t& newLength, uint32_t& newSize); 436 /* 437 * Swap buffer and size data 438 */ 439 int32_t SwapFrame(VideoFrame& videoFrame); 440 /** 441 * Copy buffer: If newLength is bigger than allocated size, a new buffer of 442 * size length 443 * is allocated. 444 */ 445 int32_t CopyFrame(const VideoFrame& videoFrame); 446 /** 447 * Copy buffer: If newLength is bigger than allocated size, a new buffer of 448 * size length 449 * is allocated. 450 */ 451 int32_t CopyFrame(uint32_t length, const uint8_t* sourceBuffer); 452 /** 453 * Delete VideoFrame and resets members to zero 454 */ 455 void Free(); 456 /** 457 * Set frame timestamp (90kHz) 458 */ 459 void SetTimeStamp(const uint32_t timeStamp) { _timeStamp = timeStamp; } 460 /** 461 * Get pointer to frame buffer 462 */ 463 uint8_t* Buffer() const { return _buffer; } 464 465 uint8_t*& Buffer() { return _buffer; } 466 467 /** 468 * Get allocated buffer size 469 */ 470 uint32_t Size() const { return _bufferSize; } 471 /** 472 * Get frame length 473 */ 474 uint32_t Length() const { return _bufferLength; } 475 /** 476 * Get frame timestamp (90kHz) 477 */ 478 uint32_t TimeStamp() const { return _timeStamp; } 479 /** 480 * Get frame width 481 */ 482 uint32_t Width() const { return _width; } 483 /** 484 * Get frame height 485 */ 486 uint32_t Height() const { return _height; } 487 /** 488 * Set frame width 489 */ 490 void SetWidth(const uint32_t width) { _width = width; } 491 /** 492 * Set frame height 493 */ 494 void SetHeight(const uint32_t height) { _height = height; } 495 /** 496 * Set render time in miliseconds 497 */ 498 void SetRenderTime(const int64_t renderTimeMs) { 499 _renderTimeMs = renderTimeMs; 500 } 501 /** 502 * Get render time in miliseconds 503 */ 504 int64_t RenderTimeMs() const { return _renderTimeMs; } 505 506 private: 507 void Set(uint8_t* buffer, uint32_t size, uint32_t length, uint32_t timeStamp); 508 509 uint8_t* _buffer; // Pointer to frame buffer 510 uint32_t _bufferSize; // Allocated buffer size 511 uint32_t _bufferLength; // Length (in bytes) of buffer 512 uint32_t _timeStamp; // Timestamp of frame (90kHz) 513 uint32_t _width; 514 uint32_t _height; 515 int64_t _renderTimeMs; 516 }; // end of VideoFrame class declaration 517 518 // inline implementation of VideoFrame class: 519 inline VideoFrame::VideoFrame() 520 : _buffer(0), 521 _bufferSize(0), 522 _bufferLength(0), 523 _timeStamp(0), 524 _width(0), 525 _height(0), 526 _renderTimeMs(0) { 527 // 528 } 529 inline VideoFrame::~VideoFrame() { 530 if (_buffer) { 531 delete[] _buffer; 532 _buffer = NULL; 533 } 534 } 535 536 inline int32_t VideoFrame::VerifyAndAllocate(const uint32_t minimumSize) { 537 if (minimumSize < 1) { 538 return -1; 539 } 540 if (minimumSize > _bufferSize) { 541 // create buffer of sufficient size 542 uint8_t* newBufferBuffer = new uint8_t[minimumSize]; 543 if (_buffer) { 544 // copy old data 545 memcpy(newBufferBuffer, _buffer, _bufferSize); 546 delete[] _buffer; 547 } else { 548 memset(newBufferBuffer, 0, minimumSize * sizeof(uint8_t)); 549 } 550 _buffer = newBufferBuffer; 551 _bufferSize = minimumSize; 552 } 553 return 0; 554 } 555 556 inline int32_t VideoFrame::SetLength(const uint32_t newLength) { 557 if (newLength > _bufferSize) { // can't accomodate new value 558 return -1; 559 } 560 _bufferLength = newLength; 561 return 0; 562 } 563 564 inline int32_t VideoFrame::SwapFrame(VideoFrame& videoFrame) { 565 uint32_t tmpTimeStamp = _timeStamp; 566 uint32_t tmpWidth = _width; 567 uint32_t tmpHeight = _height; 568 int64_t tmpRenderTime = _renderTimeMs; 569 570 _timeStamp = videoFrame._timeStamp; 571 _width = videoFrame._width; 572 _height = videoFrame._height; 573 _renderTimeMs = videoFrame._renderTimeMs; 574 575 videoFrame._timeStamp = tmpTimeStamp; 576 videoFrame._width = tmpWidth; 577 videoFrame._height = tmpHeight; 578 videoFrame._renderTimeMs = tmpRenderTime; 579 580 return Swap(videoFrame._buffer, videoFrame._bufferLength, 581 videoFrame._bufferSize); 582 } 583 584 inline int32_t VideoFrame::Swap(uint8_t*& newMemory, uint32_t& newLength, 585 uint32_t& newSize) { 586 uint8_t* tmpBuffer = _buffer; 587 uint32_t tmpLength = _bufferLength; 588 uint32_t tmpSize = _bufferSize; 589 _buffer = newMemory; 590 _bufferLength = newLength; 591 _bufferSize = newSize; 592 newMemory = tmpBuffer; 593 newLength = tmpLength; 594 newSize = tmpSize; 595 return 0; 596 } 597 598 inline int32_t VideoFrame::CopyFrame(uint32_t length, 599 const uint8_t* sourceBuffer) { 600 if (length > _bufferSize) { 601 int32_t ret = VerifyAndAllocate(length); 602 if (ret < 0) { 603 return ret; 604 } 605 } 606 memcpy(_buffer, sourceBuffer, length); 607 _bufferLength = length; 608 return 0; 609 } 610 611 inline int32_t VideoFrame::CopyFrame(const VideoFrame& videoFrame) { 612 if (CopyFrame(videoFrame.Length(), videoFrame.Buffer()) != 0) { 613 return -1; 614 } 615 _timeStamp = videoFrame._timeStamp; 616 _width = videoFrame._width; 617 _height = videoFrame._height; 618 _renderTimeMs = videoFrame._renderTimeMs; 619 return 0; 620 } 621 622 inline void VideoFrame::Free() { 623 _timeStamp = 0; 624 _bufferLength = 0; 625 _bufferSize = 0; 626 _height = 0; 627 _width = 0; 628 _renderTimeMs = 0; 629 630 if (_buffer) { 631 delete[] _buffer; 632 _buffer = NULL; 633 } 634 } 635 636 /* This class holds up to 60 ms of super-wideband (32 kHz) stereo audio. It 637 * allows for adding and subtracting frames while keeping track of the resulting 638 * states. 639 * 640 * Notes 641 * - The total number of samples in |data_| is 642 * samples_per_channel_ * num_channels_ 643 * 644 * - Stereo data is interleaved starting with the left channel. 645 * 646 * - The +operator assume that you would never add exactly opposite frames when 647 * deciding the resulting state. To do this use the -operator. 648 */ 649 class AudioFrame { 650 public: 651 // Stereo, 32 kHz, 60 ms (2 * 32 * 60) 652 static const int kMaxDataSizeSamples = 3840; 653 654 enum VADActivity { 655 kVadActive = 0, 656 kVadPassive = 1, 657 kVadUnknown = 2 658 }; 659 enum SpeechType { 660 kNormalSpeech = 0, 661 kPLC = 1, 662 kCNG = 2, 663 kPLCCNG = 3, 664 kUndefined = 4 665 }; 666 667 AudioFrame(); 668 virtual ~AudioFrame() {} 669 670 // Resets all members to their default state (except does not modify the 671 // contents of |data_|). 672 void Reset(); 673 674 // |interleaved_| is not changed by this method. 675 void UpdateFrame(int id, uint32_t timestamp, const int16_t* data, 676 int samples_per_channel, int sample_rate_hz, 677 SpeechType speech_type, VADActivity vad_activity, 678 int num_channels = 1, uint32_t energy = -1); 679 680 AudioFrame& Append(const AudioFrame& rhs); 681 682 void CopyFrom(const AudioFrame& src); 683 684 void Mute(); 685 686 AudioFrame& operator>>=(const int rhs); 687 AudioFrame& operator+=(const AudioFrame& rhs); 688 AudioFrame& operator-=(const AudioFrame& rhs); 689 690 int id_; 691 // RTP timestamp of the first sample in the AudioFrame. 692 uint32_t timestamp_; 693 // Time since the first frame in milliseconds. 694 // -1 represents an uninitialized value. 695 int64_t elapsed_time_ms_; 696 // NTP time of the estimated capture time in local timebase in milliseconds. 697 // -1 represents an uninitialized value. 698 int64_t ntp_time_ms_; 699 int16_t data_[kMaxDataSizeSamples]; 700 int samples_per_channel_; 701 int sample_rate_hz_; 702 int num_channels_; 703 SpeechType speech_type_; 704 VADActivity vad_activity_; 705 // Note that there is no guarantee that |energy_| is correct. Any user of this 706 // member must verify that the value is correct. 707 // TODO(henrike) Remove |energy_|. 708 // See https://code.google.com/p/webrtc/issues/detail?id=3315. 709 uint32_t energy_; 710 bool interleaved_; 711 712 private: 713 DISALLOW_COPY_AND_ASSIGN(AudioFrame); 714 }; 715 716 inline AudioFrame::AudioFrame() 717 : data_() { 718 Reset(); 719 } 720 721 inline void AudioFrame::Reset() { 722 id_ = -1; 723 // TODO(wu): Zero is a valid value for |timestamp_|. We should initialize 724 // to an invalid value, or add a new member to indicate invalidity. 725 timestamp_ = 0; 726 elapsed_time_ms_ = -1; 727 ntp_time_ms_ = -1; 728 samples_per_channel_ = 0; 729 sample_rate_hz_ = 0; 730 num_channels_ = 0; 731 speech_type_ = kUndefined; 732 vad_activity_ = kVadUnknown; 733 energy_ = 0xffffffff; 734 interleaved_ = true; 735 } 736 737 inline void AudioFrame::UpdateFrame(int id, uint32_t timestamp, 738 const int16_t* data, 739 int samples_per_channel, int sample_rate_hz, 740 SpeechType speech_type, 741 VADActivity vad_activity, int num_channels, 742 uint32_t energy) { 743 id_ = id; 744 timestamp_ = timestamp; 745 samples_per_channel_ = samples_per_channel; 746 sample_rate_hz_ = sample_rate_hz; 747 speech_type_ = speech_type; 748 vad_activity_ = vad_activity; 749 num_channels_ = num_channels; 750 energy_ = energy; 751 752 const int length = samples_per_channel * num_channels; 753 assert(length <= kMaxDataSizeSamples && length >= 0); 754 if (data != NULL) { 755 memcpy(data_, data, sizeof(int16_t) * length); 756 } else { 757 memset(data_, 0, sizeof(int16_t) * length); 758 } 759 } 760 761 inline void AudioFrame::CopyFrom(const AudioFrame& src) { 762 if (this == &src) return; 763 764 id_ = src.id_; 765 timestamp_ = src.timestamp_; 766 elapsed_time_ms_ = src.elapsed_time_ms_; 767 ntp_time_ms_ = src.ntp_time_ms_; 768 samples_per_channel_ = src.samples_per_channel_; 769 sample_rate_hz_ = src.sample_rate_hz_; 770 speech_type_ = src.speech_type_; 771 vad_activity_ = src.vad_activity_; 772 num_channels_ = src.num_channels_; 773 energy_ = src.energy_; 774 interleaved_ = src.interleaved_; 775 776 const int length = samples_per_channel_ * num_channels_; 777 assert(length <= kMaxDataSizeSamples && length >= 0); 778 memcpy(data_, src.data_, sizeof(int16_t) * length); 779 } 780 781 inline void AudioFrame::Mute() { 782 memset(data_, 0, samples_per_channel_ * num_channels_ * sizeof(int16_t)); 783 } 784 785 inline AudioFrame& AudioFrame::operator>>=(const int rhs) { 786 assert((num_channels_ > 0) && (num_channels_ < 3)); 787 if ((num_channels_ > 2) || (num_channels_ < 1)) return *this; 788 789 for (int i = 0; i < samples_per_channel_ * num_channels_; i++) { 790 data_[i] = static_cast<int16_t>(data_[i] >> rhs); 791 } 792 return *this; 793 } 794 795 inline AudioFrame& AudioFrame::Append(const AudioFrame& rhs) { 796 // Sanity check 797 assert((num_channels_ > 0) && (num_channels_ < 3)); 798 assert(interleaved_ == rhs.interleaved_); 799 if ((num_channels_ > 2) || (num_channels_ < 1)) return *this; 800 if (num_channels_ != rhs.num_channels_) return *this; 801 802 if ((vad_activity_ == kVadActive) || rhs.vad_activity_ == kVadActive) { 803 vad_activity_ = kVadActive; 804 } else if (vad_activity_ == kVadUnknown || rhs.vad_activity_ == kVadUnknown) { 805 vad_activity_ = kVadUnknown; 806 } 807 if (speech_type_ != rhs.speech_type_) { 808 speech_type_ = kUndefined; 809 } 810 811 int offset = samples_per_channel_ * num_channels_; 812 for (int i = 0; i < rhs.samples_per_channel_ * rhs.num_channels_; i++) { 813 data_[offset + i] = rhs.data_[i]; 814 } 815 samples_per_channel_ += rhs.samples_per_channel_; 816 return *this; 817 } 818 819 inline AudioFrame& AudioFrame::operator+=(const AudioFrame& rhs) { 820 // Sanity check 821 assert((num_channels_ > 0) && (num_channels_ < 3)); 822 assert(interleaved_ == rhs.interleaved_); 823 if ((num_channels_ > 2) || (num_channels_ < 1)) return *this; 824 if (num_channels_ != rhs.num_channels_) return *this; 825 826 bool noPrevData = false; 827 if (samples_per_channel_ != rhs.samples_per_channel_) { 828 if (samples_per_channel_ == 0) { 829 // special case we have no data to start with 830 samples_per_channel_ = rhs.samples_per_channel_; 831 noPrevData = true; 832 } else { 833 return *this; 834 } 835 } 836 837 if ((vad_activity_ == kVadActive) || rhs.vad_activity_ == kVadActive) { 838 vad_activity_ = kVadActive; 839 } else if (vad_activity_ == kVadUnknown || rhs.vad_activity_ == kVadUnknown) { 840 vad_activity_ = kVadUnknown; 841 } 842 843 if (speech_type_ != rhs.speech_type_) speech_type_ = kUndefined; 844 845 if (noPrevData) { 846 memcpy(data_, rhs.data_, 847 sizeof(int16_t) * rhs.samples_per_channel_ * num_channels_); 848 } else { 849 // IMPROVEMENT this can be done very fast in assembly 850 for (int i = 0; i < samples_per_channel_ * num_channels_; i++) { 851 int32_t wrapGuard = 852 static_cast<int32_t>(data_[i]) + static_cast<int32_t>(rhs.data_[i]); 853 if (wrapGuard < -32768) { 854 data_[i] = -32768; 855 } else if (wrapGuard > 32767) { 856 data_[i] = 32767; 857 } else { 858 data_[i] = (int16_t)wrapGuard; 859 } 860 } 861 } 862 energy_ = 0xffffffff; 863 return *this; 864 } 865 866 inline AudioFrame& AudioFrame::operator-=(const AudioFrame& rhs) { 867 // Sanity check 868 assert((num_channels_ > 0) && (num_channels_ < 3)); 869 assert(interleaved_ == rhs.interleaved_); 870 if ((num_channels_ > 2) || (num_channels_ < 1)) return *this; 871 872 if ((samples_per_channel_ != rhs.samples_per_channel_) || 873 (num_channels_ != rhs.num_channels_)) { 874 return *this; 875 } 876 if ((vad_activity_ != kVadPassive) || rhs.vad_activity_ != kVadPassive) { 877 vad_activity_ = kVadUnknown; 878 } 879 speech_type_ = kUndefined; 880 881 for (int i = 0; i < samples_per_channel_ * num_channels_; i++) { 882 int32_t wrapGuard = 883 static_cast<int32_t>(data_[i]) - static_cast<int32_t>(rhs.data_[i]); 884 if (wrapGuard < -32768) { 885 data_[i] = -32768; 886 } else if (wrapGuard > 32767) { 887 data_[i] = 32767; 888 } else { 889 data_[i] = (int16_t)wrapGuard; 890 } 891 } 892 energy_ = 0xffffffff; 893 return *this; 894 } 895 896 inline bool IsNewerSequenceNumber(uint16_t sequence_number, 897 uint16_t prev_sequence_number) { 898 return sequence_number != prev_sequence_number && 899 static_cast<uint16_t>(sequence_number - prev_sequence_number) < 0x8000; 900 } 901 902 inline bool IsNewerTimestamp(uint32_t timestamp, uint32_t prev_timestamp) { 903 return timestamp != prev_timestamp && 904 static_cast<uint32_t>(timestamp - prev_timestamp) < 0x80000000; 905 } 906 907 inline uint16_t LatestSequenceNumber(uint16_t sequence_number1, 908 uint16_t sequence_number2) { 909 return IsNewerSequenceNumber(sequence_number1, sequence_number2) 910 ? sequence_number1 911 : sequence_number2; 912 } 913 914 inline uint32_t LatestTimestamp(uint32_t timestamp1, uint32_t timestamp2) { 915 return IsNewerTimestamp(timestamp1, timestamp2) ? timestamp1 : timestamp2; 916 } 917 918 } // namespace webrtc 919 920 #endif // MODULE_COMMON_TYPES_H 921