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)#include "media/base/buffers.h"
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace media {
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kDefaultSampleRate = 44100;
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AudioTimestampHelperTest : public ::testing::Test {
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  AudioTimestampHelperTest() : helper_(kDefaultSampleRate) {
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    helper_.SetBaseTimestamp(base::TimeDelta());
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Adds frames to the helper and returns the current timestamp in
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // microseconds.
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int64 AddFrames(int frames) {
227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    helper_.AddFrames(frames);
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return helper_.GetTimestamp().InMicroseconds();
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int64 FramesToTarget(int target_in_microseconds) {
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return helper_.GetFramesToTarget(
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::TimeDelta::FromMicroseconds(target_in_microseconds));
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void TestGetFramesToTargetRange(int frame_count, int start, int end) {
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    for (int i = start; i <= end; ++i) {
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      EXPECT_EQ(frame_count, FramesToTarget(i)) << " Failure for timestamp "
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                << i << " us.";
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AudioTimestampHelper helper_;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AudioTimestampHelperTest);
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioTimestampHelperTest, Basic) {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, helper_.GetTimestamp().InMicroseconds());
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that the output timestamp is always rounded down to the
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // nearest microsecond. 1 frame @ 44100 is ~22.67573 microseconds,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // which is why the timestamp sometimes increments by 23 microseconds
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and other times it increments by 22 microseconds.
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(0, AddFrames(0));
527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(22, AddFrames(1));
537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(45, AddFrames(1));
547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(68, AddFrames(1));
557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(90, AddFrames(1));
567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_EQ(113, AddFrames(1));
577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Verify that adding frames one frame at a time matches the timestamp
597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // returned if the same number of frames are added all at once.
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta timestamp_1  = helper_.GetTimestamp();
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  helper_.SetBaseTimestamp(kNoTimestamp());
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(kNoTimestamp() == helper_.base_timestamp());
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  helper_.SetBaseTimestamp(base::TimeDelta());
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, helper_.GetTimestamp().InMicroseconds());
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  helper_.AddFrames(5);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(113, helper_.GetTimestamp().InMicroseconds());
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(timestamp_1 == helper_.GetTimestamp());
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioTimestampHelperTest, GetDuration) {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  helper_.SetBaseTimestamp(base::TimeDelta::FromMicroseconds(100));
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int frame_count = 5;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 expected_durations[] = { 113, 113, 114, 113, 113, 114 };
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(expected_durations); ++i) {
787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::TimeDelta duration = helper_.GetFrameDuration(frame_count);
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(expected_durations[i], duration.InMicroseconds());
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::TimeDelta timestamp_1 = helper_.GetTimestamp() + duration;
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    helper_.AddFrames(frame_count);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::TimeDelta timestamp_2 = helper_.GetTimestamp();
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(timestamp_1 == timestamp_2);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_F(AudioTimestampHelperTest, GetFramesToTarget) {
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Verify GetFramesToTarget() rounding behavior.
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 1 frame @ 44100 is ~22.67573 microseconds,
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test values less than half of the frame duration.
937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestGetFramesToTargetRange(0, 0, 11);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Test values between half the frame duration & the
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // full frame duration.
977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestGetFramesToTargetRange(1, 12, 22);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Verify that the same number of frames is returned up
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to the next half a frame.
1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestGetFramesToTargetRange(1, 23, 34);
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify the next 3 ranges.
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestGetFramesToTargetRange(2, 35, 56);
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestGetFramesToTargetRange(3, 57, 79);
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestGetFramesToTargetRange(4, 80, 102);
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestGetFramesToTargetRange(5, 103, 124);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Add frames to the helper so negative frame counts can be tested.
1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  helper_.AddFrames(5);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note: The timestamp ranges must match the positive values
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // tested above to verify that the code is rounding properly.
1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestGetFramesToTargetRange(0, 103, 124);
1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestGetFramesToTargetRange(-1, 80, 102);
1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestGetFramesToTargetRange(-2, 57, 79);
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestGetFramesToTargetRange(-3, 35, 56);
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestGetFramesToTargetRange(-4, 12, 34);
1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestGetFramesToTargetRange(-5, 0, 11);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace media
123