0

私のプロジェクトでは、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);
        }
    }
}
4

2 に答える 2

0

コードをffmpegでテストしました

ffmpeg.exe -i aa.mp4 -f mpeg udp://224.0.0.21:3956

int PORT = 3956;
string MULTICAST_IP = "224.0.0.21";


UdpClient udpClient = new UdpClient(PORT);
udpClient.JoinMulticastGroup(IPAddress.Parse(MULTICAST_IP));

var from = new IPEndPoint(0, 0);
var recvBuffer = udpClient.Receive(ref from);
于 2017-08-24T18:54:00.910 に答える