|
@@ -0,0 +1,52 @@
|
|
|
|
|
+using System.IO;
|
|
|
|
|
+using System.Windows.Media.Imaging;
|
|
|
|
|
+using IvfTl.ControlHost.Debug;
|
|
|
|
|
+using Xunit;
|
|
|
|
|
+
|
|
|
|
|
+namespace IvfTl.ControlHost.Tests
|
|
|
|
|
+{
|
|
|
|
|
+ public class MjpegStreamWriterTests
|
|
|
|
|
+ {
|
|
|
|
|
+ // 造一张 4x4 纯色 24bpp BGR 像素(每像素 3 字节)。
|
|
|
|
|
+ private static byte[] SolidBgr(int w, int h, byte b, byte g, byte r)
|
|
|
|
|
+ {
|
|
|
|
|
+ var buf = new byte[w * h * 3];
|
|
|
|
|
+ for (int i = 0; i < w * h; i++) { buf[i * 3] = b; buf[i * 3 + 1] = g; buf[i * 3 + 2] = r; }
|
|
|
|
|
+ return buf;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ [Fact]
|
|
|
|
|
+ public void EncodeJpeg_ProducesDecodableJpeg_WithRightSize()
|
|
|
|
|
+ {
|
|
|
|
|
+ var rgb = SolidBgr(4, 4, 10, 20, 30);
|
|
|
|
|
+ byte[] jpeg = MjpegStreamWriter.EncodeJpeg(rgb, 4, 4);
|
|
|
|
|
+
|
|
|
|
|
+ Assert.NotNull(jpeg);
|
|
|
|
|
+ Assert.True(jpeg.Length > 2);
|
|
|
|
|
+ // JPEG 魔数 FF D8 开头
|
|
|
|
|
+ Assert.Equal(0xFF, jpeg[0]);
|
|
|
|
|
+ Assert.Equal(0xD8, jpeg[1]);
|
|
|
|
|
+ // 能被解码器读回、尺寸对
|
|
|
|
|
+ var dec = new JpegBitmapDecoder(new MemoryStream(jpeg),
|
|
|
|
|
+ BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
|
|
|
|
|
+ Assert.Equal(4, dec.Frames[0].PixelWidth);
|
|
|
|
|
+ Assert.Equal(4, dec.Frames[0].PixelHeight);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ [Fact]
|
|
|
|
|
+ public void FrameBytes_WrapsJpegInMultipartBoundary()
|
|
|
|
|
+ {
|
|
|
|
|
+ var jpeg = new byte[] { 0xFF, 0xD8, 1, 2, 0xFF, 0xD9 };
|
|
|
|
|
+ byte[] frame = MjpegStreamWriter.FrameBytes(jpeg);
|
|
|
|
|
+
|
|
|
|
|
+ string head = System.Text.Encoding.ASCII.GetString(frame, 0, 60);
|
|
|
|
|
+ Assert.Contains("--frame", head);
|
|
|
|
|
+ Assert.Contains("Content-Type: image/jpeg", head);
|
|
|
|
|
+ Assert.Contains("Content-Length: 6", head);
|
|
|
|
|
+ // 帧尾部含 jpeg 原始字节 + 末尾 \r\n
|
|
|
|
|
+ Assert.Equal(0xFF, frame[frame.Length - 8]); // jpeg 起点附近(粗校验帧体存在)
|
|
|
|
|
+ Assert.Equal((byte)'\r', frame[frame.Length - 2]);
|
|
|
|
|
+ Assert.Equal((byte)'\n', frame[frame.Length - 1]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|