mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-01-26 07:08:34 -05:00
Add connect/disconnect handling for mac-avcapture
This commit is contained in:
@@ -49,6 +49,10 @@ struct av_capture {
|
||||
dispatch_queue_t queue;
|
||||
bool has_clock;
|
||||
|
||||
NSString *uid;
|
||||
id connect_observer;
|
||||
id disconnect_observer;
|
||||
|
||||
unsigned fourcc;
|
||||
enum video_format video_format;
|
||||
|
||||
@@ -149,6 +153,9 @@ static void av_capture_destroy(void *data)
|
||||
if (!capture)
|
||||
return;
|
||||
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
[nc removeObserver:capture->connect_observer];
|
||||
[nc removeObserver:capture->disconnect_observer];
|
||||
|
||||
remove_device(capture);
|
||||
AVFREE(capture->out);
|
||||
@@ -159,6 +166,8 @@ static void av_capture_destroy(void *data)
|
||||
AVFREE(capture->delegate);
|
||||
AVFREE(capture->session);
|
||||
|
||||
AVFREE(capture->uid);
|
||||
|
||||
bfree(capture);
|
||||
}
|
||||
|
||||
@@ -367,27 +376,90 @@ error_input:
|
||||
AVFREE(capture->device);
|
||||
}
|
||||
|
||||
static inline void handle_disconnect(struct av_capture* capture,
|
||||
AVCaptureDevice *dev)
|
||||
{
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
if (![dev.uniqueID isEqualTo:capture->uid])
|
||||
return;
|
||||
|
||||
if (!capture->device) {
|
||||
AVLOG(LOG_ERROR, "Received disconnect for unused device '%s'",
|
||||
capture->uid.UTF8String);
|
||||
return;
|
||||
}
|
||||
|
||||
AVLOG(LOG_ERROR, "Device with unique ID '%s' disconnected",
|
||||
dev.uniqueID.UTF8String);
|
||||
|
||||
remove_device(capture);
|
||||
}
|
||||
|
||||
static inline void handle_connect(struct av_capture *capture,
|
||||
AVCaptureDevice *dev, obs_data_t settings)
|
||||
{
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
if (![dev.uniqueID isEqualTo:capture->uid])
|
||||
return;
|
||||
|
||||
if (capture->device) {
|
||||
AVLOG(LOG_ERROR, "Received connect for in-use device '%s'",
|
||||
capture->uid.UTF8String);
|
||||
return;
|
||||
}
|
||||
|
||||
AVLOG(LOG_INFO, "Device with unique ID '%s' connected, "
|
||||
"resuming capture", dev.uniqueID.UTF8String);
|
||||
|
||||
capture_device(capture, [dev retain], settings);
|
||||
}
|
||||
|
||||
static void av_capture_init(struct av_capture *capture, obs_data_t settings)
|
||||
{
|
||||
if (!init_session(capture))
|
||||
return;
|
||||
|
||||
NSString *uid = get_string(settings, "device");
|
||||
capture->uid = [get_string(settings, "device") retain];
|
||||
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
capture->disconnect_observer = [nc
|
||||
addObserverForName:AVCaptureDeviceWasDisconnectedNotification
|
||||
object:nil
|
||||
queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification *note)
|
||||
{
|
||||
handle_disconnect(capture, note.object);
|
||||
}
|
||||
];
|
||||
|
||||
capture->connect_observer = [nc
|
||||
addObserverForName:AVCaptureDeviceWasConnectedNotification
|
||||
object:nil
|
||||
queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification *note)
|
||||
{
|
||||
handle_connect(capture, note.object, settings);
|
||||
}
|
||||
];
|
||||
|
||||
AVCaptureDevice *dev =
|
||||
[[AVCaptureDevice deviceWithUniqueID:uid] retain];
|
||||
[[AVCaptureDevice deviceWithUniqueID:capture->uid] retain];
|
||||
|
||||
if (!dev) {
|
||||
if (uid.length < 1)
|
||||
if (capture->uid.length < 1)
|
||||
AVLOG(LOG_ERROR, "No device selected");
|
||||
else
|
||||
AVLOG(LOG_ERROR, "Could not initialize device " \
|
||||
"with unique ID '%s'",
|
||||
uid.UTF8String);
|
||||
capture->uid.UTF8String);
|
||||
return;
|
||||
}
|
||||
|
||||
init_with_device(capture, dev, settings);
|
||||
capture_device(capture, dev, settings);
|
||||
}
|
||||
|
||||
static void *av_capture_create(obs_data_t settings, obs_source_t source)
|
||||
@@ -549,6 +621,9 @@ static void switch_device(struct av_capture *capture, NSString *uid,
|
||||
if (capture->device)
|
||||
remove_device(capture);
|
||||
|
||||
AVFREE(capture->uid);
|
||||
capture->uid = [uid retain];
|
||||
|
||||
AVCaptureDevice *dev = [AVCaptureDevice deviceWithUniqueID:uid];
|
||||
if (!dev) {
|
||||
AVLOG(LOG_ERROR, "Device with unique id '%s' not found",
|
||||
|
||||
Reference in New Issue
Block a user