⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 captureserver.cpp

📁 mysee网络直播源代码Mysee Lite是Mysee独立研发的网络视频流媒体播放系统。在应有了P2P技术和一系列先进流媒体技术之后
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	if(cfgData.chnlStr.length() >= 64) {
		MessageBox(parentWindow, "配置文件中channelName一项其长度必须小于64字符。", "错误", MB_OK|MB_ICONERROR);
		return FALSE;
	}
	if(cfgData.password.length() != 32) {
		MessageBox(parentWindow, "配置文件中Password一项其长度必须等于32字符。", "错误", MB_OK|MB_ICONERROR);
		return FALSE;
	}

	return TRUE;
}

BOOL CaptureServer::SetFormatData(TVMEDIATYPESECTION& tv, BYTE* data, BOOL isAudio)
{
	if(!data)
		return FALSE;

	// 因为SetAudioOrVideoOnly比SetFormatData先被调用,所以要在这里记录
	bool bIsThisPinOnly = isAudio?audioStruct.bThisPinOnly:videoStruct.bThisPinOnly;

	// 分别复制视频和音频数据
	if(!isAudio) {
		SAFE_ARRAYDELETE(videoData);
		memcpy(&videoStruct, &tv, sizeof(TVMEDIATYPESECTION));
		if(videoStruct.cbFormat > 512)
			return FALSE;
		videoData = new BYTE[videoStruct.cbFormat];
		memcpy(videoData, data, videoStruct.cbFormat);

		// 恢复
		videoStruct.bThisPinOnly = bIsThisPinOnly;
				
	}
	else {
		SAFE_ARRAYDELETE(audioData);
		memcpy(&audioStruct, &tv, sizeof(TVMEDIATYPESECTION));
		if(audioStruct.cbFormat > 512)
			return FALSE;
		audioData = new BYTE[audioStruct.cbFormat];
		memcpy(audioData, data, audioStruct.cbFormat);

		// 恢复
		audioStruct.bThisPinOnly = bIsThisPinOnly;
	}

	for(UINT i = 0; i < bufferList.size();++i)
	{
		if(!bufferList[i]->AttachMediaDataToCurrentBlock(tv, data, isAudio, logList[i]))
			return FALSE;
	}

	if((audioData&&videoData) || // 如果视频和音频的数据都有了
		(audioData&&audioStruct.bThisPinOnly) || // 如果只有音频
		(videoData&&videoStruct.bThisPinOnly)) { // 如果只有视频

		// 如果需要保存zzl文件,则建立zzl文件
		if(!cfgData.savePath.empty()) {
			if(!m_zzlWriter.Init(cfgData.savePath, cfgData.chnlStr)) {
				//MessageBox(parentWindow, "无法建立节目文件!", "错误", MB_OK);
				return 0;
			}
			if(!m_zzlWriter.SetMediaType(audioStruct, audioData, videoStruct, videoData)) {
				MessageBox(parentWindow, "无法建立节目文件!SetMediaType Error!", "错误", MB_OK);
			}
		}
	}

	return TRUE;
}

BOOL CaptureServer::GetFormatData(TVMEDIATYPESECTION& tv, PBYTE& data, BOOL isAudio)
{
	if(!isAudio)
	{
		if(audioStruct.bThisPinOnly)
		{
			memset(&tv, 0, sizeof(tv));
			data = NULL;
			return TRUE;
		}

		if(!videoData)
			return FALSE;

		memcpy(&tv, &videoStruct, sizeof(TVMEDIATYPESECTION));
		data = new BYTE[videoStruct.cbFormat];
		memcpy(data, videoData, videoStruct.cbFormat);
	}
	else
	{
		if(videoStruct.bThisPinOnly)
		{
			memset(&tv, 0, sizeof(tv));
			data = NULL;
			return TRUE;
		}

		if(!audioData)
			return FALSE;

		memcpy(&tv, &audioStruct, sizeof(TVMEDIATYPESECTION));
		
		data = new BYTE[audioStruct.cbFormat];
		memcpy(data, audioData, audioStruct.cbFormat);
	}

	return TRUE;
}

void CaptureServer::SetAudioOrVideoOnly(BOOL isAudio)
{
	if(isAudio)
	{
		audioStruct.bThisPinOnly = true;
	}
	else
	{
		videoStruct.bThisPinOnly = true;
	}
	m_bIsOnlyOnePin = TRUE;
	m_zzlWriter.SetIsSingleAudio(isAudio);
}

