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

📄 tvpinstream.cpp

📁 mysee网络直播源代码Mysee Lite是Mysee独立研发的网络视频流媒体播放系统。在应有了P2P技术和一系列先进流媒体技术之后
💻 CPP
字号:
#include "stdafx.h"
#include "Dvdmedia.h"

CTVStreamSourcePin::CTVStreamSourcePin(
	   TCHAR *pObjectName, HRESULT *phr, CSource *pFilter, bool isAudio)
		: CSourceStream(pObjectName, phr, pFilter, L"Out"), 
		m_pFilter((CTVStreamSource*)pFilter), 
		m_iVideoSampleSize(0), 
		m_iAudioSampleSize(0),
		m_pAnotherPin(NULL) ,
		m_bPinAvaible(TRUE) ,
        m_bFlushforSync(0),
		CSourceSeeking(NAME("Chaos Filter Seeking Pin"), NULL, phr, pFilter->pStateLock())
{	
    m_Data = new BYTE[65536];
	m_rtStart    = 0;
	m_rtStop     = 1 * UNITS;
	m_rtDuration = 1 * UNITS; 
	//
	m_isAudioPin = isAudio;
	//
	m_SeekData.rtSeekTo = _I64_MAX;
	m_SeekData.bSycn    = FALSE;
	//
	//
	SetSeekData(0);

	m_bSync = FALSE;

	m_bTryGetMediaType = true;
	m_MediaType.cbFormat = 0;
	// 必须是winxp 及其以上版本的OS
	if(m_pFilter->CanDynamicReconnect()) {
		// Winxp之前不能支持切换编码
		SetDefaultMediaType();
	}

#ifdef USE_LOG
    if(m_isAudioPin)
        log = fopen("c:\\chaosaudiopinlog.log", "w+");
    else
        log = fopen("c:\\chaosvideopinlog.log", "w+");
    
	fprintf(log, "start pin\r\n");
	fflush(log);
#endif

}
//
CTVStreamSourcePin::~CTVStreamSourcePin() 
{
    delete[] m_Data;
#ifdef USE_LOG
	if(log)
		fclose(log);
#endif
}
//
void CTVStreamSourcePin::SetDefaultMediaType()
{
	// raw video type
	static const BYTE videoData[] = {
		0x76, 0x69, 0x64, 0x73, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71, 
		0x7D, 0xEB, 0x36, 0xE4, 0x4F, 0x52, 0xCE, 0x11, 0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70, 
		0x80, 0x9F, 0x58, 0x05, 0x56, 0xC3, 0xCE, 0x11, 0xBF, 0x01, 0x00, 0xAA, 0x00, 0x55, 0x59, 0x5A, 
		0x01, 0x00, 0x00, 0x00, 0xC2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x62, 0x17, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 
		0xF0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x03, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};

	/*
	// raw audio type
	static const BYTE audioData[] = {
		0x61, 0x75, 0x64, 0x73, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71, 
		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71, 
		0x81, 0x9F, 0x58, 0x05, 0x56, 0xC3, 0xCE, 0x11, 0xBF, 0x01, 0x00, 0xAA, 0x00, 0x55, 0x59, 0x5A, 
		0x04, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x44, 0xAC, 0x00, 0x00, 
		0x10, 0xB1, 0x02, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00
	};
	*/

	// 直接无法创建,只能从现有的filter中寻找(所以默认的音频必须是GSM,这样才能找到)
	// gsm6.10
	static const BYTE audioData[] = {
		0x61, 0x75, 0x64, 0x73, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71, 
		0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71, 
		0x81, 0x9F, 0x58, 0x05, 0x56, 0xC3, 0xCE, 0x11, 0xBF, 0x01, 0x00, 0xAA, 0x00, 0x55, 0x59, 0x5A, 
		0x41, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x31, 0x00, 0x01, 0x00, 0x44, 0xAC, 0x00, 0x00, 
		0xFD, 0x22, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x01
	};

	TVMEDIATYPESECTION tv;
	BYTE data[256];

	if(m_isAudioPin) {
		memcpy(&tv, audioData, sizeof(tv));
		if(tv.cbFormat)
			memcpy(data, audioData+sizeof(tv), tv.cbFormat);
	}
	else {
		memcpy(&tv, videoData, sizeof(tv));
		if(tv.cbFormat)
			memcpy(data, videoData+sizeof(tv), tv.cbFormat);
	}

	CMediaType MediaType;
	//memset(&MediaType, 0, sizeof(CMediaType));
	LPVOID *pvi = (LPVOID*)MediaType.AllocFormatBuffer(tv.cbFormat);
	//
	memcpy(pvi, data, tv.cbFormat);
	MediaType.SetType(&tv.majortype);
	MediaType.SetSubtype(&tv.subtype);
	MediaType.SetFormatType(&tv.formattype);
	MediaType.SetTemporalCompression(tv.bTemporalCompression);
	MediaType.SetSampleSize(tv.lSampleSize);
	MediaType.bFixedSizeSamples = tv.bFixedSizeSamples;
	MediaType.cbFormat = tv.cbFormat;
	//
	m_MediaType.Set(MediaType);
	
}

