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