BOOL CaptureServer::PutSample(const SampleHeader& header, BYTE* pData)
{
	totalBytes += header.size;

	for(UINT i = 0; i < bufferList.size();++i)
	{
		if(!bufferList[i]->PutSample(header, pData, logList[i]))
			return FALSE;
	}

	if(!cfgData.savePath.empty())
	{
		::EnterCriticalSection(&m_SamQueueCSec);
		//if(!m_bTransDataEnd)
		{
			if(audioStruct.bThisPinOnly || videoStruct.bThisPinOnly)
			{
				if(!m_zzlWriter.PutSample(header, pData))
				{
					ASSERT(FALSE);
				}
			}
			else
			{		
				if(header.bAudioSample)
				{
					if(m_llAudioTime >= m_llVideoTime + MAX_AVDELAY)
					{
						BYTE *pSamData = new BYTE[header.size];
						SAMPLEDATA *pSAMPLEDATA = new SAMPLEDATA;
						memset(pSAMPLEDATA, 0, sizeof(SAMPLEDATA));
						memcpy(&(pSAMPLEDATA->samplehr), &header, sizeof(SampleHeader));
						memcpy(pSamData, pData, header.size);
						pSAMPLEDATA->pData = pSamData;
						m_AudioSamQueue.push(pSAMPLEDATA);
					}
					else
					{
						if(m_AudioSamQueue.size() > 0)
						{
							BYTE *pSamData = new BYTE[header.size];
							SAMPLEDATA *pSAMPLEDATA = new SAMPLEDATA;
							memset(pSAMPLEDATA, 0, sizeof(SAMPLEDATA));
							memcpy(&(pSAMPLEDATA->samplehr), &header, sizeof(SampleHeader));
							memcpy(pSamData, pData, header.size);
							pSAMPLEDATA->pData = pSamData;
							m_AudioSamQueue.push(pSAMPLEDATA);

							SAMPLEDATA *pCurrentSampleData = m_AudioSamQueue.front();
							m_AudioSamQueue.pop();

							if(!m_zzlWriter.PutSample(pCurrentSampleData->samplehr, pCurrentSampleData->pData))
							{
								ASSERT(FALSE);
							}

							m_llAudioTime = pCurrentSampleData->samplehr.start;
							delete pCurrentSampleData->pData;
							delete pCurrentSampleData;
						}
						else
						{
							if(!m_zzlWriter.PutSample(header, pData))
							{
								ASSERT(FALSE);
							}

							m_llAudioTime = header.start;
						}
					}

					
					//以音频的动力拉动视频符合误差范围的Sample
					while(m_VideoSamQueue.size() > 0 && m_VideoSamQueue.front()->samplehr.start <= m_llAudioTime + MAX_AVDELAY)
					{
						SAMPLEDATA *pCurrentSampleData = m_VideoSamQueue.front();
						if(!m_zzlWriter.PutSample(pCurrentSampleData->samplehr, pCurrentSampleData->pData))
						{
							ASSERT(FALSE);
						}

						m_VideoSamQueue.pop();
						m_llVideoTime = pCurrentSampleData->samplehr.start;
						delete pCurrentSampleData->pData;
						delete pCurrentSampleData;
					}
					
				}
				else
				{
					if(m_llVideoTime >= m_llAudioTime + MAX_AVDELAY)
					{
						BYTE *pSamData = new BYTE[header.size];
						SAMPLEDATA *pSAMPLEDATA = new SAMPLEDATA;
						memset(pSAMPLEDATA, 0, sizeof(SAMPLEDATA));
						memcpy(&(pSAMPLEDATA->samplehr), &header, sizeof(SampleHeader));
						memcpy(pSamData, pData, header.size);
						pSAMPLEDATA->pData = pSamData;
						m_VideoSamQueue.push(pSAMPLEDATA);
					}
					else
					{
						if(m_VideoSamQueue.size() > 0)
						{
							BYTE *pSamData = new BYTE[header.size];
							SAMPLEDATA *pSAMPLEDATA = new SAMPLEDATA;
							memset(pSAMPLEDATA, 0, sizeof(SAMPLEDATA));
							memcpy(&(pSAMPLEDATA->samplehr), &header, sizeof(SampleHeader));
							memcpy(pSamData, pData, header.size);
							pSAMPLEDATA->pData = pSamData;
							m_VideoSamQueue.push(pSAMPLEDATA);

							SAMPLEDATA *pCurrentSampleData = m_VideoSamQueue.front();
							m_VideoSamQueue.pop();

							if(!m_zzlWriter.PutSample(pCurrentSampleData->samplehr, pCurrentSampleData->pData))
							{
								ASSERT(FALSE);
							}

							m_llVideoTime = pCurrentSampleData->samplehr.start;
							delete pCurrentSampleData->pData;
							delete pCurrentSampleData;
						}
						else
						{
							if(!m_zzlWriter.PutSample(header, pData))
							{
								ASSERT(FALSE);
							}

							m_llVideoTime = header.start;
						}
					}
				
					//以视频的动力拉动音频符合误差范围的Sample
					while(m_AudioSamQueue.size() > 0 && m_AudioSamQueue.front()->samplehr.start <= m_llVideoTime + MAX_AVDELAY)
					{
						SAMPLEDATA *pCurrentSampleData = m_AudioSamQueue.front();
						if(!m_zzlWriter.PutSample(pCurrentSampleData->samplehr, pCurrentSampleData->pData))
						{
							ASSERT(FALSE);
						}

						m_AudioSamQueue.pop();
						m_llAudioTime = pCurrentSampleData->samplehr.start;
						delete pCurrentSampleData->pData;
						delete pCurrentSampleData;
					}
					
				}
			}
		}
 		::LeaveCriticalSection(&m_SamQueueCSec);
	}

	return TRUE;
}

float CaptureServer::GetSpeedInKBPS()
{
	
	if(!cfgData.savePath.empty())
		return (float)m_zzlWriter.GetBitRate();	// 由于压缩用的时间可能超过媒体文件的实际长度,所以此处统计的码率更加准确

	SYSTEMTIME stNow;
	GetSystemTime(&stNow);
	LARGE_INTEGER llNow;
	SystemTimeToFileTime(&stNow, (FILETIME*)&llNow);

	LARGE_INTEGER llStart;
	SystemTimeToFileTime(&startTime, (FILETIME*)&llStart);

	if(llNow.QuadPart - llStart.QuadPart > 0) {
		DbgLog((LOG_TRACE, 5, TEXT("Speed: %f"), totalBytes/(double)((llNow.QuadPart-llStart.QuadPart)/10000) ));
		return static_cast<float>(totalBytes/(double)((llNow.QuadPart-llStart.QuadPart)/10000));
	}	
	else
		return 0.0;
}
// Implementation of CaptureServer }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -