Skip to content

Commit

Permalink
switch to PushFrame interface
Browse files Browse the repository at this point in the history
  • Loading branch information
radioman committed Dec 10, 2016
1 parent 33e5e13 commit 15e0624
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 229 deletions.
58 changes: 32 additions & 26 deletions WebRtc.NET.Demo/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,25 +48,7 @@ private void MainForm_Shown(object sender, EventArgs e)
checkBoxWebsocket.Checked = true;
}

const int screenWidth = 640;
const int screenHeight = 360;

readonly byte[] imgBuf = new byte[screenWidth * 3 * screenHeight];
IntPtr imgBufPtr = IntPtr.Zero;
Bitmap img;
readonly Bitmap imgView = new Bitmap(screenWidth, screenHeight, PixelFormat.Format24bppRgb);

readonly TurboJpegEncoder encoder = TurboJpegEncoder.CreateEncoder();
public unsafe void OnFillBuffer(byte* yuv, uint yuvSize)
{
if (SetEncode && imgBufPtr != IntPtr.Zero)
{
lock (img)
{
encoder.EncodeBGR24toI420((byte*)imgBufPtr.ToPointer(), screenWidth, screenHeight, yuv, yuvSize, true);
}
}
}

byte[] bgrBuff;
Bitmap remoteImg;
Expand Down Expand Up @@ -159,9 +141,9 @@ private void checkBoxWebsocket_CheckedChanged(object sender, EventArgs e)
if (checkBoxWebsocket.Checked)
{
webSocketServer = new WebRTCServer((int)numericWebSocket.Value);
webSocketServer.Form = this;
unsafe
{
webSocketServer.OnFillBuffer = OnFillBuffer;
webSocketServer.OnRenderRemote = OnRenderRemote;
}
numericMaxClients_ValueChanged(null, null);
Expand All @@ -180,6 +162,17 @@ private void checkBoxWebsocket_CheckedChanged(object sender, EventArgs e)

private System.Windows.Forms.Timer timerDemo;

public const bool audio = true;
public const int screenWidth = 640;
public const int screenHeight = 360;
public const int captureFps = 5;
public const bool barCodeScreen = false;

readonly byte[] imgBuf = new byte[screenWidth * 3 * screenHeight];
IntPtr imgBufPtr = IntPtr.Zero;
Bitmap img;
readonly Bitmap imgView = new Bitmap(screenWidth, screenHeight, PixelFormat.Format24bppRgb);

private void timerDemo_Tick(object sender, EventArgs e)
{
try
Expand All @@ -193,15 +186,28 @@ private void timerDemo_Tick(object sender, EventArgs e)

if (SetEncode)
{
lock (img)
using (var g = Graphics.FromImage(img))
{
using (var g = Graphics.FromImage(img))
{
g.Clear(Color.DarkBlue);
g.Clear(Color.DarkBlue);

var rc = RectangleF.FromLTRB(0, 0, img.Width, img.Height);
g.DrawString(string.Format("{0}", DateTime.Now.ToString("hh:mm:ss.fff")), fBig, Brushes.LimeGreen, rc, sfTopRight);
var rc = RectangleF.FromLTRB(0, 0, img.Width, img.Height);
g.DrawString(string.Format("{0}", DateTime.Now.ToString("hh:mm:ss.fff")), fBig, Brushes.LimeGreen, rc, sfTopRight);
}

foreach (var s in webSocketServer.Streams)
{
if (!barCodeScreen)
{
unsafe
{
var yuv = s.Value.WebRtc.VideoCapturerI420Buffer();
if (yuv != null)
{
encoder.EncodeBGR24toI420((byte*)imgBufPtr.ToPointer(), screenWidth, screenHeight, yuv, 0, true);
}
}
}
s.Value.WebRtc.PushFrame();
}
}

Expand Down Expand Up @@ -238,7 +244,7 @@ private void checkBoxDemo_CheckedChanged(object sender, EventArgs e)
if (timerDemo == null)
{
timerDemo = new System.Windows.Forms.Timer();
timerDemo.Interval = 200;
timerDemo.Interval = 1000 / captureFps;
timerDemo.Tick += timerDemo_Tick;
}
timerDemo.Enabled = checkBoxDemo.Checked;
Expand Down
29 changes: 13 additions & 16 deletions WebRtc.NET.Demo/WebRTCServer.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@

namespace WebRtc.NET.Demo
{
using Fleck;
using LitJson;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.Threading.Tasks;
using Fleck;
using LitJson;
class WebRTCServer : IDisposable
{
class WebRtcSession
public class WebRtcSession
{
public readonly ManagedConductor WebRtc;
public readonly CancellationTokenSource Cancel;
Expand All @@ -25,10 +22,12 @@ public WebRtcSession()
}
}

ConcurrentDictionary<Guid, IWebSocketConnection> UserList = new ConcurrentDictionary<Guid, IWebSocketConnection>();
ConcurrentDictionary<Guid, WebRtcSession> Streams = new ConcurrentDictionary<Guid, WebRtcSession>();
public readonly ConcurrentDictionary<Guid, IWebSocketConnection> UserList = new ConcurrentDictionary<Guid, IWebSocketConnection>();
public readonly ConcurrentDictionary<Guid, WebRtcSession> Streams = new ConcurrentDictionary<Guid, WebRtcSession>();

WebSocketServer server;
public MainForm Form;

public WebRTCServer(int port) : this("ws://0.0.0.0:" + port)
{

Expand Down Expand Up @@ -187,7 +186,11 @@ private void OnReceive(IWebSocketConnection context, string msg)
session.WebRtc.AddServerConfig("stun:stun.stunprotocol.org:3478", string.Empty, string.Empty);
//session.WebRtc.AddServerConfig("turn:127.0.0.1:444", "test", "test");

session.WebRtc.SetAudio(true);
session.WebRtc.SetAudio(MainForm.audio);
session.WebRtc.SetVideoCapturer(MainForm.screenWidth,
MainForm.screenHeight,
MainForm.captureFps,
MainForm.barCodeScreen);

var ok = session.WebRtc.InitializePeerConnection();
if (ok)
Expand Down Expand Up @@ -251,11 +254,6 @@ private void OnReceive(IWebSocketConnection context, string msg)

unsafe
{
session.WebRtc.OnFillBuffer += delegate (byte * frame_buffer, uint yuvSize)
{
OnFillBuffer(frame_buffer, yuvSize);
};

session.WebRtc.OnRenderRemote += delegate (byte* frame_buffer, uint w, uint h)
{
OnRenderRemote(frame_buffer, w, h);
Expand Down Expand Up @@ -291,7 +289,6 @@ private void OnReceive(IWebSocketConnection context, string msg)
}
}

public ManagedConductor.OnCallbackFillBuffer OnFillBuffer;
public ManagedConductor.OnCallbackRender OnRenderRemote;

public void Dispose()
Expand Down
11 changes: 7 additions & 4 deletions WebRtc.NET/src/TJpeg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,14 @@ namespace WebRtc
int height = h;
int pitch = TJPAD(tjPixelSize[TJPF_BGR] * width);

int yuvSizeCheck = tjBufSizeYUV2(width, pad, height, TJSAMP_420);
if (yuvSizeCheck != yuvSize)
if (yuvSize > 0)
{
Debug::WriteLine(String::Format("tjBufSizeYUV2, yuvSizeCheck[{0}] != {1}", yuvSizeCheck, yuvSize));
return -1;
int yuvSizeCheck = tjBufSizeYUV2(width, pad, height, TJSAMP_420);
if (yuvSizeCheck != yuvSize)
{
Debug::WriteLine(String::Format("tjBufSizeYUV2, yuvSizeCheck[{0}] != {1}", yuvSizeCheck, yuvSize));
return -1;
}
}

int r = tjEncodeYUV3(jpegc, rgbBuf, width, pitch, height, TJPF_BGR, yuv, pad, TJSAMP_420, fast ? TJFLAG_FASTDCT : TJFLAG_ACCURATEDCT);
Expand Down
52 changes: 25 additions & 27 deletions WebRtc.NET/src/conductor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ namespace Native
onSuccess = nullptr;
onFailure = nullptr;
onIceCandidate = nullptr;
capturer = nullptr;

width_ = 640;
height_ = 360;
caputureFps = 5;
barcodeEnabled = false;
audioEnabled = false;
Expand All @@ -81,15 +82,11 @@ namespace Native
if (turnServer)
{
turnServer->disconnect_all();
delete turnServer;
turnServer = nullptr;
}

if (stunServer)
{
stunServer->disconnect_all();
delete stunServer;
stunServer = nullptr;
}

if (turnServer || stunServer)
Expand All @@ -115,7 +112,6 @@ namespace Native
}

pc_factory_ = nullptr;
capturer = nullptr;

if (data_channel)
{
Expand Down Expand Up @@ -264,14 +260,6 @@ namespace Native

// ...

void Conductor::OnFillBuffer(uint8_t * frame_buffer, uint32_t yuvSize)
{
if (onFillBuffer)
{
onFillBuffer(frame_buffer, yuvSize);
}
}

bool Conductor::OpenVideoCaptureDevice()
{
std::vector<std::string> device_names;
Expand All @@ -294,11 +282,10 @@ namespace Native
}

cricket::WebRtcVideoDeviceCapturerFactory factory;
cricket::VideoCapturer * capturer = nullptr;
for (const auto& name : device_names)
{
capturer = factory.Create(cricket::Device(name, 0));
if (capturer)
capturer_internal.reset(factory.Create(cricket::Device(name, 0)));
if (capturer_internal)
{
LOG(LS_ERROR) << "Capturer != NULL!";
return true;
Expand All @@ -313,12 +300,18 @@ namespace Native
if (active_streams_.find(kStreamLabel) != active_streams_.end())
return; // Already added.

if (!capturer)
cricket::VideoCapturer * vc = nullptr;
if (capturer_internal)
{
capturer = new Native::YuvFramesCapturer2(*this);
vc = capturer_internal.get();
}
else
{
capturer.reset(new Native::YuvFramesCapturer2(*this));
vc = capturer.get();
}

auto v = pc_factory_->CreateVideoSource(capturer, NULL);
auto v = pc_factory_->CreateVideoSource(vc, NULL);
auto video_track = pc_factory_->CreateVideoTrack(kVideoLabel, v);
if (onRenderLocal)
{
Expand Down Expand Up @@ -375,6 +368,8 @@ namespace Native
LOG(INFO) << __FUNCTION__ << " " << stream->label();
remote_video.reset();
remote_audio.reset();
capturer.reset();
capturer_internal.reset();
}

void Conductor::OnIceCandidate(const webrtc::IceCandidateInterface* candidate)
Expand Down Expand Up @@ -486,7 +481,7 @@ namespace Native
return false;
}

stunServer = new cricket::StunServer(server_socket);
stunServer.reset(new cricket::StunServer(server_socket));

LOG(INFO) << "Listening at " << server_addr.ToString() << std::endl;

Expand Down Expand Up @@ -525,12 +520,15 @@ namespace Native
return false;
}

turnServer = new cricket::TurnServer(main);
turnServer->set_realm(realm);
turnServer->set_software(kSoftware);
turnServer->set_auth_hook(auth);
turnServer->AddInternalSocket(int_socket, cricket::PROTO_UDP);
turnServer->SetExternalSocketFactory(new rtc::BasicPacketSocketFactory(),

auto t = new cricket::TurnServer(main);
turnServer.reset(t);

t->set_realm(realm);
t->set_software(kSoftware);
t->set_auth_hook(auth);
t->AddInternalSocket(int_socket, cricket::PROTO_UDP);
t->SetExternalSocketFactory(new rtc::BasicPacketSocketFactory(),
rtc::SocketAddress(ext_addr, 0));

LOG(INFO) << "Listening internally at " << int_addr.ToString() << std::endl;
Expand Down
34 changes: 22 additions & 12 deletions WebRtc.NET/src/conductor.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ namespace Native
typedef void(__stdcall *OnSuccessCallbackNative)(const char * type, const char * sdp);
typedef void(__stdcall *OnFailureCallbackNative)(const char * error);
typedef void(__stdcall *OnIceCandidateCallbackNative)(const char * sdp_mid, int sdp_mline_index, const char * sdp);
typedef void(__stdcall *OnFillBufferCallbackNative)(uint8_t * frame_buffer, uint32_t yuvSize);
typedef void(__stdcall *OnRenderCallbackNative)(uint8_t * frame_buffer, uint32_t w, uint32_t h);
typedef void(__stdcall *OnDataMessageCallbackNative)(const char * msg);

Expand All @@ -44,12 +43,23 @@ namespace Native
}

bool OpenVideoCaptureDevice();
void OnFillBuffer(uint8_t * frame_buffer, uint32_t yuvSize);
void AddServerConfig(std::string uri, std::string username, std::string password);

void SetAudio(bool enable)
uint8_t * VideoCapturerI420Buffer()
{
audioEnabled = enable;
if (capturer)
{
return (uint8_t*)capturer->video_buffer->DataY();
}
return nullptr;
}

void PushFrame()
{
if (capturer)
{
capturer->PushFrame();
}
}

void CreateDataChannel(const std::string & label);
Expand All @@ -59,7 +69,6 @@ namespace Native
OnSuccessCallbackNative onSuccess;
OnFailureCallbackNative onFailure;
OnIceCandidateCallbackNative onIceCandidate;
OnFillBufferCallbackNative onFillBuffer;
OnRenderCallbackNative onRenderLocal;
OnRenderCallbackNative onRenderRemote;
OnDataMessageCallbackNative onDataMessage;
Expand Down Expand Up @@ -159,29 +168,30 @@ namespace Native

bool CreatePeerConnection(bool dtls);
void DeletePeerConnection();
void AddStreams();

cricket::VideoCapturer * capturer;
void AddStreams();

rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_;
std::map<std::string, rtc::scoped_refptr<webrtc::MediaStreamInterface>> active_streams_;

rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel;

std::vector<webrtc::PeerConnectionInterface::IceServer> serverConfigs;

std::unique_ptr<YuvFramesCapturer2> capturer;
std::unique_ptr<cricket::VideoCapturer> capturer_internal;
std::unique_ptr<VideoRenderer> local_video;
std::unique_ptr<VideoRenderer> remote_video;
std::unique_ptr<AudioRenderer> remote_audio;

cricket::TurnServer * turnServer;
cricket::StunServer * stunServer;
std::unique_ptr<cricket::TurnServer> turnServer;
std::unique_ptr<cricket::StunServer> stunServer;

public:
int caputureFps;
bool barcodeEnabled;
bool audioEnabled;

int width_;
int height_;
};
}
#endif // WEBRTC_NET_CONDUCTOR_H_
Loading

0 comments on commit 15e0624

Please sign in to comment.