亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? rtpsink.cpp

?? rtsp協議的主要實現代碼.對開發流媒體
?? CPP
字號:
// RTPSink.cpp: implementation of the RTPSink class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "RTPSink.h"

#pragma comment(lib,"winmm.lib")

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
static unsigned const rtpHeaderSize = 12;
typedef void TaskFunc(void* clientData);

RTPSink::RTPSink(unsigned char rtpPayloadType,unsigned rtpTimestampFrequency,
				 unsigned numChannels):
	fRTPPayloadType(rtpPayloadType),fTimestampFrequency(rtpTimestampFrequency),
	fCurFragmentationOffset(0),fHaveComputedFirstTimestamp(False)
{
	fSeqNo = (unsigned short)CUtility::our_random();
	fSSRC = CUtility::our_random32();
	fTimestampBase = CUtility::our_random32();
	fCurrentTimestamp = fTimestampBase;	
	fRTPInterface = RTPInterface::createNew();
	fNumFramesUsedSoFar = 0;
	setPacketSizes(1000, 1448);
}

RTPSink::~RTPSink()
{
	timeKillEvent(m_timeID);
	delete fRTPInterface;
	delete fOutBuf;
}

void RTPSink::setPacketSizes(unsigned preferredPacketSize,
										unsigned maxPacketSize) {
	if (preferredPacketSize > maxPacketSize || preferredPacketSize == 0) return;
	// sanity check
	
	fOutBuf = new OutPacketBuffer(preferredPacketSize, maxPacketSize);
}

Boolean RTPSink::startPlaying(FramedSource* fMediaSource)
{
	// Make sure we're not already being played:
	//if (fSource != NULL) {
	// 	CUtility::setResultMsg("This sink is already being played");
	//	return FALSE;
	//}
	// Make sure our source is compatible:
	fSource = (FramedSource*)fMediaSource;

	return continuePlaying();
}

Boolean RTPSink::continuePlaying() {
	// Send the first packet.
	// (This will also schedule any future sends.)
	buildAndSendPacket(True);
	return True;
}

void RTPSink::buildAndSendPacket(Boolean isFirstPacket)
{
	fIsFirstPacket = isFirstPacket;

	// Set up the RTP header:
	unsigned rtpHdr = 0x80000000; // RTP version 2
	rtpHdr |= (fRTPPayloadType<<16);
	rtpHdr |= fSeqNo; // sequence number
	fOutBuf->enqueueWord(rtpHdr);
	
	// Note where the RTP timestamp will go.
	// (We can't fill this in until we start packing payload frames.)
	fTimestampPosition = fOutBuf->curPacketSize();
	fOutBuf->skipBytes(4); // leave a hole for the timestamp
	
	fOutBuf->enqueueWord(fSSRC);
	
	// Allow for a special, payload-format-specific header following the
	// RTP header:
	fSpecialHeaderPosition = fOutBuf->curPacketSize();
	fSpecialHeaderSize = frameSpecificHeaderSize();
	fOutBuf->skipBytes(fSpecialHeaderSize);
	
	// Begin packing as many (complete) frames into the packet as we can:
	fTotalFrameSpecificHeaderSizes = 0;
	fNoFramesLeft = False;
	fNumFramesUsedSoFar = 0;
	packFrame();
}

void RTPSink::packFrame()
{
	if (fSource == NULL) return;
	
    fCurFrameSpecificHeaderPosition = fOutBuf->curPacketSize();
    fCurFrameSpecificHeaderSize = frameSpecificHeaderSize();
    fOutBuf->skipBytes(fCurFrameSpecificHeaderSize);
    fTotalFrameSpecificHeaderSizes += fCurFrameSpecificHeaderSize;
	
    fSource->getNextFrame(fOutBuf->curPtr(), fOutBuf->totalBytesAvailable(),afterGettingFrame, this);	
	//padding timestamp
	//sendto
}

void RTPSink
::afterGettingFrame(void* clientData, unsigned numBytesRead,
					unsigned numTruncatedBytes,
					struct timeval presentationTime,
					unsigned durationInMicroseconds) {
	RTPSink* sink = (RTPSink*)clientData;
	sink->afterGettingFrame1(numBytesRead, numTruncatedBytes,
		presentationTime, durationInMicroseconds);
}

void RTPSink
::doSpecialFrameHandling(unsigned /*fragmentationOffset*/,
						 unsigned char* /*frameStart*/,
						 unsigned /*numBytesInFrame*/,
						 struct timeval frameTimestamp,
						 unsigned /*numRemainingBytes*/) {
	// default implementation: If this is the first frame in the packet,
	// use its timestamp for the RTP timestamp:
	if (isFirstFrameInPacket()) {
		setTimestamp(frameTimestamp);
	}
}

void RTPSink::setTimestamp(struct timeval timestamp) {
	// First, convert the timestamp to a 32-bit RTP timestamp:
	fCurrentTimestamp = convertToRTPTimestamp(timestamp);
	
	// Then, insert it into the RTP packet:
	fOutBuf->insertWord(fCurrentTimestamp, fTimestampPosition);
}

u_int32_t RTPSink::convertToRTPTimestamp(struct timeval tv) {
	u_int32_t rtpTimestampIncrement = timevalToTimestamp(tv);
	
	if (!fHaveComputedFirstTimestamp) {
		// Make the first timestamp the same as the current "fTimestampBase", so that
		// timestamps begin with the value we promised when this "RTPSink" was created:
		fTimestampBase -= rtpTimestampIncrement;
		fHaveComputedFirstTimestamp = True;
	}
	
	u_int32_t const rtpTimestamp = fTimestampBase + rtpTimestampIncrement;
#ifdef DEBUG_TIMESTAMPS
	fprintf(stderr, "fTimestampBase: 0x%08x, tv: %lu.%06ld\n\t=> RTP timestamp: 0x%08x\n",
		fTimestampBase, tv.tv_sec, tv.tv_usec, rtpTimestamp);
	fflush(stderr);
#endif
	
	return rtpTimestamp;
}

u_int32_t RTPSink::timevalToTimestamp(struct timeval tv) const {
	u_int32_t timestamp = (fTimestampFrequency*tv.tv_sec);
	timestamp += (u_int32_t)((2.0*fTimestampFrequency*tv.tv_usec + 1000000.0)/2000000);
	// note: rounding
	return timestamp;
}


void RTPSink
::afterGettingFrame1(unsigned frameSize, unsigned numTruncatedBytes,
					 struct timeval presentationTime,
					 unsigned durationInMicroseconds) 
{
	if (fIsFirstPacket) {
		// Record the fact that we're starting to play now:
		gettimeofday(&fNextSendTime, NULL);
	}

	unsigned curFragmentationOffset = fCurFragmentationOffset;
	unsigned numFrameBytesToUse = frameSize;
	unsigned overflowBytes = 0;

    // Use this frame in our outgoing packet:
	
    // Here's where any payload format specific processing gets done:
    doSpecialFrameHandling(curFragmentationOffset, fOutBuf->curPtr(),
		numFrameBytesToUse, presentationTime,
		overflowBytes);
	
    fOutBuf->increment(numFrameBytesToUse);
    ++fNumFramesUsedSoFar;
	
	
    // Send our packet now if (i) it's already at our preferred size, or
    // (ii) (heuristic) another frame of the same size as the one we just
    //      read would overflow the packet, or
    // (iii) it contains the last fragment of a fragmented frame, and we
    //      don't allow anything else to follow this or
    // (iv) one frame per packet is allowed:
    if (TRUE) 
	{
		// The packet is ready to be sent now
		sendPacketIfNecessary();
	}
}

// The following is called after each delay between packet sends:
void CALLBACK sendNext(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
	RTPSink* sink = (RTPSink*)dwUser;
	sink->buildAndSendPacket(False);
}

void RTPSink::sendPacketIfNecessary() {
	if (fNumFramesUsedSoFar > 0) {
		// Send the packet:
#ifdef TEST_LOSS
		//if ((our_random()%10) != 0) // simulate 10% packet loss #####
#endif
		fRTPInterface->sendPacket(fOutBuf->packet(), fOutBuf->curPacketSize());
		++fPacketCount;
		fTotalOctetCount += fOutBuf->curPacketSize();
		fOctetCount += fOutBuf->curPacketSize()
			- rtpHeaderSize - fSpecialHeaderSize - fTotalFrameSpecificHeaderSizes;
		
		++fSeqNo; // for next time
	}

	// Normal case: Reset the packet start pointer back to the start:
    fOutBuf->resetPacketStart();
	
	fOutBuf->resetOffset();

	//do loop send next frame
	m_timeID = timeSetEvent(1,0,sendNext,(DWORD)this,TIME_ONESHOT);
}

unsigned RTPSink::frameSpecificHeaderSize() const {
	// default implementation: Assume no frame-specific header:
	return 0;
}

////////// OutPacketBuffer //////////

unsigned OutPacketBuffer::maxSize = 60000; // by default

OutPacketBuffer::OutPacketBuffer(unsigned preferredPacketSize,
				 unsigned maxPacketSize)
  : fPreferred(preferredPacketSize), fMax(maxPacketSize),
    fOverflowDataSize(0) {
  unsigned maxNumPackets = (maxSize + (maxPacketSize-1))/maxPacketSize;
  fLimit = maxNumPackets*maxPacketSize;
  fBuf = new unsigned char[fLimit];
  resetPacketStart();
  resetOffset();
  resetOverflowData();
}

OutPacketBuffer::~OutPacketBuffer() {
  delete[] fBuf;
}

void OutPacketBuffer::enqueue(unsigned char const* from, unsigned numBytes) {
  if (numBytes > totalBytesAvailable()) {
#ifdef DEBUG
    fprintf(stderr, "OutPacketBuffer::enqueue() warning: %d > %d\n", numBytes, totalBytesAvailable());
#endif
    numBytes = totalBytesAvailable();
  }

  if (curPtr() != from) memmove(curPtr(), from, numBytes);
  increment(numBytes);
}

void OutPacketBuffer::enqueueWord(unsigned word) {
  unsigned nWord = htonl(word);
  enqueue((unsigned char*)&nWord, 4);
}

void OutPacketBuffer::insert(unsigned char const* from, unsigned numBytes,
			     unsigned toPosition) {
  unsigned realToPosition = fPacketStart + toPosition;
  if (realToPosition + numBytes > fLimit) {
    if (realToPosition > fLimit) return; // we can't do this
    numBytes = fLimit - realToPosition;
  }

  memmove(&fBuf[realToPosition], from, numBytes);
  if (toPosition + numBytes > fCurOffset) {
    fCurOffset = toPosition + numBytes;
  }
}

void OutPacketBuffer::insertWord(unsigned word, unsigned toPosition) {
  unsigned nWord = htonl(word);
  insert((unsigned char*)&nWord, 4, toPosition);
}

void OutPacketBuffer::extract(unsigned char* to, unsigned numBytes,
			      unsigned fromPosition) {
  unsigned realFromPosition = fPacketStart + fromPosition;
  if (realFromPosition + numBytes > fLimit) { // sanity check
    if (realFromPosition > fLimit) return; // we can't do this
    numBytes = fLimit - realFromPosition;
  }

  memmove(to, &fBuf[realFromPosition], numBytes);
}

unsigned OutPacketBuffer::extractWord(unsigned fromPosition) {
  unsigned nWord;
  extract((unsigned char*)&nWord, 4, fromPosition);
  return ntohl(nWord);
}

void OutPacketBuffer::skipBytes(unsigned numBytes) {
  if (numBytes > totalBytesAvailable()) {
    numBytes = totalBytesAvailable();
  }

  increment(numBytes);
}

