objc2-av-foundation 0.3.2

Bindings to the AVFoundation framework
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
#[cfg(feature = "dispatch2")]
use dispatch2::*;
use objc2::__framework_prelude::*;
#[cfg(feature = "objc2-core-foundation")]
use objc2_core_foundation::*;
#[cfg(feature = "objc2-core-media")]
use objc2_core_media::*;
#[cfg(feature = "objc2-core-video")]
use objc2_core_video::*;
use objc2_foundation::*;

use crate::*;

extern_class!(
    /// AVAssetWriterInput defines an interface for appending either new media samples or references to existing media samples packaged as CMSampleBuffer objects to a single track of the output file of an AVAssetWriter.
    ///
    /// Clients that need to write multiple concurrent tracks of media data should use one AVAssetWriterInput instance per track. In order to write multiple concurrent tracks with ideal interleaving of media data, clients should observe the value returned by the readyForMoreMediaData property of each AVAssetWriterInput instance.
    ///
    /// AVAssetWriterInput also supports writing per-track metadata collections to the output file.
    ///
    /// As of macOS 10.10 and iOS 8.0 AVAssetWriterInput can also be used to create tracks that are not self-contained. Such tracks reference sample data that is located in another file. This is currently supported only for instances of AVAssetWriterInput attached to an instance of AVAssetWriter that writes files of type AVFileTypeQuickTimeMovie.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avassetwriterinput?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct AVAssetWriterInput;
);

extern_conformance!(
    unsafe impl NSObjectProtocol for AVAssetWriterInput {}
);

impl AVAssetWriterInput {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;

        #[cfg(feature = "AVMediaFormat")]
        /// Creates a new input of the specified media type to receive sample buffers for writing to the output file.
        ///
        /// Each new input accepts data for a new track of the AVAssetWriter's output file. Inputs are added to an asset writer using -[AVAssetWriter addInput:].
        ///
        /// Passing nil for output settings instructs the input to pass through appended samples, doing no processing before they are written to the output file. This is useful if, for example, you are appending buffers that are already in a desirable compressed format. However, if not writing to a QuickTime Movie file (i.e. the AVAssetWriter was initialized with a file type other than AVFileTypeQuickTimeMovie), AVAssetWriter only supports passing through a restricted set of media types and subtypes. In order to pass through media data to files other than AVFileTypeQuickTimeMovie, a non-NULL format hint must be provided using +assetWriterInputWithMediaType:outputSettings:sourceFormatHint: instead of this method.
        ///
        /// For AVMediaTypeAudio the following keys are not currently supported in the outputSettings dictionary: AVSampleRateConverterAudioQualityKey. When using this method to construct a new instance, an audio settings dictionary must be fully specified, meaning that it must contain AVFormatIDKey, AVSampleRateKey, and AVNumberOfChannelsKey. If no other channel layout information is available, a value of 1 for AVNumberOfChannelsKey will result in mono output and a value of 2 will result in stereo output. If AVNumberOfChannelsKey specifies a channel count greater than 2, the dictionary must also specify a value for AVChannelLayoutKey. For kAudioFormatLinearPCM, all relevant AVLinearPCM*Key keys must be included, and for kAudioFormatAppleLossless, AVEncoderBitDepthHintKey keys must be included. See +assetWriterInputWithMediaType:outputSettings:sourceFormatHint: for a way to avoid having to specify a value for each of those keys.
        ///
        /// For AVMediaTypeVideo, any output settings dictionary must request a compressed video format. This means that the value passed in for outputSettings must follow the rules for compressed video output, as laid out in AVVideoSettings.h. When using this method to construct a new instance, a video settings dictionary must be fully specified, meaning that it must contain AVVideoCodecKey, AVVideoWidthKey, and AVVideoHeightKey. See +assetWriterInputWithMediaType:outputSettings:sourceFormatHint: for a way to avoid having to specify a value for each of those keys. On iOS, the only values currently supported for AVVideoCodecKey are AVVideoCodecTypeH264 and AVVideoCodecTypeJPEG. AVVideoCodecTypeH264 is not supported on iPhone 3G. For AVVideoScalingModeKey, the value AVVideoScalingModeFit is not supported.
        ///
        /// - Parameter mediaType: The media type of samples that will be accepted by the input. Media types are defined in AVMediaFormat.h.
        /// - Parameter outputSettings: The settings used for encoding the media appended to the output. See AVAudioSettings.h for AVMediaTypeAudio or AVVideoSettings.h for AVMediaTypeVideo and for more information on how to construct an output settings dictionary. If you only require simple preset-based output settings, see AVOutputSettingsAssistant.
        ///
        /// - Returns: An instance of AVAssetWriterInput.
        ///
        /// # Safety
        ///
        /// `output_settings` generic should be of the correct type.
        #[unsafe(method(assetWriterInputWithMediaType:outputSettings:))]
        #[unsafe(method_family = none)]
        pub unsafe fn assetWriterInputWithMediaType_outputSettings(
            media_type: &AVMediaType,
            output_settings: Option<&NSDictionary<NSString, AnyObject>>,
        ) -> Retained<Self>;

        #[cfg(all(feature = "AVMediaFormat", feature = "objc2-core-media"))]
        /// Creates a new input of the specified media type to receive sample buffers for writing to the output file.
        ///
        /// A version of +assetWriterInputWithMediaType:outputSettings: that includes the ability to hint at the format of media data that will be appended to the new instance of AVAssetWriterInput. When a source format hint is provided, the outputSettings dictionary is not required to be fully specified. For AVMediaTypeAudio, this means that AVFormatIDKey is the only required key. For AVMediaTypeVideo, this means that AVVideoCodecKey is the only required key. Values for the remaining keys will be chosen by the asset writer input, with consideration given to the attributes of the source format. To guarantee successful file writing, clients who specify a format hint should ensure that subsequently-appended buffers are of the specified format.
        ///
        /// This method throws an exception for any of the following reasons:
        /// - the media type of the format description does not match the media type passed into this method
        /// - the width and height of video format hint are not positive
        /// - the output settings do not match the supplied media type
        /// - for video inputs, the output settings do not contain a required key (AVVideoCodecKey, AVVideoWidthKey, AVVideoHeightKey)
        /// - the output scaling mode is AVVideoScalingModeFit
        /// - the output settings contain AVSampleRateConverterAudioQualityKey or AVVideoDecompressionPropertiesKey
        ///
        /// - Parameter mediaType: The media type of samples that will be accepted by the input. Media types are defined in AVMediaFormat.h.
        /// - Parameter outputSettings: The settings used for encoding the media appended to the output. See AVAudioSettings.h for AVMediaTypeAudio or AVVideoSettings.h for AVMediaTypeVideo and for more information on how to construct an output settings dictionary. If you only require simple preset-based output settings, see AVOutputSettingsAssistant.
        /// - Parameter sourceFormatHint: A hint about the format of media data that will be appended to the new input.
        ///
        /// - Returns: An instance of AVAssetWriterInput.
        ///
        /// # Safety
        ///
        /// `output_settings` generic should be of the correct type.
        #[unsafe(method(assetWriterInputWithMediaType:outputSettings:sourceFormatHint:))]
        #[unsafe(method_family = none)]
        pub unsafe fn assetWriterInputWithMediaType_outputSettings_sourceFormatHint(
            media_type: &AVMediaType,
            output_settings: Option<&NSDictionary<NSString, AnyObject>>,
            source_format_hint: Option<&CMFormatDescription>,
        ) -> Retained<Self>;

