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

代碼片段和文件信息
#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];
?屬性????????????大小?????日期????時(shí)間???名稱
-----------?---------??----------?-----??----
?????文件???????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
評(píng)論
共有 條評(píng)論