|
6 | 6 | #endif // !COREBUILD |
7 | 7 | using CoreGraphics; |
8 | 8 | using ObjCRuntime; |
| 9 | +using CoreMedia; |
9 | 10 |
|
10 | 11 | #nullable enable |
11 | 12 |
|
@@ -880,4 +881,174 @@ public static AVCaptionSize Create (AVCaptionDimension width, AVCaptionDimension |
880 | 881 | => AVCaptionSizeMake (width, height); |
881 | 882 | } |
882 | 883 | #endif // __TVOS__ |
| 884 | + |
| 885 | + /// <summary>Represents a timecode structure adhering to SMPTE standards for precise time information and synchronization.</summary> |
| 886 | + /// <remarks>This structure corresponds to the SMPTE 12M-1 Linear Timecode (LTC) format.</remarks> |
| 887 | + [SupportedOSPlatform ("ios26.0")] |
| 888 | + [SupportedOSPlatform ("maccatalyst26.0")] |
| 889 | + [SupportedOSPlatform ("macos26.0")] |
| 890 | + [SupportedOSPlatform ("tvos26.0")] |
| 891 | + [StructLayout (LayoutKind.Sequential)] |
| 892 | + public struct AVCaptureTimecode |
| 893 | +#if !COREBUILD |
| 894 | + : IEquatable<AVCaptureTimecode> |
| 895 | +#endif |
| 896 | + { |
| 897 | + /* uint8_t */ |
| 898 | + byte hours; |
| 899 | + /* uint8_t */ |
| 900 | + byte minutes; |
| 901 | + /* uint8_t */ |
| 902 | + byte seconds; |
| 903 | + /* uint8_t */ |
| 904 | + byte frames; |
| 905 | + /* uint32_t */ |
| 906 | + uint userBits; |
| 907 | + CMTime frameDuration; |
| 908 | + nuint sourceType; |
| 909 | + |
| 910 | + /// <summary>Gets or sets the hour component of the timecode.</summary> |
| 911 | + /// <value>The hour value of the current timecode.</value> |
| 912 | + public byte Hours { |
| 913 | + get => hours; |
| 914 | + set => hours = value; |
| 915 | + } |
| 916 | + |
| 917 | + /// <summary>Gets or sets the minute component of the timecode.</summary> |
| 918 | + /// <value>The minute value of the current timecode.</value> |
| 919 | + public byte Minutes { |
| 920 | + get => minutes; |
| 921 | + set => minutes = value; |
| 922 | + } |
| 923 | + |
| 924 | + /// <summary>Gets or sets the second component of the timecode.</summary> |
| 925 | + /// <value>The second value of the current timecode.</value> |
| 926 | + public byte Seconds { |
| 927 | + get => seconds; |
| 928 | + set => seconds = value; |
| 929 | + } |
| 930 | + |
| 931 | + /// <summary>Gets or sets the frame component of the timecode.</summary> |
| 932 | + /// <value>The frame count within the current second.</value> |
| 933 | + public byte Frames { |
| 934 | + get => frames; |
| 935 | + set => frames = value; |
| 936 | + } |
| 937 | + |
| 938 | + /// <summary>Gets or sets the SMPTE user bits field.</summary> |
| 939 | + /// <value>A field carrying additional metadata such as scene-take information, reel numbers, or dates.</value> |
| 940 | + /// <remarks>The exact usage of user bits is application-dependent and not strictly standardized by SMPTE.</remarks> |
| 941 | + public uint UserBits { |
| 942 | + get => userBits; |
| 943 | + set => userBits = value; |
| 944 | + } |
| 945 | + |
| 946 | + /// <summary>Gets or sets the frame duration of the timecode.</summary> |
| 947 | + /// <value>The duration of each frame. If unknown, the value is <see cref="CMTime.Invalid" />.</value> |
| 948 | + public CMTime FrameDuration { |
| 949 | + get => frameDuration; |
| 950 | + set => frameDuration = value; |
| 951 | + } |
| 952 | + |
| 953 | +#if !COREBUILD |
| 954 | + /// <summary>Gets or sets the source type of the timecode.</summary> |
| 955 | + /// <value>The type indicating the emitter, carriage, or transport mechanism of the timecode.</value> |
| 956 | + public AVCaptureTimecodeSourceType SourceType { |
| 957 | + get => (AVCaptureTimecodeSourceType) (long) sourceType; |
| 958 | + set => sourceType = (nuint) (long) value; |
| 959 | + } |
| 960 | + |
| 961 | + /// <summary>Initializes a new instance of the AVCaptureTimecode structure.</summary> |
| 962 | + /// <param name="hours">The hour component of the timecode.</param> |
| 963 | + /// <param name="minutes">The minute component of the timecode.</param> |
| 964 | + /// <param name="seconds">The second component of the timecode.</param> |
| 965 | + /// <param name="frames">The frame component of the timecode.</param> |
| 966 | + /// <param name="userBits">The SMPTE user bits for additional metadata.</param> |
| 967 | + /// <param name="frameDuration">The duration of each frame.</param> |
| 968 | + /// <param name="sourceType">The source type of the timecode.</param> |
| 969 | + public AVCaptureTimecode (byte hours, byte minutes, byte seconds, byte frames, uint userBits, CMTime frameDuration, AVCaptureTimecodeSourceType sourceType) |
| 970 | + { |
| 971 | + Hours = hours; |
| 972 | + Minutes = minutes; |
| 973 | + Seconds = seconds; |
| 974 | + Frames = frames; |
| 975 | + UserBits = userBits; |
| 976 | + FrameDuration = frameDuration; |
| 977 | + SourceType = sourceType; |
| 978 | + } |
| 979 | + |
| 980 | + // CMSampleBufferRef _Nullable AVCaptureTimecodeCreateMetadataSampleBufferAssociatedWithPresentationTimeStamp(AVCaptureTimecode timecode, CMTime presentationTimeStamp) |
| 981 | + [DllImport (Constants.AVFoundationLibrary)] |
| 982 | + static extern IntPtr /* CMSampleBufferRef */ AVCaptureTimecodeCreateMetadataSampleBufferAssociatedWithPresentationTimeStamp (AVCaptureTimecode timecode, CMTime presentationTimeStamp); |
| 983 | + |
| 984 | + /// <summary>Creates a sample buffer containing timecode metadata associated with a presentation timestamp.</summary> |
| 985 | + /// <param name="presentationTimeStamp">The presentation time stamp that determines when the metadata should be applied in the media timeline.</param> |
| 986 | + /// <returns>A sample buffer with encoded timecode metadata for video synchronization, or <see langword="null" /> if creation fails.</returns> |
| 987 | + /// <remarks>This method creates a <see cref="CMSampleBuffer" /> with metadata for integration with a video track at a specific moment in time.</remarks> |
| 988 | + public CMSampleBuffer? CreateMetadataSampleBufferAssociatedWithPresentationTimeStamp (CMTime presentationTimeStamp) |
| 989 | + { |
| 990 | + var ptr = AVCaptureTimecodeCreateMetadataSampleBufferAssociatedWithPresentationTimeStamp (this, presentationTimeStamp); |
| 991 | + return CMSampleBuffer.Create (ptr, owns: true); |
| 992 | + } |
| 993 | + |
| 994 | + // CMSampleBufferRef _Nullable AVCaptureTimecodeCreateMetadataSampleBufferForDuration(AVCaptureTimecode timecode, CMTime duration) |
| 995 | + [DllImport (Constants.AVFoundationLibrary)] |
| 996 | + static extern IntPtr /* CMSampleBufferRef */ AVCaptureTimecodeCreateMetadataSampleBufferForDuration (AVCaptureTimecode timecode, CMTime duration); |
| 997 | + |
| 998 | + /// <summary>Creates a sample buffer containing timecode metadata for a specified duration.</summary> |
| 999 | + /// <param name="duration">The duration that the metadata sample buffer should represent.</param> |
| 1000 | + /// <returns>A sample buffer with encoded timecode metadata for the given duration, or <see langword="null" /> if creation fails.</returns> |
| 1001 | + /// <remarks>Use this method for scenarios where timecode metadata needs to span a custom interval rather than a single frame.</remarks> |
| 1002 | + public CMSampleBuffer? CreateMetadataSampleBufferForDuration (CMTime duration) |
| 1003 | + { |
| 1004 | + var ptr = AVCaptureTimecodeCreateMetadataSampleBufferForDuration (this, duration); |
| 1005 | + return CMSampleBuffer.Create (ptr, owns: true); |
| 1006 | + } |
| 1007 | + |
| 1008 | + // AVCaptureTimecode AVCaptureTimecodeAdvancedByFrames(AVCaptureTimecode timecode, int64_t framesToAdd) |
| 1009 | + [DllImport (Constants.AVFoundationLibrary)] |
| 1010 | + static extern AVCaptureTimecode AVCaptureTimecodeAdvancedByFrames (AVCaptureTimecode timecode, long framesToAdd); |
| 1011 | + |
| 1012 | + /// <summary>Generates a new timecode by adding a specified number of frames to this timecode.</summary> |
| 1013 | + /// <param name="framesToAdd">The number of frames to add to the timecode.</param> |
| 1014 | + /// <returns>A new timecode with the updated time values after adding the specified frames.</returns> |
| 1015 | + /// <remarks>This method handles overflow for seconds, minutes, and hours appropriately.</remarks> |
| 1016 | + public AVCaptureTimecode AddFrames (long framesToAdd) => AVCaptureTimecodeAdvancedByFrames (this, framesToAdd); |
| 1017 | + |
| 1018 | + /// <summary>Determines whether two timecode instances are equal.</summary> |
| 1019 | + /// <param name="left">The first timecode to compare.</param> |
| 1020 | + /// <param name="right">The second timecode to compare.</param> |
| 1021 | + /// <returns>True if the timecodes are equal; otherwise, false.</returns> |
| 1022 | + public static bool operator == (AVCaptureTimecode left, AVCaptureTimecode right) => left.Equals (right); |
| 1023 | + |
| 1024 | + /// <summary>Determines whether two timecode instances are not equal.</summary> |
| 1025 | + /// <param name="left">The first timecode to compare.</param> |
| 1026 | + /// <param name="right">The second timecode to compare.</param> |
| 1027 | + /// <returns>True if the timecodes are not equal; otherwise, false.</returns> |
| 1028 | + public static bool operator != (AVCaptureTimecode left, AVCaptureTimecode right) => !left.Equals (right); |
| 1029 | + |
| 1030 | + /// <summary>Determines whether this timecode is equal to the specified object.</summary> |
| 1031 | + /// <param name="obj">The object to compare with this timecode.</param> |
| 1032 | + /// <returns>True if the specified object is equal to this timecode; otherwise, false.</returns> |
| 1033 | + public override bool Equals (object? obj) => obj is AVCaptureTimecode other && Equals (other); |
| 1034 | + |
| 1035 | + /// <summary>Determines whether this timecode is equal to another timecode.</summary> |
| 1036 | + /// <param name="other">The other timecode to compare with this timecode.</param> |
| 1037 | + /// <returns>True if the timecodes are equal; otherwise, false.</returns> |
| 1038 | + public bool Equals (AVCaptureTimecode other) |
| 1039 | + { |
| 1040 | + return Hours == other.Hours |
| 1041 | + && Minutes == other.Minutes |
| 1042 | + && Seconds == other.Seconds |
| 1043 | + && Frames == other.Frames |
| 1044 | + && UserBits == other.UserBits |
| 1045 | + && FrameDuration.Equals (other.FrameDuration) |
| 1046 | + && SourceType == other.SourceType; |
| 1047 | + } |
| 1048 | + |
| 1049 | + /// <summary>Returns the hash code for this timecode.</summary> |
| 1050 | + /// <returns>A hash code for the current timecode.</returns> |
| 1051 | + public override int GetHashCode () => HashCode.Combine (Hours, Minutes, Seconds, Frames, UserBits, FrameDuration, SourceType); |
| 1052 | +#endif |
| 1053 | + } |
883 | 1054 | } |
0 commit comments