        #[cfg(feature = "AVMediaFormat")]
        /// Creates a new input of the specified media type to receive sample buffers for writing to the output file.
        ///
        /// Each new input accepts data for a new track of the AVAssetWriter's output file. Inputs are added to an asset writer using -[AVAssetWriter addInput:].
        ///
        /// Passing nil for output settings instructs the input to pass through appended samples, doing no processing before they are written to the output file. This is useful if, for example, you are appending buffers that are already in a desirable compressed format. However, if not writing to a QuickTime Movie file (i.e. the AVAssetWriter was initialized with a file type other than AVFileTypeQuickTimeMovie), AVAssetWriter only supports passing through a restricted set of media types and subtypes. In order to pass through media data to files other than AVFileTypeQuickTimeMovie, a non-NULL format hint must be provided using -initWithMediaType:outputSettings:sourceFormatHint: instead of this method.
        ///
        /// For AVMediaTypeAudio the following keys are not currently supported in the outputSettings dictionary: AVSampleRateConverterAudioQualityKey. When using this initializer, an audio settings dictionary must be fully specified, meaning that it must contain AVFormatIDKey, AVSampleRateKey, and AVNumberOfChannelsKey. If no other channel layout information is available, a value of 1 for AVNumberOfChannelsKey will result in mono output and a value of 2 will result in stereo output. If AVNumberOfChannelsKey specifies a channel count greater than 2, the dictionary must also specify a value for AVChannelLayoutKey. For kAudioFormatLinearPCM, all relevant AVLinearPCM*Key keys must be included, and for kAudioFormatAppleLossless, AVEncoderBitDepthHintKey keys must be included. See -initWithMediaType:outputSettings:sourceFormatHint: for a way to avoid having to specify a value for each of those keys.
        ///
        /// For AVMediaTypeVideo, any output settings dictionary must request a compressed video format. This means that the value passed in for outputSettings must follow the rules for compressed video output, as laid out in AVVideoSettings.h. When using this initializer, a video settings dictionary must be fully specified, meaning that it must contain AVVideoCodecKey, AVVideoWidthKey, and AVVideoHeightKey. See -initWithMediaType:outputSettings:sourceFormatHint: for a way to avoid having to specify a value for each of those keys. On iOS, the only values currently supported for AVVideoCodecKey are AVVideoCodecTypeH264 and AVVideoCodecTypeJPEG. AVVideoCodecTypeH264 is not supported on iPhone 3G. For AVVideoScalingModeKey, the value AVVideoScalingModeFit is not supported.
        ///
        /// This method throws an exception for any of the following reasons:
        /// - the media type of the format description does not match the media type passed into this method
        /// - the output settings do not match the supplied media type
        /// - for video inputs, the output settings do not contain a required key (AVVideoCodecKey, AVVideoWidthKey, AVVideoHeightKey)
        /// - the output scaling mode is AVVideoScalingModeFit
        /// - the output settings contain AVSampleRateConverterAudioQualityKey or AVVideoDecompressionPropertiesKey
        ///
        /// - Parameter mediaType: The media type of samples that will be accepted by the input. Media types are defined in AVMediaFormat.h.
        /// - Parameter outputSettings: The settings used for encoding the media appended to the output. See AVAudioSettings.h for AVMediaTypeAudio or AVVideoSettings.h for AVMediaTypeVideo and for more information on how to construct an output settings dictionary. If you only require simple preset-based output settings, see AVOutputSettingsAssistant.
        ///
        /// - Returns: An instance of AVAssetWriterInput.
        ///
        /// # Safety
        ///
        /// `output_settings` generic should be of the correct type.
        #[unsafe(method(initWithMediaType:outputSettings:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithMediaType_outputSettings(
            this: Allocated<Self>,
            media_type: &AVMediaType,
            output_settings: Option<&NSDictionary<NSString, AnyObject>>,
        ) -> Retained<Self>;

        #[cfg(all(feature = "AVMediaFormat", feature = "objc2-core-media"))]
        /// Creates a new input of the specified media type to receive sample buffers for writing to the output file. This is the designated initializer of AVAssetWriterInput.
        ///
        /// A version of -initWithMediaType:outputSettings: that includes the ability to hint at the format of media data that will be appended to the new instance of AVAssetWriterInput. When a source format hint is provided, the outputSettings dictionary is not required to be fully specified. For AVMediaTypeAudio, this means that AVFormatIDKey is the only required key. For AVMediaTypeVideo, this means that AVVideoCodecKey is the only required key. Values for the remaining keys will be chosen by the asset writer input, with consideration given to the attributes of the source format. To guarantee successful file writing, clients who specify a format hint should ensure that subsequently-appended buffers are of the specified format.
        ///
        /// This method throws an exception for any of the following reasons:
        /// - the media type of the format description does not match the media type passed into this method
        /// - the width and height of video format hint are not positive
        /// - the output settings do not match the supplied media type
        /// - for video inputs, the output settings do not contain a required key (AVVideoCodecKey, AVVideoWidthKey, AVVideoHeightKey)
        /// - the output scaling mode is AVVideoScalingModeFit
        /// - the output settings contain AVSampleRateConverterAudioQualityKey or AVVideoDecompressionPropertiesKey
        ///
        /// - Parameter mediaType: The media type of samples that will be accepted by the input. Media types are defined in AVMediaFormat.h.
        /// - Parameter outputSettings: The settings used for encoding the media appended to the output. See AVAudioSettings.h for AVMediaTypeAudio or AVVideoSettings.h for AVMediaTypeVideo and for more information on how to construct an output settings dictionary. If you only require simple preset-based output settings, see AVOutputSettingsAssistant.
        /// - Parameter sourceFormatHint: A hint about the format of media data that will be appended to the new input.
        ///
        /// - Returns: An instance of AVAssetWriterInput.
        ///
        /// # Safety
        ///
        /// `output_settings` generic should be of the correct type.
        #[unsafe(method(initWithMediaType:outputSettings:sourceFormatHint:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithMediaType_outputSettings_sourceFormatHint(
            this: Allocated<Self>,
            media_type: &AVMediaType,
            output_settings: Option<&NSDictionary<NSString, AnyObject>>,
            source_format_hint: Option<&CMFormatDescription>,
        ) -> Retained<Self>;

        #[cfg(feature = "AVMediaFormat")]
        /// The media type of the samples that can be appended to the receiver.
        ///
        /// The value of this property is one of the media types defined in AVMediaFormat.h.
        #[unsafe(method(mediaType))]
        #[unsafe(method_family = none)]
        pub unsafe fn mediaType(&self) -> Retained<AVMediaType>;

        /// The settings used for encoding the media appended to the output.
        ///
        /// The value of this property is an NSDictionary that contains values for keys as specified by either AVAudioSettings.h for AVMediaTypeAudio or AVVideoSettings.h for AVMediaTypeVideo. A value of nil indicates that the receiver will pass through appended samples, doing no processing before they are written to the output file.
        #[unsafe(method(outputSettings))]
        #[unsafe(method_family = none)]
        pub unsafe fn outputSettings(&self) -> Option<Retained<NSDictionary<NSString, AnyObject>>>;

        #[cfg(feature = "objc2-core-media")]
        /// The hint given at initialization time about the format of incoming media data.
        ///
        /// AVAssetWriterInput may be able to use this hint to fill in missing output settings or perform more upfront validation. To guarantee successful file writing, clients who specify a format hint should ensure that subsequently-appended media data are of the specified format.
        #[unsafe(method(sourceFormatHint))]
        #[unsafe(method_family = none)]
        pub unsafe fn sourceFormatHint(&self) -> Option<Retained<CMFormatDescription>>;

        #[cfg(feature = "AVMetadataItem")]
        /// A collection of metadata to be written to the track corresponding to the receiver.
        ///
        /// The value of this property is an array of AVMetadataItem objects representing the collection of track-level metadata to be written in the output file.
        ///
        /// This property cannot be set after writing on the receiver's AVAssetWriter has started.
        #[unsafe(method(metadata))]
        #[unsafe(method_family = none)]
        pub unsafe fn metadata(&self) -> Retained<NSArray<AVMetadataItem>>;

        #[cfg(feature = "AVMetadataItem")]
        /// Setter for [`metadata`][Self::metadata].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setMetadata:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMetadata(&self, metadata: &NSArray<AVMetadataItem>);

        /// Indicates the readiness of the input to accept more media data.
        ///
        /// When there are multiple inputs, AVAssetWriter tries to write media data in an ideal interleaving pattern for efficiency in storage and playback. Each of its inputs signals its readiness to receive media data for writing according to that pattern via the value of readyForMoreMediaData. You can append media data to an input only while its readyForMoreMediaData property is YES.
        ///
        /// Clients writing media data from a non-real-time source, such as an instance of AVAssetReader, should hold off on generating or obtaining more media data to append to an input when the value of readyForMoreMediaData is NO. To help with control of the supply of non-real-time media data, such clients can use -requestMediaDataWhenReadyOnQueue:usingBlock in order to specify a block that the input should invoke whenever it's ready for input to be appended.
        ///
        /// Clients writing media data from a real-time source, such as an instance of AVCaptureOutput, should set the input's expectsMediaDataInRealTime property to YES to ensure that the value of readyForMoreMediaData is calculated appropriately. When expectsMediaDataInRealTime is YES, readyForMoreMediaData will become NO only when the input cannot process media samples as quickly as they are being provided by the client. If readyForMoreMediaData becomes NO for a real-time source, the client may need to drop samples or consider reducing the data rate of appended samples.
        ///
        /// When the value of canPerformMultiplePasses is YES for any input attached to this input's asset writer, the value for this property may start as NO and/or be NO for long periods of time.
        ///
        /// The value of readyForMoreMediaData will often change from NO to YES asynchronously, as previously supplied media data is processed and written to the output. It is possible for all of an AVAssetWriter's AVAssetWriterInputs temporarily to return NO for readyForMoreMediaData.
        ///
        /// This property is key value observable. Observers should not assume that they will be notified of changes on a specific thread.
        #[unsafe(method(isReadyForMoreMediaData))]
        #[unsafe(method_family = none)]
        pub unsafe fn isReadyForMoreMediaData(&self) -> bool;

        /// Indicates whether the input should tailor its processing of media data for real-time sources.
        ///
        /// Clients appending media data to an input from a real-time source, such as an AVCaptureOutput, should set expectsMediaDataInRealTime to YES. This will ensure that readyForMoreMediaData is calculated appropriately for real-time usage.
        ///
        /// For best results, do not set both this property and performsMultiPassEncodingIfSupported to YES.
        ///
        /// This property cannot be set after writing on the receiver's AVAssetWriter has started.
        #[unsafe(method(expectsMediaDataInRealTime))]
        #[unsafe(method_family = none)]
        pub unsafe fn expectsMediaDataInRealTime(&self) -> bool;

        /// Setter for [`expectsMediaDataInRealTime`][Self::expectsMediaDataInRealTime].
        #[unsafe(method(setExpectsMediaDataInRealTime:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setExpectsMediaDataInRealTime(&self, expects_media_data_in_real_time: bool);

        #[cfg(all(feature = "block2", feature = "dispatch2"))]
        /// Instructs the receiver to invoke a client-supplied block repeatedly, at its convenience, in order to gather media data for writing to the output file.
        ///
        /// The block should append media data to the input either until the input's readyForMoreMediaData property becomes NO or until there is no more media data to supply (at which point it may choose to mark the input as finished via -markAsFinished). The block should then exit. After the block exits, if the input has not been marked as finished, once the input has processed the media data it has received and becomes ready for more media data again, it will invoke the block again in order to obtain more.
        ///
        /// A typical use of this method, with a block that supplies media data to an input while respecting the input's readyForMoreMediaData property, might look like this:
        /// ```objc
        /// [myAVAssetWriterInput requestMediaDataWhenReadyOnQueue:myInputSerialQueue usingBlock:^{
        /// while ([myAVAssetWriterInput isReadyForMoreMediaData])
        /// {
        /// CMSampleBufferRef nextSampleBuffer = [self copyNextSampleBufferToWrite];
        /// if (nextSampleBuffer)
        /// {
        /// [myAVAssetWriterInput appendSampleBuffer:nextSampleBuffer];
        /// CFRelease(nextSampleBuffer);
        /// }
        /// else
        /// {
        /// [myAVAssetWriterInput markAsFinished];
        /// break;
        /// }
        /// }
        /// }];
        /// ```
        /// This method is not recommended for use with a push-style buffer source, such as AVCaptureAudioDataOutput or AVCaptureVideoDataOutput, because such a combination will likely require intermediate queueing of buffers. Instead, this method is better suited to a pull-style buffer source such as AVAssetReaderOutput, as illustrated in the above example.
        ///
        /// When using a push-style buffer source, it is generally better to immediately append each buffer to the AVAssetWriterInput, directly via -[AVAssetWriter appendSampleBuffer:], as it is received. Using this strategy, it is often possible to avoid having to queue up buffers in between the buffer source and the AVAssetWriterInput. Note that many of these push-style buffer sources also produce buffers in real-time, in which case the client should set expectsMediaDataInRealTime to YES.
        ///
        /// Before calling this method, you must ensure that the receiver is attached to an AVAssetWriter via a prior call to -addInput: and that -startWriting has been called on the asset writer.
        ///
        /// This method throws an exception if this method is called more than once.
        ///
        /// - Parameter queue: The queue on which the block should be invoked.
        /// - Parameter block: The block the input should invoke to obtain media data.
        ///
        /// # Safety
        ///
        /// - `queue` possibly has additional threading requirements.
        /// - `block` block must be sendable.
        #[unsafe(method(requestMediaDataWhenReadyOnQueue:usingBlock:))]
        #[unsafe(method_family = none)]
        pub unsafe fn requestMediaDataWhenReadyOnQueue_usingBlock(
            &self,
            queue: &DispatchQueue,
            block: &block2::DynBlock<dyn Fn()>,
        );

        #[cfg(feature = "objc2-core-media")]
        /// Appends samples to the receiver.
        ///
        /// The timing information in the sample buffer, considered relative to the time passed to -[AVAssetWriter startSessionAtSourceTime:], will be used to determine the timing of those samples in the output file.
        ///
        /// For track types other than audio tracks, to determine the duration of all samples in the output file other than the very last sample that's appended, the difference between the sample buffer's output DTS and the following sample buffer's output DTS will be used. The duration of the last sample is determined as follows:
        /// 1. If a marker sample buffer with kCMSampleBufferAttachmentKey_EndsPreviousSampleDuration is appended following the last media-bearing sample, the difference between the output DTS of the marker sample buffer and the output DTS of the last media-bearing sample will be used.
        /// 2. If the marker sample buffer is not provided and if the output duration of the last media-bearing sample is valid, it will be used.
        /// 3. if the output duration of the last media-bearing sample is not valid, the duration of the second-to-last sample will be used.
        ///
        /// For audio tracks, the properties of each appended sample buffer are used to determine corresponding output durations.
        ///
        /// The receiver will retain the CMSampleBuffer until it is done with it, and then release it. Do not modify a CMSampleBuffer or its contents after you have passed it to this method.
        ///
        /// If the sample buffer contains audio data and the AVAssetWriterInput was intialized with an outputSettings dictionary then the format must be linear PCM. If the outputSettings dictionary was nil then audio data can be provided in a compressed format, and it will be passed through to the output without any re-compression. Note that advanced formats like AAC will have encoder delay present in their bitstreams. This data is inserted by the encoder and is necessary for proper decoding, but it is not meant to be played back. Clients who provide compressed audio bitstreams must use kCMSampleBufferAttachmentKey_TrimDurationAtStart to mark the encoder delay (generally restricted to the first sample buffer). Packetization can cause there to be extra audio frames in the last packet which are not meant to be played back. These remainder frames should be marked with kCMSampleBufferAttachmentKey_TrimDurationAtEnd. CMSampleBuffers obtained from AVAssetReader will already have the necessary trim attachments. Please see http://developer.apple.com/mac/library/technotes/tn2009/tn2258.html for more information about encoder delay. When attaching trims make sure that the output PTS of the sample buffer is what you expect. For example if you called -[AVAssetWriter startSessionAtSourceTime:kCMTimeZero] and you want your audio to start at time zero in the output file then make sure that the output PTS of the first non-fully trimmed audio sample buffer is kCMTimeZero.
        ///
        /// If the sample buffer contains a CVPixelBuffer then the choice of pixel format will affect the performance and quality of the encode. For optimal performance the format of the pixel buffer should match one of the native formats supported by the selected video encoder. Below are some recommendations:
        ///
        /// The H.264 and HEVC encoders natively support kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange and kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, which should be used with 8-bit 4:2:0 video and full range input respectively; other related pixel formats in CoreVideo/CVPixelBuffer.h are ideal for 4:2:2 and 4:4:4 (and for HEVC, 10-bit). The JPEG encoder on iOS and Apple Silicon macOS natively supports kCVPixelFormatType_422YpCbCr8FullRange. If you need to work in the RGB domain then kCVPixelFormatType_32BGRA is recommended on iOS and macOS.
        ///
        /// Pixel buffers not in a natively supported format will be converted internally prior to encoding when possible. Pixel format conversions within the same range (video or full) are generally faster than conversions between different ranges.
        ///
        /// The ProRes encoders can preserve high bit depth sources, supporting up to 12bits/ch. ProRes 4444 can contain a mathematically lossless alpha channel and it doesn't do any chroma subsampling. This makes ProRes 4444 ideal for quality critical applications. If you are working with 8bit sources ProRes is also a good format to use due to its high image quality. Use either of the recommended pixel formats above. Note that RGB pixel formats by definition have 4:4:4 chroma sampling.
        ///
        /// If you are working with high bit depth sources the following yuv pixel formats are recommended when encoding to ProRes: kCVPixelFormatType_4444AYpCbCr16, kCVPixelFormatType_422YpCbCr16, and kCVPixelFormatType_422YpCbCr10. When working in the RGB domain kCVPixelFormatType_64ARGB is recommended. Scaling and color matching are not currently supported when using AVAssetWriter with any of these high bit depth pixel formats. Please make sure that your track's output settings dictionary specifies the same width and height as the buffers you will be appending. Do not include AVVideoScalingModeKey or AVVideoColorPropertiesKey.
        ///
        /// As of macOS 10.10 and iOS 8.0, this method can be used to add sample buffers that reference existing data in a file instead of containing media data to be appended to the file. This can be used to generate tracks that are not self-contained. In order to append such a sample reference to the track create a CMSampleBufferRef with a NULL dataBuffer and dataReady set to true and set the kCMSampleBufferAttachmentKey_SampleReferenceURL and kCMSampleBufferAttachmentKey_SampleReferenceByteOffset attachments on the sample buffer. Further documentation on how to create such a "sample reference" sample buffer can be found in the description of the kCMSampleBufferAttachmentKey_SampleReferenceURL and kCMSampleBufferAttachmentKey_SampleReferenceByteOffset attachment keys in the CMSampleBuffer documentation.
        ///
        /// Before calling this method, you must ensure that the receiver is attached to an AVAssetWriter via a prior call to -addInput: and that -startWriting has been called on the asset writer. It is an error to invoke this method before starting a session (via -[AVAssetWriter startSessionAtSourceTime:]) or after ending a session (via -[AVAssetWriter endSessionAtSourceTime:]).
        ///
        /// This method throws an exception if the sample buffer's media type does not match the asset writer input's media type.
        ///
        /// - Parameter sampleBuffer: The CMSampleBuffer to be appended.
        ///
        /// - Returns: A BOOL value indicating success of appending the sample buffer. If a result of NO is returned, clients can check the value of AVAssetWriter.status to determine whether the writing operation completed, failed, or was cancelled.  If the status is AVAssetWriterStatusFailed, AVAsset.error will contain an instance of NSError that describes the failure.
        #[unsafe(method(appendSampleBuffer:))]
        #[unsafe(method_family = none)]
        pub unsafe fn appendSampleBuffer(&self, sample_buffer: &CMSampleBuffer) -> bool;

        /// Indicates to the AVAssetWriter that no more buffers will be appended to this input.
        ///
        /// Clients that are monitoring each input's readyForMoreMediaData value must call markAsFinished on an input when they are done appending buffers to it. This is necessary to prevent other inputs from stalling, as they may otherwise wait forever for that input's media data, attempting to complete the ideal interleaving pattern.
        ///
        /// After invoking this method from the serial queue passed to -requestMediaDataWhenReadyOnQueue:usingBlock:, the receiver is guaranteed to issue no more invocations of the block passed to that method. The same is true of -respondToEachPassDescriptionOnQueue:usingBlock:.
        ///
        /// Before calling this method, you must ensure that the receiver is attached to an AVAssetWriter via a prior call to -addInput: and that -startWriting has been called on the asset writer.
        #[unsafe(method(markAsFinished))]
        #[unsafe(method_family = none)]
        pub unsafe fn markAsFinished(&self);
    );
}

