The following code can be used to create a file with two audio streams that are mutually exclusive:
BSTR bstr;CString fname;HRESULT hr;USES_CONVERSION;if( m_pConvert == NULL )return;// Create the profile manager object:hr = CoCreateInstance(CLSID_ltmmWMProfileManager, NULL, CLSCTX_INPROC_SERVER, IID_IltmmWMProfileManager, (void**) &m_pProfMan);// create an empty profile:hr = m_pProfMan->CreateEmptyProfile (ltmmWMT_VER_7_0, &m_pProf);// Set the profile name and descriptionhr = m_pProf->put_Name (L"Mutex Stream_test");hr = m_pProf->put_Description (L"Example code");// add 2 audio streams with different bitrateshr = AddAudioStream(mgr, profile, 1, CODEC_AUDIO_MSAUDIO, 8000, 8000, 1, FALSE);hr = AddAudioStream(mgr, profile, 2, CODEC_AUDIO_MSAUDIO, 16000, 16000, 1, FALSE);// make them mutually exclusivehr = AddMutexObject(profile, 1, 2);// add the profile to the convert objecthr = m_pConvert->put_WMProfile (m_pProf);m_pProf->Release();m_pProfMan->Release();//set the target formathr = m_pConvert->put_TargetFormat ( ltmmConvert_TargetFormat_Asf_Compressor_Mux );// set the source file name; the source file contains multiple audio streams:hr = m_pConvert->put_SourceFile (L"London.avi");// set the output file name:hr = m_pConvert->put_TargetFile ("London.asf");// do the conversionhr = m_pConvert->StartConvert ();HRESULT AddVideoStream( IltmmWMProfileManager* mgr,IltmmWMProfile* profile,UINT nStreamNum,DWORD dwFourCC,ULONG nBitRate,ULONG nWidth,ULONG nHeight,ULONG nFPS,ULONG nQuality,ULONG nSecPerKey ){long cCodecs;IltmmWMStreamConfig* stream = NULL;IltmmMediaTypeDisp* pmt = NULL;VIDEOINFOHEADER *pVIH = NULL;VARIANT varFormat;VariantInit(&varFormat);// get MEDIATYPE_Video codec countBSTR bstr = ::SysAllocString(ltmmMEDIATYPE_Video);HRESULT hr = mgr->GetCodecInfoCount(bstr, &cCodecs);::SysFreeString(bstr);// search for matching codecfor(long i = 0; !stream && i < cCodecs; i++){long cFormats;// get MEDIATYPE_Video codec format countBSTR bstr = ::SysAllocString(ltmmMEDIATYPE_Video);HRESULT hr = mgr->GetCodecFormatCount(bstr, i, &cFormats);::SysFreeString(bstr);for(long j = 0; j < cFormats; j++){// get MEDIATYPE_Video stream config interfacebstr = ::SysAllocString(ltmmMEDIATYPE_Video);hr = mgr->GetCodecFormat(bstr, i, j, &stream);::SysFreeString(bstr);if(SUCCEEDED(hr)){// get this format's media typehr = stream->GetMediaType (&pmt);if(SUCCEEDED(hr)){hr = pmt->get_FormatType(&bstr);if(SUCCEEDED(hr)){// only check FORMAT_VideoInfo formatsif(!wcsicmp(bstr, ltmmFORMAT_VideoInfo)){pmt->GetFormatData(-1, &varFormat);SafeArrayAccessData(V_ARRAY(&varFormat), (void**) &pVIH);if(pVIH->bmiHeader.biCompression == dwFourCC){::SysFreeString(bstr);break;}SafeArrayUnaccessData(V_ARRAY(&varFormat));VariantClear(&varFormat);}::SysFreeString(bstr);}pmt->Release();pmt = NULL;}stream->Release();stream = NULL;}}}// return an error, if we didn't find a good candidateif(!stream)return E_FAIL;pVIH->dwBitRate = nBitRate;pVIH->rcSource.right = nWidth;pVIH->rcSource.bottom = nHeight;pVIH->rcTarget.right = nWidth;pVIH->rcTarget.bottom = nHeight;pVIH->bmiHeader.biWidth = nWidth;pVIH->bmiHeader.biHeight = nHeight;pVIH->AvgTimePerFrame = ((LONGLONG) 10000000 ) / ((LONGLONG) nFPS );pmt->SetFormatData(-1, varFormat);hr = stream->put_Quality ( nQuality );hr = stream->put_MaxKeyFrameSpacing ((double) nSecPerKey);stream->put_StreamNumber (nStreamNum);bstr = ::SysAllocString(L"Video Stream");stream->put_StreamName (bstr);::SysFreeString(bstr);bstr = ::SysAllocString(L"Video");stream->put_ConnectionName(bstr);::SysFreeString(bstr);stream->put_Bitrate(nBitRate);stream->SetMediaType (pmt);profile->AddStream (stream);stream->Release();pmt->Release();SafeArrayUnaccessData(V_ARRAY(&varFormat));VariantClear(&varFormat);return S_OK;}HRESULT AddAudioStream(IltmmWMProfileManager* mgr,IltmmWMProfile* profile,UINT nStreamNum,UINT nFormatTag,ULONG nBitRate,ULONG nSamplesPerSec,UINT nChannels,BOOL bVideo){long cCodecs;VARIANT varSave;VariantInit(&varSave);// get MEDIATYPE_Audio codec countBSTR bstr = ::SysAllocString(ltmmMEDIATYPE_Audio);HRESULT hr = mgr->GetCodecInfoCount (bstr, &cCodecs);::SysFreeString(bstr);// search for matching codecfor(long i = 0; i < cCodecs; i++){long cFormats;// get MEDIATYPE_Audio codec format countBSTR bstr = ::SysAllocString(ltmmMEDIATYPE_Audio);HRESULT hr = mgr->GetCodecFormatCount (bstr, i, &cFormats);::SysFreeString(bstr);for(long j = 0; j < cFormats; j++){// get MEDIATYPE_Audio stream config interfaceIltmmWMStreamConfig* format;bstr = ::SysAllocString(ltmmMEDIATYPE_Audio);hr = mgr->GetCodecFormat (bstr, i, j, &format);::SysFreeString(bstr);if(SUCCEEDED(hr)){// get this format's media typeIltmmMediaTypeDisp* pmt;hr = format->GetMediaType (&pmt);if(SUCCEEDED(hr)){hr = pmt->get_FormatType(&bstr);if(SUCCEEDED(hr)){// only check FORMAT_WaveFormatEx formatsif(!wcsicmp(bstr, ltmmFORMAT_WaveFormatEx)){VARIANT var;VariantInit(&var);pmt->get_Format(&var);WAVEFORMATEX *pWfx;SafeArrayAccessData(V_ARRAY(&var), (void**) &pWfx);// does this format look like a good candidatelong nDiff = (long) (pWfx->nAvgBytesPerSec * 8 - nBitRate);if( nDiff < 250 &&nDiff > -250 &&pWfx->nSamplesPerSec == nSamplesPerSec &&pWfx->nChannels == nChannels &&pWfx->wFormatTag == nFormatTag){if( V_VT(&varSave) != VT_EMPTY ){WAVEFORMATEX *pSaveWFX;SafeArrayAccessData(V_ARRAY(&varSave), (void**) &pSaveWFX);if(bVideo){//// For audio/video configurations, we want to// find the smaller nBlockAlign. In this case,// the nBlockAlign is larger, so we want to// use the old format.//if( pWfx->nBlockAlign <= pSaveWFX->nBlockAlign ){SafeArrayUnaccessData(V_ARRAY(&varSave));VariantClear(&varSave);VariantCopy(&varSave, &var);}}else{// otherwise, we want the larger nBlockAlignif( pWfx->nBlockAlign >= pSaveWFX->nBlockAlign ){SafeArrayUnaccessData(V_ARRAY(&varSave));VariantClear(&varSave);VariantCopy(&varSave, &var);}}}else{VariantClear(&varSave);VariantCopy(&varSave, &var);}}SafeArrayUnaccessData(V_ARRAY(&var));VariantClear(&var);}::SysFreeString(bstr);}pmt->Release();}format->Release();}}}// return an error, if we didn't find a good candidateif( V_VT(&varSave) == VT_EMPTY)return E_FAIL;WAVEFORMATEX *pSaveWFX;SafeArrayAccessData(V_ARRAY(&varSave), (void**) &pSaveWFX);IltmmMediaTypeDisp* pmt;hr = CoCreateInstance(CLSID_ltmmMediaType, NULL, CLSCTX_INPROC_SERVER, IID_IltmmMediaTypeDisp, (void**) &pmt);// setup the new stream's media typebstr = ::SysAllocString(ltmmMEDIATYPE_Audio);pmt->put_Type(bstr);::SysFreeString(bstr);CString s;s.Format(_T("{%.8X-0000-0010-8000-00AA00389B71}"), (UINT) pSaveWFX->wFormatTag);bstr = s.AllocSysString();pmt->put_Subtype(bstr);::SysFreeString(bstr);pmt->put_FixedSizeSamples(VARIANT_TRUE);pmt->put_TemporalCompression(VARIANT_FALSE);pmt->put_SampleSize(pSaveWFX->nBlockAlign);bstr = ::SysAllocString(ltmmFORMAT_WaveFormatEx);pmt->put_FormatType(bstr);::SysFreeString(bstr);pmt->SetFormatData(-1L, varSave);IltmmWMStreamConfig* stream;bstr = ::SysAllocString(ltmmMEDIATYPE_Audio);hr = profile->CreateNewStream (bstr, &stream);::SysFreeString(bstr);stream->put_StreamNumber (nStreamNum);bstr = ::SysAllocString(L"Audio Stream");stream->put_StreamName (bstr);::SysFreeString(bstr);bstr = ::SysAllocString(L"Audio");stream->put_ConnectionName(bstr);::SysFreeString(bstr);stream->put_Bitrate(pSaveWFX->nAvgBytesPerSec * 8);hr = stream->SetMediaType (pmt);hr = profile->AddStream (stream);stream->Release();pmt->Release();SafeArrayUnaccessData(V_ARRAY(&varSave));VariantClear(&varSave);return S_OK;}HRESULT AddMutexObject(IltmmWMProfile *profile, UINT nBaseStream, UINT nStreamCount){IltmmWMMutualExclusion *excl = NULL;// create an exclusion objectHRESULT hr = profile->CreateNewMutualExclusion (&excl);// mark all the streams for mutual exclusionfor(UINT i = 0; i < nStreamCount; i++){hr = excl->AddStream (nBaseStream + i);}// indicate that the streams differ by Bitrate// see CLSID_WMMUTEX_Bitrate in the WMSDKBSTR bstr = ::SysAllocString(L"{D6E22A01-35DA-11D1-9034-00A0C90349BE}");hr = excl->put_Type(bstr);::SysFreeString(bstr);// assign the exclusion object to the profilehr = profile->AddMutualExclusion (excl);excl->Release();return hr;}
Help Collections
Raster .NET | C API | C++ Class Library | HTML5 JavaScript
Document .NET | C API | C++ Class Library | HTML5 JavaScript
Medical .NET | C API | C++ Class Library | HTML5 JavaScript
Medical Web Viewer .NET
Multimedia
Direct Show .NET | C API | Filters
Media Foundation .NET | C API | Transforms
Supported Platforms
.NET, Java, Android, and iOS/macOS Assemblies
Imaging, Medical, and Document
C API/C++ Class Libraries
Imaging, Medical, and Document
HTML5 JavaScript Libraries
Imaging, Medical, and Document
