lavd/qtkit: Support choosing the input device by index or by name.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		
				
					committed by
					
						
						Michael Niedermayer
					
				
			
			
				
	
			
			
			
						parent
						
							23d1c75efa
						
					
				
				
					commit
					4654774aaf
				
			@@ -535,12 +535,29 @@ ffmpeg -f pulse -i default /tmp/pulse.wav
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
QTKit input device.
 | 
					QTKit input device.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The filename passed as input is unused. The default device will be chosen.
 | 
					The filename passed as input is parsed to contain either a device name or index.
 | 
				
			||||||
 | 
					The device index can also be given by using -video_device_index.
 | 
				
			||||||
 | 
					A given device index will override any given device name.
 | 
				
			||||||
 | 
					If the desired device consists of numbers only, use -video_device_index to identify it.
 | 
				
			||||||
 | 
					The default device will be chosen if an empty string  or the device name "default" is given.
 | 
				
			||||||
 | 
					The available devices can be enumerated by using -list_devices.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@example
 | 
					@example
 | 
				
			||||||
ffmpeg -f qtkit -i "0" out.mpg
 | 
					ffmpeg -f qtkit -i "0" out.mpg
 | 
				
			||||||
@end example
 | 
					@end example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@example
 | 
				
			||||||
 | 
					ffmpeg -f qtkit -video_device_index 0 -i "" out.mpg
 | 
				
			||||||
 | 
					@end example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@example
 | 
				
			||||||
 | 
					ffmpeg -f qtkit -i "default" out.mpg
 | 
				
			||||||
 | 
					@end example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@example
 | 
				
			||||||
 | 
					ffmpeg -f qtkit -list_devices true -i ""
 | 
				
			||||||
 | 
					@end example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@section sndio
 | 
					@section sndio
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sndio input device.
 | 
					sndio input device.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,6 +53,9 @@ typedef struct
 | 
				
			|||||||
    pthread_cond_t  frame_wait_cond;
 | 
					    pthread_cond_t  frame_wait_cond;
 | 
				
			||||||
    id              qt_delegate;
 | 
					    id              qt_delegate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int             list_devices;
 | 
				
			||||||
 | 
					    int             video_device_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QTCaptureSession*                 capture_session;
 | 
					    QTCaptureSession*                 capture_session;
 | 
				
			||||||
    QTCaptureDecompressedVideoOutput* video_output;
 | 
					    QTCaptureDecompressedVideoOutput* video_output;
 | 
				
			||||||
    CVImageBufferRef                  current_frame;
 | 
					    CVImageBufferRef                  current_frame;
 | 
				
			||||||
@@ -145,8 +148,52 @@ static int qtkit_read_header(AVFormatContext *s)
 | 
				
			|||||||
    pthread_mutex_init(&ctx->frame_lock, NULL);
 | 
					    pthread_mutex_init(&ctx->frame_lock, NULL);
 | 
				
			||||||
    pthread_cond_init(&ctx->frame_wait_cond, NULL);
 | 
					    pthread_cond_init(&ctx->frame_wait_cond, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Find default capture device
 | 
					    // List devices if requested
 | 
				
			||||||
    QTCaptureDevice *video_device = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeMuxed];
 | 
					    if (ctx->list_devices) {
 | 
				
			||||||
 | 
					        av_log(ctx, AV_LOG_INFO, "QTKit video devices:\n");
 | 
				
			||||||
 | 
					        NSArray *devices = [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo];
 | 
				
			||||||
 | 
					        for (QTCaptureDevice *device in devices) {
 | 
				
			||||||
 | 
					            const char *name = [[device localizedDisplayName] UTF8String];
 | 
				
			||||||
 | 
					            int index  = [devices indexOfObject:device];
 | 
				
			||||||
 | 
					            av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Find capture device
 | 
				
			||||||
 | 
					    QTCaptureDevice *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 = [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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 = [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (QTCaptureDevice *device in devices) {
 | 
				
			||||||
 | 
					            if (!strncmp(s->filename, [[device localizedDisplayName] 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 = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeMuxed];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    BOOL success = [video_device open:nil];
 | 
					    BOOL success = [video_device open:nil];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -284,6 +331,10 @@ static int qtkit_close(AVFormatContext *s)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static const AVOption options[] = {
 | 
					static const AVOption options[] = {
 | 
				
			||||||
    { "frame_rate", "set frame rate", offsetof(CaptureContext, frame_rate), AV_OPT_TYPE_FLOAT, { .dbl = 30.0 }, 0.1, 30.0, AV_OPT_TYPE_VIDEO_RATE, NULL },
 | 
					    { "frame_rate", "set frame rate", offsetof(CaptureContext, frame_rate), AV_OPT_TYPE_FLOAT, { .dbl = 30.0 }, 0.1, 30.0, AV_OPT_TYPE_VIDEO_RATE, NULL },
 | 
				
			||||||
 | 
					    { "list_devices", "list available devices", offsetof(CaptureContext, list_devices), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
 | 
				
			||||||
 | 
					    { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
 | 
				
			||||||
 | 
					    { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
 | 
				
			||||||
 | 
					    { "video_device_index", "select video device by index for devices with same name (starts at 0)", offsetof(CaptureContext, video_device_index), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
 | 
				
			||||||
    { NULL },
 | 
					    { NULL },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user