| Index: media/formats/mp2t/timestamp_unroller.cc
|
| diff --git a/media/formats/mp2t/timestamp_unroller.cc b/media/formats/mp2t/timestamp_unroller.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7346a4c15badb2e19e735945128e02d8c3e97386
|
| --- /dev/null
|
| +++ b/media/formats/mp2t/timestamp_unroller.cc
|
| @@ -0,0 +1,82 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "media/formats/mp2t/timestamp_unroller.h"
|
| +
|
| +#include "base/logging.h"
|
| +
|
| +namespace media {
|
| +namespace mp2t {
|
| +
|
| +TimestampUnroller::TimestampUnroller()
|
| + : is_previous_timestamp_valid_(false),
|
| + previous_unrolled_timestamp_(0),
|
| + min_unrolled_timestamp_(0) {
|
| +}
|
| +
|
| +TimestampUnroller::~TimestampUnroller() {
|
| +}
|
| +
|
| +int64 TimestampUnroller::GetUnrolledTimestamp(int64 timestamp) {
|
| + // Mpeg2 TS timestamps have an accuracy of 33 bits.
|
| + const int nbits = 33;
|
| +
|
| + // |timestamp| has a precision of |nbits|
|
| + // so make sure the highest bits are set to 0.
|
| + DCHECK_EQ((timestamp >> nbits), 0);
|
| +
|
| + if (!is_previous_timestamp_valid_) {
|
| + previous_unrolled_timestamp_ = timestamp;
|
| + min_unrolled_timestamp_ = timestamp;
|
| + is_previous_timestamp_valid_ = true;
|
| + return timestamp;
|
| + }
|
| +
|
| + // Consider 3 possibilities to estimate the missing high bits of |time|.
|
| + int64 previous_unrolled_time_high =
|
| + (previous_unrolled_timestamp_ >> nbits);
|
| + int64 time0 = ((previous_unrolled_time_high - 1) << nbits) | timestamp;
|
| + int64 time1 = ((previous_unrolled_time_high + 0) << nbits) | timestamp;
|
| + int64 time2 = ((previous_unrolled_time_high + 1) << nbits) | timestamp;
|
| +
|
| + // Select the min absolute difference with the current time
|
| + // so as to ensure time continuity.
|
| + int64 diff0 = time0 - previous_unrolled_timestamp_;
|
| + int64 diff1 = time1 - previous_unrolled_timestamp_;
|
| + int64 diff2 = time2 - previous_unrolled_timestamp_;
|
| + if (diff0 < 0)
|
| + diff0 = -diff0;
|
| + if (diff1 < 0)
|
| + diff1 = -diff1;
|
| + if (diff2 < 0)
|
| + diff2 = -diff2;
|
| +
|
| + int64 unrolled_time;
|
| + int64 min_diff;
|
| + if (diff1 < diff0) {
|
| + unrolled_time = time1;
|
| + min_diff = diff1;
|
| + } else {
|
| + unrolled_time = time0;
|
| + min_diff = diff0;
|
| + }
|
| + if (diff2 < min_diff)
|
| + unrolled_time = time2;
|
| +
|
| + // Update the state of the timestamp unroller.
|
| + previous_unrolled_timestamp_ = unrolled_time;
|
| + if (unrolled_time < min_unrolled_timestamp_)
|
| + min_unrolled_timestamp_ = unrolled_time;
|
| +
|
| + return unrolled_time;
|
| +}
|
| +
|
| +void TimestampUnroller::Reset() {
|
| + is_previous_timestamp_valid_ = false;
|
| + previous_unrolled_timestamp_ = 0;
|
| + min_unrolled_timestamp_ = 0;
|
| +}
|
| +
|
| +} // namespace mp2t
|
| +} // namespace media
|
|
|