From d82090afef813e059d80b09311e5221d64dd6201 Mon Sep 17 00:00:00 2001 From: deva Date: Wed, 16 Nov 2005 10:15:38 +0000 Subject: *** empty log message *** --- src/libmplex_wrapper.cc | 723 ++++++++++++++++++---------------------------- src/libmplex_wrapper.h | 15 +- src/mov_encoder_writer.cc | 9 + src/player.cc | 1 + src/yuv_draw.cc | 35 +++ src/yuv_draw.h | 1 + 6 files changed, 344 insertions(+), 440 deletions(-) (limited to 'src') 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 -#ifdef HAVE_GETOPT_H -#include -#endif -#include -#include -#include -#ifndef _WIN32 -#include -#endif -#include -#include -//#include #include #include #include @@ -49,154 +37,127 @@ #include #include - -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 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 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 ... \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(optarg); - do - { - startptr = endptr; - samples_sec = static_cast(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(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(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 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 ... + %%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(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(optarg); + do { + startptr = endptr; + samples_sec = static_cast(strtol(startptr, &endptr, 10)); + if( startptr == endptr || *endptr != ':' ) + return false; + + startptr = endptr+1; + channels = static_cast(strtol(startptr, &endptr, 10)); + if(startptr == endptr || *endptr != ':' ) + return false; + + startptr = endptr+1; + bits_sample = static_cast(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(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 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 #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(); -- cgit v1.2.3