1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "media/base/audio_timestamp_helper.h"
6
7#include "base/logging.h"
8#include "media/base/buffers.h"
9
10namespace media {
11
12AudioTimestampHelper::AudioTimestampHelper(int samples_per_second)
13    : base_timestamp_(kNoTimestamp()),
14      frame_count_(0) {
15  DCHECK_GT(samples_per_second, 0);
16  double fps = samples_per_second;
17  microseconds_per_frame_ = base::Time::kMicrosecondsPerSecond / fps;
18}
19
20void AudioTimestampHelper::SetBaseTimestamp(base::TimeDelta base_timestamp) {
21  base_timestamp_ = base_timestamp;
22  frame_count_ = 0;
23}
24
25base::TimeDelta AudioTimestampHelper::base_timestamp() const {
26  return base_timestamp_;
27}
28
29void AudioTimestampHelper::AddFrames(int frame_count) {
30  DCHECK_GE(frame_count, 0);
31  DCHECK(base_timestamp_ != kNoTimestamp());
32  frame_count_ += frame_count;
33}
34
35base::TimeDelta AudioTimestampHelper::GetTimestamp() const {
36  return ComputeTimestamp(frame_count_);
37}
38
39base::TimeDelta AudioTimestampHelper::GetFrameDuration(int frame_count) const {
40  DCHECK_GE(frame_count, 0);
41  base::TimeDelta end_timestamp = ComputeTimestamp(frame_count_ + frame_count);
42  return end_timestamp - GetTimestamp();
43}
44
45int64 AudioTimestampHelper::GetFramesToTarget(base::TimeDelta target) const {
46  DCHECK(base_timestamp_ != kNoTimestamp());
47  DCHECK(target >= base_timestamp_);
48
49  int64 delta_in_us = (target - GetTimestamp()).InMicroseconds();
50  if (delta_in_us == 0)
51    return 0;
52
53  // Compute a timestamp relative to |base_timestamp_| since timestamps
54  // created from |frame_count_| are computed relative to this base.
55  // This ensures that the time to frame computation here is the proper inverse
56  // of the frame to time computation in ComputeTimestamp().
57  base::TimeDelta delta_from_base = target - base_timestamp_;
58
59  // Compute frame count for the time delta. This computation rounds to
60  // the nearest whole number of frames.
61  double threshold = microseconds_per_frame_ / 2;
62  int64 target_frame_count =
63      (delta_from_base.InMicroseconds() + threshold) / microseconds_per_frame_;
64  return target_frame_count - frame_count_;
65}
66
67base::TimeDelta AudioTimestampHelper::ComputeTimestamp(
68    int64 frame_count) const {
69  DCHECK_GE(frame_count, 0);
70  DCHECK(base_timestamp_ != kNoTimestamp());
71  double frames_us = microseconds_per_frame_ * frame_count;
72  return base_timestamp_ + base::TimeDelta::FromMicroseconds(frames_us);
73}
74
75}  // namespace media
76