Splitting an AVI File into Multiple Bitmaps Using ltmmSampleTarget for C

The following code utilizes ltmmSampleTarget and ltmmConvert to generate multiple device independent bitmaps from an AVI file.

// define helper macros for using interfaces under C 
#ifndef COBJMACROS 
   #define COBJMACROS 
#endif 
 
// include the LEAD Multimedia TOOLKIT header 
#include "ltmm.h"  
// include amvideo.h for VIDEOINFOHEADER, available in the Visual Studio 6.0 or the DirectX SDK 
#include <amvideo.h> 
// includes for string handling 
#include <tchar.h> 
#include <wchar.h> 
#include <string.h> 
#include <stdio.h> 
 
///////////////////////////////////////////////////////////////// 
// SaveBMP24 
// saves a bitmap to a file (supports only 24 BPP) 
// pszFile - output file name 
// pHeader - BITMAPINFOHEADER 
// pBits - bitmap image data 
// 
BOOL SaveBMP24(LPCWSTR pszFile, BITMAPINFOHEADER* pHeader, void* pBits) 
{ 
   HANDLE hFile; 
   TCHAR szFile[MAX_PATH]; 
   BITMAPFILEHEADER bfh; 
   DWORD nWritten; 
 
#if defined(_UNICODE) 
   wcscpy(szFile, pszFile); 
#else 
   WideCharToMultiByte(CP_ACP, 0, pszFile, -1, szFile, MAX_PATH, NULL, NULL); 
#endif 
 
   hFile = CreateFile(szFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
   if(hFile == INVALID_HANDLE_VALUE) 
      return FALSE; 
 
   bfh.bfType = 0x4D42; 
   bfh.bfOffBits = sizeof(bfh) + pHeader->biSize; 
   bfh.bfSize = bfh.bfOffBits + pHeader->biSizeImage; 
   bfh.bfReserved1 = 0; 
   bfh.bfReserved2 = 0; 
 
   if(!WriteFile(hFile, &bfh, sizeof(bfh), &nWritten, NULL) || nWritten != sizeof(bfh)) 
   { 
      CloseHandle(hFile); 
      return FALSE; 
   } 
 
   if(!WriteFile(hFile, pHeader, pHeader->biSize, &nWritten, NULL) || nWritten != pHeader->biSize) 
   { 
      CloseHandle(hFile); 
      return FALSE; 
   } 
 
   if(!WriteFile(hFile, pBits, pHeader->biSizeImage, &nWritten, NULL) || nWritten != pHeader->biSizeImage) 
   { 
      CloseHandle(hFile); 
      return FALSE; 
   } 
 
   CloseHandle(hFile); 
   return TRUE; 
} 
 
///////////////////////////////////////////////////////////////// 
// SplitAvi 
// splits an avi file into individual BMP files 
// pszAviFile - source file name 
// pszOutputDir - directory of output BMP files (split?.bmp) 
// nMaxFrames - maximum number of BMP files (frames) to generate 
// 
HRESULT SplitAvi(LPCWSTR pszAviFile, LPCWSTR pszOutputDir, int nMaxFrames) 
{ 
   HRESULT hr; 
   IltmmConvert* pConvert = NULL; 
   IltmmSampleTarget* pSampleTarget = NULL; 
   IltmmMediaTypeDisp* pMediaType = NULL; 
   IltmmMediaSampleDisp* pMediaSample; 
   VARIANT varFormat; 
   VARIANT varBuffer; 
   VIDEOINFOHEADER* pVIH; 
   void* pBuffer; 
   BSTR bstr; 
   int n; 
   WCHAR szFile[MAX_PATH]; 
 
   // initialize COM library 
   hr = CoInitialize(NULL); 
   if(FAILED(hr)) 
      goto error; 
 
   // create the convert object 
   hr = CoCreateInstance(&CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmConvert, (void**) &pConvert); 
   if(FAILED(hr)) 
      goto error; 
 
   // create the target object 
   hr = CoCreateInstance(&CLSID_ltmmSampleTarget, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmSampleTarget, (void**) &pSampleTarget); 
   if(FAILED(hr)) 
      goto error; 
 
   // create the media type object 
   hr = CoCreateInstance(&CLSID_ltmmMediaType, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmMediaTypeDisp, (void**) &pMediaType); 
   if(FAILED(hr)) 
      goto error; 
 
   // set type to MEDIATYPE_Video 
   bstr = SysAllocString(L"{73646976-0000-0010-8000-00AA00389B71}"); 
   hr = IltmmMediaTypeDisp_put_Type (pMediaType, bstr); 
   SysFreeString(bstr); 
   if(FAILED(hr)) 
      goto error; 
 
   // set subtype to MEDIASUBTYPE_RGB24 
   bstr = SysAllocString(L"{e436eb7d-524f-11ce-9f53-0020af0ba770}"); 
   hr = IltmmMediaTypeDisp_put_Subtype (pMediaType, bstr); 
   SysFreeString(bstr); 
   if(FAILED(hr)) 
      goto error; 
 
 
   //   set the accepted media type 
   hr = IltmmSampleTarget_SetAcceptedMediaType (pSampleTarget, pMediaType); 
   if(FAILED(hr)) 
      goto error; 
 
   IUnknown_Release(pMediaType); 
   pMediaType = NULL; 
 
#ifdef _DEBUG 
   // get it back for debugging 
   hr = IltmmSampleTarget_GetAcceptedMediaType (pSampleTarget, &pMediaType); 
   if(FAILED(hr)) 
      goto error; 
 
   IUnknown_Release(pMediaType); 
   pMediaType = NULL; 
#endif 
 
   //   set the convert input file name 
   bstr = SysAllocString(pszAviFile); 
   hr = IltmmConvert_put_SourceFile (pConvert, bstr); 
   SysFreeString(bstr); 
   if(FAILED(hr)) 
      goto error; 
 
   //   set the convert object target 
   hr = IltmmConvert_put_TargetObject (pConvert, (IUnknown*) pSampleTarget); 
   if(FAILED(hr)) 
      goto error; 
 
   // start the conversion 
   hr = IltmmConvert_StartConvert(pConvert); 
   if(FAILED(hr)) 
      goto error; 
 
   // get the connected media type 
   hr = IltmmSampleTarget_GetConnectedMediaType (pSampleTarget, &pMediaType); 
   if(FAILED(hr)) 
      goto error; 
 
   // get the VIDEOINFOHEADER 
   hr = IltmmMediaTypeDisp_get_Format (pMediaType, &varFormat); 
   if(FAILED(hr)) 
      goto error; 
 
   hr = SafeArrayAccessData(V_ARRAY(&varFormat), (void**) &pVIH); 
   if(FAILED(hr)) 
   { 
      VariantClear(&varFormat); 
      goto error; 
   } 
 
   for(n = 0; n < nMaxFrames; n++) 
   { 
      // fetch a sample 
      hr = IltmmSampleTarget_GetSample (pSampleTarget, 1000, &pMediaSample); 
      if(FAILED(hr) || !pMediaSample) 
         break; 
      // access the image bits 
      hr = IltmmMediaSampleDisp_get_Buffer (pMediaSample, &varBuffer); 
      if(FAILED(hr)) 
      { 
         IUnknown_Release(pMediaSample); 
         goto converterror; 
      } 
      hr = SafeArrayAccessData(V_ARRAY(&varBuffer), &pBuffer); 
      if(FAILED(hr)) 
      { 
         VariantClear(&varBuffer); 
         IUnknown_Release(pMediaSample); 
         goto converterror; 
      } 
      // save the image 
      sprintf(szFile, "%ssplit%u.bmp", pszOutputDir, n + 1); 
 
      if(!SaveBMP24(szFile, &pVIH->bmiHeader, pBuffer)) 
      { 
         SafeArrayUnaccessData(V_ARRAY(&varBuffer)); 
         VariantClear(&varBuffer); 
         IUnknown_Release(pMediaSample); 
         hr = E_FAIL; 
         goto error; 
      } 
      SafeArrayUnaccessData(V_ARRAY(&varBuffer)); 
      VariantClear(&varBuffer); 
      IUnknown_Release(pMediaSample); 
   } 
 
   // stop 
   hr = IltmmConvert_StopConvert (pConvert); 
   if(FAILED(hr)) 
      goto converterror; 
 
   // cleanup and exit 
   hr = S_OK; 
converterror: 
   SafeArrayUnaccessData(V_ARRAY(&varFormat)); 
   VariantClear(&varFormat); 
error: 
 
   if(pConvert) 
      IUnknown_Release(pConvert); 
   if(pSampleTarget) 
      IUnknown_Release(pSampleTarget); 
   if(pMediaType) 
      IUnknown_Release(pMediaType); 
   CoUninitialize(); 
 
   return hr; 
} 
 
void SplittingAVIFileIntoMultipleBitmapsUsingltmmSampleTarget_Example ( ) 
{ 
	SplitAvi((OLECHAR*)MAKE_MEDIA_PATH("count.avi"), (OLECHAR*)MAKE_MEDIA_PATH(""), 10); 
} 

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