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 + -
显示快捷键?