EVOLUTION-MANAGER
Edit File: oggCat.cpp
/* * oggCat is a command line tool, to concatenate video streams * * 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. * */ #ifdef __WIN32 #define __GNU_LIBRARY__ #include "../win32/getopt_win.h" #endif #include <iostream> #include <map> #include <vector> #include <string> #include <unistd.h> #include <cstdlib> #include <ctime> #include "definition.h" #include "fileRepository.h" #include "oggPacket.h" #include "streamMux.h" #include "streamSerializer.h" #include "streamConfig.h" #include "oggTypes.h" /* get the next file * within this function, the next stream serializer is created. * The configuration of this serializer is compared with the * configuration of the given configuration, and a matching table * is created (i.e. a theora stream with a certain configuration * may be on an other stream position, than on the first stream) * if there is no match found, the function returns false. * If there is a match found, the packets created by the serializer * should be remarked from the actual stream ID to the stream ID * of the output file. * */ bool getNextFile(std::string& fileName, StreamSerializer* &serializer, std::vector<StreamConfig>& origConfigList, std::vector<uint8>& streamMap) { serializer = new StreamSerializer; if (!serializer->open(fileName)) { std::cerr << "Unable to open file <" << fileName << "> \n"; delete serializer; serializer = 0; return (false); } std::vector<StreamConfig> actConfigList; serializer->getStreamConfig(actConfigList); uint32 matchCounter(0); uint32 origCounter(0); streamMap.resize(actConfigList.size(), 255); for (uint32 i(0); i<origConfigList.size(); ++i) { if (origConfigList[i].type == ogg_unknown) continue; origCounter++; for (uint32 j(0); j<actConfigList.size(); ++j) { if (actConfigList[j].type == ogg_unknown) continue; if ((*origConfigList[i].parameter) == (*actConfigList[j].parameter)) { streamMap[j] = i; matchCounter++; } } } if (matchCounter != origCounter) { std::cerr << "I could not find enough matching streams for file <fileName>\n"; delete serializer; serializer = 0; return (false); } // detele the config list explicitly return (true); } void printHelpScreen(const std::string& progName) { std::cerr << "usage: " << progName << " <outputFile> <inputFile1> <inputFile2> [ <inputFile3> [ ... ] ]\n" << " -- package and version \"" << PACKAGE_STRING << "\"\n\n" << "oggCat concatenates a number of ogg files. The files will only\n" << "be concatenated, if they match in the video and audio stream.\n" << "E.g. framerate and samplerate.\n\n"; } int main(int argc, char* argv[]) { srand(time(0)); std::string help("-h"); if ((argc > 1) && (help == argv[1])) { printHelpScreen(argv[0]); exit(-1); } if (argc < 4) { printHelpScreen(argv[0]); exit(-1); } std::string baseFile(argv[2]); /* open the first file to be read */ std::vector<StreamConfig> originalConfigList; StreamSerializer* serializer = new StreamSerializer; if (!serializer->open(baseFile)) { std::cerr << "Can not open file <" << baseFile << ">\n"; exit (-1); } serializer->getStreamConfig(originalConfigList); for (uint32 i(0); i<originalConfigList.size(); ++i) if (originalConfigList[i].type == ogg_unknown) std::cerr << "Warning: found unknown stream, this stream will be ignored\n"; if (originalConfigList.empty()) { std::cerr << "Can not extract a valid configuration - is this not an ogg file?\n"; exit (-1); } /* open the repository to write the file to */ std::string outputFile(argv[1]); FileRepository* repository = new FileRepository(outputFile, MediaUnit::write); if (repository->isEndOfFile()) { std::cerr << "Can not open repository <"<<outputFile<<">\n"; exit (-1); } StreamMux encoder(repository); encoder.configureStreams(originalConfigList); // write the first file to the output OggPacket packet; while (serializer->getNextPacket(packet) > -1) { packet.unsetEOS(); encoder << packet; } // handle the other files for (uint32 i(3); i<(uint32)argc; ++i) { std::string fileName(argv[i]); StreamSerializer* serializer(0); std::vector<uint8> streamMap; if (!getNextFile(fileName, serializer, originalConfigList, streamMap)) continue; while (serializer->getNextPacket(packet) > -1) { uint8 actualStreamID = packet.getStreamNo(); if ((actualStreamID < streamMap.size()) && (streamMap[actualStreamID] < 255)) { packet.unsetEOS(); packet.setStreamNo(streamMap[actualStreamID]); encoder << packet; } } serializer->close(); delete serializer; } encoder.setEndOfStream(); serializer->close(); encoder.close(); delete serializer; return (0); }