summaryrefslogtreecommitdiff
path: root/src/libmplex_wrapper.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmplex_wrapper.cc')
-rw-r--r--src/libmplex_wrapper.cc723
1 files changed, 284 insertions, 439 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();
}