Recompressing an AVI File for C

The following code demonstrates how to recompress an AVI file:

// define helper macros for using interfaces under C

The following code demonstrates how to recompress 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 "resource.h"
#include <tchar.h>
#include <stdio.h>
#include <assert.h>

IltmmConvert* g_pConvert; // convert object's interface pointer

// user defined message id used for conversion events
#define WM_CONVERTNOTIFY (WM_USER + 1000) 

//
// ConvertDlgProc
// starts the conversion process and provides status feedback
//
// controls: 
// IDC_CONVERTSTATUS - static control used for status messages
// IDC_CONVERTPROGRESS - static control used for conversion progress
// IDC_USERABORT - button control used to abort the conversion or exit the dialog

BOOL CALLBACK ConvertDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{
   TCHAR sz[256]; 
   BSTR bstr1 = NULL ; 
   BSTR bstr2 = NULL ; 
   HRESULT hr; 
   long state; 
   long type; 
   long streams; 
   IltmmVCRControl* pVCR; 


   switch (msg) 
   {
   case WM_INITDIALOG: 
      // assign the notification window
      IltmmConvert_SetNotifyWindow(g_pConvert, (long) hwnd, WM_CONVERTNOTIFY); 

      // set the abort button text
      SetDlgItemText(hwnd, IDC_USERABORT, _T("Abort"));

      // uncomment the following line to view the the graph in DirectShow GraphEdit
      // IltmmConvert_EditGraph(g_pConvert); 

      IltmmConvert_get_UnrenderedStreams(g_pConvert, &streams); 
      if(streams != 0) 
         MessageBox(hwnd, _T("Not all the streams could be rendered."), _T("Convert"), MB_ICONEXCLAMATION | MB_OK); 

      IltmmConvert_get_TargetVCRControl(g_pConvert, &pVCR); 
      hr = IltmmVCRControl_Record(pVCR); 
      IUnknown_Release(pVCR); 

      if(SUCCEEDED(hr)) 
         Sleep(2000); 

      // start the conversion
      hr = IltmmConvert_StartConvert(g_pConvert); 
      if(FAILED(hr)) 
      {
         _stprintf(sz, _T("Can't start conversion\n"));
         SetDlgItemText(hwnd, IDC_CONVERTSTATUS, sz); 
         UpdateWindow(GetDlgItem(hwnd, IDC_CONVERTSTATUS)); 
         SetDlgItemText(hwnd, IDC_USERABORT, _T("Exit"));
         MessageBeep(0); 

         // stop, if VCR
         IltmmConvert_get_TargetVCRControl(g_pConvert, &pVCR); 
         IltmmVCRControl_Stop(pVCR); 
         IUnknown_Release(pVCR); 
      }
      return TRUE; 
      break; 
   case WM_DESTROY: 
      // reset the notification window
      IltmmConvert_SetNotifyWindow (g_pConvert, (long) NULL, 0); 
#ifdef _DEBUG
      {
         long state, err, pc; 
         double start, end, dur; 
         TCHAR sz[1024]; 

         // get the current state
         IltmmConvert_get_State(g_pConvert, &state); 

         // get the current state
         IltmmConvert_get_ConvertError(g_pConvert, &err); 

         // get the amount converted
         IltmmConvert_get_PercentComplete(g_pConvert, &pc); 

         // get the start
         IltmmConvert_get_SelectionStart(g_pConvert, &start); 

         // get the end
         IltmmConvert_get_SelectionEnd(g_pConvert, &end); 

         // get the duration
         IltmmConvert_get_Duration(g_pConvert, &dur); 

         _stprintf(sz, _T("state = %d, error = 0x%.8X, complete = %d%%, start = %g, end = %g, duration = %g"), state, err, pc, start, end, dur); 
         MessageBox(NULL, sz, _T("debug"), MB_OK); 
      }
#endif

      break; 
   case WM_COMMAND: 
      switch (LOWORD(wParam)) 
      {
      case IDC_USERABORT: 
         // user abort... stop conversion
         IltmmConvert_get_State (g_pConvert, &state); 
         if(state == ltmmConvert_State_Running) 
            IltmmConvert_StopConvert(g_pConvert); 
         else
         {
            IltmmConvert_get_ConvertError(g_pConvert, (long*) &hr); 
            EndDialog(hwnd, (long) hr); 
         }
         return TRUE; 
         break; 
      }
      break; 
   case WM_CONVERTNOTIFY: 
      switch(wParam) 
      {
      case ltmmConvert_Notify_Started: 
         // indicate conversion has started
         IltmmConvert_get_SourceType(g_pConvert, &type); 
         switch(type) 
         {
         case ltmmConvert_Source_File: 
            IltmmConvert_get_SourceFile(g_pConvert, &bstr1); 
            break; 
         case ltmmConvert_Source_HGlobal: 
            bstr1 = SysAllocString(L"[hglobal]"); 
            break; 
         case ltmmConvert_Source_Array: 
            bstr1 = SysAllocString(L"[array]"); 
            break; 
         case ltmmConvert_Source_Object: 
            bstr1 = SysAllocString(L"[object]"); 
            break; 
         }
         IltmmConvert_get_TargetType(g_pConvert, &type); 
         switch(type) 
         {
         case ltmmConvert_Target_File: 
            IltmmConvert_get_TargetFile(g_pConvert, &bstr2); 
            break; 
         case ltmmConvert_Target_Array: 
            bstr2 = SysAllocString(L"[array]"); 
            break; 
         case ltmmConvert_Target_Object: 
            bstr2 = SysAllocString(L"[object]"); 
            break; 
         case ltmmConvert_Target_Device: 
            bstr2 = SysAllocString(L"[device]"); 
            break; 
         }
         IltmmConvert_get_RenderedStreams(g_pConvert, &streams); 
         if((streams & ltmmConvert_Stream_Audio) & !(streams & ltmmConvert_Stream_Video)) 
            _stprintf(sz, _T("recompressing audio from '%ls' to '%ls'..."), bstr1, bstr2); 
         else if(!(streams & ltmmConvert_Stream_Audio) & (streams & ltmmConvert_Stream_Video)) 
            _stprintf(sz, _T("recompressing video from '%ls' to '%ls'..."), bstr1, bstr2); 
         else
            _stprintf(sz, _T("recompressing '%ls' to '%ls'..."), bstr1, bstr2); 
         SysFreeString(bstr1); 
         SysFreeString(bstr2); 
         SetDlgItemText(hwnd, IDC_CONVERTSTATUS, sz); 
         UpdateWindow(GetDlgItem(hwnd, IDC_CONVERTSTATUS)); 
         break; 
      case ltmmConvert_Notify_Complete: 
         // indicate an conversion complete
         _stprintf(sz, _T("conversion complete"));
         SetDlgItemText(hwnd, IDC_CONVERTSTATUS, sz); 
         UpdateWindow(GetDlgItem(hwnd, IDC_CONVERTSTATUS)); 
         SetDlgItemText(hwnd, IDC_USERABORT, _T("Exit"));

         // stop, if VCR
         IltmmConvert_get_TargetVCRControl(g_pConvert, &pVCR); 
         IltmmVCRControl_Stop (pVCR); 
         IUnknown_Release(pVCR); 
         break; 
      case ltmmConvert_Notify_ErrorAbort: 
         // indicate an error
         _stprintf(sz, _T("conversion aborted\n"));
         SetDlgItemText(hwnd, IDC_CONVERTSTATUS, sz); 
         UpdateWindow(GetDlgItem(hwnd, IDC_CONVERTSTATUS)); 
         SetDlgItemText(hwnd, IDC_USERABORT, _T("Exit"));
         MessageBeep(0); 

         // stop, if VCR
         IltmmConvert_get_TargetVCRControl(g_pConvert, &pVCR); 
         IltmmVCRControl_Stop (pVCR); 
         IUnknown_Release(pVCR); 

         break; 
      case ltmmConvert_Notify_UserAbort: 
         // indicate user abort
         _stprintf(sz, _T("conversion aborted\n"));
         SetDlgItemText(hwnd, IDC_CONVERTSTATUS, sz); 
         UpdateWindow(GetDlgItem(hwnd, IDC_CONVERTSTATUS)); 
         SetDlgItemText(hwnd, IDC_USERABORT, _T("Exit"));

         // stop, if VCR
         IltmmConvert_get_TargetVCRControl(g_pConvert, &pVCR); 
         IltmmVCRControl_Stop (pVCR); 
         IUnknown_Release(pVCR); 

         MessageBeep(0); 
         break; 
      case ltmmConvert_Notify_Progress: 
         // indicate conversion progress
         _stprintf(sz, _T("%3d%% complete"), lParam); 
         SetDlgItemText(hwnd, IDC_CONVERTPROGRESS, sz); 
         UpdateWindow(GetDlgItem(hwnd, IDC_CONVERTPROGRESS)); 
         break; 
      }
      return TRUE; 
      break; 
   }
   return FALSE; 
}


