📄 videoenc.cpp
字号:
}
// set the profile for WMV# only
if( pParams->dwTag == WMCFOURCC_WMV3 ){
switch( pParams->nProfile ){
case P_MAIN:
bstrIn = ::SysAllocString(L"MP");
break;
case P_SIMPLE:
bstrIn = ::SysAllocString(L"SP");
break;
case P_COMPLEX:
bstrIn = ::SysAllocString(L"CP");
break;
default:
hr = E_VIDEO_INVALID_PROFILE;
break;
}
::VariantInit(&varg);
varg.vt = VT_BSTR;
varg.bstrVal = bstrIn;
hr = pPropertyBag->Write( g_wszWMVCDecoderComplexityRequested, &varg );
::SysFreeString( bstrIn );
if( FAILED( hr ) ){
hr = E_VIDEO_PROFILE_REJECTED;
break;
}
}
// set the ecoder complexity
::VariantInit(&varg);
varg.vt = VT_I4;
varg.lVal = pParams->nComplexity;
hr = pPropertyBag->Write(g_wszWMVCComplexityEx, &varg);
if( FAILED( hr ) ){
hr = E_VIDEO_COMPLEXITY_REJECTED;
break;
}
// set the max distance between the key frames
::VariantInit(&varg);
varg.vt = VT_I4;
varg.lVal = pParams->nKeyDist * 1000;
hr = pPropertyBag->Write( g_wszWMVCKeyframeDistance, &varg );
if( FAILED( hr ) ){
hr = E_VIDEO_KEYDIST_REJECTED;
break;
}
// set the crispness params for WMV# only
if( pParams->dwTag == WMCFOURCC_WMV3 ){
::VariantInit(&varg);
varg.vt = VT_I4;
varg.lVal = pParams->nQuality;
hr = pPropertyBag->Write( g_wszWMVCCrisp, &varg );
if( FAILED( hr ) ){
hr = E_VIDEO_CRISPNESS_REJECTED;
break;
}
}
} while( FALSE );
SAFERELEASE( pPropertyBag );
return hr;
}
//////////////////////////////////////////////////////////////////////////////
//
// DefaultVideoBitrate
//
//////////////////////////////////////////////////////////////////////////////
// a decent guess would be 0.4 bits per pixel
HRESULT DefaultVideoBitrate( AM_MEDIA_TYPE *pmt, double dFramesPerSec, int *pBitrate ){
if( pmt == NULL || pBitrate == NULL )
return E_INVALIDARG;
if( pmt->pbFormat == NULL || pmt->cbFormat <= 0 )
return E_INVALIDARG;
if( pmt->formattype == FORMAT_VideoInfo ){
VIDEOINFOHEADER *pvih = (VIDEOINFOHEADER*)pmt->pbFormat;
// 0.4 bits per pixel will generate good quality content at a reasonable bitrate
*pBitrate = ( pvih->bmiHeader.biWidth * pvih->bmiHeader.biHeight * 2 ) / 5;
if( dFramesPerSec == 0 ) { // use the input rate
if( pvih->AvgTimePerFrame > 0 )
dFramesPerSec = 10000000.0 / pvih->AvgTimePerFrame;
else
dFramesPerSec = 29.97; // 30 frames per sec
}
} else if( pmt->formattype == FORMAT_VideoInfo2 ){
VIDEOINFOHEADER2 *pvih = (VIDEOINFOHEADER2*)pmt->pbFormat;
// 0.4 bits per pixel will generate good quality content at a reasonable bitrate
*pBitrate = ( pvih->bmiHeader.biWidth * pvih->bmiHeader.biHeight * 2 ) / 5;
if( dFramesPerSec == 0 ) { // use the input rate
if( pvih->AvgTimePerFrame > 0 )
dFramesPerSec = 10000000.0 / pvih->AvgTimePerFrame;
else
dFramesPerSec = 29.97; // 30 frames per sec
}
} else
return E_VIDEO_INVALID_INPUT_TYPE;
*pBitrate = (int)( *pBitrate * dFramesPerSec );
return S_OK;
}
//////////////////////////////////////////////////////////////////////////////
//
// InitializeVideoEncoder
//
//////////////////////////////////////////////////////////////////////////////
HRESULT InitializeVideoEncoder( AM_MEDIA_TYPE *pmtInput, \
CVideoEncParams *pParams, \
IMediaObject *pDMO, \
AM_MEDIA_TYPE *pmtOutput){
HRESULT hr;
DWORD cbInputBuffer = 0;
DWORD cbOutputBuffer = 0;
if( pmtInput == NULL || pParams == NULL || pDMO == NULL )
return E_INVALIDARG;
//check to see if the video bitrate has been set; if not calculate the default
if( pParams->nBitrate <= 0 )
{
hr = DefaultVideoBitrate( pmtInput, pParams->fFrameRate, &pParams->nBitrate );
if( FAILED( hr ) )
return hr;
}
hr = SetVideoParams( pDMO, pParams );
// ON_FAIL("Failed SetVideoParams", hr)
// cbInputBuffer and cbOutputBuffer are actually not used here.
hr = SetVideoTypes( pDMO, pmtInput, pParams, pmtOutput, &cbInputBuffer, &cbOutputBuffer );
if( FAILED( hr ) )
{
// ON_FAIL("Failed SetVideoTypes", hr)
return hr;
}
return hr;
}
HRESULT CCaptureGraph::GetInputMediaType(IBaseFilter* pCap, AM_MEDIA_TYPE& mt)
{
HRESULT hr;
IAMStreamConfig *pSC = NULL;
AM_MEDIA_TYPE* lpmt = NULL;
//获得lpgraphBuilder2_
CComPtr<ICaptureGraphBuilder2> lpgraphBuilder2_;
hr = lpgraphBuilder2_.CoCreateInstance(CLSID_CaptureGraphBuilder2);
if (FAILED(hr))
{
return hr;
}
hr = lpgraphBuilder2_->SetFiltergraph(m_pGB);
//查询接口
hr = lpgraphBuilder2_->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Interleaved, m_pVideoCapture,
IID_IAMStreamConfig, (void **)&pSC);
if(hr != NOERROR)
hr = lpgraphBuilder2_->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, m_pVideoCapture,
IID_IAMStreamConfig, (void **)&pSC);
if (!FAILED(hr))
{
hr = pSC->GetFormat(&lpmt);
mt = *lpmt;
pSC->Release();
}
/*
CComPtr<IBaseFilter> pDummyFilter;
CComPtr<IPin> pCapOutPin;
hr = AddFilter(CLSID_NullRenderer, &pDummyFilter, "Dummy Filter");
if(FAILED(hr))
{
TRACE("Failed to create dummy filter!");
return hr;
}
hr = ConnectPins(pCap, NULL, pDummyFilter, NULL, &mt);
if(FAILED(hr))
{
TRACE("Failed to connect dummy filter!");
return hr;
}
pCapOutPin = FindPinOnFilter(pCap, NULL, PINDIR_OUTPUT);
if(pCapOutPin == NULL)
{
TRACE("Failed to get capture out pin!");
return E_FAIL;
}
hr = pCapOutPin->ConnectionMediaType(&mt);
if(FAILED(hr))
{
TRACE("Failed to get connection media type!");
return hr;
}
hr = pCapOutPin->Disconnect();
if(FAILED(hr))
{
TRACE("Failed to disconnect capture out pin!");
return hr;
}
//now disconnect and remove dummy filter
hr = m_pGB->RemoveFilter(pDummyFilter);
if(FAILED(hr))
{
TRACE("Failed to remove dummy filter!");
return hr;
}
*/
return hr;
}
extern CVideoEncParams g_VideoEncodingParams;
HRESULT ConfigureDMO(IMediaObject* pDMO, AM_MEDIA_TYPE* pmtIn, AM_MEDIA_TYPE* pmtOut)
{
HRESULT hr;
if ( FORMAT_VideoInfo == pmtIn->formattype || FORMAT_VideoInfo2 == pmtIn->formattype )
{
hr = InitializeVideoEncoder( pmtIn, &g_VideoEncodingParams, pDMO, pmtOut );
}
else
{
FreeMediaType( *pmtIn );
memset( pmtIn, 0, sizeof( AM_MEDIA_TYPE ) );
hr = E_FAIL;
}
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -