IltmmWMProfile::AddStream Example for C
For complete code, refer to the CNVWM demo.
#include "amvideo.h"
void AddAudioStream(IltmmWMProfileManager *pManager, IltmmWMProfile *pProfile, int nStreamNum, int nFormatTag, long lPrefBitrate, long lSamplesPerSec, int nChannels, BOOL bWithVideo)
{
IltmmWMStreamConfig *pCodecFormat = NULL;
IltmmMediaTypeDisp *pMediaType = NULL;
WAVEFORMATEX wfex ;
BOOL bCandidate;
WAVEFORMATEX candidatewfex;
IltmmMediaTypeDisp *pCandidatemt = NULL;
IltmmMediaTypeDisp *pMt = NULL;
IltmmWMStreamConfig *pStream = NULL;
long codecs;
long formats;
long lSize;
BYTE *pArrayData = NULL;
HRESULT hr;
int codecindex;
int formatindex;
BSTR bstrData;
long diff;
BSTR stringData;
BSTR stringData2;
bCandidate = FALSE;
// get the number of audio codecs
IltmmWMProfileManager__getCodecInfoCount(pManager, /*MEDIATYPE_Audio*/L"{73647561-0000-0010-8000-00AA00389B71}", &codecs);
// search for matching codec
for(codecindex = 0; codecindex < codecs; codecindex++)
{
IltmmWMProfileManager__getCodecFormatCount(pManager, /*MEDIATYPE_Audio*/L"{73647561-0000-0010-8000-00AA00389B71}", codecindex, &formats);
for(formatindex = 0; formatindex < formats; formatindex++)
{
if(pCodecFormat)
{
IltmmWMStreamConfig_Release(pCodecFormat);
pCodecFormat = NULL;
}
hr = IltmmWMProfileManager__getCodecFormat(pManager, /*MEDIATYPE_Audio*/L"{73647561-0000-0010-8000-00AA00389B71}", codecindex, formatindex, &pCodecFormat);
if(pMediaType)
{
IltmmMediaTypeDisp_Release(pMediaType);
pMediaType = NULL;
}
hr = IltmmWMStreamConfig__getMediaType(pCodecFormat, &pMediaType);
IltmmMediaTypeDisp__get_FormatType(pMediaType, &bstrData);
if (!wcscmp(_wcsupr(bstrData), /*FORMAT_WaveFormatEx*/L"{05589F81-C356-11CE-BF01-00AA0055595A}"))
{
VARIANT var;
IltmmMediaTypeDisp__get_Format (pMediaType, &var);
SafeArrayAccessData(V_ARRAY(&var), (void**) &pArrayData);
lSize = var.parray->cbElements * var.parray->rgsabound->cElements;
CopyWaveFormatEx(&wfex, pArrayData);
SafeArrayUnaccessData(V_ARRAY(&var));
VariantClear(&var);
diff = (wfex.nAvgBytesPerSec * 8 - lPrefBitrate);
if(diff < 250 &&
diff > -250 &&
wfex.nSamplesPerSec == (unsigned int)lSamplesPerSec &&
wfex.nChannels == nChannels &&
wfex.wFormatTag == nFormatTag)
{
if(bCandidate)
{
if(bWithVideo)
{
//
// For audio/video configurations,
// we want to
// find the smaller blockalign.
// In this case,
// the blockalign is larger, so we want to
// use the old format.
//
if (wfex.nBlockAlign <= candidatewfex.nBlockAlign)
{
memcpy(&candidatewfex, &wfex, sizeof(WAVEFORMATEX));
pCandidatemt = pMediaType;
}
}
else
{
if (wfex.nBlockAlign >= candidatewfex.nBlockAlign)
{
memcpy(&candidatewfex, &wfex, sizeof(WAVEFORMATEX));
pCandidatemt = pMediaType;
}
}
}
else
{
bCandidate = TRUE;
memcpy(&candidatewfex, &wfex, sizeof(WAVEFORMATEX));
pCandidatemt = pMediaType;
}
}
}
}
}
if(bCandidate)
{
VARIANT var;
// modify the selected codec to support this bitrate and format
CoCreateInstance(&CLSID_ltmmMediaType,
NULL,
CLSCTX_INPROC_SERVER,
&IID_IltmmMediaTypeDisp,
(void**) &pMt);
IltmmMediaTypeDisp__put_Type(pMt, /*MEDIATYPE_Audio*/L"{73647561-0000-0010-8000-00AA00389B71}");
stringData = SysAllocStringLen(L"00000000", 150);
stringData2 = SysAllocStringLen(L"{", 150);
swprintf(stringData, L"%0 8X", 353);
wcscat(stringData2, stringData);
wcscat(stringData2, L"-0000-0010-8000-00AA00389B71}");
IltmmMediaTypeDisp__put_Subtype(pMt, stringData2);
IltmmMediaTypeDisp__put_FixedSizeSamples(pMt, TRUE);
IltmmMediaTypeDisp__put_TemporalCompression(pMt, FALSE);
IltmmMediaTypeDisp__put_SampleSize(pMt, candidatewfex.nBlockAlign);
IltmmMediaTypeDisp__put_FormatType(pMt, /*FORMAT_WaveFormatEx*/L"{05589F81-C356-11CE-BF01-00AA0055595A}");
IltmmMediaTypeDisp__get_Format (pCandidatemt, &var);
IltmmMediaTypeDisp_SetFormatData(pMt, -1, var);
IltmmWMProfile_CreateNewStream(pProfile, /*MEDIATYPE_Audio*/L"{73647561-0000-0010-8000-00AA00389B71}", &pStream);
IltmmWMStreamConfig__put_StreamNumber (pStream, nStreamNum);
IltmmWMStreamConfig__put_StreamName(pStream, L"Audio Stream");
IltmmWMStreamConfig__put_ConnectionName (pStream, L"Audio");
IltmmWMStreamConfig__put_Bitrate(pStream, candidatewfex.nAvgBytesPerSec * 8);
IltmmWMStreamConfig_SetMediaType (pStream, pMt);
IltmmWMProfile_AddStream(pProfile, pStream);
IltmmMediaTypeDisp_Release(pMt);
IltmmWMStreamConfig_Release(pStream);
IltmmMediaTypeDisp_Release(pCandidatemt);
}
if(pCodecFormat)
{
IltmmWMStreamConfig_Release(pCodecFormat);
pCodecFormat = NULL;
}
if(pMediaType)
{
IltmmMediaTypeDisp_Release(pMediaType);
pMediaType = NULL;
}
}
void AddVideoStream(IltmmWMProfileManager *pManager ,
IltmmWMProfile *pProfile,
int nStreamNum,
long lFourCC,
long lBitrate,
long lWidth,
long lHeight,
long lFps,
long lQuality,
long lSecperKey)
{
USES_CONVERSION;
IltmmWMStreamConfig *pCodecFormat = NULL;
IltmmMediaTypeDisp *pMediaType = NULL;
VIDEOINFOHEADER vih;
BOOL bCandidate;
VIDEOINFOHEADER candidatevih;
IltmmMediaTypeDisp *pCandidateMt = NULL;
IltmmWMStreamConfig *pCandidateStream = NULL;
long codecs;
long formats;
BSTR bstrData;
BYTE *pArrayData = NULL;
int codecindex;
int formatindex;
VARIANT var;
SAFEARRAY sa;
struct
{
LONG lowpart;
LONG highpart;
} Num64;
bCandidate = FALSE;
// get the number of video codecs
IltmmWMProfileManager__getCodecInfoCount(pManager, /*MEDIATYPE_Video*/ L"{73646976-0000-0010-8000-00AA00389B71}", &codecs);
// search for matching codec
for(codecindex = 0; codecindex < codecs; codecindex++)
{
IltmmWMProfileManager__getCodecFormatCount (pManager, /*MEDIATYPE_Video*/ L"{73646976-0000-0010-8000-00AA00389B71}", codecindex, &formats);
#ifdef DEBUG
IltmmWMProfileManager__getCodecName(pManager, /*MEDIATYPE_Video*/ L"{73646976-0000-0010-8000-00AA00389B71}", codecindex, &bstrData);
OutputDebugString(OLE2A(bstrData));
SysFreeString(bstrData);
#endif
for(formatindex = 0; formatindex < formats; formatindex++)
{
if(pCodecFormat)
{
IltmmWMStreamConfig_Release(pCodecFormat);
pCodecFormat = NULL;
}
IltmmWMProfileManager__getCodecFormat (pManager, /*MEDIATYPE_Video*/ L"{73646976-0000-0010-8000-00AA00389B71}", codecindex, formatindex, &pCodecFormat);
if(pMediaType)
{
IltmmMediaTypeDisp_Release(pMediaType);
pMediaType = NULL;
}
IltmmWMStreamConfig__getMediaType (pCodecFormat, &pMediaType);
#ifdef _DEBUG
IltmmWMProfileManager__getCodecFormatDesc(pManager, /*MEDIATYPE_Video*/ L"{73646976-0000-0010-8000-00AA00389B71}", codecindex, formatindex, &bstrData);
OutputDebugString(OLE2A(bstrData));
SysFreeString(bstrData);
#endif
IltmmMediaTypeDisp__get_FormatType (pMediaType, &bstrData);
if (!wcscmp(_wcsupr(bstrData), /*FORMAT_VideoInfo*/ L"{05589F80-C356-11CE-BF01-00AA0055595A}"))
{
VARIANT var;
IltmmMediaTypeDisp__get_Format(pMediaType, &var);
SafeArrayAccessData(V_ARRAY(&var), (void**) &pArrayData);
CopyVideoInfoHeader(&vih, pArrayData);
SafeArrayUnaccessData(V_ARRAY(&var));
VariantClear(&var);
if (vih.bmiHeader.biCompression == (unsigned long)lFourCC)
{
bCandidate = TRUE;
memcpy(&candidatevih, &vih, sizeof(VIDEOINFOHEADER));
pCandidateMt = pMediaType;
pCandidateStream = pCodecFormat;
}
}
}
}
if(bCandidate)
{
// modify the selected codec to support this bitrate and size
candidatevih.dwBitRate = lBitrate;
candidatevih.rcSource.right = lWidth;
candidatevih.rcSource.bottom = lHeight;
candidatevih.rcTarget.right = lWidth;
candidatevih.rcTarget.bottom = lHeight;
candidatevih.bmiHeader.biWidth = lWidth;
candidatevih.bmiHeader.biHeight = lHeight;
Num64.lowpart = (long)((long)(10000000.0 / lFps) % 0x10000);
Num64.highpart = (long)((10000000.0 / lFps) / 0x10000);
memcpy(&candidatevih.AvgTimePerFrame, &Num64, 8);
// pass the data to ltmmMediaType via SAFEARRAY
memset(&sa, 0, sizeof(sa));
sa.cbElements = sizeof(unsigned char);
sa.cDims = 1;
sa.fFeatures = (FADF_AUTO | FADF_FIXEDSIZE);
sa.pvData = (void*)&candidatevih;
sa.rgsabound[0].cElements = sizeof(VIDEOINFOHEADER);
VariantInit(&var);
V_VT(&var) = (VT_ARRAY | VT_UI1);
V_ARRAY(&var) = &sa;
IltmmMediaTypeDisp_SetFormatData(pCandidateMt, -1, var);
IltmmWMStreamConfig__put_Quality(pCandidateStream, lQuality);
IltmmWMStreamConfig__put_MaxKeyFrameSpacing(pCandidateStream, lSecperKey);
IltmmWMStreamConfig__put_StreamNumber(pCandidateStream, nStreamNum);
IltmmWMStreamConfig__put_StreamName(pCandidateStream, L"Video Stream");
IltmmWMStreamConfig__put_ConnectionName(pCandidateStream, L"Video");
IltmmWMStreamConfig__put_Bitrate (pCandidateStream, lBitrate);
IltmmWMStreamConfig__put_BufferWindow(pCandidateStream, -1);
IltmmWMStreamConfig_SetMediaType(pCandidateStream, pCandidateMt);
IltmmWMProfile_AddStream (pProfile, pCandidateStream);
IltmmWMProfile_ReconfigStream(pProfile, pCandidateStream);
IltmmMediaTypeDisp_Release(pCandidateMt);
IltmmWMStreamConfig_Release(pCandidateStream);
}
if(pCodecFormat)
{
IltmmWMStreamConfig_Release(pCodecFormat);
pCodecFormat = NULL;
}
if(pMediaType)
{
IltmmMediaTypeDisp_Release(pMediaType);
pMediaType = NULL;
}
}
void AddMutexObject(IltmmWMProfile *pProfile, int nBaseStream, int nStreamCount)
{
IltmmWMMutualExclusion *pExcl = NULL;
HRESULT hr;
int i;
// create an exclusion object
IltmmWMProfile_CreateNewMutualExclusion(pProfile, &pExcl);
// indicate that the streams differ by bit rate
// see CLSID_WMMUTEX_Bitrate in the WMSDK
IltmmWMMutualExclusion__put_Type(pExcl, L"{D6E22A01-35DA-11D1-9034-00A0C90349BE}");
// mark all the streams for mutual exclusion
for(i = 0; i < nStreamCount; i++)
{
hr = IltmmWMMutualExclusion_AddStream(pExcl, nBaseStream + i );
}
// assign the exclusion object to the profile
hr = IltmmWMProfile_AddMutualExclusion(pProfile, pExcl);
IltmmWMMutualExclusion_Release(pExcl);
}
void CreateCustomProfile(IltmmConvert *pConvert)
{
IltmmWMProfileManager *pManager = NULL;
IltmmWMProfile *pProfile = NULL;
int i;
// create an empty profile
CoCreateInstance(&CLSID_ltmmWMProfileManager, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmWMProfileManager, (void**) &pManager);
IltmmWMProfileManager__put_SystemProfileVersion(pManager, ltmmWMT_VER_8_0);
IltmmWMProfileManager_CreateEmptyProfile(pManager, ltmmWMT_VER_7_0, &pProfile);
IltmmWMProfile__put_Name(pProfile, L"Custom Profile");
IltmmWMProfile__put_Description(pProfile, L"Custom Profile Description");
// add a single audio stream
AddAudioStream( pManager, pProfile, 1, /*CODEC_AUDIO_MSAUDIO*/353, 8000, 8000, 1, TRUE);
// add 5 video streams with different bit rates
for(i = 0 ; i < 5; i++)
{
AddVideoStream( pManager, pProfile, 2 + i, /*CODEC_VIDEO_WMV1*/0x31564D57,
(1024 * 20) + i * 1024,
320,
240,
5 * (i + 1),
0,
8);
}
// mark all the video streams for mutual exclusion
AddMutexObject(pProfile, 2, 5);
// Assign the pProfile to a convert object
IltmmConvert__put_WMProfile(pConvert, pProfile);
// Free�
IltmmWMProfileManager_Release(pManager);
}
For complete code, refer to the CNVWM demo.
#include "amvideo.h" void CopyWaveFormatEx (WAVEFORMATEX *wfex, BYTE *pArrayData) { memcpy ( wfex, pArrayData, sizeof ( WAVEFORMATEX ) ) ; } void CopyVideoInfoHeader (VIDEOINFOHEADER *vih, BYTE *pArrayData) { memcpy ( vih, pArrayData, sizeof ( VIDEOINFOHEADER ) ) ; } void AddAudioStream(IltmmWMProfileManager *pManager, IltmmWMProfile *pProfile, int nStreamNum, int nFormatTag, long lPrefBitrate, long lSamplesPerSec, int nChannels, BOOL bWithVideo) { IltmmWMStreamConfig *pCodecFormat = NULL; IltmmMediaTypeDisp *pMediaType = NULL; WAVEFORMATEX wfex ; BOOL bCandidate; WAVEFORMATEX candidatewfex = {0}; IltmmMediaTypeDisp *pCandidatemt = NULL; IltmmMediaTypeDisp *pMt = NULL; IltmmWMStreamConfig *pStream = NULL; long codecs; long formats; long lSize; BYTE *pArrayData = NULL; HRESULT hr; int codecindex; int formatindex; BSTR bstrData; long diff; BSTR stringData; BSTR stringData2; bCandidate = FALSE; // get the number of audio codecs IltmmWMProfileManager_GetCodecInfoCount(pManager, /*MEDIATYPE_Audio*/L"{73647561-0000-0010-8000-00AA00389B71}", &codecs); // search for matching codec for(codecindex = 0; codecindex < codecs; codecindex++) { IltmmWMProfileManager_GetCodecFormatCount(pManager, /*MEDIATYPE_Audio*/L"{73647561-0000-0010-8000-00AA00389B71}", codecindex, &formats); for(formatindex = 0; formatindex < formats; formatindex++) { if(pCodecFormat) { IltmmWMStreamConfig_Release(pCodecFormat); pCodecFormat = NULL; } hr = IltmmWMProfileManager_GetCodecFormat(pManager, /*MEDIATYPE_Audio*/L"{73647561-0000-0010-8000-00AA00389B71}", codecindex, formatindex, &pCodecFormat); if(pMediaType) { IltmmMediaTypeDisp_Release(pMediaType); pMediaType = NULL; } hr = IltmmWMStreamConfig_GetMediaType(pCodecFormat, &pMediaType); IltmmMediaTypeDisp_get_FormatType(pMediaType, &bstrData); if (!wcscmp(_wcsupr(bstrData), /*FORMAT_WaveFormatEx*/L"{05589F81-C356-11CE-BF01-00AA0055595A}")) { VARIANT var; IltmmMediaTypeDisp_get_Format (pMediaType, &var); SafeArrayAccessData(V_ARRAY(&var), (void**) &pArrayData); lSize = var.parray->cbElements * var.parray->rgsabound->cElements; CopyWaveFormatEx(&wfex, pArrayData); SafeArrayUnaccessData(V_ARRAY(&var)); VariantClear(&var); diff = (wfex.nAvgBytesPerSec * 8 - lPrefBitrate); if(diff < 250 && diff > -250 && wfex.nSamplesPerSec == (unsigned int)lSamplesPerSec && wfex.nChannels == nChannels && wfex.wFormatTag == nFormatTag) { if(bCandidate) { if(bWithVideo) { // // For audio/video configurations, // we want to // find the smaller blockalign. // In this case, // the blockalign is larger, so we want to // use the old format. // if (wfex.nBlockAlign <= candidatewfex.nBlockAlign) { memcpy(&candidatewfex, &wfex, sizeof(WAVEFORMATEX)); pCandidatemt = pMediaType; } } else { if (wfex.nBlockAlign >= candidatewfex.nBlockAlign) { memcpy(&candidatewfex, &wfex, sizeof(WAVEFORMATEX)); pCandidatemt = pMediaType; } } } else { bCandidate = TRUE; memcpy(&candidatewfex, &wfex, sizeof(WAVEFORMATEX)); pCandidatemt = pMediaType; } } } } } if(bCandidate) { VARIANT var; // modify the selected codec to support this bitrate and format CoCreateInstance(&CLSID_ltmmMediaType, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmMediaTypeDisp, (void**) &pMt); IltmmMediaTypeDisp_put_Type(pMt, /*MEDIATYPE_Audio*/L"{73647561-0000-0010-8000-00AA00389B71}"); stringData = SysAllocStringLen(L"00000000", 150); stringData2 = SysAllocStringLen(L"{", 150); swprintf(stringData, 353, L"%0 8X"); wcscat(stringData2, stringData); wcscat(stringData2, L"-0000-0010-8000-00AA00389B71}"); IltmmMediaTypeDisp_put_Subtype(pMt, stringData2); IltmmMediaTypeDisp_put_FixedSizeSamples(pMt, TRUE); IltmmMediaTypeDisp_put_TemporalCompression(pMt, FALSE); IltmmMediaTypeDisp_put_SampleSize(pMt, candidatewfex.nBlockAlign); IltmmMediaTypeDisp_put_FormatType(pMt, /*FORMAT_WaveFormatEx*/L"{05589F81-C356-11CE-BF01-00AA0055595A}"); IltmmMediaTypeDisp_get_Format (pCandidatemt, &var); IltmmMediaTypeDisp_SetFormatData(pMt, -1, var); IltmmWMProfile_CreateNewStream(pProfile, /*MEDIATYPE_Audio*/L"{73647561-0000-0010-8000-00AA00389B71}", &pStream); IltmmWMStreamConfig_put_StreamNumber (pStream, nStreamNum); IltmmWMStreamConfig_put_StreamName(pStream, L"Audio Stream"); IltmmWMStreamConfig_put_ConnectionName (pStream, L"Audio"); IltmmWMStreamConfig_put_Bitrate(pStream, candidatewfex.nAvgBytesPerSec * 8); IltmmWMStreamConfig_SetMediaType (pStream, pMt); IltmmWMProfile_AddStream(pProfile, pStream); IltmmMediaTypeDisp_Release(pMt); IltmmWMStreamConfig_Release(pStream); IltmmMediaTypeDisp_Release(pCandidatemt); } if(pCodecFormat) { IltmmWMStreamConfig_Release(pCodecFormat); pCodecFormat = NULL; } if(pMediaType) { IltmmMediaTypeDisp_Release(pMediaType); pMediaType = NULL; } } void AddVideoStream ( IltmmWMProfileManager *pManager , IltmmWMProfile *pProfile, int nStreamNum, long lFourCC, long lBitrate, long lWidth, long lHeight, long lFps, long lQuality, long lSecperKey ) { IltmmWMStreamConfig *pCodecFormat = NULL; IltmmMediaTypeDisp *pMediaType = NULL; VIDEOINFOHEADER vih; BOOL bCandidate; VIDEOINFOHEADER candidatevih; IltmmMediaTypeDisp *pCandidateMt = NULL; IltmmWMStreamConfig *pCandidateStream = NULL; long codecs; long formats; BSTR bstrData; BYTE *pArrayData = NULL; int codecindex; int formatindex; VARIANT var; SAFEARRAY sa; struct { LONG lowpart; LONG highpart; } Num64; bCandidate = FALSE; // get the number of video codecs IltmmWMProfileManager_GetCodecInfoCount(pManager, /*MEDIATYPE_Video*/ L"{73646976-0000-0010-8000-00AA00389B71}", &codecs); // search for matching codec for(codecindex = 0; codecindex < codecs; codecindex++) { IltmmWMProfileManager_GetCodecFormatCount (pManager, /*MEDIATYPE_Video*/ L"{73646976-0000-0010-8000-00AA00389B71}", codecindex, &formats); #ifdef DEBUG IltmmWMProfileManager_GetCodecName(pManager, /*MEDIATYPE_Video*/ L"{73646976-0000-0010-8000-00AA00389B71}", codecindex, &bstrData); OutputDebugString(OLE2A(bstrData)); SysFreeString(bstrData); #endif for(formatindex = 0; formatindex < formats; formatindex++) { if(pCodecFormat) { IltmmWMStreamConfig_Release(pCodecFormat); pCodecFormat = NULL; } IltmmWMProfileManager_GetCodecFormat (pManager, /*MEDIATYPE_Video*/ L"{73646976-0000-0010-8000-00AA00389B71}", codecindex, formatindex, &pCodecFormat); if(pMediaType) { IltmmMediaTypeDisp_Release(pMediaType); pMediaType = NULL; } IltmmWMStreamConfig_GetMediaType (pCodecFormat, &pMediaType); IltmmMediaTypeDisp_get_FormatType (pMediaType, &bstrData); if (!wcscmp(_wcsupr(bstrData), /*FORMAT_VideoInfo*/ L"{05589F80-C356-11CE-BF01-00AA0055595A}")) { VARIANT var; IltmmMediaTypeDisp_get_Format(pMediaType, &var); SafeArrayAccessData(V_ARRAY(&var), (void**) &pArrayData); CopyVideoInfoHeader(&vih, pArrayData); SafeArrayUnaccessData(V_ARRAY(&var)); VariantClear(&var); if (vih.bmiHeader.biCompression == (unsigned long)lFourCC) { bCandidate = TRUE; memcpy(&candidatevih, &vih, sizeof(VIDEOINFOHEADER)); pCandidateMt = pMediaType; pCandidateStream = pCodecFormat; } } } } if(bCandidate) { // modify the selected codec to support this bitrate and size candidatevih.dwBitRate = lBitrate; candidatevih.rcSource.right = lWidth; candidatevih.rcSource.bottom = lHeight; candidatevih.rcTarget.right = lWidth; candidatevih.rcTarget.bottom = lHeight; candidatevih.bmiHeader.biWidth = lWidth; candidatevih.bmiHeader.biHeight = lHeight; Num64.lowpart = (long)((long)(10000000.0 / lFps) % 0x10000); Num64.highpart = (long)((10000000.0 / lFps) / 0x10000); memcpy(&candidatevih.AvgTimePerFrame, &Num64, 8); // pass the data to ltmmMediaType via SAFEARRAY memset(&sa, 0, sizeof(sa)); sa.cbElements = sizeof(unsigned char); sa.cDims = 1; sa.fFeatures = (FADF_AUTO | FADF_FIXEDSIZE); sa.pvData = (void*)&candidatevih; sa.rgsabound[0].cElements = sizeof(VIDEOINFOHEADER); VariantInit(&var); V_VT(&var) = (VT_ARRAY | VT_UI1); V_ARRAY(&var) = &sa; IltmmMediaTypeDisp_SetFormatData(pCandidateMt, -1, var); IltmmWMStreamConfig_put_Quality(pCandidateStream, lQuality); IltmmWMStreamConfig_put_MaxKeyFrameSpacing(pCandidateStream, lSecperKey); IltmmWMStreamConfig_put_StreamNumber(pCandidateStream, nStreamNum); IltmmWMStreamConfig_put_StreamName(pCandidateStream, L"Video Stream"); IltmmWMStreamConfig_put_ConnectionName(pCandidateStream, L"Video"); IltmmWMStreamConfig_put_Bitrate (pCandidateStream, lBitrate); IltmmWMStreamConfig_put_BufferWindow(pCandidateStream, -1); IltmmWMStreamConfig_SetMediaType(pCandidateStream, pCandidateMt); IltmmWMProfile_AddStream (pProfile, pCandidateStream); IltmmWMProfile_ReconfigStream(pProfile, pCandidateStream); IltmmMediaTypeDisp_Release(pCandidateMt); IltmmWMStreamConfig_Release(pCandidateStream); } if(pCodecFormat) { IltmmWMStreamConfig_Release(pCodecFormat); pCodecFormat = NULL; } if(pMediaType) { IltmmMediaTypeDisp_Release(pMediaType); pMediaType = NULL; } } void AddMutexObject(IltmmWMProfile *pProfile, int nBaseStream, int nStreamCount) { IltmmWMMutualExclusion *pExcl = NULL; HRESULT hr; int i; // create an exclusion object IltmmWMProfile_CreateNewMutualExclusion(pProfile, &pExcl); // indicate that the streams differ by bit rate // see CLSID_WMMUTEX_Bitrate in the WMSDK IltmmWMMutualExclusion_put_Type(pExcl, L"{D6E22A01-35DA-11D1-9034-00A0C90349BE}"); // mark all the streams for mutual exclusion for(i = 0; i < nStreamCount; i++) { hr = IltmmWMMutualExclusion_AddStream(pExcl, nBaseStream + i ); } // assign the exclusion object to the profile hr = IltmmWMProfile_AddMutualExclusion(pProfile, pExcl); IltmmWMMutualExclusion_Release(pExcl); } L_MULTIMEDIATEX_API void IltmmWMProfile_AddStream_Example (IltmmConvert *pConvert) { IltmmWMProfileManager *pManager = NULL; IltmmWMProfile *pProfile = NULL; int i; // create an empty profile CoCreateInstance(&CLSID_ltmmWMProfileManager, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmWMProfileManager, (void**) &pManager); IltmmWMProfileManager_put_SystemProfileVersion(pManager, ltmmWMT_VER_8_0); IltmmWMProfileManager_CreateEmptyProfile(pManager, ltmmWMT_VER_7_0, &pProfile); IltmmWMProfile_put_Name(pProfile, L"Custom Profile"); IltmmWMProfile_put_Description(pProfile, L"Custom Profile Description"); // add a single audio stream AddAudioStream( pManager, pProfile, 1, /*CODEC_AUDIO_MSAUDIO*/353, 8000, 8000, 1, TRUE); // add 5 video streams with different bit rates for(i = 0 ; i < 5; i++) { AddVideoStream( pManager, pProfile, 2 + i, /*CODEC_VIDEO_WMV1*/0x31564D57, (1024 * 20) + i * 1024, 320, 240, 5 * (i + 1), 0, 8); } // mark all the video streams for mutual exclusion AddMutexObject(pProfile, 2, 5); // Assign the pProfile to a convert object IltmmConvert_put_WMProfile(pConvert, pProfile); // Free… IltmmWMProfileManager_Release(pManager); }