MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
FFmpegCameraDiscovery.cpp
Go to the documentation of this file.
2
3extern "C" {
4#include <libavdevice/avdevice.h>
5#include <libavformat/avformat.h>
6}
7
8#ifdef MAYAFLUX_PLATFORM_LINUX
9#include <fcntl.h>
10#include <linux/videodev2.h>
11#include <sys/ioctl.h>
12#include <unistd.h>
13#endif
14
15namespace MayaFlux::IO {
16
17#ifdef MAYAFLUX_PLATFORM_MACOS
18std::vector<CameraConfig> enumerate_macos_cameras();
19#endif
20
21#ifndef MAYAFLUX_PLATFORM_MACOS
22namespace {
23
24 bool provides_video(const AVDeviceInfo& info)
25 {
26 if (info.nb_media_types == 0)
27 return true;
28 return std::ranges::find(
29 std::span(info.media_types, static_cast<size_t>(info.nb_media_types)),
30 AVMEDIA_TYPE_VIDEO)
31 != std::span(info.media_types, static_cast<size_t>(info.nb_media_types)).end();
32 }
33
34#ifdef MAYAFLUX_PLATFORM_LINUX
35 bool can_capture(const std::string& path)
36 {
37 const int fd = ::open(path.c_str(), O_RDONLY | O_NONBLOCK);
38 if (fd < 0)
39 return false;
40
41 v4l2_capability capability {};
42 const bool queried = ::ioctl(fd, VIDIOC_QUERYCAP, &capability) == 0;
43 ::close(fd);
44 if (!queried)
45 return false;
46
47 const uint32_t caps = (capability.capabilities & V4L2_CAP_DEVICE_CAPS)
48 ? capability.device_caps
49 : capability.capabilities;
50 return (caps & V4L2_CAP_VIDEO_CAPTURE) != 0;
51 }
52#endif
53
54}
55#endif
56
57std::vector<CameraConfig> FFmpegCameraReader::enumerate_configs() const
58{
59#ifdef MAYAFLUX_PLATFORM_MACOS
60 return enumerate_macos_cameras();
61#else
62 std::vector<CameraConfig> configs;
63
64 avdevice_register_all();
65 const AVInputFormat* format = av_find_input_format(std::string(CAMERA_FORMAT).c_str());
66 AVDeviceInfoList* list = nullptr;
67 if (!format || avdevice_list_input_sources(format, nullptr, nullptr, &list) < 0)
68 return configs;
69
70 for (int i = 0; i < list->nb_devices; ++i) {
71 const AVDeviceInfo& info = *list->devices[i];
72 if (!provides_video(info))
73 continue;
74
75 CameraConfig config;
76 config.device_name = info.device_name;
77 config.display_name = info.device_description ? info.device_description : "";
78#ifdef MAYAFLUX_PLATFORM_WINDOWS
79 config.device_name.insert(0, "video=");
80#endif
81#ifdef MAYAFLUX_PLATFORM_LINUX
82 if (!can_capture(config.device_name))
83 continue;
84#endif
85 configs.push_back(std::move(config));
86 }
87 avdevice_free_list_devices(&list);
88
89 std::ranges::sort(configs, {}, &CameraConfig::device_name);
90 return configs;
91#endif
92}
93
94}
bool format
std::vector< CameraConfig > enumerate_configs() const override
Discover ready-to-open camera configurations without starting capture.
std::string device_name
Platform device string.
std::string display_name
Human-readable device name for a chooser.
Configuration for opening a camera device via FFmpeg.