-
-
Notifications
You must be signed in to change notification settings - Fork 106
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[macos] Camera improvements. Use pixel format in camera, and improve …
…display
- Loading branch information
Showing
7 changed files
with
148 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,143 @@ | ||
#import <AVFoundation/AVFoundation.h> | ||
#include "CameraDevice.hpp" | ||
|
||
#include "CameraSettings.hpp" | ||
#include <functional> | ||
|
||
#include <Gfx/CameraDeviceEnumerator.hpp> | ||
|
||
#import <AVFoundation/AVFoundation.h> | ||
#include <libavutil/pixfmt.h> | ||
|
||
#include <QDebug> | ||
#include <functional> | ||
#include <iostream> | ||
#include <memory> | ||
|
||
namespace Gfx | ||
{ | ||
static void iterateCameraFormats(AVCaptureDevice* device, std::function<void(CameraSettings, QString)> func) | ||
static constexpr int avf_pixelformat_to_ffmpeg(uint32_t fourcc) | ||
{ | ||
const char *name = [[device localizedName] UTF8String]; | ||
for (id format in [device valueForKey:@"formats"]) { | ||
CMFormatDescriptionRef formatDescription{}; | ||
CMVideoDimensions dimensions{}; | ||
switch(fourcc) | ||
{ | ||
case kCMPixelFormat_32ARGB: | ||
return AV_PIX_FMT_ARGB; | ||
case kCMPixelFormat_32BGRA: | ||
return AV_PIX_FMT_BGRA; | ||
case kCMPixelFormat_24RGB: | ||
return AV_PIX_FMT_RGB24; | ||
case kCMPixelFormat_16BE555: | ||
return AV_PIX_FMT_RGB555BE; | ||
case kCMPixelFormat_16BE565: | ||
return AV_PIX_FMT_RGB565BE; | ||
case kCMPixelFormat_16LE555: | ||
return AV_PIX_FMT_RGB555LE; | ||
case kCMPixelFormat_16LE565: | ||
return AV_PIX_FMT_RGB565LE; | ||
case kCMPixelFormat_16LE5551: | ||
return 0; | ||
case 'yuv2': | ||
case 'YUV2': | ||
case 'uyvy': | ||
case 'UYVY': | ||
case kCMPixelFormat_422YpCbCr8: | ||
return AV_PIX_FMT_UYVY422; | ||
case kCMPixelFormat_422YpCbCr8_yuvs: | ||
return AV_PIX_FMT_YUYV422; | ||
case kCMPixelFormat_444YpCbCr8: | ||
return AV_PIX_FMT_YUV444P; // WARNING ! this is planar, macOS's is packed. check that it's ok and ffmpeg assumes the conversion | ||
case kCMPixelFormat_4444YpCbCrA8: | ||
return AV_PIX_FMT_YUVA444P; | ||
case kCMPixelFormat_422YpCbCr16: | ||
return AV_PIX_FMT_YUV422P16LE; | ||
case kCMPixelFormat_422YpCbCr10: | ||
return AV_PIX_FMT_YUV422P10LE; | ||
case kCMPixelFormat_444YpCbCr10: | ||
return AV_PIX_FMT_YUV444P10LE; | ||
case kCMPixelFormat_8IndexedGray_WhiteIsZero: | ||
default: | ||
return -1; | ||
} | ||
} | ||
|
||
formatDescription = (__bridge CMFormatDescriptionRef) [format performSelector:@selector(formatDescription)]; | ||
dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription); | ||
struct AVFCameraEnumerator : public Device::DeviceEnumerator | ||
{ | ||
explicit AVFCameraEnumerator( | ||
std::shared_ptr<CameraDeviceEnumerator> parent, AVCaptureDevice* dev) | ||
: parent{parent} | ||
, device{dev} | ||
{ | ||
} | ||
std::shared_ptr<CameraDeviceEnumerator> parent; | ||
AVCaptureDevice* device{}; | ||
void enumerate(std::function<void(const QString&, const Device::DeviceSettings&)> func) | ||
const override | ||
{ | ||
const char* name = [[device localizedName] UTF8String]; | ||
for(id format in [device valueForKey:@"formats"]) | ||
{ | ||
CMFormatDescriptionRef formatDescription{}; | ||
CMVideoDimensions dimensions{}; | ||
|
||
for (id range in [format valueForKey:@"videoSupportedFrameRateRanges"]) { | ||
double fps{}; | ||
formatDescription = (__bridge CMFormatDescriptionRef) | ||
[format performSelector:@selector(formatDescription)]; | ||
dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription); | ||
auto fourcc = CMFormatDescriptionGetMediaSubType(formatDescription); | ||
std::string_view fcc((const char*)&fourcc, 4); | ||
for(id range in [format valueForKey:@"videoSupportedFrameRateRanges"]) | ||
{ | ||
double fps{}; | ||
|
||
[[range valueForKey:@"maxFrameRate"] getValue:&fps]; | ||
[[range valueForKey:@"maxFrameRate"] getValue:&fps]; | ||
|
||
const auto prettyName = QString("%1 (%2x%3@%4)").arg(name).arg(dimensions.width).arg(dimensions.height).arg(fps); | ||
const auto mode = QString("%1x%2@%3 %4") | ||
.arg(dimensions.width) | ||
.arg(dimensions.height) | ||
.arg(fps) | ||
.arg(std::string(fcc).c_str()); | ||
|
||
func({.input = "avfoundation", .device = name, .size = { dimensions.width, dimensions.height}, .fps = fps }, prettyName); | ||
Device::DeviceSettings s; | ||
CameraSettings set; | ||
set.input = "avfoundation"; | ||
set.device = name; | ||
set.size = {dimensions.width, dimensions.height}; | ||
set.fps = fps; | ||
set.pixelformat = avf_pixelformat_to_ffmpeg(fourcc); | ||
s.name = name; | ||
s.protocol = CameraProtocolFactory::static_concreteKey(); | ||
s.deviceSpecificSettings = QVariant::fromValue(set); | ||
func(mode, s); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
|
||
void enumerateCameraDevices(std::function<void(CameraSettings, QString)> func) | ||
struct AVFCameraDeviceEnumerator : public CameraDeviceEnumerator | ||
{ | ||
void registerAllEnumerators(Device::DeviceEnumerators& enums) override | ||
{ | ||
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; | ||
for (AVCaptureDevice *device in devices) { | ||
iterateCameraFormats(device, func); | ||
auto self = shared_from_this(); | ||
SCORE_ASSERT(self); | ||
|
||
{ | ||
NSArray* devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; | ||
for(AVCaptureDevice* device in devices) | ||
{ | ||
const char* name = [[device localizedName] UTF8String]; | ||
enums.push_back({name, new AVFCameraEnumerator{self, device}}); | ||
} | ||
} | ||
} | ||
|
||
{ | ||
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeMuxed]; | ||
for (AVCaptureDevice *device in devices) { | ||
iterateCameraFormats(device, func); | ||
{ | ||
NSArray* devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeMuxed]; | ||
for(AVCaptureDevice* device in devices) | ||
{ | ||
const char* name = [[device localizedName] UTF8String]; | ||
enums.push_back({name, new AVFCameraEnumerator{self, device}}); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
|
||
std::shared_ptr<CameraDeviceEnumerator> make_camera_enumerator() | ||
{ | ||
return std::make_shared<AVFCameraDeviceEnumerator>(); | ||
} | ||
} // namespace Gfx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
src/plugins/score-plugin-gfx/Gfx/Shmdata/ShmdataInputDevice.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters