OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #ifndef WEBRTC_MODULES_INCLUDE_MODULE_COMMON_TYPES_H_ | 11 #ifndef WEBRTC_MODULES_INCLUDE_MODULE_COMMON_TYPES_H_ |
12 #define WEBRTC_MODULES_INCLUDE_MODULE_COMMON_TYPES_H_ | 12 #define WEBRTC_MODULES_INCLUDE_MODULE_COMMON_TYPES_H_ |
13 | 13 |
14 #include <assert.h> | 14 #include <assert.h> |
15 #include <string.h> // memcpy | 15 #include <string.h> // memcpy |
16 | 16 |
17 #include <algorithm> | 17 #include <algorithm> |
18 #include <limits> | 18 #include <limits> |
19 | 19 |
20 #include "webrtc/api/video/video_rotation.h" | 20 #include "webrtc/api/video/video_rotation.h" |
21 #include "webrtc/base/constructormagic.h" | 21 #include "webrtc/base/constructormagic.h" |
22 #include "webrtc/base/deprecation.h" | 22 #include "webrtc/base/deprecation.h" |
| 23 #include "webrtc/base/optional.h" |
23 #include "webrtc/base/safe_conversions.h" | 24 #include "webrtc/base/safe_conversions.h" |
24 #include "webrtc/common_types.h" | 25 #include "webrtc/common_types.h" |
| 26 #include "webrtc/modules/video_coding/codecs/h264/include/h264_globals.h" |
25 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_globals.h" | 27 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_globals.h" |
26 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9_globals.h" | 28 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9_globals.h" |
27 #include "webrtc/modules/video_coding/codecs/h264/include/h264_globals.h" | |
28 #include "webrtc/typedefs.h" | 29 #include "webrtc/typedefs.h" |
29 | 30 |
30 namespace webrtc { | 31 namespace webrtc { |
31 | 32 |
32 struct RTPAudioHeader { | 33 struct RTPAudioHeader { |
33 uint8_t numEnergy; // number of valid entries in arrOfEnergy | 34 uint8_t numEnergy; // number of valid entries in arrOfEnergy |
34 uint8_t arrOfEnergy[kRtpCsrcSize]; // one energy byte (0-9) per channel | 35 uint8_t arrOfEnergy[kRtpCsrcSize]; // one energy byte (0-9) per channel |
35 bool isCNG; // is this CNG | 36 bool isCNG; // is this CNG |
36 size_t channel; // number of channels 2 = stereo | 37 size_t channel; // number of channels 2 = stereo |
37 }; | 38 }; |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 // IMPROVEMENT this can be done very fast in assembly | 468 // IMPROVEMENT this can be done very fast in assembly |
468 for (size_t i = 0; i < samples_per_channel_ * num_channels_; i++) { | 469 for (size_t i = 0; i < samples_per_channel_ * num_channels_; i++) { |
469 int32_t wrap_guard = | 470 int32_t wrap_guard = |
470 static_cast<int32_t>(data_[i]) + static_cast<int32_t>(rhs.data_[i]); | 471 static_cast<int32_t>(data_[i]) + static_cast<int32_t>(rhs.data_[i]); |
471 data_[i] = rtc::saturated_cast<int16_t>(wrap_guard); | 472 data_[i] = rtc::saturated_cast<int16_t>(wrap_guard); |
472 } | 473 } |
473 } | 474 } |
474 return *this; | 475 return *this; |
475 } | 476 } |
476 | 477 |
| 478 template <typename U> |
| 479 inline bool IsNewer(U value, U prev_value) { |
| 480 static_assert(!std::numeric_limits<U>::is_signed, "U must be unsigned"); |
| 481 // kBreakpoint is the half-way mark for the type U. For instance, for a |
| 482 // uint16_t it will be 0x8000, and for a uint32_t, it will be 0x8000000. |
| 483 constexpr U kBreakpoint = (std::numeric_limits<U>::max() >> 1) + 1; |
| 484 // Distinguish between elements that are exactly kBreakpoint apart. |
| 485 // If t1>t2 and |t1-t2| = kBreakpoint: IsNewer(t1,t2)=true, |
| 486 // IsNewer(t2,t1)=false |
| 487 // rather than having IsNewer(t1,t2) = IsNewer(t2,t1) = false. |
| 488 if (value - prev_value == kBreakpoint) { |
| 489 return value > prev_value; |
| 490 } |
| 491 return value != prev_value && |
| 492 static_cast<U>(value - prev_value) < kBreakpoint; |
| 493 } |
| 494 |
477 inline bool IsNewerSequenceNumber(uint16_t sequence_number, | 495 inline bool IsNewerSequenceNumber(uint16_t sequence_number, |
478 uint16_t prev_sequence_number) { | 496 uint16_t prev_sequence_number) { |
479 // Distinguish between elements that are exactly 0x8000 apart. | 497 return IsNewer(sequence_number, prev_sequence_number); |
480 // If s1>s2 and |s1-s2| = 0x8000: IsNewer(s1,s2)=true, IsNewer(s2,s1)=false | |
481 // rather than having IsNewer(s1,s2) = IsNewer(s2,s1) = false. | |
482 if (static_cast<uint16_t>(sequence_number - prev_sequence_number) == 0x8000) { | |
483 return sequence_number > prev_sequence_number; | |
484 } | |
485 return sequence_number != prev_sequence_number && | |
486 static_cast<uint16_t>(sequence_number - prev_sequence_number) < 0x8000; | |
487 } | 498 } |
488 | 499 |
489 inline bool IsNewerTimestamp(uint32_t timestamp, uint32_t prev_timestamp) { | 500 inline bool IsNewerTimestamp(uint32_t timestamp, uint32_t prev_timestamp) { |
490 // Distinguish between elements that are exactly 0x80000000 apart. | 501 return IsNewer(timestamp, prev_timestamp); |
491 // If t1>t2 and |t1-t2| = 0x80000000: IsNewer(t1,t2)=true, | |
492 // IsNewer(t2,t1)=false | |
493 // rather than having IsNewer(t1,t2) = IsNewer(t2,t1) = false. | |
494 if (static_cast<uint32_t>(timestamp - prev_timestamp) == 0x80000000) { | |
495 return timestamp > prev_timestamp; | |
496 } | |
497 return timestamp != prev_timestamp && | |
498 static_cast<uint32_t>(timestamp - prev_timestamp) < 0x80000000; | |
499 } | 502 } |
500 | 503 |
501 inline uint16_t LatestSequenceNumber(uint16_t sequence_number1, | 504 inline uint16_t LatestSequenceNumber(uint16_t sequence_number1, |
502 uint16_t sequence_number2) { | 505 uint16_t sequence_number2) { |
503 return IsNewerSequenceNumber(sequence_number1, sequence_number2) | 506 return IsNewerSequenceNumber(sequence_number1, sequence_number2) |
504 ? sequence_number1 | 507 ? sequence_number1 |
505 : sequence_number2; | 508 : sequence_number2; |
506 } | 509 } |
507 | 510 |
508 inline uint32_t LatestTimestamp(uint32_t timestamp1, uint32_t timestamp2) { | 511 inline uint32_t LatestTimestamp(uint32_t timestamp1, uint32_t timestamp2) { |
509 return IsNewerTimestamp(timestamp1, timestamp2) ? timestamp1 : timestamp2; | 512 return IsNewerTimestamp(timestamp1, timestamp2) ? timestamp1 : timestamp2; |
510 } | 513 } |
511 | 514 |
512 // Utility class to unwrap a sequence number to a larger type, for easier | 515 // Utility class to unwrap a number to a larger type. The numbers will never be |
513 // handling large ranges. Note that sequence numbers will never be unwrapped | 516 // unwrapped to a negative value. |
514 // to a negative value. | 517 template <typename U> |
515 class SequenceNumberUnwrapper { | 518 class Unwrapper { |
| 519 static_assert(!std::numeric_limits<U>::is_signed, "U must be unsigned"); |
| 520 static_assert(std::numeric_limits<U>::max() <= |
| 521 std::numeric_limits<uint32_t>::max(), |
| 522 "U must not be wider than 32 bits"); |
| 523 |
516 public: | 524 public: |
517 SequenceNumberUnwrapper() : last_seq_(-1) {} | 525 // Get the unwrapped value, but don't update the internal state. |
| 526 int64_t UnwrapWithoutUpdate(U value) { |
| 527 if (!last_value_) |
| 528 return value; |
518 | 529 |
519 // Get the unwrapped sequence, but don't update the internal state. | 530 constexpr int64_t kMaxPlusOne = |
520 int64_t UnwrapWithoutUpdate(uint16_t sequence_number) { | 531 static_cast<int64_t>(std::numeric_limits<U>::max()) + 1; |
521 if (last_seq_ == -1) | |
522 return sequence_number; | |
523 | 532 |
524 uint16_t cropped_last = static_cast<uint16_t>(last_seq_); | 533 U cropped_last = static_cast<U>(*last_value_); |
525 int64_t delta = sequence_number - cropped_last; | 534 int64_t delta = value - cropped_last; |
526 if (IsNewerSequenceNumber(sequence_number, cropped_last)) { | 535 if (IsNewer(value, cropped_last)) { |
527 if (delta < 0) | 536 if (delta < 0) |
528 delta += (1 << 16); // Wrap forwards. | 537 delta += kMaxPlusOne; // Wrap forwards. |
529 } else if (delta > 0 && (last_seq_ + delta - (1 << 16)) >= 0) { | 538 } else if (delta > 0 && (*last_value_ + delta - kMaxPlusOne) >= 0) { |
530 // If sequence_number is older but delta is positive, this is a backwards | 539 // If value is older but delta is positive, this is a backwards |
531 // wrap-around. However, don't wrap backwards past 0 (unwrapped). | 540 // wrap-around. However, don't wrap backwards past 0 (unwrapped). |
532 delta -= (1 << 16); | 541 delta -= kMaxPlusOne; |
533 } | 542 } |
534 | 543 |
535 return last_seq_ + delta; | 544 return *last_value_ + delta; |
536 } | 545 } |
537 | 546 |
538 // Only update the internal state to the specified last (unwrapped) sequence. | 547 // Only update the internal state to the specified last (unwrapped) value. |
539 void UpdateLast(int64_t last_sequence) { last_seq_ = last_sequence; } | 548 void UpdateLast(int64_t last_value) { |
| 549 last_value_ = rtc::Optional<int64_t>(last_value); |
| 550 } |
540 | 551 |
541 // Unwrap the sequence number and update the internal state. | 552 // Unwrap the value and update the internal state. |
542 int64_t Unwrap(uint16_t sequence_number) { | 553 int64_t Unwrap(U value) { |
543 int64_t unwrapped = UnwrapWithoutUpdate(sequence_number); | 554 int64_t unwrapped = UnwrapWithoutUpdate(value); |
544 UpdateLast(unwrapped); | 555 UpdateLast(unwrapped); |
545 return unwrapped; | 556 return unwrapped; |
546 } | 557 } |
547 | 558 |
548 private: | 559 private: |
549 int64_t last_seq_; | 560 rtc::Optional<int64_t> last_value_; |
550 }; | 561 }; |
551 | 562 |
| 563 using SequenceNumberUnwrapper = Unwrapper<uint16_t>; |
| 564 using TimestampUnwrapper = Unwrapper<uint32_t>; |
| 565 |
552 struct PacedPacketInfo { | 566 struct PacedPacketInfo { |
553 PacedPacketInfo() {} | 567 PacedPacketInfo() {} |
554 PacedPacketInfo(int probe_cluster_id, | 568 PacedPacketInfo(int probe_cluster_id, |
555 int probe_cluster_min_probes, | 569 int probe_cluster_min_probes, |
556 int probe_cluster_min_bytes) | 570 int probe_cluster_min_bytes) |
557 : probe_cluster_id(probe_cluster_id), | 571 : probe_cluster_id(probe_cluster_id), |
558 probe_cluster_min_probes(probe_cluster_min_probes), | 572 probe_cluster_min_probes(probe_cluster_min_probes), |
559 probe_cluster_min_bytes(probe_cluster_min_bytes) {} | 573 probe_cluster_min_bytes(probe_cluster_min_bytes) {} |
560 | 574 |
561 bool operator==(const PacedPacketInfo& rhs) const { | 575 bool operator==(const PacedPacketInfo& rhs) const { |
562 return send_bitrate_bps == rhs.send_bitrate_bps && | 576 return send_bitrate_bps == rhs.send_bitrate_bps && |
563 probe_cluster_id == rhs.probe_cluster_id && | 577 probe_cluster_id == rhs.probe_cluster_id && |
564 probe_cluster_min_probes == rhs.probe_cluster_min_probes && | 578 probe_cluster_min_probes == rhs.probe_cluster_min_probes && |
565 probe_cluster_min_bytes == rhs.probe_cluster_min_bytes; | 579 probe_cluster_min_bytes == rhs.probe_cluster_min_bytes; |
566 } | 580 } |
567 | 581 |
568 static constexpr int kNotAProbe = -1; | 582 static constexpr int kNotAProbe = -1; |
569 int send_bitrate_bps = -1; | 583 int send_bitrate_bps = -1; |
570 int probe_cluster_id = kNotAProbe; | 584 int probe_cluster_id = kNotAProbe; |
571 int probe_cluster_min_probes = -1; | 585 int probe_cluster_min_probes = -1; |
572 int probe_cluster_min_bytes = -1; | 586 int probe_cluster_min_bytes = -1; |
573 }; | 587 }; |
574 | 588 |
575 } // namespace webrtc | 589 } // namespace webrtc |
576 | 590 |
577 #endif // WEBRTC_MODULES_INCLUDE_MODULE_COMMON_TYPES_H_ | 591 #endif // WEBRTC_MODULES_INCLUDE_MODULE_COMMON_TYPES_H_ |
OLD | NEW |