feat: 完成jpeg读取后端
This commit is contained in:
@@ -20,6 +20,11 @@ public class HdmiVideoStreamClient
|
||||
public required Jpeg JpegClient { get; set; }
|
||||
|
||||
public required CancellationTokenSource CTS { get; set; }
|
||||
|
||||
public required int Offset { get; set; }
|
||||
|
||||
public int Width { get; set; }
|
||||
public int Height { get; set; }
|
||||
}
|
||||
|
||||
public class HttpHdmiVideoStreamService : BackgroundService
|
||||
@@ -97,14 +102,14 @@ public class HttpHdmiVideoStreamService : BackgroundService
|
||||
var client = _clientDict[key];
|
||||
client.CTS.Cancel();
|
||||
|
||||
var disableResult = await client.HdmiInClient.EnableTrans(false);
|
||||
if (disableResult.IsSuccessful)
|
||||
var disableResult = await client.JpegClient.SetEnable(false);
|
||||
if (disableResult)
|
||||
{
|
||||
logger.Info("Successfully disabled HDMI transmission");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error($"Failed to disable HDMI transmission: {disableResult.Error}");
|
||||
logger.Error($"Failed to disable HDMI transmission");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -115,7 +120,12 @@ public class HttpHdmiVideoStreamService : BackgroundService
|
||||
|
||||
private async Task<HdmiVideoStreamClient?> GetOrCreateClientAsync(string boardId)
|
||||
{
|
||||
if (_clientDict.TryGetValue(boardId, out var client)) return client;
|
||||
if (_clientDict.TryGetValue(boardId, out var client))
|
||||
{
|
||||
client.Width = client.JpegClient.Width;
|
||||
client.Height = client.JpegClient.Height;
|
||||
return client;
|
||||
}
|
||||
|
||||
var userManager = new Database.UserManager();
|
||||
|
||||
@@ -132,19 +142,20 @@ public class HttpHdmiVideoStreamService : BackgroundService
|
||||
{
|
||||
HdmiInClient = new HdmiIn(board.IpAddr, board.Port, 1),
|
||||
JpegClient = new Jpeg(board.IpAddr, board.Port, 1),
|
||||
CTS = new CancellationTokenSource()
|
||||
CTS = new CancellationTokenSource(),
|
||||
Offset = 0
|
||||
};
|
||||
|
||||
// 启用HDMI传输
|
||||
try
|
||||
{
|
||||
var hdmiEnableRet = await client.HdmiInClient.EnableTrans(true);
|
||||
if (!hdmiEnableRet.IsSuccessful)
|
||||
{
|
||||
logger.Error($"Failed to enable HDMI transmission for board {boardId}: {hdmiEnableRet.Error}");
|
||||
return null;
|
||||
}
|
||||
logger.Info($"Successfully enabled HDMI transmission for board {boardId}");
|
||||
// var hdmiEnableRet = await client.JpegClient.EnableTrans(true);
|
||||
// if (!hdmiEnableRet.IsSuccessful)
|
||||
// {
|
||||
// logger.Error($"Failed to enable HDMI transmission for board {boardId}: {hdmiEnableRet.Error}");
|
||||
// return null;
|
||||
// }
|
||||
// logger.Info($"Successfully enabled HDMI transmission for board {boardId}");
|
||||
|
||||
var jpegEnableRet = await client.JpegClient.Init(true);
|
||||
if (!jpegEnableRet.IsSuccessful)
|
||||
@@ -153,6 +164,9 @@ public class HttpHdmiVideoStreamService : BackgroundService
|
||||
return null;
|
||||
}
|
||||
logger.Info($"Successfully enabled JPEG transmission for board {boardId}");
|
||||
|
||||
client.Width = client.JpegClient.Width;
|
||||
client.Height = client.JpegClient.Height;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -209,8 +223,8 @@ public class HttpHdmiVideoStreamService : BackgroundService
|
||||
logger.Debug("处理HDMI快照请求");
|
||||
|
||||
// 从HDMI读取RGB565数据
|
||||
var frameResult = await client.HdmiInClient.ReadFrame();
|
||||
if (!frameResult.IsSuccessful || frameResult.Value == null)
|
||||
var frameResult = await client.JpegClient.GetMultiFrames((uint)client.Offset);
|
||||
if (!frameResult.IsSuccessful || frameResult.Value == null || frameResult.Value.Count == 0)
|
||||
{
|
||||
logger.Error("HDMI快照获取失败");
|
||||
response.StatusCode = 500;
|
||||
@@ -220,17 +234,27 @@ public class HttpHdmiVideoStreamService : BackgroundService
|
||||
return;
|
||||
}
|
||||
|
||||
var jpegData = frameResult.Value;
|
||||
var jpegData = frameResult.Value[0];
|
||||
var jpegImage = Common.Image.CompleteJpegData(jpegData, client.Width, client.Height);
|
||||
if (!jpegImage.IsSuccessful)
|
||||
{
|
||||
logger.Error("JPEG数据补全失败");
|
||||
response.StatusCode = 500;
|
||||
var errorBytes = System.Text.Encoding.UTF8.GetBytes("Failed to complete JPEG data");
|
||||
await response.OutputStream.WriteAsync(errorBytes, 0, errorBytes.Length, cancellationToken);
|
||||
response.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置响应头(参考Camera版本)
|
||||
response.ContentType = "image/jpeg";
|
||||
response.ContentLength64 = jpegData.Length;
|
||||
response.ContentLength64 = jpegImage.Value.Length;
|
||||
response.Headers.Add("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
|
||||
await response.OutputStream.WriteAsync(jpegData, 0, jpegData.Length, cancellationToken);
|
||||
await response.OutputStream.WriteAsync(jpegImage.Value, 0, jpegImage.Value.Length, cancellationToken);
|
||||
await response.OutputStream.FlushAsync(cancellationToken);
|
||||
|
||||
logger.Debug("已发送HDMI快照图像,大小:{Size} 字节", jpegData.Length);
|
||||
logger.Debug("已发送HDMI快照图像,大小:{Size} 字节", jpegImage.Value.Length);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -260,13 +284,35 @@ public class HttpHdmiVideoStreamService : BackgroundService
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
var frameStartTime = DateTime.UtcNow;
|
||||
var frameStartTime = DateTime.UtcNow;
|
||||
|
||||
var ret = await client.HdmiInClient.GetMJpegFrame();
|
||||
if (ret == null) continue;
|
||||
var frame = ret.Value;
|
||||
var frameResult =
|
||||
await client.JpegClient.GetMultiFrames((uint)client.Offset);
|
||||
if (!frameResult.IsSuccessful || frameResult.Value == null || frameResult.Value.Count == 0)
|
||||
{
|
||||
logger.Error("获取HDMI帧失败");
|
||||
await Task.Delay(100, cancellationToken);
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var framebytes in frameResult.Value)
|
||||
{
|
||||
var jpegImage = Common.Image.CompleteJpegData(framebytes, client.Width, client.Height);
|
||||
if (!jpegImage.IsSuccessful)
|
||||
{
|
||||
logger.Error("JPEG数据不完整");
|
||||
await Task.Delay(100, cancellationToken);
|
||||
continue;
|
||||
}
|
||||
|
||||
var frameRet = Common.Image.CreateMjpegFrameFromJpeg(jpegImage.Value);
|
||||
if (!frameRet.IsSuccessful)
|
||||
{
|
||||
logger.Error("创建MJPEG帧失败");
|
||||
await Task.Delay(100, cancellationToken);
|
||||
continue;
|
||||
}
|
||||
var frame = frameRet.Value;
|
||||
|
||||
await response.OutputStream.WriteAsync(frame.header, 0, frame.header.Length, cancellationToken);
|
||||
await response.OutputStream.WriteAsync(frame.data, 0, frame.data.Length, cancellationToken);
|
||||
@@ -283,10 +329,7 @@ public class HttpHdmiVideoStreamService : BackgroundService
|
||||
logger.Debug("HDMI帧 {FrameNumber} 性能统计 - 总计: {TotalTime:F1}ms, JPEG大小: {JpegSize} 字节",
|
||||
frameCounter, totalTime, frame.data.Length);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "处理HDMI帧时发生错误");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user