📄 tvpinstream.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 + -