//***************************************************************************** // // Microsoft Windows Media // Copyright ( C) Microsoft Corporation. All rights reserved. // // FileName: main.cpp // // Abstract: Parse the parameters and call CWMVRecompress::Recompress // //***************************************************************************** #include #include #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 -o \n" ) ); _tprintf( _T( " { -ps | -pf }\n" ) ); _tprintf( _T( " [-m] [-c] [-s]\n" ) ); _tprintf( _T( " -i = input ASF/WMV/WMA file name\n" ) ); _tprintf( _T( " -o = output file name\n" ) ); _tprintf( _T( " -ps = load the system profile by index\n" ) ); _tprintf( _T( " -pf = 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 ); }