IltmmWMProfile::AddStream Example for C++

For complete code, refer to the CNVWM demo.

#include "amvideo.h" 
#include "Mmreg.h" 
 
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 count 
	BSTR bstr = ::SysAllocString(ltmmMEDIATYPE_Audio); 
	HRESULT hr = mgr->GetCodecInfoCount(bstr, &cCodecs); 
	::SysFreeString(bstr); 
	if (FAILED(hr)) 
		return hr; 
 
	// search for matching codec 
	for (long i = 0; i < cCodecs; i++) 
	{ 
		long cFormats; 
		// get MEDIATYPE_Audio codec format count 
		BSTR bstr = ::SysAllocString(ltmmMEDIATYPE_Audio); 
      HRESULT hr = mgr->GetCodecFormatCount(bstr, i, &cFormats); 
		::SysFreeString(bstr); 
		if(FAILED(hr)) 
			break; 
 
		for (long j = 0; j < cFormats; j++) 
		{ 
			// get MEDIATYPE_Audio stream config interface 
			IltmmWMStreamConfig* format; 
			bstr = ::SysAllocString(ltmmMEDIATYPE_Audio); 
			hr = mgr->GetCodecFormat(bstr, i, j, &format); 
			::SysFreeString(bstr); 
			if (SUCCEEDED(hr)) 
			{ 
				// get this format's media type 
				IltmmMediaTypeDisp* pmt; 
				hr = format->GetMediaType(&pmt); 
				if (SUCCEEDED(hr)) 
				{ 
					hr = pmt->get_FormatType(&bstr); 
					if (SUCCEEDED(hr)) 
					{ 
						// only check FORMAT_WaveFormatEx formats 
						if (!_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 candidate 
							long 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 nBlockAlign 
										if (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 candidate 
	if (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); 
	if (FAILED(hr)) 
	{ 
		SafeArrayUnaccessData(V_ARRAY(&varSave)); 
		VariantClear(&varSave); 
		return hr; 
	} 
 
	// setup the new stream's media type 
	bstr = ::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); 
	 
   if (FAILED(hr)) 
	{ 
		SafeArrayUnaccessData(V_ARRAY(&varSave)); 
		VariantClear(&varSave); 
		pmt->Release(); 
		return hr; 
	} 
	 
	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); 
 
	stream->SetMediaType(pmt); 
	profile->AddStream(stream); 
 
	stream->Release(); 
	pmt->Release(); 
	SafeArrayUnaccessData(V_ARRAY(&varSave)); 
	VariantClear(&varSave); 
 
	return S_OK; 
} 
 
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 count 
	BSTR bstr = ::SysAllocString(ltmmMEDIATYPE_Video); 
	HRESULT hr = mgr->GetCodecInfoCount(bstr, &cCodecs); 
	::SysFreeString(bstr); 
	if (FAILED(hr)) 
		return hr; 
 
	// search for matching codec 
	for (long i = 0; !stream && i < cCodecs; i++) 
	{ 
		long cFormats; 
		// get MEDIATYPE_Video codec format count 
		BSTR bstr = ::SysAllocString(ltmmMEDIATYPE_Video); 
		HRESULT hr = mgr->GetCodecFormatCount(bstr, i, &cFormats); 
		::SysFreeString(bstr); 
		if (FAILED(hr)) 
			break; 
		 
      for (long j = 0; j < cFormats; j++) 
		{ 
			// get MEDIATYPE_Video stream config interface 
			bstr = ::SysAllocString(ltmmMEDIATYPE_Video); 
			hr = mgr->GetCodecFormat(bstr, i, j, &stream); 
			::SysFreeString(bstr); 
			if (SUCCEEDED(hr)) 
			{ 
				// get this format's media type 
				hr = stream->GetMediaType(&pmt); 
				if (SUCCEEDED(hr)) 
				{ 
					hr = pmt->get_FormatType(&bstr); 
					if (SUCCEEDED(hr)) 
					{ 
						// only check FORMAT_VideoInfo formats 
						if (!_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 candidate 
	if (!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 AddMutexObject(IltmmWMProfile *profile, UINT nBaseStream, UINT nStreamCount) 
{ 
    IltmmWMMutualExclusion *excl = NULL; 
 
	// create an exclusion object 
	HRESULT hr = profile->CreateNewMutualExclusion(&excl); 
	if (FAILED(hr)) 
		return hr; 
 
	// indicate that the streams differ by bit rate 
	// see CLSID_WMMUTEX_Bitrate in the WMSDK 
	BSTR bstr = ::SysAllocString(L"{D6E22A01-35DA-11D1-9034-00A0C90349BE}"); 
	hr = excl->put_Type(bstr); 
	::SysFreeString(bstr); 
   if (FAILED(hr)) 
	{ 
		excl->Release(); 
		return hr; 
	} 
 
	// mark all the streams for mutual exclusion 
	for (UINT i = 0; i < nStreamCount; i++) 
	{ 
		hr = excl->AddStream(nBaseStream + i); 
		if (FAILED(hr)) 
		{ 
			excl->Release(); 
			return hr; 
		} 
	} 
 
	// assign the exclusion object to the profile 
	hr = profile->AddMutualExclusion(excl); 
	excl->Release(); 
	return hr; 
} 

Help Version 21.0.2021.7.19
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS Multimedia C API Help
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.