// include the LEAD Multimedia TOOLKIT header
#include "ltmm.h"
#include "resource.h"
#include <tchar.h>
#include <stdio.h>
#include <assert.h>
HINSTANCE g_hInstance; // application instance handle
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];
HRESULT hr;
long state;
switch (msg)
{
case WM_INITDIALOG:
// assign the notification window
g_pConvert->SetNotifyWindow((long) hwnd, WM_CONVERTNOTIFY);
// set the abort button text
SetDlgItemText(hwnd, IDC_USERABORT, _T("Abort"));
// start the conversion
hr = g_pConvert->StartConvert();
if(FAILED(hr))
{
_stprintf(sz, _T("conversion error 0x%.8X"), lParam);
SetDlgItemText(hwnd, IDC_CONVERTSTATUS, sz);
UpdateWindow(GetDlgItem(hwnd, IDC_CONVERTSTATUS));
SetDlgItemText(hwnd, IDC_USERABORT, _T("Exit"));
MessageBeep(0);
}
return TRUE;
break;
case WM_DESTROY:
// reset the notification window
g_pConvert->SetNotifyWindow((long) NULL, 0);
#ifdef _DEBUG
{
long state, err, pc;
TCHAR sz[1024];
// get the current state
g_pConvert->get_State(&state);
// get the current state
g_pConvert->get_ConvertError(&err);
// get the amount converted
g_pConvert->get_PercentComplete(&pc);
_stprintf(sz, _T("state = %d, error = 0x%.8X, complete = %d%%"), state, err, pc);
MessageBox(NULL, sz, _T("debug"), MB_OK);
}
#endif
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_USERABORT:
// user abort... stop conversion
g_pConvert->get_State(&state);
if(state == ltmmConvert_State_Running)
g_pConvert->StopConvert();
else
{
g_pConvert->get_ConvertError((long*) &hr);
EndDialog(hwnd, (long)hr);
}
return TRUE;
break;
}
break;
case WM_CONVERTNOTIFY:
switch(wParam)
{
case ltmmConvert_Notify_Started:
// indicate conversion has started
SetDlgItemText(hwnd, IDC_CONVERTSTATUS, TEXT("Starting conversion"));
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"));
break;
case ltmmConvert_Notify_ErrorAbort:
// indicate an error
_stprintf(sz, _T("conversion error 0x%.8X"), lParam);
SetDlgItemText(hwnd, IDC_CONVERTSTATUS, sz);
UpdateWindow(GetDlgItem(hwnd, IDC_CONVERTSTATUS));
SetDlgItemText(hwnd, IDC_USERABORT, _T("Exit"));
MessageBeep(0);
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"));
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
g_pConvert->get_VideoCompressors(&pCompressors);
bstr = SysAllocString(L"@device:sw:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\\LEAD MCMP/MJPEG Codec (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
g_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
g_pConvert->put_TargetFormat(ltmmConvert_TargetFormat_Avi);
// set video compressor properties
g_pConvert->HasDialog(ltmmConvert_Dlg_VideoCompressor, &f);
if(f)
g_pConvert->ShowDialog(ltmmConvert_Dlg_VideoCompressor, (long) hwndParent);
// set audio compressor properties
g_pConvert->HasDialog(ltmmConvert_Dlg_AudioCompressor, &f);
if(f)
g_pConvert->ShowDialog(ltmmConvert_Dlg_AudioCompressor, (long) hwndParent);
return S_OK;
}
//
// RecompressMemory
// recompresses from global memory to a file using the LEAD video and MP3 audio compressors
//
// 1. the source file is preloaded into memory object
// 2. the source memory is recompressed to the target file
//
// pszSource = source file path
// pszTarget = target file path
//
HRESULT RecompressMemory(LPCTSTR pszSource, LPCTSTR pszTarget)
{
HRESULT hr;
HANDLE hfile;
DWORD size, dwRead;
VARIANT var;
IltmmMemory *pMemSource = NULL, *pMemTarget = NULL;
#ifndef _UNICODE
WCHAR wsz[MAX_PATH];
#endif
// open the source file
hfile = CreateFile(pszSource, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if(hfile == INVALID_HANDLE_VALUE)
return E_FAIL;
// allocate same-sized buffer
size = GetFileSize(hfile, NULL);
// create the source memory object
hr = CoCreateInstance(CLSID_ltmmMemory, NULL, CLSCTX_ALL, IID_IltmmMemory, (void**) &pMemSource);
if (FAILED(hr))
{
AfxMessageBox(TEXT("Error allocating source memory object. Conversion aborted."));
goto error;
}
hr = pMemSource->put_BufferSize(size);
if (FAILED(hr))
goto error;
VariantInit(&var);
pMemSource->LockBuffer(&var);
// read the source file contents
ReadFile(hfile, var.parray->pvData, size, &dwRead, NULL);
pMemSource->Unlock();
VariantClear(&var);
CloseHandle(hfile);
hfile = NULL;
// assign the source object
hr = g_pConvert->put_SourceStream(pMemSource);
if(FAILED(hr))
goto error;
// create the target memory stream
hr = CoCreateInstance(CLSID_ltmmMemory, NULL, CLSCTX_ALL, IID_IltmmMemory, (void**)&pMemTarget);
if (FAILED(hr))
{
AfxMessageBox(TEXT("Error allocating target memory object. Conversion aborted."));
goto error;
}
// set target stream
hr = g_pConvert->put_TargetStream(pMemTarget);
if (FAILED(hr))
goto error;
// setup AVI recompression
hr = SetAVIRecompression(NULL);
if (FAILED(hr))
goto error;
// do conversion
hr = (HRESULT)DialogBox(g_hInstance, (LPCTSTR)IDD_CONVERTDLG, NULL, ConvertDlgProc);
if (FAILED(hr))
goto error;
// write the data to a file
hfile = CreateFile(pszTarget, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
long fl = 0;
unsigned long lBytesWritten;
IltmmMemory *pTarget = NULL;
VARIANT varData;
unsigned char *pBuffer = NULL;
SAFEARRAY sa;
hr = g_pConvert->get_TargetStream((IUnknown**)&pTarget);
if (FAILED(hr))
goto error;
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);
// if LockBuffer() or LockRegion() is used, Unloack() must be called :
// g_pTarget->Unlock();
SafeArrayUnaccessData(V_ARRAY(&varData));
VariantClear(&varData);
CloseHandle(hfile);
hfile = NULL;
pTarget->Release();
error:
g_pConvert->ResetSource();
g_pConvert->ResetTarget();
if(pMemSource)
pMemSource->Release();
if(pMemTarget)
pMemTarget->Release();
if (hfile)
CloseHandle(hfile);
return hr;
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HRESULT hr;
g_hInstance = hInstance;
// 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 = RecompressMemory(MAKE_MEDIA_PATH("source.avi"), MAKE_MEDIA_PATH("target.avi"));
if(FAILED(hr))
goto error;
error:
// cleanup
if (g_pConvert)
g_pConvert->Release();
CoUninitialize();
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
Your email has been sent to support! Someone should be in touch! If your matter is urgent please come back into chat.
Chat Hours:
Monday - Friday, 8:30am to 6pm ET
Thank you for your feedback!
Please fill out the form again to start a new chat.
All agents are currently offline.
Chat Hours:
Monday - Friday
8:30AM - 6PM EST
To contact us please fill out this form and we will contact you via email.