私のプロジェクトでは、UDP 経由でビデオを受信する必要があります。ソースには IP 224.0.0.21 があり、シンクには IP 169.254.170.141 があります。ポート 3956 からビデオを受信しています (これは Wireshark からの有効な情報です)。UDP トラフィックの受信に SharpPcap を使用していますが、マルチキャストに参加する方法がありません。MSDN からこのコードを試してみましたが、うまくいきません。
IPAddress multicastaddress = IPAddress.Parse("224.0.0.21");
IPEndPoint remoteep = new IPEndPoint(IPAddress.Any, 3956);
m_ClientTarget.JoinMulticastGroup(multicastaddress, localAddr);
私の PC にはいくつかのネットワーク アダプターがありますが、ソース ビデオに接続されているデバイスの IP アドレスを使用しています。ソースとシンクが直結。Wireshark でトラフィックの監視を開始すると、プログラムもパケットを受信しますが、Wireshack がないとそれを実行できません。私のコード:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SharpPcap;
using SharpPcap.LibPcap;
using SharpPcap.AirPcap;
using SharpPcap.WinPcap;
using System.IO;
using System.Net.Sockets;
using System.Net;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Threading;
namespace GVSPCapture
{
public partial class Form1 : Form
{
static int frameCounter = 0;
static byte[] pixels = new byte[1920 * 1080 * 3];
static IPAddress fpgaAddr = IPAddress.Parse("224.0.0.21");
static IPAddress localAddr = IPAddress.Parse("169.254.170.141");
static MulticastOption mcastOption = new MulticastOption(fpgaAddr, localAddr);
private static UdpClient m_ClientTarget = new UdpClient(3956);
private static IPAddress m_GrpAddr;
const int GroupPort = 3956;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
findDevices();
}
public void findDevices()
{
string ver = SharpPcap.Version.VersionString;
var devices = CaptureDeviceList.Instance;
foreach (var dev in devices)
{
lbxDevices.Items.Add(dev.Name + dev.Description);
}
}
private void JoinVideoMulticast()
{
IPAddress multicastaddress = IPAddress.Parse("224.0.0.21");
IPEndPoint remoteep = new IPEndPoint(IPAddress.Any, 3956);
m_ClientTarget.JoinMulticastGroup(multicastaddress, IPAddress.Parse("169.254.170.141"));
while (true)
{ }
}
private void startCapture(ICaptureDevice dev)
{
if (!dev.Started)
{
dev.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival);
int readTimeoutMilliseconds = 1000;
if (dev is AirPcapDevice)
{
// NOTE: AirPcap devices cannot disable local capture
var airPcap = dev as AirPcapDevice;
airPcap.Open(SharpPcap.WinPcap.OpenFlags.DataTransferUdp, readTimeoutMilliseconds);
}
else if (dev is WinPcapDevice)
{
var winPcap = dev as WinPcapDevice;
winPcap.Open(SharpPcap.WinPcap.OpenFlags.DataTransferUdp | SharpPcap.WinPcap.OpenFlags.NoCaptureLocal, readTimeoutMilliseconds);
}
else if (dev is LibPcapLiveDevice)
{
var livePcapDevice = dev as LibPcapLiveDevice;
livePcapDevice.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
}
else
{
throw new System.InvalidOperationException("unknown device type of " + dev.GetType().ToString());
}
dev.StartCapture();
Thread recvThread = new Thread(JoinVideoMulticast);
recvThread.Start();
}
}
delegate void SetTextCallback(string text);
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.tbxCnt.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.tbxCnt.Text = text;
}
}
private void device_OnPacketArrival(object sender, CaptureEventArgs e)
{
var time = e.Packet.Timeval.Date;
var len = e.Packet.Data.Length;
if (len == 572)
{
var tmp = e.Packet.Data;
int packet_id = tmp[47] << 16 | tmp[48] << 8 | tmp[49];
int startPos = (packet_id - 1) * 522;
for (int i = 50; i < tmp.Length; i+=3)
{
pixels[startPos + i + 0 - 50] = tmp[i];
pixels[startPos + i + 1 - 50] = tmp[i];
pixels[startPos + i + 2 - 50] = tmp[i];
}
}
if (len == 60)
{
var im = CopyDataToBitmap(pixels);
pictbFrame.Image = im;
frameCounter += 1;
SetText(frameCounter.ToString());
}
}
public Bitmap CopyDataToBitmap(byte[] data)
{
GCHandle pinned = GCHandle.Alloc(data, GCHandleType.Pinned);
IntPtr ptr = pinned.AddrOfPinnedObject();
BitmapData dt = new BitmapData();
dt.Scan0 = ptr;
dt.Stride = 5760;
dt.Width = 1920;
dt.Height = 1080;
dt.PixelFormat = PixelFormat.Format24bppRgb;
Bitmap btm = new Bitmap(1920, 1080, 5760, PixelFormat.Format24bppRgb, dt.Scan0);
return btm;
}
private void btnStart_Click(object sender, EventArgs e)
{
int devNum = lbxDevices.SelectedIndex;
if (devNum > 0)
{
var device = CaptureDeviceList.Instance[devNum];
startCapture(device);
}
}
private void btnStop_Click(object sender, EventArgs e)
{
int devNum = lbxDevices.SelectedIndex;
if (devNum > 0)
{
var device = CaptureDeviceList.Instance[devNum];
if (device.Started)
{
device.StopCapture();
device.Close();
}
}
m_ClientTarget.DropMulticastGroup(fpgaAddr);
}
}
}