Skip to content

Commit 7cc297f

Browse files
authored
feat: added the missing macOS camera capture functionality (#180)
* feat: implement macOS video capture support with Objective-C integration * refactor: unify video capture classes under VideoCaptureBase * feat: implement VideoTrackDeviceSourceBase and macOS specific video capture support * feat: update macOS video capture to use VideoTrackDeviceSourceMac * feat: enhance macOS video capture with improved frame handling and callback integration * fix: update macOS deployment target to 11.0 and refine CMake configurations
1 parent 112f0fb commit 7cc297f

21 files changed

Lines changed: 787 additions & 91 deletions

webrtc-jni/src/main/cpp/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ target_link_libraries(${PROJECT_NAME} webrtc)
9898

9999
if(APPLE)
100100
set_source_files_properties(${SOURCES} PROPERTIES COMPILE_FLAGS "-x objective-c++")
101-
target_link_libraries(${PROJECT_NAME} "-framework Foundation" "-framework AVFoundation" "-framework CoreMedia" "-framework CoreAudio" "-framework IOKit")
101+
target_link_libraries(${PROJECT_NAME} "-framework Foundation" "-framework AVFoundation" "-framework CoreMedia" "-framework CoreAudio" "-framework IOKit" "-framework CoreVideo" "-framework VideoToolbox")
102102
elseif(LINUX)
103103
if(NOT TARGET_CPU MATCHES "^arm")
104104
set(CXX_LIBS "-static-libgcc -stdlib=libc++ -lc++ -lc++abi")

webrtc-jni/src/main/cpp/dependencies/webrtc/CMakeLists.txt

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@ target_include_directories(${PROJECT_NAME}
159159
target_link_libraries(${PROJECT_NAME} ${TARGET_LINK_LIB})
160160

161161
if(APPLE)
162+
target_include_directories(${PROJECT_NAME}
163+
PUBLIC
164+
${TARGET_INC_DIR}/sdk/objc
165+
${TARGET_INC_DIR}/sdk/objc/base
166+
)
162167
target_compile_definitions(${PROJECT_NAME} PUBLIC WEBRTC_MAC WEBRTC_POSIX)
163168
target_link_libraries(${PROJECT_NAME} "-framework Foundation" "-framework AVFoundation" "-framework CoreGraphics" "-framework CoreAudio" "-framework CoreVideo" "-framework ScreenCaptureKit" "-framework AudioToolbox" "-framework IOSurface" "-framework ApplicationServices" "-framework AppKit")
164169
elseif(LINUX)
@@ -277,10 +282,23 @@ execute_command(
277282
)
278283

279284
message(STATUS "WebRTC: compile")
280-
execute_command(
281-
COMMAND ninja -C "${WEBRTC_BUILD}"
282-
WORKING_DIRECTORY "${WEBRTC_SRC}"
283-
)
285+
if(APPLE)
286+
execute_command(
287+
COMMAND ninja -C "${WEBRTC_BUILD}" :default sdk:native_api sdk:videocapture_objc
288+
WORKING_DIRECTORY "${WEBRTC_SRC}"
289+
)
290+
291+
file(GLOB_RECURSE SDK_OBJC_FILES ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/*.o)
292+
293+
execute_command(
294+
COMMAND ${CMAKE_AR} rc ${WEBRTC_SRC}/${WEBRTC_BUILD}/obj/libwebrtc.a ${SDK_OBJC_FILES}
295+
)
296+
else()
297+
execute_command(
298+
COMMAND ninja -C "${WEBRTC_BUILD}"
299+
WORKING_DIRECTORY "${WEBRTC_SRC}"
300+
)
301+
endif()
284302

285303
if(LINUX)
286304
if(LINUX AND NOT TARGET_CPU MATCHES "^arm")
@@ -338,7 +356,7 @@ install(
338356
REGEX /src/examples/ EXCLUDE
339357
REGEX /src/out/ EXCLUDE
340358
REGEX /src/resources/ EXCLUDE
341-
REGEX /src/sdk/ EXCLUDE
359+
REGEX /src/sdk/android/ EXCLUDE
342360
REGEX /src/stats/ EXCLUDE
343361
REGEX /src/style-guide/ EXCLUDE
344362
REGEX /src/test/ EXCLUDE
@@ -348,6 +366,7 @@ install(
348366
REGEX /src/tools_webrtc/ EXCLUDE
349367
REGEX /test/ EXCLUDE
350368
)
369+
351370
# Delete empty directories
352371
install(CODE "
353372
file(GLOB_RECURSE headers LIST_DIRECTORIES true ${WEBRTC_INSTALL_DIR}/include/!*)

webrtc-jni/src/main/cpp/include/media/video/VideoCapture.h

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,24 @@
1717
#ifndef JNI_WEBRTC_MEDIA_VIDEO_CAPTURE_H_
1818
#define JNI_WEBRTC_MEDIA_VIDEO_CAPTURE_H_
1919

20-
#include "media/video/VideoDevice.h"
20+
#include "media/video/VideoCaptureBase.h"
2121

22-
#include "api/create_peerconnection_factory.h"
23-
#include "api/video/video_sink_interface.h"
24-
#include "media/base/video_adapter.h"
2522
#include "modules/video_capture/video_capture.h"
2623
#include "modules/video_capture/video_capture_defines.h"
2724

2825
namespace jni
2926
{
30-
class VideoCapture
27+
class VideoCapture : public VideoCaptureBase
3128
{
3229
public:
3330
VideoCapture();
3431
~VideoCapture();
3532

36-
void setDevice(const avdev::DevicePtr & device);
37-
void setVideoCaptureCapability(const webrtc::VideoCaptureCapability & capability);
38-
void setVideoSink(std::unique_ptr<webrtc::VideoSinkInterface<webrtc::VideoFrame>> sink);
39-
void start();
40-
void stop();
41-
void destroy();
33+
void start() override;
34+
void stop() override;
35+
void destroy() override;
4236

4337
private:
44-
avdev::DevicePtr device;
45-
webrtc::VideoCaptureCapability capability;
46-
std::unique_ptr<webrtc::VideoSinkInterface<webrtc::VideoFrame>> sink;
47-
4838
webrtc::scoped_refptr<webrtc::VideoCaptureModule> captureModule;
4939
};
5040
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2021 Alex Andres
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef JNI_WEBRTC_MEDIA_VIDEO_CAPTURE_BASE_H_
18+
#define JNI_WEBRTC_MEDIA_VIDEO_CAPTURE_BASE_H_
19+
20+
#include "media/video/VideoDevice.h"
21+
22+
#include "api/video/video_sink_interface.h"
23+
#include "modules/video_capture/video_capture_defines.h"
24+
25+
namespace jni
26+
{
27+
class VideoCaptureBase
28+
{
29+
public:
30+
VideoCaptureBase();
31+
~VideoCaptureBase();
32+
33+
void setDevice(const avdev::DevicePtr & device);
34+
void setVideoCaptureCapability(const webrtc::VideoCaptureCapability & capability);
35+
void setVideoSink(std::unique_ptr<webrtc::VideoSinkInterface<webrtc::VideoFrame>> sink);
36+
37+
virtual void start() = 0;
38+
virtual void stop() = 0;
39+
virtual void destroy() = 0;
40+
41+
protected:
42+
avdev::DevicePtr device;
43+
webrtc::VideoCaptureCapability capability;
44+
std::unique_ptr<webrtc::VideoSinkInterface<webrtc::VideoFrame>> sink;
45+
};
46+
}
47+
48+
#endif

webrtc-jni/src/main/cpp/include/media/video/VideoTrackDeviceSource.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,20 @@
2626
#include "modules/video_capture/video_capture.h"
2727
#include "modules/video_capture/video_capture_defines.h"
2828

29+
#include "media/video/VideoTrackDeviceSourceBase.h"
2930
#include "media/video/VideoDevice.h"
3031

3132
namespace jni
3233
{
33-
class VideoTrackDeviceSource : public webrtc::VideoTrackSource, public webrtc::VideoSinkInterface<webrtc::VideoFrame>
34+
class VideoTrackDeviceSource : public webrtc::VideoTrackSource, public webrtc::VideoSinkInterface<webrtc::VideoFrame>, public VideoTrackDeviceSourceBase
3435
{
3536
public:
3637
VideoTrackDeviceSource();
3738
~VideoTrackDeviceSource();
3839

39-
void setVideoDevice(const avdev::VideoDevicePtr & device);
40-
void setVideoCaptureCapability(const webrtc::VideoCaptureCapability & capability);
41-
42-
void start();
43-
void stop();
40+
// VideoTrackDeviceSourceBase implementation.
41+
void start() override;
42+
void stop() override;
4443

4544
// VideoSourceInterface implementation.
4645
void AddOrUpdateSink(webrtc::VideoSinkInterface<webrtc::VideoFrame> * sink, const webrtc::VideoSinkWants & wants) override;
@@ -58,9 +57,6 @@ namespace jni
5857
void destroy();
5958

6059
private:
61-
avdev::VideoDevicePtr device;
62-
webrtc::VideoCaptureCapability capability;
63-
6460
webrtc::scoped_refptr<webrtc::VideoCaptureModule> captureModule;
6561
webrtc::VideoBroadcaster broadcaster;
6662
webrtc::VideoAdapter videoAdapter;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright 2019 Alex Andres
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef JNI_WEBRTC_MEDIA_VIDEO_TRACK_DEVICE_SOURCE_BASE_H_
18+
#define JNI_WEBRTC_MEDIA_VIDEO_TRACK_DEVICE_SOURCE_BASE_H_
19+
20+
#include "modules/video_capture/video_capture_defines.h"
21+
22+
#include "media/video/VideoDevice.h"
23+
24+
namespace jni
25+
{
26+
class VideoTrackDeviceSourceBase
27+
{
28+
public:
29+
VideoTrackDeviceSourceBase();
30+
~VideoTrackDeviceSourceBase();
31+
32+
void setVideoDevice(const avdev::VideoDevicePtr & device);
33+
void setVideoCaptureCapability(const webrtc::VideoCaptureCapability & capability);
34+
35+
virtual void start() = 0;
36+
virtual void stop() = 0;
37+
38+
protected:
39+
avdev::VideoDevicePtr device;
40+
webrtc::VideoCaptureCapability capability;
41+
};
42+
}
43+
44+
#endif
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2021 Alex Andres
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef JNI_WEBRTC_MEDIA_VIDEO_CAPTURE_MAC_H_
18+
#define JNI_WEBRTC_MEDIA_VIDEO_CAPTURE_MAC_H_
19+
20+
#include "media/video/VideoCaptureBase.h"
21+
22+
#include "rtc_base/timestamp_aligner.h"
23+
24+
#include "sdk/objc/base/RTCVideoCapturer.h"
25+
#include "sdk/objc/base/RTCMacros.h"
26+
#include "sdk/objc/components/capturer/RTCCameraVideoCapturer.h"
27+
28+
29+
@interface VideoCaptureCallback
30+
: NSObject <RTC_OBJC_TYPE (RTCVideoCapturerDelegate)>
31+
@end
32+
33+
34+
namespace jni
35+
{
36+
class VideoCaptureMac : public VideoCaptureBase
37+
{
38+
public:
39+
VideoCaptureMac();
40+
~VideoCaptureMac();
41+
42+
void start() override;
43+
void stop() override;
44+
void destroy() override;
45+
46+
void OnCapturedFrame(RTC_OBJC_TYPE(RTCVideoFrame) * frame);
47+
48+
private:
49+
webrtc::TimestampAligner timestamp_aligner;
50+
RTCCameraVideoCapturer * cameraVideoCapturer;
51+
};
52+
}
53+
54+
#endif
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2019 Alex Andres
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef JNI_WEBRTC_MEDIA_VIDEO_TRACK_DEVICE_SOURCE_MAC_H_
18+
#define JNI_WEBRTC_MEDIA_VIDEO_TRACK_DEVICE_SOURCE_MAC_H_
19+
20+
#include "media/base/adapted_video_track_source.h"
21+
#include "modules/video_capture/video_capture_defines.h"
22+
#include "rtc_base/timestamp_aligner.h"
23+
24+
#include "sdk/objc/base/RTCVideoCapturer.h"
25+
#include "sdk/objc/base/RTCMacros.h"
26+
#include "sdk/objc/components/capturer/RTCCameraVideoCapturer.h"
27+
28+
#include "media/video/VideoTrackDeviceSourceBase.h"
29+
30+
31+
@interface VideoTrackDeviceSourceCallback
32+
: NSObject <RTC_OBJC_TYPE (RTCVideoCapturerDelegate)>
33+
@end
34+
35+
36+
namespace jni
37+
{
38+
class VideoTrackDeviceSourceMac : public webrtc::AdaptedVideoTrackSource, public VideoTrackDeviceSourceBase
39+
{
40+
public:
41+
VideoTrackDeviceSourceMac();
42+
~VideoTrackDeviceSourceMac();
43+
44+
// VideoTrackDeviceSourceBase implementation.
45+
void start() override;
46+
void stop() override;
47+
48+
// AdaptedVideoTrackSource implementation.
49+
virtual bool is_screencast() const override;
50+
virtual std::optional<bool> needs_denoising() const override;
51+
SourceState state() const override;
52+
bool remote() const override;
53+
54+
void OnCapturedFrame(RTC_OBJC_TYPE(RTCVideoFrame) * frame);
55+
56+
private:
57+
void destroy();
58+
59+
private:
60+
webrtc::TimestampAligner timestamp_aligner;
61+
62+
RTCCameraVideoCapturer * cameraVideoCapturer;
63+
};
64+
}
65+
66+
#endif

webrtc-jni/src/main/cpp/src/JNI_PeerConnectionFactory.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,13 @@ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_PeerConnectionFactory_initialize
5858

5959
try {
6060
auto networkThread = webrtc::Thread::CreateWithSocketServer();
61+
networkThread->SetName("webrtc_jni_network_thread", nullptr);
62+
6163
auto signalingThread = webrtc::Thread::Create();
64+
signalingThread->SetName("webrtc_jni_signaling_thread", nullptr);
65+
6266
auto workerThread = webrtc::Thread::Create();
67+
workerThread->SetName("webrtc_jni_worker_thread", nullptr);
6368

6469
if (!networkThread->Start()) {
6570
throw jni::Exception("Start network thread failed");

0 commit comments

Comments
 (0)