EVOLUTION-MANAGER
Edit File: oggDump.cpp
/* * oggDump will dump out an ogg file either by packets or by pages * * 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 <sstream> #include <fstream> #include <ostream> #include <cstdlib> #include <unistd.h> #include "fileRepository.h" #include "rawMediaPacket.h" #include "oggDecoder.h" #include "oggEncoder.h" #include "oggStreamDecoder.h" #include "oggPacket.h" #include "oggBOSExtractorFactory.h" struct OutputUnit { OggEncoder encoder; FileRepository repository; }; void printHelp(std::string programName) { std::cout << "usage <"<<programName<<"> [options] file" << std::endl; std::cout << "Options are:\n" << " -h : help screen \n" << " -g : dump pages \n" << " -p : dump packets \n" << " -l <level> : information depth default: 5(most information)\n" << " -s : promt for streams to dump\n" << " -o <file> : output dump information to a file\n"; } int main(int argc, char* argv[]) { /* default values * for the command line arguments */ uint8 dumpLevel(5); std::string outFilename(""); bool dumpPages(false); bool dumpPackets(false); bool promtForStreams(false); std::string programName(argv[0]); int opt; while ((opt = getopt(argc, argv, "hgpl:so:")) != EOF) switch (opt) { case 'h': printHelp(argv[0]); exit(-1); case 'g': dumpPages = true; break; case 'p': dumpPackets = true; break; case 's': promtForStreams = true; break; case 'o': outFilename = std::string(optarg); break; case 'l': dumpLevel = atoi(optarg); // yes, I know the atoi bug break; } argc -= optind; argv += optind; std::string analysisFile; if (argc == 1) analysisFile = std::string(argv[0]); else { printHelp(programName); exit(-1); } if ((!dumpPages) && (!dumpPackets)) { std::cout << "Specify wether you want to dump pages, packet or both by -g and/or -p\n"; exit(-1); } std::ofstream outStream; /* if there is a filename given, write the data to this file */ if (!outFilename.empty()) outStream.open(outFilename.c_str()); /* open the repository in this easy example, it is a simple file */ FileRepository repository(analysisFile, MediaUnit::read); OggDecoder oggDecoder; std::map<uint32, OggStreamDecoder> oggStreamDecoderList; std::vector<OggPage> bosPages; /* run through the repository until there is no data left */ while (!repository.isEndOfFile()) { RawMediaPacket rawDecoderPacket; /* 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()) { OggPage oggPage; /* grap the next page */ oggDecoder >> oggPage; /* what ID has this page / what stream does this page belongs to */ uint32 serialID = oggPage.serialno(); if (oggPage.isBOS()) { bool addPage(false); switch (OggBOSExtractorFactory::getStreamType(oggPage)) { case ogg_theora: { std::cout << "Found theora stream with ID= 0x" << std::hex << serialID << std::dec << std::endl; if (promtForStreams) { std::cout << "Dump this stream? (y/n) \n"; char answer = std::cin.get(); if (answer == 'Y' || answer == 'y') addPage = true; std::cout << answer << "\n"; } else addPage = true; } break; case ogg_vorbis: { std::cout << "Found vorbis stream with ID= 0x" << std::hex << serialID << std::dec << std::endl; if (promtForStreams) { std::cout << "Dump this stream? (y/n) "; char answer = std::cin.get(); if (answer == 'Y' || answer == 'y') addPage = true; std::cout << answer << "\n"; } else addPage = true; } break; case ogg_kate: { std::cout << "Found kate stream with ID= 0x" << std::hex << serialID << std::dec << std::endl; if (promtForStreams) { std::cout << "Dump this stream? (y/n) "; char answer = std::cin.get(); if (answer == 'Y' || answer == 'y') addPage = true; std::cout << answer << "\n"; } else addPage = true; } break; default: { std::cout << "Found unknown stream with ID= 0x" << std::hex << serialID << std::dec << std::endl; if (promtForStreams) { std::cout << "Dump this stream? (y/n) \n"; char answer = std::cin.get(); if (answer == 'Y' || answer == 'y') addPage = true; std::cout << answer << "\n"; } else addPage = true; } break; } if (addPage) { oggStreamDecoderList[serialID] = OggStreamDecoder(); oggStreamDecoderList[serialID] << oggPage; bosPages.push_back(oggPage); } } else { /* does the user want to dump this stream */ if (oggStreamDecoderList.find(serialID) != oggStreamDecoderList.end()) { if (dumpPages) { std::string outputString; // are there any bos pages, then print them first if (!bosPages.empty()) { for (uint32 j(0); j<bosPages.size(); ++j) outputString += bosPages[j].print(dumpLevel); bosPages.clear(); } outputString += oggPage.print(dumpLevel); if (outFilename.empty()) std::cout << outputString; else outStream << outputString; } /* if the packets should be dumped, they must be extracted first */ if (dumpPackets) { /* insert the page into the right decoder */ oggStreamDecoderList[serialID] << oggPage; while (oggStreamDecoderList[serialID].isAvailable()) { OggPacket packet; /* extract the full packets */ oggStreamDecoderList[serialID] >> packet; if (outFilename.empty()) std::cout << packet.print(dumpLevel); else outStream << packet.print(dumpLevel); } } } } } } /* close all files */ repository.close(); if (!outFilename.empty()) outStream.close(); return (0); }