diff --git a/contrib/src/libav/osx.patch b/contrib/src/libav/osx.patch index a4be9a98e89062a6898d78bc3202249eaf75c560..4f885fd6d14fe20309ff7304a90618ad39dac25d 100644 --- a/contrib/src/libav/osx.patch +++ b/contrib/src/libav/osx.patch @@ -242,10 +242,10 @@ index 5dbe277..8439b5b 100644 REGISTER_INDEV (FBDEV, fbdev); diff --git a/libavdevice/avfoundation_dec.m b/libavdevice/avfoundation_dec.m new file mode 100644 -index 0000000..581f845 +index 0000000..f1b9c03 --- /dev/null +++ b/libavdevice/avfoundation_dec.m -@@ -0,0 +1,449 @@ +@@ -0,0 +1,447 @@ +/* + * AVFoundation input device + * Copyright (c) 2015 Luca Barbato @@ -406,7 +406,7 @@ index 0000000..581f845 + +@end + -+NSString *pat = @"(\b[A-Z0-9]+\b)"; ++NSString *pat = @"\\[[^\\].]*\\]"; + +static int setup_stream(AVFormatContext *s, AVCaptureDevice *device) +{ @@ -491,7 +491,6 @@ index 0000000..581f845 + // Take stream info from the first frame. + while (ctx->frames_captured < 1) { + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES); -+ av_log(s, AV_LOG_ERROR, "Waiting for incoming frame\n"); + } + + lock_frames(ctx); @@ -586,8 +585,7 @@ index 0000000..581f845 + if (matches.count > 0) { + for (NSTextCheckingResult *match in matches) { + NSRange range = [match rangeAtIndex:0]; -+ NSString *uniqueID = [filename substringWithRange:range]; -+ av_log(s, AV_LOG_INFO, "opening device with ID: %s\n",[uniqueID UTF8String]); ++ NSString *uniqueID = [filename substringWithRange:NSMakeRange(range.location + 1, range.length-2)]; av_log(s, AV_LOG_INFO, "opening device with ID: %s\n",[uniqueID UTF8String]); + if (!(device = [AVCaptureDevice deviceWithUniqueID:uniqueID])) { + // report error + av_log(s, AV_LOG_ERROR, "Device with name %s not found",[filename UTF8String]); diff --git a/src/media/video/osxvideo/video_device_impl.mm b/src/media/video/osxvideo/video_device_impl.mm index 7d491f98e8f2394e8440fadf112cca0091d41169..ffb26eb5440dc4152a9a756c32a2e1f66930c5ae 100644 --- a/src/media/video/osxvideo/video_device_impl.mm +++ b/src/media/video/osxvideo/video_device_impl.mm @@ -154,13 +154,13 @@ std::vector<std::string> VideoDeviceImpl::getRateList(const std::string& channel, const std::string& size) const { auto format = [avDevice_ activeFormat]; - auto frameRate = (AVFrameRateRange*) - [format.videoSupportedFrameRateRanges objectAtIndex:0]; - std::vector<std::string> v; - std::stringstream ss; - ss << frameRate.maxFrameRate; - v.push_back(ss.str()); + + for (AVFrameRateRange* frameRateRange in format.videoSupportedFrameRateRanges) { + std::stringstream ss; + ss << frameRateRange.maxFrameRate; + v.push_back(ss.str()); + } return v; } @@ -169,14 +169,12 @@ VideoDeviceImpl::getSizeList(const std::string& channel) const { std::vector<std::string> v; - auto format = [avDevice_ activeFormat]; - auto dimensions = - CMVideoFormatDescriptionGetDimensions(format.formatDescription); - - std::stringstream ss; - ss << dimensions.width << "x" << dimensions.height; - v.push_back(ss.str()); - + for (AVCaptureDeviceFormat* format in avDevice_.formats) { + std::stringstream ss; + auto dimensions = CMVideoFormatDescriptionGetDimensions(format.formatDescription); + ss << dimensions.width << "x" << dimensions.height; + v.push_back(ss.str()); + } return v; } diff --git a/src/media/video/osxvideo/video_device_monitor_impl.mm b/src/media/video/osxvideo/video_device_monitor_impl.mm index eb3242be7a87f91fceec284d5de67b99f35d6a48..2eeee8e0f487aaa7d8bfe627b38ae60b90b94bcf 100644 --- a/src/media/video/osxvideo/video_device_monitor_impl.mm +++ b/src/media/video/osxvideo/video_device_monitor_impl.mm @@ -66,19 +66,12 @@ class VideoDeviceMonitorImpl { NON_COPYABLE(VideoDeviceMonitorImpl); VideoDeviceMonitor* monitor_; - - void run(); - - mutable std::mutex mutex_; - std::atomic_bool probing_; - std::thread thread_; + NSArray* observers; }; VideoDeviceMonitorImpl::VideoDeviceMonitorImpl(VideoDeviceMonitor* monitor) : - monitor_(monitor), - mutex_(), probing_(false), - thread_() + monitor_(monitor) { /* Enumerate existing devices */ auto myVideoDevices = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] @@ -95,7 +88,7 @@ VideoDeviceMonitorImpl::VideoDeviceMonitorImpl(VideoDeviceMonitor* monitor) : for ( ivideo = 0; ivideo < deviceCount; ++ivideo ) { AVCaptureDevice* avf_device = [myVideoDevices objectAtIndex:ivideo]; - RING_DBG("avcapture %lu/%lu %s %s", ivideo, + printf("avcapture %d/%d %s %s\n", ivideo + 1, deviceCount, [[avf_device modelID] UTF8String], [[avf_device uniqueID] UTF8String]); @@ -110,23 +103,31 @@ VideoDeviceMonitorImpl::VideoDeviceMonitorImpl(VideoDeviceMonitor* monitor) : void VideoDeviceMonitorImpl::start() { - probing_ = true; - //thread_ = std::thread(&VideoDeviceMonitorImpl::run, this); + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + id deviceWasConnectedObserver = [notificationCenter addObserverForName:AVCaptureDeviceWasConnectedNotification + object:nil + queue:[NSOperationQueue mainQueue] + usingBlock:^(NSNotification *note) { + AVCaptureDevice* dev = (AVCaptureDevice*)note.object; + monitor_->addDevice([[dev uniqueID] UTF8String]); + }]; + id deviceWasDisconnectedObserver = [notificationCenter addObserverForName:AVCaptureDeviceWasDisconnectedNotification + object:nil + queue:[NSOperationQueue mainQueue] + usingBlock:^(NSNotification *note) { + AVCaptureDevice* dev = (AVCaptureDevice*)note.object; + monitor_->removeDevice([[dev uniqueID] UTF8String]); + }]; + observers = [[NSArray alloc] initWithObjects:deviceWasConnectedObserver, deviceWasDisconnectedObserver, nil]; } VideoDeviceMonitorImpl::~VideoDeviceMonitorImpl() { - probing_ = false; - if (thread_.joinable()) - thread_.join(); -} + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + for (id observer in observers) + [notificationCenter removeObserver:observer]; -void VideoDeviceMonitorImpl::run() -{ - while (probing_) { - //TODO: Enable detection of new devices - sleep(1); - } + [observers release]; } VideoDeviceMonitor::VideoDeviceMonitor() :