28 #import <AVFoundation/AVFoundation.h> 
   76 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 
  135 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 
  136     AVCaptureDeviceTransportControlsPlaybackMode observed_mode;
 
  160 - (void)  captureOutput:(AVCaptureOutput *)captureOutput
 
  161   didOutputSampleBuffer:(CMSampleBufferRef)videoFrame
 
  162          fromConnection:(AVCaptureConnection *)connection;
 
  170     if (
self = [super 
init]) {
 
  174 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 
  176             NSString *keyPath = NSStringFromSelector(
@selector(transportControlsPlaybackMode));
 
  177             NSKeyValueObservingOptions 
options = NSKeyValueObservingOptionNew;
 
  179             [
_context->observed_device addObserver: self
 
  191 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 
  193         NSString *keyPath = NSStringFromSelector(
@selector(transportControlsPlaybackMode));
 
  194         [_context->observed_device removeObserver: self forKeyPath: keyPath];
 
  200 - (void)observeValueForKeyPath:(NSString *)keyPath
 
  202                         change:(NSDictionary *)change
 
  203                        context:(
void *)context {
 
  205 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 
  206         AVCaptureDeviceTransportControlsPlaybackMode 
mode =
 
  207             [change[NSKeyValueChangeNewKey] integerValue];
 
  210             if (
mode == AVCaptureDeviceTransportControlsNotPlayingMode) {
 
  217         [
super observeValueForKeyPath: keyPath
 
  224 - (void)  captureOutput:(AVCaptureOutput *)captureOutput
 
  225   didOutputSampleBuffer:(CMSampleBufferRef)videoFrame
 
  226          fromConnection:(AVCaptureConnection *)connection
 
  252 - (void)  captureOutput:(AVCaptureOutput *)captureOutput
 
  253   didOutputSampleBuffer:(CMSampleBufferRef)audioFrame
 
  254          fromConnection:(AVCaptureConnection *)connection;
 
  262     if (
self = [super 
init]) {
 
  268 - (void)  captureOutput:(AVCaptureOutput *)captureOutput
 
  269   didOutputSampleBuffer:(CMSampleBufferRef)audioFrame
 
  270          fromConnection:(AVCaptureConnection *)connection
 
  289     [ctx->capture_session stopRunning];
 
  291     [ctx->capture_session release];
 
  292     [ctx->video_output    release];
 
  293     [ctx->audio_output    release];
 
  294     [ctx->avf_delegate    release];
 
  295     [ctx->avf_audio_delegate release];
 
  301     ctx->avf_audio_delegate = 
NULL;
 
  307     if (
ctx->current_frame) {
 
  308         CFRelease(
ctx->current_frame);
 
  341     NSObject *range = nil;
 
  343     NSObject *selected_range = nil;
 
  344     NSObject *selected_format = nil;
 
  350         for (
format in [video_device valueForKey:
@"formats"]) {
 
  351             CMFormatDescriptionRef formatDescription;
 
  352             CMVideoDimensions dimensions;
 
  354             formatDescription = (CMFormatDescriptionRef) [
format performSelector:
@selector(formatDescription)];
 
  355             dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription);
 
  357             if ((
ctx->width == 0 && 
ctx->height == 0) ||
 
  358                 (dimensions.width == 
ctx->width && dimensions.height == 
ctx->height)) {
 
  362                 for (range 
in [
format valueForKey:
@"videoSupportedFrameRateRanges"]) {
 
  363                     double max_framerate;
 
  365                     [[range valueForKey:@"maxFrameRate"] getValue:&max_framerate];
 
  366                     if (fabs (
framerate - max_framerate) < 0.01) {
 
  367                         selected_range = range;
 
  374         if (!selected_format) {
 
  377             goto unsupported_format;
 
  380         if (!selected_range) {
 
  383             if (
ctx->video_is_muxed) {
 
  386                 goto unsupported_format;
 
  390         if ([video_device lockForConfiguration:
NULL] == YES) {
 
  391             if (selected_format) {
 
  392                 [video_device setValue:selected_format forKey:@"activeFormat"];
 
  394             if (selected_range) {
 
  395                 NSValue *min_frame_duration = [selected_range valueForKey:@"minFrameDuration"];
 
  396                 [video_device setValue:min_frame_duration forKey:@"activeVideoMinFrameDuration"];
 
  397                 [video_device setValue:min_frame_duration forKey:@"activeVideoMaxFrameDuration"];
 
  403     } 
@catch(NSException *e) {
 
  412     for (
format in [video_device valueForKey:
@"formats"]) {
 
  413         CMFormatDescriptionRef formatDescription;
 
  414         CMVideoDimensions dimensions;
 
  416         formatDescription = (CMFormatDescriptionRef) [
format performSelector:
@selector(formatDescription)];
 
  417         dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription);
 
  419         for (range 
in [
format valueForKey:
@"videoSupportedFrameRateRanges"]) {
 
  420             double min_framerate;
 
  421             double max_framerate;
 
  423             [[range valueForKey:@"minFrameRate"] getValue:&min_framerate];
 
  424             [[range valueForKey:@"maxFrameRate"] getValue:&max_framerate];
 
  426                 dimensions.width, dimensions.height,
 
  427                 min_framerate, max_framerate);
 
  437     NSError *
error  = nil;
 
  438     AVCaptureInput* capture_input = nil;
 
  440     NSNumber *pixel_format;
 
  441     NSDictionary *capture_dict;
 
  442     dispatch_queue_t queue;
 
  444     if (
ctx->video_device_index < 
ctx->num_video_devices) {
 
  445         capture_input = (AVCaptureInput*) [[[AVCaptureDeviceInput alloc] initWithDevice:video_device 
error:&
error] autorelease];
 
  447         capture_input = (AVCaptureInput*) video_device;
 
  450     if (!capture_input) {
 
  452                [[
error localizedDescription] UTF8String]);
 
  456     if ([
ctx->capture_session canAddInput:capture_input]) {
 
  457         [ctx->capture_session addInput:capture_input];
 
  464     ctx->video_output = [[AVCaptureVideoDataOutput alloc] init];
 
  466     if (!
ctx->video_output) {
 
  476     } 
@catch (NSException *exception) {
 
  477         if (![[exception 
name] isEqualToString:NSUndefinedKeyException]) {
 
  501     if ([[
ctx->video_output availableVideoCVPixelFormatTypes] indexOfObject:[NSNumber numberWithInt:pxl_fmt_spec.avf_id]] == NSNotFound) {
 
  502         av_log(
s, 
AV_LOG_ERROR, 
"Selected pixel format (%s) is not supported by the input device.\n",
 
  508         for (NSNumber *pxl_fmt 
in [
ctx->video_output availableVideoCVPixelFormatTypes]) {
 
  523                     pxl_fmt_spec = pxl_fmt_dummy;
 
  538     if (
ctx->capture_raw_data) {
 
  539         ctx->pixel_format = pxl_fmt_spec.ff_id;
 
  540         ctx->video_output.videoSettings = @{ };
 
  542         ctx->pixel_format = pxl_fmt_spec.ff_id;
 
  543         pixel_format = [NSNumber numberWithUnsignedInt:pxl_fmt_spec.avf_id];
 
  544         capture_dict = [NSDictionary dictionaryWithObject:pixel_format
 
  545                                                    forKey:(id)kCVPixelBufferPixelFormatTypeKey];
 
  547         [ctx->video_output setVideoSettings:capture_dict];
 
  549     [ctx->video_output setAlwaysDiscardsLateVideoFrames:ctx->drop_late_frames];
 
  551 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 
  553     if (!
ctx->video_is_screen) {
 
  554         int trans_ctrl = [video_device transportControlsSupported];
 
  555         AVCaptureDeviceTransportControlsPlaybackMode trans_mode = [video_device transportControlsPlaybackMode];
 
  558             ctx->observed_mode   = trans_mode;
 
  559             ctx->observed_device = video_device;
 
  566     queue = dispatch_queue_create(
"avf_queue", 
NULL);
 
  567     [ctx->video_output setSampleBufferDelegate:ctx->avf_delegate queue:queue];
 
  568     dispatch_release(queue);
 
  570     if ([
ctx->capture_session canAddOutput:
ctx->video_output]) {
 
  571         [ctx->capture_session addOutput:ctx->video_output];
 
  583     NSError *
error  = nil;
 
  584     AVCaptureDeviceInput* audio_dev_input = [[[AVCaptureDeviceInput alloc] initWithDevice:audio_device 
error:&
error] autorelease];
 
  585     dispatch_queue_t queue;
 
  587     if (!audio_dev_input) {
 
  589                [[
error localizedDescription] UTF8String]);
 
  593     if ([
ctx->capture_session canAddInput:audio_dev_input]) {
 
  594         [ctx->capture_session addInput:audio_dev_input];
 
  601     ctx->audio_output = [[AVCaptureAudioDataOutput alloc] init];
 
  603     if (!
ctx->audio_output) {
 
  610     queue = dispatch_queue_create(
"avf_audio_queue", 
NULL);
 
  611     [ctx->audio_output setSampleBufferDelegate:ctx->avf_audio_delegate queue:queue];
 
  612     dispatch_release(queue);
 
  614     if ([
ctx->capture_session canAddOutput:
ctx->audio_output]) {
 
  615         [ctx->capture_session addOutput:ctx->audio_output];
 
  627     CVImageBufferRef image_buffer;
 
  628     CMBlockBufferRef block_buffer;
 
  629     CGSize image_buffer_size;
 
  637     while (
ctx->frames_captured < 1) {
 
  638         CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES);
 
  643     ctx->video_stream_index = stream->index;
 
  647     image_buffer = CMSampleBufferGetImageBuffer(
ctx->current_frame);
 
  648     block_buffer = CMSampleBufferGetDataBuffer(
ctx->current_frame);
 
  651         image_buffer_size = CVImageBufferGetEncodedSize(image_buffer);
 
  655         stream->codecpar->width      = (
int)image_buffer_size.width;
 
  656         stream->codecpar->height     = (
int)image_buffer_size.height;
 
  657         stream->codecpar->format     = 
ctx->pixel_format;
 
  661         stream->codecpar->format     = 
ctx->pixel_format;
 
  664     CFRelease(
ctx->current_frame);
 
  665     ctx->current_frame = nil;
 
  675     CMFormatDescriptionRef format_desc;
 
  683     while (
ctx->audio_frames_captured < 1) {
 
  684         CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES);
 
  689     ctx->audio_stream_index = stream->index;
 
  693     format_desc = CMSampleBufferGetFormatDescription(
ctx->current_audio_frame);
 
  694     const AudioStreamBasicDescription *basic_desc = CMAudioFormatDescriptionGetStreamBasicDescription(format_desc);
 
  702     stream->codecpar->sample_rate    = basic_desc->mSampleRate;
 
  703     stream->codecpar->channels       = basic_desc->mChannelsPerFrame;
 
  706     ctx->audio_channels        = basic_desc->mChannelsPerFrame;
 
  707     ctx->audio_bits_per_sample = basic_desc->mBitsPerChannel;
 
  708     ctx->audio_float           = basic_desc->mFormatFlags & kAudioFormatFlagIsFloat;
 
  709     ctx->audio_be              = basic_desc->mFormatFlags & kAudioFormatFlagIsBigEndian;
 
  710     ctx->audio_signed_integer  = basic_desc->mFormatFlags & kAudioFormatFlagIsSignedInteger;
 
  711     ctx->audio_packed          = basic_desc->mFormatFlags & kAudioFormatFlagIsPacked;
 
  712     ctx->audio_non_interleaved = basic_desc->mFormatFlags & kAudioFormatFlagIsNonInterleaved;
 
  714     if (basic_desc->mFormatID == kAudioFormatLinearPCM &&
 
  716         ctx->audio_bits_per_sample == 32 &&
 
  719     } 
else if (basic_desc->mFormatID == kAudioFormatLinearPCM &&
 
  720         ctx->audio_signed_integer &&
 
  721         ctx->audio_bits_per_sample == 16 &&
 
  724     } 
else if (basic_desc->mFormatID == kAudioFormatLinearPCM &&
 
  725         ctx->audio_signed_integer &&
 
  726         ctx->audio_bits_per_sample == 24 &&
 
  729     } 
else if (basic_desc->mFormatID == kAudioFormatLinearPCM &&
 
  730         ctx->audio_signed_integer &&
 
  731         ctx->audio_bits_per_sample == 32 &&
 
  739     if (
ctx->audio_non_interleaved) {
 
  740         CMBlockBufferRef block_buffer = CMSampleBufferGetDataBuffer(
ctx->current_audio_frame);
 
  741         ctx->audio_buffer_size        = CMBlockBufferGetDataLength(block_buffer);
 
  743         if (!
ctx->audio_buffer) {
 
  749     CFRelease(
ctx->current_audio_frame);
 
  750     ctx->current_audio_frame = nil;
 
  759     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
  760     uint32_t num_screens    = 0;
 
  762     AVCaptureDevice *video_device = nil;
 
  763     AVCaptureDevice *audio_device = nil;
 
  765     NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
 
  766     NSArray *devices_muxed = [AVCaptureDevice devicesWithMediaType:AVMediaTypeMuxed];
 
  768     ctx->num_video_devices = [devices count] + [devices_muxed count];
 
  774 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 
  775     CGGetActiveDisplayList(0, 
NULL, &num_screens);
 
  779     if (
ctx->list_devices) {
 
  782         for (AVCaptureDevice *device 
in devices) {
 
  783             const char *
name = [[device localizedName] UTF8String];
 
  784             index            = [devices indexOfObject:device];
 
  787         for (AVCaptureDevice *device 
in devices_muxed) {
 
  788             const char *
name = [[device localizedName] UTF8String];
 
  789             index            = [devices count] + [devices_muxed indexOfObject:device];
 
  792 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 
  793         if (num_screens > 0) {
 
  794             CGDirectDisplayID screens[num_screens];
 
  795             CGGetActiveDisplayList(num_screens, screens, &num_screens);
 
  796             for (
int i = 0; 
i < num_screens; 
i++) {
 
  803         devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio];
 
  804         for (AVCaptureDevice *device 
in devices) {
 
  805             const char *
name = [[device localizedName] UTF8String];
 
  806             int index  = [devices indexOfObject:device];
 
  816     if (
ctx->video_device_index == -1 && 
ctx->video_filename) {
 
  817         sscanf(
ctx->video_filename, 
"%d", &
ctx->video_device_index);
 
  819     if (
ctx->audio_device_index == -1 && 
ctx->audio_filename) {
 
  820         sscanf(
ctx->audio_filename, 
"%d", &
ctx->audio_device_index);
 
  823     if (
ctx->video_device_index >= 0) {
 
  824         if (
ctx->video_device_index < 
ctx->num_video_devices) {
 
  825             if (
ctx->video_device_index < [devices count]) {
 
  826                 video_device = [devices objectAtIndex:ctx->video_device_index];
 
  828                 video_device = [devices_muxed objectAtIndex:(ctx->video_device_index - [devices count])];
 
  829                 ctx->video_is_muxed = 1;
 
  831         } 
else if (
ctx->video_device_index < 
ctx->num_video_devices + num_screens) {
 
  832 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 
  833             CGDirectDisplayID screens[num_screens];
 
  834             CGGetActiveDisplayList(num_screens, screens, &num_screens);
 
  835             AVCaptureScreenInput* capture_screen_input = [[[AVCaptureScreenInput alloc] initWithDisplayID:screens[ctx->video_device_index - ctx->
num_video_devices]] autorelease];
 
  837             if (
ctx->framerate.num > 0) {
 
  838                 capture_screen_input.minFrameDuration = CMTimeMake(
ctx->framerate.den, 
ctx->framerate.num);
 
  841 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 
  842             if (
ctx->capture_cursor) {
 
  843                 capture_screen_input.capturesCursor = YES;
 
  845                 capture_screen_input.capturesCursor = NO;
 
  849             if (
ctx->capture_mouse_clicks) {
 
  850                 capture_screen_input.capturesMouseClicks = YES;
 
  852                 capture_screen_input.capturesMouseClicks = NO;
 
  855             video_device = (AVCaptureDevice*) capture_screen_input;
 
  856             ctx->video_is_screen = 1;
 
  862     } 
else if (
ctx->video_filename &&
 
  863                strncmp(
ctx->video_filename, 
"none", 4)) {
 
  864         if (!strncmp(
ctx->video_filename, 
"default", 7)) {
 
  865             video_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
 
  868         for (AVCaptureDevice *device 
in devices) {
 
  869             if (!strncmp(
ctx->video_filename, [[device localizedName] UTF8String], strlen(
ctx->video_filename))) {
 
  870                 video_device = device;
 
  875         for (AVCaptureDevice *device 
in devices_muxed) {
 
  876             if (!strncmp(
ctx->video_filename, [[device localizedName] UTF8String], strlen(
ctx->video_filename))) {
 
  877                 video_device = device;
 
  878                 ctx->video_is_muxed = 1;
 
  883 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 
  887             if(sscanf(
ctx->video_filename, 
"Capture screen %d", &idx) && idx < num_screens) {
 
  888                 CGDirectDisplayID screens[num_screens];
 
  889                 CGGetActiveDisplayList(num_screens, screens, &num_screens);
 
  890                 AVCaptureScreenInput* capture_screen_input = [[[AVCaptureScreenInput alloc] initWithDisplayID:screens[idx]] autorelease];
 
  891                 video_device = (AVCaptureDevice*) capture_screen_input;
 
  892                 ctx->video_device_index = 
ctx->num_video_devices + idx;
 
  893                 ctx->video_is_screen = 1;
 
  895                 if (
ctx->framerate.num > 0) {
 
  896                     capture_screen_input.minFrameDuration = CMTimeMake(
ctx->framerate.den, 
ctx->framerate.num);
 
  899 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 
  900                 if (
ctx->capture_cursor) {
 
  901                     capture_screen_input.capturesCursor = YES;
 
  903                     capture_screen_input.capturesCursor = NO;
 
  907                 if (
ctx->capture_mouse_clicks) {
 
  908                     capture_screen_input.capturesMouseClicks = YES;
 
  910                     capture_screen_input.capturesMouseClicks = NO;
 
  924     if (
ctx->audio_device_index >= 0) {
 
  925         NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio];
 
  927         if (
ctx->audio_device_index >= [devices count]) {
 
  932         audio_device = [devices objectAtIndex:ctx->audio_device_index];
 
  933     } 
else if (
ctx->audio_filename &&
 
  934                strncmp(
ctx->audio_filename, 
"none", 4)) {
 
  935         if (!strncmp(
ctx->audio_filename, 
"default", 7)) {
 
  936             audio_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
 
  938         NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio];
 
  940         for (AVCaptureDevice *device 
in devices) {
 
  941             if (!strncmp(
ctx->audio_filename, [[device localizedName] UTF8String], strlen(
ctx->audio_filename))) {
 
  942                 audio_device = device;
 
  955     if (!video_device && !audio_device) {
 
  961         if (
ctx->video_device_index < 
ctx->num_video_devices) {
 
  968         av_log(
s, 
AV_LOG_DEBUG, 
"audio device '%s' opened\n", [[audio_device localizedName] UTF8String]);
 
  972     ctx->capture_session = [[AVCaptureSession alloc] init];
 
  980     [ctx->capture_session startRunning];
 
  984     if (!
ctx->video_is_screen) {
 
  985         [video_device unlockForConfiguration];
 
 1007                                CVPixelBufferRef image_buffer,
 
 1011     int src_linesize[4];
 
 1013     int width  = CVPixelBufferGetWidth(image_buffer);
 
 1014     int height = CVPixelBufferGetHeight(image_buffer);
 
 1017     memset(src_linesize, 0, 
sizeof(src_linesize));
 
 1018     memset(src_data, 0, 
sizeof(src_data));
 
 1020     status = CVPixelBufferLockBaseAddress(image_buffer, 0);
 
 1021     if (
status != kCVReturnSuccess) {
 
 1026     if (CVPixelBufferIsPlanar(image_buffer)) {
 
 1027         size_t plane_count = CVPixelBufferGetPlaneCount(image_buffer);
 
 1029         for(
i = 0; 
i < plane_count; 
i++){
 
 1030             src_linesize[i] = CVPixelBufferGetBytesPerRowOfPlane(image_buffer, 
i);
 
 1031             src_data[i] = CVPixelBufferGetBaseAddressOfPlane(image_buffer, 
i);
 
 1034         src_linesize[0] = CVPixelBufferGetBytesPerRow(image_buffer);
 
 1035         src_data[0] = CVPixelBufferGetBaseAddress(image_buffer);
 
 1039                                      src_data, src_linesize,
 
 1044     CVPixelBufferUnlockBaseAddress(image_buffer, 0);
 
 1054         CVImageBufferRef image_buffer;
 
 1055         CMBlockBufferRef block_buffer;
 
 1058         if (
ctx->current_frame != nil) {
 
 1062             image_buffer = CMSampleBufferGetImageBuffer(
ctx->current_frame);
 
 1063             block_buffer = CMSampleBufferGetDataBuffer(
ctx->current_frame);
 
 1065             if (image_buffer != nil) {
 
 1066                 length = (
int)CVPixelBufferGetDataSize(image_buffer);
 
 1067             } 
else if (block_buffer != nil) {
 
 1068                 length = (
int)CMBlockBufferGetDataLength(block_buffer);
 
 1080             if (CMSampleBufferGetOutputSampleTimingInfoArray(
ctx->current_frame, 1, &
timing_info, &count) == noErr) {
 
 1092                 OSStatus 
ret = CMBlockBufferCopyDataBytes(block_buffer, 0, 
pkt->
size, 
pkt->
data);
 
 1093                 if (
ret != kCMBlockBufferNoErr) {
 
 1097             CFRelease(
ctx->current_frame);
 
 1098             ctx->current_frame = nil;
 
 1102         } 
else if (
ctx->current_audio_frame != nil) {
 
 1103             CMBlockBufferRef block_buffer = CMSampleBufferGetDataBuffer(
ctx->current_audio_frame);
 
 1104             int block_buffer_size         = CMBlockBufferGetDataLength(block_buffer);
 
 1106             if (!block_buffer || !block_buffer_size) {
 
 1110             if (
ctx->audio_non_interleaved && block_buffer_size > 
ctx->audio_buffer_size) {
 
 1121             if (CMSampleBufferGetOutputSampleTimingInfoArray(
ctx->current_audio_frame, 1, &
timing_info, &count) == noErr) {
 
 1129             if (
ctx->audio_non_interleaved) {
 
 1132                 OSStatus 
ret = CMBlockBufferCopyDataBytes(block_buffer, 0, 
pkt->
size, 
ctx->audio_buffer);
 
 1133                 if (
ret != kCMBlockBufferNoErr) {
 
 1137                 num_samples = 
pkt->
size / (
ctx->audio_channels * (
ctx->audio_bits_per_sample >> 3));
 
 1140                 #define INTERLEAVE_OUTPUT(bps)                                         \ 
 1142                     int##bps##_t **src;                                                \ 
 1143                     int##bps##_t *dest;                                                \ 
 1144                     src = av_malloc(ctx->audio_channels * sizeof(int##bps##_t*));      \ 
 1145                     if (!src) return AVERROR(EIO);                                     \ 
 1146                     for (c = 0; c < ctx->audio_channels; c++) {                        \ 
 1147                         src[c] = ((int##bps##_t*)ctx->audio_buffer) + c * num_samples; \ 
 1149                     dest  = (int##bps##_t*)pkt->data;                                  \ 
 1150                     shift = bps - ctx->audio_bits_per_sample;                          \ 
 1151                     for (sample = 0; sample < num_samples; sample++)                   \ 
 1152                         for (c = 0; c < ctx->audio_channels; c++)                      \ 
 1153                             *dest++ = src[c][sample] << shift;                         \ 
 1157                 if (
ctx->audio_bits_per_sample <= 16) {
 
 1163                 OSStatus 
ret = CMBlockBufferCopyDataBytes(block_buffer, 0, 
pkt->
size, 
pkt->
data);
 
 1164                 if (
ret != kCMBlockBufferNoErr) {
 
 1169             CFRelease(
ctx->current_audio_frame);
 
 1170             ctx->current_audio_frame = nil;
 
 1174             if (
ctx->observed_quit) {
 
 1218     .
name           = 
"avfoundation",