|
|
@@ -0,0 +1,74 @@
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Text;
|
|
|
+using ivf_tl_Operate.Debug;
|
|
|
+using Xunit;
|
|
|
+
|
|
|
+namespace IvfTl.ControlHost.Tests
|
|
|
+{
|
|
|
+ public class MjpegFrameParserTests
|
|
|
+ {
|
|
|
+ // 造一个 multipart 帧字节(与 control MjpegStreamWriter.FrameBytes 同格式)。
|
|
|
+ private static byte[] MakeFrame(byte[] jpeg)
|
|
|
+ {
|
|
|
+ string head = $"--frame\r\nContent-Type: image/jpeg\r\nContent-Length: {jpeg.Length}\r\n\r\n";
|
|
|
+ var ms = new List<byte>();
|
|
|
+ ms.AddRange(Encoding.ASCII.GetBytes(head));
|
|
|
+ ms.AddRange(jpeg);
|
|
|
+ ms.AddRange(Encoding.ASCII.GetBytes("\r\n"));
|
|
|
+ return ms.ToArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<byte[]> FeedAll(MjpegFrameParser p, byte[] data)
|
|
|
+ {
|
|
|
+ var all = new List<byte[]>();
|
|
|
+ all.AddRange(p.Feed(data, data.Length));
|
|
|
+ return all;
|
|
|
+ }
|
|
|
+
|
|
|
+ [Fact]
|
|
|
+ public void SingleWholeFrame_YieldsOneJpeg()
|
|
|
+ {
|
|
|
+ var jpeg = new byte[] { 0xFF, 0xD8, 1, 2, 3, 0xFF, 0xD9 };
|
|
|
+ var p = new MjpegFrameParser();
|
|
|
+ var frames = FeedAll(p, MakeFrame(jpeg));
|
|
|
+ Assert.Single(frames);
|
|
|
+ Assert.Equal(jpeg, frames[0]);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Fact]
|
|
|
+ public void TwoFramesInOneChunk_YieldsTwo()
|
|
|
+ {
|
|
|
+ var j1 = new byte[] { 0xFF, 0xD8, 1, 0xFF, 0xD9 };
|
|
|
+ var j2 = new byte[] { 0xFF, 0xD8, 9, 8, 0xFF, 0xD9 };
|
|
|
+ var combined = new List<byte>();
|
|
|
+ combined.AddRange(MakeFrame(j1));
|
|
|
+ combined.AddRange(MakeFrame(j2));
|
|
|
+ var p = new MjpegFrameParser();
|
|
|
+ var frames = FeedAll(p, combined.ToArray());
|
|
|
+ Assert.Equal(2, frames.Count);
|
|
|
+ Assert.Equal(j1, frames[0]);
|
|
|
+ Assert.Equal(j2, frames[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Fact]
|
|
|
+ public void FrameSplitAcrossChunks_Reassembles()
|
|
|
+ {
|
|
|
+ var jpeg = new byte[] { 0xFF, 0xD8, 5, 6, 7, 8, 0xFF, 0xD9 };
|
|
|
+ byte[] full = MakeFrame(jpeg);
|
|
|
+ var p = new MjpegFrameParser();
|
|
|
+ // 在帧中间切两半喂
|
|
|
+ int mid = full.Length / 2;
|
|
|
+ var first = new byte[mid];
|
|
|
+ var second = new byte[full.Length - mid];
|
|
|
+ System.Array.Copy(full, 0, first, 0, mid);
|
|
|
+ System.Array.Copy(full, mid, second, 0, second.Length);
|
|
|
+
|
|
|
+ var frames = new List<byte[]>();
|
|
|
+ frames.AddRange(p.Feed(first, first.Length));
|
|
|
+ Assert.Empty(frames); // 半帧,还吐不出
|
|
|
+ frames.AddRange(p.Feed(second, second.Length));
|
|
|
+ Assert.Single(frames);
|
|
|
+ Assert.Equal(jpeg, frames[0]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|