IltmmWMProfile::AddStream Example for C

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);  
} 
 
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);  
} 

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

LEADTOOLS Multimedia C API Help