diff --git a/src/CoreMedia/CMSampleBuffer.cs b/src/CoreMedia/CMSampleBuffer.cs index 5baa8977ca..514324dce5 100644 --- a/src/CoreMedia/CMSampleBuffer.cs +++ b/src/CoreMedia/CMSampleBuffer.cs @@ -8,6 +8,8 @@ // Copyright 2012-2014 Xamarin Inc // +#nullable enable + using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; @@ -32,53 +34,23 @@ namespace CoreMedia { #if !NET [Watch (6,0)] #endif - public class CMSampleBuffer : ICMAttachmentBearer -#if !COREBUILD - , IDisposable -#endif + public class CMSampleBuffer : NativeObject, ICMAttachmentBearer { #if !COREBUILD - internal IntPtr handle; GCHandle invalidate; - internal CMSampleBuffer (IntPtr handle) - { - this.handle = handle; - } - [Preserve (Conditional=true)] internal CMSampleBuffer (IntPtr handle, bool owns) + : base (handle, owns) { - if (!owns) - CFObject.CFRetain (handle); - - this.handle = handle; - } - - ~CMSampleBuffer () - { - Dispose (false); - } - - public void Dispose () - { - Dispose (true); - GC.SuppressFinalize (this); } - public IntPtr Handle { - get { return handle; } - } - - protected virtual void Dispose (bool disposing) + protected override void Dispose (bool disposing) { if (invalidate.IsAllocated) invalidate.Free (); - if (handle != IntPtr.Zero){ - CFObject.CFRelease (handle); - handle = IntPtr.Zero; - } + base.Dispose (disposing); } [DllImport(Constants.CoreMediaLibrary)] @@ -94,13 +66,13 @@ namespace CoreMedia { /* AudioStreamPacketDescription* */ AudioStreamPacketDescription[] packetDescriptions, /* CMSampleBufferRef* */ out IntPtr sBufOut); - public static CMSampleBuffer CreateWithPacketDescriptions (CMBlockBuffer dataBuffer, CMFormatDescription formatDescription, int samplesCount, + public static CMSampleBuffer? CreateWithPacketDescriptions (CMBlockBuffer? dataBuffer, CMFormatDescription formatDescription, int samplesCount, CMTime sampleTimestamp, AudioStreamPacketDescription[] packetDescriptions, out CMSampleBufferError error) { - if (formatDescription == null) - throw new ArgumentNullException ("formatDescription"); + if (formatDescription is null) + throw new ArgumentNullException (nameof (formatDescription)); if (samplesCount <= 0) - throw new ArgumentOutOfRangeException ("samplesCount"); + throw new ArgumentOutOfRangeException (nameof (samplesCount)); IntPtr buffer; error = CMAudioSampleBufferCreateWithPacketDescriptions (IntPtr.Zero, @@ -126,18 +98,18 @@ namespace CoreMedia { /* CMSampleBufferRef* */ out IntPtr sBufCopyOut ); - public static CMSampleBuffer CreateWithNewTiming (CMSampleBuffer original, CMSampleTimingInfo [] timing) + public static CMSampleBuffer? CreateWithNewTiming (CMSampleBuffer original, CMSampleTimingInfo []? timing) { OSStatus status; return CreateWithNewTiming (original, timing, out status); } - public unsafe static CMSampleBuffer CreateWithNewTiming (CMSampleBuffer original, CMSampleTimingInfo [] timing, out OSStatus status) + public unsafe static CMSampleBuffer? CreateWithNewTiming (CMSampleBuffer original, CMSampleTimingInfo []? timing, out OSStatus status) { - if (original == null) - throw new ArgumentNullException ("original"); + if (original is null) + throw new ArgumentNullException (nameof (original)); - nint count = timing == null ? 0 : timing.Length; + nint count = timing is null ? 0 : timing.Length; IntPtr handle; fixed (CMSampleTimingInfo *t = timing) { @@ -168,7 +140,7 @@ namespace CoreMedia { { GCHandle gch = GCHandle.FromIntPtr (refCon); var obj = gch.Target as Tuple, CMSampleBuffer>; - if (obj == null) + if (obj is null) return CMSampleBufferError.RequiredParameterMissing; return obj.Item1 (obj.Item2, index); } @@ -176,13 +148,15 @@ namespace CoreMedia { public CMSampleBufferError CallForEachSample (Func callback) { // it makes no sense not to provide a callback - and it also crash the app - if (callback == null) - throw new ArgumentNullException ("callback"); + if (callback is null) + throw new ArgumentNullException (nameof (callback)); GCHandle h = GCHandle.Alloc (Tuple.Create (callback, this)); - var result = CMSampleBufferCallForEachSample (handle, ForEachSampleHandler, (IntPtr)h); - h.Free (); - return result; + try { + return CMSampleBufferCallForEachSample (Handle, ForEachSampleHandler, (IntPtr) h); + } finally { + h.Free (); + } } /* @@ -230,16 +204,16 @@ namespace CoreMedia { /* CMSampleBufferRef* */ out IntPtr bufOut ); - public static CMSampleBuffer CreateForImageBuffer (CVImageBuffer imageBuffer, bool dataReady, CMVideoFormatDescription formatDescription, CMSampleTimingInfo sampleTiming, out CMSampleBufferError error) + public static CMSampleBuffer? CreateForImageBuffer (CVImageBuffer imageBuffer, bool dataReady, CMVideoFormatDescription formatDescription, CMSampleTimingInfo sampleTiming, out CMSampleBufferError error) { - if (imageBuffer == null) - throw new ArgumentNullException ("imageBuffer"); - if (formatDescription == null) - throw new ArgumentNullException ("formatDescription"); + if (imageBuffer is null) + throw new ArgumentNullException (nameof (imageBuffer)); + if (formatDescription is null) + throw new ArgumentNullException (nameof (formatDescription)); IntPtr buffer; error = CMSampleBufferCreateForImageBuffer (IntPtr.Zero, - imageBuffer.handle, dataReady, + imageBuffer.Handle, dataReady, IntPtr.Zero, IntPtr.Zero, formatDescription.Handle, ref sampleTiming, @@ -259,7 +233,7 @@ namespace CoreMedia { { get { - return CMSampleBufferDataIsReady (handle); + return CMSampleBufferDataIsReady (Handle); } } @@ -293,9 +267,9 @@ namespace CoreMedia { [DllImport(Constants.CoreMediaLibrary)] extern static /* CMBlockBufferRef */ IntPtr CMSampleBufferGetDataBuffer (/* CMSampleBufferRef */ IntPtr sbuf); - public CMBlockBuffer GetDataBuffer () + public CMBlockBuffer? GetDataBuffer () { - var blockHandle = CMSampleBufferGetDataBuffer (handle); + var blockHandle = CMSampleBufferGetDataBuffer (Handle); if (blockHandle == IntPtr.Zero) { return null; @@ -313,7 +287,7 @@ namespace CoreMedia { { get { - return CMSampleBufferGetDecodeTimeStamp (handle); + return CMSampleBufferGetDecodeTimeStamp (Handle); } } @@ -324,25 +298,25 @@ namespace CoreMedia { { get { - return CMSampleBufferGetDuration (handle); + return CMSampleBufferGetDuration (Handle); } } [DllImport(Constants.CoreMediaLibrary)] extern static /* CMFormatDescriptionRef */ IntPtr CMSampleBufferGetFormatDescription (/* CMSampleBufferRef */ IntPtr sbuf); - public CMAudioFormatDescription GetAudioFormatDescription () + public CMAudioFormatDescription? GetAudioFormatDescription () { - var descHandle = CMSampleBufferGetFormatDescription (handle); + var descHandle = CMSampleBufferGetFormatDescription (Handle); if (descHandle == IntPtr.Zero) return null; return new CMAudioFormatDescription (descHandle, false); } - public CMVideoFormatDescription GetVideoFormatDescription () + public CMVideoFormatDescription? GetVideoFormatDescription () { - var descHandle = CMSampleBufferGetFormatDescription (handle); + var descHandle = CMSampleBufferGetFormatDescription (Handle); if (descHandle == IntPtr.Zero) return null; @@ -352,9 +326,9 @@ namespace CoreMedia { [DllImport(Constants.CoreMediaLibrary)] extern static /* CVImageBufferRef */ IntPtr CMSampleBufferGetImageBuffer (/* CMSampleBufferRef */ IntPtr sbuf); - public CVImageBuffer GetImageBuffer () + public CVImageBuffer? GetImageBuffer () { - IntPtr ib = CMSampleBufferGetImageBuffer (handle); + IntPtr ib = CMSampleBufferGetImageBuffer (Handle); if (ib == IntPtr.Zero) return null; @@ -371,7 +345,7 @@ namespace CoreMedia { { get { - return CMSampleBufferGetNumSamples (handle); + return CMSampleBufferGetNumSamples (Handle); } } @@ -382,7 +356,7 @@ namespace CoreMedia { { get { - return CMSampleBufferGetOutputDecodeTimeStamp (handle); + return CMSampleBufferGetOutputDecodeTimeStamp (Handle); } } @@ -393,7 +367,7 @@ namespace CoreMedia { { get { - return CMSampleBufferGetOutputDuration (handle); + return CMSampleBufferGetOutputDuration (Handle); } } @@ -404,7 +378,7 @@ namespace CoreMedia { { get { - return CMSampleBufferGetOutputPresentationTimeStamp (handle); + return CMSampleBufferGetOutputPresentationTimeStamp (Handle); } } @@ -424,10 +398,10 @@ namespace CoreMedia { public CMTime PresentationTimeStamp { get { - return CMSampleBufferGetPresentationTimeStamp (handle); + return CMSampleBufferGetPresentationTimeStamp (Handle); } set { - var result = CMSampleBufferSetOutputPresentationTimeStamp (handle, value); + var result = CMSampleBufferSetOutputPresentationTimeStamp (Handle, value); if (result != 0) throw new ArgumentException (result.ToString ()); } @@ -436,16 +410,16 @@ namespace CoreMedia { [DllImport(Constants.CoreMediaLibrary)] extern static /* CFArrayRef */ IntPtr CMSampleBufferGetSampleAttachmentsArray (/* CMSampleBufferRef */ IntPtr sbuf, /* Boolean */ [MarshalAs (UnmanagedType.I1)] bool createIfNecessary); - public CMSampleBufferAttachmentSettings [] GetSampleAttachments (bool createIfNecessary) + public CMSampleBufferAttachmentSettings? [] GetSampleAttachments (bool createIfNecessary) { - var cfArrayRef = CMSampleBufferGetSampleAttachmentsArray (handle, createIfNecessary); + var cfArrayRef = CMSampleBufferGetSampleAttachmentsArray (Handle, createIfNecessary); if (cfArrayRef == IntPtr.Zero) { - return new CMSampleBufferAttachmentSettings [0]; + return Array.Empty (); } else { - return NSArray.ArrayFromHandle (cfArrayRef, h => new CMSampleBufferAttachmentSettings ((NSMutableDictionary) Runtime.GetNSObject (h))); + return NSArray.ArrayFromHandle (cfArrayRef, h => new CMSampleBufferAttachmentSettings ((NSMutableDictionary) Runtime.GetNSObject (h)!))!; } } @@ -454,7 +428,7 @@ namespace CoreMedia { public nuint GetSampleSize (nint sampleIndex) { - return CMSampleBufferGetSampleSize (handle, sampleIndex); + return CMSampleBufferGetSampleSize (Handle, sampleIndex); } /*[DllImport(Constants.CoreMediaLibrary)] @@ -481,21 +455,21 @@ namespace CoreMedia { /* CMItemCount* */ out nint timingArrayEntriesNeededOut ); - public CMSampleTimingInfo [] GetSampleTimingInfo () + public CMSampleTimingInfo []? GetSampleTimingInfo () { OSStatus status; return GetSampleTimingInfo (out status); } - public unsafe CMSampleTimingInfo [] GetSampleTimingInfo (out OSStatus status) { + public unsafe CMSampleTimingInfo []? GetSampleTimingInfo (out OSStatus status) { nint count; status = default (OSStatus); - if (handle == IntPtr.Zero) + if (Handle == IntPtr.Zero) return null; - status = CMSampleBufferGetSampleTimingInfoArray (handle, 0, null, out count); + status = CMSampleBufferGetSampleTimingInfoArray (Handle, 0, null, out count); if (status != (OSStatus) 0) return null; @@ -505,7 +479,7 @@ namespace CoreMedia { return pInfo; fixed (CMSampleTimingInfo* info = pInfo) { - status = CMSampleBufferGetSampleTimingInfoArray (handle, count, info, out count); + status = CMSampleBufferGetSampleTimingInfoArray (Handle, count, info, out count); if (status != (OSStatus) 0) return null; } @@ -515,7 +489,7 @@ namespace CoreMedia { static string OSStatusToString (OSStatus status) { - return new NSError (NSError.OsStatusErrorDomain, status).LocalizedDescription; + return new NSError (NSError.OsStatusErrorDomain, (nint) status).LocalizedDescription; } [DllImport(Constants.CoreMediaLibrary)] @@ -525,7 +499,7 @@ namespace CoreMedia { { get { - return CMSampleBufferGetTotalSampleSize (handle); + return CMSampleBufferGetTotalSampleSize (Handle); } } @@ -542,7 +516,7 @@ namespace CoreMedia { public CMSampleBufferError Invalidate () { - return CMSampleBufferInvalidate (handle); + return CMSampleBufferInvalidate (Handle); } [DllImport(Constants.CoreMediaLibrary)] @@ -553,7 +527,7 @@ namespace CoreMedia { { get { - return CMSampleBufferIsValid (handle); + return CMSampleBufferIsValid (Handle); } } @@ -562,7 +536,7 @@ namespace CoreMedia { public CMSampleBufferError MakeDataReady () { - return CMSampleBufferMakeDataReady (handle); + return CMSampleBufferMakeDataReady (Handle); } [DllImport(Constants.CoreMediaLibrary)] @@ -587,7 +561,7 @@ namespace CoreMedia { public CMSampleBufferError SetDataReady () { - return CMSampleBufferSetDataReady (handle); + return CMSampleBufferSetDataReady (Handle); } #if false @@ -602,7 +576,7 @@ namespace CoreMedia { [DllImport(Constants.CoreMediaLibrary)] extern static /* OSStatus */ CMSampleBufferError CMSampleBufferSetInvalidateCallback ( /* CMSampleBufferRef */ IntPtr sbuf, - /* CMSampleBufferInvalidateCallback */ CMSampleBufferInvalidateCallback invalidateCallback, + /* CMSampleBufferInvalidateCallback */ CMSampleBufferInvalidateCallback? invalidateCallback, /* uint64_t */ ulong invalidateRefCon); delegate void CMSampleBufferInvalidateCallback (/* CMSampleBufferRef */ IntPtr sbuf, @@ -617,17 +591,17 @@ namespace CoreMedia { { GCHandle gch = GCHandle.FromIntPtr ((IntPtr) invalidateRefCon); var obj = gch.Target as Tuple, CMSampleBuffer>; - if (obj != null) + if (obj is not null) obj.Item1 (obj.Item2); } public CMSampleBufferError SetInvalidateCallback (Action invalidateHandler) { - if (invalidateHandler == null) { + if (invalidateHandler is null) { if (invalidate.IsAllocated) invalidate.Free (); - return CMSampleBufferSetInvalidateCallback (handle, null, 0); + return CMSampleBufferSetInvalidateCallback (Handle, null, 0); } // only one callback can be assigned - and ObjC does not let you re-assign a different one, @@ -637,7 +611,7 @@ namespace CoreMedia { return CMSampleBufferError.RequiredParameterMissing; invalidate = GCHandle.Alloc (Tuple.Create (invalidateHandler, this)); - return CMSampleBufferSetInvalidateCallback (handle, invalidate_handler, (ulong)(IntPtr)invalidate); + return CMSampleBufferSetInvalidateCallback (Handle, invalidate_handler, (ulong)(IntPtr)invalidate); } [DllImport(Constants.CoreMediaLibrary)] @@ -645,8 +619,7 @@ namespace CoreMedia { public CMSampleBufferError TrackDataReadiness (CMSampleBuffer bufferToTrack) { - var handleToTrack = bufferToTrack == null ? IntPtr.Zero : bufferToTrack.handle; - return CMSampleBufferTrackDataReadiness (handle, handleToTrack); + return CMSampleBufferTrackDataReadiness (Handle, bufferToTrack.GetHandle ()); } #if !NET @@ -660,10 +633,10 @@ namespace CoreMedia { #endif public CMSampleBufferError CopyPCMDataIntoAudioBufferList (int frameOffset, int numFrames, AudioBuffers bufferList) { - if (bufferList == null) - throw new ArgumentNullException ("bufferList"); + if (bufferList is null) + throw new ArgumentNullException (nameof (bufferList)); - return CMSampleBufferCopyPCMDataIntoAudioBufferList (handle, frameOffset, numFrames, (IntPtr) bufferList); + return CMSampleBufferCopyPCMDataIntoAudioBufferList (Handle, frameOffset, numFrames, (IntPtr) bufferList); } #if !NET @@ -676,21 +649,21 @@ namespace CoreMedia { /* CMFormatDescriptionRef */ IntPtr formatDescription, /* CMItemCount */ nint numSamples, CMTime sbufPTS, - /* AudioStreamPacketDescription* */ AudioStreamPacketDescription[] packetDescriptions, + /* AudioStreamPacketDescription* */ AudioStreamPacketDescription[]? packetDescriptions, /* CMSampleBufferRef* */ out IntPtr sBufOut); #if !NET [iOS (8,0)][Mac (10,10)] #endif - public static CMSampleBuffer CreateReadyWithPacketDescriptions (CMBlockBuffer dataBuffer, CMFormatDescription formatDescription, int samplesCount, - CMTime sampleTimestamp, AudioStreamPacketDescription[] packetDescriptions, out CMSampleBufferError error) + public static CMSampleBuffer? CreateReadyWithPacketDescriptions (CMBlockBuffer dataBuffer, CMFormatDescription formatDescription, int samplesCount, + CMTime sampleTimestamp, AudioStreamPacketDescription[]? packetDescriptions, out CMSampleBufferError error) { - if (dataBuffer == null) - throw new ArgumentNullException ("dataBuffer"); - if (formatDescription == null) - throw new ArgumentNullException ("formatDescription"); + if (dataBuffer is null) + throw new ArgumentNullException (nameof (dataBuffer)); + if (formatDescription is null) + throw new ArgumentNullException (nameof (formatDescription)); if (samplesCount <= 0) - throw new ArgumentOutOfRangeException ("samplesCount"); + throw new ArgumentOutOfRangeException (nameof (samplesCount)); error = CMAudioSampleBufferCreateReadyWithPacketDescriptions (IntPtr.Zero, dataBuffer.Handle, formatDescription.Handle, samplesCount, sampleTimestamp, packetDescriptions, out var buffer); @@ -711,27 +684,27 @@ namespace CoreMedia { /* CMFormatDescriptionRef */ IntPtr formatDescription, // can be null /* CMItemCount */ nint numSamples, // can be 0 /* CMItemCount */ nint numSampleTimingEntries, // 0, 1 or numSamples - CMSampleTimingInfo[] sampleTimingArray, // can be null + CMSampleTimingInfo[]? sampleTimingArray, // can be null /* CMItemCount */ nint numSampleSizeEntries, // 0, 1 or numSamples - /* size_t* */ nuint[] sampleSizeArray, // can be null + /* size_t* */ nuint[]? sampleSizeArray, // can be null /* CMSampleBufferRef* */ out IntPtr sBufOut); #if !NET [iOS (8,0)][Mac (10,10)] #endif - public static CMSampleBuffer CreateReady (CMBlockBuffer dataBuffer, CMFormatDescription formatDescription, - int samplesCount, CMSampleTimingInfo[] sampleTimingArray, nuint[] sampleSizeArray, + public static CMSampleBuffer? CreateReady (CMBlockBuffer dataBuffer, CMFormatDescription? formatDescription, + int samplesCount, CMSampleTimingInfo[]? sampleTimingArray, nuint[]? sampleSizeArray, out CMSampleBufferError error) { - if (dataBuffer == null) - throw new ArgumentNullException ("dataBuffer"); + if (dataBuffer is null) + throw new ArgumentNullException (nameof (dataBuffer)); if (samplesCount < 0) - throw new ArgumentOutOfRangeException ("samplesCount"); + throw new ArgumentOutOfRangeException (nameof (samplesCount)); IntPtr buffer; - var fdh = formatDescription == null ? IntPtr.Zero : formatDescription.Handle; - var timingCount = sampleTimingArray == null ? 0 : sampleTimingArray.Length; - var sizeCount = sampleSizeArray == null ? 0 : sampleSizeArray.Length; + var fdh = formatDescription.GetHandle (); + var timingCount = sampleTimingArray is null ? 0 : sampleTimingArray.Length; + var sizeCount = sampleSizeArray is null ? 0 : sampleSizeArray.Length; error = CMSampleBufferCreateReady (IntPtr.Zero, dataBuffer.Handle, fdh, samplesCount, timingCount, sampleTimingArray, sizeCount, sampleSizeArray, out buffer); @@ -763,7 +736,7 @@ namespace CoreMedia { public static CMSampleBuffer CreateReadyWithImageBuffer (CVImageBuffer imageBuffer, CMFormatDescription formatDescription, CMSampleTimingInfo[] sampleTiming, out CMSampleBufferError error) { - if (sampleTiming == null) + if (sampleTiming is null) throw new ArgumentNullException (nameof (sampleTiming)); if (sampleTiming.Length != 1) throw new ArgumentException ("Only a single sample is allowed.", nameof (sampleTiming)); @@ -774,16 +747,16 @@ namespace CoreMedia { #if !NET [iOS (8,0)][Mac (10,10)] #endif - public static CMSampleBuffer CreateReadyWithImageBuffer (CVImageBuffer imageBuffer, + public static CMSampleBuffer? CreateReadyWithImageBuffer (CVImageBuffer imageBuffer, CMFormatDescription formatDescription, ref CMSampleTimingInfo sampleTiming, out CMSampleBufferError error) { - if (imageBuffer == null) + if (imageBuffer is null) throw new ArgumentNullException (nameof (imageBuffer)); - if (formatDescription == null) + if (formatDescription is null) throw new ArgumentNullException (nameof (formatDescription)); IntPtr buffer; - error = CMSampleBufferCreateReadyWithImageBuffer (IntPtr.Zero, imageBuffer.handle, + error = CMSampleBufferCreateReadyWithImageBuffer (IntPtr.Zero, imageBuffer.Handle, formatDescription.Handle, ref sampleTiming, out buffer); if (error != CMSampleBufferError.None) @@ -947,7 +920,7 @@ namespace CoreMedia { } #if !MONOMAC - public string DroppedFrameReason { + public string? DroppedFrameReason { get { return GetStringValue (CMSampleAttachmentKey.DroppedFrameReason); } @@ -959,8 +932,8 @@ namespace CoreMedia { #endif public LensStabilizationStatus StillImageLensStabilizationStatus { get { - string reason = GetStringValue (CMSampleAttachmentKey.StillImageLensStabilizationInfo); - if (reason == null) + var reason = GetStringValue (CMSampleAttachmentKey.StillImageLensStabilizationInfo); + if (reason is null) return LensStabilizationStatus.None; if (reason == CMSampleAttachmentKey.BufferLensStabilizationInfo_Active)