28 #import <AVFoundation/AVFoundation.h>
73 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
118 - (
void) captureOutput:(AVCaptureOutput *)captureOutput
119 didOutputSampleBuffer:(CMSampleBufferRef)videoFrame
120 fromConnection:(AVCaptureConnection *)connection;
128 if (
self = [super
init]) {
134 - (
void) captureOutput:(AVCaptureOutput *)captureOutput
135 didOutputSampleBuffer:(CMSampleBufferRef)videoFrame
136 fromConnection:(AVCaptureConnection *)connection
157 [ctx->capture_session stopRunning];
159 [ctx->capture_session release];
160 [ctx->video_output release];
161 [ctx->avf_delegate release];
177 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
187 NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
188 for (AVCaptureDevice *device
in devices) {
189 const char *
name = [[device localizedName] UTF8String];
190 int index = [devices indexOfObject:device];
197 AVCaptureDevice *video_device = nil;
205 NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
212 video_device = [devices objectAtIndex:ctx->video_device_index];
213 }
else if (strncmp(s->
filename,
"", 1) &&
214 strncmp(s->
filename,
"default", 7)) {
215 NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
217 for (AVCaptureDevice *device
in devices) {
218 if (!strncmp(s->
filename, [[device localizedName] UTF8String], strlen(s->
filename))) {
219 video_device = device;
229 video_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeMuxed];
234 video_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
242 NSString* dev_display_name = [video_device localizedName];
248 NSError *error = nil;
249 AVCaptureDeviceInput* capture_dev_input = [[[AVCaptureDeviceInput alloc] initWithDevice:video_device error:&error] autorelease];
251 if (!capture_dev_input) {
253 [[error localizedDescription] UTF8String]);
257 if (!capture_dev_input) {
259 [[error localizedDescription] UTF8String]);
264 [ctx->capture_session addInput:capture_dev_input];
271 ctx->
video_output = [[AVCaptureVideoDataOutput alloc] init];
284 pxl_fmt_spec = avf_pixel_formats[i];
291 av_log(s,
AV_LOG_ERROR,
"Selected pixel format (%s) is not supported by AVFoundation.\n",
297 if ([[ctx->
video_output availableVideoCVPixelFormatTypes] indexOfObject:[NSNumber numberWithInt:pxl_fmt_spec.
avf_id]] == NSNotFound) {
298 av_log(s,
AV_LOG_ERROR,
"Selected pixel format (%s) is not supported by the input device.\n",
304 for (NSNumber *pxl_fmt
in [ctx->
video_output availableVideoCVPixelFormatTypes]) {
308 if ([pxl_fmt intValue] == avf_pixel_formats[i].
avf_id) {
309 pxl_fmt_dummy = avf_pixel_formats[i];
319 pxl_fmt_spec = pxl_fmt_dummy;
334 NSNumber *pixel_format = [NSNumber numberWithUnsignedInt:pxl_fmt_spec.avf_id];
335 NSDictionary *capture_dict = [NSDictionary dictionaryWithObject:pixel_format
336 forKey:(id)kCVPixelBufferPixelFormatTypeKey];
338 [ctx->video_output setVideoSettings:capture_dict];
339 [ctx->video_output setAlwaysDiscardsLateVideoFrames:YES];
343 dispatch_queue_t queue = dispatch_queue_create(
"avf_queue", NULL);
344 [ctx->video_output setSampleBufferDelegate:ctx->avf_delegate queue:queue];
345 dispatch_release(queue);
348 [ctx->capture_session addOutput:ctx->video_output];
354 [ctx->capture_session startRunning];
358 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES);
371 CVImageBufferRef image_buffer = CMSampleBufferGetImageBuffer(ctx->
current_frame);
372 CGSize image_buffer_size = CVImageBufferGetEncodedSize(image_buffer);
376 stream->
codec->
width = (int)image_buffer_size.width;
377 stream->
codec->
height = (
int)image_buffer_size.height;
400 CVImageBufferRef image_buffer = CMSampleBufferGetImageBuffer(ctx->
current_frame);
403 if (
av_new_packet(pkt, (
int)CVPixelBufferGetDataSize(image_buffer)) < 0) {
413 CVPixelBufferLockBaseAddress(image_buffer, 0);
415 void*
data = CVPixelBufferGetBaseAddress(image_buffer);
418 CVPixelBufferUnlockBaseAddress(image_buffer, 0);
440 {
"frame_rate",
"set frame rate", offsetof(
AVFContext, frame_rate),
AV_OPT_TYPE_FLOAT, { .dbl = 30.0 }, 0.1, 30.0,
AV_OPT_TYPE_VIDEO_RATE, NULL },
441 {
"list_devices",
"list available devices", offsetof(
AVFContext, list_devices),
AV_OPT_TYPE_INT, {.i64=0}, 0, 1,
AV_OPT_FLAG_DECODING_PARAM,
"list_devices" },
458 .
name =
"avfoundation",
465 .priv_class = &avf_class,