当前位置:首页 > darwin分析
?
if (isMulticastDest) { fSockets = sSocketPool.GetUDPSocketPair(INADDR_ANY, fStreamInfo.fPort, fStreamInfo.fSrcIPAddr, 0); } else { fSockets = sSocketPool.GetUDPSocketPair(fStreamInfo.fDestIPAddr, fStreamInfo.fPort, fStreamInfo.fSrcIPAddr, 0); } ... ...
// also put this stream onto the socket's queue of streams
((ReflectorSocket*)fSockets->GetSocketA())->AddSender(&fRTPSender); ((ReflectorSocket*)fSockets->GetSocketB())->AddSender(&fRTCPSender); // A broadcaster is setting up a UDP session so let the sockets update the session
if (fStreamInfo.fSetupToReceive &&qtssRTPTransportTypeUDP==transportType&&inParams!=NULL) { ((ReflectorSocket*)fSockets->GetSocketA())->AddBroadcasterSession(inParams->inClientSession); ((ReflectorSocket*)fSockets->GetSocketB())->AddBroadcasterSession(inParams->inClientSession); }
((ReflectorSocket*)fSockets->GetSocketA())->SetSSRCFilter(filterState, timeout); ((ReflectorSocket*)fSockets->GetSocketB())->SetSSRCFilter(filterState, timeout); // Always set the Rcv buf size for the sockets. This is important because the these // sockets is only useful for RTCP Rrs. // 512K
fSockets->GetSocketA()->SetSocketRcvBufSize(512 * 1024); fSockets->GetSocketB()->SetSocketRcvBufSize(512 * 1024); if (isMulticastDest) { ... ... } // 针对sdp的多播的目的地址 fStreamInfo.fPort = fSockets->GetSocketA()->GetLocalPort(); // 申请监听
fSockets->GetSocketA()->RequestEvent(EV_RE); fSockets->GetSocketB()->RequestEvent(EV_RE); // Copy the source ID and setup the ref
StrPtrLen theSourceID(fSourceIDBuf, kStreamIDSize);
ReflectorStream::GenerateSourceID(&fStreamInfo, fSourceIDBuf); fRef.Set(theSourceID, this);
(3)、AddOutput
// 寻找第一个fOutputArray[num][x] == NULL,将putInThisBucket设为num if (putInThisBucket < 0) putInThisBucket = this->FindBucket(); if (fNumBuckets <= (Uint32)putInThisBucket) this->AllocateBucketArray(putInThisBucket * 2); // 保存inOutput
for(UInt32 y=0; y ReflectorSession This object supports reflecting an RTP multicast stream to N RTPStreams. It spaces out the packet send times in order to maximize the randomness of the sending pattern and smooth the stream. (1)、SetupReflectorSession fLocalSDP.Delete(); fLocalSDP.Ptr = inInfo->GetLocalSDP(&fLocalSDP.Len); // Allocate all our ReflectorStreams, using the SourceInfo delete fStreamArray; // 音视频分为两个流,对于每个流,创建ReflectorStream对象。 fStreamArray = NEW ReflectorStream*[fSourceInfo->GetNumStreams()]; for (UInt32 x = 0; x < fSourceInfo->GetNumStreams(); x++) { ... ... if(theStreamRef == NULL) { fStreamArray[x] = NEW ReflectorStream(fSourceInfo->GetStreamInfo(x)); ? } } fStreamArray[x]->BindSockets(inParams,inFlags, filterState, filterTimeout); fStreamArray[x]->SetEnableBuffer(this->fHasBufferedStreams); fSourceInfo->GetStreamInfo(x)->fPort = fStreamArray[x]->GetStreamInfo()->fPort; ReflectorStream::GenerateSourceID(fSourceInfo->GetStreamInfo(x), sStreamMap->Register(fStreamArray[x]->GetRef()); &theStreamID[0]); (2)、AddOutput bucket = -1; lastBucket = -1; while (true) { // 针对每一个ReflectorStream调用AddOutput添加inOutput for ( ; x < fSourceInfo->GetNumStreams(); x++) { bucket = fStreamArray[x]->AddOutput(inOutput, bucket); if (bucket == -1) break; else { lastBucket = bucket; if (isClient) fStreamArray[x]->IncEyeCount(); } } ... ... } atomic_add(&fNumOutputs, 1); QTAtom (1)、构建函数 QTAtom::QTAtom(QTFile * File, QTFile::AtomTOCEntry * Atom, Bool16 Debug, Bool16 DeepDebug) : fDebug(Debug), fDeepDebug(DeepDebug), fFile(File) { memcpy(&fTOCEntry, Atom, sizeof(QTFile::AtomTOCEntry)); } ? QTAtom_mvhd 基于QTAtom类 (1)、构建函数 QTAtom_mvhd::QTAtom_mvhd(QTFile* File, QTFile::AtomTOCEntry* TOCEntry, Bool16 Debug, Bool16 DeepDebug) ? : QTAtom(File, TOCEntry, Debug, DeepDebug) { } (2)、Initialize() // Parse this atom's fields. fFile为QTFile类型的对象 // 调用fFile->Read(fTOCEntry.AtomDataPos+Offset, Buffer, Length) ReadInt32(mvhdPos_VersionFlags, &tempInt32); fVersion = (Uint8)((tempInt32 >> 24) & 0x000000ff); fFlags = tempInt32 & 0x00ffffff; 通过fFile->Read读取各个参数数据保存到fCreationTime、fModificationTime... ... QTTrack The central point of control for a track in a QTFile. (1)、构建函数 QTTrack::QTTrack(QTFile * File, QTFile::AtomTOCEntry * Atom, Bool16 Debug, Bool16 DeepDebug) { : fDebug(Debug), fDeepDebug(DeepDebug), fFile(File), ... ... QTFile::AtomTOCEntry *tempTOCEntry; // Make a copy of the TOC entry. memcpy(&fTOCEntry, Atom, sizeof(QTFile::AtomTOCEntry)); // Load in the track header atom for this track. fFile->FindTOCEntry(“:tkhd”, &tempTOCEntry, &fTOCEntry) // 创建QTAtom_tkhd类对象,并执行Initialize函数,类似于QTAtom_mvhd类。 } fTrackHeaderAtom = NEW QTAtom_tkhd(fFile, tempTOCEntry, fDebug, fDeepDebug); fTrackHeaderAtom->Initialize(); (2)、Initialize() // See if this track has a name and load it in. // fTOCEntry在构建函数里初始化。 if( fFile->FindTOCEntry(\, &tempTOCEntry, &fTOCEntry) ) { fTrackName = NEW char[ (SInt32) (tempTOCEntry->AtomDataLength + 1) ]; if( fTrackName != NULL ) fFile->Read(tempTOCEntry->AtomDataPos, fTrackName, (UInt32) tempTOCEntry->AtomDataLength); } // Load in the media header atom for this track. fFile->FindTOCEntry(\, &tempTOCEntry, &fTOCEntry) fMediaHeaderAtom = NEW QTAtom_mdhd(fFile, tempTOCEntry, fDebug, fDeepDebug); fMediaHeaderAtom->Initialize(); // Load in the edit list atom for this track. 类似于上面那样创建并初始化fEditListAtom,并初始化fFirstEditMediaTime。 // Load in the data reference atom for this track. 创建并初始化fDataReferenceAtom。 // Load in the sample table atoms. 创建并初始化fTimeToSampleAtom、fCompTimeToSampleAtom、fSampleToChunkAtom、 fSampleDescriptionAtom、fChunkOffsetAtom、fSampleSizeAtom、fSyncSampleAtom fIsInitialized = true; ? QTHintTrack QTTrack的继承类,The central point of control for a hint track in a QTFile. (1)、构建函数 QTHintTrack::QTHintTrack(QTFile * File, QTFile::AtomTOCEntry * Atom, Bool16 Debug, Bool16 : QTTrack(File, Atom, Debug, DeepDebug), ... ... DeepDebug) (2)、Initialize() QTTrack::Initialize() // Get the sample description table for this track and verify that it is an RTP track. // fSampleDescriptionAtom在QTTrack::Initialize里面创建并初始化 fSampleDescriptionAtom->FindSampleDescription(FOUR_CHARS_TO_INT('r', 't', 'p', ' '), &sampleDescription, &sampleDescriptionLength) ::memcpy(&fMaxPacketSize, sampleDescription + 20, 4); fMaxPacketSize = ntohl(fMaxPacketSize); for( pSampleDescription = (sampleDescription + 24); pSampleDescription < (sampleDescription + sampleDescriptionLength);) { // Get the entry length and data type of this entry ::memcpy(&entryLength, pSampleDescription+0, 4); entryLength=ntohl(entryLength); ::memcpy(&dataType, pSampleDescription+4, 4); dataType = ntohl(dataType); // Process this data type. switch(dataType) { case FOUR_CHARS_TO_INT('t', 'i', 'm', 's'): // tims RTP timescale ::memcpy(&fRTPTimescale, pSampleDescription + 8, 4); offset fRTPTimescale = ntohl(fRTPTimescale); break; case FOUR_CHARS_TO_INT('t', 's', 'r', 'o'): // tsro Timestamp random ::memcpy(&fTimestampRandomOffset, pSampleDescription + 8, 4); random offset fTimestampRandomOffset = ntohl(fTimestampRandomOffset); break; case FOUR_CHARS_TO_INT('s', 'n', 'r', 'o'): // snro Sequence number ::memcpy(&fSequenceNumberRandomOffset, pSampleDescription + 8, 2); fSequenceNumberRandomOffset = ntohl(fSequenceNumberRandomOffset); break; } pSampleDescription += entryLength; } // Load in the hint info atom for this track. 创建并初始化fHintInfoAtom // Load in the hint track reference atom for this track. 创建并初始化fHintTrackReferenceAtom // Allocate space for our track reference table. numTrackRefs = fHintTrackReferenceAtom->GetNumReferences(); fTrackRefs = NEW QTTrack *[numTrackRefs]; // Locate all of the tracks that we use, but don't initialize them until we actually try // to access them. for( UInt32 CurRef = 0; CurRef < numTrackRefs; CurRef++ ) { // Get the reference and make sure it's not empty. fHintTrackReferenceAtom->TrackReferenceToTrackID(CurRef, &trackID) // Store away a reference to this track. fFile->FindTrack(trackID, &fTrackRefs[CurRef]); ? } // Calculate the first RTP timestamp for this track. 设置fFirstRTPTimestamp fHintTrackInitialized = true; OSFileSource 底层的文件操作类,simple file abstraction. This file abstraction is ONLY to be used for files intended for serving。 (1)构建函数 会调用Set函数,在该函数里,调用open打开文件、调用fstat获取文件信息。 (2)Read 调用ReadFromPos或者ReadFromCache。 ReadFromPos和ReadFromCache的区别待分析!! ? QTSSFile (1)Open // Because this is a role being executed from inside a callback, we need to make // sure that QTSS_RequestEvent will not work ??? ... ... curTask = theState->curTask; ... ... 调用注册QTSS_OpenFilePreProcess_Role处理的模块的处理函数。系统自带的模块没有提 供这个Role的处理。 如果返回QTSS_FileNotFound,则调用注册QTSS_OpenFile_Role处理的模块的处理函数。 QTSSPosixFileSysModule提供了这个Role的处理。 将上述找到的模块赋给fModule,后续可以通过fModule来调用该模块没有注册的Role处理
共分享92篇相关文档