123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565 |
- #include "pch.h"
-
- #include "../common/comm.h"
- #include "api.h"
- #include "callback.h"
- #include "api/create_peerconnection_factory.h"
- #include "video_frame_observer.h"
- #include "data_channel_observer.h"
- #include "audio_frame_observer.h"
- #include "peer_connection.h"
- #include "sdp_utils.h"
- #ifdef WEBRTC_LINUX
- //#include <opencv2/opencv.hpp>
- //#include <opencv2/core/core.hpp>
- //#include <opencv2/opencv.hpp>
- #include "capture_op.h"
- #include "gsml_capturer.h"
- #else
- #include "cap_interface.h"
- #include "overlay_video.h"
- #endif
- #include "NullEncoder.h"
- #include "NullDecoder.h"
-
-
- #ifdef WEBRTC_LINUX
- #include "sanitize_string.h"
- #include "capture_op.h"
- #include "gsml_capturer.h"
- #include "VideoScaler.h"
- #include "VideoFilter.h"
- #endif
- struct mrsEnumerator {
- virtual ~mrsEnumerator() = default;
- virtual void dispose() = 0;
- };
- rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
- g_peer_connection_factory;
- /*
- #ifdef WEBRTC_LINUX
- std::unique_ptr<webrtc::VideoDecoderFactory> g_video_decode_factory;
- #endif
- */
- /// WebRTC worker thread.
- std::unique_ptr<rtc::Thread> g_worker_thread;
- // #ifdef WIN32
- // //rtc::Win32SocketServer w32_ss;
- // std::unique_ptr<rtc::Thread> g_network_thread;
- // #else
- // rtc::AutoSocketServerThread g_network_thread;
- // #endif
- /// WebRTC signaling thread.
- std::unique_ptr<rtc::Thread> g_signaling_thread;
- std::unordered_map<
- PeerConnectionHandle,
- rtc::scoped_refptr<PeerConnection>>
- g_peer_connection_map;
- /// Predefined name of the local video track.
- const std::string kLocalVideoLabel("local_video");
- /// Predefined name of the local audio track.
- const std::string kLocalAudioLabel("local_audio");
- const std::string kLocalDataChannel("local_channel");
- /// WebRTC worker thread.
- const std::unique_ptr<rtc::Thread>& GetWorkerThread() {
- return g_worker_thread;
- }
- /// WebRTC signaling thread.
- const std::unique_ptr<rtc::Thread>& GetSignalingThread() {
- return g_signaling_thread;
- }
- void mrsCloseEnum(mrsEnumHandle* handleRef) {
- if (handleRef) {
- if (auto& handle = *handleRef) {
- handle->dispose();
- delete handle;
- handle = nullptr;
- }
- }
- }
- void mrsEnumVideoCaptureDevicesAsync(
- mrsVideoCaptureDeviceEnumCallback callback,
- void* userData,
- mrsVideoCaptureDeviceEnumCompletedCallback completedCallback,
- void* completedCallbackUserData) {
- if (!callback) {
- return;
- }
- std::unique_ptr<webrtc::VideoCaptureModule::DeviceInfo> info(
- webrtc::VideoCaptureFactory::CreateDeviceInfo());
- if (!info) {
- if (completedCallback) {
- (*completedCallback)(completedCallbackUserData);
- }
- }
- int num_devices = info->NumberOfDevices();
- for (int i = 0; i < num_devices; ++i) {
- constexpr uint32_t kSize = 256;
- char name[kSize] = { 0 };
- char id[kSize] = { 0 };
- if (info->GetDeviceName(i, name, kSize, id, kSize) != -1) {
- (*callback)(id, name, userData);
- }
- }
- if (completedCallback) {
- (*completedCallback)(completedCallbackUserData);
- }
- }
- std::unique_ptr<webrtc::VideoEncoderFactory> CreateEncoderFactory(bool bNullCodec)
- {
- std::unique_ptr<webrtc::VideoEncoderFactory> factory;
- #ifdef WIN32
- if (bNullCodec) {
-
- factory=std::make_unique<VideoEncoderFactory>();
-
- }
- else {
- #endif
- factory=webrtc::CreateBuiltinVideoEncoderFactory();
- #ifdef WIN32
- }
- #endif
- return factory;
- }
- std::unique_ptr<webrtc::VideoDecoderFactory> CreateDecoderFactory(bool nullCodec) {
- std::unique_ptr<webrtc::VideoDecoderFactory> factory;
-
- #ifdef WEBRTC_LINUX
- //factory= webrtc::CreateBuiltinVideoDecoderFactory();
- factory = std::make_unique<VideoDecoderFactory>();
- #else
- if (nullCodec) {
- factory = std::make_unique<VideoDecoderFactory>();
- }
- else
- {
- factory = webrtc::CreateBuiltinVideoDecoderFactory();
- }
- #endif
-
-
- return factory;
- }
- bool mrsWebrtcCreateFactory(bool NullEnCodec, bool NullDecode)
- {
- if (g_peer_connection_factory == nullptr) {
- g_worker_thread=(rtc::Thread::Create());
- g_worker_thread->Start();
- g_signaling_thread=(rtc::Thread::Create());
- g_signaling_thread->Start();
-
- g_peer_connection_factory = webrtc::CreatePeerConnectionFactory(
- nullptr, g_worker_thread.get(), g_signaling_thread.get(),
- nullptr, webrtc::CreateBuiltinAudioEncoderFactory(),
- webrtc::CreateBuiltinAudioDecoderFactory(),
-
- CreateEncoderFactory(NullEnCodec),
- /*
- std::unique_ptr<webrtc::VideoEncoderFactory>(
- new webrtc::MultiplexEncoderFactory(
- #ifdef WEBRTC_AARCH
- std::make_unique<webrtc::InternalEncoderFactory>()
- #else
- std::make_unique<webrtc::NvVideoEncoderFactory>()
- #endif
- )),
- */
- CreateDecoderFactory(NullDecode),
- /*
- std::unique_ptr<webrtc::VideoDecoderFactory>(
- new webrtc::MultiplexDecoderFactory(
- std::make_unique<webrtc::InternalDecoderFactory>())),*/
- nullptr, nullptr);
- }
- if (!g_peer_connection_factory.get()) {
- return false;
- }
- return true;
- }
- PeerConnectionHandle mrsPeerConnectionCreate() {
- // Ensure the factory exists
- // Setup the connection configuration
- webrtc::PeerConnectionInterface::RTCConfiguration config;
- config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
- config.enable_dtls_srtp = false;
- config.enable_rtp_data_channel = true;
- webrtc::PeerConnectionInterface::IceServer server;
- server.uri = "stun:stun1.l.google.com:19302";
- config.servers.push_back(server);
- server.uri = "turn:58.34.98.12:3478";
- server.username = "ubuntu12";
- server.password = "ubuntu12@123";
- config.servers.push_back(server);
-
- config.enable_dtls_srtp = false; //< TODO - Should be true/unset for security
- // Create the new peer connection
- rtc::scoped_refptr<PeerConnection> peer =
- new rtc::RefCountedObject<PeerConnection>();
- /* webrtc::PeerConnectionDependencies dependencies(peer);*/
- rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection =
- g_peer_connection_factory->CreatePeerConnection(config, nullptr, nullptr,
- peer.get());
- if (peer_connection.get() == nullptr)
- return {};
- peer->SetPeerImpl(peer_connection);
- const PeerConnectionHandle handle{ peer.get() };
- g_peer_connection_map.insert({ handle, std::move(peer) });
- return handle;
- }
- void mrsPeerConnectionRegisterConnectedCallback(
- PeerConnectionHandle peerHandle,
- PeerConnectionConnectedCallback callback,
- void* user_data) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- peer->RegisterConnectedCallback(Callback<>{callback, user_data});
- }
- }
- void mrsPeerConnectionRegisterLocalSdpReadytoSendCallback(
- PeerConnectionHandle peerHandle,
- int32_t pid,
- int32_t index,
- PeerConnectionLocalSdpReadytoSendCallback callback,
- void* user_data) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- peer->RegisterLocalSdpReadytoSendCallback(
- Callback<int32_t,int32_t,const char*, const char*>{callback,user_data,pid,index});
- }
- }
- void mrsPeerConnectionRegisterIceCandidateReadytoSendCallback(
- PeerConnectionHandle peerHandle,
- int32_t pid,
- int32_t view,
- PeerConnectionIceCandidateReadytoSendCallback callback,
- void* user_data) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- peer->RegisterIceCandidateReadytoSendCallback(
- Callback<int32_t,int32_t,const char*, int, const char*>{callback, user_data,pid,view});
- }
- }
- void mrsPeerConnectionRegisterLocalVideoFrameCallback(
- PeerConnectionHandle peerHandle,
- PeerConnectionVideoFrameCallback callback,
- void* user_data) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- peer->RegisterLocalVideoFrameCallback(
- VideoFrameReadyCallback{callback, user_data });
- }
- }
- void mrsPeerConnectionRegisterRemoteVideoFrameCallback(
- PeerConnectionHandle peerHandle,
- PeerConnectionVideoFrameCallback callback,
- void* user_data) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- peer->RegisterRemoteVideoFrameCallback(
- VideoFrameReadyCallback{callback, user_data });
- }
- }
- void mrsPeerConnectionRegisterChannelCallback(PeerConnectionHandle peerHandle,
- PeerConnectionDataChannelMessageCallback message_callback, void* message_user_data,
- PeerConnectionDataChannelBufferingCallback buffering_callback, void* buffering_user_data,
- PeerConnectionDataChannelStateCallback state_callback,
- void* state_user_data) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle))
- {
- peer->RegisterDataChannelCallback(
- DataChannelMessageCallback{ message_callback, message_user_data },
- DataChannelBufferingCallback{ buffering_callback, buffering_user_data },
- DataChannelStateCallback{ state_callback, state_user_data });
- }
- }
- bool mrsPeerConnectionAddIceCandidate(PeerConnectionHandle peerHandle,
- const char* sdp,
- const int sdp_mline_index,
- const char* sdp_mid) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- return peer->AddIceCandidate(sdp_mid, sdp_mline_index, sdp);
- }
- return false;
- }
- bool mrsPeerConnectionCreateOffer(PeerConnectionHandle peerHandle) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- return peer->CreateOffer();
- }
- return false;
- }
- bool mrsPeerConnectionCreateAnswer(PeerConnectionHandle peerHandle) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- return peer->CreateAnswer();
- }
- return false;
- }
- bool mrsPeerConnectionSetRemoteDescription(PeerConnectionHandle peerHandle,
- const char* type,
- const char* sdp) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- return peer->SetRemoteDescription(type, sdp);
- }
- return false;
- }
- void mrsPeerConnectionClose(PeerConnectionHandle* peerHandlePtr) {
- if (peerHandlePtr) {
- if (auto peer = static_cast<PeerConnection*>(*peerHandlePtr)) {
- auto it = g_peer_connection_map.find(peer);
- if (it != g_peer_connection_map.end()) {
- // This generally removes the last reference to the PeerConnection and
- // leads to its destruction, unless some background running task is
- // still using the connection.
- g_peer_connection_map.erase(it);
- if (g_peer_connection_map.empty()) {
- // Release the factory so that the threads are stopped and the DLL can
- // be unloaded. This is mandatory to be able to unload/reload in the
- // Unity Editor and be able to Play/Stop multiple times per Editor
- // process run.
- g_peer_connection_factory = nullptr;
- g_signaling_thread.reset();
- g_worker_thread.reset();
- }
- }
- }
- *peerHandlePtr = nullptr;
- }
- }
-
- #ifdef WEBRTC_LINUX
- bool mrsPeerConnectionAddLocalVideoTrack( PeerConnectionHandle peerHandle,
- RenderPosition type,
- int32_t index)
- {
- if(auto peer=static_cast<PeerConnection *>(peerHandle))
- {
- if (!g_peer_connection_factory)
- return false;
-
- std::unique_ptr<CaptureOp > op=std::make_unique<CaptureOp>(type,index);
- auto ptr=op.get();
- peer->RegisterCaptureOp(op);
- rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> video_source = OpenGSMLCapture(ptr);
- if(!video_source) return false;
- rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track =
- g_peer_connection_factory->CreateVideoTrack(kLocalVideoLabel+std::to_string(type),
- video_source);
- if (!video_track) {
- return false;
- }
- return peer->AddLocalVideoTrack(std::move(video_track), kLocalVideoLabel+std::to_string(type));
- }
- return false;
- }
-
- bool mrsPeerConnectionSwitchCapture(
- PeerConnectionHandle peerHandle,
- bool front
- )
- {
- if(auto peer=static_cast<PeerConnection *>(peerHandle))
- {
- peer->SwitchCapture(front);
- return true;
- }
- return false;
- }
- bool mrsPeerConnectionSetCtx(PeerConnectionHandle peerHandle,void * data)
- {
- if(auto peer=static_cast<PeerConnection *>(peerHandle))
- {
- peer->SetOtherCtx(data);
- return true;
- }
- return false;
- }
- void * mrsPeerConnectionCurrentCtx(PeerConnectionHandle peerHandle)
- {
- if(auto peer=static_cast<PeerConnection *>(peerHandle))
- {
- return peer->GetCurrentCtx();
- }
- return nullptr;
- }
- #else
- bool mrsPeerConnectionAddLocalVideoTrack(
- PeerConnectionHandle peerHandle,
- IOverlayVideo* video)
- {
- if (auto peer = static_cast<PeerConnection*>(peerHandle))
- {
- if (!g_peer_connection_factory)
- return false;
- rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> video_source = OpenOverlayVideoTrack(video);
- if (!video_source) return false;
- rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track =
- g_peer_connection_factory->CreateVideoTrack(kLocalVideoLabel + std::string("native"),
- video_source);
- return peer->AddLocalVideoTrack(std::move(video_track), kLocalVideoLabel + std::string("native"));
- }
- return false;
- }
- IOverlayVideo* mrsPeerConnectionCreateOverlayVideo()
- {
- return CreateOverlayVideo();
- }
- #endif
- bool mrsPeerConnectionAddLocalAudioTrack(PeerConnectionHandle peerHandle) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- if (!g_peer_connection_factory)
- return false;
-
- rtc::scoped_refptr<webrtc::AudioSourceInterface> audio_source =
- g_peer_connection_factory->CreateAudioSource(cricket::AudioOptions());
- if (!audio_source)
- return false;
-
- rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track =
- g_peer_connection_factory->CreateAudioTrack(kLocalAudioLabel,
- audio_source);
- if (!audio_track)
- return false;
-
- return peer->AddLocalAudioTrack(std::move(audio_track));
- }
- return false;
- }
- mrsResult mrsPeerConnectionAddDataChannel(
- PeerConnectionHandle peerHandle,
- bool ordered,
- bool reliable//,
- // PeerConnectionDataChannelMessageCallback message_callback,
- // void* message_user_data,
- // PeerConnectionDataChannelBufferingCallback buffering_callback,
- // void* buffering_user_data,
- // PeerConnectionDataChannelStateCallback state_callback,
- // void* state_user_data
- )
- {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- return peer->AddDataChannel(kLocalDataChannel.c_str(), ordered, reliable);
- // DataChannelMessageCallback{ message_callback, message_user_data },
- // DataChannelBufferingCallback{ buffering_callback, buffering_user_data },
- // DataChannelStateCallback{ state_callback, state_user_data });
- }
- return MRS_E_INVALID_PEER_HANDLE;
- }
- void mrsPeerConnectionRemoveLocalVideoTrack(
- PeerConnectionHandle peerHandle) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- peer->RemoveLocalVideoTrack();
- }
- }
- void mrsPeerConnectionRemoveLocalAudioTrack(
- PeerConnectionHandle peerHandle) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- peer->RemoveLocalAudioTrack();
- }
- }
- bool mrsPeerConnectionRemoveDataChannel(PeerConnectionHandle peerHandle) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- return peer->RemoveDataChannel();
- }
- return false;
- }
- bool mrsPeerConnectionSendDataChannelMessage(PeerConnectionHandle peerHandle,
- const void* data,
- uint64_t size) {
- if (auto peer = static_cast<PeerConnection*>(peerHandle)) {
- return peer->SendDataChannelMessage(data, size);
- }
- return false;
- }
- bool mrsSdpForceCodecs(const char* message,
- const char* audio_codec_name,
- const char* video_codec_name,
- char* buffer,
- size_t* buffer_size) {
- RTC_CHECK(message);
- RTC_CHECK(buffer);
- RTC_CHECK(buffer_size);
- std::string message_str(message);
- std::string audio_codec_name_str;
- std::string video_codec_name_str;
- if (audio_codec_name) {
- audio_codec_name_str.assign(audio_codec_name);
- }
- if (video_codec_name) {
- video_codec_name_str.assign(video_codec_name);
- }
- std::string out_message =
- SdpForceCodecs(message_str, audio_codec_name_str, video_codec_name_str);
- const size_t capacity = *buffer_size;
- const size_t size = out_message.size();
- *buffer_size = size + 1;
- if (capacity < size + 1) {
- return false;
- }
- memcpy(buffer, out_message.c_str(), size);
- buffer[size] = '\0';
- return true;
- }
- void mrsMemCpy(void* dst, const void* src, size_t size) {
- memcpy(dst, src, size);
- }
- void mrsMemCpyStride(void* dst,
- int dst_stride,
- const void* src,
- int src_stride,
- int elem_size,
- int elem_count) {
- RTC_CHECK(dst);
- RTC_CHECK(dst_stride >= elem_size);
- RTC_CHECK(src);
- RTC_CHECK(src_stride >= elem_size);
- if ((dst_stride == elem_size) && (src_stride == elem_size)) {
- // If tightly packed, do a single memcpy() for performance
- const size_t total_size = (size_t)elem_size * elem_count;
- memcpy(dst, src, total_size);
- }
- else {
- // Otherwise, copy row by row
- for (int i = 0; i < elem_count; ++i) {
- memcpy(dst, src, elem_size);
- dst = (char*)dst + dst_stride;
- src = (const char*)src + src_stride;
- }
- }
- }
|