main.cpp
来自「Motion JPEG编解码器源代码」· C++ 代码 · 共 623 行 · 第 1/2 页
CPP
623 行
/************************************************************************** @mainpage* mplex - General-purpose MPEG-1/2 multiplexer.* (C) 2000, 2001 Andrew Stevens <andrew.stevens@philips.com>* * Doxygen documentation and MPEG Z/Alpha multiplexing part by* Gernot Ziegler <gz@lysator.liu.se>* Constructed using mplex - MPEG-1/SYSTEMS multiplexer as starting point* Copyright (C) 1994 1995 Christoph Moar* Siemens ZFE ST SN 11 / T SN 6** 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 <config.h>#include <stdio.h>#ifdef HAVE_GETOPT_H#include <getopt.h>#endif#include <string>#include <memory>#include <sys/stat.h>#ifndef _WIN32#include <sys/param.h>#endif#include <ctype.h>#include <math.h>#include "cpu_accel.h"#include "mjpeg_types.h"#include "mjpeg_logging.h"#include "mpegconsts.h"#include "interact.hpp"#include "bits.hpp"#include "outputstrm.hpp"#include "multiplexor.hpp"using std::auto_ptr;/************************************************************************* Command line wrapper. Basically, all the command line and file (actually pipe and FIFO is what would be more normal) I/O specific sub-classes Plus the top-level entry point. That's all!!*************************************************************************/#if !defined(HAVE_LROUND)extern "C" {longlround(double x){ long l = ceil(x); return(l);}};#endifclass FileOutputStream : public OutputStream{public: FileOutputStream( const char *filename_pat ); virtual int Open( ); virtual void Close(); virtual off_t SegmentSize( ); virtual void NextSegment(); virtual void Write(uint8_t *data, unsigned int len);private: FILE *strm; char filename_pat[MAXPATHLEN]; char cur_filename[MAXPATHLEN];};FileOutputStream::FileOutputStream( const char *name_pat ) { strncpy( filename_pat, name_pat, MAXPATHLEN ); snprintf( cur_filename, MAXPATHLEN, filename_pat, segment_num );} int FileOutputStream::Open(){ strm = fopen( cur_filename, "wb" ); if( strm == NULL ) { mjpeg_error_exit1( "Could not open for writing: %s", cur_filename ); } return 0;}void FileOutputStream::Close(){ fclose(strm);}off_tFileOutputStream::SegmentSize(){ struct stat stb; fstat(fileno(strm), &stb); off_t written = stb.st_size; return written;}void FileOutputStream::NextSegment( ){ auto_ptr<char> prev_filename_buf( new char[strlen(cur_filename)+1] ); char *prev_filename = prev_filename_buf.get(); fclose(strm); ++segment_num; strcpy( prev_filename, cur_filename ); snprintf( cur_filename, MAXPATHLEN, filename_pat, segment_num ); if( strcmp( prev_filename, cur_filename ) == 0 ) { mjpeg_error_exit1( "Need to split output but there appears to be no %%d in the filename pattern %s", filename_pat ); } strm = fopen( cur_filename, "wb" ); if( strm == NULL ) { mjpeg_error_exit1( "Could not open for writing: %s", cur_filename ); }}voidFileOutputStream::Write( uint8_t *buf, unsigned int len ){ if( fwrite( buf, 1, len, strm ) != len ) { mjpeg_error_exit1( "Failed write: %s", cur_filename ); }}/******************************** * * IFileBitStream - Input bit stream class for bit streams sourced * from standard file I/O (this of course *includes* network sockets, * fifo's, et al). * * OLAF: To hook into your PES reader/reconstructor you need to define * a class like this one, where 'ReadStreamBytes' calls you code to * generate the required number of bytes of ES data and transfer it * to the specified buffer. The logical way to do this would be to * inherit IBitStream as a base class of the top-level classes for the ES * reconstructors. * ********************************/class IFileBitStream : public IBitStream{public: IFileBitStream( const char *bs_filename, unsigned int buf_size = BUFFER_SIZE); ~IFileBitStream();private: FILE *fileh; char *filename; virtual size_t ReadStreamBytes( uint8_t *buf, size_t number ) { return fread(buf,sizeof(uint8_t), number, fileh ); } virtual bool EndOfStream() { return feof(fileh) != 0; } };IFileBitStream::IFileBitStream( const char *bs_filename, unsigned int buf_size) : IBitStream(){ if ((fileh = fopen(bs_filename, "rb")) == NULL) { mjpeg_error_exit1( "Unable to open file %s for reading.", bs_filename); } filename = strcpy( new char[strlen(bs_filename)+1], bs_filename ); streamname = filename; SetBufSize(buf_size); eobs = false; byteidx = 0; if (!ReadIntoBuffer()) { if (buffered==0) { mjpeg_error_exit1( "Unable to read from %s.", bs_filename); } }}/** Destructor: close the device containing the bit stream after a read process*/IFileBitStream::~IFileBitStream(){ if (fileh) { fclose(fileh); delete filename; } fileh = 0; Release();}/******************************* * * Command line job class - sets up a Multiplex Job based on command * line and File I/O... * ******************************/class CmdLineMultiplexJob : public MultiplexJob{public: CmdLineMultiplexJob( unsigned int argc, char *argv[]);private: void InputStreamsFromCmdLine (unsigned int argc, char* argv[] ); void Usage(char *program_name); bool ParseVideoOpt( const char *optarg ); bool ParseLpcmOpt( const char *optarg ); bool ParseWorkaroundOpt( const char *optarg ); bool ParseTimeOffset( const char *optarg ); static const char short_options[];#if defined(HAVE_GETOPT_LONG) static struct option long_options[];#endif};const char CmdLineMultiplexJob::short_options[] = "o:b:r:O:v:f:l:s:S:p:W:L:VMh";#if defined(HAVE_GETOPT_LONG)struct option CmdLineMultiplexJob::long_options[] = { { "verbose", 1, 0, 'v' }, { "format", 1, 0, 'f' }, { "mux-bitrate", 1, 0, 'r' }, { "video-buffer", 1, 0, 'b' }, { "lpcm-params", 1, 0, 'L' }, { "output", 1, 0, 'o' }, { "sync-offset", 1, 0, 'O' }, { "vbr", 1, 0, 'V' }, { "system-headers", 1, 0, 'h' }, { "ignore-seqend-markers", 0, 0, 'M' }, { "max-segment-size", 1, 0, 'S' }, { "mux-limit", 1, 0, 'l' }, { "packets-per-pack", 1, 0, 'p' }, { "sector-size", 1, 0, 's' }, { "workarounds", 1, 0, 'W' }, { "help", 0, 0, '?' }, { 0, 0, 0, 0 }};#endifCmdLineMultiplexJob::CmdLineMultiplexJob(unsigned int argc, char *argv[]) : MultiplexJob(){ int n; outfile_pattern = NULL;#if defined(HAVE_GETOPT_LONG) while( (n=getopt_long(argc,argv,short_options,long_options, NULL)) != -1 )#else while( (n=getopt(argc,argv,short_options)) != -1 )#endif { switch(n) { case 0 : break; case 'o' : outfile_pattern = optarg; break; case 'v' : verbose = atoi(optarg); if( verbose < 0 || verbose > 2 ) Usage(argv[0]);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?