diff options
| -rw-r--r-- | src/libmplex_wrapper.cc | 723 | ||||
| -rw-r--r-- | src/libmplex_wrapper.h | 15 | ||||
| -rw-r--r-- | src/mov_encoder_writer.cc | 9 | ||||
| -rw-r--r-- | src/player.cc | 1 | ||||
| -rw-r--r-- | src/yuv_draw.cc | 35 | ||||
| -rw-r--r-- | src/yuv_draw.h | 1 | 
6 files changed, 344 insertions, 440 deletions
| diff --git a/src/libmplex_wrapper.cc b/src/libmplex_wrapper.cc index 9b37c02..a93b4a9 100644 --- a/src/libmplex_wrapper.cc +++ b/src/libmplex_wrapper.cc @@ -26,20 +26,8 @@   */  #include "config.h"  #include "libmplex_wrapper.h" +#include "miav_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> @@ -49,154 +37,127 @@  #include <mplex/outputstrm.hpp>  #include <mplex/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" { -long -lround(double x) -{ -	long l = (long)ceil(x); -	return(l); -} -}; -#endif - - - +/** + * FrameOutputStream - Wraps the File object + */  class FrameOutputStream : public OutputStream  {  public: -    FrameOutputStream( 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); +    FrameOutputStream( Info *info, File *outputfile ); +    int  Open( ); +    void Close(); +    off_t SegmentSize( ); +    void NextSegment(); +    void Write(uint8_t *data, unsigned int len);  private: -    FILE *strm; -    char filename_pat[MAXPATHLEN]; -    char cur_filename[MAXPATHLEN]; - +  Info *info; +  off_t written; +  File *file;  }; -FrameOutputStream::FrameOutputStream( const char *name_pat )  +FrameOutputStream::FrameOutputStream( Info *info, File *outputfile )   { -	strncpy( filename_pat, name_pat, MAXPATHLEN ); -	snprintf( cur_filename, MAXPATHLEN, filename_pat, segment_num ); +  this->info = info; +  file = outputfile; +  written = 0; +  info->info("FrameOutputStream - constructor");  }  int FrameOutputStream::Open()  { -	strm = fopen( cur_filename, "wb" ); -	if( strm == NULL ) -	{ -		mjpeg_error_exit1( "Could not open for writing: %s", cur_filename ); -	} - +  //  info->info("FrameOutputStream::Open"); +  // Nothing to do here!  	return 0;  }  void FrameOutputStream::Close()  {  -    fclose(strm); +  //  info->info("FrameOutputStream::Close"); +  // Nothing to do here!  } -off_t -FrameOutputStream::SegmentSize() +off_t FrameOutputStream::SegmentSize()  { +  //  info->info("FrameOutputStream::SegmentSize - return: %d", written); +  return written; + +  /*  	struct stat stb; -    fstat(fileno(strm), &stb); +  fstat(fileno(strm), &stb);  	off_t written = stb.st_size; -    return written; +  return written; +  */  } -void  -FrameOutputStream::NextSegment( ) +void FrameOutputStream::NextSegment( )  { -    auto_ptr<char> prev_filename_buf( new char[strlen(cur_filename)+1] ); -    char *prev_filename = prev_filename_buf.get(); +  //  info->info("FrameOutputStream::NextSegment"); +  // Nothing to do here! +  /* +  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 ); +  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 ); +	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 ) -	{ +	if( strm == NULL ) {  		mjpeg_error_exit1( "Could not open for writing: %s", cur_filename );  	} +  */  } -void -FrameOutputStream::Write( uint8_t *buf, unsigned int len ) +void FrameOutputStream::Write( uint8_t *buf, unsigned int len )  { -    if( fwrite( buf, 1, len, strm ) != len ) -    { -        mjpeg_error_exit1( "Failed write: %s", cur_filename ); -    } +  unsigned int write; +  write = file->Write(buf, len); +  written += write; +  //  info->info("FrameOutputStream::Write - len: %d", len);  } - - -/******************************** - * - * FrameInputStream - 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. - * - ********************************/ - +/** + * FrameInputStream - Wraps the ThreadSafeQueuePriority objects, containing  + * the prosessed frames from libfame and liblame. + */  class FrameInputStream : public IBitStream  {  public: - 	FrameInputStream( const char *bs_filename,  -					unsigned int buf_size = BUFFER_SIZE); + 	FrameInputStream(  Info *info, ThreadSafeQueuePriority *queue );  	~FrameInputStream();  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; } -	 +  Frame *getFrame(); +  size_t ReadStreamBytes( uint8_t *buf, size_t size ); +	bool EndOfStream(); + +  Info *info; +  ThreadSafeQueuePriority *queue; +  bool seen_eof; +  Frame *frame; +  unsigned int read;  }; - - -FrameInputStream::FrameInputStream( const char *bs_filename, -                                unsigned int buf_size) : +FrameInputStream::FrameInputStream( Info *info, ThreadSafeQueuePriority *queue ) :      IBitStream()  { +  this->info = info; +  this->queue = queue; +  seen_eof = false; +  frame = NULL; +  read = 0; +  streamname = "MIaV Stream\0"; +   +  //  info->info("FrameInputStream - constructor", seen_eof); + +  /*  	if ((fileh = fopen(bs_filename, "rb")) == NULL)  	{  		mjpeg_error_exit1( "Unable to open file %s for reading.", bs_filename); @@ -214,6 +175,18 @@ FrameInputStream::FrameInputStream( const char *bs_filename,  			mjpeg_error_exit1( "Unable to read from %s.", bs_filename);  		}  	} +  */ +  SetBufSize(BUFFER_SIZE); +  // SetBufSize(buf_size); +	eobs = false; +  byteidx = 0; +	if (!ReadIntoBuffer()) { +		if (buffered==0) { +      info->error( "Unable to read from %s.", streamname); +		} +	} + +  //  info->info("FrameInputStream - leaving constructor", seen_eof);  } @@ -223,15 +196,69 @@ FrameInputStream::FrameInputStream( const char *bs_filename,  */  FrameInputStream::~FrameInputStream()  { +  //  info->info("FrameInputStream - destructor", seen_eof); +  // Nothing to do here! +  /*  	if (fileh)  	{  		fclose(fileh);  		delete filename;  	}  	fileh = 0; -    Release(); +  */ +  Release(); // Hmmm.. wonder what this 'Release()' does!? +} + +Frame *FrameInputStream::getFrame() +{ +  read = 0; +  return queue->pop(); +} + +bool FrameInputStream::EndOfStream() +{  +  //  info->info("FrameInputStream::EndOfStream - return: %d", seen_eof); +  return seen_eof;  } +size_t FrameInputStream::ReadStreamBytes( uint8_t *buf, size_t size )  +{ +  //  info->info("FrameInputStream::ReadStreamBytes - size: %d", size); +  unsigned int copied = 0; +   +  while( copied < size ) { +     +    // If we read the entire frame, prepare to get a new one +    if(frame && read == frame->size) { +      delete frame; +      frame = NULL; +    } +     +    // If no frame is in the buffer, get one from the queue +    if(frame == NULL) frame = getFrame(); +     +    // check for end of stream +    if( frame->endOfFrameStream == true) { +      seen_eof = true; +      return copied; +    } +     +    // If a frame exists in the buffer copy it to the output buffer +    // (No frame ocurres when *running is set to false) +    if( frame ) { +      unsigned int doread = (size - copied) < (frame->size - read) ? +        size - copied : (frame->size - read); +       +      //info->info("Requested: %d. Read: %d. Doread: %d. In buffer %d", size, (*read), doread, (*frame)->size); +       +      memcpy(buf + copied, frame->data + read, doread); +      read += doread; +      copied += doread; +    } +    } +   +  return copied; +}  /*******************************   * @@ -240,318 +267,160 @@ FrameInputStream::~FrameInputStream()   *   ******************************/ -class CmdLineMultiplexJob : public MultiplexJob +class MIaVMultiplexJob : public MultiplexJob  {  public: -	CmdLineMultiplexJob( unsigned int argc, char *argv[]); +	MIaVMultiplexJob(Info *info,  +                   ThreadSafeQueuePriority *video_queue, +                   ThreadSafeQueuePriority *audio_queue);  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   }  }; -#endif - -CmdLineMultiplexJob::CmdLineMultiplexJob(unsigned int argc, char *argv[]) : +MIaVMultiplexJob::MIaVMultiplexJob(Info *info,  +                                   ThreadSafeQueuePriority *video_queue, +                                   ThreadSafeQueuePriority *audio_queue) :  	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]); -			break; - -		case 'V' : -			VBR = true; -			break; -	   -		case 'h' : -			always_system_headers = true; -			break; - -		case 'b' : -            if( ! ParseVideoOpt( optarg ) ) -            { -                mjpeg_error( "Illegal video decoder buffer size(s): %s",  -                             optarg ); -                Usage(argv[0]); -            } -            break; -        case 'L': -            if( ! ParseLpcmOpt( optarg ) ) -            { -                mjpeg_error( "Illegal LPCM option(s): %s", optarg ); -                Usage(argv[0]); -            } -            break; - -		case 'r': -			data_rate = atoi(optarg); -			if( data_rate < 0 ) -				Usage(argv[0]); -			/* Convert from kbit/sec (user spec) to 50B/sec units... */ -			data_rate = (( data_rate * 1000 / 8 + 49) / 50 ) * 50; -			break; - -		case 'O': -			if( ! ParseTimeOffset(optarg) ) -			{ -				mjpeg_error( "Time offset units if specified must: ms|s|mpt" ); -				Usage(argv[0]); -			} -			break; -           -		case 'l' :  - 			max_PTS = atoi(optarg); -			if( max_PTS < 1  ) -				Usage(argv[0]); -			break; -		 -		case 'p' :  -			packets_per_pack = atoi(optarg); -			if( packets_per_pack < 1 || packets_per_pack > 100  ) -				Usage(argv[0]); -			break; -		 -	   -		case 'f' : -			mux_format = atoi(optarg); -			if( mux_format < MPEG_FORMAT_MPEG1 || mux_format > MPEG_FORMAT_LAST -                ) -				Usage(argv[0]); -			break; -		case 's' : -			sector_size = atoi(optarg); -			if( sector_size < 256 || sector_size > 16384 ) -				Usage(argv[0]); -			break; -		case 'S' : -			max_segment_size = atoi(optarg); -			if( max_segment_size < 0  ) -				Usage(argv[0]); -			break; -		case 'M' : -			multifile_segment = true; -			break; -        case 'W' : -            if( ! ParseWorkaroundOpt( optarg ) ) -            { -                Usage(argv[0]); -            } -            break; -		case '?' : -		default : -			Usage(argv[0]); -			break; -		} -	} -	if (argc - optind < 1 || outfile_pattern == NULL) -    {	 -		Usage(argv[0]); -    } -	(void)mjpeg_default_handler_verbosity(verbose); -	mjpeg_info( "mplex version %s (%s %s)",VERSION,MPLEX_VER,MPLEX_DATE ); +  //  this->info = info; +  //  info->info("MIaVMultiplexJob - constructor"); +  outfile_pattern = "/tmp/aaargh.mpg"; // Output file... or something -    InputStreamsFromCmdLine( argc-(optind-1), argv+optind-1); -} - -/************************************************************************* - Usage banner for the command line wrapper. -*************************************************************************/ - -     -void CmdLineMultiplexJob::Usage(char *str) -{ -    fprintf( stderr, -	"mjpegtools mplex-2 version " VERSION " (" MPLEX_VER ")\n" -	"Usage: %s [params] -o <output filename pattern> <input file>... \n" -	"         %%d in the output file name is by segment count\n" -	"  where possible params are:\n" -	"--verbose|-v num\n" -    "  Level of verbosity. 0 = quiet, 1 = normal 2 = verbose/debug\n" -	"--format|-f fmt\n" -    "  Set defaults for particular MPEG profiles\n" -	"  [0 = Generic MPEG1, 1 = VCD, 2 = user-rate VCD, 3 = Generic MPEG2,\n" -    "   4 = SVCD, 5 = user-rate SVCD\n" -	"   6 = VCD Stills, 7 = SVCD Stills, 8 = DVD with NAV sectors, 9 = DVD]\n" -    "--mux-bitrate|-r num\n" -    "  Specify data rate of output stream in kbit/sec\n" -	"    (default 0=Compute from source streams)\n" -	"--video-buffer|-b num [, num...] \n" -    "  Specifies decoder buffers size in kB.  [ 20...2000]\n" -    "--lpcm-params | -L samppersec:chan:bits [, samppersec:chan:bits]\n" -	"--mux-limit|-l num\n" -    "  Multiplex only num seconds of material (default 0=multiplex all)\n" -	"--sync-offset|-O num ms|s|mpt\n" -    "  Specify offset of timestamps (video-audio) in mSec\n" -	"--sector-size|-s num\n" -    "  Specify sector size in bytes for generic formats [256..16384]\n" -    "--vbr|-V\n" -    "  Multiplex variable bit-rate video\n" -	"--packets-per-pack|-p num\n" -    "  Number of packets per pack generic formats [1..100]\n" -	"--system-headers|-h\n" -    "  Create System header in every pack in generic formats\n" -	"--max-segment-size|-S size\n" -    "  Maximum size of output file(s) in Mbyte (default: 0) (no limit)\n" -	"--ignore-seqend-markers|-M\n" -    "  Don't switch to a new output file if a  sequence end marker\n" -	"  is encountered ithe input video.\n" -    "--workaround|-W workaround [, workaround ]\n" -	"--help|-?\n" -    "  Print this lot out!\n", str); -	exit (1); -} +  verbose = 0; // Level of verbosity. 0 = quiet, 1 = normal 2 = verbose/debug +  VBR = config->readInt("video_bitrate") == 0; // Multiplex variable bit-rate video -bool CmdLineMultiplexJob::ParseLpcmOpt( const char *optarg ) -{ -    char *endptr, *startptr; -    unsigned int samples_sec; -    unsigned int channels; -    unsigned int bits_sample; -    endptr = const_cast<char *>(optarg); -    do  -    { -        startptr = endptr; -        samples_sec = static_cast<unsigned int>(strtol(startptr, &endptr, 10)); -        if( startptr == endptr || *endptr != ':' ) -            return false; +  always_system_headers = true; //  Create System header in every pack in generic formats +  // Specifies decoder buffers size in kB.  [ 20...2000] +  if( ! ParseVideoOpt( "500" ) ) +    info->error( "Illegal video decoder buffer size(s): %s", "500" ); -        startptr = endptr+1; -        channels = static_cast<unsigned int>(strtol(startptr, &endptr, 10)); -        if(startptr == endptr || *endptr != ':' ) -            return false; +  // --lpcm-params | -L samppersec:chan:bits [, samppersec:chan:bits] +  //  if( ! ParseLpcmOpt( "48000:2:16" ) ) info->error( "Illegal LPCM option(s): %s", "48000:2:16" ); -        startptr = endptr+1; -        bits_sample = static_cast<unsigned int>(strtol(startptr, &endptr, 10)); -        if( startptr == endptr ) -            return false; +  data_rate = 0; //Specify data rate of output stream in kbit/sec (default 0=Compute from source streams) +  // Convert from kbit/sec (user spec) to 50B/sec units... +  data_rate = (( data_rate * 1000 / 8 + 49) / 50 ) * 50; -        LpcmParams *params = LpcmParams::Checked( samples_sec, -                                                  channels, -                                                  bits_sample ); -        if( params == 0 ) -            return false; -        lpcm_param.push_back(params); -        if( *endptr == ',' ) -            ++endptr; -    } while( *endptr != '\0' ); -    return true; +  audio_offset = 0; //Specify offset of timestamps (video-audio) in mSec +  video_offset = 0; //Specify offset of timestamps (video-audio) in mSec +           +  max_PTS = 0; // Multiplex only num seconds of material (default 0=multiplex all) +   +  packets_per_pack = 5; //Number of packets per pack generic formats [1..100] +   +  mux_format = 3; // Set defaults for particular MPEG profiles: +  // 0 = Generic MPEG1 +  // 1 = VCD +  // 2 = user-rate VCD +  // 3 = Generic MPEG2 +  // 4 = SVCD +  // 5 = user-rate SVCD +  // 6 = VCD Stills +  // 7 = SVCD Stills +  // 8 = DVD with NAV sectors +  // 9 = DVD + +  sector_size = 2042; // Specify sector size in bytes for generic formats [256..16384] +   +  //max_segment_size = 0; // Maximum size of output file(s) in Mbyte (default: 0) (no limit) +   +  multifile_segment = true; // Don't switch to a new output file if a sequence end marker +  // is encountered ithe input video + +  (void)mjpeg_default_handler_verbosity(verbose); +  info->info( "mplex version %s (%s %s)", VERSION,MPLEX_VER, MPLEX_DATE ); +   +  // Connect streams +	vector<IBitStream *> inputs; +  if(video_queue) inputs.push_back( new FrameInputStream( info, video_queue ) ); +  if(audio_queue) inputs.push_back( new FrameInputStream( info, audio_queue ) ); +	SetupInputStreams( inputs );  } +/************************************************************************* + Usage banner for the command line wrapper. +*************************************************************************/ +/* +	mjpegtools mplex-2 version  VERSION  ( MPLEX_VER ) +	Usage: %s [params] -o <output filename pattern> <input file>...  +	         %%d in the output file name is by segment count +	  where possible params are: +	--verbose|-v num +      Level of verbosity. 0 = quiet, 1 = normal 2 = verbose/debug +	--format|-f fmt +      Set defaults for particular MPEG profiles +	  [0 = Generic MPEG1, 1 = VCD, 2 = user-rate VCD, 3 = Generic MPEG2, +       4 = SVCD, 5 = user-rate SVCD +	   6 = VCD Stills, 7 = SVCD Stills, 8 = DVD with NAV sectors, 9 = DVD] +  --mux-bitrate|-r num +      Specify data rate of output stream in kbit/sec +	    (default 0=Compute from source streams) +	--video-buffer|-b num [, num...]  +      Specifies decoder buffers size in kB.  [ 20...2000] +  --lpcm-params | -L samppersec:chan:bits [, samppersec:chan:bits] +	--mux-limit|-l num +      Multiplex only num seconds of material (default 0=multiplex all) +	--sync-offset|-O num ms|s|mpt +      Specify offset of timestamps (video-audio) in mSec +	--sector-size|-s num +      Specify sector size in bytes for generic formats [256..16384] +  --vbr|-V +      Multiplex variable bit-rate video +	--packets-per-pack|-p num +      Number of packets per pack generic formats [1..100] +	--system-headers|-h +      Create System header in every pack in generic formats +	--max-segment-size|-S size +      Maximum size of output file(s) in Mbyte (default: 0) (no limit) +	--ignore-seqend-markers|-M +      Don't switch to a new output file if a  sequence end marker +	  is encountered ithe input video. +  --workaround|-W workaround [, workaround ] +	--help|-? +      Print this lot out! +*/ -bool CmdLineMultiplexJob::ParseWorkaroundOpt( const char *optarg ) -{ -    char *endptr, *startptr; -    endptr = const_cast<char *>(optarg); -    struct { const char *longname; char shortname; bool *flag; } flag_table[] = -        { -            { 0, '\0', 0 } -        }; -    for(;;) -    { -        // Find start of next flag... -        while( isspace(*endptr) || *endptr == ',' ) -            ++endptr; -        if( *endptr == '\0' ) -            break; -        startptr = endptr; -        // Find end of current flag... -        while( *endptr != ' ' && *endptr != ',' && *endptr != '\0' ) -            ++endptr; -             -        size_t len = endptr - startptr; - -        int flag = 0; -        while( flag_table[flag].longname != 0 ) -        { -            if( (len == 1 && *startptr == flag_table[flag].shortname ) || -                strncmp( startptr, flag_table[flag].longname, len ) == 0 ) -            { -                *flag_table[flag].flag = true; -                break; -            } -            ++flag; -        } - -        if( flag_table[flag].longname == 0 ) -        { -            std::string message( "Illegal work-around option: not one of " ); -            flag = 0; -            char sep[] = ","; -            do -            { -                message += flag_table[flag].longname; -                message += sep; -                message += flag_table[flag].shortname; -                ++flag; -                if( flag_table[flag].longname != 0 ) -                    message += sep; -            } -            while( flag_table[flag].longname != 0 ); -            mjpeg_error( message.c_str() ); -            return false; -        } -    }  -    return true; +bool MIaVMultiplexJob::ParseLpcmOpt( const char *optarg ) +{ +  char *endptr, *startptr; +  unsigned int samples_sec; +  unsigned int channels; +  unsigned int bits_sample; +  endptr = const_cast<char *>(optarg); +  do { +    startptr = endptr; +    samples_sec = static_cast<unsigned int>(strtol(startptr, &endptr, 10)); +    if( startptr == endptr || *endptr != ':' ) +      return false; +     +    startptr = endptr+1; +    channels = static_cast<unsigned int>(strtol(startptr, &endptr, 10)); +    if(startptr == endptr || *endptr != ':' ) +      return false; +     +    startptr = endptr+1; +    bits_sample = static_cast<unsigned int>(strtol(startptr, &endptr, 10)); +    if( startptr == endptr ) +      return false; +       +    LpcmParams *params = LpcmParams::Checked( samples_sec, +                                              channels, +                                              bits_sample ); +    if( params == 0 ) +      return false; +    lpcm_param.push_back(params); +    if( *endptr == ',' ) +      ++endptr; +  } while( *endptr != '\0' ); +  return true;  } -bool CmdLineMultiplexJob::ParseVideoOpt( const char *optarg ) +bool MIaVMultiplexJob::ParseVideoOpt( const char *optarg )  {      char *endptr, *startptr;      unsigned int buffer_size; @@ -574,53 +443,29 @@ bool CmdLineMultiplexJob::ParseVideoOpt( const char *optarg )      return true;  } -bool CmdLineMultiplexJob::ParseTimeOffset(const char *optarg) -{ -    double f; -    double persecond=1000.0; -    char *e; - -    f=strtod(optarg,&e); -    if( *e ) { -        while(isspace(*e)) e++; -        if(!strcmp(e,"ms")) persecond=1000.0; -        else if(!strcmp(e,"s")) persecond=1.0; -        else if(!strcmp(e,"mpt")) persecond=90000.0; -		else -			return false; -    } -    video_offset = static_cast<int>(f*CLOCKS/(persecond)); -	if( video_offset < 0 ) -	{ -		audio_offset = - video_offset; -		video_offset = 0; -	} -	return true; -} - -void CmdLineMultiplexJob::InputStreamsFromCmdLine(unsigned int argc, char* argv[] ) -{ -	vector<IBitStream *> inputs; -    unsigned int i; -	for( i = 1; i < argc; ++i ) -    { -		inputs.push_back( new FrameInputStream( argv[i] ) ); -	} -	SetupInputStreams( inputs ); -} - -LibMPlexWrapper::LibMPlexWrapper() +LibMPlexWrapper::LibMPlexWrapper(Info *info, +                                 File *outputfile, +                                 ThreadSafeQueuePriority *video_queue, +                                 ThreadSafeQueuePriority *audio_queue)  { +  this->info = info; +  this->outputfile = outputfile; +  this->video_queue = video_queue; +  this->audio_queue = audio_queue;  }  LibMPlexWrapper::~LibMPlexWrapper()  {  } +  void LibMPlexWrapper::multiplex()  { -	CmdLineMultiplexJob job(0, NULL); -	FrameOutputStream output( job.outfile_pattern ); +  //  info->info("MPLEX!"); +  //  sleep(10); +  //  info->info("The road goes ever on and on..."); +	MIaVMultiplexJob job(info, video_queue, audio_queue); +	FrameOutputStream output( info, outputfile );  	Multiplexor mux(job, output);  	mux.Multiplex();  } diff --git a/src/libmplex_wrapper.h b/src/libmplex_wrapper.h index 0246314..8591563 100644 --- a/src/libmplex_wrapper.h +++ b/src/libmplex_wrapper.h @@ -28,12 +28,25 @@  #ifndef __MIAV_LIBMPLEX_WRAPPER_H__  #define __MIAV_LIBMPLEX_WRAPPER_H__ +#include "info.h" +#include "file.h" +#include "threadsafe_queue_priority.h" +  class LibMPlexWrapper {  public: -	LibMPlexWrapper(); +	LibMPlexWrapper(Info *info,  +                  File *outputfile, +                  ThreadSafeQueuePriority *video_queue, +                  ThreadSafeQueuePriority *audio_queue);  	~LibMPlexWrapper();    void multiplex(); + +private: +  Info *info; +  File *outputfile; +  ThreadSafeQueuePriority *video_queue; +  ThreadSafeQueuePriority *audio_queue;  };  #endif/*__MIAV_LIBMPLEX_WRAPPER_H__*/ diff --git a/src/mov_encoder_writer.cc b/src/mov_encoder_writer.cc index 9bedba1..e831b9e 100644 --- a/src/mov_encoder_writer.cc +++ b/src/mov_encoder_writer.cc @@ -45,6 +45,7 @@ using namespace std;  #include <time.h>  #include "multiplexer.h" +#include "libmplex_wrapper.h"  #include "multicast_configuration.h" @@ -122,6 +123,14 @@ void MovEncoderWriter::thread_main()                            audio_queue);    multiplexer.multiplex(); +  /* +  LibMPlexWrapper mplex(info, +                        file, +                        video_queue, +                        audio_queue); +  mplex.multiplex(); +  */ +    info->info("MovEncoderWriter::stop");  } diff --git a/src/player.cc b/src/player.cc index f6ac686..58d3897 100644 --- a/src/player.cc +++ b/src/player.cc @@ -205,6 +205,7 @@ void Player::player()                             pitches);        // Set status text +      yuv_draw->mute(true);        if(recording != recording_prev) {          if(recording) yuv_draw->setTopText(TEXT_RECORDING);          else yuv_draw->setTopText(TEXT_STOPPED); diff --git a/src/yuv_draw.cc b/src/yuv_draw.cc index a444fa7..bb8b23f 100644 --- a/src/yuv_draw.cc +++ b/src/yuv_draw.cc @@ -143,7 +143,42 @@ void YUVDraw::draw()    }  } +static QImage *loadIcon( char *name, int height ) +{ +  QImage scaled; +  QImage *img; + +  img = new QImage(); +  img->load( name ); + +  int h = height; +  int w = (int)((float)img->width() / (float)(img->height() / (float)h)); +  scaled = img->smoothScale(w, h); +  delete img; +  img = new QImage(scaled); + +  return img; +} +#include "mainwindow.h" +void YUVDraw::mute(bool muted) +{ +  int xoffset = 0; +  int yoffset = 0; +  int width = 48; +  int height = 48; + +  QImage *img = loadIcon(PIXMAP_UNMUTE, height); + +  //  Swicth the bool and draw an mute/unmute symbol +  for(int x = 0; x < width; x++) { +    for(int y = 0; y < height; y++) { +      unsigned char color = qGray(img->pixel(x, y)); +      if(!qAlpha(img->pixel(x, y))) color = 0; +      addPixel(x + xoffset, y + yoffset, color); +    } +  } +} diff --git a/src/yuv_draw.h b/src/yuv_draw.h index 9c5b84a..651eb8e 100644 --- a/src/yuv_draw.h +++ b/src/yuv_draw.h @@ -46,6 +46,7 @@ public:    void setTopText(char* text);    void setBottomText(char* text); +  void mute(bool muted);    void draw(); | 
