EVOLUTION-MANAGER
Edit File: oggSplit.cpp
/* * oggSplit will demultiplex a number of video and audio streams from an ogg file * * Copyright (C) 2008 Joern Seger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <iostream> #include <map> #include <sstream> #include <string> #include <cstdlib> #include <unistd.h> #include "fileRepository.h" #include "rawMediaPacket.h" #include "oggDecoder.h" #include "oggEncoder.h" #include "oggStreamDecoder.h" #include "oggBOSExtractorFactory.h" struct OutputUnit { OggEncoder encoder; FileRepository repository; }; void printHelpScreen(const std::string& progName) { std::cerr << "usage: " << progName << " <file.ogv>\n" << " -- package and version \"" << PACKAGE_STRING << "\"\n\n" << "oggSplit demultiplexes an ogg file into its streams.\n" << "Every stream is placed into a single file, which are\n" << "called theora_<serialNo>.ogg or vorbis_<serialNo>.ogg.\n" << "The serial number is the unique ogg serial number of\n" << "this stream.\n\n"; } int main(int argc, char* argv[]) { if (argc != 2) { printHelpScreen(argv[0]); exit(-1); } std::string help("-h"); if (help == argv[1]) { printHelpScreen(argv[0]); exit(-1); } /* open the repository in this easy example, it is a simple file */ FileRepository repository(argv[1], MediaUnit::read); /* open the file to write the new stream */ std::map<uint32, OutputUnit> outputFileList; RawMediaPacket rawDecoderPacket; OggDecoder oggDecoder; OggPage oggPage; /* run through the repository until there is no data left */ while (!repository.isEndOfFile()) { /* extract a raw data bunch from the file .. */ repository >> rawDecoderPacket; /* .. and insert it into the ogg decoder */ oggDecoder << rawDecoderPacket; /* are there any complete ogg Pages available ? */ while (oggDecoder.isAvailable()) { /* grap the next page */ oggDecoder >> oggPage; /* what ID has this page / what stream does this page belongs to */ uint32 serialID = oggPage.serialno(); /* if this is the start of a stream, create a repository file for it */ if (oggPage.isBOS()) { std::stringstream filename; switch (OggBOSExtractorFactory::getStreamType(oggPage)) { case ogg_theora: filename << "theora_" << std::hex << serialID << std::dec << ".ogv"; break; case ogg_vorbis: filename << "vorbis_" << std::hex << serialID << std::dec << ".oga"; break; case ogg_kate: filename << "kate_" << std::hex << serialID << std::dec << ".ogv"; break; default: std::cerr << "unknown type ID "<< std::hex << serialID << std::dec <<"\n"; filename << "unknown_" << std::hex << serialID << std::dec << ".ogv"; } std::cerr << "creating file <"<<filename.str()<<">\n"; outputFileList[serialID].repository = FileRepository( filename.str(), MediaUnit::write); outputFileList[serialID].encoder = OggEncoder(); } /* if this is a simple page, insert it into the decoder it belongs to */ outputFileList[serialID].encoder << oggPage; while (outputFileList[serialID].encoder.isAvailable()) { RawMediaPacket rawOutput; /* extract the raw packets */ outputFileList[serialID].encoder >> rawOutput; outputFileList[serialID].repository << rawOutput; } if (oggPage.isEOS()) outputFileList[serialID].repository.close(); } } repository.close(); return (0); }