//
// 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) 
{
   IltmmCompressors* pCompressors; 
   long index; 
   VARIANT_BOOL f; 
   BSTR bstr; 

   // select the LEAD video compressor
   IltmmConvert_get_VideoCompressors(g_pConvert, &pCompressors); 
   bstr = SysAllocString(L"@device:sw:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\\LEAD MCMP/MJPEG Codec (2.0)");
   IltmmCompressors_Find(pCompressors, bstr, &index); 
   SysFreeString(bstr); 
   if(index < 0) 
   {
      // compressor isn't registered
      IUnknown_Release(pCompressors); 
      return E_FAIL; 
   }
   IltmmCompressors_put_Selection(pCompressors, index); 
   IUnknown_Release(pCompressors); 


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

   // set output format to AVI
   IltmmConvert_put_TargetFormat(g_pConvert, ltmmConvert_TargetFormat_Avi); 
#ifdef _DEBUG
   {
      long v; 
      IltmmConvert_get_TargetFormat(g_pConvert, &v); 
      assert(v == ltmmConvert_TargetFormat_Avi); 
   }
#endif

   // set video compressor properties
   IltmmConvert_HasDialog(g_pConvert, ltmmConvert_Dlg_VideoCompressor, &f); 
   if(f) 
      IltmmConvert_ShowDialog(g_pConvert, ltmmConvert_Dlg_VideoCompressor, (long) hwndParent); 

   // set audio compressor properties
   IltmmConvert_HasDialog(g_pConvert, ltmmConvert_Dlg_AudioCompressor, &f); 
   if(f) 
      IltmmConvert_ShowDialog(g_pConvert, ltmmConvert_Dlg_AudioCompressor, (long) hwndParent); 

   return S_OK; 
}