void OutPacketBuffer
::setOverflowData(unsigned overflowDataOffset,
		  unsigned overflowDataSize,
		  struct timeval const& presentationTime,
		  unsigned durationInMicroseconds) {
  fOverflowDataOffset = overflowDataOffset;
  fOverflowDataSize = overflowDataSize;
  fOverflowPresentationTime = presentationTime;
  fOverflowDurationInMicroseconds = durationInMicroseconds;
}

void OutPacketBuffer::useOverflowData() {
  enqueue(&fBuf[fPacketStart + fOverflowDataOffset], fOverflowDataSize);
  fCurOffset -= fOverflowDataSize; // undoes increment performed by "enqueue"
  resetOverflowData();
}

void OutPacketBuffer::adjustPacketStart(unsigned numBytes) { 
  fPacketStart += numBytes;
  if (fOverflowDataOffset >= numBytes) {
    fOverflowDataOffset -= numBytes;
  } else {
    fOverflowDataOffset = 0;
    fOverflowDataSize = 0; // an error otherwise
  }
}

void OutPacketBuffer::resetPacketStart() {
  if (fOverflowDataSize > 0) {
    fOverflowDataOffset += fPacketStart;
  }
  fPacketStart = 0;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
91亚洲精品乱码久久久久久蜜桃| 麻豆精品一区二区综合av| 26uuu精品一区二区三区四区在线| 欧美日韩综合色| 欧美在线三级电影| 欧美高清你懂得| 欧美一区二区三区小说| 欧美精品一区二区在线观看| 精品欧美一区二区在线观看| 亚洲精品在线网站| 中文字幕制服丝袜一区二区三区| 亚洲视频你懂的| 亚洲mv大片欧洲mv大片精品| 日本va欧美va精品发布| 亚洲精品高清视频在线观看| 亚洲品质自拍视频| 亚洲一区二区不卡免费| 日本亚洲天堂网| 狠狠v欧美v日韩v亚洲ⅴ| 不卡的av电影在线观看| 在线精品视频免费播放| 精品蜜桃在线看| 欧美自拍偷拍午夜视频| 在线观看国产91| 精品日韩在线一区| 亚洲精选免费视频| 蜜臀av一区二区| 91蜜桃在线观看| 欧美tickling挠脚心丨vk| 国产精品国产馆在线真实露脸| 亚洲午夜精品在线| 国产精品一区久久久久| 欧美自拍丝袜亚洲| 久久这里只有精品首页| 亚洲国产精品一区二区久久 | 成人小视频免费观看| 欧美影视一区在线| 久久免费国产精品| 午夜久久久久久久久| 国产精品一区一区| 欧美精品一二三区| 一区二区三区四区蜜桃| 高清在线成人网| 日韩欧美黄色影院| 午夜在线电影亚洲一区| 99r国产精品| 中文天堂在线一区| 久久不见久久见中文字幕免费| 色婷婷综合久色| 中文字幕二三区不卡| 激情五月婷婷综合网| 欧美高清视频www夜色资源网| 亚洲免费伊人电影| 成人av在线播放网站| 日韩精品一区在线| 天天综合天天做天天综合| 色中色一区二区| 中文字幕日韩一区| av电影在线观看一区| 中文字幕va一区二区三区| 国产成人一区在线| 久久美女艺术照精彩视频福利播放 | yourporn久久国产精品| 久久人人超碰精品| 国产乱码精品一区二区三| 欧美大黄免费观看| 美国十次综合导航| 精品国产sm最大网站免费看| 另类小说一区二区三区| 精品理论电影在线| 精品影院一区二区久久久| 欧美精品一区二区三| 捆绑调教一区二区三区| 精品第一国产综合精品aⅴ| 美女脱光内衣内裤视频久久网站 | 日韩精品电影在线观看| 91精品在线免费观看| 五月天激情小说综合| 欧美高清视频在线高清观看mv色露露十八 | 欧美自拍偷拍一区| 亚洲1区2区3区视频| 91精品国产aⅴ一区二区| 另类综合日韩欧美亚洲| 久久蜜桃av一区精品变态类天堂| 国产99久久久精品| 亚洲欧美视频在线观看视频| 欧美性猛片xxxx免费看久爱| 日韩av二区在线播放| 欧美mv日韩mv国产| 成人污视频在线观看| 亚洲靠逼com| 91精品国产综合久久小美女| 极品尤物av久久免费看| 中日韩免费视频中文字幕| 色婷婷综合久久久| 久久99精品久久久久久国产越南| 国产欧美日韩久久| 91黄色在线观看| 国内一区二区视频| 亚洲视频在线一区| 日韩一区二区视频| 成人免费黄色在线| 一级中文字幕一区二区| 精品国产一区二区精华| 91啪亚洲精品| 国产一区激情在线| 一区二区三区中文免费| 久久综合网色—综合色88| 在线观看欧美黄色| 国产高清久久久久| 亚洲大尺度视频在线观看| 久久一夜天堂av一区二区三区| 色伊人久久综合中文字幕| 国内久久婷婷综合| 亚洲不卡在线观看| 国产精品国产成人国产三级| 日韩精品一区二区三区中文精品| 91一区二区三区在线观看| 国内精品视频一区二区三区八戒| 樱花草国产18久久久久| 久久久久久一级片| 8x8x8国产精品| 欧美色偷偷大香| 91亚洲国产成人精品一区二区三 | 国产精品少妇自拍| 在线播放亚洲一区| 色8久久人人97超碰香蕉987| 丁香激情综合国产| 国产精品一级片| 美美哒免费高清在线观看视频一区二区 | 国产成人av电影免费在线观看| 日韩主播视频在线| 亚洲一区二区三区在线看| 国产精品视频一二三| 精品国产免费久久| 欧美成人r级一区二区三区| 欧美日韩不卡在线| 在线一区二区观看| 91美女精品福利| 成人禁用看黄a在线| 成人午夜av在线| 国产**成人网毛片九色| 精品一区二区免费看| 六月丁香婷婷色狠狠久久| 免费高清不卡av| 人妖欧美一区二区| 美腿丝袜亚洲综合| 美腿丝袜亚洲一区| 韩国女主播一区| 国产精品羞羞答答xxdd| 国产精品亚洲人在线观看| 国产一区久久久| 国产成人午夜99999| 国产成人精品免费一区二区| 岛国一区二区在线观看| 99久久精品久久久久久清纯| av电影在线不卡| 欧美性生活大片视频| 欧美日韩一级视频| 日韩视频免费观看高清完整版在线观看| 3d动漫精品啪啪一区二区竹菊| 欧美美女bb生活片| 精品国内片67194| 国产精品乱人伦| 亚洲国产一区二区在线播放| 蜜桃91丨九色丨蝌蚪91桃色| 国产麻豆精品久久一二三| 国产不卡视频一区| 在线影视一区二区三区| 欧美一区2区视频在线观看| 久久夜色精品国产欧美乱极品| 国产欧美日韩精品在线| 亚洲一区在线观看视频| 狂野欧美性猛交blacked| yourporn久久国产精品| 欧美日韩国产高清一区二区 | 99久久国产综合精品麻豆| 欧美三区免费完整视频在线观看| 欧美一区二区精品| 国产精品乱码久久久久久| 亚洲成人久久影院| 成人一区二区在线观看| 欧美日韩国产小视频在线观看| 精品国产伦一区二区三区免费| 综合婷婷亚洲小说| 精品一区二区久久| 欧美性猛交xxxx黑人交| 精品毛片乱码1区2区3区| 亚洲视频每日更新| 久久99精品久久久久久久久久久久 | 久久99精品久久久久久动态图| 91视频一区二区三区| 久久亚洲影视婷婷| 午夜视频在线观看一区二区| 成人一道本在线| 精品国产乱码久久久久久免费| 亚洲一区二区黄色| 91亚洲精华国产精华精华液| 26uuu另类欧美| 日本不卡视频一二三区|