diff --git a/qtox.pro b/qtox.pro
index 2cc0f86ec..960a78412 100644
--- a/qtox.pro
+++ b/qtox.pro
@@ -160,6 +160,7 @@ win32 {
QMAKE_INFO_PLIST = osx/info.plist
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -ltoxencryptsave -ltoxdns -lsodium -lvpx -lopus -framework OpenAL -lavformat -lavdevice -lavcodec -lavutil -lswscale -mmacosx-version-min=10.7
+ LIBS += -framework AVFoundation -framework Foundation -framework CoreMedia
LIBS += -lqrencode -lsqlcipher
contains(DEFINES, QTOX_PLATFORM_EXT) { LIBS += -framework IOKit -framework CoreFoundation }
contains(DEFINES, QTOX_FILTER_AUDIO) { LIBS += -lfilteraudio }
@@ -462,7 +463,11 @@ macx {
src/platform/install_osx.cpp
HEADERS += \
- src/platform/install_osx.h
+ src/platform/install_osx.h \
+ src/platform/camera/avfoundation.h
+
+ OBJECTIVE_SOURCES += \
+ src/platform/camera/avfoundation.mm
}
SOURCES += \
diff --git a/src/platform/camera/avfoundation.h b/src/platform/camera/avfoundation.h
new file mode 100644
index 000000000..942074eca
--- /dev/null
+++ b/src/platform/camera/avfoundation.h
@@ -0,0 +1,37 @@
+/*
+ Copyright © 2015 by The qTox Project
+
+ This file is part of qTox, a Qt-based graphical interface for Tox.
+
+ qTox is libre software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ qTox is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with qTox. If not, see .
+*/
+#ifndef AVFOUNDATION_H
+#define AVFOUNDATION_H
+
+#include
+#include
+#include
+#include "src/video/videomode.h"
+
+#ifndef Q_OS_MACX
+#error "This file is only meant to be compiled for Mac OS X targets"
+#endif
+
+namespace avfoundation
+{
+ QVector getDeviceModes(QString devName);
+ QVector> getDeviceList();
+}
+
+#endif // AVFOUNDATION_H
diff --git a/src/platform/camera/avfoundation.mm b/src/platform/camera/avfoundation.mm
new file mode 100644
index 000000000..5f625e17e
--- /dev/null
+++ b/src/platform/camera/avfoundation.mm
@@ -0,0 +1,70 @@
+/*
+ Copyright (c) 2014 Thilo Borgmann
+ Copyright © 2015 by The qTox Project
+
+ This file is part of qTox, a Qt-based graphical interface for Tox.
+
+ qTox is libre software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ qTox is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with qTox. If not, see .
+ */
+
+#include "avfoundation.h"
+
+#import
+
+QVector > avfoundation::getDeviceList()
+{
+ QVector > result;
+
+ NSArray* devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
+ for (AVCaptureDevice* device in devices) {
+ result.append({ QString::fromUtf8([[device uniqueID] UTF8String]), QString::fromUtf8([[device localizedName] UTF8String]) });
+ }
+
+ return result;
+}
+
+QVector avfoundation::getDeviceModes(QString devName)
+{
+ QVector result;
+
+ NSArray* devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
+ AVCaptureDevice* device = nil;
+
+ for (AVCaptureDevice* dev in devices) {
+ if (devName == QString::fromUtf8([[dev uniqueID] UTF8String])) {
+ device = dev;
+ break;
+ }
+ }
+ if (device == nil) {
+ return result;
+ }
+
+ for (AVCaptureDeviceFormat* format in [device formats]) {
+ CMFormatDescriptionRef formatDescription;
+ CMVideoDimensions dimensions;
+ formatDescription = (CMFormatDescriptionRef)[format performSelector:@selector(formatDescription)];
+ dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription);
+
+ for (AVFrameRateRange* range in format.videoSupportedFrameRateRanges) {
+ VideoMode mode;
+ mode.width = dimensions.width;
+ mode.height = dimensions.height;
+ mode.FPS = range.maxFrameRate;
+ result.append(mode);
+ }
+ }
+
+ return result;
+}
diff --git a/src/video/cameradevice.cpp b/src/video/cameradevice.cpp
index 96c1ec3fa..d9cab566a 100644
--- a/src/video/cameradevice.cpp
+++ b/src/video/cameradevice.cpp
@@ -34,6 +34,9 @@ extern "C" {
#ifdef Q_OS_LINUX
#include "src/platform/camera/v4l2.h"
#endif
+#ifdef Q_OS_OSX
+#include "src/platform/camera/avfoundation.h"
+#endif
QHash CameraDevice::openDevices;
QMutex CameraDevice::openDeviceLock, CameraDevice::iformatLock;
@@ -162,6 +165,13 @@ CameraDevice* CameraDevice::open(QString devName, VideoMode mode)
av_dict_set(&options, "video_size", QString("%1x%2").arg(mode.width).arg(mode.height).toStdString().c_str(), 0);
av_dict_set(&options, "framerate", QString().setNum(mode.FPS).toStdString().c_str(), 0);
}
+#endif
+#ifdef Q_OS_OSX
+ else if (iformat->name == QString("avfoundation") && mode)
+ {
+ av_dict_set(&options, "video_size", QString("%1x%2").arg(mode.width).arg(mode.height).toStdString().c_str(), 0);
+ av_dict_set(&options, "framerate", QString().setNum(mode.FPS).toStdString().c_str(), 0);
+ }
#endif
else if (mode)
{
@@ -281,6 +291,10 @@ QVector> CameraDevice::getDeviceList()
#ifdef Q_OS_LINUX
else if (iformat->name == QString("video4linux2,v4l2"))
devices += v4l2::getDeviceList();
+#endif
+#ifdef Q_OS_OSX
+ else if (iformat->name == QString("avfoundation"))
+ devices += avfoundation::getDeviceList();
#endif
else
devices += getRawDeviceListGeneric();
@@ -324,6 +338,10 @@ QVector CameraDevice::getVideoModes(QString devName)
#ifdef Q_OS_LINUX
else if (iformat->name == QString("video4linux2,v4l2"))
return v4l2::getDeviceModes(devName);
+#endif
+#ifdef Q_OS_OSX
+ else if (iformat->name == QString("avfoundation"))
+ return avfoundation::getDeviceModes(devName);
#endif
else
qWarning() << "Video mode listing not implemented for input "<name;
diff --git a/src/video/videomode.h b/src/video/videomode.h
index ff76c063b..d3e17f98b 100644
--- a/src/video/videomode.h
+++ b/src/video/videomode.h
@@ -25,7 +25,7 @@
struct VideoMode
{
unsigned short width, height; ///< Displayed video resolution (NOT frame resolution)
- unsigned short FPS; ///< Max frames per second supported by the device at this resolution
+ float FPS; ///< Max frames per second supported by the device at this resolution
/// All zeros means a default/unspecified mode
operator bool() const