📄 genprofile_lib.cpp
字号:
//
// The width must be on a byte boundry
//
if ( dwWidth * wBitsPerPixel % 8 != 0 )
{
return E_INVALIDARG;
}
//
// The width, height, and frames per second must all be non-zero
//
if ( 0 == dwWidth || 0 == dwHeight || 0 == dwFPS )
{
return E_INVALIDARG;
}
do
{
//
// Allocate space for the format data ( WMVIDEOINFOHEADER + pallete data )
//
dwFormatDataSize = sizeof( WMVIDEOINFOHEADER );
cbExpectedPostVIHDataSize = 0;
//
// If there are <= 8 bits / pixel, then there needs to be palette data following the WMVIDEOINFOHEADER
//
fPalettePresent = ( wBitsPerPixel <= 8 );
if ( fPalettePresent )
{
dwMaxColors = 1 << wBitsPerPixel;
cbExpectedPostVIHDataSize = sizeof( RGBQUAD ) * dwMaxColors;
}
//
// If the format uses bitfields, then make sure the data is following
//
fBitfieldsPresent = ( BI_BITFIELDS == dwFourCC );
if ( fBitfieldsPresent )
{
cbExpectedPostVIHDataSize = BITFIELD_DATA_SIZE;
}
if ( fPalettePresent || fBitfieldsPresent )
{
dwFormatDataSize += cbExpectedPostVIHDataSize;
if ( !pbPaletteData || ( cbPaletteDataSize != cbExpectedPostVIHDataSize ) )
{
hr = E_INVALIDARG;
break;
}
}
pbFormatData = new BYTE[ dwFormatDataSize ];
if ( !pbFormatData )
{
hr = E_OUTOFMEMORY;
break;
}
ZeroMemory( pbFormatData, dwFormatDataSize );
pbPostVIHData = pbFormatData + sizeof( WMVIDEOINFOHEADER );
pvihUncompressedVideo = (WMVIDEOINFOHEADER*) pbFormatData;
//
// Set up the local copy of the uncompressed media type
//
ZeroMemory( &mtUncompressedVideo, sizeof( mtUncompressedVideo ) );
mtUncompressedVideo.majortype = WMMEDIATYPE_Video;
mtUncompressedVideo.subtype = guidFormat;
mtUncompressedVideo.bFixedSizeSamples = TRUE;
mtUncompressedVideo.bTemporalCompression = FALSE;
mtUncompressedVideo.lSampleSize = wBitsPerPixel * dwWidth * dwHeight / 8;
mtUncompressedVideo.formattype = WMFORMAT_VideoInfo;
mtUncompressedVideo.pUnk = NULL;
mtUncompressedVideo.cbFormat = dwFormatDataSize;
mtUncompressedVideo.pbFormat = (BYTE*) pbFormatData;
//
// Configure the WMVIDEOINFOHEADER structure for uncompressed video
//
pvihUncompressedVideo->dwBitRate = mtUncompressedVideo.lSampleSize * dwFPS * 8;
pvihUncompressedVideo->rcSource.right = dwWidth;
pvihUncompressedVideo->rcSource.bottom = dwHeight;
pvihUncompressedVideo->rcTarget.right = dwWidth;
pvihUncompressedVideo->rcTarget.bottom = dwHeight;
pvihUncompressedVideo->bmiHeader.biSizeImage = mtUncompressedVideo.lSampleSize;
pvihUncompressedVideo->bmiHeader.biPlanes = 1;
pvihUncompressedVideo->bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
pvihUncompressedVideo->bmiHeader.biWidth = dwWidth;
pvihUncompressedVideo->bmiHeader.biHeight = dwHeight;
pvihUncompressedVideo->bmiHeader.biCompression = dwFourCC;
pvihUncompressedVideo->bmiHeader.biBitCount = wBitsPerPixel;
pvihUncompressedVideo->AvgTimePerFrame = ( (LONGLONG) 10000000 ) / ( (LONGLONG) dwFPS );
//
// Copy the palette information, if present
//
if ( ( fPalettePresent || fBitfieldsPresent ) && pbPaletteData )
{
memcpy( pbPostVIHData, pbPaletteData, cbExpectedPostVIHDataSize );
}
//
// Return a copy of the media type to the caller, since the media type is on the stack
//
hr = CopyMediaType( ppmtMediaType, &mtUncompressedVideo );
if ( FAILED( hr ) )
{
break;
}
}
while( FALSE );
SAFE_ARRAYDELETE( pbFormatData );
return( hr );
}
//------------------------------------------------------------------------------
// Name: CreateScriptMediaType()
// Desc: Initializes a WM_MEDIA_TYPE for script.
//------------------------------------------------------------------------------
STDMETHODIMP CreateScriptMediaType( WM_MEDIA_TYPE** ppmtMediaType )
{
HRESULT hr = S_OK;
WM_MEDIA_TYPE wmtMediaType;
WMSCRIPTFORMAT wsfScriptFormat;
assert( ppmtMediaType );
do
{
ZeroMemory( &wmtMediaType, sizeof( wmtMediaType ) );
//
// Configure media type
//
wmtMediaType.majortype = WMMEDIATYPE_Script;
wmtMediaType.subtype = GUID_NULL;
wmtMediaType.bFixedSizeSamples = FALSE;
wmtMediaType.bTemporalCompression = TRUE;
wmtMediaType.lSampleSize = 0;
wmtMediaType.formattype = WMFORMAT_Script;
wmtMediaType.cbFormat = sizeof( WMSCRIPTFORMAT );
wmtMediaType.pbFormat = (BYTE*) &wsfScriptFormat;
wsfScriptFormat.scriptType = WMSCRIPTTYPE_TwoStrings;
//
// Return a copy of the media type to the caller
//
hr = CopyMediaType( ppmtMediaType, &wmtMediaType );
if ( FAILED( hr ) )
{
break;
}
}
while ( FALSE );
return hr;
}
//------------------------------------------------------------------------------
// Name: CreateImageMediaType()
// Desc: Initializes a WM_MEDIA_TYPE for image.
//------------------------------------------------------------------------------
STDMETHODIMP CreateImageMediaType( WM_MEDIA_TYPE** ppmtMediaType,
DWORD dwWidth,
DWORD dwHeight,
DWORD dwBitrate )
{
static const WORD BIT_COUNT = 24;
HRESULT hr = S_OK;
WM_MEDIA_TYPE wmtMediaType;
WMVIDEOINFOHEADER vihVideoInfo;
do
{
ZeroMemory( &wmtMediaType, sizeof( wmtMediaType ) );
//
// Set up the WM_MEDIA_TYPE structure
//
wmtMediaType.majortype = WMMEDIATYPE_Image;
wmtMediaType.subtype = WMMEDIASUBTYPE_RGB24;
wmtMediaType.bFixedSizeSamples = FALSE;
wmtMediaType.bTemporalCompression = FALSE;
wmtMediaType.lSampleSize = 0;
wmtMediaType.bFixedSizeSamples = FALSE;
wmtMediaType.bTemporalCompression = FALSE;
wmtMediaType.lSampleSize = 0;
wmtMediaType.formattype = WMFORMAT_VideoInfo;
wmtMediaType.pUnk = NULL;
wmtMediaType.cbFormat = sizeof( WMVIDEOINFOHEADER );
wmtMediaType.pbFormat = (BYTE*) &vihVideoInfo;
//
// Set up the WMVIDEOINFOHEADER structure
//
ZeroMemory( &vihVideoInfo, sizeof( vihVideoInfo ) );
vihVideoInfo.rcSource.left = 0;
vihVideoInfo.rcSource.top = 0;
vihVideoInfo.rcSource.bottom = dwHeight;
vihVideoInfo.rcSource.right = dwWidth;
vihVideoInfo.rcTarget = vihVideoInfo.rcSource;
vihVideoInfo.dwBitRate = dwBitrate;
vihVideoInfo.dwBitErrorRate = 0;
vihVideoInfo.AvgTimePerFrame = 0;
vihVideoInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
vihVideoInfo.bmiHeader.biWidth = dwWidth;
vihVideoInfo.bmiHeader.biHeight = dwHeight;
vihVideoInfo.bmiHeader.biPlanes = 1;
vihVideoInfo.bmiHeader.biBitCount = BIT_COUNT;
vihVideoInfo.bmiHeader.biCompression = BI_RGB;
vihVideoInfo.bmiHeader.biSizeImage = ( dwHeight * dwWidth * vihVideoInfo.bmiHeader.biBitCount ) / 8;
vihVideoInfo.bmiHeader.biXPelsPerMeter = 0;
vihVideoInfo.bmiHeader.biYPelsPerMeter = 0;
vihVideoInfo.bmiHeader.biClrUsed = 0;
vihVideoInfo.bmiHeader.biClrImportant = 0;
//
// Return a copy of the media type to the caller
//
hr = CopyMediaType( ppmtMediaType, &wmtMediaType );
if ( FAILED( hr ) )
{
break;
}
}
while ( FALSE );
return hr;
}
//------------------------------------------------------------------------------
// Name: CreateWebMediaType()
// Desc: Initializes a WM_MEDIA_TYPE for Web media.
//------------------------------------------------------------------------------
STDMETHODIMP CreateWebMediaType( WM_MEDIA_TYPE** ppmtMediaType )
{
HRESULT hr = S_OK;
WM_MEDIA_TYPE wmtMediaType;
WMT_WEBSTREAM_FORMAT wwfWebFormat;
do
{
ZeroMemory( &wmtMediaType, sizeof( wmtMediaType ) );
//
// Configure media type
//
wmtMediaType.majortype = WMMEDIATYPE_FileTransfer;
wmtMediaType.subtype = WMMEDIASUBTYPE_WebStream;
wmtMediaType.bFixedSizeSamples = FALSE;
wmtMediaType.bTemporalCompression = TRUE;
wmtMediaType.lSampleSize = 0;
wmtMediaType.formattype = WMFORMAT_WebStream;
wmtMediaType.pUnk = NULL;
wmtMediaType.cbFormat = sizeof( WMT_WEBSTREAM_FORMAT );
wmtMediaType.pbFormat = (BYTE*) &wwfWebFormat;
ZeroMemory( &wwfWebFormat, sizeof( wwfWebFormat ) );
wwfWebFormat.cbSize = sizeof( WMT_WEBSTREAM_FORMAT );
wwfWebFormat.cbSampleHeaderFixedData = sizeof( WMT_WEBSTREAM_SAMPLE_HEADER );
wwfWebFormat.wVersion = 1;
wwfWebFormat.wReserved = 0;
//
// Return a copy of the media type to the caller
//
hr = CopyMediaType( ppmtMediaType, &wmtMediaType );
if ( FAILED( hr ) )
{
break;
}
}
while ( FALSE );
return hr;
}
//------------------------------------------------------------------------------
// Name: CreateFileMediaType()
// Desc: Initializes a WM_MEDIA_TYPE for file transfer.
//------------------------------------------------------------------------------
STDMETHODIMP CreateFileMediaType( WM_MEDIA_TYPE** ppmtMediaType )
{
HRESULT hr = S_OK;
WM_MEDIA_TYPE wmtMediaType;
do
{
ZeroMemory( &wmtMediaType, sizeof( wmtMediaType ) );
//
// Configure media type
//
wmtMediaType.majortype = WMMEDIATYPE_FileTransfer;
wmtMediaType.subtype = GUID_NULL;
wmtMediaType.bFixedSizeSamples = FALSE;
wmtMediaType.bTemporalCompression = FALSE;
wmtMediaType.lSampleSize = 0;
//
// Return a copy of the media type to the caller
//
hr = CopyMediaType( ppmtMediaType, &wmtMediaType );
if ( FAILED( hr ) )
{
break;
}
}
while ( FALSE );
return hr;
}
//------------------------------------------------------------------------------
// Name: CreateVideoStream()
// Desc: Creates a video stream and returns its configuration object.
//------------------------------------------------------------------------------
STDMETHODIMP CreateVideoStream( Twmv9dll *dll,
IWMStreamConfig** ppStreamConfig,
IWMCodecInfo3* pCodecInfo3,
IWMProfile *pProfile,
DWORD dwCodecIndex,
DWORD dwBitrate,
DWORD dwBufferWindow,
DWORD dwWidth,
DWORD dwHeight,
double dFPS,
DWORD dwQuality,
DWORD dwSecPerKey,
BOOL fIsVBR,
VIDEO_VBR_MODE vbrMode,
DWORD dwVBRQuality,
DWORD dwMaxBitrate,
DWORD dwMaxBufferWindow,
LCID dwLanguage )
{
HRESULT hr = S_OK;
IWMStreamConfig* pStreamConfig = NULL;
IWMPropertyVault* pPropertyVault = NULL;
WM_MEDIA_TYPE* pMediaType = NULL;
IWMVideoMediaProps* pVideoMediaProps = NULL;
DWORD dwNumberOfPasses;
if ( !ppStreamConfig )
{
return E_POINTER;
}
if ( !pProfile )
{
return E_INVALIDARG;
}
//
// pCodecInfo3 is allowed to be NULL, since CreateVideoMediatype calls EnsureIWMCodecInfo3
//
do
{
switch( vbrMode )
{
case VBR_OFF:
dwNumberOfPasses = 0;
break;
case VBR_QUALITYBASED:
dwNumberOfPasses = 1;
break;
case VBR_CONSTRAINED:
dwNumberOfPasses = 2;
break;
case VBR_UNCONSTRAINED:
dwNumberOfPasses = 2;
break;
default:
hr = E_FAIL;
break;
}
if ( FAILED( hr ) )
{
break;
}
//
// Create the video stream
//
hr = pProfile->CreateNewStream( WMMEDIATYPE_Video, &pStreamConfig );
if ( FAILED( hr ) )
{
break;
}
assert( pStreamConfig );
//
// Configure the new video stream
//
hr = pStreamConfig->SetBitrate( dwBitrate );
if ( FAILED( hr ) )
{
break;
}
hr = pStreamConfig->SetBufferWindow( dwBufferWindow );
if ( FAILED( hr ) )
{
break;
}
//
// Set the media type for the stream
//
hr = CreateVideoMediaType( dll,
&pMediaType,
pCodecInfo3,
dwCodecIndex,
dFPS,
dwWidth,
dwHeight,
dwBitrate,
fIsVBR,
dwNumberOfPasses );
if ( FAILED( hr ) )
{
break;
}
assert( pMediaType );
hr = pStreamConfig->QueryInterface( IID_IWMVideoMediaProps, (void**) &pVideoMediaProps );
if ( FAILED( hr ) )
{
break;
}
assert( pVideoMediaProps );
hr = pVideoMediaProps->SetMediaType( pMediaType );
if ( FAILED( hr ) )
{
break;
}
//
// Set quality and MaxKeyFrameSpacing on the IWMVideoMediaProps object
//
hr = pVideoMediaProps->SetQuality( dwQuality );
if ( FAILED( hr ) )
{
break;
}
hr = pVideoMediaProps->SetMaxKeyFrameSpacing( (LONGLONG) dwSecPerKey * 10000000 );
if ( FAILED( hr ) )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -