📄 genprofile_lib.cpp
字号:
//*****************************************************************************//// Microsoft Windows Media// Copyright (C) Microsoft Corporation. All rights reserved.//// FileName: GenProfile_lib.cpp//// Abstract: The implementation for the GenProfile static library.////*****************************************************************************#include "stdafx.h"#include <assert.h>#include "GenProfile_lib.h"#include "Twmv9dll.h"#define SAFE_RELEASE( x ) \ if ( x ) \ { \ x->Release(); \ x = NULL; \ }#define SAFE_ADDREF( x ) \ if ( x ) \ { \ x->AddRef(); \ }#define SAFE_DELETE( x ) \ if ( x ) \ { \ delete x; \ x = NULL; \ }#define SAFE_ARRAYDELETE( x ) \ if ( x ) \ { \ delete[] x; \ x = NULL; \ }#define SAFE_SYSFREESTRING( x ) \ if ( x ) \ { \ SysFreeString( x ); \ x = NULL; \ }#define SAFE_CLOSEHANDLE( x ) \ if ( x && INVALID_HANDLE_VALUE != x ) \ { \ CloseHandle( x ); \ x = NULL; \ }struct PIXEL_FORMAT{ const GUID* guidFormat; DWORD dwFourCC; WORD wBitsPerPixel;};PIXEL_FORMAT PixelFormats[] ={ { &WMMEDIASUBTYPE_RGB555, BI_RGB, 16 }, { &WMMEDIASUBTYPE_RGB24, BI_RGB, 24 }, { &WMMEDIASUBTYPE_RGB32, BI_RGB, 32 }, { &WMMEDIASUBTYPE_I420, 0x30323449, 12 }, { &WMMEDIASUBTYPE_IYUV, 0x56555949, 12 }, { &WMMEDIASUBTYPE_YV12, 0x32315659, 12 }, { &WMMEDIASUBTYPE_YUY2, 0x32595559, 16 }, { &WMMEDIASUBTYPE_UYVY, 0x59565955, 16 }, { &WMMEDIASUBTYPE_YVYU, 0x55595659, 16 }};DWORD WaveFrequency[] ={ 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000};//------------------------------------------------------------------------------// Name: CopyMediaType()// Desc: Allocates memory for a WM_MEDIA_TYPE and its format data and// copies an existing media type into it.//------------------------------------------------------------------------------STDMETHODIMP CopyMediaType( WM_MEDIA_TYPE** ppmtDestination, WM_MEDIA_TYPE* pmtSource ){ if ( !ppmtDestination ) { return E_POINTER; } if ( !pmtSource ) { return E_NOTIMPL; } // // Create enough space for the media type and its format data // *ppmtDestination = (WM_MEDIA_TYPE*) new BYTE[ sizeof( WM_MEDIA_TYPE ) + pmtSource->cbFormat ]; if ( !*ppmtDestination) { return E_OUTOFMEMORY; } // // Copy the media type and the format data // memcpy( *ppmtDestination, pmtSource, sizeof( WM_MEDIA_TYPE ) ); (*ppmtDestination)->pbFormat = ( ((BYTE*) *ppmtDestination) + sizeof( WM_MEDIA_TYPE ) ); // Format data is immediately after media type memcpy( (*ppmtDestination)->pbFormat, pmtSource->pbFormat, pmtSource->cbFormat ); return S_OK;}//------------------------------------------------------------------------------// Name: EnsureIWMCodecInfo3()// Desc: Creates an IWMCodecInfo3 interface if none exists, and ensures// an outstanding reference either way. This way the IWMCodecInfo3// object is guaranteed to exist and isn't released too many times.//------------------------------------------------------------------------------STDMETHODIMP EnsureIWMCodecInfo3( Twmv9dll *dll,IWMCodecInfo3** ppCodecInfo3 ){ HRESULT hr = S_OK; if ( !ppCodecInfo3 ) { return E_POINTER; } do { if ( !*ppCodecInfo3 ) { // // Create a new IWMCodecInfo3 object // IWMProfileManager* pProfileManager; hr = dll->WMCreateProfileManager( &pProfileManager ); if ( FAILED( hr ) ) { break; } assert( pProfileManager ); hr = pProfileManager->QueryInterface( IID_IWMCodecInfo3, (void**) ppCodecInfo3 ); SAFE_RELEASE( pProfileManager ); if ( FAILED( hr ) ) { break; } } else { // // Add a reference to the existing object, so that it won't be destroyed during cleanup // SAFE_ADDREF( (*ppCodecInfo3) ); } assert( *ppCodecInfo3 ); // // It should now not matter if the IWMCodecInfo3 was just created or was passed in // } while ( FALSE ); return hr;}//------------------------------------------------------------------------------// Name: SetCodecVBRSettings()// Desc: Enables VBR with the specified number of passes, or disables it.//------------------------------------------------------------------------------STDMETHODIMP SetCodecVBRSettings( IWMCodecInfo3* pCodecInfo3, GUID guidCodecType, DWORD dwCodecIndex, BOOL fIsVBR, DWORD dwVBRPasses ){ HRESULT hr; if ( !pCodecInfo3 ) { return E_INVALIDARG; } do { // // Configure the codec to use or not use VBR as requested // hr = pCodecInfo3->SetCodecEnumerationSetting( guidCodecType, dwCodecIndex, g_wszVBREnabled, WMT_TYPE_BOOL, (BYTE*) &fIsVBR, sizeof( BOOL ) ); if ( FAILED( hr ) ) { // // If VBR is requested, then it's a problem, but otherwise the codec may just not support VBR // if ( ( !fIsVBR ) && ( NS_E_UNSUPPORTED_PROPERTY == hr ) ) { hr = S_OK; } else { break; } } if ( fIsVBR ) { hr = pCodecInfo3->SetCodecEnumerationSetting( guidCodecType, dwCodecIndex, g_wszNumPasses, WMT_TYPE_DWORD, (BYTE*) &dwVBRPasses, sizeof( DWORD ) ); if ( FAILED( hr ) ) { break; } } } while ( FALSE ); return hr;}//------------------------------------------------------------------------------// Name: SetStreamLanguage()// Desc: Sets the language in the stream configuration.//------------------------------------------------------------------------------/*STDMETHODIMP SetStreamLanguage( IWMStreamConfig * pStreamConfig, LCID dwLanguage ){HRESULT hr = S_OK;IWMStreamConfig3 * pStreamConfig3 = NULL;IMultiLanguage * pMLang = NULL;BSTR bstrLanguage = NULL;do{hr = CoCreateInstance( CLSID_CMultiLanguage,NULL,CLSCTX_ALL,IID_IMultiLanguage,(VOID **) &pMLang );if( FAILED( hr ) ){break;}hr = pMLang->GetRfc1766FromLcid( dwLanguage, &bstrLanguage );if( FAILED( hr ) ){break;}hr = pStreamConfig->QueryInterface( IID_IWMStreamConfig3, (void**)&pStreamConfig3 );if( FAILED( hr ) ){break;}hr = pStreamConfig3->SetLanguage( bstrLanguage );if( FAILED( hr ) ){break;}}while (FALSE);SAFE_RELEASE( pMLang );SAFE_RELEASE( pStreamConfig3 );if ( !bstrLanguage ){SysFreeString( bstrLanguage );}return hr;}*//*** Functions that create media types for the various stream types*///------------------------------------------------------------------------------// Name: CreateUncompressedAudioMediaType()// Desc: Initializes a WM_MEDIA_TYPE for uncompressed audio.//------------------------------------------------------------------------------STDMETHODIMP CreateUncompressedAudioMediaType( WM_MEDIA_TYPE** ppmtMediaType, DWORD dwSamplesPerSecond, WORD wNumChannels, WORD wBitsPerSample ){ HRESULT hr = S_OK; WM_MEDIA_TYPE mtUncompressedAudio; WAVEFORMATEX wfxUncompressedAudio; if ( !ppmtMediaType ) { return E_POINTER; } // // pCodecInfo3 is allowed to be NULL, since CreateMediatypeForFormat calls EnsureIWMCodecInfo3 // do { // // Setup the local copy of the uncompressed media type // ZeroMemory( &mtUncompressedAudio, sizeof( mtUncompressedAudio ) ); mtUncompressedAudio.majortype = WMMEDIATYPE_Audio; mtUncompressedAudio.subtype = WMMEDIASUBTYPE_PCM; mtUncompressedAudio.bFixedSizeSamples = TRUE; mtUncompressedAudio.bTemporalCompression = FALSE; mtUncompressedAudio.lSampleSize = wNumChannels * wBitsPerSample / 8; mtUncompressedAudio.formattype = WMFORMAT_WaveFormatEx; mtUncompressedAudio.pUnk = NULL; mtUncompressedAudio.cbFormat = sizeof( WAVEFORMATEX ); mtUncompressedAudio.pbFormat = (BYTE*) &wfxUncompressedAudio; // // Configure the WAVEFORMATEX structure for the uncompressed audio // ZeroMemory( &wfxUncompressedAudio, sizeof( wfxUncompressedAudio ) ); wfxUncompressedAudio.wFormatTag = 1; wfxUncompressedAudio.nChannels = wNumChannels; wfxUncompressedAudio.nSamplesPerSec = dwSamplesPerSecond; wfxUncompressedAudio.nAvgBytesPerSec = dwSamplesPerSecond * ( wNumChannels * wBitsPerSample / 8 ); wfxUncompressedAudio.nBlockAlign = wNumChannels * wBitsPerSample / 8; wfxUncompressedAudio.wBitsPerSample = wBitsPerSample; wfxUncompressedAudio.cbSize = sizeof( WAVEFORMATEX ); // // Return a copy of the media type to the caller, since the mediatype is on the stack // hr = CopyMediaType( ppmtMediaType, &mtUncompressedAudio ); if ( FAILED( hr ) ) { break; } } while( FALSE ); return( hr );}//------------------------------------------------------------------------------// Name: CreateVideoMediaType()// Desc: Initializes a WM_MEDIA_TYPE for video.//------------------------------------------------------------------------------STDMETHODIMP CreateVideoMediaType( Twmv9dll *dll, WM_MEDIA_TYPE** ppmtMediaType, IWMCodecInfo3* pCodecInfo3, DWORD dwCodecIndex, double dFPS, DWORD dwWidth, DWORD dwHeight, DWORD dwBitrate, BOOL fIsVBR, DWORD dwNumberOfPasses ){ HRESULT hr = S_OK; WM_MEDIA_TYPE *pMediaType = NULL; WMVIDEOINFOHEADER *pVIH; if ( !ppmtMediaType ) { return E_POINTER; } // // pCodecInfo3 is allowed to be NULL, since CreateMediatypeForFormat calls EnsureIWMCodecInfo3 // do { // // Get the mediatype for the codec // hr = CreateMediatypeForFormat( dll, &pMediaType, pCodecInfo3, NULL, WMMEDIATYPE_Video, dwCodecIndex, 0, fIsVBR, dwNumberOfPasses ); if( FAILED( hr ) ) { break; } assert( pMediaType ); // // Configure the WMVIDEOINFOHEADER structure of the media type // pVIH = (WMVIDEOINFOHEADER*) pMediaType->pbFormat; pVIH->dwBitRate = dwBitrate; pVIH->rcSource.right = dwWidth; pVIH->rcSource.bottom = dwHeight; pVIH->rcTarget.right = dwWidth; pVIH->rcTarget.bottom = dwHeight; pVIH->bmiHeader.biWidth = dwWidth; pVIH->bmiHeader.biHeight = dwHeight; pVIH->AvgTimePerFrame = ( (LONGLONG) 10000000 ) / ( (LONGLONG) dFPS ); // // Return a copy of the media type to the caller // hr = CopyMediaType( ppmtMediaType, pMediaType ); if ( FAILED( hr ) ) { break; } } while( FALSE ); SAFE_ARRAYDELETE( pMediaType ); return( hr );}//------------------------------------------------------------------------------// Name: CreateUncompressedVideoMediaType()// Desc: Initializes a WM_MEDIA_TYPE for uncompressed video.//------------------------------------------------------------------------------STDMETHODIMP CreateUncompressedVideoMediaType( WM_MEDIA_TYPE** ppmtMediaType, GUID guidFormat, DWORD dwFourCC, WORD wBitsPerPixel, BYTE* pbPaletteData, DWORD cbPaletteDataSize, DWORD dwFPS, DWORD dwWidth, DWORD dwHeight ){ const DWORD BITFIELD_DATA_SIZE = sizeof( RGBQUAD ) * 3; HRESULT hr; WM_MEDIA_TYPE mtUncompressedVideo; WMVIDEOINFOHEADER* pvihUncompressedVideo; BYTE* pbFormatData = NULL; DWORD dwFormatDataSize; DWORD dwMaxColors; BOOL fPalettePresent; BYTE* pbPostVIHData; DWORD cbExpectedPostVIHDataSize; BOOL fBitfieldsPresent; if ( !ppmtMediaType ) { return E_POINTER; } // // pCodecInfo3 is allowed to be NULL, since CreateMediatypeForFormat calls EnsureIWMCodecInfo3 //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -