12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/audio_timestamp_helper.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/buffers.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace media { 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochAudioTimestampHelper::AudioTimestampHelper(int samples_per_second) 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch : base_timestamp_(kNoTimestamp()), 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame_count_(0) { 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GT(samples_per_second, 0); 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) double fps = samples_per_second; 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) microseconds_per_frame_ = base::Time::kMicrosecondsPerSecond / fps; 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AudioTimestampHelper::SetBaseTimestamp(base::TimeDelta base_timestamp) { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base_timestamp_ = base_timestamp; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) frame_count_ = 0; 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::TimeDelta AudioTimestampHelper::base_timestamp() const { 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base_timestamp_; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AudioTimestampHelper::AddFrames(int frame_count) { 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_GE(frame_count, 0); 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(base_timestamp_ != kNoTimestamp()); 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch frame_count_ += frame_count; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::TimeDelta AudioTimestampHelper::GetTimestamp() const { 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ComputeTimestamp(frame_count_); 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbase::TimeDelta AudioTimestampHelper::GetFrameDuration(int frame_count) const { 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_GE(frame_count, 0); 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::TimeDelta end_timestamp = ComputeTimestamp(frame_count_ + frame_count); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return end_timestamp - GetTimestamp(); 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint64 AudioTimestampHelper::GetFramesToTarget(base::TimeDelta target) const { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(base_timestamp_ != kNoTimestamp()); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(target >= base_timestamp_); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 delta_in_us = (target - GetTimestamp()).InMicroseconds(); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (delta_in_us == 0) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Compute a timestamp relative to |base_timestamp_| since timestamps 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // created from |frame_count_| are computed relative to this base. 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This ensures that the time to frame computation here is the proper inverse 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of the frame to time computation in ComputeTimestamp(). 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta delta_from_base = target - base_timestamp_; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Compute frame count for the time delta. This computation rounds to 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the nearest whole number of frames. 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) double threshold = microseconds_per_frame_ / 2; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 target_frame_count = 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (delta_from_base.InMicroseconds() + threshold) / microseconds_per_frame_; 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return target_frame_count - frame_count_; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::TimeDelta AudioTimestampHelper::ComputeTimestamp( 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 frame_count) const { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(frame_count, 0); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(base_timestamp_ != kNoTimestamp()); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) double frames_us = microseconds_per_frame_ * frame_count; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base_timestamp_ + base::TimeDelta::FromMicroseconds(frames_us); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace media 76