diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eb76ef7cac..63fe195530 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -136,7 +136,7 @@ jobs: - name: Install ninja-build libgtk-3-dev run: sudo apt-get install -y ninja-build libgtk-3-dev - name: Install elinux - run: git clone https://github.com/sony/flutter-elinux.git ~/flutter-elinux + run: git clone https://github.com/sony/flutter-elinux.git -b 3.27.1 ~/flutter-elinux - name: Build for elinux working-directory: ./example run: /home/runner/flutter-elinux/bin/flutter-elinux pub get && /home/runner/flutter-elinux/bin/flutter-elinux build elinux diff --git a/CHANGELOG.md b/CHANGELOG.md index 6120e9fb8c..f4687f52a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # Changelog +[0.14.2] - 2025-07-01 + +* [Windows/Linux] feat: Add audio processing and sink API for cpp. (#1867) +* [Linux] fix: Fixed audio device selection error for Linux. (#1864) +* [Android] fix: Fix screen capture orientation for landscape-native devices (#1854) + [0.14.1] - 2025-05-22 * [Android] fix: Recording bug (#1839) diff --git a/android/src/main/java/com/cloudwebrtc/webrtc/OrientationAwareScreenCapturer.java b/android/src/main/java/com/cloudwebrtc/webrtc/OrientationAwareScreenCapturer.java index 13a46c4964..7bee5d0dc2 100644 --- a/android/src/main/java/com/cloudwebrtc/webrtc/OrientationAwareScreenCapturer.java +++ b/android/src/main/java/com/cloudwebrtc/webrtc/OrientationAwareScreenCapturer.java @@ -15,6 +15,7 @@ import android.view.WindowManager; import android.app.Activity; import android.hardware.display.DisplayManager; +import android.util.DisplayMetrics; import android.hardware.display.VirtualDisplay; import android.media.projection.MediaProjectionManager; import android.os.Looper; @@ -76,9 +77,11 @@ public void onFrame(VideoFrame frame) { } private boolean isDeviceOrientationPortrait() { - final int surfaceRotation = windowManager.getDefaultDisplay().getRotation(); - - return surfaceRotation != Surface.ROTATION_90 && surfaceRotation != Surface.ROTATION_270; + final Display display = windowManager.getDefaultDisplay(); + final DisplayMetrics metrics = new DisplayMetrics(); + display.getRealMetrics(metrics); + + return metrics.heightPixels > metrics.widthPixels; } diff --git a/common/cpp/include/flutter_webrtc_base.h b/common/cpp/include/flutter_webrtc_base.h index 9edabc7680..e894978ab1 100644 --- a/common/cpp/include/flutter_webrtc_base.h +++ b/common/cpp/include/flutter_webrtc_base.h @@ -12,6 +12,7 @@ #include "libwebrtc.h" #include "rtc_audio_device.h" +#include "rtc_audio_processing.h" #include "rtc_desktop_device.h" #include "rtc_dtmf_sender.h" #include "rtc_media_stream.h" @@ -21,8 +22,6 @@ #include "rtc_peerconnection_factory.h" #include "rtc_video_device.h" -#include "uuidxx.h" - namespace flutter_webrtc_plugin { using namespace libwebrtc; @@ -46,14 +45,18 @@ class FlutterWebRTCBase { FlutterWebRTCBase(BinaryMessenger* messenger, TextureRegistrar* textures, TaskRunner* task_runner); ~FlutterWebRTCBase(); + virtual scoped_refptr audio_processing() { + return audio_processing_; + } + + virtual scoped_refptr MediaTrackForId(const std::string& id); + std::string GenerateUUID(); RTCPeerConnection* PeerConnectionForId(const std::string& id); void RemovePeerConnectionForId(const std::string& id); - RTCMediaTrack* MediaTrackForId(const std::string& id); - void RemoveMediaTrackForId(const std::string& id); FlutterPeerConnectionObserver* PeerConnectionObserversForId( @@ -104,6 +107,7 @@ class FlutterWebRTCBase { scoped_refptr audio_device_; scoped_refptr video_device_; scoped_refptr desktop_device_; + scoped_refptr audio_processing_; RTCConfiguration configuration_; std::map> peerconnections_; diff --git a/common/cpp/src/flutter_media_stream.cc b/common/cpp/src/flutter_media_stream.cc index 324dbdc4ce..3f7a7a97a9 100644 --- a/common/cpp/src/flutter_media_stream.cc +++ b/common/cpp/src/flutter_media_stream.cc @@ -288,7 +288,6 @@ void FlutterMediaStream::GetUserVideo(const EncodableMap& constraints, if (!video_capturer.get()) return; - video_capturer->StartCapture(); const char* video_source_label = "video_input"; @@ -333,10 +332,11 @@ void FlutterMediaStream::GetSources(std::unique_ptr result) { for (uint16_t i = 0; i < nb_audio_devices; i++) { base_->audio_device_->RecordingDeviceName(i, strNameUTF8, strGuidUTF8); + std::string device_id = strlen(strGuidUTF8) > 0 ? std::string(strGuidUTF8) + : std::string(strNameUTF8); EncodableMap audio; audio[EncodableValue("label")] = EncodableValue(std::string(strNameUTF8)); - audio[EncodableValue("deviceId")] = - EncodableValue(std::string(strGuidUTF8)); + audio[EncodableValue("deviceId")] = EncodableValue(device_id); audio[EncodableValue("facing")] = ""; audio[EncodableValue("kind")] = "audioinput"; sources.push_back(EncodableValue(audio)); @@ -345,10 +345,11 @@ void FlutterMediaStream::GetSources(std::unique_ptr result) { nb_audio_devices = base_->audio_device_->PlayoutDevices(); for (uint16_t i = 0; i < nb_audio_devices; i++) { base_->audio_device_->PlayoutDeviceName(i, strNameUTF8, strGuidUTF8); + std::string device_id = strlen(strGuidUTF8) > 0 ? std::string(strGuidUTF8) + : std::string(strNameUTF8); EncodableMap audio; audio[EncodableValue("label")] = EncodableValue(std::string(strNameUTF8)); - audio[EncodableValue("deviceId")] = - EncodableValue(std::string(strGuidUTF8)); + audio[EncodableValue("deviceId")] = EncodableValue(device_id); audio[EncodableValue("facing")] = ""; audio[EncodableValue("kind")] = "audiooutput"; sources.push_back(EncodableValue(audio)); @@ -373,13 +374,16 @@ void FlutterMediaStream::GetSources(std::unique_ptr result) { void FlutterMediaStream::SelectAudioOutput( const std::string& device_id, std::unique_ptr result) { - char strPlayoutName[256]; - char strPlayoutGuid[256]; + char deviceName[256]; + char deviceGuid[256]; int playout_devices = base_->audio_device_->PlayoutDevices(); bool found = false; for (uint16_t i = 0; i < playout_devices; i++) { - base_->audio_device_->PlayoutDeviceName(i, strPlayoutName, strPlayoutGuid); - if (device_id != "" && device_id == strPlayoutGuid) { + base_->audio_device_->PlayoutDeviceName(i, deviceName, deviceGuid); + std::string cur_device_id = strlen(deviceGuid) > 0 + ? std::string(deviceGuid) + : std::string(deviceName); + if (device_id != "" && device_id == cur_device_id) { base_->audio_device_->SetPlayoutDevice(i); found = true; break; @@ -395,14 +399,16 @@ void FlutterMediaStream::SelectAudioOutput( void FlutterMediaStream::SelectAudioInput( const std::string& device_id, std::unique_ptr result) { - char strPlayoutName[256]; - char strPlayoutGuid[256]; + char deviceName[256]; + char deviceGuid[256]; int playout_devices = base_->audio_device_->RecordingDevices(); bool found = false; for (uint16_t i = 0; i < playout_devices; i++) { - base_->audio_device_->RecordingDeviceName(i, strPlayoutName, - strPlayoutGuid); - if (device_id != "" && device_id == strPlayoutGuid) { + base_->audio_device_->RecordingDeviceName(i, deviceName, deviceGuid); + std::string cur_device_id = strlen(deviceGuid) > 0 + ? std::string(deviceGuid) + : std::string(deviceName); + if (device_id != "" && device_id == cur_device_id) { base_->audio_device_->SetRecordingDevice(i); found = true; break; @@ -538,14 +544,14 @@ void FlutterMediaStream::MediaStreamTrackDispose( if (track->id().std_string() == track_id) { stream->RemoveTrack(track); - if (base_->video_capturers_.find(track_id) != - base_->video_capturers_.end()) { - auto video_capture = base_->video_capturers_[track_id]; - if (video_capture->CaptureStarted()) { - video_capture->StopCapture(); + if (base_->video_capturers_.find(track_id) != + base_->video_capturers_.end()) { + auto video_capture = base_->video_capturers_[track_id]; + if (video_capture->CaptureStarted()) { + video_capture->StopCapture(); + } + base_->video_capturers_.erase(track_id); } - base_->video_capturers_.erase(track_id); - } } } } diff --git a/common/cpp/src/flutter_webrtc.cc b/common/cpp/src/flutter_webrtc.cc index a402e47ed9..5e0afb6e17 100644 --- a/common/cpp/src/flutter_webrtc.cc +++ b/common/cpp/src/flutter_webrtc.cc @@ -352,7 +352,8 @@ void FlutterWebRTC::HandleMethodCall( return; } DataChannelSend(data_channel, type, data, std::move(result)); - } else if (method_call.method_name().compare("dataChannelGetBufferedAmount") == 0) { + } else if (method_call.method_name().compare( + "dataChannelGetBufferedAmount") == 0) { if (!method_call.arguments()) { result->Error("Bad Arguments", "Null constraints arguments received"); return; diff --git a/common/cpp/src/flutter_webrtc_base.cc b/common/cpp/src/flutter_webrtc_base.cc index a8c184ba15..acd169cb2c 100644 --- a/common/cpp/src/flutter_webrtc_base.cc +++ b/common/cpp/src/flutter_webrtc_base.cc @@ -3,6 +3,8 @@ #include "flutter_data_channel.h" #include "flutter_peerconnection.h" +#include "helper.h" + namespace flutter_webrtc_plugin { const char* kEventChannelName = "FlutterWebRTC.Event"; @@ -16,6 +18,7 @@ FlutterWebRTCBase::FlutterWebRTCBase(BinaryMessenger* messenger, audio_device_ = factory_->GetAudioDevice(); video_device_ = factory_->GetVideoDevice(); desktop_device_ = factory_->GetDesktopDevice(); + audio_processing_ = factory_->GetAudioProcessing(); event_channel_ = EventChannelProxy::Create(messenger_, task_runner_, kEventChannelName); } @@ -28,7 +31,7 @@ EventChannelProxy* FlutterWebRTCBase::event_channel() { } std::string FlutterWebRTCBase::GenerateUUID() { - return uuidxx::uuid::Generate().ToString(false); + return libwebrtc::Helper::CreateRandomUuid().std_string(); } RTCPeerConnection* FlutterWebRTCBase::PeerConnectionForId( @@ -47,11 +50,11 @@ void FlutterWebRTCBase::RemovePeerConnectionForId(const std::string& id) { peerconnections_.erase(it); } -RTCMediaTrack* FlutterWebRTCBase ::MediaTrackForId(const std::string& id) { +scoped_refptr FlutterWebRTCBase ::MediaTrackForId(const std::string& id) { auto it = local_tracks_.find(id); if (it != local_tracks_.end()) - return (*it).second.get(); + return (*it).second; for (auto kv : peerconnection_observers_) { auto pco = kv.second.get(); diff --git a/elinux/CMakeLists.txt b/elinux/CMakeLists.txt index 6ae0ea6390..3454f57da4 100644 --- a/elinux/CMakeLists.txt +++ b/elinux/CMakeLists.txt @@ -11,7 +11,6 @@ add_definitions(-DRTC_DESKTOP_DEVICE) add_definitions(-DFLUTTER_ELINUX) add_library(${PLUGIN_NAME} SHARED - "../third_party/uuidxx/uuidxx.cc" "../common/cpp/src/flutter_data_channel.cc" "../common/cpp/src/flutter_frame_cryptor.cc" "../common/cpp/src/flutter_frame_capturer.cc" @@ -28,7 +27,6 @@ add_library(${PLUGIN_NAME} SHARED include_directories( "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../common/cpp/include" - "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/uuidxx" "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/libwebrtc/include" "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/svpng" ) @@ -39,6 +37,7 @@ set_target_properties(${PLUGIN_NAME} PROPERTIES target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) target_include_directories(${PLUGIN_NAME} INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}/../common/cpp/include" ) target_link_libraries(${PLUGIN_NAME} PRIVATE flutter diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 5e968390f2..8adc01ed33 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -9,7 +9,6 @@ set(CMAKE_CXX_STANDARD 17) add_definitions(-DRTC_DESKTOP_DEVICE) add_library(${PLUGIN_NAME} SHARED - "../third_party/uuidxx/uuidxx.cc" "../common/cpp/src/flutter_data_channel.cc" "../common/cpp/src/flutter_frame_cryptor.cc" "../common/cpp/src/flutter_media_stream.cc" @@ -31,7 +30,6 @@ include_directories( "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/flutter/include" "${CMAKE_CURRENT_SOURCE_DIR}/../common/cpp/include" - "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/uuidxx" "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/libwebrtc/include" "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/svpng" ) @@ -41,7 +39,10 @@ set_target_properties(${PLUGIN_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden) target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) target_include_directories(${PLUGIN_NAME} INTERFACE -"${CMAKE_CURRENT_SOURCE_DIR}") + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}/../common/cpp/include" + "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/libwebrtc/include" +) target_link_libraries(${PLUGIN_NAME} PRIVATE flutter) target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK) diff --git a/linux/flutter_webrtc/flutter_web_r_t_c_plugin.h b/linux/flutter_webrtc/flutter_web_r_t_c_plugin.h index 5d88c7b76d..cee9ce7b68 100644 --- a/linux/flutter_webrtc/flutter_web_r_t_c_plugin.h +++ b/linux/flutter_webrtc/flutter_web_r_t_c_plugin.h @@ -10,6 +10,10 @@ G_BEGIN_DECLS #define FLUTTER_PLUGIN_EXPORT #endif +namespace flutter_webrtc_plugin { +class FlutterWebRTC; +} // namespace flutter_webrtc_plugin + typedef struct _FlutterWebrtcPlugin FlutterWebrtcPlugin; typedef struct { GObjectClass parent_class; @@ -20,6 +24,8 @@ FLUTTER_PLUGIN_EXPORT GType flutter_webrtc_plugin_get_type(); FLUTTER_PLUGIN_EXPORT void flutter_web_r_t_c_plugin_register_with_registrar( FlPluginRegistrar* registrar); +FLUTTER_PLUGIN_EXPORT flutter_webrtc_plugin::FlutterWebRTC* flutter_webrtc_plugin_get_shared_instance(); + G_END_DECLS #endif // PLUGINS_FLUTTER_WEBRTC_PLUGIN_CPP_H_ diff --git a/linux/flutter_webrtc_plugin.cc b/linux/flutter_webrtc_plugin.cc index 336204d55a..b2a2a847fe 100644 --- a/linux/flutter_webrtc_plugin.cc +++ b/linux/flutter_webrtc_plugin.cc @@ -5,7 +5,7 @@ #include "task_runner_linux.h" const char* kChannelName = "FlutterWebRTC.Method"; - +static flutter_webrtc_plugin::FlutterWebRTC* g_shared_instance = nullptr; //#if defined(_WINDOWS) namespace flutter_webrtc_plugin { @@ -49,6 +49,7 @@ class FlutterWebRTCPluginImpl : public FlutterWebRTCPlugin { textures_(registrar->texture_registrar()), task_runner_(std::make_unique()) { webrtc_ = std::make_unique(this); + g_shared_instance = webrtc_.get(); } // Called when a method is called on |channel_|; @@ -75,4 +76,8 @@ void flutter_web_r_t_c_plugin_register_with_registrar( static auto* plugin_registrar = new flutter::PluginRegistrar(registrar); flutter_webrtc_plugin::FlutterWebRTCPluginImpl::RegisterWithRegistrar( plugin_registrar); -} \ No newline at end of file +} + +flutter_webrtc_plugin::FlutterWebRTC* flutter_webrtc_plugin_get_shared_instance() { + return g_shared_instance; +} \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 719c1a1309..a0c02d06ee 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_webrtc description: Flutter WebRTC plugin for iOS/Android/Destkop/Web, based on GoogleWebRTC. -version: 0.14.1 +version: 0.14.2 homepage: https://github.com/cloudwebrtc/flutter-webrtc environment: sdk: ">=3.3.0 <4.0.0" diff --git a/third_party/libwebrtc/include/rtc_audio_frame.h b/third_party/libwebrtc/include/rtc_audio_frame.h index 3f276a1676..7774f0c787 100644 --- a/third_party/libwebrtc/include/rtc_audio_frame.h +++ b/third_party/libwebrtc/include/rtc_audio_frame.h @@ -1,17 +1,17 @@ -#ifndef AUDIO_FRAME_HXX -#define AUDIO_FRAME_HXX +#ifndef LIB_WEBRTC_RTC_AUDIO_FRAME_HXX +#define LIB_WEBRTC_RTC_AUDIO_FRAME_HXX -#include "media_manager_types.h" +#include "rtc_types.h" -namespace b2bua { +namespace libwebrtc { -class AudioFrame { +class AudioFrame : public RefCountInterface { public: /** * @brief Creates a new instance of AudioFrame. * @return AudioFrame*: a pointer to the newly created AudioFrame. */ - MEDIA_MANAGER_API static AudioFrame* Create(); + LIB_WEBRTC_API static AudioFrame* Create(); /** * @brief Creates a new instance of AudioFrame with specified parameters. @@ -23,16 +23,11 @@ class AudioFrame { * @param num_channels: the number of audio channels. * @return AudioFrame*: a pointer to the newly created AudioFrame. */ - MEDIA_MANAGER_API static AudioFrame* Create(int id, uint32_t timestamp, - const int16_t* data, - size_t samples_per_channel, - int sample_rate_hz, - size_t num_channels = 1); - - /** - * @brief Releases the memory of this AudioFrame. - */ - virtual void Release() = 0; + LIB_WEBRTC_API static AudioFrame* Create(int id, uint32_t timestamp, + const int16_t* data, + size_t samples_per_channel, + int sample_rate_hz, + size_t num_channels = 1); public: /** @@ -103,6 +98,6 @@ class AudioFrame { virtual int id() = 0; }; -}; // namespace b2bua +}; // namespace libwebrtc -#endif +#endif // LIB_WEBRTC_RTC_AUDIO_FRAME_HXX diff --git a/third_party/libwebrtc/include/rtc_audio_processing.h b/third_party/libwebrtc/include/rtc_audio_processing.h new file mode 100644 index 0000000000..908a16a380 --- /dev/null +++ b/third_party/libwebrtc/include/rtc_audio_processing.h @@ -0,0 +1,35 @@ +#ifndef LIB_WEBRTC_RTC_AUDIO_PROCESSING_HXX +#define LIB_WEBRTC_RTC_AUDIO_PROCESSING_HXX + +#include "rtc_types.h" + +namespace libwebrtc { + +class RTCAudioProcessing : public RefCountInterface { + public: + class CustomProcessing { + public: + virtual void Initialize(int sample_rate_hz, int num_channels) = 0; + + virtual void Process(int num_bands, int num_frames, int buffer_size, + float* buffer) = 0; + + virtual void Reset(int new_rate) = 0; + + virtual void Release() = 0; + + protected: + virtual ~CustomProcessing() {} + }; + + public: + virtual void SetCapturePostProcessing( + CustomProcessing* capture_post_processing) = 0; + + virtual void SetRenderPreProcessing( + CustomProcessing* render_pre_processing) = 0; +}; + +} // namespace libwebrtc + +#endif // LIB_WEBRTC_RTC_AUDIO_PROCESSING_HXX \ No newline at end of file diff --git a/third_party/libwebrtc/include/rtc_audio_source.h b/third_party/libwebrtc/include/rtc_audio_source.h index 43e39fd801..e2f98fca0f 100644 --- a/third_party/libwebrtc/include/rtc_audio_source.h +++ b/third_party/libwebrtc/include/rtc_audio_source.h @@ -13,6 +13,16 @@ namespace libwebrtc { * processing and transmission mechanisms. */ class RTCAudioSource : public RefCountInterface { + public: + enum SourceType { kMicrophone, kCustom }; + + public: + virtual void CaptureFrame(const void* audio_data, int bits_per_sample, + int sample_rate, size_t number_of_channels, + size_t number_of_frames) = 0; + + virtual SourceType GetSourceType() const = 0; + protected: /** * The destructor for the RTCAudioSource class. diff --git a/third_party/libwebrtc/include/rtc_audio_track.h b/third_party/libwebrtc/include/rtc_audio_track.h index c64e4bc4a5..82459005d1 100644 --- a/third_party/libwebrtc/include/rtc_audio_track.h +++ b/third_party/libwebrtc/include/rtc_audio_track.h @@ -17,6 +17,10 @@ class RTCAudioTrack : public RTCMediaTrack { // volume in [0-10] virtual void SetVolume(double volume) = 0; + virtual void AddSink(AudioTrackSink* sink) = 0; + + virtual void RemoveSink(AudioTrackSink* sink) = 0; + protected: /** * The destructor for the RTCAudioTrack class. diff --git a/third_party/libwebrtc/include/rtc_media_track.h b/third_party/libwebrtc/include/rtc_media_track.h index ff5a2f743e..d971c89d27 100644 --- a/third_party/libwebrtc/include/rtc_media_track.h +++ b/third_party/libwebrtc/include/rtc_media_track.h @@ -5,6 +5,15 @@ namespace libwebrtc { +class AudioTrackSink { + public: + virtual void OnData(const void* audio_data, int bits_per_sample, + int sample_rate, size_t number_of_channels, + size_t number_of_frames) = 0; + protected: + virtual ~AudioTrackSink() {} +}; + /*Media Track interface*/ class RTCMediaTrack : public RefCountInterface { public: diff --git a/third_party/libwebrtc/include/rtc_peerconnection_factory.h b/third_party/libwebrtc/include/rtc_peerconnection_factory.h index cb024672c2..1b6b8c1aec 100644 --- a/third_party/libwebrtc/include/rtc_peerconnection_factory.h +++ b/third_party/libwebrtc/include/rtc_peerconnection_factory.h @@ -16,6 +16,7 @@ namespace libwebrtc { class RTCPeerConnection; class RTCAudioDevice; +class RTCAudioProcessing; class RTCVideoDevice; class RTCRtpCapabilities; @@ -33,12 +34,16 @@ class RTCPeerConnectionFactory : public RefCountInterface { virtual scoped_refptr GetAudioDevice() = 0; + virtual scoped_refptr GetAudioProcessing() = 0; + virtual scoped_refptr GetVideoDevice() = 0; #ifdef RTC_DESKTOP_DEVICE virtual scoped_refptr GetDesktopDevice() = 0; #endif virtual scoped_refptr CreateAudioSource( - const string audio_source_label) = 0; + const string audio_source_label, + RTCAudioSource::SourceType source_type = + RTCAudioSource::SourceType::kMicrophone) = 0; virtual scoped_refptr CreateVideoSource( scoped_refptr capturer, const string video_source_label, diff --git a/third_party/libwebrtc/lib/linux-arm64/libwebrtc.so b/third_party/libwebrtc/lib/linux-arm64/libwebrtc.so index 22c3bde89f..9ff7018adb 100755 Binary files a/third_party/libwebrtc/lib/linux-arm64/libwebrtc.so and b/third_party/libwebrtc/lib/linux-arm64/libwebrtc.so differ diff --git a/third_party/libwebrtc/lib/linux-x64/libwebrtc.so b/third_party/libwebrtc/lib/linux-x64/libwebrtc.so index ae9c4eec39..19e93a1662 100755 Binary files a/third_party/libwebrtc/lib/linux-x64/libwebrtc.so and b/third_party/libwebrtc/lib/linux-x64/libwebrtc.so differ diff --git a/third_party/libwebrtc/lib/win64/libwebrtc.dll b/third_party/libwebrtc/lib/win64/libwebrtc.dll index e62437621a..665183e7b6 100644 Binary files a/third_party/libwebrtc/lib/win64/libwebrtc.dll and b/third_party/libwebrtc/lib/win64/libwebrtc.dll differ diff --git a/third_party/uuidxx/LICENSE b/third_party/uuidxx/LICENSE deleted file mode 100644 index 6eaf314417..0000000000 --- a/third_party/uuidxx/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2016 by NeoSmart Technologies - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/third_party/uuidxx/uuidxx.cc b/third_party/uuidxx/uuidxx.cc deleted file mode 100644 index a504635c24..0000000000 --- a/third_party/uuidxx/uuidxx.cc +++ /dev/null @@ -1,104 +0,0 @@ -#ifdef _WIN32 -#ifndef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS -#endif -#endif - -#include "uuidxx.h" -#include -#include -#include -#include - -using namespace std; -using namespace uuidxx; - -bool uuid::operator==(const uuid& guid2) const { - return memcmp(&guid2, this, sizeof(uuid)) == 0; -} - -bool uuid::operator!=(const uuid& guid2) const { - return !(*this == guid2); -} - -bool uuid::operator<(const uuid& guid2) const { - return memcmp(this, &guid2, sizeof(uuid)) < 0; -} - -bool uuid::operator>(const uuid& guid2) const { - return memcmp(this, &guid2, sizeof(uuid)) > 0; -} - -uuid::uuid(const std::string& uuidString) : uuid(uuidString.c_str()) {} - -uuid::uuid(const char* uuidString) { - if (uuidString == nullptr) { - // special case, and prevents random bugs - memset(this, 0, sizeof(uuid)); - return; - } - - if (uuidString[0] == '{') { - sscanf(uuidString, - "{%08" SCNx32 "-%04" SCNx16 "-%04" SCNx16 "-%02" SCNx8 "%02" SCNx8 - "-%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 - "%02" SCNx8 "}", - &Uuid.Data1, &Uuid.Data2, &Uuid.Data3, &Uuid.Data4[0], - &Uuid.Data4[1], &Uuid.Data4[2], &Uuid.Data4[3], &Uuid.Data4[4], - &Uuid.Data4[5], &Uuid.Data4[6], &Uuid.Data4[7]); - } else { - sscanf(uuidString, - "%08" SCNx32 "-%04" SCNx16 "-%04" SCNx16 "-%02" SCNx8 "%02" SCNx8 - "-%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 - "%02" SCNx8 "", - &Uuid.Data1, &Uuid.Data2, &Uuid.Data3, &Uuid.Data4[0], - &Uuid.Data4[1], &Uuid.Data4[2], &Uuid.Data4[3], &Uuid.Data4[4], - &Uuid.Data4[5], &Uuid.Data4[6], &Uuid.Data4[7]); - } -} - -string uuid::ToString(bool withBraces) const { - char buffer[39]; - sprintf(buffer, "%s%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X%s", - withBraces ? "{" : "", Uuid.Data1, Uuid.Data2, Uuid.Data3, - Uuid.Data4[0], Uuid.Data4[1], Uuid.Data4[2], Uuid.Data4[3], - Uuid.Data4[4], Uuid.Data4[5], Uuid.Data4[6], Uuid.Data4[7], - withBraces ? "}" : ""); - return buffer; -} - -uuid uuid::FromString(const char* uuidString) { - uuid temp(uuidString); - return temp; -} - -uuid uuid::FromString(const std::string& uuidString) { - uuid temp(uuidString.c_str()); - return temp; -} - -uuid uuid::Generatev4() { - // mach-o does not support TLS and clang still has issues with thread_local -#if !defined(__APPLE__) && !defined(__clang__) - thread_local std::random_device rd; - thread_local auto gen = std::mt19937_64(rd()); -#else - std::random_device rd; - std::mt19937_64 gen(rd()); -#endif - std::uniform_int_distribution dis64; - - uuid newGuid; - newGuid.WideIntegers[0] = dis64(gen); - newGuid.WideIntegers[1] = dis64(gen); - - // RFC4122 defines (psuedo)random uuids (in big-endian notation): - // MSB of DATA4[0] specifies the variant and should be 0b10 to indicate - // standard uuid, and MSB of DATA3 should be 0b0100 to indicate version 4 - newGuid.Bytes.Data4[0] = - (newGuid.Bytes.Data4[0] & 0x3F) | static_cast(0x80); - newGuid.Bytes.Data3[1] = - (newGuid.Bytes.Data3[1] & 0x0F) | static_cast(0x40); - - return newGuid; -} diff --git a/third_party/uuidxx/uuidxx.h b/third_party/uuidxx/uuidxx.h deleted file mode 100644 index 2d36271886..0000000000 --- a/third_party/uuidxx/uuidxx.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace uuidxx { -enum class Variant { Nil, Version1, Version2, Version3, Version4, Version5 }; - -class NotImplemented : public std::logic_error { - public: - NotImplemented() : std::logic_error("Function not yet implemented"){}; -}; - -union uuid { - private: - static uuid Generatev4(); - - public: - uint64_t WideIntegers[2]; - struct _internalData { - uint32_t Data1; - uint16_t Data2; - uint16_t Data3; - uint8_t Data4[8]; - } Uuid; - struct _byteRepresentation { - uint8_t Data1[4]; - uint8_t Data2[2]; - uint8_t Data3[2]; - uint8_t Data4[8]; - } Bytes; - - bool operator==(const uuid& guid2) const; - bool operator!=(const uuid& guid2) const; - bool operator<(const uuid& guid2) const; - bool operator>(const uuid& guid2) const; - - uuid() = default; - - uuid(const char* uuidString); - uuid(const std::string& uuidString); - static uuid FromString(const char* uuidString); - static uuid FromString(const std::string& uuidString); - - static inline uuid Generate(Variant v = Variant::Version4) { - switch (v) { - case Variant::Nil: - return uuid(nullptr); // special case; - case Variant::Version1: - case Variant::Version2: - case Variant::Version3: - case Variant::Version5: - throw new NotImplemented(); - case Variant::Version4: - return Generatev4(); - } - return uuid(nullptr); - } - - std::string ToString(bool withBraces = true) const; -}; - -static_assert(sizeof(uuid) == 2 * sizeof(int64_t), - "Check uuid type declaration/padding!"); -} // namespace uuidxx diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt index 39ee5943ac..bb6405767f 100644 --- a/windows/CMakeLists.txt +++ b/windows/CMakeLists.txt @@ -20,7 +20,6 @@ add_library(${PLUGIN_NAME} SHARED "../common/cpp/src/flutter_screen_capture.cc" "../common/cpp/src/flutter_webrtc.cc" "../common/cpp/src/flutter_webrtc_base.cc" - "../third_party/uuidxx/uuidxx.cc" "flutter_webrtc_plugin.cc" "task_runner_windows.cc" ) @@ -28,7 +27,6 @@ add_library(${PLUGIN_NAME} SHARED include_directories( "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/../common/cpp/include" - "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/uuidxx" "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/svpng" "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/libwebrtc/include" ) @@ -39,6 +37,8 @@ set_target_properties(${PLUGIN_NAME} PROPERTIES target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) target_include_directories(${PLUGIN_NAME} INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}/../common/cpp/include" + "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/libwebrtc/include" ) target_link_libraries(${PLUGIN_NAME} PRIVATE flutter diff --git a/windows/flutter_webrtc/flutter_web_r_t_c_plugin.h b/windows/flutter_webrtc/flutter_web_r_t_c_plugin.h index ed2d45208b..5065110e4f 100644 --- a/windows/flutter_webrtc/flutter_web_r_t_c_plugin.h +++ b/windows/flutter_webrtc/flutter_web_r_t_c_plugin.h @@ -9,6 +9,10 @@ #define FLUTTER_PLUGIN_EXPORT __declspec(dllimport) #endif +namespace flutter_webrtc_plugin { +class FlutterWebRTC; +} // namespace flutter_webrtc_plugin + #if defined(__cplusplus) extern "C" { #endif @@ -16,6 +20,8 @@ extern "C" { FLUTTER_PLUGIN_EXPORT void FlutterWebRTCPluginRegisterWithRegistrar( FlutterDesktopPluginRegistrarRef registrar); +FLUTTER_PLUGIN_EXPORT flutter_webrtc_plugin::FlutterWebRTC* FlutterWebRTCPluginSharedInstance(); + #if defined(__cplusplus) } // extern "C" #endif diff --git a/windows/flutter_webrtc_plugin.cc b/windows/flutter_webrtc_plugin.cc index 836989c00e..f766d98239 100644 --- a/windows/flutter_webrtc_plugin.cc +++ b/windows/flutter_webrtc_plugin.cc @@ -7,6 +7,7 @@ #include const char* kChannelName = "FlutterWebRTC.Method"; +static flutter_webrtc_plugin::FlutterWebRTC* g_shared_instance = nullptr; namespace flutter_webrtc_plugin { @@ -23,7 +24,6 @@ class FlutterWebRTCPluginImpl : public FlutterWebRTCPlugin { // Uses new instead of make_unique due to private constructor. std::unique_ptr plugin( new FlutterWebRTCPluginImpl(registrar, std::move(channel))); - channel_pointer->SetMethodCallHandler( [plugin_pointer = plugin.get()](const auto& call, auto result) { plugin_pointer->HandleMethodCall(call, std::move(result)); @@ -49,6 +49,7 @@ class FlutterWebRTCPluginImpl : public FlutterWebRTCPlugin { textures_(registrar->texture_registrar()), task_runner_(std::make_unique()) { webrtc_ = std::make_unique(this); + g_shared_instance = webrtc_.get(); } // Called when a method is called on |channel_|; @@ -76,4 +77,8 @@ void FlutterWebRTCPluginRegisterWithRegistrar( flutter_webrtc_plugin::FlutterWebRTCPluginImpl::RegisterWithRegistrar( flutter::PluginRegistrarManager::GetInstance() ->GetRegistrar(registrar)); -} \ No newline at end of file +} + +flutter_webrtc_plugin::FlutterWebRTC* FlutterWebRTCPluginSharedInstance() { + return g_shared_instance; +} \ No newline at end of file