/// AVAssetWriterInputLanguageProperties.
impl AVAssetWriterInput {
    extern_methods!(
        /// Indicates the language to associate with the track corresponding to the receiver, as an ISO 639-2/T language code; can be nil.
        ///
        /// Also see extendedLanguageTag below.
        ///
        /// This property cannot be set after writing on the receiver's AVAssetWriter has started.
        ///
        /// This property throws an exception if a language code is set which does not conform to the ISO 639-2/T language codes.
        #[unsafe(method(languageCode))]
        #[unsafe(method_family = none)]
        pub unsafe fn languageCode(&self) -> Option<Retained<NSString>>;

        /// Setter for [`languageCode`][Self::languageCode].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setLanguageCode:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setLanguageCode(&self, language_code: Option<&NSString>);

        /// Indicates the language tag to associate with the track corresponding to the receiver, as an IETF BCP 47 (RFC 4646) language identifier; can be nil.
        ///
        /// Extended language tags are normally set only when an ISO 639-2/T language code by itself is ambiguous, as in cases in which media data should be distinguished not only by language but also by the regional dialect in use or the writing system employed.
        ///
        /// This property cannot be set after writing on the receiver's AVAssetWriter has started.
        ///
        /// This property throws an exception if an extended language tag is set which does not conform to the IETF BCP 47 (RFC 4646) language identifiers.
        #[unsafe(method(extendedLanguageTag))]
        #[unsafe(method_family = none)]
        pub unsafe fn extendedLanguageTag(&self) -> Option<Retained<NSString>>;

        /// Setter for [`extendedLanguageTag`][Self::extendedLanguageTag].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setExtendedLanguageTag:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setExtendedLanguageTag(&self, extended_language_tag: Option<&NSString>);
    );
}