void CTVStreamSourcePin::GetFirstMediaType()
{
    // 不尝试多次
	if(!m_bTryGetMediaType)
	    return;

    m_bTryGetMediaType = false;
    PBYTE pData = m_Data;
	memset(pData, 0 , 65536);
    int iRet = 0;
    m_header.bAudioSample = m_isAudioPin;

    if(m_pFilter->CanDynamicReconnect())
    {
       iRet = m_pFilter->m_pComm->GetData(m_header, pData, 65536, m_isAudioPin, false);
    }
    else
    {
	    // 10秒钟内必须读取到mediatype,否则,不予等待
        int i = 0;
	    for(; i < 100; ++i)
	    {
		//		    
		    iRet = m_pFilter->m_pComm->GetData(m_header, pData, 65536, m_isAudioPin, false);
		//
		    if (iRet > 0)//取到数据
                break;
		
		    Sleep(100);
	    }

        if(i >= 100 && iRet <= 0)
            return;
    }
    if(iRet <= 0)
    {
 #ifdef USE_LOG
    	fprintf(log, "first get media data fail! \r\n");
#endif
        return;
    }

#ifdef USE_LOG
    	fprintf(log, "first get media data OK \r\n");
#endif

	if (m_header.start == 0 && m_header.length == 0)//mediaType
	{
		//
		TVMEDIATYPESECTION tv;
		memset(&tv, 0, sizeof(TVMEDIATYPESECTION));
		memcpy(&tv, pData, sizeof(TVMEDIATYPESECTION));
		//
		LPVOID *pvi = (LPVOID*)m_MediaType.AllocFormatBuffer(tv.cbFormat);
		if (pvi == 0) 
		{
			return;
		}
				//
		memcpy(pvi, pData + sizeof(TVMEDIATYPESECTION), tv.cbFormat);
		m_MediaType.SetType(&tv.majortype);
		m_MediaType.SetSubtype(&tv.subtype);
		m_MediaType.SetFormatType(&tv.formattype);
		m_MediaType.SetTemporalCompression(tv.bTemporalCompression);
		m_MediaType.SetSampleSize(tv.lSampleSize);
		m_MediaType.bFixedSizeSamples = tv.bFixedSizeSamples;
		m_MediaType.cbFormat = tv.cbFormat;
				//
		SetInfor(tv);
				//
	}//header

#ifdef USE_LOG
    	fflush(log);
#endif

	//
	return;
}
//
HRESULT CTVStreamSourcePin::GetMediaType(CMediaType *pMediaType)
{

    CheckPointer(pMediaType, E_POINTER);
	//
	if (NULL == m_pFilter)
	{
		ASSERT(FALSE);
		return S_FALSE;
	}
	//
	if (m_pFilter->m_pComm       == NULL && 
		m_pFilter->m_pFileReader == NULL)
	{
		ASSERT(FALSE);
		return S_FALSE;
	}
	//
	CAutoLock cAutoLock(m_pFilter->pStateLock());
	// 取得媒体类型的数据
	TVMEDIATYPESECTION tv;
	BOOL  nRet     = FALSE;
	PBYTE lpviTemp = NULL;
	//
	if(m_pFilter->m_pComm )  
	{
		// 必须是winxp 及其以上版本的OS
//     	if(!m_pFilter->CanDynamicReconnect()) {
			// 由于没有默认媒体类型,需要等待网络返回
			GetFirstMediaType();

			// 没有获取到媒体类型数据,返回错误
			if(m_MediaType.cbFormat == 0)
				return S_FALSE;
//		}
		return pMediaType->Set(m_MediaType);
	}
	else if(m_pFilter->m_pFileReader)
	{
		nRet = m_pFilter->m_pFileReader->GetMediaType(tv, m_isAudioPin);
		if(nRet != TRUE)
		{
			ASSERT(FALSE);
			return S_FALSE;
		}
		//
		lpviTemp = new BYTE[tv.cbFormat];
		nRet = m_pFilter->m_pFileReader->GetMediaData(lpviTemp, m_isAudioPin);
		//
		if(nRet != TRUE)
		{
			ASSERT(FALSE);
			return S_FALSE;
		}
	}
	else 
	{
		ASSERT(FALSE);
		return E_POINTER;
	}
	//
	if(tv.bThisPinOnly && m_isAudioPin)
	{
		m_pFilter->m_isAudioOnly = TRUE;
	}
	//
	if(tv.cbFormat == 0 && tv.lSampleSize == 0) 
	{
		return S_FALSE;
	}
	// Allocate enough room for the MPEG1VIDEOINFO and the color tables
    LPVOID *pvi = (LPVOID*)pMediaType->AllocFormatBuffer(tv.cbFormat);
    if (pvi == 0) 
    {
		return(E_OUTOFMEMORY);
	}
	//
	memcpy(pvi,lpviTemp,tv.cbFormat);
    pMediaType->SetType(&tv.majortype);
	pMediaType->SetSubtype(&tv.subtype);
    pMediaType->SetFormatType(&tv.formattype);
    pMediaType->SetTemporalCompression(tv.bTemporalCompression);
    pMediaType->SetSampleSize(tv.lSampleSize);
	pMediaType->bFixedSizeSamples = tv.bFixedSizeSamples;
	pMediaType->cbFormat = tv.cbFormat;
	//
	SetInfor(tv);	
	// 删除临时变量
	if (NULL != lpviTemp)
	{
		delete [] lpviTemp;
		lpviTemp = NULL;
	}
	//
	return S_OK;
}
//
void CTVStreamSourcePin::SetInfor(TVMEDIATYPESECTION tv)
{
	if(tv.bFixedSizeSamples)
	{
		(m_isAudioPin?m_iAudioSampleSize:m_iVideoSampleSize) = tv.lSampleSize;
	}
	// 因为媒体类型中所制定的SampleSize可能有误(过小),所以要保证大于

⌨️ 快捷键说明

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