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