/// AVAssetWriterInputPropertiesForVisualCharacteristic.
impl AVAssetWriterInput {
    extern_methods!(
        #[cfg(feature = "objc2-core-foundation")]
        /// The size specified in the output file as the natural dimensions of the visual media data for display purposes.
        ///
        /// If the default value, CGSizeZero, is specified, the naturalSize of the track corresponding to the receiver is set according to dimensions indicated by the format descriptions that are ultimately written to the output track.
        ///
        /// This property cannot be set after writing on the receiver's AVAssetWriter has started.
        #[unsafe(method(naturalSize))]
        #[unsafe(method_family = none)]
        pub unsafe fn naturalSize(&self) -> CGSize;

        #[cfg(feature = "objc2-core-foundation")]
        /// Setter for [`naturalSize`][Self::naturalSize].
        #[unsafe(method(setNaturalSize:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setNaturalSize(&self, natural_size: CGSize);

        #[cfg(feature = "objc2-core-foundation")]
        /// The transform specified in the output file as the preferred transformation of the visual media data for display purposes.
        ///
        /// If no value is specified, the identity transform is used.
        ///
        /// This property cannot be set after writing on the receiver's AVAssetWriter has started.
        #[unsafe(method(transform))]
        #[unsafe(method_family = none)]
        pub unsafe fn transform(&self) -> CGAffineTransform;

        #[cfg(feature = "objc2-core-foundation")]
        /// Setter for [`transform`][Self::transform].
        #[unsafe(method(setTransform:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setTransform(&self, transform: CGAffineTransform);
    );
}

/// AVAssetWriterInputPropertiesForAudibleCharacteristic.
impl AVAssetWriterInput {
    extern_methods!(
        /// The preferred volume level to be stored in the output file.
        ///
        /// The value for this property should typically be in the range of 0.0 to 1.0. The default value is 1.0, which is equivalent to a "normal" volume level for audio media type. For all other media types the default value is 0.0.
        ///
        /// This property cannot be set after writing on the receiver's AVAssetWriter has started.
        #[unsafe(method(preferredVolume))]
        #[unsafe(method_family = none)]
        pub unsafe fn preferredVolume(&self) -> c_float;

        /// Setter for [`preferredVolume`][Self::preferredVolume].
        #[unsafe(method(setPreferredVolume:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPreferredVolume(&self, preferred_volume: c_float);
    );
}

/// [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avassetwriterinputmediadatalocation?language=objc)
// NS_TYPED_ENUM
pub type AVAssetWriterInputMediaDataLocation = NSString;

extern "C" {
    /// Indicates that the media data should be interleaved with all other media data with this constant.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avassetwriterinputmediadatalocationinterleavedwithmainmediadata?language=objc)
    pub static AVAssetWriterInputMediaDataLocationInterleavedWithMainMediaData:
        &'static AVAssetWriterInputMediaDataLocation;
}

extern "C" {
    /// Indicates that the media data should be laid out before all the media data with AVAssetWriterInputMediaDataLocationInterleavedWithMainMediaData and not be interleaved.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avassetwriterinputmediadatalocationbeforemainmediadatanotinterleaved?language=objc)
    pub static AVAssetWriterInputMediaDataLocationBeforeMainMediaDataNotInterleaved:
        &'static AVAssetWriterInputMediaDataLocation;
}

extern "C" {
    /// Indicates that there may be large segments of time without any media data from this track. When mediaDataLocation is set to this value, AVAssetWriter will interleave the media data, but will not wait for media data from this track to achieve tight interleaving with other tracks.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avassetwriterinputmediadatalocationsparselyinterleavedwithmainmediadata?language=objc)
    pub static AVAssetWriterInputMediaDataLocationSparselyInterleavedWithMainMediaData:
        &'static AVAssetWriterInputMediaDataLocation;
}

/// AVAssetWriterInputFileTypeSpecificProperties.
impl AVAssetWriterInput {
    extern_methods!(
        /// For file types that support enabled and disabled tracks, such as QuickTime Movie files, specifies whether the track corresponding to the receiver should be enabled by default for playback and processing. The default value is YES.
        ///
        /// When an input group is added to an AVAssetWriter (see -[AVAssetWriter addInputGroup:]), the value of marksOutputTrackAsEnabled will automatically be set to YES for the default input and set to NO for all of the other inputs in the group. In this case, if a new value is set on this property then an exception will be raised.
        ///
        /// This property cannot be set after writing on the receiver's AVAssetWriter has started.
        ///
        /// This property throws an exception if a value is set on an asset writer input that is contained in an input group.
        #[unsafe(method(marksOutputTrackAsEnabled))]
        #[unsafe(method_family = none)]
        pub unsafe fn marksOutputTrackAsEnabled(&self) -> bool;

        /// Setter for [`marksOutputTrackAsEnabled`][Self::marksOutputTrackAsEnabled].
        #[unsafe(method(setMarksOutputTrackAsEnabled:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMarksOutputTrackAsEnabled(&self, marks_output_track_as_enabled: bool);

        #[cfg(feature = "objc2-core-media")]
        /// For file types that support media time scales, such as QuickTime Movie files, specifies the media time scale to be used.
        ///
        /// The default value is 0, which indicates that the receiver should choose a convenient value, if applicable. It is an error to set a value other than 0 if the receiver has media type AVMediaTypeAudio.
        ///
        /// This property cannot be set after writing has started.
        ///
        /// This property throws an exception if a value is set on an asset writer input with media type AVMediaTypeAudio.
        #[unsafe(method(mediaTimeScale))]
        #[unsafe(method_family = none)]
        pub unsafe fn mediaTimeScale(&self) -> CMTimeScale;

        #[cfg(feature = "objc2-core-media")]
        /// Setter for [`mediaTimeScale`][Self::mediaTimeScale].
        #[unsafe(method(setMediaTimeScale:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMediaTimeScale(&self, media_time_scale: CMTimeScale);

        #[cfg(feature = "objc2-core-media")]
        /// For file types that support media chunk duration, such as QuickTime Movie files, specifies the duration to be used for each chunk of sample data in the output file.
        ///
        /// Chunk duration can influence the granularity of the I/O performed when reading a media file, e.g. during playback. A larger chunk duration can result in fewer reads from disk, at the potential expense of a higher memory footprint.
        ///
        /// A "chunk" contains one or more samples. The total duration of the samples in a chunk is no greater than this preferred chunk duration, or the duration of a single sample if the sample's duration is greater than this preferred chunk duration.
        ///
        /// The default value is kCMTimeInvalid, which means that the receiver will choose an appropriate default value.
        ///
        /// This property cannot be set after -startWriting has been called on the receiver.
        ///
        /// This property throws an exception if a duration is set which is non-numeric or non-positive (see CMTIME_IS_NUMERIC).
        #[unsafe(method(preferredMediaChunkDuration))]
        #[unsafe(method_family = none)]
        pub unsafe fn preferredMediaChunkDuration(&self) -> CMTime;

        #[cfg(feature = "objc2-core-media")]
        /// Setter for [`preferredMediaChunkDuration`][Self::preferredMediaChunkDuration].
        #[unsafe(method(setPreferredMediaChunkDuration:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPreferredMediaChunkDuration(&self, preferred_media_chunk_duration: CMTime);

        /// For file types that support media chunk alignment, such as QuickTime Movie files, specifies the boundary for media chunk alignment in bytes (e.g. 512).
        ///
        /// The default value is 0, which means that the receiver will choose an appropriate default value. A value of 1 implies that no padding should be used to achieve a particular chunk alignment. It is an error to set a negative value for chunk alignment.
        ///
        /// This property cannot be set after -startWriting has been called on the receiver.
        #[unsafe(method(preferredMediaChunkAlignment))]
        #[unsafe(method_family = none)]
        pub unsafe fn preferredMediaChunkAlignment(&self) -> NSInteger;

        /// Setter for [`preferredMediaChunkAlignment`][Self::preferredMediaChunkAlignment].
        #[unsafe(method(setPreferredMediaChunkAlignment:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPreferredMediaChunkAlignment(
            &self,
            preferred_media_chunk_alignment: NSInteger,
        );

        /// For file types that support writing sample references, such as QuickTime Movie files, specifies the base URL sample references are relative to.
        ///
        /// If the value of this property can be resolved as an absolute URL, the sample locations written to the file when appending sample references will be relative to this URL. The URL must point to a location that is in a directory that is a parent of the sample reference location.
        ///
        /// Usage example:
        ///
        /// Setting the sampleReferenceBaseURL property to "file:///User/johnappleseed/Movies/" and appending sample buffers with the kCMSampleBufferAttachmentKey_SampleReferenceURL attachment set to "file:///User/johnappleseed/Movies/data/movie1.mov" will cause the sample reference "data/movie1.mov" to be written to the movie.
        ///
        /// If the value of the property cannot be resolved as an absolute URL or if it points to a location that is not in a parent directory of the sample reference location, the location referenced in the sample buffer will be written unmodified.
        ///
        /// The default value is nil, which means that the location referenced in the sample buffer will be written unmodified.
        ///
        /// This property cannot be set after -startWriting has been called on the receiver.
        #[unsafe(method(sampleReferenceBaseURL))]
        #[unsafe(method_family = none)]
        pub unsafe fn sampleReferenceBaseURL(&self) -> Option<Retained<NSURL>>;

        /// Setter for [`sampleReferenceBaseURL`][Self::sampleReferenceBaseURL].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setSampleReferenceBaseURL:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setSampleReferenceBaseURL(&self, sample_reference_base_url: Option<&NSURL>);

        /// Specifies where the media data will be laid out and whether the media data will be interleaved as the main media data.
        ///
        /// If this value is set to AVAssetWriterInputMediaDataLocationBeforeMainMediaDataNotInterleaved, AVAssetWriter tries to write the media data for this track before all the media data for AVAssetWriterInputs with this property set to AVAssetWriterInputMediaDataLocationInterleavedWithMainMediaData.
        ///
        /// Use of this property is recommended for optimizing tracks that contain a small amount of data that is needed all at once, independent of playback time, such as chapter name tracks and chapter image tracks.
        /// Keep it set to AVAssetWriterInputMediaDataLocationInterleavedWithMainMediaData for tracks whose media data that's needed only as its presentation time is approaching and, when multiple inputs are present that supply media data that will be played concurrently, should be interleaved for optimal access.
        ///
        /// For file types that support preloading media data such as QuickTime movie file, if this value is set to AVAssetWriterInputMediaDataLocationBeforeMainMediaDataNotInterleaved, AVAssetWriter will write an indication such as 'load' atom that the whole media data should be preloaded.
        ///
        /// The default value is AVAssetWriterInputMediaDataLocationInterleavedWithMainMediaData, which means that the receiver will not write the indication and that the media data will be interleaved.
        ///
        /// This property cannot be set after -startWriting has been called on the receiver.
        #[unsafe(method(mediaDataLocation))]
        #[unsafe(method_family = none)]
        pub unsafe fn mediaDataLocation(&self) -> Retained<AVAssetWriterInputMediaDataLocation>;

        /// Setter for [`mediaDataLocation`][Self::mediaDataLocation].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setMediaDataLocation:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMediaDataLocation(
            &self,
            media_data_location: &AVAssetWriterInputMediaDataLocation,
        );
    );
}

/// AVAssetWriterInputTrackAssociations.
impl AVAssetWriterInput {
    extern_methods!(
        /// Tests whether an association between the tracks corresponding to a pair of inputs is valid.
        ///
        /// If the type of association requires tracks of specific media types that don't match the media types of the inputs, or if the output file type does not support track associations, -canAddTrackAssociationWithTrackOfInput:type: will return NO.
        ///
        /// - Parameter input: The instance of AVAssetWriterInput with a corresponding track to associate with track corresponding with the receiver.
        /// - Parameter trackAssociationType: The type of track association to test. Common track association types, such as AVTrackAssociationTypeTimecode, are defined in AVAssetTrack.h.
        #[unsafe(method(canAddTrackAssociationWithTrackOfInput:type:))]
        #[unsafe(method_family = none)]
        pub unsafe fn canAddTrackAssociationWithTrackOfInput_type(
            &self,
            input: &AVAssetWriterInput,
            track_association_type: &NSString,
        ) -> bool;

        /// Associates the track corresponding to the specified input with the track corresponding with the receiver.
        ///
        /// If the type of association requires tracks of specific media types that don't match the media types of the inputs, or if the output file type does not support track associations, an NSInvalidArgumentException is raised.
        ///
        /// Track associations cannot be added after writing on the receiver's AVAssetWriter has started.
        ///
        /// This method throws an exception if the input and track association type cannot be added (see -canAddTrackAssociationWithTrackOfInput:type:).
        ///
        /// - Parameter input: The instance of AVAssetWriterInput with a corresponding track to associate with track corresponding to the receiver.
        /// - Parameter trackAssociationType: The type of track association to add. Common track association types, such as AVTrackAssociationTypeTimecode, are defined in AVAssetTrack.h.
        #[unsafe(method(addTrackAssociationWithTrackOfInput:type:))]
        #[unsafe(method_family = none)]
        pub unsafe fn addTrackAssociationWithTrackOfInput_type(
            &self,
            input: &AVAssetWriterInput,
            track_association_type: &NSString,
        );
    );
}

/// AVAssetWriterInputMultiPass.
impl AVAssetWriterInput {
    extern_methods!(
        /// Indicates whether the input should attempt to encode the source media data using multiple passes.
        ///
        /// The input may be able to achieve higher quality and/or lower data rate by performing multiple passes over the source media. It does this by analyzing the media data that has been appended and re-encoding certain segments with different parameters. In order to do this re-encoding, the media data for these segments must be appended again. See -markCurrentPassAsFinished and the property currentPassDescription for the mechanism by which the input nominates segments for re-appending.
        ///
        /// When the value of this property is YES, the value of readyForMoreMediaData for other inputs attached to the same AVAssetWriter may be NO more often and/or for longer periods of time. In particular, the value of readyForMoreMediaData for inputs that do not (or cannot) perform multiple passes may start out as NO after -[AVAssetWriter startWriting] has been called and may not change to YES until after all multi-pass inputs have completed their final pass.
        ///
        /// When the value of this property is YES, the input may store data in one or more temporary files before writing compressed samples to the output file. Use the AVAssetWriter property directoryForTemporaryFiles if you need to control the location of temporary file writing.
        ///
        /// The default value is NO, meaning that no additional analysis will occur and no segments will be re-encoded. Not all asset writer input configurations (for example, inputs configured with certain media types or to use certain encoders) can benefit from performing multiple passes over the source media. To determine whether the selected encoder can perform multiple passes, query the value of canPerformMultiplePasses after calling -startWriting.
        ///
        /// For best results, do not set both this property and expectsMediaDataInRealTime to YES.
        ///
        /// This property cannot be set after writing on the receiver's AVAssetWriter has started.
        #[unsafe(method(performsMultiPassEncodingIfSupported))]
        #[unsafe(method_family = none)]
        pub unsafe fn performsMultiPassEncodingIfSupported(&self) -> bool;

        /// Setter for [`performsMultiPassEncodingIfSupported`][Self::performsMultiPassEncodingIfSupported].
        #[unsafe(method(setPerformsMultiPassEncodingIfSupported:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPerformsMultiPassEncodingIfSupported(
            &self,
            performs_multi_pass_encoding_if_supported: bool,
        );

        /// Indicates whether the input might perform multiple passes over appended media data.
        ///
        /// When the value for this property is YES, your source for media data should be configured for random access. After appending all of the media data for the current pass (as specified by the currentPassDescription property), call -markCurrentPassAsFinished to start the process of determining whether additional passes are needed. Note that it is still possible in this case for the input to perform only the initial pass, if it determines that there will be no benefit to performing multiple passes.
        ///
        /// When the value for this property is NO, your source for media data only needs to support sequential access. In this case, append all of the source media once and call -markAsFinished.
        ///
        /// In the default configuration of AVAssetWriterInput, the value for this property will be NO. Currently the only way for this property to become YES is when performsMultiPassEncodingIfSupported has been set to YES. The final value will be available after -startWriting is called, when a specific encoder has been choosen.
        ///
        /// This property is key-value observable.
        #[unsafe(method(canPerformMultiplePasses))]
        #[unsafe(method_family = none)]
        pub unsafe fn canPerformMultiplePasses(&self) -> bool;

        /// Provides an object that describes the requirements, such as source time ranges to append or re-append, for the current pass.
        ///
        /// If the value of this property is nil, it means there is no request to be fulfilled and -markAsFinished should be called on the asset writer input.
        ///
        /// During the first pass, the request will contain a single time range from zero to positive infinity, indicating that all media from the source should be appended. This will also be true when canPerformMultiplePasses is NO, in which case only one pass will be performed.
        ///
        /// The value of this property will be nil before -startWriting is called on the attached asset writer. It will transition to an initial non-nil value during the call to -startWriting. After that, the value of this property will change only after a call to -markCurrentPassAsFinished. For an easy way to be notified at the beginning of each pass, see -respondToEachPassDescriptionOnQueue:usingBlock:.
        ///
        /// This property is key-value observable. Observers should not assume that they will be notified of changes on a specific thread.
        #[unsafe(method(currentPassDescription))]
        #[unsafe(method_family = none)]
        pub unsafe fn currentPassDescription(
            &self,
        ) -> Option<Retained<AVAssetWriterInputPassDescription>>;

        #[cfg(feature = "dispatch2")]
        /// Instructs the receiver to invoke a client-supplied block whenever a new pass has begun.
        ///
        /// A typical block passed to this method will perform the following steps:
        ///
        /// 1. Query the value of the receiver's currentPassDescription property and reconfigure the source of media data (e.g. AVAssetReader) accordingly
        /// 2. Call -requestMediaDataWhenReadyOnQueue:usingBlock: to begin appending data for the current pass
        /// 3. Exit
        ///
        /// When all media data has been appended for the current request, call -markCurrentPassAsFinished to begin the process of determining whether an additional pass is warranted. If an additional pass is warranted, the block passed to this method will be invoked to begin the next pass. If no additional passes are needed, the block passed to this method will be invoked one final time so the client can invoke -markAsFinished in response to the value of currentPassDescription becoming nil.
        ///
        /// Before calling this method, you must ensure that the receiver is attached to an AVAssetWriter via a prior call to -addInput: and that -startWriting has been called on the asset writer.
        ///
        /// This method throws an exception if called more than once.
        ///
        /// - Parameter queue: The queue on which the block should be invoked.
        /// - Parameter block: A block the receiver should invoke whenever a new pass has begun.
        ///
        /// # Safety
        ///
        /// - `queue` possibly has additional threading requirements.
        /// - `block` must be a valid pointer.
        #[unsafe(method(respondToEachPassDescriptionOnQueue:usingBlock:))]
        #[unsafe(method_family = none)]
        pub unsafe fn respondToEachPassDescriptionOnQueue_usingBlock(
            &self,
            queue: &DispatchQueue,
            block: dispatch_block_t,
        );

        /// Instructs the receiver to analyze the media data that has been appended and determine whether the results could be improved by re-encoding certain segments.
        ///
        /// When the value of canPerformMultiplePasses is YES, call this method after you have appended all of your media data. After the receiver analyzes whether an additional pass is warranted, the value of currentPassDescription will change (usually asynchronously) to describe how to set up for the next pass. Although it is possible to use key-value observing to determine when the value of currentPassDescription has changed, it is typically more convenient to invoke -respondToEachPassDescriptionOnQueue:usingBlock: in order to start the work for each pass.
        ///
        /// After re-appending the media data for all of the time ranges of the new pass, call this method again to determine whether additional segments should be re-appended in another pass.
        ///
        /// Calling this method effectively cancels any previous invocation of -requestMediaDataWhenReadyOnQueue:usingBlock:, meaning that -requestMediaDataWhenReadyOnQueue:usingBlock: can be invoked again for each new pass. -respondToEachPassDescriptionOnQueue:usingBlock: provides a convenient way to consolidate these invocations in your code.
        ///
        /// After each pass, you have the option of keeping the most recent results by calling -markAsFinished instead of this method. If the value of currentPassDescription is nil at the beginning of a pass, call -markAsFinished to tell the receiver to not expect any further media data.
        ///
        /// If the value of canPerformMultiplePasses is NO, the value of currentPassDescription will immediately become nil after calling this method.
        ///
        /// Before calling this method, you must ensure that the receiver is attached to an AVAssetWriter via a prior call to -addInput: and that -startWriting has been called on the asset writer.
        #[unsafe(method(markCurrentPassAsFinished))]
        #[unsafe(method_family = none)]
        pub unsafe fn markCurrentPassAsFinished(&self);
    );
}

