PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/CoreMedia/CMSync.cs

https://github.com/kjpou1/maccore
C# | 463 lines | 347 code | 101 blank | 15 comment | 52 complexity | 77dd2d736f4575aa8b9d998b41d9a3ee MD5 | raw file
Possible License(s): Apache-2.0
  1. //
  2. // CMSync.cs: Implements the managed CMSync infrastructure
  3. //
  4. // Authors: Marek Safar (marek.safar@gmail.com)
  5. //
  6. // Copyright 2012 Xamarin Inc
  7. //
  8. using System;
  9. using System.Runtime.InteropServices;
  10. using MonoMac;
  11. using MonoMac.Foundation;
  12. using MonoMac.CoreFoundation;
  13. using MonoMac.ObjCRuntime;
  14. namespace MonoMac.CoreMedia {
  15. public enum CMClockError
  16. {
  17. None = 0,
  18. MissingRequiredParameter = -12745,
  19. InvalidParameter = -12746,
  20. AllocationFailed = -12747,
  21. UnsupportedOperation = -12756,
  22. }
  23. [Since (6,0)]
  24. public class CMClock : CMClockOrTimebase
  25. {
  26. public CMClock (IntPtr handle) : base (handle)
  27. {
  28. }
  29. internal CMClock (IntPtr handle, bool owns)
  30. : base (handle, owns)
  31. {
  32. }
  33. [DllImport(Constants.CoreMediaLibrary)]
  34. extern static IntPtr CMClockGetHostTimeClock ();
  35. public static CMClock HostTimeClock {
  36. get {
  37. return new CMClock (CMClockGetHostTimeClock (), false);
  38. }
  39. }
  40. [DllImport(Constants.CoreMediaLibrary)]
  41. extern static CMTime CMClockGetTime (IntPtr clock);
  42. public CMTime CurrentTime {
  43. get {
  44. return CMClockGetTime (Handle);
  45. }
  46. }
  47. [DllImport(Constants.CoreMediaLibrary)]
  48. extern static CMClockError CMAudioClockCreate (IntPtr allocator, out IntPtr clockOut);
  49. public static CMClock CreateAudioClock (out CMClockError clockError)
  50. {
  51. IntPtr ptr;
  52. clockError = CMAudioClockCreate (IntPtr.Zero, out ptr);
  53. return clockError == CMClockError.None ? new CMClock (ptr) : null;
  54. }
  55. [DllImport(Constants.CoreMediaLibrary)]
  56. extern static CMClockError CMClockGetAnchorTime (IntPtr clock, out CMTime outClockTime, out CMTime outReferenceClockTime);
  57. public CMClockError GetAnchorTime (out CMTime clockTime, out CMTime referenceClockTime)
  58. {
  59. return CMClockGetAnchorTime (Handle, out clockTime, out referenceClockTime);
  60. }
  61. [DllImport(Constants.CoreMediaLibrary)]
  62. extern static bool CMClockMightDrift (IntPtr clock, IntPtr otherClock);
  63. public bool MightDrift (CMClock otherClock)
  64. {
  65. if (otherClock == null)
  66. throw new ArgumentNullException ("otherClock");
  67. return CMClockMightDrift (Handle, otherClock.Handle);
  68. }
  69. [DllImport(Constants.CoreMediaLibrary)]
  70. extern static void CMClockInvalidate (IntPtr clock);
  71. public void Invalidate ()
  72. {
  73. CMClockInvalidate (Handle);
  74. }
  75. [DllImport(Constants.CoreMediaLibrary, EntryPoint="CMClockConvertHostTimeToSystemUnits")]
  76. public extern static ulong ConvertHostTimeToSystemUnits (CMTime hostTime);
  77. [DllImport(Constants.CoreMediaLibrary, EntryPoint="CMClockMakeHostTimeFromSystemUnits")]
  78. public extern static CMTime CreateHostTimeFromSystemUnits (ulong hostTime);
  79. }
  80. public enum CMTimebaseError
  81. {
  82. None = 0,
  83. MissingRequiredParameter = -12748,
  84. InvalidParameter = -12749,
  85. AllocationFailed = -12750,
  86. TimerIntervalTooShort = -12751,
  87. ReadOnly = -12757,
  88. }
  89. [Since (6,0)]
  90. public class CMTimebase : CMClockOrTimebase
  91. {
  92. public CMTimebase (IntPtr handle)
  93. : base (handle)
  94. {
  95. }
  96. private CMTimebase (IntPtr handle, bool owns)
  97. : base (handle, owns)
  98. {
  99. }
  100. [DllImport(Constants.CoreMediaLibrary)]
  101. extern static CMTimebaseError CMTimebaseCreateWithMasterClock (IntPtr allocator, IntPtr masterClock, out IntPtr timebaseOut);
  102. public CMTimebase (CMClock masterClock)
  103. {
  104. if (masterClock == null)
  105. throw new ArgumentNullException ("masterClock");
  106. var error = CMTimebaseCreateWithMasterClock (IntPtr.Zero, masterClock.Handle, out handle);
  107. if (error != CMTimebaseError.None)
  108. throw new ArgumentException (error.ToString ());
  109. CFObject.CFRetain (Handle);
  110. }
  111. [DllImport(Constants.CoreMediaLibrary)]
  112. extern static CMTimebaseError CMTimebaseCreateWithMasterTimebase (IntPtr allocator, IntPtr masterTimebase, out IntPtr timebaseOut);
  113. public CMTimebase (CMTimebase masterTimebase)
  114. {
  115. if (masterTimebase == null)
  116. throw new ArgumentNullException ("masterTimebase");
  117. var error = CMTimebaseCreateWithMasterTimebase (IntPtr.Zero, masterTimebase.Handle, out handle);
  118. if (error != CMTimebaseError.None)
  119. throw new ArgumentException (error.ToString ());
  120. CFObject.CFRetain (Handle);
  121. }
  122. [DllImport(Constants.CoreMediaLibrary)]
  123. extern static double CMTimebaseGetEffectiveRate (IntPtr timebase);
  124. public double EffectiveRate {
  125. get {
  126. return CMTimebaseGetEffectiveRate (Handle);
  127. }
  128. }
  129. [DllImport(Constants.CoreMediaLibrary)]
  130. extern static double CMTimebaseGetRate (IntPtr timebase);
  131. [DllImport(Constants.CoreMediaLibrary)]
  132. extern static CMTimebaseError CMTimebaseSetRate (IntPtr timebase, double rate);
  133. public double Rate {
  134. get {
  135. return CMTimebaseGetRate (Handle);
  136. }
  137. set {
  138. var error = CMTimebaseSetRate (Handle, value);
  139. if (error != CMTimebaseError.None)
  140. throw new ArgumentException (error.ToString ());
  141. }
  142. }
  143. [DllImport(Constants.CoreMediaLibrary)]
  144. extern static CMTime CMTimebaseGetTime (IntPtr timebase);
  145. [DllImport(Constants.CoreMediaLibrary)]
  146. extern static CMTimebaseError CMTimebaseSetTime (IntPtr timebase, CMTime time);
  147. public new CMTime Time {
  148. get {
  149. return CMTimebaseGetTime (Handle);
  150. }
  151. set {
  152. var error = CMTimebaseSetTime (Handle, value);
  153. if (error != CMTimebaseError.None)
  154. throw new ArgumentException (error.ToString ());
  155. }
  156. }
  157. [DllImport(Constants.CoreMediaLibrary)]
  158. extern static IntPtr CMTimebaseGetMasterTimebase (IntPtr timebase);
  159. public CMTimebase GetMasterTimebase ()
  160. {
  161. var ptr = CMTimebaseGetMasterTimebase (Handle);
  162. if (ptr == IntPtr.Zero)
  163. return null;
  164. return new CMTimebase (ptr, false);
  165. }
  166. [DllImport(Constants.CoreMediaLibrary)]
  167. extern static IntPtr CMTimebaseGetMasterClock (IntPtr timebase);
  168. public CMClock GetMasterClock ()
  169. {
  170. var ptr = CMTimebaseGetMasterClock (Handle);
  171. if (ptr == IntPtr.Zero)
  172. return null;
  173. return new CMClock (ptr, false);
  174. }
  175. [DllImport(Constants.CoreMediaLibrary)]
  176. extern static IntPtr CMTimebaseGetMaster (IntPtr timebase);
  177. public CMClockOrTimebase GetMaster ()
  178. {
  179. var ptr = CMTimebaseGetMaster (Handle);
  180. if (ptr == IntPtr.Zero)
  181. return null;
  182. return new CMClockOrTimebase (ptr, false);
  183. }
  184. [DllImport(Constants.CoreMediaLibrary)]
  185. extern static IntPtr CMTimebaseGetUltimateMasterClock (IntPtr timebase);
  186. public CMClock GetUltimateMasterClock ()
  187. {
  188. var ptr = CMTimebaseGetUltimateMasterClock (Handle);
  189. if (ptr == IntPtr.Zero)
  190. return null;
  191. return new CMClock (ptr, false);
  192. }
  193. [DllImport(Constants.CoreMediaLibrary)]
  194. extern static CMTime CMTimebaseGetTimeWithTimeScale (IntPtr timebase, CMTimeScale timescale, CMTimeRoundingMethod method);
  195. public CMTime GetTime (CMTimeScale timeScale, CMTimeRoundingMethod roundingMethod)
  196. {
  197. return CMTimebaseGetTimeWithTimeScale (Handle, timeScale, roundingMethod);
  198. }
  199. [DllImport(Constants.CoreMediaLibrary)]
  200. extern static CMTimebaseError CMTimebaseSetAnchorTime (IntPtr timebase, CMTime timebaseTime, CMTime immediateMasterTime);
  201. public CMTimebaseError SetAnchorTime (CMTime timebaseTime, CMTime immediateMasterTime)
  202. {
  203. return CMTimebaseSetAnchorTime (Handle, timebaseTime, immediateMasterTime);
  204. }
  205. [DllImport(Constants.CoreMediaLibrary)]
  206. extern static CMTimebaseError CMTimebaseGetTimeAndRate (IntPtr timebase, out CMTime time, out double rate);
  207. public CMTimebaseError GetTimeAndRate (out CMTime time, out double rate)
  208. {
  209. return CMTimebaseGetTimeAndRate (Handle, out time, out rate);
  210. }
  211. [DllImport(Constants.CoreMediaLibrary)]
  212. extern static CMTimebaseError CMTimebaseSetRateAndAnchorTime (IntPtr timebase, double rate, CMTime timebaseTime, CMTime immediateMasterTime);
  213. public CMTimebaseError SetRateAndAnchorTime (double rate, CMTime timebaseTime, CMTime immediateMasterTime)
  214. {
  215. return CMTimebaseSetRateAndAnchorTime (Handle, rate, timebaseTime, immediateMasterTime);
  216. }
  217. [DllImport(Constants.CoreMediaLibrary)]
  218. extern static CMTimebaseError CMTimebaseNotificationBarrier (IntPtr timebase);
  219. public CMTimebaseError NotificationBarrier ()
  220. {
  221. return CMTimebaseNotificationBarrier (handle);
  222. }
  223. public const double VeryLongTimeInterval = 256.0 * 365.0 * 24.0 * 60.0 * 60.0;
  224. #if !COREBUILD
  225. [DllImport(Constants.CoreMediaLibrary)]
  226. extern static CMTimebaseError CMTimebaseAddTimer(IntPtr timebase, /*CFRunLoopTimerRef*/ IntPtr timer, /*CFRunLoopRef*/ IntPtr runloop);
  227. public CMTimebaseError AddTimer (NSTimer timer, NSRunLoop runloop)
  228. {
  229. if (timer == null)
  230. throw new ArgumentNullException ("timer");
  231. if (runloop == null)
  232. throw new ArgumentNullException ("runloop");
  233. // FIXME: Crashes inside CoreMedia
  234. return CMTimebaseAddTimer (Handle, timer.Handle, runloop.Handle);
  235. }
  236. [DllImport(Constants.CoreMediaLibrary)]
  237. extern static CMTimebaseError CMTimebaseRemoveTimer (IntPtr timebase, /*CFRunLoopTimerRef*/ IntPtr timer);
  238. public CMTimebaseError RemoveTimer (NSTimer timer)
  239. {
  240. if (timer == null)
  241. throw new ArgumentNullException ("timer");
  242. return CMTimebaseRemoveTimer (Handle, timer.Handle);
  243. }
  244. [DllImport(Constants.CoreMediaLibrary)]
  245. extern static CMTimebaseError CMTimebaseSetTimerNextFireTime (IntPtr timebase, /*CFRunLoopTimerRef*/ IntPtr timer, CMTime fireTime, uint flags);
  246. public CMTimebaseError SetTimerNextFireTime (NSTimer timer, CMTime fireTime)
  247. {
  248. if (timer == null)
  249. throw new ArgumentNullException ("timer");
  250. return CMTimebaseSetTimerNextFireTime (Handle, timer.Handle, fireTime, 0);
  251. }
  252. [DllImport(Constants.CoreMediaLibrary)]
  253. extern static CMTimebaseError CMTimebaseSetTimerToFireImmediately (IntPtr timebase, /*CFRunLoopTimerRef*/ IntPtr timer);
  254. public CMTimebaseError SetTimerToFireImmediately (NSTimer timer)
  255. {
  256. if (timer == null)
  257. throw new ArgumentNullException ("timer");
  258. return CMTimebaseSetTimerToFireImmediately (Handle, timer.Handle);
  259. }
  260. #endif
  261. //
  262. // Dispatch timers not supported
  263. //
  264. // CMTimebaseAddTimerDispatchSource
  265. // CMTimebaseRemoveTimerDispatchSource
  266. // CMTimebaseSetTimerDispatchSourceNextFireTime
  267. // CMTimebaseSetTimerDispatchSourceToFireImmediately
  268. }
  269. public enum CMSyncError {
  270. None = 0,
  271. MissingRequiredParameter = -12752,
  272. InvalidParameter = -12753,
  273. AllocationFailed = -12754,
  274. RateMustBeNonZero = -12755,
  275. }
  276. public class CMClockOrTimebase : IDisposable, INativeObject
  277. {
  278. internal IntPtr handle;
  279. internal CMClockOrTimebase ()
  280. {
  281. }
  282. public CMClockOrTimebase (IntPtr handle)
  283. {
  284. this.handle = handle;
  285. }
  286. internal CMClockOrTimebase (IntPtr handle, bool owns)
  287. {
  288. if (!owns)
  289. CFObject.CFRetain (Handle);
  290. this.handle = handle;
  291. }
  292. ~CMClockOrTimebase ()
  293. {
  294. Dispose (false);
  295. }
  296. public void Dispose ()
  297. {
  298. Dispose (true);
  299. GC.SuppressFinalize (this);
  300. }
  301. protected virtual void Dispose (bool disposing)
  302. {
  303. if (Handle != IntPtr.Zero){
  304. CFObject.CFRelease (Handle);
  305. handle = IntPtr.Zero;
  306. }
  307. }
  308. public IntPtr Handle {
  309. get {
  310. return handle;
  311. }
  312. }
  313. [DllImport(Constants.CoreMediaLibrary)]
  314. extern static CMTime CMSyncGetTime (IntPtr clockOrTimebase);
  315. public CMTime Time {
  316. get {
  317. return CMSyncGetTime (handle);
  318. }
  319. }
  320. [DllImport(Constants.CoreMediaLibrary)]
  321. extern static double CMSyncGetRelativeRate (IntPtr ofClockOrTimebase, IntPtr relativeToClockOrTimebase);
  322. public static double GetRelativeRate (CMClockOrTimebase clockOrTimebaseA, CMClockOrTimebase clockOrTimebaseB)
  323. {
  324. if (clockOrTimebaseA == null)
  325. throw new ArgumentNullException ("clockOrTimebaseA");
  326. if (clockOrTimebaseB == null)
  327. throw new ArgumentNullException ("clockOrTimebaseB");
  328. return CMSyncGetRelativeRate (clockOrTimebaseA.Handle, clockOrTimebaseB.Handle);
  329. }
  330. [DllImport(Constants.CoreMediaLibrary)]
  331. extern static CMSyncError CMSyncGetRelativeRateAndAnchorTime (IntPtr ofClockOrTimebase, IntPtr relativeToClockOrTimebase,
  332. out double outRelativeRate, out CMTime outOfClockOrTimebaseAnchorTime, out CMTime outRelativeToClockOrTimebaseAnchorTime);
  333. public static CMSyncError GetRelativeRateAndAnchorTime (CMClockOrTimebase clockOrTimebaseA, CMClockOrTimebase clockOrTimebaseB, out double relativeRate, out CMTime timeA, out CMTime timeB)
  334. {
  335. if (clockOrTimebaseA == null)
  336. throw new ArgumentNullException ("clockOrTimebaseA");
  337. if (clockOrTimebaseB == null)
  338. throw new ArgumentNullException ("clockOrTimebaseB");
  339. return CMSyncGetRelativeRateAndAnchorTime (clockOrTimebaseA.Handle, clockOrTimebaseB.handle, out relativeRate, out timeA, out timeB);
  340. }
  341. [DllImport(Constants.CoreMediaLibrary)]
  342. extern static CMTime CMSyncConvertTime (CMTime time, IntPtr fromClockOrTimebase, IntPtr toClockOrTimebase);
  343. public static CMTime ConvertTime (CMTime time, CMClockOrTimebase from, CMClockOrTimebase to)
  344. {
  345. if (from == null)
  346. throw new ArgumentNullException ("from");
  347. if (to == null)
  348. throw new ArgumentNullException ("to");
  349. return CMSyncConvertTime (time, from.Handle, to.Handle);
  350. }
  351. [DllImport(Constants.CoreMediaLibrary)]
  352. extern static bool CMSyncMightDrift (IntPtr clockOrTimebase1, IntPtr clockOrTimebase2);
  353. public static bool MightDrift (CMClockOrTimebase clockOrTimebaseA, CMClockOrTimebase clockOrTimebaseB)
  354. {
  355. if (clockOrTimebaseA == null)
  356. throw new ArgumentNullException ("clockOrTimebaseA");
  357. if (clockOrTimebaseB == null)
  358. throw new ArgumentNullException ("clockOrTimebaseB");
  359. return CMSyncMightDrift (clockOrTimebaseA.Handle, clockOrTimebaseB.Handle);
  360. }
  361. }
  362. }