1414
1515#include < cstdlib>
1616
17+ extern " C" {
18+ #include < libavdevice/avdevice.h>
19+ }
20+
1721#include " Exceptions.h"
1822
1923using namespace openshot ;
@@ -38,6 +42,8 @@ bool CameraCaptureReader::IsBackendSupported(CameraCaptureBackend backend)
3842{
3943#if defined(__linux__)
4044 return backend == CAMERA_CAPTURE_V4L2 || backend == CAMERA_CAPTURE_AUTO ;
45+ #elif defined(_WIN32)
46+ return backend == CAMERA_CAPTURE_WINDOWS_DSHOW || backend == CAMERA_CAPTURE_AUTO ;
4147#else
4248 (void ) backend;
4349 return false ;
@@ -48,18 +54,78 @@ CameraCaptureBackend CameraCaptureReader::DefaultBackend()
4854{
4955#if defined(__linux__)
5056 return CAMERA_CAPTURE_V4L2 ;
57+ #elif defined(_WIN32)
58+ return CAMERA_CAPTURE_WINDOWS_DSHOW ;
5159#else
5260 return CAMERA_CAPTURE_AUTO ;
5361#endif
5462}
5563
64+ AudioDeviceList CameraCaptureReader::GetDeviceNames (CameraCaptureBackend backend)
65+ {
66+ if (backend == CAMERA_CAPTURE_AUTO ) {
67+ backend = DefaultBackend ();
68+ }
69+
70+ AudioDeviceList devices;
71+ const char * input_format_name = nullptr ;
72+ #if defined(__linux__)
73+ if (backend == CAMERA_CAPTURE_V4L2 ) {
74+ input_format_name = " v4l2" ;
75+ }
76+ #elif defined(_WIN32)
77+ if (backend == CAMERA_CAPTURE_WINDOWS_DSHOW ) {
78+ input_format_name = " dshow" ;
79+ }
80+ #endif
81+ if (!input_format_name) {
82+ return devices;
83+ }
84+
85+ avdevice_register_all ();
86+ const AVInputFormat* input_format = av_find_input_format (input_format_name);
87+ if (!input_format) {
88+ return devices;
89+ }
90+
91+ AVDeviceInfoList* device_list = nullptr ;
92+ const int result = avdevice_list_input_sources (input_format, nullptr , nullptr , &device_list);
93+ if (result >= 0 && device_list) {
94+ for (int index = 0 ; index < device_list->nb_devices ; ++index) {
95+ const AVDeviceInfo* device = device_list->devices [index];
96+ if (!device || !device->device_name ) {
97+ continue ;
98+ }
99+ if (device->nb_media_types > 0 && device->media_types ) {
100+ bool has_video = false ;
101+ for (int media_index = 0 ; media_index < device->nb_media_types ; ++media_index) {
102+ if (device->media_types [media_index] == AVMEDIA_TYPE_VIDEO ) {
103+ has_video = true ;
104+ break ;
105+ }
106+ }
107+ if (!has_video) {
108+ continue ;
109+ }
110+ }
111+ const std::string name = device->device_name ;
112+ const std::string label = device->device_description
113+ ? device->device_description
114+ : device->device_name ;
115+ devices.emplace_back (label, name);
116+ }
117+ }
118+ avdevice_free_list_devices (&device_list);
119+ return devices;
120+ }
121+
56122void CameraCaptureReader::ValidateSettings () const
57123{
58124 if (!IsBackendSupported (settings.backend )) {
59125 throw InvalidOptions (" Camera capture backend is not supported on this OS." );
60126 }
61- if (settings.backend != CAMERA_CAPTURE_V4L2 ) {
62- throw InvalidOptions (" Only the v4l2 camera capture backend is implemented in this build." );
127+ if (settings.backend != CAMERA_CAPTURE_V4L2 && settings. backend != CAMERA_CAPTURE_WINDOWS_DSHOW ) {
128+ throw InvalidOptions (" Camera capture backend is not implemented in this build." );
63129 }
64130 if (settings.device .empty ()) {
65131 throw InvalidOptions (" Camera capture requires a device path." );
@@ -75,13 +141,19 @@ void CameraCaptureReader::ValidateSettings() const
75141ScreenCaptureSettings CameraCaptureReader::ToDeviceSettings () const
76142{
77143 ScreenCaptureSettings converted;
78- converted.backend = SCREEN_CAPTURE_X11 ;
79144 converted.display = settings.device ;
80145 converted.width = settings.width ;
81146 converted.height = settings.height ;
82147 converted.fps = settings.fps ;
83148 converted.options = settings.options ;
84- converted.options [" input_format_name" ] = " v4l2" ;
149+ if (settings.backend == CAMERA_CAPTURE_WINDOWS_DSHOW ) {
150+ converted.backend = SCREEN_CAPTURE_WINDOWS_GDI ;
151+ converted.display = " video=" + settings.device ;
152+ converted.options [" input_format_name" ] = " dshow" ;
153+ } else {
154+ converted.backend = SCREEN_CAPTURE_X11 ;
155+ converted.options [" input_format_name" ] = " v4l2" ;
156+ }
85157 return converted;
86158}
87159
0 commit comments