extern_class!(
    /// Defines an interface for querying information about the requirements of the current pass, such as the time ranges of media data to append.
    ///
    /// Subclasses of this type that are used from Swift must fulfill the requirements of a Sendable type.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avassetwriterinputpassdescription?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct AVAssetWriterInputPassDescription;
);

unsafe impl Send for AVAssetWriterInputPassDescription {}

unsafe impl Sync for AVAssetWriterInputPassDescription {}

extern_conformance!(
    unsafe impl NSObjectProtocol for AVAssetWriterInputPassDescription {}
);

impl AVAssetWriterInputPassDescription {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;

        /// An NSArray of NSValue objects wrapping CMTimeRange structures, each representing one source time range.
        ///
        /// The value of this property is suitable for using as a parameter for -[AVAssetReaderOutput resetForReadingTimeRanges:].
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(sourceTimeRanges))]
        #[unsafe(method_family = none)]
        pub unsafe fn sourceTimeRanges(&self) -> Retained<NSArray<NSValue>>;
    );
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avassetwriterinputpixelbufferadaptor?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct AVAssetWriterInputPixelBufferAdaptor;
);

extern_conformance!(
    unsafe impl NSObjectProtocol for AVAssetWriterInputPixelBufferAdaptor {}
);

impl AVAssetWriterInputPixelBufferAdaptor {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;

        /// Creates a new pixel buffer adaptor to receive pixel buffers for writing to the output file.
        ///
        /// In order to take advantage of the improved efficiency of appending buffers created from the adaptor's pixel buffer pool, clients should specify pixel buffer attributes that most closely accommodate the source format of the video frames being appended.
        ///
        /// Pixel buffer attributes keys for the pixel buffer pool are defined in
        /// <CoreVideo
        /// /CVPixelBuffer.h>. To specify the pixel format type, the pixelBufferAttributes dictionary should contain a value for kCVPixelBufferPixelFormatTypeKey. For example, use [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] for 8-bit-per-channel BGRA. See the discussion under appendPixelBuffer:withPresentationTime: for advice on choosing a pixel format.
        ///
        /// Clients that do not need a pixel buffer pool for allocating buffers should set sourcePixelBufferAttributes to nil.
        ///
        /// This method throws an exception if the input is already attached to another asset writer input pixel buffer adaptor or if the input has already started writing (the asset writer has progressed beyond AVAssetWriterStatusUnknown).
        ///
        /// - Parameter input: An instance of AVAssetWriterInput to which the receiver should append pixel buffers. Currently, only asset writer inputs that accept media data of type AVMediaTypeVideo can be used to initialize a pixel buffer adaptor.
        /// - Parameter sourcePixelBufferAttributes: Specifies the attributes of pixel buffers that will be vended by the input's CVPixelBufferPool.
        ///
        /// - Returns: An instance of AVAssetWriterInputPixelBufferAdaptor.
        ///
        /// # Safety
        ///
        /// `source_pixel_buffer_attributes` generic should be of the correct type.
        #[unsafe(method(assetWriterInputPixelBufferAdaptorWithAssetWriterInput:sourcePixelBufferAttributes:))]
        #[unsafe(method_family = none)]
        pub unsafe fn assetWriterInputPixelBufferAdaptorWithAssetWriterInput_sourcePixelBufferAttributes(
            input: &AVAssetWriterInput,
            source_pixel_buffer_attributes: Option<&NSDictionary<NSString, AnyObject>>,
        ) -> Retained<Self>;

        /// Creates a new pixel buffer adaptor to receive pixel buffers for writing to the output file.
        ///
        /// In order to take advantage of the improved efficiency of appending buffers created from the adaptor's pixel buffer pool, clients should specify pixel buffer attributes that most closely accommodate the source format of the video frames being appended.
        ///
        /// Pixel buffer attributes keys for the pixel buffer pool are defined in
        /// <CoreVideo
        /// /CVPixelBuffer.h>. To specify the pixel format type, the pixelBufferAttributes dictionary should contain a value for kCVPixelBufferPixelFormatTypeKey. For example, use [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] for 8-bit-per-channel BGRA. See the discussion under appendPixelBuffer:withPresentationTime: for advice on choosing a pixel format.
        ///
        /// Clients that do not need a pixel buffer pool for allocating buffers should set sourcePixelBufferAttributes to nil.
        ///
        /// This method throws an exception if the input is already attached to another asset writer input pixel buffer adaptor or if the input has already started writing (the asset writer has progressed beyond AVAssetWriterStatusUnknown).
        ///
        /// - Parameter input: An instance of AVAssetWriterInput to which the receiver should append pixel buffers. Currently, only asset writer inputs that accept media data of type AVMediaTypeVideo can be used to initialize a pixel buffer adaptor.
        /// - Parameter sourcePixelBufferAttributes: Specifies the attributes of pixel buffers that will be vended by the input's CVPixelBufferPool.
        ///
        /// - Returns: An instance of AVAssetWriterInputPixelBufferAdaptor.
        ///
        /// # Safety
        ///
        /// `source_pixel_buffer_attributes` generic should be of the correct type.
        #[unsafe(method(initWithAssetWriterInput:sourcePixelBufferAttributes:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithAssetWriterInput_sourcePixelBufferAttributes(
            this: Allocated<Self>,
            input: &AVAssetWriterInput,
            source_pixel_buffer_attributes: Option<&NSDictionary<NSString, AnyObject>>,
        ) -> Retained<Self>;

        /// The asset writer input to which the receiver should append pixel buffers.
        #[unsafe(method(assetWriterInput))]
        #[unsafe(method_family = none)]
        pub unsafe fn assetWriterInput(&self) -> Retained<AVAssetWriterInput>;

        /// The pixel buffer attributes of pixel buffers that will be vended by the receiver's CVPixelBufferPool.
        ///
        /// The value of this property is a dictionary containing pixel buffer attributes keys defined in
        /// <CoreVideo
        /// /CVPixelBuffer.h>.
        #[unsafe(method(sourcePixelBufferAttributes))]
        #[unsafe(method_family = none)]
        pub unsafe fn sourcePixelBufferAttributes(
            &self,
        ) -> Option<Retained<NSDictionary<NSString, AnyObject>>>;

        #[cfg(feature = "objc2-core-video")]
        /// A pixel buffer pool that will vend and efficiently recycle CVPixelBuffer objects that can be appended to the receiver.
        ///
        /// For maximum efficiency, clients should create CVPixelBuffer objects for appendPixelBuffer:withPresentationTime: by using this pool with the CVPixelBufferPoolCreatePixelBuffer() function.
        ///
        /// The value of this property will be NULL before -[AVAssetWriter startWriting] is called on the associated AVAssetWriter object.
        ///
        /// This property is key value observable.
        ///
        /// This property throws an exception if a pixel buffer pool cannot be created with this asset writer input pixel buffer adaptor's source pixel buffer attributes (must specify width, height, and either pixel format or pixel format description).
        #[unsafe(method(pixelBufferPool))]
        #[unsafe(method_family = none)]
        pub unsafe fn pixelBufferPool(&self) -> Option<Retained<CVPixelBufferPool>>;

        #[cfg(all(feature = "objc2-core-media", feature = "objc2-core-video"))]
        /// Appends a pixel buffer to the receiver.
        ///
        /// The receiver will retain the CVPixelBuffer until it is done with it, and then release it. Do not modify a CVPixelBuffer or its contents after you have passed it to this method.
        ///
        /// For optimal performance the format of the pixel buffer should match one of the native formats supported by the selected video encoder. Below are some recommendations:
        ///
        /// The H.264 and HEVC encoders natively support kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange and kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, which should be used with 8-bit 4:2:0 video and full range input respectively; other related pixel formats in CoreVideo/CVPixelBuffer.h are ideal for 4:2:2 and 4:4:4 (and for HEVC, 10-bit). The JPEG encoder on iOS and Apple Silicon macOS natively supports kCVPixelFormatType_422YpCbCr8FullRange. If you need to work in the RGB domain then kCVPixelFormatType_32BGRA is recommended on iOS and macOS.
        ///
        /// Pixel buffers not in a natively supported format will be converted internally prior to encoding when possible. Pixel format conversions within the same range (video or full) are generally faster than conversions between different ranges.
        ///
        /// The ProRes encoders can preserve high bit depth sources, supporting up to 12bits/ch. ProRes 4444 can contain a mathematically lossless alpha channel and it doesn't do any chroma subsampling. This makes ProRes 4444 ideal for quality critical applications. If you are working with 8bit sources ProRes is also a good format to use due to its high image quality. Use either of the recommended pixel formats above. Note that RGB pixel formats by definition have 4:4:4 chroma sampling.
        ///
        /// If you are working with high bit depth sources the following yuv pixel formats are recommended when encoding to ProRes: kCVPixelFormatType_4444AYpCbCr16, kCVPixelFormatType_422YpCbCr16, and kCVPixelFormatType_422YpCbCr10. When working in the RGB domain kCVPixelFormatType_64ARGB is recommended. Scaling and color matching are not currently supported when using AVAssetWriter with any of these high bit depth pixel formats. Please make sure that your track's output settings dictionary specifies the same width and height as the buffers you will be appending. Do not include AVVideoScalingModeKey or AVVideoColorPropertiesKey.
        ///
        /// Before calling this method, you must ensure that the input that underlies the receiver is attached to an AVAssetWriter via a prior call to -addInput: and that -startWriting has been called on the asset writer. It is an error to invoke this method before starting a session (via -[AVAssetWriter startSessionAtSourceTime:]) or after ending a session (via -[AVAssetWriter endSessionAtSourceTime:]).
        ///
        /// This method throws an exception if the presentation time is is non-numeric (see CMTIME_IS_NUMERIC) or if "readyForMoreMediaData" is NO.
        ///
        /// - Parameter pixelBuffer: The CVPixelBuffer to be appended.
        /// - Parameter presentationTime: The presentation time for the pixel buffer to be appended. This time will be considered relative to the time passed to -[AVAssetWriter startSessionAtSourceTime:] to determine the timing of the frame in the output file.
        ///
        /// - Returns: A BOOL value indicating success of appending the pixel buffer. If a result of NO is returned, clients can check the value of AVAssetWriter.status to determine whether the writing operation completed, failed, or was cancelled.  If the status is AVAssetWriterStatusFailed, AVAsset.error will contain an instance of NSError that describes the failure.
        #[unsafe(method(appendPixelBuffer:withPresentationTime:))]
        #[unsafe(method_family = none)]
        pub unsafe fn appendPixelBuffer_withPresentationTime(
            &self,
            pixel_buffer: &CVPixelBuffer,
            presentation_time: CMTime,
        ) -> bool;
    );
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avassetwriterinputtaggedpixelbuffergroupadaptor?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct AVAssetWriterInputTaggedPixelBufferGroupAdaptor;
);

