📄 videoenc.cpp
字号:
{
hr = E_VIDEO_PEAK_BUFFER_REJECTED;
break;
}
}
//
// set the profile for WMV# only
//
hr = S_OK;
BSTR bstrIn=NULL;
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;
}
if( FAILED( hr ) ) 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 complexity param
//
::VariantInit(&varg);
varg.vt = VT_I4;
varg.lVal = pParams->nComplexity;
hr = pPropertyBag->Write( g_wszWMVCComplexityEx, &varg );
if( FAILED( hr ) )
{
hr = E_VIDEO_KEYDIST_REJECTED;
break;
}
//
// set the max distance between the key frames
//
::VariantInit(&varg);
varg.vt = VT_I4;
varg.lVal = pParams->nKeyDist;
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 || pParams->dwTag == WMCFOURCC_WMV2 || pParams->dwTag == WMCFOURCC_WMV1 )
{
::VariantInit(&varg);
varg.vt = VT_I4;
varg.lVal = pParams->nCrisp;
hr = pPropertyBag->Write( g_wszWMVCCrisp, &varg );
if( FAILED( hr ) )
{
hr = E_VIDEO_CRISPNESS_REJECTED;
break;
}
}
if ( pParams->fIsVBR)
{
::VariantInit(&varg);
varg.vt = VT_I4;
varg.lVal = pParams->nQuality;
hr = pPropertyBag->Write( g_wszWMVCVBRQuality, &varg );
if( FAILED( hr ) )
{
hr = E_VIDEO_QUALITY_REJECTED;
break;
}
}
#ifdef SUPPORT_INTERLACE
//
// set the interlace mode for WMV# only
//
if( pParams->dwTag == WMCFOURCC_WMV3 && pParams->fIsInterlaced)
{
::VariantInit(&varg);
varg.vt = VT_BOOL;
varg.boolVal = TRUE;
hr = pPropertyBag->Write( g_wszWMVCInterlacedCodingEnabled, &varg );
if( FAILED( hr ) )
{
hr = E_VIDEO_INTERLACE_REJECTED;
break;
}
}
#endif //SUPPORT_INTERLACE
}
while( FALSE );
SAFERELEASE( pPropertyBag );
return ( hr );
}
//////////////////////////////////////////////////////////////////////////////
// a decent guess would be 0.4 bits per pixel
HRESULT DefaultVideoBitrate( AM_MEDIA_TYPE *pmt, double dFramesPerSec, int *pBitrate )
{
if( NULL == pmt || NULL == pBitrate )
{
return ( E_INVALIDARG );
}
if( NULL == pmt->pbFormat || pmt->cbFormat <= 0 )
{
return ( E_INVALIDARG );
}
if( FORMAT_VideoInfo == pmt->formattype )
{
VIDEOINFOHEADER *pvih = (VIDEOINFOHEADER*)pmt->pbFormat;
*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( FORMAT_VideoInfo2 == pmt->formattype )
{
VIDEOINFOHEADER2 *pvih = (VIDEOINFOHEADER2*)pmt->pbFormat;
*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 );
}
//////////////////////////////////////////////////////////////////////////////
HRESULT InitializeVideoEncoder( AM_MEDIA_TYPE *pmtInput,
VideoEncParams *pParams,
IMediaObject **ppDMO,
AM_MEDIA_TYPE *pmtOutput,
CHandlingMediaBuffer *pMediaBuffer )
{
HRESULT hr = S_OK;
DWORD cbInputBuffer = 0;
DWORD cbOutputBuffer = 0;
if( NULL == pmtInput || NULL == pParams || NULL == ppDMO )
{
return ( E_INVALIDARG );
}
#ifdef SUPPORT_INTERLACE
//
// Interlace encoding using IYUV or I420 at the input is not supported
//
if( NULL == pmtInput->pbFormat )
{
return ( E_INVALIDARG );
}
if( WMCFOURCC_IYUV == ((VIDEOINFOHEADER*)pmtInput->pbFormat)->bmiHeader.biCompression ||
WMCFOURCC_I420 == ((VIDEOINFOHEADER*)pmtInput->pbFormat)->bmiHeader.biCompression )
{
if( TRUE == pParams->fIsInterlaced )
{
return ( E_VIDEO_INTERLACE_REJECTED );
}
}
#endif //SUPPORT_INTERLACE
*ppDMO = NULL;
//
//check to see if the video bitrate has been set; if not calculate the default
//
if( pParams->nBitrate <= 0 )
{
hr = DefaultVideoBitrate( pmtInput, pParams->dFrameRate, &pParams->nBitrate );
if( FAILED( hr ) )
{
return ( hr );
}
if( pParams->nPeakBitrate <= 0 )
{
pParams->nPeakBitrate = 3 * pParams->nBitrate;
}
}
do
{
//
// Create the DMO Encoder
//
const CLSID *clsid=&CLSID_NULL;
char fcc[]="1234";memcpy(fcc,&pParams->dwTag,4);
switch (pParams->dwTag)
{
case WMCFOURCC_MSS1:
case WMCFOURCC_MSS2:
{
static const CLSID clsids[]={CLSID_CMSSCEncMediaObject2,CLSID_NULL};
clsid=clsids;
break;
}
case WMCFOURCC_WMV3:
case WMCFOURCC_WMVA:
case WMCFOURCC_WVC1:
case WMCFOURCC_WVP2:
{
static const CLSID clsids[]={CLSID_CWMV9EncMediaObject,CLSID_NULL};
clsid=clsids;
break;
}
case WMCFOURCC_MP43:
case WMCFOURCC_MP4S:
case WMCFOURCC_WMV1:
case WMCFOURCC_WMV2:
case WMCFOURCC_WMVP:
default:
{
static const CLSID clsids[]={CLSID_CWMVEncMediaObject2,CLSID_CWMVEncMediaObject2A,CLSID_NULL};
clsid=clsids;
break;
}
}
nextclsid:
hr = CoCreateInstance( *clsid,
NULL,
CLSCTX_INPROC_SERVER,
IID_IMediaObject,
(void**)ppDMO);
clsid++;
if( FAILED( hr ) )
if (*clsid==CLSID_NULL)
break;
else
goto nextclsid;
hr = SetVideoParams( *ppDMO, pParams );
if( FAILED( hr ) )
{
break;
}
hr = SetVideoTypes( *ppDMO, pmtInput, pParams, pmtOutput, &cbInputBuffer, &cbOutputBuffer );
if( FAILED( hr ) )
{
break;
}
#ifdef SUPPORT_INTERLACE
if( pParams->dwTag == WMCFOURCC_WMV3 && pParams->fIsInterlaced)
{
INSSBuffer3 *pINSSBuffer3 = NULL;
BYTE bType = WM_CT_INTERLACED;
hr = pMediaBuffer->QueryInterface( IID_INSSBuffer3, (void**)&pINSSBuffer3 );
if( FAILED( hr ) )
{
break;
}
pINSSBuffer3->SetProperty( WM_SampleExtension_ContentType,
&bType,
1 );
SAFERELEASE( pINSSBuffer3 );
}
#endif //SUPPORT_INTERLACE
}
while ( FALSE );
if( S_OK != hr )
{
SAFERELEASE( *ppDMO );
}
return ( hr );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -