私はWindowsPhoneでプログラミングする方法を学びたいというプライベートプロジェクトに取り組んでおり、ある時点でソケットとカメラをいじり始め、ビデオフィードを思いついたのです(私は試してみることさえできませんでした) )。
しかし今、私はここにいます。それは魅力のように機能しますが、Lumia800はforループを十分に速く通過することができません。それは、7〜8秒ごとにフレームを送信します。それは、十分に強いはずなので、奇妙だと思います。ポルノなしで56kモデムでポルノを見ているように感じ、見えます。
また、フレームが317000ピクセルであり、合計でフレームあたり約1MBになることにも気付きました。また、xy座標を送信しているので、フレームあたり2.3MBを使用しますが、これを抑えるために別の方法で解決しています。ですから、位置とピクセルの両方の値を許容可能なサイズにするために、ドームマジックを行う必要があると思います。atmは許容可能な速度でそれを取得するので、30fpsのようなものを取得するには少なくとも60MB /秒が必要ですが、それは別の日の問題です。
//How many pixels to send per burst (1000 seems to be the best)
const int PixelPerSend = 1000;
int bSize = 7 * PixelPerSend;
//Comunication thread UDP feed
private void EthernetComUDP() //Runs in own thread
{
//Connect to Server
clientUDP = new SocketClientUDP();
int[] ImageContent = new int[(int)cam.PreviewResolution.Height * (int)cam.PreviewResolution.Width];
byte[] PacketContent = new byte[bSize];
string Pixel,l;
while (SendingData)
{
cam.GetPreviewBufferArgb32(ImageContent);
int x = 1, y = 1, SenderCount = 0;
//In dire need of a speedup
for (int a = 0; a < ImageContent.Length; a++) //this loop
{
Pixel = Convert.ToString(ImageContent[a], 2).PadLeft(32, '0');
//A - removed to conserve bandwidth
//PacketContent[SenderCount] = Convert.ToByte(Pixel.Substring(0, 8), 2);//0
//R
PacketContent[SenderCount] = Convert.ToByte(Pixel.Substring(8, 8), 2);//8
//G
PacketContent[SenderCount + 1] = Convert.ToByte(Pixel.Substring(16, 8), 2);//16
//B
PacketContent[SenderCount + 2] = Convert.ToByte(Pixel.Substring(24, 8), 2);//24
//Coordinates
//X
l = Convert.ToString(x, 2).PadLeft(16, '0');
//X bit(1-8)
PacketContent[SenderCount + 3] = Convert.ToByte(l.Substring(0, 8), 2);
//X bit(9-16)
PacketContent[SenderCount + 4] = Convert.ToByte(l.Substring(8, 8), 2);
//Y
l = Convert.ToString(y, 2).PadLeft(16, '0');
//Y bit(1-8)
PacketContent[SenderCount + 5] = Convert.ToByte(l.Substring(0, 8), 2);
//Y bit(9-16)
PacketContent[SenderCount + 6] = Convert.ToByte(l.Substring(8, 8), 2);
x++;
if (x == cam.PreviewResolution.Width)
{
y++;
x = 1;
}
SenderCount += 7;
if (SenderCount == bSize)
{
clientUDP.Send(ConnectToIP, PORT + 1, PacketContent);
SenderCount = 0;
}
}
}
//Close on finish
clientUDP.Close();
}
私は簡単にするために、ピクセルを個別に使用して送信しようとしました
BitConverter.GetBytes(ImageContent[a]);
私が作成した文字列解析の混乱の代わりに(修正するには概念実証が必要でした)、単純なBitConverterを実行してもそれほど高速化されませんでした。
だから今、私の最後のアイデアで、UDP送信者ソケットの魔女はmsdnのライブラリのものとほぼ同じです。
public string Send(string serverName, int portNumber, byte[] payload)
{
string response = "Operation Timeout";
// We are re-using the _socket object that was initialized in the Connect method
if (_socket != null)
{
// Create SocketAsyncEventArgs context object
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
// Set properties on context object
socketEventArg.RemoteEndPoint = new DnsEndPoint(serverName, portNumber);
// Inline event handler for the Completed event.
// Note: This event handler was implemented inline in order to make this method self-contained.
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
response = e.SocketError.ToString();
// Unblock the UI thread
_clientDone.Set();
});
socketEventArg.SetBuffer(payload, 0, payload.Length);
// Sets the state of the event to nonsignaled, causing threads to block
_clientDone.Reset();
// Make an asynchronous Send request over the socket
_socket.SendToAsync(socketEventArg);
// Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
// If no response comes back within this time then proceed
_clientDone.WaitOne(TIMEOUT_MILLISECONDS);
}
else
{
response = "Socket is not initialized";
}
return response;
}
全体として、私は3つの解決策に行き着きました
敗北を受け入れる(しかし、それは起こらないので、2を見てみましょう)
送信されるデータの量を減らします(破壊品質640x480は十分に小さいと思います)
明らかな問題を見つけてください(グーグルと友人は良いアイデアを使い果たしました、それが私がここにいる理由です)