Use ltmmMemory for Memory Conversion Example for C++

1.

Create a convert object, source and target objects:

   
// creat a convert object, source and target memory objects
CoCreateInstance(CLSID_ltmmConvert, 
      NULL, 
      CLSCTX_INPROC_SERVER, 
      IID_IltmmConvert, 
      (void**) &pConvert); 
   
CoCreateInstance(CLSID_ltmmMemory, 
      NULL, 
      CLSCTX_INPROC_SERVER, 
      IID_IltmmMemory, 
      (void**) &source); 
   
CoCreateInstance(CLSID_ltmmMemory, 
      NULL, 
      CLSCTX_INPROC_SERVER, 
      IID_IltmmMemory, 
      (void**) &target); 

// set notify window
pConvert->SetNotifyWindow((long)m_hWnd, WM_CONVERTNOTIFY); 

2.

Setup the source object, preload it with data:

// Set the buffer size
source->put_BufferSize (fl); 

SAFEARRAY sa; 
VARIANT var; 

// pass data from the arr BYTE array... 
memset(&sa, 0, sizeof(sa)); 
sa.cbElements = sizeof(unsigned char); 
sa.cDims = 1; 
sa.fFeatures = (FADF_AUTO | FADF_FIXEDSIZE); 
sa.pvData = arr; //data to fill
sa.rgsabound[0].cElements = fl; 
VariantInit(&var); 
V_VT(&var) = (VT_ARRAY | VT_UI1); 
V_ARRAY(&var) = &sa; 
         
source->SetData (0, fl, var); 
      
// Set input memory object
pConvert->put_SourceStream (source); 

// Set output memory object
pConvert->put_TargetStream (target); 

// Set recompression
SetAVIRecompression(NULL, pConvert); 
      
// Start conversion
pConvert->StartConvert ();

3.

Handle the notification window to plot the data and save it to a file :

LRESULT OnConvertNotify(WPARAM wParam, LPARAM lParam)
{
   switch(wParam) 
   {
      case ltmmConvert_Notify_Complete: 
      {
         // Indicates a successful completion of the conversion process. 
         
         HANDLE hFile = NULL; 

         // write the data to a file
         hFile = CreateFile(TARGET,              // open file name 
                     GENERIC_WRITE,               // open for writing 
                     FILE_SHARE_READ,           // share for reading 
                     NULL,                                  // no security 
                     CREATE_ALWAYS,             // re-create the file
                     FILE_ATTRIBUTE_NORMAL, // normal file 
                     NULL);                                 // no attr. template 

         long fl = 0; 
         unsigned long lBytesWritten; 
         IltmmMemory *pTarget = NULL; 
         VARIANT varData; 
         unsigned char *pBuffer = NULL; 
         SAFEARRAY sa; 

         pConvert->get_TargetStream ((IUnknown**)&pTarget); 

         if(!pTarget) 
            break; 

         pTarget->get_BufferSize (&fl); 

         VariantInit(&varData); 

         // pass data
         memset(&sa, 0, sizeof(sa)); 
         sa.cbElements = sizeof(unsigned char); 
         sa.cDims = 1; 
         sa.fFeatures = (FADF_AUTO | FADF_FIXEDSIZE); 
         sa.pvData = new UCHAR[fl]; 
         sa.rgsabound[0].cElements = fl; 
         V_VT(&varData) = (VT_ARRAY | VT_UI1); 
         V_ARRAY(&varData) = &sa; 

//
// To lock the buffer for synchronization, use the following 
// line instead of the line below : 
// pTarget->LockBuffer (&varData); 
// or
// pTarget->LockRegion (0, fl, &varData); 
// You may also use the GetData() function
// To get the data without allocating a SAFEARRAY : 
// pTarget->GetData (0, fl, &varData); 
//

         pTarget->CopyData (0, fl, &varData); 

         SafeArrayAccessData(V_ARRAY(&varData), (void**)&pBuffer); 

         // to manipulate the buffer bytes directly without a buffer pointer
         // use the SetByte method, for example to change the first two
         // bytes in the buffer : 
         // pTarget->SetByte(0, 0x10); 
         // pTarget->SetByte(1, 0x13); 

         WriteFile(hFile, pBuffer, fl, &lBytesWritten, NULL); 

         // Plot data on screen
         string dataPlot; 
         char data[20]; 
         short sData; 

         for(int i=0; i<fl ; i++)
         {
            pTarget->GetByte (i, &sData); 
            dataPlot += "0x";
            dataPlot += ltoa(sData, data, 16); 
            dataPlot += "  ";
         }

         OutputText(dataPlot); 
         
         // if LockBuffer() or LockRegion() is used, Unloack() must be called : 
         // pTarget->Unlock ();

         SafeArrayUnaccessData(V_ARRAY(&varData)); 
         VariantClear(&varData); 

         CloseHandle(hFile); 

         pTarget->Release();
      }
      break; 
   }
   return 0; 
}

//
// SetAVIRecompression
// sets up LEAD video compression, MP3 audio compression, and AVI file output
//
// hwndParent = parent window for compressor property dialog boxes
//
HRESULT SetAVIRecompression(HWND hwndParent, IltmmConvert *pConvert) 
{
   ltmmCompressors* pCompressors; 
   long index; 
   VARIANT_BOOL f; 
   BSTR bstr; 
   
   // select the LEAD video compressor
   pConvert->get_VideoCompressors (&pCompressors); 
   bstr = SysAllocString(L"@device:sw:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\LEAD MCMP/MJPEG Codec A COmpressor combined with a DECompressor, or encoder and a decoder, which allows you to both compress and decompress that same data.COmpressor Also known as an encoder, this is a module or algorithm to compress data. Playing that data back requires a decompressor, or decoder. combined with a DECompressor, or encoder Also known as compressor, this is a module or algorithm to compress data. Playing that data back requires a decompressor, or decoder. and a decoder Also known as a decompressor, this is a module or algorithm to decompress data., which allows you to both compress and decompress that same data. (2.0)");
   pCompressors->Find (bstr, &index); 
   SysFreeString(bstr); 
   if(index < 0) 
   {
      // compressor isn't registered
      pCompressors->Release ();
      return E_FAIL; 
   }
   pCompressors->put_Selection (index); 
   pCompressors->Release();

   // select the MP3 audio video compressor
   pConvert->get_AudioCompressors (&pCompressors); 
   bstr = SysAllocString(L"@device:cm:{33D9A761-90C8-11D0-BD43-00A0C911CE86}\\85MPEG Layer-3");
   pCompressors->Find (bstr, &index); 
   SysFreeString(bstr); 
   if(index < 0) 
   {
      // compressor isn't registered
      pCompressors->Release ();
      return E_FAIL; 
   }

   pCompressors->put_Selection (index); 
   pCompressors->Release();
   
   // set output format to AVI
   pConvert->put_TargetFormat (ltmmConvert_TargetFormat_Avi); 

   // set video compressor properties
   pConvert->HasDialog (ltmmConvert_Dlg_VideoCompressor, &f); 
   if(f) 
   pConvert->ShowDialog (ltmmConvert_Dlg_VideoCompressor, (long) hwndParent); 

   // set audio compressor properties
   pConvert->HasDialog (ltmmConvert_Dlg_AudioCompressor, &f); 
   if(f) 
   pConvert->ShowDialog(ltmmConvert_Dlg_AudioCompressor, (long) hwndParent); 
   
   return S_OK; 
}