aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/SideChains/WebRtc.NET/src/managed.cpp
blob: 284fc7e7fe6754f14a142dbe731cac6d85cc26e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;

namespace Tango.Scripting.IDE.Projects
{
    public class StubProject : CSharpProject
    {
        public override BitmapSource Image => GetImage("Images/StubProject.png");

        public override Task Build()
        {
            throw new NotImplementedException();
        }

        public override Task Run()
        {
            throw new NotImplementedException();
        }
    }
}
93' href='#n293'>293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
#pragma unmanaged
#include "internals.h"
#include "defaults.h"
#include "conductor.h"
#include "webrtc\api\peerconnectioninterface.h"
#pragma managed

#include "msclr\marshal_cppstd.h"

using namespace System::Runtime::InteropServices;
using namespace System::Reflection;
using namespace System;
using namespace System::IO;
//using namespace WebRtc::NET::Utils;
using namespace System::Diagnostics;

using namespace msclr::interop;

[assembly:System::Runtime::Versioning::TargetFrameworkAttribute(L".NETFramework,Version=v4.0", FrameworkDisplayName = L".NET Framework 4")];

namespace Internal
{
	void Encode(unsigned char * data, unsigned int size, int part_idx, bool keyFrame)
	{
		//Util::OnFillBuffer(data, size, part_idx, keyFrame);
	}
}

namespace WebRtc
{
	namespace NET
	{
		public enum class IceConnectionStates : int 
		{
			kIceConnectionNew,
			kIceConnectionChecking,
			kIceConnectionConnected,
			kIceConnectionCompleted,
			kIceConnectionFailed,
			kIceConnectionDisconnected,
			kIceConnectionClosed,
			kIceConnectionMax,
		};

