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)#ifndef MEDIA_BASE_AUDIO_TIMESTAMP_HELPER_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MEDIA_BASE_AUDIO_TIMESTAMP_HELPER_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/media_export.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace media {
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Generates timestamps for a sequence of audio sample frames. This class should
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// be used any place timestamps need to be calculated for a sequence of audio
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// samples. It helps avoid timestamps inaccuracies caused by rounding/truncation
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// in repeated sample count to timestamp conversions.
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// The class is constructed with samples_per_second information so that it can
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// convert audio sample frame counts into timestamps. After the object is
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// constructed, SetBaseTimestamp() must be called to specify the starting
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// timestamp of the audio sequence. As audio samples are received, their frame
227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// counts are added using AddFrames(). These frame counts are accumulated by
237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// this class so GetTimestamp() can be used to determine the timestamp for the
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// samples that have been added. GetDuration() calculates the proper duration
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// values for samples added to the current timestamp. GetFramesToTarget()
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// determines the number of frames that need to be added/removed from the
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// accumulated frames to reach a target timestamp.
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MEDIA_EXPORT AudioTimestampHelper {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  explicit AudioTimestampHelper(int samples_per_second);
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sets the base timestamp to |base_timestamp| and the sets count to 0.
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetBaseTimestamp(base::TimeDelta base_timestamp);
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta base_timestamp() const;
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int64 frame_count() const { return frame_count_; }
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Adds |frame_count| to the frame counter.
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note: SetBaseTimestamp() must be called with a value other than
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // kNoTimestamp() before this method can be called.
417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void AddFrames(int frame_count);
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Get the current timestamp. This value is computed from the base_timestamp()
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // and the number of sample frames that have been added so far.
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta GetTimestamp() const;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Gets the duration if |frame_count| frames were added to the current
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // timestamp reported by GetTimestamp(). This method ensures that
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // (GetTimestamp() + GetFrameDuration(n)) will equal the timestamp that
507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // GetTimestamp() will return if AddFrames(n) is called.
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::TimeDelta GetFrameDuration(int frame_count) const;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Returns the number of frames needed to reach the target timestamp.
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note: |target| must be >= |base_timestamp_|.
557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int64 GetFramesToTarget(base::TimeDelta target) const;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta ComputeTimestamp(int64 frame_count) const;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double microseconds_per_frame_;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta base_timestamp_;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Number of frames accumulated by AddFrames() calls.
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 frame_count_;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(AudioTimestampHelper);
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace media
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
73