CPF/CPF.Mac/Mac/CoreMedia/CMTime.cs
2023-11-21 23:05:03 +08:00

269 lines
7.6 KiB
C#

using CPF.Mac.Foundation;
using CPF.Mac.ObjCRuntime;
using System;
using System.Runtime.InteropServices;
namespace CPF.Mac.CoreMedia
{
public struct CMTime
{
[Flags]
public enum Flags
{
Valid = 0x1,
HasBeenRounded = 0x2,
PositiveInfinity = 0x4,
NegativeInfinity = 0x8,
Indefinite = 0x10,
ImpliedValueFlagsMask = 0x1C
}
public static CMTime Invalid;
private const Flags kIndefinite = Flags.Valid | Flags.Indefinite;
public static CMTime Indefinite;
private const Flags kPositive = Flags.Valid | Flags.PositiveInfinity;
public static CMTime PositiveInfinity;
private const Flags kNegative = Flags.Valid | Flags.NegativeInfinity;
public static CMTime NegativeInfinity;
public static CMTime Zero;
public const int MaxTimeScale = int.MaxValue;
public long Value;
public int TimeScale;
public Flags TimeFlags;
public long TimeEpoch;
public static readonly NSString ValueKey;
public static readonly NSString ScaleKey;
public static readonly NSString EpochKey;
public static readonly NSString FlagsKey;
public bool IsInvalid => (TimeFlags & Flags.Valid) == 0;
public bool IsIndefinite => (TimeFlags & (Flags.Valid | Flags.Indefinite)) == (Flags.Valid | Flags.Indefinite);
public bool IsPositiveInfinity => (TimeFlags & (Flags.Valid | Flags.PositiveInfinity)) == (Flags.Valid | Flags.PositiveInfinity);
public bool IsNegativeInfinity => (TimeFlags & (Flags.Valid | Flags.NegativeInfinity)) == (Flags.Valid | Flags.NegativeInfinity);
public CMTime AbsoluteValue => CMTimeAbsoluteValue(this);
public double Seconds => CMTimeGetSeconds(this);
public IntPtr AsDictionary => CMTimeCopyAsDictionary(this, IntPtr.Zero);
public string Description => NSString.FromHandle(CMTimeCopyDescription(IntPtr.Zero, this)).ToString();
private CMTime(Flags f)
{
Value = 0L;
TimeScale = 0;
TimeEpoch = 0L;
TimeFlags = f;
}
private CMTime(Flags f, int timescale)
{
Value = 0L;
TimeScale = timescale;
TimeEpoch = 0L;
TimeFlags = f;
}
public CMTime(long value, int timescale)
{
Value = value;
TimeScale = timescale;
TimeFlags = Flags.Valid;
TimeEpoch = 0L;
}
public CMTime(long value, int timescale, long epoch)
{
Value = value;
TimeScale = timescale;
TimeFlags = Flags.Valid;
TimeEpoch = epoch;
}
[DllImport("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia")]
private static extern CMTime CMTimeAbsoluteValue(CMTime time);
[DllImport("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia")]
private static extern int CMTimeCompare(CMTime time1, CMTime time2);
public static int Compare(CMTime time1, CMTime time2)
{
return CMTimeCompare(time1, time2);
}
public static bool operator ==(CMTime time1, CMTime time2)
{
return Compare(time1, time2) == 0;
}
public static bool operator !=(CMTime time1, CMTime time2)
{
return !(time1 == time2);
}
public override bool Equals(object obj)
{
if (!(obj is CMTime))
{
return false;
}
return (CMTime)obj == this;
}
public override int GetHashCode()
{
return Value.GetHashCode() ^ TimeScale.GetHashCode() ^ TimeFlags.GetHashCode() ^ TimeEpoch.GetHashCode();
}
[DllImport("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia")]
private static extern CMTime CMTimeAdd(CMTime addend1, CMTime addend2);
public static CMTime Add(CMTime time1, CMTime time2)
{
return CMTimeAdd(time1, time2);
}
[DllImport("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia")]
private static extern CMTime CMTimeSubtract(CMTime minuend, CMTime subtraend);
public static CMTime Subtract(CMTime minuend, CMTime subtraend)
{
return CMTimeSubtract(minuend, subtraend);
}
[DllImport("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia")]
private static extern CMTime CMTimeMultiply(CMTime time, int multiplier);
public static CMTime Multiply(CMTime time, int multiplier)
{
return CMTimeMultiply(time, multiplier);
}
[DllImport("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia")]
private static extern CMTime CMTimeMultiplyByFloat64(CMTime time, double multiplier);
public static CMTime Multiply(CMTime time, double multiplier)
{
return CMTimeMultiplyByFloat64(time, multiplier);
}
public static CMTime operator +(CMTime time1, CMTime time2)
{
return Add(time1, time2);
}
public static CMTime operator -(CMTime minuend, CMTime subtraend)
{
return Subtract(minuend, subtraend);
}
public static CMTime operator *(CMTime time, int multiplier)
{
return Multiply(time, multiplier);
}
public static CMTime operator *(CMTime time, double multiplier)
{
return Multiply(time, multiplier);
}
[DllImport("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia")]
private static extern CMTime CMTimeConvertScale(CMTime time, int newScale, CMTimeRoundingMethod method);
public CMTime ConvertScale(int newScale, CMTimeRoundingMethod method)
{
return CMTimeConvertScale(this, newScale, method);
}
[DllImport("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia")]
private static extern double CMTimeGetSeconds(CMTime time);
[DllImport("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia")]
private static extern CMTime CMTimeMakeWithSeconds(double seconds, int preferredTimeScale);
public static CMTime FromSeconds(double seconds, int preferredTimeScale)
{
return CMTimeMakeWithSeconds(seconds, preferredTimeScale);
}
[DllImport("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia")]
private static extern CMTime CMTimeMaximum(CMTime time1, CMTime time2);
public static CMTime GetMaximum(CMTime time1, CMTime time2)
{
return CMTimeMaximum(time1, time2);
}
[DllImport("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia")]
private static extern CMTime CMTimeMinimum(CMTime time1, CMTime time2);
public static CMTime GetMinimum(CMTime time1, CMTime time2)
{
return CMTimeMinimum(time1, time2);
}
static CMTime()
{
Invalid = new CMTime((Flags)0);
Indefinite = new CMTime(Flags.Valid | Flags.Indefinite);
PositiveInfinity = new CMTime(Flags.Valid | Flags.PositiveInfinity);
NegativeInfinity = new CMTime(Flags.Valid | Flags.NegativeInfinity);
Zero = new CMTime(Flags.Valid, 1);
IntPtr intPtr = Dlfcn.dlopen("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia", 0);
if (intPtr != IntPtr.Zero)
{
try
{
ValueKey = Dlfcn.GetStringConstant(intPtr, "kCMTimeValueKey");
ScaleKey = Dlfcn.GetStringConstant(intPtr, "kCMTimeScaleKey");
EpochKey = Dlfcn.GetStringConstant(intPtr, "kCMTimeEpochKey");
FlagsKey = Dlfcn.GetStringConstant(intPtr, "kCMTimeFlagsKey");
}
finally
{
Dlfcn.dlclose(intPtr);
}
}
}
[DllImport("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia")]
private static extern IntPtr CMTimeCopyAsDictionary(CMTime time, IntPtr allocator);
[DllImport("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia")]
private static extern IntPtr CMTimeCopyDescription(IntPtr allocator, CMTime time);
public override string ToString()
{
return Description;
}
[DllImport("/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia")]
private static extern CMTime CMTimeMakeFromDictionary(IntPtr dict);
public static CMTime FromDictionary(IntPtr dict)
{
return CMTimeMakeFromDictionary(dict);
}
}
}