Skip to content

Commit

Permalink
native webrtc desktop capture editing!
Browse files Browse the repository at this point in the history
  • Loading branch information
radioman committed Feb 22, 2017
1 parent 9ccbce6 commit d3e0db4
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 55 deletions.
50 changes: 32 additions & 18 deletions WebRtc.NET.Demo/MainForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

69 changes: 38 additions & 31 deletions WebRtc.NET.Demo/MainForm.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
Expand Down Expand Up @@ -217,8 +218,9 @@ private void checkBoxWebsocket_CheckedChanged(object sender, EventArgs e)
Bitmap img;
Graphics g;

public int desktopWidth;
public int desktopHeight;
int desktopWidth;
int desktopHeight;
readonly Dictionary<IntPtr, Bitmap> imgDesktop = new Dictionary<IntPtr, Bitmap>();

private void timerVirtualCam_Tick(object sender, EventArgs e)
{
Expand All @@ -231,7 +233,7 @@ private void timerVirtualCam_Tick(object sender, EventArgs e)
img = new Bitmap(screenWidth, screenHeight, screenWidth * 3, PixelFormat.Format24bppRgb, imgBufPtr);
g = Graphics.FromImage(img);
}

{
// render
{
Expand All @@ -242,33 +244,38 @@ private void timerVirtualCam_Tick(object sender, EventArgs e)
g.CopyFromScreen(Cursor.Position, new Point(), new Size(screenWidth, screenHeight));
}

if (checkBoxScreen.Checked)
if (checkBoxInternalScreen.Checked)
{
#region -- TODO: native desktop capture --
//foreach (var s in webSocketServer.Streams)
//{
// s.Value.WebRtc.CaptureFrame();

// if (imgDesktop == null)
// {
// var bufHandle = GCHandle.Alloc(imgBufDesktop, GCHandleType.Pinned);
// varimgBufDesktopPtr = bufHandle.AddrOfPinnedObject();
// img = new Bitmap(screenWidth, screenHeight, screenWidth * 3, PixelFormat.Format24bppRgb, imgBufPtr);
// g = Graphics.FromImage(img);
// }
// if (desktopWidth == 0)
// {
// s.Value.WebRtc.DesktopCapturerSize(ref desktopWidth, ref desktopHeight);
// }
// unsafe
// {
// var rgba = s.Value.WebRtc.DesktopCapturerRGBAbuffer();
// if (rgba != null)
// {
// //encoderRemote.EncodeBGRAtoI420((byte*)imgBufPtr.ToPointer(), screenWidth, screenHeight, yuv, 0, true);
// }
// }
//}
#region -- native webrtc desktop capture --

//set internals.h #define DESKTOP_CAPTURE 1

foreach (var s in webSocketServer.Streams)
{
s.Value.WebRtc.CaptureFrame();
unsafe
{
var rgba = s.Value.WebRtc.DesktopCapturerRGBAbuffer();
if (rgba != null)
{
var rgbaPtr = new IntPtr(rgba);
Bitmap desktopImg;
if(!imgDesktop.TryGetValue(rgbaPtr, out desktopImg))
{
s.Value.WebRtc.DesktopCapturerSize(ref desktopWidth, ref desktopHeight);
imgDesktop[rgbaPtr] = new Bitmap(desktopWidth, desktopHeight, desktopWidth * 4, PixelFormat.Format32bppRgb, rgbaPtr);
}

g.DrawImage(desktopImg, 0,0, new Rectangle(Cursor.Position, new Size(screenWidth, screenHeight)), GraphicsUnit.Pixel);

// if no editing is needed
//var yuv = s.Value.WebRtc.VideoCapturerI420Buffer();
//encoderRemote.EncodeI420((byte*)rgba, screenWidth, screenHeight, (int)TJPF.TJPF_BGRX, 0, true, yuv);
}
}
break;
}

#endregion
}

Expand All @@ -285,7 +292,7 @@ private void timerVirtualCam_Tick(object sender, EventArgs e)
var yuv = s.Value.WebRtc.VideoCapturerI420Buffer();
if (yuv != null)
{
encoderRemote.EncodeBGR24toI420((byte*)imgBufPtr.ToPointer(), screenWidth, screenHeight, yuv, 0, true);
encoderRemote.EncodeI420((byte*)imgBufPtr.ToPointer(), screenWidth, screenHeight, (int)TJPF.TJPF_BGR, 0, true, yuv);
}
}
}
Expand All @@ -295,7 +302,7 @@ private void timerVirtualCam_Tick(object sender, EventArgs e)
}
catch (Exception ex)
{
Debug.WriteLine("timerDemo_Tick: " + ex);
Trace.WriteLine("timerDemo_Tick: " + ex);
}
}

Expand Down
6 changes: 3 additions & 3 deletions WebRtc.NET/src/TJpeg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,13 @@ namespace WebRtc
return 0;
}

int TurboJpegEncoder::EncodeBGR24toI420(Byte * rgbBuf, Int32 w, Int32 h, Byte * yuv, Int64 yuvSize, Boolean fast)
int TurboJpegEncoder::EncodeI420(Byte * rgbBuf, Int32 w, Int32 h, Int32 pxFormat, Int64 yuvSize, Boolean fast, Byte * yuv)
{
int pad = 4;

int width = w;
int height = h;
int pitch = TJPAD(tjPixelSize[TJPF_BGR] * width);
int pitch = TJPAD(tjPixelSize[pxFormat] * width);

if (yuvSize > 0)
{
Expand All @@ -242,7 +242,7 @@ namespace WebRtc
}
}

int r = tjEncodeYUV3(jpegc, rgbBuf, width, pitch, height, TJPF_BGR, yuv, pad, TJSAMP_420, fast ? TJFLAG_FASTDCT : TJFLAG_ACCURATEDCT);
int r = tjEncodeYUV3(jpegc, rgbBuf, width, pitch, height, pxFormat, yuv, pad, TJSAMP_420, fast ? TJFLAG_FASTDCT : TJFLAG_ACCURATEDCT);
if (r != 0)
{
Debug::WriteLine(String::Format("tjEncodeYUV3, LastJpegError: {0}", LastJpegError));
Expand Down
2 changes: 1 addition & 1 deletion WebRtc.NET/src/TJpeg.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace WebRtc
int EncodeJpegToI420(array<Byte> ^ buffer, array<Byte> ^% yuv);

int EncodeI420(array<System::Byte> ^ buffer, Int32 w, Int32 h, Int32 pxFormat, System::Boolean fast, array<System::Byte> ^% yuv);
int EncodeBGR24toI420(Byte * rgbBuf, Int32 w, Int32 h, Byte * yuv, Int64 yuvSize, Boolean fast);
int EncodeI420(Byte * rgbBuf, Int32 w, Int32 h, Int32 pxFormat, Int64 yuvSize, Boolean fast, Byte * yuv);
int EncodeI420toBGR24(Byte * yuv, UInt32 w, UInt32 h, array<System::Byte> ^% bgrBuffer, Boolean fast);

int EncodeJpeg(array<Byte> ^ buffer, Int32 bufferSize, array<Byte> ^% rgb, Int32 maxwidth, Double scale, Int32 % jwidth, Int32 % jheight, Int32 % pitch, Int32 pxFormat);
Expand Down
14 changes: 12 additions & 2 deletions WebRtc.NET/src/managed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,25 +323,35 @@ namespace WebRtc
cd->PushFrame();
}

#if DESKTOP_CAPTURE
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)
Expand Down

0 comments on commit d3e0db4

Please sign in to comment.