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 19.0.2017.10.27
Products | Support | Contact Us | Copyright Notices
© 1991-2017 LEAD Technologies, Inc. All Rights Reserved.
LEADTOOLS Multimedia C API Help