You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
6.3 KiB
225 lines
6.3 KiB
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// The contents of this file are subject to the Mozilla Public License
|
|
// Version 1.1 (the "License"); you may not use this file except in
|
|
// compliance with the License. You may obtain a copy of the License at
|
|
// http://www.mozilla.org/MPL/
|
|
//
|
|
// Software distributed under the License is distributed on an "AS IS"
|
|
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
|
// License for the specific language governing rights and limitations
|
|
// under the License.
|
|
//
|
|
// The Original Code is MP4v2.
|
|
//
|
|
// The Initial Developer of the Original Code is Kona Blend.
|
|
// Portions created by Kona Blend are Copyright (C) 2008.
|
|
// Portions created by David Byron are Copyright (C) 2010.
|
|
// All Rights Reserved.
|
|
//
|
|
// Contributors:
|
|
// Kona Blend, kona8lend@@gmail.com
|
|
// David Byron, dbyron@dbyron.com
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "util/impl.h"
|
|
|
|
namespace mp4v2 { namespace util {
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
class FileUtility : public Utility
|
|
{
|
|
private:
|
|
enum FileLongCode {
|
|
LC_LIST = _LC_MAX,
|
|
LC_OPTIMIZE,
|
|
LC_DUMP,
|
|
};
|
|
|
|
public:
|
|
FileUtility( int, char** );
|
|
|
|
protected:
|
|
// delegates implementation
|
|
bool utility_option( int, bool& );
|
|
bool utility_job( JobContext& );
|
|
|
|
private:
|
|
bool actionList ( JobContext& );
|
|
bool actionOptimize ( JobContext& );
|
|
bool actionDump ( JobContext& );
|
|
|
|
private:
|
|
Group _actionGroup;
|
|
|
|
bool (FileUtility::*_action)( JobContext& );
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
FileUtility::FileUtility( int argc, char** argv )
|
|
: Utility ( "mp4file", argc, argv )
|
|
, _actionGroup ( "ACTIONS" )
|
|
, _action ( NULL )
|
|
{
|
|
// add standard options which make sense for this utility
|
|
_group.add( STD_DRYRUN );
|
|
_group.add( STD_KEEPGOING );
|
|
_group.add( STD_QUIET );
|
|
_group.add( STD_DEBUG );
|
|
_group.add( STD_VERBOSE );
|
|
_group.add( STD_HELP );
|
|
_group.add( STD_VERSION );
|
|
_group.add( STD_VERSIONX );
|
|
|
|
_actionGroup.add( "list", false, LC_LIST, "list (summary information)" );
|
|
_actionGroup.add( "optimize", false, LC_OPTIMIZE, "optimize mp4 structure" );
|
|
_actionGroup.add( "dump", false, LC_DUMP, "dump mp4 structure in human-readable format" );
|
|
_groups.push_back( &_actionGroup );
|
|
|
|
_usage = "[OPTION]... ACTION file...";
|
|
_description =
|
|
// 79-cols, inclusive, max desired width
|
|
// |----------------------------------------------------------------------------|
|
|
"\nFor each mp4 file specified, perform the specified ACTION. An action must be"
|
|
"\nspecified. Some options are not applicable to some actions.";
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool
|
|
FileUtility::actionDump( JobContext& job )
|
|
{
|
|
job.fileHandle = MP4Read( job.file.c_str() );
|
|
if( job.fileHandle == MP4_INVALID_FILE_HANDLE )
|
|
return herrf( "unable to open for read: %s\n", job.file.c_str() );
|
|
|
|
if( !MP4Dump( job.fileHandle, _debugImplicits ))
|
|
return herrf( "dump failed: %s\n", job.file.c_str() );
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool
|
|
FileUtility::actionList( JobContext& job )
|
|
{
|
|
ostringstream report;
|
|
|
|
const int wbrand = 5;
|
|
const int wcompat = 18;
|
|
const int wsizing = 6;
|
|
const string sep = " ";
|
|
|
|
if( _jobCount == 0 ) {
|
|
report << setw(wbrand) << left << "BRAND"
|
|
<< sep << setw(wcompat) << left << "COMPAT"
|
|
<< sep << setw(wsizing) << left << "SIZING"
|
|
<< sep << setw(0) << "FILE"
|
|
<< '\n';
|
|
|
|
report << setfill('-') << setw(70) << "" << setfill(' ') << '\n';
|
|
}
|
|
|
|
job.fileHandle = MP4Read( job.file.c_str() );
|
|
if( job.fileHandle == MP4_INVALID_FILE_HANDLE )
|
|
return herrf( "unable to open for read: %s\n", job.file.c_str() );
|
|
|
|
FileSummaryInfo info;
|
|
if( fileFetchSummaryInfo( job.fileHandle, info ))
|
|
return herrf( "unable to fetch file summary info" );
|
|
|
|
string compat;
|
|
{
|
|
const FileSummaryInfo::BrandSet::iterator ie = info.compatible_brands.end();
|
|
int count = 0;
|
|
for( FileSummaryInfo::BrandSet::iterator it = info.compatible_brands.begin(); it != ie; it++, count++ ) {
|
|
if( count > 0 )
|
|
compat += ',';
|
|
compat += *it;
|
|
}
|
|
}
|
|
|
|
const bool sizing = info.nlargesize | info.nversion1 | info.nspecial;
|
|
|
|
report << setw(wbrand) << left << info.major_brand
|
|
<< sep << setw(wcompat) << left << compat
|
|
<< sep << setw(wsizing) << left << (sizing ? "64-bit" : "32-bit")
|
|
<< sep << job.file
|
|
<< '\n';
|
|
|
|
verbose1f( "%s", report.str().c_str() );
|
|
return SUCCESS;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool
|
|
FileUtility::actionOptimize( JobContext& job )
|
|
{
|
|
verbose1f( "optimizing %s\n", job.file.c_str() );
|
|
|
|
if( dryrunAbort() )
|
|
return SUCCESS;
|
|
|
|
if( !MP4Optimize( job.file.c_str(), NULL ))
|
|
return herrf( "optimize failed: %s\n", job.file.c_str() );
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool
|
|
FileUtility::utility_job( JobContext& job )
|
|
{
|
|
if( !_action )
|
|
return herrf( "no action specified\n" );
|
|
|
|
return (this->*_action)( job );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool
|
|
FileUtility::utility_option( int code, bool& handled )
|
|
{
|
|
handled = true;
|
|
|
|
switch( code ) {
|
|
case LC_LIST:
|
|
_action = &FileUtility::actionList;
|
|
break;
|
|
|
|
case LC_OPTIMIZE:
|
|
_action = &FileUtility::actionOptimize;
|
|
break;
|
|
|
|
case LC_DUMP:
|
|
_action = &FileUtility::actionDump;
|
|
break;
|
|
|
|
default:
|
|
handled = false;
|
|
break;
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
}} // namespace mp4v2::util
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
extern "C"
|
|
int main( int argc, char** argv )
|
|
{
|
|
mp4v2::util::FileUtility util( argc, argv );
|
|
return util.process();
|
|
}
|