extern_conformance!(
    unsafe impl NSObjectProtocol for AVAssetWriterInputTaggedPixelBufferGroupAdaptor {}
);

impl AVAssetWriterInputTaggedPixelBufferGroupAdaptor {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;

        /// Creates a new tagged buffer adaptor to receive tagged buffer groups for writing to the output file.
        ///
        /// In order to take advantage of the improved efficiency of appending buffers created from the adaptor's pixel buffer pool, clients should specify pixel buffer attributes that most closely accommodate the source format of the video frames being appended.
        ///
        /// Pixel buffer attributes keys for the pixel buffer pool are defined in
        /// <CoreVideo
        /// /CVPixelBuffer.h>. To specify the pixel format type, the pixelBufferAttributes dictionary should contain a value for kCVPixelBufferPixelFormatTypeKey. For example, use [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] for 8-bit-per-channel BGRA. See the discussion under appendPixelBuffer:withPresentationTime: for advice on choosing a pixel format.
        ///
        /// Clients that do not need a pixel buffer pool for allocating buffers should set sourcePixelBufferAttributes to nil.
        ///
        /// This method throws an exception if the input is already attached to another asset writer input tagged buffer group adaptor or if the input has already started writing (the asset writer has progressed beyond AVAssetWriterStatusUnknown).
        ///
        /// - Parameter input: An instance of AVAssetWriterInput to which the receiver should append tagged buffer groups. Currently, only asset writer inputs that accept media data of type AVMediaTypeVideo can be used to initialize a tagged buffer adaptor.
        /// - Parameter sourcePixelBufferAttributes: Specifies the attributes of pixel buffers of tagged buffer groups that will be vended by the input's CVPixelBufferPool.
        ///
        /// - Returns: An instance of AVAssetWriterInputTaggedPixelBufferGroupAdaptor.
        ///
        /// # Safety
        ///
        /// `source_pixel_buffer_attributes` generic should be of the correct type.
        #[unsafe(method(assetWriterInputTaggedPixelBufferGroupAdaptorWithAssetWriterInput:sourcePixelBufferAttributes:))]
        #[unsafe(method_family = none)]
        pub unsafe fn assetWriterInputTaggedPixelBufferGroupAdaptorWithAssetWriterInput_sourcePixelBufferAttributes(
            input: &AVAssetWriterInput,
            source_pixel_buffer_attributes: Option<&NSDictionary<NSString, AnyObject>>,
        ) -> Retained<Self>;

        /// Creates a new tagged buffer group adaptor to receive tagged buffer groups for writing to the output file.
        ///
        /// In order to take advantage of the improved efficiency of appending buffers created from the adaptor's pixel buffer pool, clients should specify pixel buffer attributes that most closely accommodate the source format of the video frames of tagged buffer groups being appended.
        ///
        /// Pixel buffer attributes keys for the pixel buffer pool are defined in
        /// <CoreVideo
        /// /CVPixelBuffer.h>. To specify the pixel format type, the pixelBufferAttributes dictionary should contain a value for kCVPixelBufferPixelFormatTypeKey. For example, use [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] for 8-bit-per-channel BGRA. See the discussion under appendPixelBuffer:withPresentationTime: in AVAssetWriterInputPixelBufferAdaptor for advice on choosing a pixel format.
        ///
        /// Clients that do not need a pixel buffer pool for allocating buffers should set sourcePixelBufferAttributes to nil.
        ///
        /// It is an error to initialize an instance of AVAssetWriterInputTaggedPixelBufferGroupAdaptor with an asset writer input that is already attached to another instance of AVAssetWriterInputTaggedPixelBufferGroupAdaptor. It is also an error to initialize an instance of AVAssetWriterInputTaggedPixelBufferGroupAdaptor with an asset writer input whose asset writer has progressed beyond AVAssetWriterStatusUnknown.
        ///
        /// - Parameter input: An instance of AVAssetWriterInput to which the receiver should append tagged buffer groups. In addition to the pixel buffer adaptor, asset writer inputs with media data of type AVMediaTypeVideo can be used to initialize a tagged buffer group adaptor.
        /// - Parameter sourcePixelBufferAttributes: Specifies the attributes of pixel buffers of tagged buffer groups that will be vended by the input's CVPixelBufferPool.
        ///
        /// - Returns: An instance of AVAssetWriterInputTaggedPixelBufferGroupAdaptor.
        ///
        /// # Safety
        ///
        /// `source_pixel_buffer_attributes` generic should be of the correct type.
        #[unsafe(method(initWithAssetWriterInput:sourcePixelBufferAttributes:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithAssetWriterInput_sourcePixelBufferAttributes(
            this: Allocated<Self>,
            input: &AVAssetWriterInput,
            source_pixel_buffer_attributes: Option<&NSDictionary<NSString, AnyObject>>,
        ) -> Retained<Self>;

        /// The asset writer input to which the receiver should append tagged buffer groups.
        #[unsafe(method(assetWriterInput))]
        #[unsafe(method_family = none)]
        pub unsafe fn assetWriterInput(&self) -> Retained<AVAssetWriterInput>;

        /// The pixel buffer attributes of pixel buffers that will be vended by the receiver's CVPixelBufferPool.
        ///
        /// The value of this property is a dictionary containing pixel buffer attributes keys defined in
        /// <CoreVideo
        /// /CVPixelBuffer.h>.
        #[unsafe(method(sourcePixelBufferAttributes))]
        #[unsafe(method_family = none)]
        pub unsafe fn sourcePixelBufferAttributes(
            &self,
        ) -> Option<Retained<NSDictionary<NSString, AnyObject>>>;

        #[cfg(feature = "objc2-core-video")]
        /// A pixel buffer pool that will vend and efficiently recycle CVPixelBuffer objects of tagged buffer groups that can be appended to the receiver.
        ///
        /// For maximum efficiency, clients should create CVPixelBuffer objects of tagged buffer groups for appendTaggedPixelBufferGroup:withPresentationTime: by using this pool with the CVPixelBufferPoolCreatePixelBuffer() function.
        ///
        /// The value of this property will be NULL before -[AVAssetWriter startWriting] is called on the associated AVAssetWriter object. Clients should read this property after -[AVAssetWriter startWriting] calling to get a non-NULL value.
        ///
        /// This property is not key value observable.
        #[unsafe(method(pixelBufferPool))]
        #[unsafe(method_family = none)]
        pub unsafe fn pixelBufferPool(&self) -> Option<Retained<CVPixelBufferPool>>;

        #[cfg(feature = "objc2-core-media")]
        /// Appends a tagged buffer group to the receiver.
        ///
        /// The receiver will retain the CMTaggedBufferGroup until it is done with it, and then release it. Do not modify a CMTaggedBufferGroup or its contents after you have passed it to this method.
        ///
        /// Before calling this method, you must ensure that the input that underlies the receiver is attached to an AVAssetWriter via a prior call to -addInput: and that -startWriting has been called on the asset writer. It is an error to invoke this method before starting a session (via -[AVAssetWriter startSessionAtSourceTime:]) or after ending a session (via -[AVAssetWriter endSessionAtSourceTime:]).
        ///
        /// In an AVAssetWriterInput instance creation with AVMediaTypeVideo, kVTCompressionPropertyKey_MVHEVCVideoLayerIDs key must be specified as part of the dictionary given for AVVideoCompressionPropertiesKey. It sets video layer IDs to a target multi-image video encoder. This method checks the values for kCMTagCategory_VideoLayerID tag in tag collections of taggedPixelBufferGroup over the array values for kVTCompressionPropertyKey_MVHEVCVideoLayerIDs key. An NSInvalidArgumentException will be raised if the video layer IDs mismatch between the value of kVTCompressionPropertyKey_MVHEVCVideoLayerIDs in the AVVideoCompressionPropertiesKey sub-dictionary of the input's outputSettings property and tag collections of taggedPixelBufferGroup.
        ///
        /// Below is a sample code sketch focusing on data flow that illustrates how you might append a taggedPixelBufferGroup instance.
        /// ```objc
        /// // Set up an AVAssetWriterInput and AVAssetWriterInputTaggedPixelBufferGroupAdaptor instance
        /// AVAssetWriterInput *assetWriterInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:
        /// @
        /// {
        /// ..,
        /// AVVideoCompressionPropertiesKey:
        /// @
        /// { (NSString *)kVTCompressionPropertyKey_MVHEVCVideoLayerIDs : .. }}];
        ///
        /// AVAssetWriterInputTaggedPixelBufferGroupAdaptor *assetWriterInputAdaptor = [[AVAssetWriterInputTaggedPixelBufferGroupAdaptor alloc] initWithAssetWriterInput:assetWriterInput ..];
        /// ```
        /// Later, when the writer input is ready for more media data, create and append a tagged buffer group containing one or more pixel buffers and the exact tag values associated with kCMTagCategory_VideoLayerID being specified via kVTCompressionPropertyKey_MVHEVCVideoLayerIDs.
        /// ```objc
        /// // Set up tag collection buffers
        /// CMTag tags[] = CMTagMakeWithSInt64Value(kCMTagCategory_VideoLayerID, ..);
        /// CMItemCount tagCount = sizeof(tags) / sizeof(tags[0]);
        /// CMTagCollectionCreate(.., tags, tagCount,
        /// &tagCollection
        /// );
        /// CFArrayAppendValue(tagCollectionArray, tagCollection);
        ///
        /// // Set up pixel buffers
        /// CVPixelBufferPoolCreatePixelBuffer(..,
        /// &pixelBuffer
        /// );
        /// CFArrayAppendValue(pixelBufferArray, pixelBuffer);
        ///
        /// // Append a CMTaggedBufferGroupRef instance to asset writer input
        /// CMTaggedBufferGroupCreate(.., tagCollectionArray, pixelBufferArray,
        /// &taggedBufferGroup
        /// );
        /// [assetWriterInputAdaptor appendTaggedPixelBufferGroup:taggedBufferGroup ..];
        /// ```
        /// - Parameter taggedPixelBufferGroup: The CMTaggedBufferGroup to be appended. All of the buffers in taggedPixelBufferGroup should be CVPixelBuffers, and they should correspond to tag collections that contain kCMTagCategory_VideoLayerID values matching the list set using kVTCompressionPropertyKey_MVHEVCVideoLayerIDs. The pixel buffers should be IOSurface-backed.
        /// - Parameter presentationTime: The presentation time for the tagged buffer group to be appended. This time will be considered relative to the time passed to -[AVAssetWriter startSessionAtSourceTime:] to determine the timing of the frame in the output file.
        ///
        /// - Returns: A BOOL value indicating success of appending the tagged buffer group. If a result of NO is returned, clients can check the value of AVAssetWriter.status to determine whether the writing operation completed, failed, or was cancelled. If the status is AVAssetWriterStatusFailed, AVAssetWriter.error will contain an instance of NSError that describes the failure.
        #[unsafe(method(appendTaggedPixelBufferGroup:withPresentationTime:))]
        #[unsafe(method_family = none)]
        pub unsafe fn appendTaggedPixelBufferGroup_withPresentationTime(
            &self,
            tagged_pixel_buffer_group: &CMTaggedBufferGroup,
            presentation_time: CMTime,
        ) -> bool;
    );
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avassetwriterinputmetadataadaptor?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct AVAssetWriterInputMetadataAdaptor;
);

