1010using System ;
1111using System . Runtime . InteropServices ;
1212using FlashCap . Devices ;
13+ using static FlashCap . Internal . NativeMethods_AVFoundation ;
1314
14- namespace FlashCap . Internal ;
15+ namespace FlashCap . Internal . AVFoundation ;
1516
16- partial class NativeMethods_AVFoundation
17+ partial class LibAVFoundation
1718{
18- public static partial class LibAVFoundation
19+ public sealed class AVCaptureVideoDataOutput : AVCaptureOutput
1920 {
20- public sealed class AVCaptureVideoDataOutput : AVCaptureOutput
21+
22+ AVCaptureVideoDataOutputSampleBuffer . CaptureOutputDidOutputSampleBuffer ? callbackDelegate ;
23+
24+ public AVCaptureVideoDataOutput ( ) : base ( IntPtr . Zero , retain : false )
25+ {
26+ Init ( ) ;
27+ }
28+
29+ private void Init ( )
2130 {
2231
23- AVCaptureVideoDataOutputSampleBuffer . CaptureOutputDidOutputSampleBuffer ? callbackDelegate ;
32+ IntPtr allocSel = LibObjC . GetSelector ( "alloc" ) ;
33+ IntPtr initSel = LibObjC . GetSelector ( "init" ) ;
34+ IntPtr videoDataOutputClass = LibObjC . GetClass ( "AVCaptureVideoDataOutput" ) ;
35+ IntPtr videoOutputAlloc = LibObjC . SendAndGetHandle ( videoDataOutputClass , allocSel ) ;
36+ IntPtr videoDataOutput = LibObjC . SendAndGetHandle ( videoOutputAlloc , initSel ) ;
2437
25- public AVCaptureVideoDataOutput ( ) : base ( IntPtr . Zero , retain : false )
26- {
27- Init ( ) ;
28- }
38+ Handle = videoDataOutput ;
39+
40+ LibCoreFoundation . CFRetain ( Handle ) ;
41+ }
2942
30- private void Init ( )
31- {
32-
33- IntPtr allocSel = LibObjC . GetSelector ( "alloc" ) ;
34- IntPtr initSel = LibObjC . GetSelector ( "init" ) ;
35- IntPtr videoDataOutputClass = LibObjC . GetClass ( "AVCaptureVideoDataOutput" ) ;
36- IntPtr videoOutputAlloc = LibObjC . SendAndGetHandle ( videoDataOutputClass , allocSel ) ;
37- IntPtr videoDataOutput = LibObjC . SendAndGetHandle ( videoOutputAlloc , initSel ) ;
38-
39- Handle = videoDataOutput ;
40-
41- LibCoreFoundation . CFRetain ( Handle ) ;
42- }
43+ public unsafe int [ ] AvailableVideoCVPixelFormatTypes =>
44+ LibCoreFoundation . CFArray . ToArray (
45+ LibObjC . SendAndGetHandle (
46+ Handle ,
47+ LibObjC . GetSelector ( "availableVideoCVPixelFormatTypes" ) ) ,
48+ static handle =>
49+ {
50+ int value ;
51+ if ( LibCoreFoundation . CFNumberGetValue ( handle , LibCoreFoundation . CFNumberType . sInt32Type , & value ) )
52+ return value ;
53+ throw new InvalidOperationException ( "The value contained by CFNumber cannot be read as 32-bit signed integer." ) ;
54+ } ) ;
55+
56+ public bool AlwaysDiscardsLateVideoFrames
57+ {
58+ get =>
59+ LibObjC . SendAndGetBool (
60+ Handle ,
61+ LibObjC . GetSelector ( "alwaysDiscardsLateVideoFrames" ) ) ;
62+ set =>
63+ LibObjC . SendNoResult (
64+ Handle ,
65+ LibObjC . GetSelector ( "setAlwaysDiscardsLateVideoFrames:" ) ,
66+ value ) ;
67+ }
4368
44- public unsafe int [ ] AvailableVideoCVPixelFormatTypes =>
45- LibCoreFoundation . CFArray . ToArray (
46- LibObjC . SendAndGetHandle (
47- Handle ,
48- LibObjC . GetSelector ( "availableVideoCVPixelFormatTypes" ) ) ,
49- static handle =>
50- {
51- int value ;
52- if ( LibCoreFoundation . CFNumberGetValue ( handle , LibCoreFoundation . CFNumberType . sInt32Type , & value ) )
53- return value ;
54- throw new InvalidOperationException ( "The value contained by CFNumber cannot be read as 32-bit signed integer." ) ;
55- } ) ;
56-
57- public bool AlwaysDiscardsLateVideoFrames
69+ public void SetPixelFormatType ( int format )
70+ {
71+
72+ var pixelFormat = format ;
73+
74+ IntPtr pixelFormatTypeKeyPtr = Dlfcn . dlsym ( LibCoreVideo . Handle , "kCVPixelBufferPixelFormatTypeKey" ) ;
75+ if ( pixelFormatTypeKeyPtr == IntPtr . Zero )
5876 {
59- get =>
60- LibObjC . SendAndGetBool (
61- Handle ,
62- LibObjC . GetSelector ( "alwaysDiscardsLateVideoFrames" ) ) ;
63- set =>
64- LibObjC . SendNoResult (
65- Handle ,
66- LibObjC . GetSelector ( "setAlwaysDiscardsLateVideoFrames:" ) ,
67- value ) ;
77+ throw new Exception ( "Error comunicating with the AVCaptureVideoDataOutput" ) ;
6878 }
6979
70- public void SetPixelFormatType ( int format )
71- {
80+ // Get NSString value
81+ IntPtr nsPixelFormatKey = Marshal . ReadIntPtr ( pixelFormatTypeKeyPtr ) ;
82+ IntPtr nsNumber = LibObjC . CreateNSNumber ( pixelFormat ) ;
7283
73- var pixelFormat = format ;
74-
75- IntPtr pixelFormatTypeKeyPtr = Dlfcn . dlsym ( LibCoreVideo . Handle , "kCVPixelBufferPixelFormatTypeKey" ) ;
76- if ( pixelFormatTypeKeyPtr == IntPtr . Zero )
77- {
78- throw new Exception ( "Error comunicating with the AVCaptureVideoDataOutput" ) ;
79- }
80-
81- // Get NSString value
82- IntPtr nsPixelFormatKey = Marshal . ReadIntPtr ( pixelFormatTypeKeyPtr ) ;
83- IntPtr nsNumber = LibObjC . CreateNSNumber ( pixelFormat ) ;
84-
85- IntPtr nsDictionaryClass = LibObjC . GetClass ( "NSDictionary" ) ;
86- IntPtr dictSel = LibObjC . GetSelector ( "dictionaryWithObject:forKey:" ) ;
87- IntPtr videoSettings = LibObjC . SendAndGetHandle ( nsDictionaryClass , dictSel , nsNumber , nsPixelFormatKey ) ;
88- IntPtr setVideoSettingsSel = LibObjC . GetSelector ( "setVideoSettings:" ) ;
89- LibObjC . SendNoResult ( this . Handle , setVideoSettingsSel , videoSettings ) ;
90-
91- }
84+ IntPtr nsDictionaryClass = LibObjC . GetClass ( "NSDictionary" ) ;
85+ IntPtr dictSel = LibObjC . GetSelector ( "dictionaryWithObject:forKey:" ) ;
86+ IntPtr videoSettings = LibObjC . SendAndGetHandle ( nsDictionaryClass , dictSel , nsNumber , nsPixelFormatKey ) ;
87+ IntPtr setVideoSettingsSel = LibObjC . GetSelector ( "setVideoSettings:" ) ;
88+ LibObjC . SendNoResult ( this . Handle , setVideoSettingsSel , videoSettings ) ;
89+
90+ }
9291
93- public void SetSampleBufferDelegate ( AVFoundationDevice . VideoBufferHandler sampleBufferDelegate ,
94- LibCoreFoundation . DispatchQueue sampleBufferCallbackQueue )
92+ public void SetSampleBufferDelegate ( AVFoundationDevice . VideoBufferHandler sampleBufferDelegate ,
93+ LibCoreFoundation . DispatchQueue sampleBufferCallbackQueue )
94+ {
95+
96+ if ( sampleBufferDelegate == null )
9597 {
96-
97- if ( sampleBufferDelegate == null )
98- {
99- Console . WriteLine ( "AVCaptureVideoDataOutputSampleBufferDelegate is null" ) ;
100- return ;
101- }
102-
103- IntPtr allocSel = LibObjC . GetSelector ( "alloc" ) ;
104- IntPtr initSel = LibObjC . GetSelector ( "init" ) ;
105- IntPtr nsObjectClass = LibObjC . GetClass ( "NSObject" ) ;
106- IntPtr delegateClass = LibObjC . objc_allocateClassPair ( nsObjectClass , "CaptureDelegate_" + Handle , IntPtr . Zero ) ;
107- IntPtr selDidOutput = LibObjC . GetSelector ( "captureOutput:didOutputSampleBuffer:fromConnection:" ) ;
108-
109- callbackDelegate = sampleBufferDelegate . CaptureOutputCallback ;
110-
111- IntPtr impCallback = Marshal . GetFunctionPointerForDelegate ( callbackDelegate ) ;
112-
113- // "v@:@@@" this means the methood returns void and receives (self, _cmd, output, sampleBuffer, connection).
114- string types = "v@:@@@" ;
115- bool added = LibObjC . class_addMethod ( delegateClass , selDidOutput , impCallback , types ) ;
116- if ( ! added )
117- {
118- return ;
119- }
98+ Console . WriteLine ( "AVCaptureVideoDataOutputSampleBufferDelegate is null" ) ;
99+ return ;
100+ }
101+
102+ IntPtr allocSel = LibObjC . GetSelector ( "alloc" ) ;
103+ IntPtr initSel = LibObjC . GetSelector ( "init" ) ;
104+ IntPtr nsObjectClass = LibObjC . GetClass ( "NSObject" ) ;
105+ IntPtr delegateClass = LibObjC . objc_allocateClassPair ( nsObjectClass , "CaptureDelegate_" + Handle , IntPtr . Zero ) ;
106+ IntPtr selDidOutput = LibObjC . GetSelector ( "captureOutput:didOutputSampleBuffer:fromConnection:" ) ;
107+
108+ callbackDelegate = sampleBufferDelegate . CaptureOutputCallback ;
109+
110+ IntPtr impCallback = Marshal . GetFunctionPointerForDelegate ( callbackDelegate ) ;
120111
121- LibObjC . objc_registerClassPair ( delegateClass ) ;
112+ // "v@:@@@" this means the methood returns void and receives (self, _cmd, output, sampleBuffer, connection).
113+ string types = "v@:@@@" ;
114+ bool added = LibObjC . class_addMethod ( delegateClass , selDidOutput , impCallback , types ) ;
115+ if ( ! added )
116+ {
117+ return ;
118+ }
122119
123- // Delegate creation
124- IntPtr delegateInstanceAlloc = LibObjC . SendAndGetHandle ( delegateClass , allocSel ) ;
125- IntPtr delegateInstance = LibObjC . SendAndGetHandle ( delegateInstanceAlloc , initSel ) ;
126-
127- IntPtr setDelegateSel = LibObjC . GetSelector ( "setSampleBufferDelegate:queue:" ) ;
128- LibObjC . SendNoResult ( Handle , setDelegateSel , delegateInstance , sampleBufferCallbackQueue . Handle ) ;
120+ LibObjC . objc_registerClassPair ( delegateClass ) ;
129121
130- }
122+ // Delegate creation
123+ IntPtr delegateInstanceAlloc = LibObjC . SendAndGetHandle ( delegateClass , allocSel ) ;
124+ IntPtr delegateInstance = LibObjC . SendAndGetHandle ( delegateInstanceAlloc , initSel ) ;
125+
126+ IntPtr setDelegateSel = LibObjC . GetSelector ( "setSampleBufferDelegate:queue:" ) ;
127+ LibObjC . SendNoResult ( Handle , setDelegateSel , delegateInstance , sampleBufferCallbackQueue . Handle ) ;
131128
132129 }
130+
133131 }
134- }
132+ }
0 commit comments