| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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(); |
| } |