2025-11-28 00:35:46 +09:00

329 lines
9.8 KiB
C++

//*****************************************************************************
//
// Microsoft Windows Media
// Copyright ( C) Microsoft Corporation. All rights reserved.
//
// FileName: main.cpp
//
// Abstract: Parse the parameters and call CWMVRecompress::Recompress
//
//*****************************************************************************
#include <tchar.h>
#include <stdio.h>
#include "WMVRecompress.h"
///////////////////////////////////////////////////////////////////////////////
// Convert a TCHAR string to WCHAR string.
// Caller must release the memory of pwszOutput by calling delete[] pwszOutput.
///////////////////////////////////////////////////////////////////////////////
HRESULT ConvertTCharToWChar( LPCTSTR ptszInput, __out LPWSTR * pwszOutput )
{
int cchOutput = 0;
if( NULL == ptszInput || NULL == pwszOutput )
{
return( E_INVALIDARG );
}
//
// Get output buffer size
//
#ifdef UNICODE
cchOutput = wcslen( ptszInput ) + 1;
#else //UNICODE
cchOutput = MultiByteToWideChar( CP_ACP, 0, ptszInput, -1, NULL, 0 );
if( 0 == cchOutput )
{
return( HRESULT_FROM_WIN32( GetLastError() ) );
}
#endif // UNICODE
*pwszOutput = new WCHAR[ cchOutput ];
if( NULL == *pwszOutput)
{
return( E_OUTOFMEMORY );
}
#ifdef UNICODE
wcsncpy_s( *pwszOutput, cchOutput, ptszInput, cchOutput - 1 );
#else //UNICODE
if( 0 == MultiByteToWideChar( CP_ACP, 0, ptszInput, -1, *pwszOutput, cchOutput ) )
{
SAFE_ARRAYDELETE( *pwszOutput );
return( HRESULT_FROM_WIN32( GetLastError() ) );
}
#endif // UNICODE
return( S_OK );
}
////////////////////////////////////////////////////////////////////////////////
// This function gives the correct usage,
// if the user gives invalid arguments.
////////////////////////////////////////////////////////////////////////////////
void Usage()
{
_tprintf( _T( "Usage: WMVRecompress -i <INPUT_FILE> -o <OUTPUT_FILE> \n" ) );
_tprintf( _T( " { -ps <SYSTEM_PROFILE_INDEX> | -pf <CUSTOM_PROFILE_FILE> }\n" ) );
_tprintf( _T( " [-m] [-c] [-s]\n" ) );
_tprintf( _T( " -i <INPUT_FILE> = input ASF/WMV/WMA file name\n" ) );
_tprintf( _T( " -o <OUTPUT_FILE> = output file name\n" ) );
_tprintf( _T( " -ps <SYSTEM_PROFILE_INDEX> = load the system profile by index\n" ) );
_tprintf( _T( " -pf <CUSTOM_PROFILE_FILE> = load custom profile by file name\n" ) );
_tprintf( _T( " -m = use multi-pass encoding if supported by the codec\n" ) );
_tprintf( _T( " -c = enable multi-channel output if the audio stream supports (for WinXP or newer only)\n" ) );
_tprintf( _T( " -s = enable smart recompression if the source has one or more audio streams\n" ) );
_tprintf( _T( "\n" ) );
//
// List system profiles
//
HRESULT hr = CWMVRecompress::ListSystemProfile();
if( FAILED( hr ) )
{
_tprintf( _T( "Could not list system profile (hr=0x%08x).\n" ), hr );
}
}
////////////////////////////////////////////////////////////////////////////////
int __cdecl _tmain( int argc, __in_ecount(argc) LPTSTR argv[] )
{
HRESULT hr = S_OK;
WCHAR * pwszOutFile = NULL;
WCHAR * pwszInFile = NULL;
WCHAR * pwszCustomProfile = NULL;
DWORD dwSystemProfile = 0xFFFFFFFF;
BOOL fMultiPass = FALSE;
BOOL fMultiChannel = FALSE;
BOOL fSmartRecompression = FALSE;
BOOL fValidArgument = FALSE;
IWMProfile * pIWMProfile = NULL;
CWMVRecompress * pWMVRecompress = NULL;
//
// Initial COM library
//
hr = CoInitialize( NULL );
if( FAILED( hr ) )
{
_tprintf( _T( "CoInitialize failed: (hr=0x%08x)\n" ), hr );
return( hr );
}
do
{
//
// Parse the command line
//
int i;
for( i = 1; i < argc; i ++ )
{
fValidArgument = FALSE;
if( 0 == _tcsicmp( argv[i], _T( "-i" ) ) )
{
i++;
if( i >= argc )
{
break;
}
hr = ConvertTCharToWChar( argv[i], &pwszInFile );
if( FAILED( hr ) )
{
break;
}
}
else if( 0 == _tcsicmp( argv[i], _T( "-o" ) ) )
{
i++;
if( i >= argc )
{
break;
}
hr = ConvertTCharToWChar( argv[i], &pwszOutFile );
if( FAILED( hr ) )
{
break;
}
}
else if( 0 == _tcsicmp( argv[i], _T( "-ps" ) ) )
{
i++;
if( i >= argc )
{
break;
}
if( !_stscanf_s( argv[i], _T( "%d" ), &dwSystemProfile ) )
{
break;
}
}
else if( 0 == _tcsicmp( argv[i], _T( "-pf" ) ) )
{
i++;
if( i >= argc )
{
break;
}
hr = ConvertTCharToWChar( argv[i], &pwszCustomProfile );
if( FAILED( hr ) )
{
break;
}
}
else if( 0 == _tcsicmp( argv[i], _T( "-m" ) ) )
{
fMultiPass = TRUE;
}
else if( 0 == _tcsicmp( argv[i], _T( "-c" ) ) )
{
fMultiChannel = TRUE;
}
else if( 0 == _tcsicmp( argv[i], _T( "-s" ) ) )
{
fSmartRecompression = TRUE;
}
else
{
break;
}
fValidArgument = TRUE;
}
if( !fValidArgument || i < argc )
{
hr = E_INVALIDARG;
_tprintf( _T( "Invalid argument.\n" ) );
Usage();
break;
}
//
// The input file and the output file must not be empty, or equal.
//
if( NULL == pwszInFile ||
NULL == pwszOutFile ||
0 == _wcsicmp(pwszInFile, pwszOutFile) )
{
hr = E_INVALIDARG;
_tprintf( _T( "Input file and output file must be specified.\n" ) );
Usage();
break;
}
//
// MultiChannel output is only supported on Windows XP. We need to check
// the current OS version to ascertain whether multichannel output is enabled.
//
if( fMultiChannel )
{
OSVERSIONINFO vi;
memset( &vi, 0, sizeof( vi ) );
vi.dwOSVersionInfoSize = sizeof( vi );
if( !GetVersionEx( &vi ) )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
_tprintf( _T( "Could not get the system version.\n" ) );
break;
}
if( vi.dwMajorVersion < 5
|| vi.dwMajorVersion == 5 && vi.dwMinorVersion < 1 )
{
hr = E_INVALIDARG;
_tprintf( _T( "Multi-channel is only supported on Windows XP or newer version.\n" ) );
Usage();
break;
}
}
if( 0xFFFFFFFF != dwSystemProfile )
{
if( NULL != pwszCustomProfile )
{
//
// System profile and custom profile cannot be used together.
//
hr = E_INVALIDARG;
_tprintf( _T( "System profile and custom profile can not be used together.\n" ) );
break;
}
else
{
//
// Load system profile
//
hr = CWMVRecompress::LoadSystemProfile( dwSystemProfile, &pIWMProfile );
if( FAILED( hr ) )
{
_tprintf( _T( "Could not load system profile (hr=0x%08x)\n" ), hr );
break;
}
}
}
else if( NULL != pwszCustomProfile )
{
//
// Load custom profile
//
hr = CWMVRecompress::LoadCustomProfile( pwszCustomProfile, &pIWMProfile );
if( FAILED( hr ) )
{
_tprintf( _T( "Could not load custom profile %s (hr=0x%08x)\n" ), pwszCustomProfile, hr );
break;
}
}
else
{
hr = E_INVALIDARG;
_tprintf( _T( "Systemp profile or custom profile must be specified.\n" ) );
break;
}
pWMVRecompress = new CWMVRecompress();
if( NULL == pWMVRecompress )
{
hr = E_OUTOFMEMORY;
_tprintf( _T( "Could not allocate memory for CWMVRecompress: (hr=0x%08x)\n" ), hr );
break;
}
//
// Recompress the WMV file using the specified profile.
//
hr = pWMVRecompress->Recompress( pwszInFile,
pwszOutFile,
pIWMProfile,
fMultiPass,
fMultiChannel,
fSmartRecompression );
if( FAILED( hr ) )
{
break;
}
}
while ( FALSE );
//
// Release all resources
//
SAFE_ARRAYDELETE( pwszCustomProfile );
SAFE_ARRAYDELETE( pwszOutFile );
SAFE_ARRAYDELETE( pwszInFile );
SAFE_RELEASE( pWMVRecompress );
SAFE_RELEASE( pIWMProfile );
CoUninitialize();
return( hr );
}