Products | Support | Send comments on this topic. | Email a link to this topic. | Back to Getting Started | Help Version 18.0.10.24
LEADTOOLS Multimedia API Help

IltmmWMProfile::AddStream Example for C++

Show in webframe

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;
}
Products | Support | Contact Us | Copyright Notices
© 2006-2014 All Rights Reserved. LEAD Technologies, Inc.