Browse Source

lavd/avfoundation: Split adding a device and getting the device configuration into separate functions.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
tags/n2.5
Thilo Borgmann Michael Niedermayer 11 years ago
parent
commit
a69c70e148
1 changed files with 105 additions and 89 deletions
  1. +105
    -89
      libavdevice/avfoundation.m

+ 105
- 89
libavdevice/avfoundation.m View File

@@ -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;



Loading…
Cancel
Save