Commit 4bb2a506 authored by Alexandre Lision's avatar Alexandre Lision Committed by Alexandre Lision

video: add switching input for osx

- devices are refreshed during runtime
- resolutions and rates properly listed
- one channel by device

Refs #66543

Change-Id: Ic554786d1930a28f25c7d603ef405b77f2a85746
parent 93843c34
......@@ -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]);
......
......@@ -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;
}
......
......@@ -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() :
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment