資源簡介
一個小工具,將TS流文件發送到以太網絡上。
支持使用UDP或者RTP協議。
根據TS流的PCR值跟蹤時間同步發送。
我用的GetTickCount進行發送時間同步,線程按照10毫秒進行輪回,按照Win32系統普通線程切換時間,應該可以保證到10毫秒左右的同步精度。
但聽人提過使用GetTickCount進行時間同步,長時間會有時間漂移現象,而且誤差會逐漸累加,直到客戶端緩沖溢出。對方提出的解決方案是使用GPS衛星時間同步...
個人以為GetTickCount是使用Win32底層的某個高精度時間結果。在微觀上不是很精確,但是宏觀上應該是很精確。
我實際曾經使用這個工具,發送過同一個文件三天三夜,客戶端使用VideoLan進行在線播放,緩沖設置300ms,沒有發現VideoLan緩沖有溢出的情況。
如果這種同步方式,長時間發送,確實有精度問題,希望有同志給出例證和解決方案(除了使用GPS衛星時間以外的方案...)。以便我改進。
demo中根據以太網通常的MTU值直接按7個TS包進行封裝:
SetGetTsPacketDataCB(GetTsPacketData, NULL, TS_PACKET_SIZE_MIN*7);
如果是其他網絡類型,需要根據網絡的MTU值調整TS包數量。

代碼片段和文件信息
#include?“stdafx.h“
#include?“Rtp.h“
static?const?UINT16?RTP_HEADER_SIZE?=?12;
static?const?UINT16?RTP_H263_HEADER_SIZE?=?2;
Rtp::Rtp(UINT?mtu)?:Udp(mtu)
{
m_SequenceNumber?=?0;
}
Rtp::~Rtp()
{
}
int?Rtp::Read(BYTE*?pBuffer?UINT16?bufferSize?INT8*?pPayloadType?UINT16*?pSequenceNumber?INT32*?pTimeStamp?INT32*?pSsrc?UINT?nTimeOut)
{
int?iRead;
UINT8?payloadType;
UINT16?sequenceNumber;
INT32?timeStamp;
INT32?ssrc;
m_RtpPacket.ExtendBuffer(bufferSize+RTP_HEADER_SIZE);
m_RtpPacket.ClearData();
iRead?=?Udp::Read(m_RtpPacket.m_pBuffer?m_RtpPacket.m_nBufferSize?nTimeOut);
if?(iRead?12)
return?-1;
if?(!ParseRtpHeader(m_RtpPacket.m_pBuffer?&payloadType?&sequenceNumber?&timeStamp?&ssrc))
return?-1;
m_RtpPacket.m_nDataSize?=?iRead;
memcpy(pBuffer?m_RtpPacket.m_pBuffer?+?RTP_HEADER_SIZE?iRead?-?RTP_HEADER_SIZE);
if?(pPayloadType)
*pPayloadType?=?payloadType;
if?(pSequenceNumber)
*pSequenceNumber?=?sequenceNumber;
if?(pTimeStamp)
*pTimeStamp?=?timeStamp;
if?(pSsrc)
*pSsrc?=?ssrc;
return?iRead?-?RTP_HEADER_SIZE;
}
int?Rtp::Write(PBYTE?pBuffer?UINT16?bufferSize?INT8?payloadType?INT32?timeStamp?INT32?ssrc?BOOL?marker?UINT?nTimeOut)
{
int?iWrite;
CreateRtpPacket(pBuffer?bufferSize?payloadType?timeStamp?ssrc?marker);
iWrite?=?Udp::Write(m_RtpPacket.m_pBuffer?m_RtpPacket.m_nDataSize?nTimeOut);
if?(iWrite? return?-1;
return?iWrite?-?RTP_HEADER_SIZE;
}
void?Rtp::CreateRtpPacket(PBYTE?pData?UINT16?dataSize?UINT8?nPayloadType?INT32?timeStamp?INT32?nSSRC?BOOL?marker)
{
m_RtpPacket.ExtendBuffer(RTP_HEADER_SIZE?+?dataSize);
m_RtpPacket.ClearData();
m_RtpPacket.m_pBuffer[0]?=?0x80;
m_RtpPacket.m_pBuffer[1]?=?(marker?0x80:0x00)|nPayloadType;
m_RtpPacket.m_pBuffer[2]?=?(?m_SequenceNumber?>>?8?)&0xff;
m_RtpPacket.m_pBuffer[3]?=?m_SequenceNumber&0xff;
m_RtpPacket.m_pBuffer[4]?=?(BYTE)(?timeStamp?>>?24?)&0xff;
m_RtpPacket.m_pBuffer[5]?=?(BYTE)(?timeStamp?>>?16?)&0xff;
m_RtpPacket.m_pBuffer[6]?=?(BYTE)(?timeStamp?>>??8?)&0xff;
m_RtpPacket.m_pBuffer[7]?=?(BYTE)timeStamp&0xff;
m_RtpPacket.m_pBuffer[?8]?=?(?nSSRC?>>?24?)&0xff;
m_RtpPacket.m_pBuffer[?9]?=?(?nSSRC?>>?16?)&0xff;
m_RtpPacket.m_pBuffer[10]?=?(?nSSRC?>>??8?)&0xff;
m_RtpPacket.m_pBuffer[11]?=?nSSRC&0xff;
m_SequenceNumber++;
m_RtpPacket.m_nDataSize?=?RTP_HEADER_SIZE;
m_RtpPacket.AppendData(pData?dataSize);
}
BOOL?Rtp::ParseRtpHeader(PBYTE?pRtpHeader?UINT8*?pPayloadType?UINT16*?pSequenceNumber?INT32*?pTimeStamp?INT32*?pSsrc)
{
if?(pRtpHeader[0]?!=?0x80)
return?FALSE;
*pPayloadType =?pRtpHeader[1];?
*pSequenceNumber?=?((WORD)pRtpHeader[2])?<8?|?pRtpHeader[3];
*pTimeStamp?=?(INT32)pRtpHeader[4]?<24?|?(INT32)pRtpHeader[5]?<16?|?(INT32)pRtpHeader[6]?<8?|?pRtpHeader[7];
*pSsrc?=?(INT32)pRtpHeader[8]?<24?|?(INT32)pRtpHeader[9]?<16?|?(INT32)pRtpHeader[10]?<8?|?pRtpHeader[11];
?屬性????????????大小?????日期????時間???名稱
-----------?---------??----------?-----??----
?????文件???????1226??2009-08-25?15:15??SendTs2Ip\ReadMe.txt
?????文件???????3017??2009-03-24?14:53??SendTs2Ip\Rtp.cpp
?????文件????????780??2009-03-24?14:55??SendTs2Ip\Rtp.h
?????文件???????3376??2009-09-30?17:04??SendTs2Ip\SendTs2Ip.cpp
?????文件???????4702??2009-08-25?15:19??SendTs2Ip\SendTs2Ip.dsp
?????文件????????541??2009-08-25?15:15??SendTs2Ip\SendTs2Ip.dsw
?????文件????????883??2009-08-25?15:56??SendTs2Ip\SendTs2Ip.sln
?????文件???????6983??2009-08-25?18:24??SendTs2Ip\SendTs2Ip.vcproj
?????文件???????1427??2009-10-21?13:37??SendTs2Ip\SendTs2Ip.vcproj.SB-4198B7C3284E.cc.user
?????文件???????3867??2009-04-02?14:31??SendTs2Ip\Socket.cpp
?????文件???????1093??2009-04-02?14:32??SendTs2Ip\Socket.h
?????文件???????6587??2009-08-25?17:51??SendTs2Ip\SourceTsFile.cpp
?????文件???????1418??2009-08-25?15:57??SendTs2Ip\SourceTsFile.h
?????文件????????296??2009-08-25?15:15??SendTs2Ip\StdAfx.cpp
?????文件????????936??2009-08-25?16:42??SendTs2Ip\StdAfx.h
?????文件???????2412??2009-08-07?10:11??SendTs2Ip\string_t.h
?????文件????????738??2009-01-19?17:35??SendTs2Ip\TLock.h
?????文件???????4148??2008-07-29?17:48??SendTs2Ip\Udp.cpp
?????文件????????531??2009-04-02?12:03??SendTs2Ip\Udp.h
?????文件???????8526??2009-08-25?11:46??SendTs2Ip\VBuffer.h
?????文件???????2249??2008-05-26?12:20??SendTs2Ip\VBufferT.h
?????目錄??????????0??2009-11-27?14:57??SendTs2Ip
-----------?---------??----------?-----??----
????????????????55736????????????????????22
- 上一篇:基于CSerialPort修改類的串口調試助手源代碼
- 下一篇:廣工數據庫課設報告
評論
共有 條評論