From a69c70e148d99240a48969179c0ac1f45f29ce89 Mon Sep 17 00:00:00 2001 From: Thilo Borgmann Date: Wed, 24 Sep 2014 12:16:31 +0200 Subject: lavd/avfoundation: Split adding a device and getting the device configuration into separate functions. Signed-off-by: Michael Niedermayer --- libavdevice/avfoundation.m | 194 ++++++++++++++++++++++++--------------------- 1 file changed, 105 insertions(+), 89 deletions(-) (limited to 'libavdevice') diff --git a/libavdevice/avfoundation.m b/libavdevice/avfoundation.m index 4ac50a0ef2..895bd29964 100644 --- a/libavdevice/avfoundation.m +++ b/libavdevice/avfoundation.m @@ -172,99 +172,23 @@ static void destroy_context(AVFContext* ctx) } } -static int avf_read_header(AVFormatContext *s) +static int add_video_device(AVFormatContext *s, AVCaptureDevice *video_device) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - AVFContext *ctx = (AVFContext*)s->priv_data; - ctx->first_pts = av_gettime(); - - pthread_mutex_init(&ctx->frame_lock, NULL); - pthread_cond_init(&ctx->frame_wait_cond, NULL); - - // List devices if requested - if (ctx->list_devices) { - av_log(ctx, AV_LOG_INFO, "AVFoundation video devices:\n"); - NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; - for (AVCaptureDevice *device in devices) { - const char *name = [[device localizedName] UTF8String]; - int index = [devices indexOfObject:device]; - av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name); - } - goto fail; - } - - // Find capture device - AVCaptureDevice *video_device = nil; - - // check for device index given in filename - if (ctx->video_device_index == -1) { - sscanf(s->filename, "%d", &ctx->video_device_index); - } - - if (ctx->video_device_index >= 0) { - NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; - - if (ctx->video_device_index >= [devices count]) { - av_log(ctx, AV_LOG_ERROR, "Invalid device index\n"); - goto fail; - } - - video_device = [devices objectAtIndex:ctx->video_device_index]; - } else if (strncmp(s->filename, "", 1) && - strncmp(s->filename, "default", 7)) { - NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; - - for (AVCaptureDevice *device in devices) { - if (!strncmp(s->filename, [[device localizedName] UTF8String], strlen(s->filename))) { - video_device = device; - break; - } - } - - if (!video_device) { - av_log(ctx, AV_LOG_ERROR, "Video device not found\n"); - goto fail; - } - } else { - video_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeMuxed]; - } - - // Video capture device not found, looking for AVMediaTypeVideo - if (!video_device) { - video_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; - - if (!video_device) { - av_log(s, AV_LOG_ERROR, "No AV capture device found\n"); - goto fail; - } - } - - NSString* dev_display_name = [video_device localizedName]; - av_log(s, AV_LOG_DEBUG, "'%s' opened\n", [dev_display_name UTF8String]); - - // Initialize capture session - ctx->capture_session = [[AVCaptureSession alloc] init]; - - NSError *error = nil; + AVFContext *ctx = (AVFContext*)s->priv_data; + NSError *error = nil; AVCaptureDeviceInput* capture_dev_input = [[[AVCaptureDeviceInput alloc] initWithDevice:video_device error:&error] autorelease]; if (!capture_dev_input) { av_log(s, AV_LOG_ERROR, "Failed to create AV capture input device: %s\n", [[error localizedDescription] UTF8String]); - goto fail; - } - - if (!capture_dev_input) { - av_log(s, AV_LOG_ERROR, "Failed to add AV capture input device to session: %s\n", - [[error localizedDescription] UTF8String]); - goto fail; + return 1; } if ([ctx->capture_session canAddInput:capture_dev_input]) { [ctx->capture_session addInput:capture_dev_input]; } else { av_log(s, AV_LOG_ERROR, "can't add video input to capture session\n"); - goto fail; + return 1; } // Attaching output @@ -272,7 +196,7 @@ static int avf_read_header(AVFormatContext *s) if (!ctx->video_output) { av_log(s, AV_LOG_ERROR, "Failed to init AV video output\n"); - goto fail; + return 1; } // select pixel format @@ -290,7 +214,7 @@ static int avf_read_header(AVFormatContext *s) if (pxl_fmt_spec.ff_id == AV_PIX_FMT_NONE) { av_log(s, AV_LOG_ERROR, "Selected pixel format (%s) is not supported by AVFoundation.\n", av_get_pix_fmt_name(pxl_fmt_spec.ff_id)); - goto fail; + return 1; } // check if the pixel format is available for this device @@ -323,14 +247,14 @@ static int avf_read_header(AVFormatContext *s) // fail if there is no appropriate pixel format or print a warning about overriding the pixel format if (pxl_fmt_spec.ff_id == AV_PIX_FMT_NONE) { - goto fail; + return 1; } else { av_log(s, AV_LOG_WARNING, "Overriding selected pixel format to use %s instead.\n", av_get_pix_fmt_name(pxl_fmt_spec.ff_id)); } } - + ctx->pixel_format = pxl_fmt_spec.ff_id; NSNumber *pixel_format = [NSNumber numberWithUnsignedInt:pxl_fmt_spec.avf_id]; NSDictionary *capture_dict = [NSDictionary dictionaryWithObject:pixel_format forKey:(id)kCVPixelBufferPixelFormatTypeKey]; @@ -348,10 +272,15 @@ static int avf_read_header(AVFormatContext *s) [ctx->capture_session addOutput:ctx->video_output]; } else { av_log(s, AV_LOG_ERROR, "can't add video output to capture session\n"); - goto fail; + return 1; } - [ctx->capture_session startRunning]; + return 0; +} + +static int get_video_config(AVFormatContext *s) +{ + AVFContext *ctx = (AVFContext*)s->priv_data; // Take stream info from the first frame. while (ctx->frames_captured < 1) { @@ -363,7 +292,7 @@ static int avf_read_header(AVFormatContext *s) AVStream* stream = avformat_new_stream(s, NULL); if (!stream) { - goto fail; + return 1; } avpriv_set_pts_info(stream, 64, 1, avf_time_base); @@ -375,12 +304,99 @@ static int avf_read_header(AVFormatContext *s) stream->codec->codec_type = AVMEDIA_TYPE_VIDEO; stream->codec->width = (int)image_buffer_size.width; stream->codec->height = (int)image_buffer_size.height; - stream->codec->pix_fmt = pxl_fmt_spec.ff_id; + stream->codec->pix_fmt = ctx->pixel_format; CFRelease(ctx->current_frame); ctx->current_frame = nil; unlock_frames(ctx); + + return 0; +} + +static int avf_read_header(AVFormatContext *s) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + AVFContext *ctx = (AVFContext*)s->priv_data; + ctx->first_pts = av_gettime(); + + pthread_mutex_init(&ctx->frame_lock, NULL); + pthread_cond_init(&ctx->frame_wait_cond, NULL); + + // List devices if requested + if (ctx->list_devices) { + av_log(ctx, AV_LOG_INFO, "AVFoundation video devices:\n"); + NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; + for (AVCaptureDevice *device in devices) { + const char *name = [[device localizedName] UTF8String]; + int index = [devices indexOfObject:device]; + av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name); + } + goto fail; + } + + // Find capture device + AVCaptureDevice *video_device = nil; + + // check for device index given in filename + if (ctx->video_device_index == -1) { + sscanf(s->filename, "%d", &ctx->video_device_index); + } + + if (ctx->video_device_index >= 0) { + NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; + + if (ctx->video_device_index >= [devices count]) { + av_log(ctx, AV_LOG_ERROR, "Invalid device index\n"); + goto fail; + } + + video_device = [devices objectAtIndex:ctx->video_device_index]; + } else if (strncmp(s->filename, "", 1) && + strncmp(s->filename, "default", 7)) { + NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; + + for (AVCaptureDevice *device in devices) { + if (!strncmp(s->filename, [[device localizedName] UTF8String], strlen(s->filename))) { + video_device = device; + break; + } + } + + if (!video_device) { + av_log(ctx, AV_LOG_ERROR, "Video device not found\n"); + goto fail; + } + } else { + video_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + } + + // Video capture device not found, looking for AVMediaTypeVideo + if (!video_device) { + video_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + + if (!video_device) { + av_log(s, AV_LOG_ERROR, "No AV capture device found\n"); + goto fail; + } + } + + NSString* dev_display_name = [video_device localizedName]; + av_log(s, AV_LOG_DEBUG, "'%s' opened\n", [dev_display_name UTF8String]); + + // Initialize capture session + ctx->capture_session = [[AVCaptureSession alloc] init]; + + if (add_video_device(s, video_device)) { + goto fail; + } + + [ctx->capture_session startRunning]; + + if (get_video_config(s)) { + goto fail; + } + [pool release]; return 0; -- cgit v1.2.3