/*---------------------------------------------------------------------- | ParseCommandLine +---------------------------------------------------------------------*/ static void ParseCommandLine(char** args) { const char* arg; /* default values */ Options.path = NULL; Options.friendly_name = NULL; Options.broadcast = false; Options.port = 0; while ((arg = *args++)) { if (!strcmp(arg, "-f")) { Options.friendly_name = *args++; } else if (!strcmp(arg, "-p")) { if (NPT_FAILED(NPT_ParseInteger32U(*args++, Options.port))) { fprintf(stderr, "ERROR: invalid argument\n"); PrintUsageAndExit(); } } else if (!strcmp(arg, "-b")) { Options.broadcast = true; } else if (Options.path == NULL) { Options.path = arg; } else { fprintf(stderr, "ERROR: too many arguments\n"); PrintUsageAndExit(); } } /* check args */ if (Options.path == NULL) { fprintf(stderr, "ERROR: path missing\n"); PrintUsageAndExit(); } }
int main(int argc, char *argv[]) { int opt; while ((opt = getopt(argc, argv, "ql:d:uw:f:bc:s:")) != -1) { switch (opt) { case 'q': quietFlag = 1; break; case 'd': { char *c = optarg; while (*c) { Debug_SetFlag(*c, 1); c++; } break; } default: PrintUsageAndExit(argv[0]); } } if (optind != argc-1) { PrintUsageAndExit(argv[0]); } char *configfile = argv[optind]; int err = ReadConfigFile(configfile); if (err < 0) { exit(EXIT_FAILURE); } /* * Since we create a process (i.e. fork) we need to clean up its state when * we exit. We do this by having the OS send us a signal when something * finishes. */ signal(SIGCHLD, handleSIGCHLD); err = InitializeBackends(); if (err < 0) { exit(EXIT_FAILURE); } int listenfd = SetupListenSocket(); if(listenfd < 0){ exit(EXIT_FAILURE); } HandleConnections(listenfd); return 0; /* Never reached. */ }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { // check command line if (argc != 3) { PrintUsageAndExit(); } // init options Options.verbose = true; ServerType server_type = SERVER_TYPE_UNKNOWN; int port = -1; // parse command line if (!strcmp(argv[1], "udp")) { server_type = SERVER_TYPE_UDP; } else if (!strcmp(argv[1], "tcp")) { server_type = SERVER_TYPE_TCP; } else { fprintf(stderr, "ERROR: unknown server type\n"); exit(1); } port = strtoul(argv[2], NULL, 10); switch (server_type) { case SERVER_TYPE_TCP: TcpServerLoop(port); break; case SERVER_TYPE_UDP: UdpServerLoop(port); break; default: break; } return 0; }
/*---------------------------------------------------------------------- | ParseCommandLine +---------------------------------------------------------------------*/ static void ParseCommandLine(char** args) { const char* arg; char** tmp = args+1; /* default values */ Options.port = 0; Options.path = ""; while ((arg = *tmp++)) { if (Options.port == 0 && !strcmp(arg, "-p")) { long port; if (NPT_FAILED(NPT_ParseInteger(*tmp++, port, false))) { fprintf(stderr, "ERROR: invalid port\n"); exit(1); } Options.port = port; } else if (Options.path.IsEmpty() && !strcmp(arg, "-f")) { Options.path = *tmp++; } else { fprintf(stderr, "ERROR: too many arguments\n"); PrintUsageAndExit(args); } } }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc == 1) PrintUsageAndExit(); // parse options const char* input_filename = NULL; const char* output_filename = NULL; bool verbose = false; AP4_Result result; // parse the command line arguments char* arg; while ((arg = *++argv)) { if (!AP4_CompareStrings(arg, "--verbose")) { verbose = true; } else if (input_filename == NULL) { input_filename = arg; } else if (output_filename == NULL) { output_filename = arg; } else { fprintf(stderr, "ERROR: unexpected argument (%s)\n", arg); return 1; } } // create the input stream AP4_ByteStream* input = NULL; result = AP4_FileByteStream::Create(input_filename, AP4_FileByteStream::STREAM_MODE_READ, input); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open input file (%s)\n", input_filename); return 1; } // create the output stream AP4_ByteStream* output = NULL; result = AP4_FileByteStream::Create(output_filename, AP4_FileByteStream::STREAM_MODE_WRITE, output); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open output file (%s)\n", output_filename); return 1; } // process the file AP4_CompactingProcessor* processor = new AP4_CompactingProcessor(verbose); result = processor->Process(*input, *output, NULL); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: failed to process the file (%d)\n", result); } // cleanup delete processor; input->Release(); output->Release(); return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { AP4_Result result = AP4_SUCCESS; // parse the command line if (argc != 2) PrintUsageAndExit(); // create the input stream AP4_ByteStream* input; try { input = new AP4_FileByteStream(argv[1], AP4_FileByteStream::STREAM_MODE_READ); } catch (AP4_Exception) { fprintf(stderr, "ERROR: cannot open input file (%s)\n", argv[1]); return 1; } AP4_File* file = new AP4_File(*input); AP4_Movie* movie = file->GetMovie(); if (movie != NULL) { // get a hint track reader AP4_Track* hint_track = movie->GetTrack(AP4_Track::TYPE_HINT, 1); if (hint_track == NULL) { AP4_Debug("No hint track in this movie\n"); return AP4_FAILURE; } AP4_HintTrackReader reader(*hint_track, *movie, 0x01020304); AP4_String rtp_file_name(argv[1]); rtp_file_name += ".rtp"; // display the sdp AP4_String sdp; reader.GetSdpText(sdp); AP4_Debug("sdp:\n%s\n\n", sdp.c_str()); // dump the packet result = DumpRtpPackets(reader, rtp_file_name.c_str()); if (AP4_FAILED(result)) goto bail; } else { AP4_Debug("No movie found in the file\n"); return AP4_FAILURE; } bail: delete file; input->Release(); return result; }
int main(int argc, char* argv[]) { if (argc != 2) PrintUsageAndExit(); vector<CWordInfo> WordInfos; string BigramsFileName = argv[1]; string WordFreqFileName = MakeFName(BigramsFileName, "wrd_freq"); // читаем статистику слов if (!ReadWordFreqs(WordFreqFileName, WordInfos)) return 1; // создаем бинарный файл для биграмм if (!BuildBigramsBin(BigramsFileName, WordInfos, true)) return 1; { string RevFile = MakeFName(BigramsFileName, "rev"); string Command = Format ("gsort -k 2,3 <%s >%s", BigramsFileName.c_str(), RevFile.c_str()); fprintf (stderr, "%s\n", Command.c_str()); if (system (Command.c_str()) != 0) { fprintf (stderr,"!!! an exception occurred (cannot sort) !!!\n"); return 1; }; if (!BuildBigramsBin(RevFile, WordInfos, false)) return 1; fprintf (stderr, "remove %s\n", RevFile.c_str()); remove(RevFile.c_str()); } string OutIndexFile = MakeFName(BigramsFileName, "wrd_idx"); fprintf (stderr, "create file %s\n", OutIndexFile.c_str()); FILE* fp = fopen (OutIndexFile.c_str(), "w"); if (!fp) { fprintf (stderr, "cannot open file %s\n", OutIndexFile.c_str()); return 1; } for (vector<CWordInfo>::const_iterator it = WordInfos.begin(); it != WordInfos.end(); it++) { fprintf (fp, "%s %u %u %u %u %u\n",it->m_WordStr.c_str(), it->m_Freq, it->m_FileOffset1,it->m_FileLen1, it->m_FileOffset2,it->m_FileLen2 ); } fclose (fp); return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc != 2) { PrintUsageAndExit(); } const char* input_filename = argv[1]; // open the input AP4_ByteStream* input = NULL; AP4_Result result = AP4_FileByteStream::Create(input_filename, AP4_FileByteStream::STREAM_MODE_READ, input); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open input file (%s)\n", input_filename); return 1; } // get the movie AP4_File* file = new AP4_File(*input, AP4_DefaultAtomFactory::Instance, true); AP4_Movie* movie = file->GetMovie(); AP4_Atom* atom = NULL; do { // process the next atom result = AP4_DefaultAtomFactory::Instance.CreateAtomFromStream(*input, atom); if (AP4_SUCCEEDED(result)) { printf("atom size=%lld\n", atom->GetSize()); if (atom->GetType() == AP4_ATOM_TYPE_MOOF) { AP4_ContainerAtom* moof = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom); if (moof) { // remember where we are in the stream AP4_Position position = 0; input->Tell(position); // process the movie fragment ProcessMoof(movie, moof, input, position-atom->GetSize(), position+8); // go back to where we were before processing the fragment input->Seek(position); } } else { delete atom; } } } while (AP4_SUCCEEDED(result)); // cleanup delete file; input->Release(); return 0; }
/*---------------------------------------------------------------------- | ParseCommandLine +---------------------------------------------------------------------*/ static void ParseCommandLine(char** args) { char** _args = args++; const char* arg; /* default values */ Options.path = NULL; while ((arg = *args++)) { if (Options.path == NULL) { Options.path = arg; } else { fprintf(stderr, "ERROR: too many arguments\n"); PrintUsageAndExit(_args); } } /* check args */ if (Options.path == NULL) { fprintf(stderr, "ERROR: path missing\n"); PrintUsageAndExit(_args); } }
int main(int argc, char const *argv[]) { if (argc < 3) { PrintUsageAndExit(argc, argv); } NHSE::TSearchEngine searchEngine(argv[1], argv[2]); std::cerr << "Search engine is loaded\n"; std::string query; while (query != "exit") { std::cout << "Query: "; std::getline(std::cin, query); std::vector<std::string> documents = searchEngine.Search(query); PrintSearchResults(documents); } return 0; }
/* ------------------------------------------------------------ */ int main(int argc, char **argv) { if (argc != 2) { PrintUsageAndExit(); } string ConfigFile = argv[1]; CTrigramModel M; try { fprintf (stderr, "init model from %s\n", ConfigFile.c_str() ); M.InitModelFromConfigAndBuildTagset(ConfigFile, 0, 0, false); fprintf (stderr, "register tags from ngram file\n"); M.register_tags_from_ngram_file(); fprintf (stderr, "convert_to_lex_binary, lexfile=%s\n", M.m_DictionaryFile.c_str()); if (!M.convert_to_lex_binary()) return 1; if (!M.read_ngram_file()) return 1; fprintf (stderr, "compute_counts_for_boundary ... \n"); M.compute_counts_for_boundary(); fprintf (stderr, "compute_bucketed_lambdas ... \n"); M.compute_bucketed_lambdas(); M.compute_transition_probs(); M.SaveBinary(); fprintf (stderr, "exiting \n"); } catch ( CExpc c) { fprintf (stderr, "%s\n", c.m_strCause.c_str()); return 1; } catch ( ...) { fprintf (stderr, "General exception\n"); return 1; } return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc != 2) { PrintUsageAndExit(); } const char* input_filename = argv[1]; // open the input AP4_ByteStream* input = NULL; try { input = new AP4_FileByteStream(input_filename, AP4_FileByteStream::STREAM_MODE_READ); } catch (AP4_Exception) { fprintf(stderr, "ERROR: cannot open input file (%s)\n", input_filename); return 1; } // get the movie AP4_File* file = new AP4_File(*input); AP4_Movie* movie = file->GetMovie(); CHECK(movie != NULL); AP4_Track* video_track = movie->GetTrack(AP4_Track::TYPE_VIDEO); CHECK(video_track != NULL); AP4_Ordinal index; index = video_track->GetNearestSyncSampleIndex(0, true); CHECK(index == 0); index = video_track->GetNearestSyncSampleIndex(0, false); CHECK(index == 0); index = video_track->GetNearestSyncSampleIndex(1, true); CHECK(index == 0); index = video_track->GetNearestSyncSampleIndex(1, false); CHECK(index == 12); index = video_track->GetNearestSyncSampleIndex(52, true); CHECK(index == 48); index = video_track->GetNearestSyncSampleIndex(52, false); CHECK(index == video_track->GetSampleCount()); // cleanup delete file; input->Release(); return 0; }
int main(int argc, char **argv) { if (argc != 3) { PrintUsageAndExit(); } std::string mode(argv[1]); int nrows; if (mode == "--direct") { nrows = LoadText_Direct(argv[2]); } else if (mode == "--fscanf") { nrows = LoadText_Fscanf(argv[2]); } printf("Read %d rows\n", nrows); return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc != 3) { PrintUsageAndExit(); } // create the input stream AP4_Result result; AP4_ByteStream* input = NULL; result = AP4_FileByteStream::Create(argv[1], AP4_FileByteStream::STREAM_MODE_READ, input); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open input file (%s) %d\n", argv[1], result); return 1; } // create the output stream AP4_ByteStream* output = NULL; result = AP4_FileByteStream::Create(argv[2], AP4_FileByteStream::STREAM_MODE_WRITE, output); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open output file (%s) %d\n", argv[2], result); return 1; } // create the processor AP4_Processor* processor = new AP4_AacSampleDescriptionFixer; result = processor->Process(*input, *output, NULL); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: failed to process the file (%d)\n", result); } // cleanup delete processor; input->Release(); output->Release(); return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc < 2) { PrintUsageAndExit(); } // init the variables AP4_ByteStream* input = NULL; const char* filename = NULL; AP4_ProtectionKeyMap key_map; AP4_Array<AP4_Ordinal> tracks_to_dump; AP4_Ordinal verbosity = 0; bool json_format = false; // parse the command line argv++; char* arg; while ((arg = *argv++)) { if (!strcmp(arg, "--track")) { arg = *argv++; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument after --track option\n"); return 1; } char* track_ascii = arg; char* key_ascii = NULL; char* delimiter = strchr(arg, ':'); if (delimiter != NULL) { *delimiter = '\0'; key_ascii = delimiter+1; } // this track will be dumped AP4_Ordinal track_id = (AP4_Ordinal) strtoul(track_ascii, NULL, 10); tracks_to_dump.Append(track_id); // see if we have a key for this track if (key_ascii != NULL) { unsigned char key[16]; if (AP4_ParseHex(key_ascii, key, 16)) { fprintf(stderr, "ERROR: invalid hex format for key\n"); return 1; } // set the key in the map key_map.SetKey(track_id, key, 16); } } else if (!strcmp(arg, "--verbosity")) { arg = *argv++; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument after --verbosity option\n"); return 1; } verbosity = strtoul(arg, NULL, 10); } else if (!strcmp(arg, "--format")) { arg = *argv++; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument after --format option\n"); return 1; } if (strcmp(arg, "json") == 0) { json_format = true; } else if (strcmp(arg, "text")) { fprintf(stderr, "ERROR: unknown output format\n"); return 1; } } else { #ifdef __EMSCRIPTEN__ // Emscripten has to "mount" the filesystem to a virtual directory. EM_ASM(FS.mkdir('/working')); EM_ASM(FS.mount(NODEFS, { root: '.' }, '/working')); const char* const mount_name = "/working/%s"; const int filename_size = snprintf(NULL, 0, mount_name, arg); char* mounted_filename = (char*) malloc(filename_size + 1); sprintf(mounted_filename, mount_name, arg); filename = mounted_filename; #else filename = arg; #endif AP4_Result result = AP4_FileByteStream::Create(filename, AP4_FileByteStream::STREAM_MODE_READ, input); #ifdef __EMSCRIPTEN__ free(mounted_filename); mounted_filename = NULL; #endif if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open input (%d)\n", result); return 1; } } }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc < 3) { PrintUsageAndExit(); } // parse command line AP4_Result result; char** args = argv+1; unsigned char key[16]; bool key_option = false; if (!strcmp(*args, "--key")) { if (argc != 5) { fprintf(stderr, "ERROR: invalid command line\n"); return 1; } ++args; if (AP4_ParseHex(*args++, key, 16)) { fprintf(stderr, "ERROR: invalid hex format for key\n"); return 1; } key_option = true; } // create the input stream AP4_ByteStream* input = NULL; result = AP4_FileByteStream::Create(*args++, AP4_FileByteStream::STREAM_MODE_READ, input); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open input (%d)\n", result); } // create the output stream AP4_ByteStream* output = NULL; result = AP4_FileByteStream::Create(*args++, AP4_FileByteStream::STREAM_MODE_WRITE, output); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open output (%d)\n", result); } // open the file AP4_File* input_file = new AP4_File(*input); // get the movie AP4_SampleDescription* sample_description; AP4_Track* video_track; AP4_Movie* movie = input_file->GetMovie(); if (movie == NULL) { fprintf(stderr, "ERROR: no movie in file\n"); goto end; } // get the video track video_track = movie->GetTrack(AP4_Track::TYPE_VIDEO); if (video_track == NULL) { fprintf(stderr, "ERROR: no video track found\n"); goto end; } // check that the track is of the right type sample_description = video_track->GetSampleDescription(0); if (sample_description == NULL) { fprintf(stderr, "ERROR: unable to parse sample description\n"); goto end; } // show info AP4_Debug("Video Track:\n"); AP4_Debug(" duration: %ld ms\n", video_track->GetDurationMs()); AP4_Debug(" sample count: %ld\n", video_track->GetSampleCount()); switch (sample_description->GetType()) { case AP4_SampleDescription::TYPE_HEVC: WriteSamples(video_track, sample_description, output); break; case AP4_SampleDescription::TYPE_PROTECTED: if (!key_option) { fprintf(stderr, "ERROR: encrypted tracks require a key\n"); goto end; } DecryptAndWriteSamples(video_track, sample_description, key, output); break; default: fprintf(stderr, "ERROR: unsupported sample type\n"); break; } end: delete input_file; input->Release(); output->Release(); return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc < 2) { PrintUsageAndExit(); } // init the variables const char* input_filename = NULL; const char* output_filename = NULL; const char* track_selector = NULL; AP4_UI32 selected_track_id = 0; unsigned int fragment_duration = 0; bool auto_detect_fragment_duration = true; bool create_segment_index = false; bool quiet = false; AP4_UI32 timescale = 0; AP4_Result result; Options.verbosity = 1; Options.debug = false; Options.trim = false; Options.no_tfdt = false; Options.force_i_frame_sync = AP4_FRAGMENTER_FORCE_SYNC_MODE_NONE; // parse the command line argv++; char* arg; while ((arg = *argv++)) { if (!strcmp(arg, "--verbosity")) { arg = *argv++; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument after --verbosity option\n"); return 1; } Options.verbosity = strtoul(arg, NULL, 10); } else if (!strcmp(arg, "--debug")) { Options.debug = true; } else if (!strcmp(arg, "--index")) { create_segment_index = true; } else if (!strcmp(arg, "--quiet")) { quiet = true; } else if (!strcmp(arg, "--trim")) { Options.trim = true; } else if (!strcmp(arg, "--no-tfdt")) { Options.no_tfdt = true; } else if (!strcmp(arg, "--force-i-frame-sync")) { arg = *argv++; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument after --fragment-duration option\n"); return 1; } if (!strcmp(arg, "all")) { Options.force_i_frame_sync = AP4_FRAGMENTER_FORCE_SYNC_MODE_ALL; } else if (!strcmp(arg, "auto")) { Options.force_i_frame_sync = AP4_FRAGMENTER_FORCE_SYNC_MODE_AUTO; } else { fprintf(stderr, "ERROR: unknown mode for --force-i-frame-sync\n"); return 1; } } else if (!strcmp(arg, "--fragment-duration")) { arg = *argv++; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument after --fragment-duration option\n"); return 1; } fragment_duration = strtoul(arg, NULL, 10); auto_detect_fragment_duration = false; } else if (!strcmp(arg, "--timescale")) { arg = *argv++; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument after --timescale option\n"); return 1; } timescale = strtoul(arg, NULL, 10); } else if (!strcmp(arg, "--track")) { track_selector = *argv++; if (track_selector == NULL) { fprintf(stderr, "ERROR: missing argument after --track option\n"); return 1; } } else { if (input_filename == NULL) { input_filename = arg; } else if (output_filename == NULL) { output_filename = arg; } else { fprintf(stderr, "ERROR: unexpected argument '%s'\n", arg); return 1; } } } if (Options.debug && Options.verbosity == 0) { Options.verbosity = 1; } if (input_filename == NULL) { fprintf(stderr, "ERROR: no input specified\n"); return 1; } AP4_ByteStream* input_stream = NULL; result = AP4_FileByteStream::Create(input_filename, AP4_FileByteStream::STREAM_MODE_READ, input_stream); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open input (%d)\n", result); return 1; } if (output_filename == NULL) { fprintf(stderr, "ERROR: no output specified\n"); return 1; } AP4_ByteStream* output_stream = NULL; result = AP4_FileByteStream::Create(output_filename, AP4_FileByteStream::STREAM_MODE_WRITE, output_stream); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot create/open output (%d)\n", result); return 1; } // parse the input MP4 file (moov only) AP4_File input_file(*input_stream, AP4_DefaultAtomFactory::Instance, true); // check the file for basic properties if (input_file.GetMovie() == NULL) { fprintf(stderr, "ERROR: no movie found in the file\n"); return 1; } if (!quiet && input_file.GetMovie()->HasFragments()) { fprintf(stderr, "NOTICE: file is already fragmented, it will be re-fragmented\n"); } // create a cusor list to keep track of the tracks we will read from AP4_Array<TrackCursor*> cursors; // iterate over all tracks TrackCursor* video_track = NULL; TrackCursor* audio_track = NULL; TrackCursor* subtitles_track = NULL; unsigned int video_track_count = 0; unsigned int audio_track_count = 0; unsigned int subtitles_track_count = 0; for (AP4_List<AP4_Track>::Item* track_item = input_file.GetMovie()->GetTracks().FirstItem(); track_item; track_item = track_item->GetNext()) { AP4_Track* track = track_item->GetData(); // sanity check if (track->GetSampleCount() == 0 && !input_file.GetMovie()->HasFragments()) { fprintf(stderr, "WARNING: track %d has no samples, it will be skipped\n", track->GetId()); continue; } // create a sample array for this track SampleArray* sample_array; if (input_file.GetMovie()->HasFragments()) { sample_array = new CachedSampleArray(track); } else { sample_array = new SampleArray(track); } // create a cursor for the track TrackCursor* cursor = new TrackCursor(track, sample_array); cursor->m_Tfra->SetTrackId(track->GetId()); cursors.Append(cursor); if (track->GetType() == AP4_Track::TYPE_VIDEO) { if (video_track) { fprintf(stderr, "WARNING: more than one video track found\n"); } else { video_track = cursor; } video_track_count++; } else if (track->GetType() == AP4_Track::TYPE_AUDIO) { if (audio_track == NULL) { audio_track = cursor; } audio_track_count++; } else if (track->GetType() == AP4_Track::TYPE_SUBTITLES) { if (subtitles_track == NULL) { subtitles_track = cursor; } subtitles_track_count++; } } if (cursors.ItemCount() == 0) { fprintf(stderr, "ERROR: no valid track found\n"); return 1; } if (track_selector) { if (!strncmp("audio", track_selector, 5)) { if (audio_track) { selected_track_id = audio_track->m_Track->GetId(); } else { fprintf(stderr, "ERROR: no audio track found\n"); return 1; } } else if (!strncmp("video", track_selector, 5)) { if (video_track) { selected_track_id = video_track->m_Track->GetId(); } else { fprintf(stderr, "ERROR: no video track found\n"); return 1; } } else if (!strncmp("subtitles", track_selector, 9)) { if (subtitles_track) { selected_track_id = subtitles_track->m_Track->GetId(); } else { fprintf(stderr, "ERROR: no subtitles track found\n"); return 1; } } else { selected_track_id = (AP4_UI32)strtol(track_selector, NULL, 10); bool found = false; for (unsigned int i=0; i<cursors.ItemCount(); i++) { if (cursors[i]->m_Track->GetId() == selected_track_id) { found = true; break; } } if (!found) { fprintf(stderr, "ERROR: track not found\n"); return 1; } } } if (video_track_count == 0 && audio_track_count == 0 && subtitles_track_count == 0) { fprintf(stderr, "ERROR: no audio, video, or subtitles track in the file\n"); return 1; } AP4_AvcSampleDescription* avc_desc = NULL; if (video_track && (Options.force_i_frame_sync != AP4_FRAGMENTER_FORCE_SYNC_MODE_NONE)) { // that feature is only supported for AVC AP4_SampleDescription* sdesc = video_track->m_Track->GetSampleDescription(0); if (sdesc) { avc_desc = AP4_DYNAMIC_CAST(AP4_AvcSampleDescription, sdesc); } if (avc_desc == NULL) { fprintf(stderr, "--force-i-frame-sync can only be used with AVC/H.264 video\n"); return 1; } } // remember where the stream was AP4_Position position; input_stream->Tell(position); // for fragmented input files, we need to populate the sample arrays if (input_file.GetMovie()->HasFragments()) { AP4_LinearReader reader(*input_file.GetMovie(), input_stream); for (unsigned int i=0; i<cursors.ItemCount(); i++) { reader.EnableTrack(cursors[i]->m_Track->GetId()); } AP4_UI32 track_id; AP4_Sample sample; do { result = reader.GetNextSample(sample, track_id); if (AP4_SUCCEEDED(result)) { for (unsigned int i=0; i<cursors.ItemCount(); i++) { if (cursors[i]->m_Track->GetId() == track_id) { cursors[i]->m_Samples->AddSample(sample); break; } } } } while (AP4_SUCCEEDED(result)); } else if (video_track && (Options.force_i_frame_sync != AP4_FRAGMENTER_FORCE_SYNC_MODE_NONE)) { AP4_Sample sample; if (Options.force_i_frame_sync == AP4_FRAGMENTER_FORCE_SYNC_MODE_AUTO) { // detect if this looks like an open-gop source for (unsigned int i=1; i<video_track->m_Samples->GetSampleCount(); i++) { if (AP4_SUCCEEDED(video_track->m_Samples->GetSample(i, sample))) { if (sample.IsSync()) { // we found a sync i-frame, assume this is *not* an open-gop source Options.force_i_frame_sync = AP4_FRAGMENTER_FORCE_SYNC_MODE_NONE; if (Options.debug) { printf("this does not look like an open-gop source, not forcing i-frame sync flags\n"); } break; } } } } if (Options.force_i_frame_sync != AP4_FRAGMENTER_FORCE_SYNC_MODE_NONE) { for (unsigned int i=0; i<video_track->m_Samples->GetSampleCount(); i++) { if (AP4_SUCCEEDED(video_track->m_Samples->GetSample(i, sample))) { if (IsIFrame(sample, avc_desc)) { video_track->m_Samples->ForceSync(i); } } } } } // return the stream to its original position input_stream->Seek(position); // auto-detect the fragment duration if needed if (auto_detect_fragment_duration) { if (video_track) { fragment_duration = AutoDetectFragmentDuration(video_track); } else if (audio_track && input_file.GetMovie()->HasFragments()) { fragment_duration = AutoDetectAudioFragmentDuration(*input_stream, audio_track); } if (fragment_duration == 0) { if (Options.verbosity > 0) { fprintf(stderr, "unable to autodetect fragment duration, using default\n"); } fragment_duration = AP4_FRAGMENTER_DEFAULT_FRAGMENT_DURATION; } else if (fragment_duration > AP4_FRAGMENTER_MAX_AUTO_FRAGMENT_DURATION) { if (Options.verbosity > 0) { fprintf(stderr, "auto-detected fragment duration too large, using default\n"); } fragment_duration = AP4_FRAGMENTER_DEFAULT_FRAGMENT_DURATION; } } // fragment the file Fragment(input_file, *output_stream, cursors, fragment_duration, timescale, selected_track_id, create_segment_index); // cleanup and exit if (input_stream) input_stream->Release(); if (output_stream) output_stream->Release(); return 0; }
int main(int argc, const char *argv[]) { int returnCode = 0; MAINHELPER_SETUP_MEMORY_LEAK_EXIT_REPORT("bbackupctl.memleaks", "bbackupctl") MAINHELPER_START Logging::SetProgramName("bbackupctl"); // Filename for configuration file? std::string configFilename = BOX_GET_DEFAULT_BBACKUPD_CONFIG_FILE; // See if there's another entry on the command line int c; std::string options("c:"); options += Logging::OptionParser::GetOptionString(); Logging::OptionParser LogLevel; while((c = getopt(argc, (char * const *)argv, options.c_str())) != -1) { switch(c) { case 'c': // store argument configFilename = optarg; break; default: int ret = LogLevel.ProcessOption(c); if(ret != 0) { PrintUsageAndExit(ret); } } } // Adjust arguments argc -= optind; argv += optind; // Check there's a command if(argc != 1) { PrintUsageAndExit(2); } Logging::FilterConsole(LogLevel.GetCurrentLevel()); // Read in the configuration file BOX_INFO("Using configuration file " << configFilename); std::string errs; std::auto_ptr<Configuration> config( Configuration::LoadAndVerify (configFilename, &BackupDaemonConfigVerify, errs)); if(config.get() == 0 || !errs.empty()) { BOX_ERROR("Invalid configuration file: " << errs); return 1; } // Easier coding const Configuration &conf(*config); // Check there's a socket defined in the config file if(!conf.KeyExists("CommandSocket")) { BOX_ERROR("Daemon isn't using a control socket, " "could not execute command.\n" "Add a CommandSocket declaration to the " "bbackupd.conf file."); return 1; } // Connect to socket #ifndef WIN32 SocketStream connection; #else /* WIN32 */ WinNamedPipeStream connection; #endif /* ! WIN32 */ try { #ifdef WIN32 std::string socket = conf.GetKeyValue("CommandSocket"); connection.Connect(socket); #else connection.Open(Socket::TypeUNIX, conf.GetKeyValue("CommandSocket").c_str()); #endif } catch(...) { BOX_ERROR("Failed to connect to daemon control socket.\n" "Possible causes:\n" " * Daemon not running\n" " * Daemon busy syncing with store server\n" " * Another bbackupctl process is communicating with the daemon\n" " * Daemon is waiting to recover from an error" ); return 1; } // For receiving data IOStreamGetLine getLine(connection); // Wait for the configuration summary std::string configSummary; if(!getLine.GetLine(configSummary, false, PROTOCOL_DEFAULT_TIMEOUT)) { BOX_ERROR("Failed to receive configuration summary " "from daemon"); return 1; } // Was the connection rejected by the server? if(getLine.IsEOF()) { BOX_ERROR("Server rejected the connection. Are you running " "bbackupctl as the same user as the daemon?"); return 1; } // Decode it int autoBackup, updateStoreInterval, minimumFileAge, maxUploadWait; if(::sscanf(configSummary.c_str(), "bbackupd: %d %d %d %d", &autoBackup, &updateStoreInterval, &minimumFileAge, &maxUploadWait) != 4) { BOX_ERROR("Config summary didn't decode."); return 1; } // Print summary? BOX_TRACE("Daemon configuration summary:\n" " AutomaticBackup = " << (autoBackup?"true":"false") << "\n" " UpdateStoreInterval = " << updateStoreInterval << " seconds\n" " MinimumFileAge = " << minimumFileAge << " seconds\n" " MaxUploadWait = " << maxUploadWait << " seconds"); std::string stateLine; if(!getLine.GetLine(stateLine, false, PROTOCOL_DEFAULT_TIMEOUT) || getLine.IsEOF()) { BOX_ERROR("Failed to receive state line from daemon"); return 1; } // Decode it int currentState; if(::sscanf(stateLine.c_str(), "state %d", ¤tState) != 1) { BOX_ERROR("Received invalid state line from daemon"); return 1; } BOX_TRACE("Current state: " << BackupDaemon::GetStateName(currentState)); Command command = Default; std::string commandName(argv[0]); if(commandName == "wait-for-sync") { command = WaitForSyncStart; } else if(commandName == "wait-for-end") { command = WaitForSyncEnd; } else if(commandName == "sync-and-wait") { command = SyncAndWaitForEnd; } else if(commandName == "status") { BOX_NOTICE("state " << BackupDaemon::GetStateName(currentState)); command = NoCommand; } switch(command) { case WaitForSyncStart: case WaitForSyncEnd: { // Check that it's in automatic mode, // because otherwise it'll never start if(!autoBackup) { BOX_ERROR("Daemon is not in automatic mode, " "sync will never start!"); return 1; } } break; case SyncAndWaitForEnd: { // send a sync command commandName = "force-sync"; std::string cmd = commandName + "\n"; connection.Write(cmd, PROTOCOL_DEFAULT_TIMEOUT); connection.WriteAllBuffered(); if(currentState != 0) { BOX_INFO("Waiting for current sync/error state " "to finish..."); } } break; default: { // Normal case, just send the command given, plus a // quit command. std::string cmd = commandName + "\n"; connection.Write(cmd, PROTOCOL_DEFAULT_TIMEOUT); } // fall through case NoCommand: { // Normal case, just send the command given plus a // quit command. std::string cmd = "quit\n"; connection.Write(cmd, PROTOCOL_DEFAULT_TIMEOUT); } } // Read the response std::string line; bool syncIsRunning = false; bool finished = false; while(command != NoCommand && !finished && !getLine.IsEOF() && getLine.GetLine(line, false, PROTOCOL_DEFAULT_TIMEOUT)) { BOX_TRACE("Received line: " << line); if(line.substr(0, 6) == "state ") { std::string state_str = line.substr(6); int state_num; if(sscanf(state_str.c_str(), "%d", &state_num) == 1) { BOX_INFO("Daemon state changed to: " << BackupDaemon::GetStateName(state_num)); } else { BOX_WARNING("Failed to parse line: " << line); } } switch(command) { case WaitForSyncStart: { // Need to wait for the state change... if(line == "start-sync") { // And we're done finished = true; } } break; case WaitForSyncEnd: case SyncAndWaitForEnd: { if(line == "start-sync") { BOX_TRACE("Sync started..."); syncIsRunning = true; } else if(line == "finish-sync") { if (syncIsRunning) { // And we're done BOX_TRACE("Sync finished."); finished = true; } else { BOX_TRACE("Previous sync finished."); } // daemon must still be busy } } break; default: { // Is this an OK or error line? if(line == "ok") { BOX_TRACE("Control command " "sent: " << commandName); finished = true; } else if(line == "error") { BOX_ERROR("Control command failed: " << commandName << ". Check " "command spelling."); returnCode = 1; finished = true; } } } } // Send a quit command to finish nicely connection.Write("quit\n", 5, PROTOCOL_DEFAULT_TIMEOUT); MAINHELPER_END #if defined WIN32 && ! defined BOX_RELEASE_BUILD closelog(); #endif return returnCode; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc < 2) { PrintUsageAndExit(); } const char* filename = NULL; //bool verbose = false; while (char* arg = *++argv) { if (!strcmp(arg, "--verbose")) { //verbose = true; } else { if (filename == NULL) { filename = arg; } else { fprintf(stderr, "ERROR: unexpected argument '%s'\n", arg); return 1; } } } if (filename == NULL) { fprintf(stderr, "ERROR: filename missing\n"); return 1; } AP4_ByteStream* input; try { input = new AP4_FileByteStream(filename, AP4_FileByteStream::STREAM_MODE_READ); } catch (AP4_Exception) { fprintf(stderr, "ERROR: cannot open input file (%s)\n", argv[1]); return 1; } AP4_AvcNalParser parser; unsigned int nalu_count = 0; for (;;) { bool eos; unsigned char input_buffer[4096]; AP4_Size bytes_in_buffer = 0; AP4_Result result = input->ReadPartial(input_buffer, sizeof(input_buffer), bytes_in_buffer); if (AP4_SUCCEEDED(result)) { eos = false; } else if (result == AP4_ERROR_EOS) { eos = true; } else { fprintf(stderr, "ERROR: failed to read from input file\n"); break; } AP4_Size offset = 0; do { const AP4_DataBuffer* nalu = NULL; AP4_Size bytes_consumed = 0; result = parser.Feed(&input_buffer[offset], bytes_in_buffer, bytes_consumed, nalu, eos); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: Feed() failed (%d)\n", result); break; } if (nalu) { const unsigned char* nalu_payload = (const unsigned char*)nalu->GetData(); unsigned int nalu_type = nalu_payload[0]&0x1F; const char* nalu_type_name = AP4_AvcNalParser::NaluTypeName(nalu_type); if (nalu_type_name == NULL) nalu_type_name = "UNKNOWN"; printf("NALU %5d: size=%5d, type=%02d (%s)", nalu_count, (int)nalu->GetDataSize(), nalu_type, nalu_type_name); if (nalu_type == 9) { unsigned int primary_pic_type = (nalu_payload[1]>>5); const char* primary_pic_type_name = AP4_AvcNalParser::PrimaryPicTypeName(primary_pic_type); if (primary_pic_type_name == NULL) primary_pic_type_name = "UNKNOWN"; printf(" [%d:%s]\n", primary_pic_type, primary_pic_type_name); } else if (nalu_type == 1 || nalu_type == 2 || nalu_type == 5 || nalu_type == 19) { PrintSliceInfo(&nalu_payload[1]); printf("\n"); } else { printf("\n"); } nalu_count++; } offset += bytes_consumed; bytes_in_buffer -= bytes_consumed; } while (bytes_in_buffer);
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { // check command line if (argc < 2) { PrintUsageAndExit(); } // init endpoints EndPoint in_endpoint; in_endpoint.direction = ENDPOINT_DIRECTION_IN; EndPoint out_endpoint; out_endpoint.direction = ENDPOINT_DIRECTION_OUT; EndPoint* current_endpoint = &in_endpoint; // init other parameters unsigned int packet_size = PUMP_DEFAULT_PACKET_SIZE; // init options Options.verbose = false; Options.show_progress = false; // parse command line argv++; char* arg; while ((arg = *argv++)) { if (current_endpoint == NULL) { NPT_Debug("ERROR: unexpected argument (%s)\n", arg); exit(1); } if (!strcmp(arg, "--packet-size")) { packet_size = strtoul(*argv++, NULL, 10); continue; } else if (!strcmp(arg, "--verbose")) { Options.verbose = true; continue; } else if (!strcmp(arg, "--show-progress")) { Options.show_progress = true; continue; } else if (!strcmp(arg, "udp")) { if (argv[0] && argv[1]) { if (!strcmp(argv[0], "server")) { if (current_endpoint->direction == ENDPOINT_DIRECTION_OUT){ NPT_Debug("ERROR: cannot use 'udp server' as output\n"); exit(1); } current_endpoint->type = ENDPOINT_TYPE_UDP_SERVER; current_endpoint->info.udp_server.port = strtoul(argv[1], NULL, 10); argv += 2; } else if (!strcmp(argv[0], "client")) { if (current_endpoint->direction == ENDPOINT_DIRECTION_IN) { NPT_Debug("ERROR: cannot use 'udp client' as input\n"); exit(1); } if (argv[2]) { current_endpoint->type = ENDPOINT_TYPE_UDP_CLIENT; current_endpoint->info.udp_client.hostname = argv[1]; current_endpoint->info.udp_client.port = strtoul(argv[2], NULL, 10); argv += 3; } else { NPT_Debug("ERROR: missing argument for 'udp client'\n"); exit(1); } } } else { NPT_Debug("ERROR: missing argument for 'udp' endpoint\n"); exit(1); } } else if (!strcmp(arg, "multicast")) { if (argv[0] && argv[1]) { if (!strcmp(argv[0], "server")) { if (current_endpoint->direction == ENDPOINT_DIRECTION_OUT){ NPT_Debug("ERROR: cannot use 'multicast server' as output\n"); exit(1); } if (argv[2]) { current_endpoint->type = ENDPOINT_TYPE_MULTICAST_SERVER; current_endpoint->info.multicast_server.groupname = argv[1]; current_endpoint->info.multicast_server.port = strtoul(argv[2], NULL, 10); argv += 3; } else { NPT_Debug("ERROR: missing argument for 'multicast server'\n"); exit(1); } } else if (!strcmp(argv[0], "client")) { if (current_endpoint->direction == ENDPOINT_DIRECTION_IN) { NPT_Debug("ERROR: cannot use 'udp client' as input\n"); exit(1); } if (argv[2] && argv[3]) { current_endpoint->type = ENDPOINT_TYPE_MULTICAST_CLIENT; current_endpoint->info.multicast_client.groupname = argv[1]; current_endpoint->info.multicast_client.port = strtoul(argv[2], NULL, 10); current_endpoint->info.multicast_client.ttl = strtoul(argv[3], NULL, 10); argv += 4; } else { NPT_Debug("ERROR: missing argument for 'multicast client'\n"); exit(1); } } } else { NPT_Debug("ERROR: missing argument for 'multicast' endpoint\n"); exit(1); } } else if (!strcmp(arg, "tcp")) { if (argv[0] && argv[1]) { if (!strcmp(argv[0], "server")) { current_endpoint->type = ENDPOINT_TYPE_TCP_SERVER; current_endpoint->info.tcp_server.port = strtoul(argv[1], NULL, 10); argv += 2; } else if (!strcmp(argv[0], "client")) { if (argv[2]) { current_endpoint->type = ENDPOINT_TYPE_TCP_CLIENT; current_endpoint->info.tcp_client.hostname = argv[1]; current_endpoint->info.tcp_client.port = strtoul(argv[2], NULL, 10); argv += 3; } else { NPT_Debug("ERROR: missing argument for 'tcp client'\n"); exit(1); } } } else { NPT_Debug("ERROR: missing argument for 'tcp' endpoint\n"); exit(1); } } else if (!strcmp(arg, "file")) { if (argv[0]) { current_endpoint->type = ENDPOINT_TYPE_FILE; current_endpoint->info.file.name = *argv++; } else { NPT_Debug("ERROR: missing argument for 'file' endpoint\n"); exit(1); } } else if (!strcmp(arg, "serial")) { if (argv[0]) { current_endpoint->type = ENDPOINT_TYPE_SERIAL_PORT; current_endpoint->info.serial_port.name = *argv++; } else { NPT_Debug("ERROR: missing argument for 'serial' endpoint\n"); exit(1); } if (argv[0]) { long speed = 0; if (NPT_FAILED(NPT_ParseInteger(*argv++, speed))) { NPT_Debug("ERROR: invalid speed for 'serial' endpoint\n"); exit(1); } current_endpoint->info.serial_port.speed = (unsigned int)speed; } else { NPT_Debug("ERROR: missing argument for 'serial' endpoint\n"); exit(1); } } else { NPT_Debug("ERROR: invalid argument (%s)\n", arg); exit(1); } if (current_endpoint == &in_endpoint) { current_endpoint = &out_endpoint; } else { current_endpoint = NULL; } } if (current_endpoint) { NPT_Debug("ERROR: missing endpoint specification\n"); exit(1); } // data pump NPT_Result result; // allocate buffer unsigned char* buffer; buffer = (unsigned char*)malloc(packet_size); if (buffer == NULL) { NPT_Debug("ERROR: out of memory\n"); exit(1); } // get output stream NPT_OutputStreamReference out; result = GetEndPointStreams(&out_endpoint, NULL, &out); if (NPT_FAILED(result)) { NPT_Debug("ERROR: failed to get stream for output (%d)", result); exit(1); } unsigned long offset = 0; unsigned long total = 0; if (in_endpoint.type == ENDPOINT_TYPE_UDP_SERVER || in_endpoint.type == ENDPOINT_TYPE_MULTICAST_SERVER) { NPT_UdpSocket* udp_socket; result = GetEndPointUdpSocket(&in_endpoint, udp_socket); // packet loop NPT_DataBuffer packet(32768); NPT_SocketAddress address; do { result = udp_socket->Receive(packet, &address); if (NPT_SUCCEEDED(result)) { if (Options.verbose) { NPT_String ip = address.GetIpAddress().ToString(); NPT_Debug("Received %d bytes from %s\n", packet.GetDataSize(), ip.GetChars()); } result = out->Write(packet.GetData(), packet.GetDataSize(), NULL); offset += packet.GetDataSize(); total += packet.GetDataSize(); } } while (NPT_SUCCEEDED(result)); } else { // get the input stream NPT_InputStreamReference in; result = GetEndPointStreams(&in_endpoint, &in, NULL); if (NPT_FAILED(result)) { NPT_Debug("ERROR: failed to get stream for input (%d)\n", result); exit(1); } // stream loop do { NPT_Size bytes_read; NPT_Size bytes_written; // send result = in->Read(buffer, packet_size, &bytes_read); if (Options.show_progress) { NPT_Debug("[%d]\r", total); } if (NPT_SUCCEEDED(result) && bytes_read) { result = out->Write(buffer, bytes_read, &bytes_written); if (Options.show_progress) { NPT_Debug("[%d]\r", total); } offset += bytes_written; total += bytes_written; } else { printf("[%d] *******************\n", result); exit(1); } } while (NPT_SUCCEEDED(result)); } delete buffer; return 0; }
int main(int argc, char *argv[]) { int opt; while ((opt = getopt(argc, argv, "iqpr:")) != -1) { switch (opt) { case 'q': quietFlag = 1; break; case 'i': idumpFlag = 1; break; case 'p': pdumpFlag = 1; break; case 'r': removeFlag = optarg; break; default: PrintUsageAndExit(argv[0]); } } if (optind != argc-1) { PrintUsageAndExit(argv[0]); } char *diskpath = argv[optind]; int fd = diskimg_open(diskpath, (removeFlag == NULL)); if (fd < 0) { fprintf(stderr, "Can't open diskimagePath %s\n", diskpath); exit(EXIT_FAILURE); } struct unixfilesystem *fs = unixfilesystem_init(fd); if (!fs) { fprintf(stderr, "Failed to initialize unix filesystem\n"); exit(EXIT_FAILURE); } if (!quietFlag) { int disksize = diskimg_getsize(fd); if (disksize < 0) { fprintf(stderr, "Error getting the size of %s\n", argv[1]); // Cast the result of diskimg_close to void so the compiler doesn't // complain that we're ignoring its return value. (void) diskimg_close(fd); free(fs); exit(EXIT_FAILURE); } printf("Disk %s is %d bytes (%d KB)\n", argv[1], disksize, disksize/1024); printf("Superblock s_isize %d\n",(int)fs->superblock.s_isize); printf("Superblock s_fsize %d\n",(int)fs->superblock.s_fsize); printf("Superblock s_nfree %d\n",(int)fs->superblock.s_nfree); printf("Superblock s_ninode %d\n",(int)fs->superblock.s_ninode); } if (idumpFlag) { DumpInodeChecksum(fs, stdout); } if (pdumpFlag) { DumpPathnameChecksum(fs, stdout); } if (removeFlag) { RemovePathname(fs, removeFlag); } int err = diskimg_close(fd); if (err < 0) { fprintf(stderr, "Error closing %s\n", argv[1]); } free(fs); exit(EXIT_SUCCESS); return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc < 2) { PrintUsageAndExit(); } const char* filename = NULL; while (char* arg = *++argv) { if (filename == NULL) { filename = arg; } else { fprintf(stderr, "ERROR: unexpected argument '%s'\n", arg); return 1; } } if (filename == NULL) { fprintf(stderr, "ERROR: filename missing\n"); return 1; } AP4_ByteStream* input = NULL; AP4_Result result = AP4_FileByteStream::Create(filename, AP4_FileByteStream::STREAM_MODE_READ, input); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open input file %s (%d)\n", filename, result); return 1; } AP4_HevcParser parser; unsigned int nalu_count = 0; for (;;) { bool eos; unsigned char input_buffer[4096]; AP4_Size bytes_in_buffer = 0; result = input->ReadPartial(input_buffer, sizeof(input_buffer), bytes_in_buffer); if (AP4_SUCCEEDED(result)) { eos = false; } else if (result == AP4_ERROR_EOS) { eos = true; } else { fprintf(stderr, "ERROR: failed to read from input file\n"); break; } AP4_Size offset = 0; do { const AP4_DataBuffer* nalu = NULL; AP4_Size bytes_consumed = 0; result = parser.Feed(&input_buffer[offset], bytes_in_buffer, bytes_consumed, nalu, eos); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: Feed() failed (%d)\n", result); break; } if (nalu) { const unsigned char* nalu_payload = (const unsigned char*)nalu->GetData(); unsigned int nalu_type = (nalu_payload[0] >> 1) & 0x3F; const char* nalu_type_name = AP4_HevcParser::NaluTypeName(nalu_type); if (nalu_type_name == NULL) nalu_type_name = "UNKNOWN"; printf("NALU %5d: size=%5d, type=%02d (%s)", nalu_count, (int)nalu->GetDataSize(), nalu_type, nalu_type_name); if (nalu_type == AP4_HEVC_NALU_TYPE_AUD_NUT) { // Access Unit Delimiter unsigned int pic_type = (nalu_payload[1]>>5); const char* pic_type_name = AP4_HevcParser::PicTypeName(pic_type); if (pic_type_name == NULL) pic_type_name = "UNKNOWN"; printf(" [%d:%s]\n", pic_type, pic_type_name); } else { printf("\n"); } nalu_count++; } offset += bytes_consumed; bytes_in_buffer -= bytes_consumed; } while (bytes_in_buffer);
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc == 1) PrintUsageAndExit(); // parse options const char* kms_uri = NULL; enum Method method = METHOD_NONE; const char* input_filename = NULL; const char* output_filename = NULL; const char* fragments_info_filename = NULL; AP4_ProtectionKeyMap key_map; AP4_TrackPropertyMap property_map; bool show_progress = false; bool strict = false; AP4_Array<AP4_PsshAtom*> pssh_atoms; AP4_DataBuffer kids; unsigned int kid_count = 0; AP4_Result result; // parse the command line arguments char* arg; while ((arg = *++argv)) { if (!strcmp(arg, "--method")) { arg = *++argv; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument for --method option\n"); return 1; } if (!strcmp(arg, "OMA-PDCF-CBC")) { method = METHOD_OMA_PDCF_CBC; } else if (!strcmp(arg, "OMA-PDCF-CTR")) { method = METHOD_OMA_PDCF_CTR; } else if (!strcmp(arg, "MARLIN-IPMP-ACBC")) { method = METHOD_MARLIN_IPMP_ACBC; } else if (!strcmp(arg, "MARLIN-IPMP-ACGK")) { method = METHOD_MARLIN_IPMP_ACGK; } else if (!strcmp(arg, "PIFF-CBC")) { method = METHOD_PIFF_CBC; } else if (!strcmp(arg, "PIFF-CTR")) { method = METHOD_PIFF_CTR; } else if (!strcmp(arg, "MPEG-CENC")) { method = METHOD_MPEG_CENC; } else if (!strcmp(arg, "ISMA-IAEC")) { method = METHOD_ISMA_AES; } else { fprintf(stderr, "ERROR: invalid value for --method argument\n"); return 1; } } else if (!strcmp(arg, "--fragments-info")) { arg = *++argv; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument for --fragments-info option\n"); return 1; } fragments_info_filename = arg; } else if (!strcmp(arg, "--pssh") || !strcmp(arg, "--pssh-v1")) { bool v1 = (strcmp(arg, "--pssh-v1") == 0); arg = *++argv; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument for --pssh\n"); return 1; } if (AP4_StringLength(arg) < 32+1 || arg[32] != ':') { fprintf(stderr, "ERROR: invalid argument syntax for --pssh\n"); return 1; } unsigned char system_id[16]; arg[32] = '\0'; result = AP4_ParseHex(arg, system_id, 16); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: invalid argument syntax for --pssh\n"); return 1; } const char* pssh_filename = arg+33; // load the pssh payload AP4_DataBuffer pssh_payload; if (pssh_filename[0]) { AP4_ByteStream* pssh_input = NULL; result = AP4_FileByteStream::Create(pssh_filename, AP4_FileByteStream::STREAM_MODE_READ, pssh_input); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open pssh payload file (%d)\n", result); return 1; } AP4_LargeSize pssh_payload_size = 0; pssh_input->GetSize(pssh_payload_size); pssh_payload.SetDataSize((AP4_Size)pssh_payload_size); result = pssh_input->Read(pssh_payload.UseData(), (AP4_Size)pssh_payload_size); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot read pssh payload from file (%d)\n", result); return 1; } } AP4_PsshAtom* pssh; if (v1) { if (kid_count) { pssh = new AP4_PsshAtom(system_id, kids.GetData(), kid_count); } else { pssh = new AP4_PsshAtom(system_id); } } else { pssh = new AP4_PsshAtom(system_id); } if (pssh_payload.GetDataSize()) { pssh->SetData(pssh_payload.GetData(), pssh_payload.GetDataSize()); } pssh_atoms.Append(pssh); } else if (!strcmp(arg, "--kms-uri")) { arg = *++argv; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument for --kms-uri option\n"); return 1; } if (method != METHOD_ISMA_AES) { fprintf(stderr, "ERROR: --kms-uri only applies to method ISMA-IAEC\n"); return 1; } kms_uri = arg; } else if (!strcmp(arg, "--show-progress")) { show_progress = true; } else if (!strcmp(arg, "--strict")) { strict = true; } else if (!strcmp(arg, "--key")) { if (method == METHOD_NONE) { fprintf(stderr, "ERROR: --method argument must appear before --key\n"); return 1; } arg = *++argv; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument for --key option\n"); return 1; } char* track_ascii = NULL; char* key_ascii = NULL; char* iv_ascii = NULL; if (AP4_FAILED(AP4_SplitArgs(arg, track_ascii, key_ascii, iv_ascii))) { fprintf(stderr, "ERROR: invalid argument for --key option\n"); return 1; } unsigned int track = strtoul(track_ascii, NULL, 10); // parse the key value unsigned char key[16]; AP4_SetMemory(key, 0, sizeof(key)); if (AP4_CompareStrings(key_ascii, "random") == 0) { result = AP4_System_GenerateRandomBytes(key, 16); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: failed to generate random key (%d)\n", result); return 1; } char key_hex[32+1]; key_hex[32] = '\0'; AP4_FormatHex(key, 16, key_hex); printf("KEY.%d=%s\n", track, key_hex); } else { if (AP4_ParseHex(key_ascii, key, 16)) { fprintf(stderr, "ERROR: invalid hex format for key\n"); return 1; } } // parse the iv unsigned char iv[16]; AP4_SetMemory(iv, 0, sizeof(iv)); if (AP4_CompareStrings(iv_ascii, "random") == 0) { result = AP4_System_GenerateRandomBytes(iv, 16); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: failed to generate random key (%d)\n", result); return 1; } iv[0] &= 0x7F; // always set the MSB to 0 so we don't have wraparounds } else { unsigned int iv_size = (unsigned int)AP4_StringLength(iv_ascii)/2; if (AP4_ParseHex(iv_ascii, iv, iv_size)) { fprintf(stderr, "ERROR: invalid hex format for iv\n"); return 1; } } switch (method) { case METHOD_OMA_PDCF_CTR: case METHOD_ISMA_AES: case METHOD_PIFF_CTR: case METHOD_MPEG_CENC: // truncate the IV AP4_SetMemory(&iv[8], 0, 8); break; default: break; } // check that the key is not already there if (key_map.GetKey(track)) { fprintf(stderr, "ERROR: key already set for track %d\n", track); return 1; } // set the key in the map key_map.SetKey(track, key, 16, iv, 16); } else if (!strcmp(arg, "--property")) { char* track_ascii = NULL; char* name = NULL; char* value = NULL; if (method != METHOD_OMA_PDCF_CBC && method != METHOD_OMA_PDCF_CTR && method != METHOD_MARLIN_IPMP_ACBC && method != METHOD_MARLIN_IPMP_ACGK && method != METHOD_PIFF_CBC && method != METHOD_PIFF_CTR && method != METHOD_MPEG_CENC) { fprintf(stderr, "ERROR: this method does not use properties\n"); return 1; } arg = *++argv; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument for --property option\n"); return 1; } if (AP4_FAILED(AP4_SplitArgs(arg, track_ascii, name, value))) { fprintf(stderr, "ERROR: invalid argument for --property option\n"); return 1; } unsigned int track = strtoul(track_ascii, NULL, 10); // check that the property is not already set if (property_map.GetProperty(track, name)) { fprintf(stderr, "ERROR: property %s already set for track %d\n", name, track); return 1; } // set the property in the map property_map.SetProperty(track, name, value); // special treatment for KID properties if (!strcmp(name, "KID")) { if (AP4_StringLength(value) != 32) { fprintf(stderr, "ERROR: invalid size for KID property (must be 32 hex chars)\n"); return 1; } AP4_UI08 kid[16]; if (AP4_FAILED(AP4_ParseHex(value, kid, 16))) { fprintf(stderr, "ERROR: invalid syntax for KID property (must be 32 hex chars)\n"); return 1; } // check if we already have this KID bool kid_already_present = false; for (unsigned int i=0; i<kid_count; i++) { if (AP4_CompareMemory(kids.GetData()+(i*16), kid, 16) == 0) { kid_already_present = true; break; } } if (!kid_already_present) { ++kid_count; kids.AppendData(kid, 16); } } } else if (!strcmp(arg, "--global-option")) { arg = *++argv; char* name = NULL; char* value = NULL; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument for --global-option option\n"); return 1; } if (AP4_FAILED(AP4_SplitArgs(arg, name, value))) { fprintf(stderr, "ERROR: invalid argument for --global-option option\n"); return 1; } AP4_GlobalOptions::SetString(name, value); } else if (input_filename == NULL) { input_filename = arg; } else if (output_filename == NULL) { output_filename = arg; } else { fprintf(stderr, "ERROR: unexpected argument (%s)\n", arg); return 1; } } // check the arguments if (method == METHOD_NONE) { fprintf(stderr, "ERROR: missing --method argument\n"); return 1; } if (input_filename == NULL) { fprintf(stderr, "ERROR: missing input filename\n"); return 1; } if (output_filename == NULL) { fprintf(stderr, "ERROR: missing output filename\n"); return 1; } // create an encrypting processor AP4_Processor* processor = NULL; if (method == METHOD_ISMA_AES) { if (kms_uri == NULL) { fprintf(stderr, "ERROR: method ISMA-IAEC requires --kms-uri\n"); return 1; } AP4_IsmaEncryptingProcessor* isma_processor = new AP4_IsmaEncryptingProcessor(kms_uri); isma_processor->GetKeyMap().SetKeys(key_map); processor = isma_processor; } else if (method == METHOD_MARLIN_IPMP_ACBC || method == METHOD_MARLIN_IPMP_ACGK) { bool use_group_key = (method == METHOD_MARLIN_IPMP_ACGK); if (use_group_key) { // check that the group key is set if (key_map.GetKey(0) == NULL) { fprintf(stderr, "ERROR: method MARLIN-IPMP-ACGK requires a group key\n"); return 1; } } AP4_MarlinIpmpEncryptingProcessor* marlin_processor = new AP4_MarlinIpmpEncryptingProcessor(use_group_key); marlin_processor->GetKeyMap().SetKeys(key_map); marlin_processor->GetPropertyMap().SetProperties(property_map); processor = marlin_processor; } else if (method == METHOD_OMA_PDCF_CTR || method == METHOD_OMA_PDCF_CBC) { AP4_OmaDcfEncryptingProcessor* oma_processor = new AP4_OmaDcfEncryptingProcessor(method == METHOD_OMA_PDCF_CTR? AP4_OMA_DCF_CIPHER_MODE_CTR : AP4_OMA_DCF_CIPHER_MODE_CBC); oma_processor->GetKeyMap().SetKeys(key_map); oma_processor->GetPropertyMap().SetProperties(property_map); processor = oma_processor; } else if (method == METHOD_PIFF_CTR || method == METHOD_PIFF_CBC || method == METHOD_MPEG_CENC) { AP4_CencVariant variant = AP4_CENC_VARIANT_MPEG; switch (method) { case METHOD_PIFF_CBC: variant = AP4_CENC_VARIANT_PIFF_CBC; break; case METHOD_PIFF_CTR: variant = AP4_CENC_VARIANT_PIFF_CTR; break; case METHOD_MPEG_CENC: variant = AP4_CENC_VARIANT_MPEG; break; default: break; } AP4_CencEncryptingProcessor* cenc_processor = new AP4_CencEncryptingProcessor(variant); cenc_processor->GetKeyMap().SetKeys(key_map); cenc_processor->GetPropertyMap().SetProperties(property_map); for (unsigned int i=0; i<pssh_atoms.ItemCount(); i++) { cenc_processor->GetPsshAtoms().Append(pssh_atoms[i]); } processor = cenc_processor; } // create the input stream AP4_ByteStream* input = NULL; result = AP4_FileByteStream::Create(input_filename, AP4_FileByteStream::STREAM_MODE_READ, input); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open input file (%s)\n", input_filename); return 1; } // create the output stream AP4_ByteStream* output = NULL; result = AP4_FileByteStream::Create(output_filename, AP4_FileByteStream::STREAM_MODE_WRITE, output); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open output file (%s)\n", output_filename); return 1; } // create the fragments info stream if needed AP4_ByteStream* fragments_info = NULL; if (fragments_info_filename) { result = AP4_FileByteStream::Create(fragments_info_filename, AP4_FileByteStream::STREAM_MODE_READ, fragments_info); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open fragments info file (%s)\n", fragments_info_filename); return 1; } } // process/decrypt the file ProgressListener listener; if (fragments_info) { bool check = CheckWarning(*fragments_info, key_map, method); if (strict && check) return 1; result = processor->Process(*input, *output, *fragments_info, show_progress?&listener:NULL); } else { bool check = CheckWarning(*input, key_map, method); if (strict && check) return 1; result = processor->Process(*input, *output, show_progress?&listener:NULL); } if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: failed to process the file (%d)\n", result); } // cleanup delete processor; input->Release(); output->Release(); if (fragments_info) fragments_info->Release(); for (unsigned int i=0; i<pssh_atoms.ItemCount(); i++) { delete pssh_atoms[i]; } return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc < 2) { PrintUsageAndExit(); } // default options Options.verbose = false; Options.input = NULL; Options.init_segment_name = AP4_SPLIT_DEFAULT_INIT_SEGMENT_NAME; Options.media_segment_name = AP4_SPLIT_DEFAULT_MEDIA_SEGMENT_NAME; Options.pattern_params = AP4_SPLIT_DEFAULT_PATTERN_PARAMS; Options.start_number = 1; Options.track_id = 0; Options.audio_only = false; Options.video_only = false; Options.init_only = false; Options.track_filter = 0; // parse command line AP4_Result result; char** args = argv+1; while (const char* arg = *args++) { if (!strcmp(arg, "--verbose")) { Options.verbose = true; } else if (!strcmp(arg, "--init-segment")) { if (*args == NULL) { fprintf(stderr, "ERROR: missing argument after --init-segment option\n"); return 1; } Options.init_segment_name = *args++; } else if (!strcmp(arg, "--media-segment")) { if (*args == NULL) { fprintf(stderr, "ERROR: missing argument after --media-segment option\n"); return 1; } Options.media_segment_name = *args++; } else if (!strcmp(arg, "--pattern-parameters")) { if (*args == NULL) { fprintf(stderr, "ERROR: missing argument after --pattern-params option\n"); return 1; } Options.pattern_params = *args++; } else if (!strcmp(arg, "--track-id")) { Options.track_id = strtoul(*args++, NULL, 10); } else if (!strcmp(arg, "--start-number")) { Options.start_number = strtoul(*args++, NULL, 10); } else if (!strcmp(arg, "--init-only")) { Options.init_only = true; } else if (!strcmp(arg, "--audio")) { Options.audio_only = true; } else if (!strcmp(arg, "--video")) { Options.video_only = true; } else if (Options.input == NULL) { Options.input = arg; } else { fprintf(stderr, "ERROR: unexpected argument\n"); return 1; } } // check args if (Options.input == NULL) { fprintf(stderr, "ERROR: missing input file name\n"); return 1; } if ((Options.audio_only && (Options.video_only || Options.track_id)) || (Options.video_only && (Options.audio_only || Options.track_id)) || (Options.track_id && (Options.audio_only || Options.video_only))) { fprintf(stderr, "ERROR: --audio, --video and --track-id options are mutualy exclusive\n"); return 1; } if (strlen(Options.pattern_params) < 1) { fprintf(stderr, "ERROR: --pattern-params argument is too short\n"); return 1; } if (strlen(Options.pattern_params) > 2) { fprintf(stderr, "ERROR: --pattern-params argument is too long\n"); return 1; } const char* cursor = Options.pattern_params; while (*cursor) { if (*cursor != 'I' && *cursor != 'N') { fprintf(stderr, "ERROR: invalid pattern parameter '%c'\n", *cursor); return 1; } ++cursor; } // create the input stream AP4_ByteStream* input = NULL; result = AP4_FileByteStream::Create(Options.input, AP4_FileByteStream::STREAM_MODE_READ, input); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open input (%d)\n", result); return 1; } // get the movie AP4_File* file = new AP4_File(*input, AP4_DefaultAtomFactory::Instance, true); AP4_Movie* movie = file->GetMovie(); if (movie == NULL) { fprintf(stderr, "no movie found in file\n"); return 1; } // filter tracks if required if (Options.audio_only) { AP4_Track* track = movie->GetTrack(AP4_Track::TYPE_AUDIO); if (track == NULL) { fprintf(stderr, "--audio option specified, but no audio track found\n"); return 1; } Options.track_filter = track->GetId(); } else if (Options.video_only) { AP4_Track* track = movie->GetTrack(AP4_Track::TYPE_VIDEO); if (track == NULL) { fprintf(stderr, "--video option specified, but no video track found\n"); return 1; } Options.track_filter = track->GetId(); } else if (Options.track_id) { AP4_Track* track = movie->GetTrack(Options.track_id); if (track == NULL) { fprintf(stderr, "--track-id option specified, but no such track found\n"); return 1; } Options.track_filter = track->GetId(); } // save the init segment AP4_ByteStream* output = NULL; result = AP4_FileByteStream::Create(Options.init_segment_name, AP4_FileByteStream::STREAM_MODE_WRITE, output); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open output file (%d)\n", result); return 1; } AP4_FtypAtom* ftyp = file->GetFileType(); if (ftyp) { result = ftyp->Write(*output); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot write ftyp segment (%d)\n", result); return 1; } } if (Options.track_filter) { AP4_MoovAtom* moov = movie->GetMoovAtom(); // only keep the 'trak' atom that we need AP4_List<AP4_Atom>::Item* child = moov->GetChildren().FirstItem(); while (child) { AP4_Atom* atom = child->GetData(); child = child->GetNext(); if (atom->GetType() == AP4_ATOM_TYPE_TRAK) { AP4_TrakAtom* trak = (AP4_TrakAtom*)atom; AP4_TkhdAtom* tkhd = (AP4_TkhdAtom*)trak->GetChild(AP4_ATOM_TYPE_TKHD); if (tkhd && tkhd->GetTrackId() != Options.track_filter) { atom->Detach(); delete atom; } } } // only keep the 'trex' atom that we need AP4_ContainerAtom* mvex = AP4_DYNAMIC_CAST(AP4_ContainerAtom, moov->GetChild(AP4_ATOM_TYPE_MVEX)); if (mvex) { child = mvex->GetChildren().FirstItem(); while (child) { AP4_Atom* atom = child->GetData(); child = child->GetNext(); if (atom->GetType() == AP4_ATOM_TYPE_TREX) { AP4_TrexAtom* trex = AP4_DYNAMIC_CAST(AP4_TrexAtom, atom); if (trex && trex->GetTrackId() != Options.track_filter) { atom->Detach(); delete atom; } } } } } result = movie->GetMoovAtom()->Write(*output); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot write init segment (%d)\n", result); return 1; } AP4_Atom* atom = NULL; unsigned int track_id = 0; for (;!Options.init_only;) { // process the next atom result = AP4_DefaultAtomFactory::Instance.CreateAtomFromStream(*input, atom); if (AP4_FAILED(result)) break; if (atom->GetType() == AP4_ATOM_TYPE_MOOF) { AP4_ContainerAtom* moof = AP4_DYNAMIC_CAST(AP4_ContainerAtom, atom); unsigned int traf_count = 0; AP4_ContainerAtom* traf = NULL; do { traf = AP4_DYNAMIC_CAST(AP4_ContainerAtom, moof->GetChild(AP4_ATOM_TYPE_TRAF, traf_count)); if (traf == NULL) break; AP4_TfhdAtom* tfhd = AP4_DYNAMIC_CAST(AP4_TfhdAtom, traf->GetChild(AP4_ATOM_TYPE_TFHD)); if (tfhd == NULL) { fprintf(stderr, "ERROR: invalid media format\n"); return 1; } track_id = tfhd->GetTrackId(); traf_count++; } while (traf); // check if this fragment has more than one traf if (traf_count > 1) { if (Options.audio_only) { fprintf(stderr, "ERROR: --audio option incompatible with multi-track fragments"); return 1; } if (Options.video_only) { fprintf(stderr, "ERROR: --video option incompatible with multi-track fragments"); return 1; } track_id = 0; } // open a new file for this fragment if (output) { output->Release(); output = NULL; } char segment_name[4096]; if (Options.track_filter == 0 || Options.track_filter == track_id) { AP4_UI64 p[2] = {0,0}; unsigned int params_len = strlen(Options.pattern_params); for (unsigned int i=0; i<params_len; i++) { if (Options.pattern_params[i] == 'I') { p[i] = track_id; } else if (Options.pattern_params[i] == 'N') { p[i] = NextFragmentIndex(track_id)+Options.start_number; } } switch (params_len) { case 1: sprintf(segment_name, Options.media_segment_name, p[0]); break; case 2: sprintf(segment_name, Options.media_segment_name, p[0], p[1]); break; default: segment_name[0] = 0; break; } result = AP4_FileByteStream::Create(segment_name, AP4_FileByteStream::STREAM_MODE_WRITE, output); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open output file (%d)\n", result); return 1; } } } // write the atom if (output && atom->GetType() != AP4_ATOM_TYPE_MFRA) { atom->Write(*output); } delete atom; } // cleanup delete file; if (input) input->Release(); if (output) output->Release(); return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc < 3) { PrintUsageAndExit(); } // default options Options.segment_duration = 0; Options.pmt_pid = 0x100; Options.audio_pid = 0x101; Options.video_pid = 0x102; Options.verbose = false; Options.playlist = NULL; Options.playlist_hls_version = 3; Options.input = NULL; Options.output = NULL; Options.segment_duration_threshold = DefaultSegmentDurationThreshold; // parse command line AP4_Result result; char** args = argv+1; while (const char* arg = *args++) { if (!strcmp(arg, "--segment")) { if (*args == NULL) { fprintf(stderr, "ERROR: --segment requires a number\n"); return 1; } Options.segment_duration = strtoul(*args++, NULL, 10); } else if (!strcmp(arg, "--segment-duration-threshold")) { if (*args == NULL) { fprintf(stderr, "ERROR: --segment-duration-threshold requires a number\n"); return 1; } Options.segment_duration_threshold = strtoul(*args++, NULL, 10); } else if (!strcmp(arg, "--verbose")) { Options.verbose = true; } else if (!strcmp(arg, "--pmt-pid")) { if (*args == NULL) { fprintf(stderr, "ERROR: --pmt-pid requires a number\n"); return 1; } Options.pmt_pid = strtoul(*args++, NULL, 10); } else if (!strcmp(arg, "--audio-pid")) { if (*args == NULL) { fprintf(stderr, "ERROR: --audio-pid requires a number\n"); return 1; } Options.audio_pid = strtoul(*args++, NULL, 10); } else if (!strcmp(arg, "--video-pid")) { if (*args == NULL) { fprintf(stderr, "ERROR: --video-pid requires a number\n"); return 1; } Options.video_pid = strtoul(*args++, NULL, 10); } else if (!strcmp(arg, "--playlist")) { if (*args == NULL) { fprintf(stderr, "ERROR: --playlist requires a filename\n"); return 1; } Options.playlist = *args++; } else if (!strcmp(arg, "--playlist-hls-version")) { if (*args == NULL) { fprintf(stderr, "ERROR: --playlist-hls-version requires a number\n"); return 1; } Options.playlist_hls_version = strtoul(*args++, NULL, 10); if (Options.playlist_hls_version ==0) { fprintf(stderr, "ERROR: --playlist-hls-version requires number > 0\n"); return 1; } } else if (Options.input == NULL) { Options.input = arg; } else if (Options.output == NULL) { Options.output = arg; } else { fprintf(stderr, "ERROR: unexpected argument\n"); return 1; } } // check args if (Options.input == NULL) { fprintf(stderr, "ERROR: missing input file name\n"); return 1; } if (Options.output == NULL) { fprintf(stderr, "ERROR: missing output file name\n"); return 1; } // create the input stream AP4_ByteStream* input = NULL; result = AP4_FileByteStream::Create(Options.input, AP4_FileByteStream::STREAM_MODE_READ, input); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open input (%d)\n", result); return 1; } // open the file AP4_File* input_file = new AP4_File(*input, AP4_DefaultAtomFactory::Instance, true); // get the movie AP4_SampleDescription* sample_description; AP4_Movie* movie = input_file->GetMovie(); if (movie == NULL) { fprintf(stderr, "ERROR: no movie in file\n"); return 1; } // get the audio and video tracks AP4_Track* audio_track = movie->GetTrack(AP4_Track::TYPE_AUDIO); AP4_Track* video_track = movie->GetTrack(AP4_Track::TYPE_VIDEO); if (audio_track == NULL && video_track == NULL) { fprintf(stderr, "ERROR: no suitable tracks found\n"); delete input_file; input->Release(); return 1; } // create the appropriate readers AP4_LinearReader* linear_reader = NULL; SampleReader* audio_reader = NULL; SampleReader* video_reader = NULL; if (movie->HasFragments()) { // create a linear reader to get the samples linear_reader = new AP4_LinearReader(*movie, input); if (audio_track) { linear_reader->EnableTrack(audio_track->GetId()); audio_reader = new FragmentedSampleReader(*linear_reader, audio_track->GetId()); } if (video_track) { linear_reader->EnableTrack(video_track->GetId()); video_reader = new FragmentedSampleReader(*linear_reader, video_track->GetId()); } } else { if (audio_track) { audio_reader = new TrackSampleReader(*audio_track); } if (video_track) { video_reader = new TrackSampleReader(*video_track); } } // create an MPEG2 TS Writer AP4_Mpeg2TsWriter writer(Options.pmt_pid); AP4_Mpeg2TsWriter::SampleStream* audio_stream = NULL; AP4_Mpeg2TsWriter::SampleStream* video_stream = NULL; // add the audio stream if (audio_track) { sample_description = audio_track->GetSampleDescription(0); if (sample_description == NULL) { fprintf(stderr, "ERROR: unable to parse audio sample description\n"); goto end; } unsigned int stream_type = 0; unsigned int stream_id = 0; if (sample_description->GetFormat() == AP4_SAMPLE_FORMAT_MP4A) { stream_type = AP4_MPEG2_STREAM_TYPE_ISO_IEC_13818_7; stream_id = AP4_MPEG2_TS_DEFAULT_STREAM_ID_AUDIO; } else if (sample_description->GetFormat() == AP4_SAMPLE_FORMAT_AC_3 || sample_description->GetFormat() == AP4_SAMPLE_FORMAT_EC_3) { stream_type = AP4_MPEG2_STREAM_TYPE_ATSC_AC3; stream_id = AP4_MPEG2_TS_STREAM_ID_PRIVATE_STREAM_1; } else { fprintf(stderr, "ERROR: audio codec not supported\n"); return 1; } result = writer.SetAudioStream(audio_track->GetMediaTimeScale(), stream_type, stream_id, audio_stream, Options.audio_pid); if (AP4_FAILED(result)) { fprintf(stderr, "could not create audio stream (%d)\n", result); goto end; } } // add the video stream if (video_track) { sample_description = video_track->GetSampleDescription(0); if (sample_description == NULL) { fprintf(stderr, "ERROR: unable to parse video sample description\n"); goto end; } // decide on the stream type unsigned int stream_type = 0; unsigned int stream_id = AP4_MPEG2_TS_DEFAULT_STREAM_ID_VIDEO; if (sample_description->GetFormat() == AP4_SAMPLE_FORMAT_AVC1 || sample_description->GetFormat() == AP4_SAMPLE_FORMAT_AVC2 || sample_description->GetFormat() == AP4_SAMPLE_FORMAT_AVC3 || sample_description->GetFormat() == AP4_SAMPLE_FORMAT_AVC4) { stream_type = AP4_MPEG2_STREAM_TYPE_AVC; } else if (sample_description->GetFormat() == AP4_SAMPLE_FORMAT_HEV1 || sample_description->GetFormat() == AP4_SAMPLE_FORMAT_HVC1) { stream_type = AP4_MPEG2_STREAM_TYPE_HEVC; } else { fprintf(stderr, "ERROR: video codec not supported\n"); return 1; } result = writer.SetVideoStream(video_track->GetMediaTimeScale(), stream_type, stream_id, video_stream, Options.video_pid); if (AP4_FAILED(result)) { fprintf(stderr, "could not create video stream (%d)\n", result); goto end; } } result = WriteSamples(writer, audio_track, audio_reader, audio_stream, video_track, video_reader, video_stream, Options.segment_duration_threshold); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: failed to write samples (%d)\n", result); } end: delete input_file; input->Release(); delete linear_reader; delete audio_reader; delete video_reader; return result == AP4_SUCCESS?0:1; }
int main(int argc, char *argv[]) { int opt; char *queryWord = NULL; char *queryFile = NULL; int discardDupFiles = 1; int cacheSizeInKB = 0; while ((opt = getopt(argc, argv, "ql:d:uw:f:bc:s:")) != -1) { switch (opt) { case 'q': quietFlag = 1; break; case 'l': diskLatency = atoi(optarg); break; case 'c': cacheSizeInKB = atoi(optarg); break; case 'b': diskBusyWaitEnable = 1; break; case 'u': discardDupFiles = 0; break; case 'w': queryWord = strdup(optarg); break; case 'f': queryFile = strdup(optarg); break; case 's': serverAckFd = atoi(optarg); diskLatency = 0; /* Default for assignment 3 is zero-latency */ break; case 'd': { char *c = optarg; while (*c) { Debug_SetFlag(*c, 1); c++; } break; } default: PrintUsageAndExit(argv[0]); } } if (optind != argc-1) { PrintUsageAndExit(argv[0]); } /* * Allocate Memory for any caching of data. 0 means infinite cache. */ if (cacheSizeInKB == 0) { cacheSizeInKB = INFINITE_CACHE_SIZE/1024; } int retVal = CacheMem_Init(cacheSizeInKB); if (retVal < 0) { fprintf(stderr, "Can't allocate memory for cache\n"); return 1; } char *diskpath = diskpath = argv[optind]; BuildDiskIndex(diskpath, discardDupFiles); if (queryWord) { TestServiceBySingleWord(queryWord); } if (queryFile) { TestServiceByFileOfWords(queryFile); } if (serverAckFd) { ServerMode(serverAckFd); } if (!quietFlag) { printf("************ Stats ***************\n"); DumpStats(stdout); DumpUsageStats(stdout); } exit(EXIT_SUCCESS); return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc < 5) { PrintUsageAndExit(); } // parse options if (strcmp(*++argv, "--kms-uri")) { fprintf(stderr, "ERROR: the first option must be --kms-uri\n"); return 1; } const char* kms_uri = *++argv; // create an encrypting processor AP4_IsmaEncryptingProcessor processor(kms_uri); // setup default values const char* input_filename = NULL; const char* output_filename = NULL; char* arg; while ((arg = *++argv)) { if (!strcmp(arg, "--key")) { arg = *++argv; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument for --key option\n"); return 1; } char* track_ascii = NULL; char* key_ascii = NULL; char* salt_ascii = NULL; if (AP4_FAILED(AP4_SplitArgs(arg, track_ascii, key_ascii, salt_ascii))) { fprintf(stderr, "ERROR: invalid argument for --key option\n"); return 1; } unsigned char key[16]; unsigned char salt[8]; unsigned int track = strtoul(track_ascii, NULL, 10); if (AP4_ParseHex(key_ascii, key, 16)) { fprintf(stderr, "ERROR: invalid hex format for key\n"); } if (AP4_ParseHex(salt_ascii, salt, 8)) { fprintf(stderr, "ERROR: invalid hex format for salt\n"); } // set the key in the map processor.GetKeyMap().SetKey(track, key, salt); } else if (input_filename == NULL) { input_filename = arg; } else if (output_filename == NULL) { output_filename = arg; } else { fprintf(stderr, "ERROR: unexpected argument (%s)\n", arg); return 1; } } // check the arguments if (input_filename == NULL) { fprintf(stderr, "ERROR: missing input filename\n"); return 1; } if (output_filename == NULL) { fprintf(stderr, "ERROR: missing output filename\n"); return 1; } if (kms_uri == NULL) { fprintf(stderr, "ERROR: missing kms uri\n"); return 1; } // create the input stream AP4_ByteStream* input; try{ input = new AP4_FileByteStream(input_filename, AP4_FileByteStream::STREAM_MODE_READ); } catch (AP4_Exception) { fprintf(stderr, "ERROR: cannot open input file (%s)\n", input_filename); return 1; } // create the output stream AP4_ByteStream* output; try { output = new AP4_FileByteStream(output_filename, AP4_FileByteStream::STREAM_MODE_WRITE); } catch (AP4_Exception) { fprintf(stderr, "ERROR: cannot open output file (%s)\n", output_filename); return 1; } // process/decrypt the file processor.Process(*input, *output); // cleanup input->Release(); output->Release(); return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc == 1) PrintUsageAndExit(); // parse options AP4_UI08 encryption_method = 0; bool encryption_method_is_set = false; AP4_UI08 padding_scheme = 0; const char* input_filename = NULL; const char* output_filename = NULL; bool show_progress = false; bool key_is_set = false; unsigned char key[16]; unsigned char iv[16]; AP4_BlockCipher::CipherMode cipher_mode = AP4_BlockCipher::CBC; const char* content_type = ""; const char* content_id = ""; const char* rights_issuer_url = ""; AP4_LargeSize plaintext_length = 0; AP4_DataBuffer textual_headers_buffer; AP4_TrackPropertyMap textual_headers; AP4_SetMemory(key, 0, sizeof(key)); AP4_SetMemory(iv, 0, sizeof(iv)); // parse the command line arguments char* arg; while ((arg = *++argv)) { if (!strcmp(arg, "--method")) { arg = *++argv; if (!strcmp(arg, "CBC")) { encryption_method = AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CBC; encryption_method_is_set = true; padding_scheme = AP4_OMA_DCF_PADDING_SCHEME_RFC_2630; cipher_mode = AP4_BlockCipher::CBC; } else if (!strcmp(arg, "CTR")) { encryption_method = AP4_OMA_DCF_ENCRYPTION_METHOD_AES_CTR; encryption_method_is_set = true; padding_scheme = AP4_OMA_DCF_PADDING_SCHEME_NONE; cipher_mode = AP4_BlockCipher::CTR; } else if (!strcmp(arg, "NULL")) { encryption_method = AP4_OMA_DCF_ENCRYPTION_METHOD_NULL; encryption_method_is_set = true; padding_scheme = AP4_OMA_DCF_PADDING_SCHEME_NONE; } else { fprintf(stderr, "ERROR: invalid value for --method argument\n"); return 1; } } else if (!strcmp(arg, "--show-progress")) { show_progress = true; } else if (!strcmp(arg, "--content-type")) { content_type = *++argv; if (content_type == NULL) { fprintf(stderr, "ERROR: missing argument for --content-type option\n"); return 1; } } else if (!strcmp(arg, "--content-id")) { content_id = *++argv; if (content_type == NULL) { fprintf(stderr, "ERROR: missing argument for --content-id option\n"); return 1; } } else if (!strcmp(arg, "--rights-issuer")) { rights_issuer_url = *++argv; if (rights_issuer_url == NULL) { fprintf(stderr, "ERROR: missing argument for --rights-issuer option\n"); return 1; } } else if (!strcmp(arg, "--key")) { if (!encryption_method_is_set) { fprintf(stderr, "ERROR: --method argument must appear before --key\n"); return 1; } else if (encryption_method_is_set == AP4_OMA_DCF_ENCRYPTION_METHOD_NULL) { fprintf(stderr, "ERROR: --key cannot be used with --method NULL\n"); return 1; } arg = *++argv; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument for --key option\n"); return 1; } char* key_ascii = NULL; char* iv_ascii = NULL; if (AP4_FAILED(AP4_SplitArgs(arg, key_ascii, iv_ascii))) { fprintf(stderr, "ERROR: invalid argument for --key option\n"); return 1; } if (AP4_ParseHex(key_ascii, key, 16)) { fprintf(stderr, "ERROR: invalid hex format for key\n"); } if (AP4_ParseHex(iv_ascii, iv, 16)) { fprintf(stderr, "ERROR: invalid hex format for iv\n"); return 1; } // check that the key is not already there if (key_is_set) { fprintf(stderr, "ERROR: key already set\n"); return 1; } key_is_set = true; } else if (!strcmp(arg, "--textual-header")) { char* name = NULL; char* value = NULL; arg = *++argv; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument for --textual-header option\n"); return 1; } if (AP4_FAILED(AP4_SplitArgs(arg, name, value))) { fprintf(stderr, "ERROR: invalid argument for --textual-header option\n"); return 1; } // check that the property is not already set if (textual_headers.GetProperty(0, name)) { fprintf(stderr, "ERROR: textual header %s already set\n", name); return 1; } // set the property in the map textual_headers.SetProperty(0, name, value); } else if (input_filename == NULL) { input_filename = arg; } else if (output_filename == NULL) { output_filename = arg; } else { fprintf(stderr, "ERROR: unexpected argument (%s)\n", arg); return 1; } } // check the arguments if (!encryption_method_is_set) { fprintf(stderr, "ERROR: missing --method argument\n"); return 1; } if (!key_is_set) { fprintf(stderr, "ERROR: encryption key not specified\n"); return 1; } if (input_filename == NULL) { fprintf(stderr, "ERROR: missing input filename\n"); return 1; } if (output_filename == NULL) { fprintf(stderr, "ERROR: missing output filename\n"); return 1; } (void)show_progress; // avoid warnings // convert to a textual headers buffer textual_headers.GetTextualHeaders(0, textual_headers_buffer); // create the input stream AP4_Result result; AP4_ByteStream* input = NULL; result = AP4_FileByteStream::Create(input_filename, AP4_FileByteStream::STREAM_MODE_READ, input); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open input file (%s) %d\n", input_filename, result); return 1; } // get the size of the input result = input->GetSize(plaintext_length); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot get the size of the input\n"); return 1; } // create an encrypting stream for the input AP4_ByteStream* encrypted_stream; if (encryption_method == AP4_OMA_DCF_ENCRYPTION_METHOD_NULL) { encrypted_stream = input; } else { result = AP4_EncryptingStream::Create(cipher_mode, *input, iv, 16, key, 16, true, &AP4_DefaultBlockCipherFactory::Instance, encrypted_stream); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: failed to create cipher (%d)\n", result); return 1; } } // create the output stream AP4_ByteStream* output = NULL; result = AP4_FileByteStream::Create(output_filename, AP4_FileByteStream::STREAM_MODE_WRITE, output); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: cannot open output file (%s) %d\n", output_filename, result); return 1; } // create the file AP4_File file; // set the brand AP4_UI32 compatible_brands[1] = {AP4_OMA_DCF_BRAND_ODCF}; file.SetFileType(AP4_OMA_DCF_BRAND_ODCF, 2, compatible_brands, 1); // create the odrm atom (force a 64-bit size) AP4_ContainerAtom* odrm = new AP4_ContainerAtom(AP4_ATOM_TYPE_ODRM, AP4_FULL_ATOM_HEADER_SIZE_64, true, 0, 0); // create the ohdr atom AP4_OhdrAtom* ohdr = new AP4_OhdrAtom(encryption_method, padding_scheme, plaintext_length, content_id, rights_issuer_url, textual_headers_buffer.GetData(), textual_headers_buffer.GetDataSize()); // create the odhe atom (the ownership is transfered) AP4_OdheAtom* odhe = new AP4_OdheAtom(content_type, ohdr); odrm->AddChild(odhe); // create the odda atom AP4_OddaAtom* odda = new AP4_OddaAtom(*encrypted_stream); odrm->AddChild(odda); // add the odrm atom to the file (the owndership is transfered) file.GetTopLevelAtoms().Add(odrm); // write the file to the output AP4_FileWriter::Write(file, *output); // cleanup input->Release(); output->Release(); return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc == 1) PrintUsageAndExit(); // parse options const char* kms_uri = NULL; enum Method method = METHOD_NONE; const char* input_filename = NULL; const char* output_filename = NULL; AP4_ProtectionKeyMap key_map; AP4_TrackPropertyMap property_map; bool show_progress = false; // parse the command line arguments char* arg; while ((arg = *++argv)) { if (!strcmp(arg, "--method")) { arg = *++argv; if (!strcmp(arg, "OMA-PDCF-CBC")) { method = METHOD_OMA_PDCF_CBC; } else if (!strcmp(arg, "OMA-PDCF-CTR")) { method = METHOD_OMA_PDCF_CTR; } else if (!strcmp(arg, "MARLIN-IPMP")) { method = METHOD_MARLIN_IPMP; } else if (!strcmp(arg, "ISMA-IAEC")) { method = METHOD_ISMA_AES; } else { fprintf(stderr, "ERROR: invalid value for --method argument\n"); return 1; } } else if (!strcmp(arg, "--kms-uri")) { if (method != METHOD_ISMA_AES) { fprintf(stderr, "ERROR: --kms-uri only applies to method ISMA-IAEC\n"); return 1; } kms_uri = *++argv; } else if (!strcmp(arg, "--show-progress")) { show_progress = true; } else if (!strcmp(arg, "--key")) { if (method == METHOD_NONE) { fprintf(stderr, "ERROR: --method argument must appear before --key\n"); return 1; } arg = *++argv; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument for --key option\n"); return 1; } char* track_ascii = NULL; char* key_ascii = NULL; char* iv_ascii = NULL; if (AP4_FAILED(AP4_SplitArgs(arg, track_ascii, key_ascii, iv_ascii))) { fprintf(stderr, "ERROR: invalid argument for --key option\n"); return 1; } unsigned char key[16]; unsigned char iv[16]; unsigned int track = strtoul(track_ascii, NULL, 10); AP4_SetMemory(key, 0, sizeof(key)); AP4_SetMemory(iv, 0, sizeof(iv)); if (AP4_ParseHex(key_ascii, key, 16)) { fprintf(stderr, "ERROR: invalid hex format for key\n"); } if (AP4_ParseHex(iv_ascii, iv, 8)) { fprintf(stderr, "ERROR: invalid hex format for iv\n"); return 1; } // check that the key is not already there if (key_map.GetKey(track)) { fprintf(stderr, "ERROR: key already set for track %d\n", track); return 1; } // set the key in the map key_map.SetKey(track, key, iv); } else if (!strcmp(arg, "--property")) { char* track_ascii = NULL; char* name = NULL; char* value = NULL; if (method != METHOD_OMA_PDCF_CBC && method != METHOD_OMA_PDCF_CTR && method != METHOD_MARLIN_IPMP) { fprintf(stderr, "ERROR: this method does not use properties\n"); return 1; } arg = *++argv; if (arg == NULL) { fprintf(stderr, "ERROR: missing argument for --property option\n"); return 1; } if (AP4_FAILED(AP4_SplitArgs(arg, track_ascii, name, value))) { fprintf(stderr, "ERROR: invalid argument for --property option\n"); return 1; } unsigned int track = strtoul(track_ascii, NULL, 10); // check that the property is not already set if (property_map.GetProperty(track, name)) { fprintf(stderr, "ERROR: property %s already set for track %d\n", name, track); return 1; } // set the property in the map property_map.SetProperty(track, name, value); } else if (input_filename == NULL) { input_filename = arg; } else if (output_filename == NULL) { output_filename = arg; } else { fprintf(stderr, "ERROR: unexpected argument (%s)\n", arg); return 1; } } // check the arguments if (method == METHOD_NONE) { fprintf(stderr, "ERROR: missing --method argument\n"); return 1; } if (input_filename == NULL) { fprintf(stderr, "ERROR: missing input filename\n"); return 1; } if (output_filename == NULL) { fprintf(stderr, "ERROR: missing output filename\n"); return 1; } // create an encrypting processor AP4_Processor* processor; if (method == METHOD_ISMA_AES) { if (kms_uri == NULL) { fprintf(stderr, "ERROR: method ISMA-IAEC requires --kms-uri\n"); return 1; } AP4_IsmaEncryptingProcessor* isma_processor = new AP4_IsmaEncryptingProcessor(kms_uri); isma_processor->GetKeyMap().SetKeys(key_map); processor = isma_processor; } else if (method == METHOD_MARLIN_IPMP) { AP4_MarlinIpmpEncryptingProcessor* marlin_processor = new AP4_MarlinIpmpEncryptingProcessor(); marlin_processor->GetKeyMap().SetKeys(key_map); marlin_processor->GetPropertyMap().SetProperties(property_map); processor = marlin_processor; } else { AP4_OmaDcfEncryptingProcessor* oma_processor = new AP4_OmaDcfEncryptingProcessor(method == METHOD_OMA_PDCF_CTR? AP4_OMA_DCF_CIPHER_MODE_CTR : AP4_OMA_DCF_CIPHER_MODE_CBC); oma_processor->GetKeyMap().SetKeys(key_map); oma_processor->GetPropertyMap().SetProperties(property_map); processor = oma_processor; } // create the input stream AP4_ByteStream* input; try{ input = new AP4_FileByteStream(input_filename, AP4_FileByteStream::STREAM_MODE_READ); } catch (AP4_Exception) { fprintf(stderr, "ERROR: cannot open input file (%s)\n", input_filename); return 1; } // create the output stream AP4_ByteStream* output; try { output = new AP4_FileByteStream(output_filename, AP4_FileByteStream::STREAM_MODE_WRITE); } catch (AP4_Exception) { fprintf(stderr, "ERROR: cannot open output file (%s)\n", output_filename); return 1; } // process/decrypt the file ProgressListener listener; AP4_Result result = processor->Process(*input, *output, show_progress?&listener:NULL); if (AP4_FAILED(result)) { fprintf(stderr, "ERROR: failed to process the file (%d)\n", result); } // cleanup delete processor; input->Release(); output->Release(); return 0; }
/* main */ int main(int argc, char **argv) { /*OpenCL variables */ cl_device_id device; cl_device_type device_type; /*to test if we are on cpu or gpu*/ cl_context context; cl_command_queue cmdQueue; /* The event variables are created only when needed */ #ifdef _UNBLOCK cl_uint num_events = 3; cl_event event[num_events]; #endif FPTYPE * buffers[3]; cl_mdsys_t cl_sys; cl_int status; int nprint, i, nthreads = 0; char restfile[BLEN], trajfile[BLEN], ergfile[BLEN], line[BLEN]; FILE *fp,*traj,*erg; mdsys_t sys; /* Start profiling */ #ifdef __PROFILING double t1, t2; t1 = second(); #endif /* handling the command line arguments */ switch (argc) { case 2: /* only the cpu/gpu argument was passed, setting default nthreads */ if( !strcmp( argv[1], "cpu" ) ) nthreads = 16; else nthreads = 1024; break; case 3: /* both the device type (cpu/gpu) and the number of threads were passed */ nthreads = strtol(argv[2],NULL,10); if( nthreads<0 ) { fprintf( stderr, "\n. The number of threads must be more than 1.\n"); PrintUsageAndExit(); } break; default: PrintUsageAndExit(); break; } /* Initialize the OpenCL environment */ if( InitOpenCLEnvironment( argv[1], &device, &context, &cmdQueue ) != CL_SUCCESS ){ fprintf( stderr, "Program Error! OpenCL Environment was not initialized correctly.\n" ); return 4; } /* The event initialization is performed only when needed */ #ifdef _UNBLOCK /* initialize the cl_event handler variables */ for( i = 0; i < num_events; ++i) { event[i] = clCreateUserEvent( context, NULL ); clSetUserEventStatus( event[i], CL_COMPLETE ); } #endif /* read input file */ if(get_me_a_line(stdin,line)) return 1; sys.natoms=atoi(line); if(get_me_a_line(stdin,line)) return 1; sys.mass=atof(line); if(get_me_a_line(stdin,line)) return 1; sys.epsilon=atof(line); if(get_me_a_line(stdin,line)) return 1; sys.sigma=atof(line); if(get_me_a_line(stdin,line)) return 1; sys.rcut=atof(line); if(get_me_a_line(stdin,line)) return 1; sys.box=atof(line); if(get_me_a_line(stdin,restfile)) return 1; if(get_me_a_line(stdin,trajfile)) return 1; if(get_me_a_line(stdin,ergfile)) return 1; if(get_me_a_line(stdin,line)) return 1; sys.nsteps=atoi(line); if(get_me_a_line(stdin,line)) return 1; sys.dt=atof(line); if(get_me_a_line(stdin,line)) return 1; nprint=atoi(line); /* allocate memory */ cl_sys.natoms = sys.natoms; cl_sys.rx = clCreateBuffer( context, CL_MEM_READ_WRITE, cl_sys.natoms * sizeof(FPTYPE), NULL, &status ); cl_sys.ry = clCreateBuffer( context, CL_MEM_READ_WRITE, cl_sys.natoms * sizeof(FPTYPE), NULL, &status ); cl_sys.rz = clCreateBuffer( context, CL_MEM_READ_WRITE, cl_sys.natoms * sizeof(FPTYPE), NULL, &status ); cl_sys.vx = clCreateBuffer( context, CL_MEM_READ_WRITE, cl_sys.natoms * sizeof(FPTYPE), NULL, &status ); cl_sys.vy = clCreateBuffer( context, CL_MEM_READ_WRITE, cl_sys.natoms * sizeof(FPTYPE), NULL, &status ); cl_sys.vz = clCreateBuffer( context, CL_MEM_READ_WRITE, cl_sys.natoms * sizeof(FPTYPE), NULL, &status ); cl_sys.fx = clCreateBuffer( context, CL_MEM_READ_WRITE, cl_sys.natoms * sizeof(FPTYPE), NULL, &status ); cl_sys.fy = clCreateBuffer( context, CL_MEM_READ_WRITE, cl_sys.natoms * sizeof(FPTYPE), NULL, &status ); cl_sys.fz = clCreateBuffer( context, CL_MEM_READ_WRITE, cl_sys.natoms * sizeof(FPTYPE), NULL, &status ); buffers[0] = (FPTYPE *) malloc( 2 * cl_sys.natoms * sizeof(FPTYPE) ); buffers[1] = (FPTYPE *) malloc( 2 * cl_sys.natoms * sizeof(FPTYPE) ); buffers[2] = (FPTYPE *) malloc( 2 * cl_sys.natoms * sizeof(FPTYPE) ); /* read restart */ fp = fopen( restfile, "r" ); if( fp ) { for( i = 0; i < 2 * cl_sys.natoms; ++i ){ #ifdef _USE_FLOAT fscanf( fp, "%f%f%f", buffers[0] + i, buffers[1] + i, buffers[2] + i); #else fscanf( fp, "%lf%lf%lf", buffers[0] + i, buffers[1] + i, buffers[2] + i); #endif } status = clEnqueueWriteBuffer( cmdQueue, cl_sys.rx, CL_TRUE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[0], 0, NULL, NULL ); status |= clEnqueueWriteBuffer( cmdQueue, cl_sys.ry, CL_TRUE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[1], 0, NULL, NULL ); status |= clEnqueueWriteBuffer( cmdQueue, cl_sys.rz, CL_TRUE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[2], 0, NULL, NULL ); status |= clEnqueueWriteBuffer( cmdQueue, cl_sys.vx, CL_TRUE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[0] + cl_sys.natoms, 0, NULL, NULL ); status |= clEnqueueWriteBuffer( cmdQueue, cl_sys.vy, CL_TRUE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[1] + cl_sys.natoms, 0, NULL, NULL ); status |= clEnqueueWriteBuffer( cmdQueue, cl_sys.vz, CL_TRUE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[2] + cl_sys.natoms, 0, NULL, NULL ); fclose(fp); } else { perror("cannot read restart file"); return 3; } /* initialize forces and energies.*/ sys.nfi=0; size_t globalWorkSize[1]; globalWorkSize[0] = nthreads; const char * sourcecode = #include <opencl_kernels_as_string.h> ; cl_program program = clCreateProgramWithSource( context, 1, (const char **) &sourcecode, NULL, &status ); status |= clBuildProgram( program, 0, NULL, kernelflags, NULL, NULL ); #ifdef __DEBUG size_t log_size; char log [200000]; clGetProgramBuildInfo( program, device, CL_PROGRAM_BUILD_LOG, sizeof(log), log, &log_size ); fprintf( stderr, "\nLog: \n\n %s", log ); #endif cl_kernel kernel_force = clCreateKernel( program, "opencl_force", &status ); cl_kernel kernel_ekin = clCreateKernel( program, "opencl_ekin", &status ); cl_kernel kernel_verlet_first = clCreateKernel( program, "opencl_verlet_first", &status ); cl_kernel kernel_verlet_second = clCreateKernel( program, "opencl_verlet_second", &status ); cl_kernel kernel_azzero = clCreateKernel( program, "opencl_azzero", &status ); FPTYPE * tmp_epot; cl_mem epot_buffer; tmp_epot = (FPTYPE *) malloc( nthreads * sizeof(FPTYPE) ); epot_buffer = clCreateBuffer( context, CL_MEM_READ_WRITE, nthreads * sizeof(FPTYPE), NULL, &status ); /* precompute some constants */ FPTYPE c12 = 4.0 * sys.epsilon * pow( sys.sigma, 12.0); FPTYPE c6 = 4.0 * sys.epsilon * pow( sys.sigma, 6.0); FPTYPE rcsq = sys.rcut * sys.rcut; FPTYPE boxby2 = HALF * sys.box; FPTYPE dtmf = HALF * sys.dt / mvsq2e / sys.mass; sys.epot = ZERO; sys.ekin = ZERO; /* Azzero force buffer */ status = clSetMultKernelArgs( kernel_azzero, 0, 4, KArg(cl_sys.fx), KArg(cl_sys.fy), KArg(cl_sys.fz), KArg(cl_sys.natoms)); status = clEnqueueNDRangeKernel( cmdQueue, kernel_azzero, 1, NULL, globalWorkSize, NULL, 0, NULL, NULL ); status |= clSetMultKernelArgs( kernel_force, 0, 13, KArg(cl_sys.fx), KArg(cl_sys.fy), KArg(cl_sys.fz), KArg(cl_sys.rx), KArg(cl_sys.ry), KArg(cl_sys.rz), KArg(cl_sys.natoms), KArg(epot_buffer), KArg(c12), KArg(c6), KArg(rcsq), KArg(boxby2), KArg(sys.box)); status = clEnqueueNDRangeKernel( cmdQueue, kernel_force, 1, NULL, globalWorkSize, NULL, 0, NULL, NULL ); status |= clEnqueueReadBuffer( cmdQueue, epot_buffer, CL_TRUE, 0, nthreads * sizeof(FPTYPE), tmp_epot, 0, NULL, NULL ); for( i = 0; i < nthreads; i++) sys.epot += tmp_epot[i]; FPTYPE * tmp_ekin; cl_mem ekin_buffer; tmp_ekin = (FPTYPE *) malloc( nthreads * sizeof(FPTYPE) ); ekin_buffer = clCreateBuffer( context, CL_MEM_READ_WRITE, nthreads * sizeof(FPTYPE), NULL, &status ); status |= clSetMultKernelArgs( kernel_ekin, 0, 5, KArg(cl_sys.vx), KArg(cl_sys.vy), KArg(cl_sys.vz), KArg(cl_sys.natoms), KArg(ekin_buffer)); status = clEnqueueNDRangeKernel( cmdQueue, kernel_ekin, 1, NULL, globalWorkSize, NULL, 0, NULL, NULL ); status |= clEnqueueReadBuffer( cmdQueue, ekin_buffer, CL_TRUE, 0, nthreads * sizeof(FPTYPE), tmp_ekin, 0, NULL, NULL ); for( i = 0; i < nthreads; i++) sys.ekin += tmp_ekin[i]; sys.ekin *= HALF * mvsq2e * sys.mass; sys.temp = TWO * sys.ekin / ( THREE * sys.natoms - THREE ) / kboltz; erg=fopen(ergfile,"w"); traj=fopen(trajfile,"w"); printf("Starting simulation with %d atoms for %d steps.\n",sys.natoms, sys.nsteps); printf(" NFI TEMP EKIN EPOT ETOT\n"); /* download data on host */ status = clEnqueueReadBuffer( cmdQueue, cl_sys.rx, CL_TRUE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[0], 0, NULL, NULL ); status |= clEnqueueReadBuffer( cmdQueue, cl_sys.ry, CL_TRUE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[1], 0, NULL, NULL ); status |= clEnqueueReadBuffer( cmdQueue, cl_sys.rz, CL_TRUE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[2], 0, NULL, NULL ); sys.rx = buffers[0]; sys.ry = buffers[1]; sys.rz = buffers[2]; output(&sys, erg, traj); /**************************************************/ /* main MD loop */ for(sys.nfi=1; sys.nfi <= sys.nsteps; ++sys.nfi) { /* propagate system and recompute energies */ /* 2) verlet_first */ status |= clSetMultKernelArgs( kernel_verlet_first, 0, 12, KArg(cl_sys.fx), KArg(cl_sys.fy), KArg(cl_sys.fz), KArg(cl_sys.rx), KArg(cl_sys.ry), KArg(cl_sys.rz), KArg(cl_sys.vx), KArg(cl_sys.vy), KArg(cl_sys.vz), KArg(cl_sys.natoms), KArg(sys.dt), KArg(dtmf)); CheckSuccess(status, 2); /* When the data transfer is non blocking, this kernel has to wait the completion of part 8 (event[2]) */ #ifdef _UNBLOCK status = clEnqueueNDRangeKernel( cmdQueue, kernel_verlet_first, 1, NULL, globalWorkSize, NULL, 1, &event[2], NULL ); #else status = clEnqueueNDRangeKernel( cmdQueue, kernel_verlet_first, 1, NULL, globalWorkSize, NULL, 0, NULL, NULL ); #endif /* 6) download position@device to position@host */ if ((sys.nfi % nprint) == nprint-1) { /* In non blocking mode (CL_FALSE) this data transfer raises events[i] */ #ifdef _UNBLOCK status = clEnqueueReadBuffer( cmdQueue, cl_sys.rx, CL_FALSE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[0], 0, NULL, &event[2] ); status |= clEnqueueReadBuffer( cmdQueue, cl_sys.ry, CL_FALSE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[1], 0, NULL, &event[1] ); status |= clEnqueueReadBuffer( cmdQueue, cl_sys.rz, CL_FALSE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[2], 0, NULL, &event[0] ); #else status = clEnqueueReadBuffer( cmdQueue, cl_sys.rx, CL_TRUE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[0], 0, NULL, NULL ); status |= clEnqueueReadBuffer( cmdQueue, cl_sys.ry, CL_TRUE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[1], 0, NULL, NULL ); status |= clEnqueueReadBuffer( cmdQueue, cl_sys.rz, CL_TRUE, 0, cl_sys.natoms * sizeof(FPTYPE), buffers[2], 0, NULL, NULL ); #endif CheckSuccess(status, 6); } /* 3) force */ status |= clSetMultKernelArgs( kernel_force, 0, 13, KArg(cl_sys.fx), KArg(cl_sys.fy), KArg(cl_sys.fz), KArg(cl_sys.rx), KArg(cl_sys.ry), KArg(cl_sys.rz), KArg(cl_sys.natoms), KArg(epot_buffer), KArg(c12), KArg(c6), KArg(rcsq), KArg(boxby2), KArg(sys.box)); CheckSuccess(status, 3); status = clEnqueueNDRangeKernel( cmdQueue, kernel_force, 1, NULL, globalWorkSize, NULL, 0, NULL, NULL ); /* 7) download E_pot[i]@device and perform reduction to E_pot@host */ if ((sys.nfi % nprint) == nprint-1) { /* In non blocking mode (CL_FALSE) this data transfer kernel raises an event[1] */ #ifdef _UNBLOCK status |= clEnqueueReadBuffer( cmdQueue, epot_buffer, CL_FALSE, 0, nthreads * sizeof(FPTYPE), tmp_epot, 0, NULL, &event[1] ); #else status |= clEnqueueReadBuffer( cmdQueue, epot_buffer, CL_TRUE, 0, nthreads * sizeof(FPTYPE), tmp_epot, 0, NULL, NULL ); #endif CheckSuccess(status, 7); } /* 4) verlet_second */ status |= clSetMultKernelArgs( kernel_verlet_second, 0, 9, KArg(cl_sys.fx), KArg(cl_sys.fy), KArg(cl_sys.fz), KArg(cl_sys.vx), KArg(cl_sys.vy), KArg(cl_sys.vz), KArg(cl_sys.natoms), KArg(sys.dt), KArg(dtmf)); CheckSuccess(status, 4); status = clEnqueueNDRangeKernel( cmdQueue, kernel_verlet_second, 1, NULL, globalWorkSize, NULL, 0, NULL, NULL ); if ((sys.nfi % nprint) == nprint-1) { /* 5) ekin */ status |= clSetMultKernelArgs( kernel_ekin, 0, 5, KArg(cl_sys.vx), KArg(cl_sys.vy), KArg(cl_sys.vz), KArg(cl_sys.natoms), KArg(ekin_buffer)); CheckSuccess(status, 5); status = clEnqueueNDRangeKernel( cmdQueue, kernel_ekin, 1, NULL, globalWorkSize, NULL, 0, NULL, NULL ); /* 8) download E_kin[i]@device and perform reduction to E_kin@host */ /* In non blocking mode (CL_FALSE) this data transfer kernel raises an event[2] */ #ifdef _UNBLOCK status |= clEnqueueReadBuffer( cmdQueue, ekin_buffer, CL_FALSE, 0, nthreads * sizeof(FPTYPE), tmp_ekin, 0, NULL, &event[2] ); #else status |= clEnqueueReadBuffer( cmdQueue, ekin_buffer, CL_TRUE, 0, nthreads * sizeof(FPTYPE), tmp_ekin, 0, NULL, NULL ); #endif CheckSuccess(status, 8); } /* 1) write output every nprint steps */ if ((sys.nfi % nprint) == 0) { /* Calling a synchronization function (only when in non blocking mode) that will wait until all the * events[i], related to the data transfers, to be completed */ #ifdef _UNBLOCK clWaitForEvents(3, event); #endif sys.rx = buffers[0]; sys.ry = buffers[1]; sys.rz = buffers[2]; /* initialize the sys.epot@host and sys.ekin@host variables to ZERO */ sys.epot = ZERO; sys.ekin = ZERO; /* reduction on the tmp_Exxx[i] buffers downloaded from the device * during parts 7 and 8 of the previous MD loop iteration */ for( i = 0; i < nthreads; i++) { sys.epot += tmp_epot[i]; sys.ekin += tmp_ekin[i]; } /* multiplying the kinetic energy by prefactors */ sys.ekin *= HALF * mvsq2e * sys.mass; sys.temp = TWO * sys.ekin / ( THREE * sys.natoms - THREE ) / kboltz; /* writing output files (positions, energies and temperature) */ output(&sys, erg, traj); } } /**************************************************/ /* End profiling */ #ifdef __PROFILING t2 = second(); fprintf( stdout, "\n\nTime of execution = %.3g (seconds)\n", (t2 - t1) ); #endif /* clean up: close files, free memory */ printf("Simulation Done.\n"); fclose(erg); fclose(traj); free(buffers[0]); free(buffers[1]); free(buffers[2]); return 0; }