extern_conformance!(
    unsafe impl NSObjectProtocol for AVAssetWriterInputMetadataAdaptor {}
);

impl AVAssetWriterInputMetadataAdaptor {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;

        /// Creates a new timed metadata group adaptor to receive instances of AVTimedMetadataGroup for writing to the output file.
        ///
        /// The instance of AVAssetWriterInput passed in to this method must have been created with a format hint indicating all possible combinations of identifier (or, alternatively, key and keySpace), dataType, and extendedLanguageTag that will be appended to the metadata adaptor. It is an error to append metadata items not represented in the input's format hint.
        ///
        /// This method throws an exception for any of the following reasons:
        /// - input is already attached to another instance of AVAssetWriterInputMetadataAdaptor
        /// - input's asset writer has already started writing (progressed beyond AVAssetWriterStatusUnknown)
        /// - input's asset writer does not carry a source format hint
        /// - input's source format hint media subtype is not kCMMetadataFormatType_Boxed
        ///
        /// - Parameter input: An instance of AVAssetWriterInput to which the receiver should append groups of timed metadata. Only asset writer inputs that accept media data of type AVMediaTypeMetadata can be used to initialize a timed metadata group adaptor.
        ///
        /// - Returns: An instance of AVAssetWriterInputMetadataAdaptor.
        #[unsafe(method(assetWriterInputMetadataAdaptorWithAssetWriterInput:))]
        #[unsafe(method_family = none)]
        pub unsafe fn assetWriterInputMetadataAdaptorWithAssetWriterInput(
            input: &AVAssetWriterInput,
        ) -> Retained<Self>;

        /// Creates a new timed metadator group adaptor to receive instances of AVTimedMetadataGroup for writing to the output file.
        ///
        /// The instance of AVAssetWriterInput passed in to this method must have been created with a format hint indicating all possible combinations of identifier (or, alternatively, key and keySpace), dataType, and extendedLanguageTag that will be appended to the metadata adaptor. It is an error to append metadata items not represented in the input's format hint. For help creating a suitable format hint, see -[AVTimedMetadataGroup copyFormatDescription].
        ///
        /// This method throws an exception for any of the following reasons:
        /// - input is already attached to another instance of AVAssetWriterInputMetadataAdaptor
        /// - input's asset writer has already started writing (progressed beyond AVAssetWriterStatusUnknown)
        /// - input's asset writer does not carry a source format hint
        /// - input's source format hint media subtype is not kCMMetadataFormatType_Boxed
        ///
        /// - Parameter input: An instance of AVAssetWriterInput to which the receiver should append groups of timed metadata. Only asset writer inputs that accept media data of type AVMediaTypeMetadata can be used to initialize a timed metadata group adaptor.
        ///
        /// - Returns: An instance of AVAssetWriterInputMetadataAdaptor.
        #[unsafe(method(initWithAssetWriterInput:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithAssetWriterInput(
            this: Allocated<Self>,
            input: &AVAssetWriterInput,
        ) -> Retained<Self>;

        /// The asset writer input to which the receiver should append timed metadata groups.
        #[unsafe(method(assetWriterInput))]
        #[unsafe(method_family = none)]
        pub unsafe fn assetWriterInput(&self) -> Retained<AVAssetWriterInput>;

        #[cfg(feature = "AVTimedMetadataGroup")]
        /// Appends a timed metadata group to the receiver.
        ///
        /// The receiver will retain the AVTimedMetadataGroup until it is done with it, and then release it.
        ///
        /// The timing of the metadata items in the output asset will correspond to the timeRange of the AVTimedMetadataGroup, regardless of the values of the time and duration properties of the individual items.
        ///
        /// Before calling this method, you must ensure that the input that underlies the receiver is attached to an AVAssetWriter via a prior call to -addInput: and that -startWriting has been called on the asset writer. It is an error to invoke this method before starting a session (via -[AVAssetWriter startSessionAtSourceTime:]) or after ending a session (via -[AVAssetWriter endSessionAtSourceTime:]).
        ///
        /// This method throws an exception if the attached asset writer input has not been added to an asset writer or -startWriting has not been called on that asset writer.
        ///
        /// - Parameter timedMetadataGroup: The AVTimedMetadataGroup to be appended.
        ///
        /// - Returns: A BOOL value indicating success of appending the timed metadata group.  If a result of NO is returned, AVAssetWriter.error will contain more information about why apending the timed metadata group failed.
        #[unsafe(method(appendTimedMetadataGroup:))]
        #[unsafe(method_family = none)]
        pub unsafe fn appendTimedMetadataGroup(
            &self,
            timed_metadata_group: &AVTimedMetadataGroup,
        ) -> bool;
    );
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/avfoundation/avassetwriterinputcaptionadaptor?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct AVAssetWriterInputCaptionAdaptor;
);

extern_conformance!(
    unsafe impl NSObjectProtocol for AVAssetWriterInputCaptionAdaptor {}
);

impl AVAssetWriterInputCaptionAdaptor {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;

        /// Creates a new caption adaptor for writing to the specified asset writer input.
        #[unsafe(method(assetWriterInputCaptionAdaptorWithAssetWriterInput:))]
        #[unsafe(method_family = none)]
        pub unsafe fn assetWriterInputCaptionAdaptorWithAssetWriterInput(
            input: &AVAssetWriterInput,
        ) -> Retained<Self>;

        /// Creates a new caption adaptor for writing to the specified asset writer input.
        ///
        /// This method thows an exception for any of the following reasons:
        /// - input is nil
        /// - the input's media type is not supported (should use text or closed caption)
        /// - the input is already attached to an asset writer caption adaptor
        /// - the input has already started writing
        #[unsafe(method(initWithAssetWriterInput:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithAssetWriterInput(
            this: Allocated<Self>,
            input: &AVAssetWriterInput,
        ) -> Retained<Self>;

        /// The asset writer input that was used to initialize the receiver.
        #[unsafe(method(assetWriterInput))]
        #[unsafe(method_family = none)]
        pub unsafe fn assetWriterInput(&self) -> Retained<AVAssetWriterInput>;

        #[cfg(feature = "AVCaption")]
        /// Append a single caption to be written.
        ///
        /// If this method returns NO, check the value of AVAssetWriter.status on the attached asset writer to determine why appending failed.
        ///
        /// The start time of each caption's timeRange property must be numeric (see CMTIME_IS_NUMERIC) and must be at least as large as the start time of any previous caption (including any captions present in a group appended via -appendCaptionGroup:). In other words, the sequence of captions appended using this method must have monotonically increasing start times.
        ///
        /// The duration of each caption's timeRange property must be numeric.
        ///
        /// - Parameter caption: The caption to append.
        ///
        /// - Returns: Returns YES if the operation succeeded, NO if it failed.
        #[unsafe(method(appendCaption:))]
        #[unsafe(method_family = none)]
        pub unsafe fn appendCaption(&self, caption: &AVCaption) -> bool;

        #[cfg(feature = "AVCaptionGroup")]
        /// Append a group of captions to be written.
        ///
        /// If this method returns NO, check the value of AVAssetWriter.status on the attached asset writer to determine why appending failed.
        /// When appending a sequence of captions groups, the start time of each group must be equal to or greater than the end time of any previous group. The easiest way to achieve this is to create the group using a caption whose duration is kCMTimeInvalid, in which case the duration will be determined by subtracting the start time of the group from the start time of the next appended group.
        /// When mixing calls to -appendCaptionGroup: and -appendCaption:, the start time of each group must be equal to or greater than the end time of any previous captions.
        /// To mark a time range containing no captions, append a group containing an empty caption array.
        ///
        /// - Parameter captionGroup:
        ///
        /// - Returns: Returns YES if the operation succeeded, NO if it failed.
        #[unsafe(method(appendCaptionGroup:))]
        #[unsafe(method_family = none)]
        pub unsafe fn appendCaptionGroup(&self, caption_group: &AVCaptionGroup) -> bool;
    );
}