static void CompressionCallback (IntPtr outputCallbackClosure, IntPtr sourceFrame, VTStatus status, VTEncodeInfoFlags infoFlags, IntPtr cmSampleBufferPtr) { var gch = GCHandle.FromIntPtr (outputCallbackClosure); var func = (VTCompressionOutputCallback) gch.Target; using (var sampleBuffer = new CMSampleBuffer (cmSampleBufferPtr)) { func (sourceFrame, status, infoFlags, sampleBuffer); } }
static unsafe void VTCompressionOutputHandlerTrampoline(BlockLiteral *block, VTStatus status, VTEncodeInfoFlags infoFlags, IntPtr sampleBuffer) { var del = (VTCompressionOutputHandler)(block->Target); if (del != null) { del(status, infoFlags, new CMSampleBuffer(sampleBuffer)); } }
static unsafe void VTDecompressionOutputHandlerTrampoline(BlockLiteral *block, VTStatus status, VTDecodeInfoFlags infoFlags, IntPtr imageBuffer, CMTime presentationTimeStamp, CMTime presentationDuration) { var del = (VTDecompressionOutputHandler)(block->Target); if (del != null) { del(status, infoFlags, new CVImageBuffer(imageBuffer), presentationTimeStamp, presentationDuration); } }
void DidDecompress(IntPtr sourceFrame, VTStatus status, VTDecodeInfoFlags flags, CVImageBuffer buffer, CMTime presentationTimeStamp, CMTime presentationDuration) { if (status != VTStatus.Ok) { Console.WriteLine("Error decompresssing frame at time: {0:#.###} error: {1} infoFlags: {2}", (float)presentationTimeStamp.Value / presentationTimeStamp.TimeScale, (int)status, flags); return; } if (buffer == null) { return; } // Find the correct position for this frame in the output frames array if (presentationTimeStamp.IsInvalid) { Console.WriteLine("Not a valid time for image buffer"); return; } var framePTS = presentationTimeStamp.Seconds; lock (thisLock) { // since we want to keep the managed `pixelBuffer` alive outside the execution // of the callback we need to create our own (managed) instance from the handle var pixelBuffer = Runtime.GetINativeObject <CVPixelBuffer> (buffer.Handle, false); int insertionIndex = presentationTimes.Count - 1; while (insertionIndex >= 0) { var aNumber = presentationTimes [insertionIndex]; if (aNumber <= framePTS) { break; } insertionIndex--; } if (insertionIndex + 1 == presentationTimes.Count) { presentationTimes.Add(framePTS); outputFrames.Add(pixelBuffer); } else { presentationTimes.Insert(insertionIndex + 1, framePTS); outputFrames.Insert(insertionIndex + 1, pixelBuffer); } } }
static void DecompressionCallback (IntPtr outputCallbackClosure, IntPtr sourceFrame, VTStatus status, VTDecodeInfoFlags infoFlags, IntPtr imageBufferPtr, CMTime presentationTimeStamp, CMTime presentationDuration) { var gch = GCHandle.FromIntPtr (outputCallbackClosure); var func = (VTDecompressionOutputCallback) gch.Target; // Apple headers states that the callback should get a CVImageBuffer but it turned out that not all of them are a // CVImageBuffer, some can be instances of CVImageBuffer and others can be instances of CVPixelBuffer. So we go one // step further in the inheritance hierarchy and supply the callback a CVPixelBuffer and the callback supplies // to the developer a CVImageBuffer, so the developer can choose when to use one or the other and we mimic // what Apple provides on its headers. using (var sampleBuffer = new CVPixelBuffer (imageBufferPtr)) { func (sourceFrame, status, infoFlags, sampleBuffer, presentationTimeStamp, presentationDuration); } }
static void CompressionCallback(IntPtr outputCallbackClosure, IntPtr sourceFrame, VTStatus status, VTEncodeInfoFlags infoFlags, IntPtr cmSampleBufferPtr, bool owns) { var gch = GCHandle.FromIntPtr(outputCallbackClosure); var func = (VTCompressionOutputCallback)gch.Target; if (cmSampleBufferPtr == IntPtr.Zero) { func(sourceFrame, status, infoFlags, null); } else { using (var sampleBuffer = new CMSampleBuffer(cmSampleBufferPtr, owns: owns)) func(sourceFrame, status, infoFlags, sampleBuffer); } }
static void DecompressionCallback(IntPtr outputCallbackClosure, IntPtr sourceFrame, VTStatus status, VTDecodeInfoFlags infoFlags, IntPtr imageBufferPtr, CMTime presentationTimeStamp, CMTime presentationDuration) { var gch = GCHandle.FromIntPtr(outputCallbackClosure); var func = (VTDecompressionOutputCallback)gch.Target; // Apple headers states that the callback should get a CVImageBuffer but it turned out that not all of them are a // CVImageBuffer, some can be instances of CVImageBuffer and others can be instances of CVPixelBuffer. So we go one // step further in the inheritance hierarchy and supply the callback a CVPixelBuffer and the callback supplies // to the developer a CVImageBuffer, so the developer can choose when to use one or the other and we mimic // what Apple provides on its headers. using (var sampleBuffer = new CVPixelBuffer(imageBufferPtr)) { func(sourceFrame, status, infoFlags, sampleBuffer, presentationTimeStamp, presentationDuration); } }
static unsafe void VTDecompressionOutputHandlerTrampoline (BlockLiteral *block, VTStatus status, VTDecodeInfoFlags infoFlags, IntPtr imageBuffer, CMTime presentationTimeStamp, CMTime presentationDuration) { var del = (VTDecompressionOutputHandler)(block->Target); if (del != null) del (status, infoFlags, new CVImageBuffer (imageBuffer), presentationTimeStamp, presentationDuration); }
static unsafe void VTCompressionOutputHandlerTrampoline (BlockLiteral *block, VTStatus status, VTEncodeInfoFlags infoFlags, IntPtr sampleBuffer) { var del = (VTCompressionOutputHandler)(block->Target); if (del != null) del (status, infoFlags, new CMSampleBuffer (sampleBuffer)); }
public VTStatus Close() { if (closed) return closedStatus; closedStatus = VTMultiPassStorageClose (handle); closed = true; return closedStatus; }
void DidDecompress(IntPtr sourceFrame, VTStatus status, VTDecodeInfoFlags flags, CVImageBuffer buffer, CMTime presentationTimeStamp, CMTime presentationDuration) { if (status != VTStatus.Ok) { Console.WriteLine ("Error decompresssing frame at time: {0:#.###} error: {1} infoFlags: {2}", (float)presentationTimeStamp.Value / presentationTimeStamp.TimeScale, (int)status, flags); return; } if (buffer == null) return; // Find the correct position for this frame in the output frames array if (presentationTimeStamp.IsInvalid) { Console.WriteLine ("Not a valid time for image buffer"); return; } var framePTS = presentationTimeStamp.Seconds; lock (thisLock) { // since we want to keep the managed `pixelBuffer` alive outside the execution // of the callback we need to create our own (managed) instance from the handle var pixelBuffer = Runtime.GetINativeObject<CVPixelBuffer> (buffer.Handle, false); int insertionIndex = presentationTimes.Count - 1; while (insertionIndex >= 0) { var aNumber = presentationTimes [insertionIndex]; if (aNumber <= framePTS) break; insertionIndex--; } if (insertionIndex + 1 == presentationTimes.Count) { presentationTimes.Add (framePTS); outputFrames.Add (pixelBuffer); } else { presentationTimes.Insert (insertionIndex + 1, framePTS); outputFrames.Insert (insertionIndex + 1, pixelBuffer); } } }
static void CompressionCallback(IntPtr outputCallbackClosure, IntPtr sourceFrame, VTStatus status, VTEncodeInfoFlags infoFlags, IntPtr cmSampleBufferPtr) { var gch = GCHandle.FromIntPtr(outputCallbackClosure); var func = (VTCompressionOutputCallback)gch.Target; using (var sampleBuffer = new CMSampleBuffer(cmSampleBufferPtr)) { func(sourceFrame, status, infoFlags, sampleBuffer); } }