		public ref class ManagedConductor
		{
		private:

			bool m_isDisposed;
			Native::Conductor * cd;

			delegate void _OnRenderCallback(uint8_t * frame_buffer, uint32_t w, uint32_t h);
			_OnRenderCallback ^ onRenderLocal;
			_OnRenderCallback ^ onRenderRemote;
			GCHandle ^ onRenderLocalHandle;			
			GCHandle ^ onRenderRemoteHandle;

			delegate void _OnErrorCallback();
			_OnErrorCallback ^ onError;
			GCHandle ^ onErrorHandle;

			delegate void _OnSuccessCallback(String ^ type, String ^ sdp);
			_OnSuccessCallback ^ onSuccess;
			GCHandle ^ onSuccessHandle;

			delegate void _OnIceStateChangedCallback(webrtc::PeerConnectionInterface::IceConnectionState state);
			_OnIceStateChangedCallback ^ onIceStateChanged;
			GCHandle ^ onIceStateChangedHandle;

			delegate void _OnFailureCallback(String ^ error);
			_OnFailureCallback ^ onFailure;
			GCHandle ^ onFailureHandle;

			delegate void _OnDataMessageCallback(String ^ msg);
			_OnDataMessageCallback ^ onDataMessage;
			GCHandle ^ onDataMessageHandle;

			delegate void _OnDataBinaryMessageCallback(uint8_t * msg, uint32_t size);
			_OnDataBinaryMessageCallback ^ onDataBinaryMessage;
			GCHandle ^ onDataBinaryMessageHandle;

			delegate void _OnIceCandidateCallback(String ^ sdp_mid, Int32 sdp_mline_index, String ^ sdp);
			_OnIceCandidateCallback ^ onIceCandidate;
			GCHandle ^ onIceCandidateHandle;

			void FreeGCHandle(GCHandle ^% g)
			{
				if (g != nullptr)
				{
					g->Free();
					g = nullptr;
				}
			}

			void _OnError()
			{
				Debug::WriteLine("OnError");

				OnError();
			}

			void _OnSuccess(String ^ type, String ^ sdp)
			{
				Debug::WriteLine(String::Format("OnSuccess: {0} -> {1}", type, sdp));

				if (type == "offer")
				{
					OnSuccessOffer(sdp);
				}
				else if (type == "answer")
				{
					OnSuccessAnswer(sdp);
				}
			}

			void _OnIceStateChanged(webrtc::PeerConnectionInterface::IceConnectionState state)
			{
				IceConnectionStates managedState = static_cast<IceConnectionStates>(state);
				OnIceStateChanged(managedState);
			}

			void _OnIceCandidate(String ^ sdp_mid, Int32 sdp_mline_index, String ^ sdp)
			{
				Debug::WriteLine(String::Format("OnIceCandidate: {0}", sdp));

				OnIceCandidate(sdp_mid, sdp_mline_index, sdp);
			}

			void _OnFailure(String ^ error)
			{
				Debug::WriteLine(String::Format("OnFailure: {0}", error));

				OnFailure(error);
			}

			void _OnDataMessage(String ^ msg)
			{
				OnDataMessage(msg);
			}

			void _OnDataBinaryMessage(uint8_t * data, uint32_t size)
			{
				array<Byte>^ data_array = gcnew array<Byte>(size);

				IntPtr src(data);
				Marshal::Copy(src, data_array, 0, size);

				OnDataBinaryMessage(data_array);
			}

			void _OnRenderLocal(uint8_t * frame_buffer, uint32_t w, uint32_t h)
			{
				OnRenderLocal(frame_buffer, w, h);
			}

			void _OnRenderRemote(uint8_t * frame_buffer, uint32_t w, uint32_t h)
			{
				OnRenderRemote(frame_buffer, w, h);
			}

		public:

			delegate void OnCallbackSdp(String ^ sdp);
			event OnCallbackSdp ^ OnSuccessOffer;
			event OnCallbackSdp ^ OnSuccessAnswer;

			delegate void OnCallbackIceCandidate(String ^ sdp_mid, Int32 sdp_mline_index, String ^ sdp);
			event OnCallbackIceCandidate ^ OnIceCandidate;

			delegate void OnIceStateChangedCallback(IceConnectionStates state);
			event OnIceStateChangedCallback ^ OnIceStateChanged;

			event Action ^ OnError;

			delegate void OnCallbackError(String ^ error);
			event OnCallbackError ^ OnFailure;

			delegate void OnCallbackDataMessage(String ^ msg);
			event OnCallbackDataMessage ^ OnDataMessage;

			delegate void OnCallbackDataBinaryMessage(array<Byte>^ msg);
			event OnCallbackDataBinaryMessage ^ OnDataBinaryMessage;

			delegate void OnCallbackRender(System::Byte * frame_buffer, System::UInt32 w, System::UInt32 h);
			event OnCallbackRender ^ OnRenderLocal;
			event OnCallbackRender ^ OnRenderRemote;

			ManagedConductor()
			{
				m_isDisposed = false;
				cd = new Native::Conductor();

				onRenderLocal = gcnew _OnRenderCallback(this, &ManagedConductor::_OnRenderLocal);
				onRenderLocalHandle = GCHandle::Alloc(onRenderLocal);
				cd->onRenderLocal = static_cast<Native::OnRenderCallbackNative>(Marshal::GetFunctionPointerForDelegate(onRenderLocal).ToPointer());

				onRenderRemote = gcnew _OnRenderCallback(this, &ManagedConductor::_OnRenderRemote);
				onRenderRemoteHandle = GCHandle::Alloc(onRenderRemote);
				cd->onRenderRemote = static_cast<Native::OnRenderCallbackNative>(Marshal::GetFunctionPointerForDelegate(onRenderRemote).ToPointer());

				onError = gcnew _OnErrorCallback(this, &ManagedConductor::_OnError);
				onErrorHandle = GCHandle::Alloc(onError);
				cd->onError = static_cast<Native::OnErrorCallbackNative>(Marshal::GetFunctionPointerForDelegate(onError).ToPointer());

				onSuccess = gcnew _OnSuccessCallback(this, &ManagedConductor::_OnSuccess);
				onSuccessHandle = GCHandle::Alloc(onSuccess);
				cd->onSuccess = static_cast<Native::OnSuccessCallbackNative>(Marshal::GetFunctionPointerForDelegate(onSuccess).ToPointer());

				onIceStateChanged = gcnew _OnIceStateChangedCallback(this, &ManagedConductor::_OnIceStateChanged);
				onIceStateChangedHandle = GCHandle::Alloc(onIceStateChanged);
				cd->onIceStateChanged = static_cast<Native::OnIceStateChangedCallbackNative>(Marshal::GetFunctionPointerForDelegate(onIceStateChanged).ToPointer());

				onFailure = gcnew _OnFailureCallback(this, &ManagedConductor::_OnFailure);
				onFailureHandle = GCHandle::Alloc(onFailure);
				cd->onFailure = static_cast<Native::OnFailureCallbackNative>(Marshal::GetFunctionPointerForDelegate(onFailure).ToPointer());

				onDataMessage = gcnew _OnDataMessageCallback(this, &ManagedConductor::_OnDataMessage);
				onDataMessageHandle = GCHandle::Alloc(onDataMessage);
				cd->onDataMessage = static_cast<Native::OnDataMessageCallbackNative>(Marshal::GetFunctionPointerForDelegate(onDataMessage).ToPointer());

				onDataBinaryMessage = gcnew _OnDataBinaryMessageCallback(this, &ManagedConductor::_OnDataBinaryMessage);
				onDataBinaryMessageHandle = GCHandle::Alloc(onDataBinaryMessage);
				cd->onDataBinaryMessage = static_cast<Native::OnDataBinaryMessageCallbackNative>(Marshal::GetFunctionPointerForDelegate(onDataBinaryMessage).ToPointer());

				onIceCandidate = gcnew _OnIceCandidateCallback(this, &ManagedConductor::_OnIceCandidate);
				onIceCandidateHandle = GCHandle::Alloc(onIceCandidate);
				cd->onIceCandidate = static_cast<Native::OnIceCandidateCallbackNative>(Marshal::GetFunctionPointerForDelegate(onIceCandidate).ToPointer());
			}

			~ManagedConductor()
			{
				if (m_isDisposed)
					return;

				m_isDisposed = true;

				cd->Dispose();

				// dispose managed data
				FreeGCHandle(onErrorHandle);
				FreeGCHandle(onSuccessHandle);
				FreeGCHandle(onIceStateChangedHandle);
				FreeGCHandle(onFailureHandle);
				FreeGCHandle(onIceCandidateHandle);
				FreeGCHandle(onRenderLocalHandle);
				FreeGCHandle(onRenderRemoteHandle);
				FreeGCHandle(onDataMessageHandle);

    			//this->!ManagedConductor(); // call finalizer
			}

			static void InitializeSSL()
			{
				Native::InitializeSSL();
			}

			static void CleanupSSL()
			{
				Native::CleanupSSL();
			}

			bool InitializePeerConnection()
			{
				return cd->InitializePeerConnection();
			}

			void CreateOffer()
			{
				cd->CreateOffer();
			}

			bool ProcessMessages(Int32 delay)
			{
				return cd->ProcessMessages(delay);
			}

			bool OpenVideoCaptureDevice(String ^ name)
			{
				return cd->OpenVideoCaptureDevice(marshal_as<std::string>(name));
			}

			static System::Collections::Generic::List<String^> ^ GetVideoDevices()
			{
				System::Collections::Generic::List<String^> ^ ret = nullptr;
				std::vector<std::string> devices = Native::Conductor::GetVideoDevices();
				for (const auto & d : devices)
				{
					if (ret == nullptr)
					{
						ret = gcnew System::Collections::Generic::List<String^>();
					}
					ret->Add(marshal_as<String^>(d));
				}
				return ret;
			}

			void OnOfferReply(String ^ type, String ^ sdp)
			{
				cd->OnOfferReply(marshal_as<std::string>(type), marshal_as<std::string>(sdp));
			}

			void OnOfferRequest(String ^ sdp)
			{
				cd->OnOfferRequest(marshal_as<std::string>(sdp));
			}

			bool AddIceCandidate(String ^ sdp_mid, Int32 sdp_mlineindex, String ^ sdp)
			{
				return cd->AddIceCandidate(marshal_as<std::string>(sdp_mid), sdp_mlineindex, marshal_as<std::string>(sdp));
			}

			void AddServerConfig(String ^ uri, String ^ username, String ^ password)
			{
				cd->AddServerConfig(marshal_as<std::string>(uri), marshal_as<std::string>(username), marshal_as<std::string>(password));
			}

			void CreateDataChannel(String ^ label)
			{
				cd->CreateDataChannel(marshal_as<std::string>(label));
			}

			void DataChannelSendText(String ^ text)
			{
				cd->DataChannelSendText(marshal_as<std::string>(text));
			}

			void DataChannelSendData(array<Byte>^ array_data)
			{
				pin_ptr<uint8_t> thePtr = &array_data[0];
				uint8_t * bPtr = thePtr;
				rtc::CopyOnWriteBuffer writeBuffer(bPtr, array_data->Length);
				cd->DataChannelSendData(webrtc::DataBuffer(writeBuffer, true));
			}

			void SetAudio(bool enable)
			{
				cd->audioEnabled = enable;
			}

			void SetVideoCapturer(int width, int height, int caputureFps, bool barcodeEnabled)
			{
				cd->width_ = width;
				cd->height_ = height;
				cd->caputureFps = caputureFps;
				cd->barcodeEnabled = barcodeEnabled;
			}

			System::Byte * VideoCapturerI420Buffer()
			{
				return cd->VideoCapturerI420Buffer();
			}

			void PushFrame()
			{
				cd->PushFrame();
			}

			System::Byte * DesktopCapturerRGBAbuffer()
			{
#if DESKTOP_CAPTURE
				return cd->DesktopCapturerRGBAbuffer();
#else
				throw gcnew System::NotImplementedException("set internals.h #define DESKTOP_CAPTURE 1");
#endif
			}

			void DesktopCapturerSize(Int32 % w, Int32 % h)
			{
#if DESKTOP_CAPTURE
				int wn = 0, hn = 0;
				cd->DesktopCapturerSize(wn, hn);
				w = wn;
				h = hn;
#else
				throw gcnew System::NotImplementedException("set internals.h #define DESKTOP_CAPTURE 1");
#endif
			}

			void CaptureFrame()
			{
#if DESKTOP_CAPTURE
				cd->CaptureFrame();
#else
				throw gcnew System::NotImplementedException("set internals.h #define DESKTOP_CAPTURE 1");
#endif
			}

#pragma region -- Servers --
			bool RunStunServer(String ^ bindIp)
			{
				return cd->RunStunServer(marshal_as<std::string>(bindIp));
			}

			// File is stored as lines of <username>=<HA1>.
			// Generate HA1 via "echo -n "<username>:<realm>:<password>" | md5sum"
			bool RunTurnServer(String ^ bindIp, String ^ ip, String ^ realm, String ^ authFile)
			{
				return cd->RunTurnServer(marshal_as<std::string>(bindIp), marshal_as<std::string>(ip), marshal_as<std::string>(realm), marshal_as<std::string>(authFile));
			}
#pragma endregion

		protected:

			!ManagedConductor()
			{
				// free unmanaged data
				//if (cd != NULL)
				//{
				//	delete cd;					
				//}
				//cd = NULL;
			}
		};
	}
}