[FFmpeg-devel] [PATCH 1/5] lavd/avfoundation: Split adding a device and getting the device configuration into separate functions.
Thilo Borgmann
thilo.borgmann at mail.de
Wed Sep 24 12:41:35 CEST 2014
-------------- next part --------------
>From be85e7d6fe11431ca3917d07da673cc2cc6a5ad6 Mon Sep 17 00:00:00 2001
From: Thilo Borgmann <thilo.borgmann at mail.de>
Date: Wed, 24 Sep 2014 12:16:31 +0200
Subject: [PATCH 1/5] lavd/avfoundation: Split adding a device and getting the
device configuration into separate functions.
---
libavdevice/avfoundation.m | 194 ++++++++++++++++++++++++---------------------
1 file changed, 105 insertions(+), 89 deletions(-)
diff --git a/libavdevice/avfoundation.m b/libavdevice/avfoundation.m
index 4ac50a0..895bd29 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;
--
1.8.3.2
More information about the ffmpeg-devel
mailing list