The following code utilizes ltmmSampleSource and ltmmConvert to generate an AVI file from generated 24-bit device independent bitmaps.
// include the LEAD Multimedia TOOLKIT header#include "ltmm.h"// include amvideo.h for VIDEOINFOHEADER, available in Visual Studio or DirectX SDK#include <amvideo.h>// includes for string handling#include <tchar.h>#include <string.h>#include <stdio.h>#include <assert.h>/////////////////////////////////////////////////////////////////// CreateCountingAvi// create an AVI file composed of frames of counting numbers// pszAviFile - output file name// nFrames - number of frames to generate//HRESULT CreateCountingAvi(LPWSTR pszAviFile, int nFrames){HRESULT hr;IltmmConvert* pConvert = NULL;IltmmSampleSource* pSampleSource = NULL;IltmmMediaTypeDisp* pMediaType = NULL;IltmmMediaSampleDisp* pMediaSample;BSTR bstr;VIDEOINFOHEADER vih;SAFEARRAY sa;VARIANT var;int n;HBITMAP hbmFrame;HBITMAP hbmSave;HDC hDC;RECT rc;TCHAR sz[16];LARGE_INTEGER starttime;LARGE_INTEGER stoptime;LARGE_INTEGER mstarttime;LARGE_INTEGER mstoptime;LOGFONT logfont;HFONT hfntSave;HFONT hfntFrame;int len;SIZE size;// initialize COM libraryhr = CoInitialize(NULL);if(FAILED(hr))goto error;// create the convert objecthr = CoCreateInstance(CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, IID_IltmmConvert, (void**) &pConvert);if(FAILED(hr))goto error;// create the source objecthr = CoCreateInstance(CLSID_ltmmSampleSource, NULL, CLSCTX_INPROC_SERVER, IID_IltmmSampleSource, (void**) &pSampleSource);if(FAILED(hr))goto error;// create the media type objecthr = CoCreateInstance(CLSID_ltmmMediaType, NULL, CLSCTX_INPROC_SERVER, IID_IltmmMediaTypeDisp, (void**) &pMediaType);if(FAILED(hr))goto error;// set type to MEDIATYPE_Videobstr = SysAllocString(L"{73646976-0000-0010-8000-00AA00389B71}");hr = pMediaType->put_Type(bstr);SysFreeString(bstr);if(FAILED(hr))goto error;// set subtype to MEDIASUBTYPE_RGB24bstr = SysAllocString(L"{e436eb7d-524f-11ce-9f53-0020af0ba770}");hr = pMediaType->put_Subtype(bstr);SysFreeString(bstr);if(FAILED(hr))goto error;// set format to FORMAT_VideoInfobstr = SysAllocString(L"{05589f80-c356-11ce-bf01-00aa0055595a}");hr = pMediaType->put_FormatType(bstr);SysFreeString(bstr);if(FAILED(hr))goto error;// set VIDEOINFOHEADER to 320x240 24-bit RGB image at 15 frames per secondmemset(&vih, 0, sizeof(vih));vih.bmiHeader.biCompression = BI_RGB;vih.bmiHeader.biBitCount = 24;vih.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);vih.bmiHeader.biWidth = 320;vih.bmiHeader.biHeight = 240;vih.bmiHeader.biPlanes = 1;vih.bmiHeader.biSizeImage = (((vih.bmiHeader.biWidth * 3) + 3) & ~3) * vih.bmiHeader.biHeight;vih.bmiHeader.biClrImportant = 0;vih.AvgTimePerFrame = ((__int64) 10000000 / 15);vih.dwBitRate = vih.bmiHeader.biSizeImage * 8 * 15;// pass VIDEOINFOHEADER to ltmmMediaType via SAFEARRAYmemset(&sa, 0, sizeof(sa));sa.cbElements = sizeof(unsigned char);sa.cDims = 1;sa.fFeatures = (FADF_AUTO | FADF_FIXEDSIZE);sa.pvData = &vih;sa.rgsabound[0].cElements = sizeof(vih);VariantInit(&var);V_VT(&var) = (VT_ARRAY | VT_UI1);V_ARRAY(&var) = &sa;hr = pMediaType->SetFormatData(sizeof(vih), var);if(FAILED(hr))goto error;// fixed image size sampleshr = pMediaType->put_FixedSizeSamples(VARIANT_TRUE);if(FAILED(hr))goto error;hr = pMediaType->put_SampleSize(vih.bmiHeader.biSizeImage);if(FAILED(hr))goto error;// set the source media typehr = pSampleSource->SetMediaType(pMediaType);if(FAILED(hr))goto error;// set the convert object sourcehr = pConvert->put_SourceObject(pSampleSource);if(FAILED(hr))goto error;#ifdef _DEBUG{IUnknown* punk;pConvert->get_SourceObject(&punk);assert(punk != NULL);if(punk)punk->Release();}#endif// set the convert output file namebstr = ::SysAllocString(pszAviFile);hr = pConvert->put_TargetFile(bstr);SysFreeString(bstr);if(FAILED(hr))goto error;// need a dc to draw tohDC = CreateCompatibleDC(NULL);if(!hDC){hr = E_OUTOFMEMORY;goto error;}// create a SAFEARRAY that points to a DIB sections bitsmemset(&sa, 0, sizeof(sa));sa.cbElements = sizeof(unsigned char);sa.cDims = 1;sa.fFeatures = (FADF_AUTO | FADF_FIXEDSIZE);sa.pvData = &vih;sa.rgsabound[0].cElements = vih.bmiHeader.biSizeImage;V_VT(&var) = (VT_ARRAY | VT_UI1);V_ARRAY(&var) = &sa;hbmFrame = CreateDIBSection(NULL, (BITMAPINFO*) &vih.bmiHeader, DIB_RGB_COLORS, &sa.pvData, NULL, 0);if(!hbmFrame){DeleteDC(hDC);hr = E_OUTOFMEMORY;goto error;}// create a font big enough to fit the height of each framememset(&logfont, 0, sizeof(logfont));_tcscpy(logfont.lfFaceName, _T("Arial"));logfont.lfHeight = vih.bmiHeader.biHeight;hfntFrame = CreateFontIndirect(&logfont);if(!hfntFrame){DeleteDC(hDC);DeleteObject(hbmFrame);hr = E_OUTOFMEMORY;goto error;}// select the font and the bitmap into the device contexthbmSave = (HBITMAP) SelectObject(hDC, hbmFrame);hfntSave = (HFONT) SelectObject(hDC, hfntFrame);// need a rect for the ExtTextOutSetRect(&rc, 0, 0, vih.bmiHeader.biWidth, vih.bmiHeader.biHeight);// start the conversionhr = pConvert->StartConvert();if(FAILED(hr))goto converterror;starttime.QuadPart = 0;mstarttime.QuadPart = 0;for(n = 0; n < nFrames; n++){// convert the frame number to text and draw it to the bitmaplen = _stprintf(sz, _T("%u"), n + 1);GetTextExtentPoint32(hDC, sz, len, &size);ExtTextOut(hDC, (rc.right - rc.left - size.cx) / 2, (rc.bottom - rc.top - size.cy) / 2, ETO_CLIPPED | ETO_OPAQUE, &rc, sz, len, NULL);GdiFlush();// get a free sample bufferhr = pSampleSource->GetSampleBuffer(1000, &pMediaSample);if(FAILED(hr))goto converterror;// set the time in 100 nanoseconds (based on frame rate)stoptime.QuadPart = starttime.QuadPart + vih.AvgTimePerFrame;hr = pMediaSample->SetTime(starttime.HighPart, starttime.LowPart, stoptime.HighPart, stoptime.LowPart);if(FAILED(hr)){pMediaSample->Release();goto converterror;}// media time is equal to the frame numbermstoptime.QuadPart = mstarttime.QuadPart + 1;hr = pMediaSample->SetMediaTime(mstarttime.HighPart, mstarttime.LowPart, mstoptime.HighPart, mstoptime.LowPart);if(FAILED(hr)){pMediaSample->Release();goto converterror;}// this is a sync pointhr = pMediaSample->put_SyncPoint(VARIANT_TRUE);if(FAILED(hr)){pMediaSample->Release();goto converterror;}// set the sample datahr = pMediaSample->SetData(vih.bmiHeader.biSizeImage, var);if(FAILED(hr)){pMediaSample->Release();goto converterror;}// send the sample downstreamhr = pSampleSource->DeliverSample(1000, pMediaSample);if(FAILED(hr)){pMediaSample->Release();goto converterror;}// adjust the next time valuesstarttime = stoptime;mstarttime = mstoptime;// release the sample bufferpMediaSample->Release();}// all done, inform the downstream filtershr = pSampleSource->DeliverEndOfStream(1000);if(FAILED(hr))goto converterror;// stophr = pConvert->StopConvert();if(FAILED(hr))goto converterror;// cleanup and exithr = S_OK;converterror:SelectObject(hDC, hfntSave);DeleteObject(hfntFrame);SelectObject(hDC, hbmSave);DeleteObject(hbmFrame);DeleteDC(hDC);error:if(pConvert)pConvert->Release();if(pSampleSource)pSampleSource->Release();if(pMediaType)pMediaType->Release();CoUninitialize();return hr;}int main(int argc, char* argv[]){CreateCountingAvi(MAKE_MEDIA_PATH("count.avi"), 10);return 0;}
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
