Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(363)

Side by Side Diff: webrtc/modules/include/module_common_types.h

Issue 2813593003: Add TimestampUnwrapper and generalize the code (Closed)
Patch Set: Remove ctor Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | webrtc/modules/module_common_types_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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_
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/module_common_types_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698