1/* 2 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#import "config.h" 27 28#if USE(COREMEDIA) 29 30#import "PlatformClockCM.h" 31 32#import "MediaTimeMac.h" 33#import "SoftLinking.h" 34#if PLATFORM(IOS) 35#import <CoreMedia/CMAudioClock.h> 36#else 37#import <CoreMedia/CMAudioDeviceClock.h> 38#endif 39 40SOFT_LINK_FRAMEWORK_OPTIONAL(CoreMedia) 41 42#if PLATFORM(IOS) 43SOFT_LINK(CoreMedia, CMAudioClockCreate, OSStatus, (CFAllocatorRef allocator, CMClockRef *clockOut), (allocator, clockOut)) 44#else 45SOFT_LINK(CoreMedia, CMAudioDeviceClockCreate, OSStatus, (CFAllocatorRef allocator, CFStringRef deviceUID, CMClockRef *clockOut), (allocator, deviceUID, clockOut)) 46#endif 47SOFT_LINK(CoreMedia, CMTimebaseCreateWithMasterClock, OSStatus, (CFAllocatorRef allocator, CMClockRef masterClock, CMTimebaseRef *timebaseOut), (allocator, masterClock, timebaseOut)) 48SOFT_LINK(CoreMedia, CMTimebaseSetTime, OSStatus, (CMTimebaseRef timebase, CMTime time), (timebase, time)) 49SOFT_LINK(CoreMedia, CMTimebaseGetTime, CMTime, (CMTimebaseRef timebase), (timebase)) 50SOFT_LINK(CoreMedia, CMTimebaseSetRate, OSStatus, (CMTimebaseRef timebase, Float64 rate), (timebase, rate)) 51SOFT_LINK(CoreMedia, CMTimeMakeWithSeconds, CMTime, (Float64 seconds, int32_t preferredTimeScale), (seconds, preferredTimeScale)) 52SOFT_LINK(CoreMedia, CMTimeGetSeconds, Float64, (CMTime time), (time)) 53 54using namespace WebCore; 55 56// A default time scale of 1000 allows milli-second CMTime precision without scaling the timebase. 57static const int32_t DefaultTimeScale = 1000; 58 59PlatformClockCM::PlatformClockCM() 60 : m_timebase(0) 61 , m_rate(1) 62 , m_running(false) 63{ 64 CMClockRef rawClockPtr = 0; 65#if PLATFORM(IOS) 66 CMAudioClockCreate(kCFAllocatorDefault, &rawClockPtr); 67#else 68 CMAudioDeviceClockCreate(kCFAllocatorDefault, NULL, &rawClockPtr); 69#endif 70 RetainPtr<CMClockRef> clock = adoptCF(rawClockPtr); 71 initializeWithTimingSource(clock.get()); 72} 73 74PlatformClockCM::PlatformClockCM(CMClockRef clock) 75 : m_timebase(0) 76 , m_running(false) 77{ 78 initializeWithTimingSource(clock); 79} 80 81void PlatformClockCM::initializeWithTimingSource(CMClockRef clock) 82{ 83 CMTimebaseRef rawTimebasePtr = 0; 84 CMTimebaseCreateWithMasterClock(kCFAllocatorDefault, clock, &rawTimebasePtr); 85 m_timebase = adoptCF(rawTimebasePtr); 86} 87 88void PlatformClockCM::setCurrentTime(double time) 89{ 90 CMTime cmTime = CMTimeMakeWithSeconds(time, DefaultTimeScale); 91 CMTimebaseSetTime(m_timebase.get(), cmTime); 92} 93 94double PlatformClockCM::currentTime() const 95{ 96 CMTime cmTime = CMTimebaseGetTime(m_timebase.get()); 97 return CMTimeGetSeconds(cmTime); 98} 99 100void PlatformClockCM::setCurrentMediaTime(const MediaTime& time) 101{ 102 CMTimebaseSetTime(m_timebase.get(), toCMTime(time)); 103} 104 105MediaTime PlatformClockCM::currentMediaTime() const 106{ 107 return toMediaTime(CMTimebaseGetTime(m_timebase.get())); 108} 109 110void PlatformClockCM::setPlayRate(double rate) 111{ 112 if (m_rate == rate) 113 return; 114 115 m_rate = rate; 116 if (m_running) 117 CMTimebaseSetRate(m_timebase.get(), rate); 118} 119 120void PlatformClockCM::start() 121{ 122 if (m_running) 123 return; 124 m_running = true; 125 CMTimebaseSetRate(m_timebase.get(), m_rate); 126} 127 128void PlatformClockCM::stop() 129{ 130 if (!m_running) 131 return; 132 m_running = false; 133 CMTimebaseSetRate(m_timebase.get(), 0); 134} 135 136#endif 137