//
// RecompressFile
// recompresses a file using the LEAD video and MP3 audio compressors
//
// pszSource = source file path
// pszTarget = target file path
//
HRESULT RecompressFile(LPCTSTR pszSource, LPCTSTR pszTarget, HINSTANCE hInstance) 
{
   HRESULT hr; 
   BSTR bstr; 
#ifndef _UNICODE
   WCHAR wsz[MAX_PATH]; 
#endif



   // set source file
#ifdef _UNICODE
   bstr = SysAllocString(pszSource); 
#else
   swprintf(wsz, L"%hs", pszSource); 
   bstr = SysAllocString(wsz); 
#endif
   hr = IltmmConvert_put_SourceFile(g_pConvert, bstr); 
   SysFreeString(bstr); 
   if(FAILED(hr)) 
      return hr; 

   // set target file
#ifdef _UNICODE
   bstr = SysAllocString(pszTarget); 
#else
   swprintf(wsz, L"%hs", pszTarget); 
   bstr = SysAllocString(wsz); 
#endif
   hr = IltmmConvert_put_TargetFile(g_pConvert, bstr); 
   SysFreeString(bstr); 
   if(FAILED(hr)) 
      return hr; 

   // setup AVI recompression
   hr = SetAVIRecompression(NULL); 
   if(FAILED(hr)) 
      return hr; 

   // do conversion
   hr = (HRESULT) DialogBox(hInstance, (LPCTSTR)IDD_CONVERTDLG, NULL, ConvertDlgProc); 


   return hr; 
}

L_MULTIMEDIATEX_API void RecompressingAVIFile_Example ( HINSTANCE hInstance /*application instance handle*/ )
{
   HRESULT hr; 


   // 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**) &g_pConvert); 
   if(FAILED(hr)) 
      goto error; 


   hr = RecompressFile(_T("c:\\source.avi"), _T("c:\\target1.avi"), hInstance);
   if(FAILED(hr)) 
      goto error; 

error: 
   // cleanup

   if(g_pConvert) 
      IUnknown_Release(g_pConvert); 

   CoUninitialize();
}