我试图从(IcsOverbyte)服务器(TWSocketServer)到客户端(TWSocket)传输原始h264视频数据包,但是我在尝试正确组装消息时遇到了一些麻烦。
在进入我的问题之前,我只想说我已经确认了.h264数据是有效的,在我序列化我的消息之后,我将它反序列化,并将视频包数据部分保存到一个文件中,然后用VLC播放它,这个文件可以播放,没有任何问题。这样我也确认了我的Serialize/Deserialize例程是正确的(服务器和客户端都有相同的类型和ser/des例程源)。
我的留言是这样的-〉
TMessageHeader = packed record
MessageID: UInt32;
TotalSize: UInt32; {Meaning HeaderSize + Payload}
end;
TMediaDataMessage = record
Header: TMessageHeader;
Channel: UInt32;
Stream: UInt32;
MediaType: Byte; {0 - Video, 1 - Audio}
Data: TArray<Byte>;
function FromBytes(pBytes: TArray<Byte>): Boolean;
function ToBytes: TArray<Byte>;
function GetSize: UInt32;
end;
在客户端,我有一个如下所示的消息组装例程...
procedure TfrmMain.HandleDataAvailable(pSender: TObject; ErrCode: Word);
var
vRcvdCount: Integer;
vBytes: TBytes;
vMessageTotalSize: UInt32;
vOffset: UInt32;
begin
{$POINTERMATH ON}
if ErrCode <> 0 then
Exit;
if pSender = nil then
Exit;
SetLength(vBytes, 65536);
vRcvdCount := fTCPClient.Receive(@vBytes[0], 65536);
vOffset := 0;
try
if fRemainingDataSize > 0 then
begin
if vRcvdCount >= fRemainingDataSize then
begin
fCurrentBuf.Write(vBytes[vOffset], fRemainingDataSize);
Inc(vOffset, fRemainingDataSize);
Dec(vRcvdCount, fRemainingDataSize);
fRemainingDataSize := 0;
SetHandleMessage(fIdx.ToString + 'Sync');
end
else
begin
fCurrentBuf.Write(vBytes[vOffset], vRcvdCount);
Dec(fRemainingDataSize, vRcvdCount);
end;
end;
except
reLog.Lines.Add('Error sync');
end;
try
while (vRcvdCount > 0) do
begin
vMessageTotalSize := PUInt32(@vBytes[vOffset + 4])^;
if vRcvdCount >= vMessageTotalSize then
begin
fCurrentBuf.Write(vBytes[vOffset], vMessageTotalSize);
Inc(vOffset, vMessageTotalSize);
Dec(vRcvdCount, vMessageTotalSize);
SetHandleMessage('Loop');
end
else
begin
fCurrentBuf.Write(vBytes[vOffset], vRcvdCount);
fRemainingDataSize := vMessageTotalSize - vRcvdCount;
vRcvdCount := 0;
end;
end;
except
reLog.Lines.Add('Loop');
end;
//fTcpClient.Flush;
end;
仅供参考,从未发生过例外情况。
这就是SetHandleMessage过程
procedure TfrmMain.SetHandleMessage(pSort: string);
var
vMsgBytes: TArray<Byte>;
vMessageID: UInt32;
begin
fCurrentBuf.Position := 0;
SetLength(vMsgBytes, fCurrentBuf.Size);
fCurrentBuf.Read(vMsgBytes[0], fCurrentBuf.Size);
fCurrentBuf.Clear;
vMessageID := PUInt32(@vMsgBytes[0])^;
HandleMessage(vMessageID, vMsgBytes, pSort);
end;
我一直在追自己的尾巴有一段时间了,现在我似乎不能确定是什么问题。
我也尝试过将原始的.h264流传输到客户端并将其保存到文件,效果也很好...
看起来唯一可能出错的是消息组装例程。
编辑:.决定添加序列化函数。
一个一个三个一个一个一个一个一个四个一个一个一个一个一个五个一个
1条答案
按热度按时间bogh5gae1#
我想通了...我必须在第一个else语句中将vRcvdCount设置为0。
现在看起来像这样-〉