Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

mxg2mjpg.cpp

Go to the documentation of this file.
00001 //           ///          //                                        Mx clientSDK
00002 //          /////        ////                    Mx Crossplatform Client Library
00003 //         /// XXX     XXX ///
00004 //        ///    XXX XXX    ///     $RCSfile: mxg2mjpg.cpp,v $
00005 //       ///       XXX       ///     $Revision: 1.1 $
00006 //      ///      XXX XXX      ///     $Date: 2006/01/17 12:43:19 $
00007 //     ////    XXX     XXX    ////     $Author: cvs-kai $
00008 //    ////                     ////
00009 //   ////  M  O  B  O  T  I  X  ////////////////////////////////////////////////
00010 //  //// Security Vision Systems //////////////////////////////////////////////
00011 //                                                                          //
00012 //  Copyright (C) 2005 - 2006, MOBOTIX AG, Germany                         //
00013 //  This software is made available under the BSD licence. Please refer   //
00014 //  to the file LICENCE.TXT contained in this distribution for details.  //
00015 //                                                                      //
00016 //  /////////////////////////////////////////////////////////////////////
00017 
00018 
00019 
00020 /*! \file mxg2mjpg.cpp
00021     \brief The UNIX-style 
00022     <tt>MxPEG</tt>-to-<tt>MJPEG</tt>/<tt>RGB</tt>/<tt>yv12</tt> converter.
00023 */
00024 
00025 
00026 
00027 #include <mxcpcFramewiseMxPEGDecoder.h>
00028 #include <mxcpcStreamFile.h>
00029 #include <mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly.h>
00030 #include <mxcpcFramewiseMxPEGScanDecoderSoftwareOnly.h>
00031 #include <mxcpcDefaultMxPEGDecoderBackEnd.h>
00032 #include <mxcpcMxPEGRawFrameDumper.h>
00033 #include <mxcpcMJPEGWriter.h>
00034 #include <mxcpcDevNullStatusMessageHandler.h>
00035 #include <mxcpcTime.h>
00036 
00037 #include <cstdio>
00038 #include <unistd.h>
00039 
00040 
00041 
00042 void print_usage(const char *progname) {
00043 
00044   std::printf("%s : convert an MxPEG stream to MJPEG\n", progname);
00045   std::printf("%s\n", mxcpc::getVersionString());
00046   std::printf("\n");
00047   std::printf("Usage: %s [options]\n", progname);
00048   std::printf("\n");
00049   std::printf("Options:\n");
00050   std::printf("-h, --help             : this message\n");
00051   std::printf("-f <mxpeg_stream_file> : reads input from <mxpeg_stream_file> "
00052                                        "rather than from stdin\n");
00053   std::printf("-o <output_file>       : writes the generated MJPEG stream "
00054                                        "to <output_file> rather than to "
00055                                        "stdout\n");
00056   std::printf("-s <separator_string>  : HTTP mode, inserts a MIME separator "
00057                                        "between JPEG frames (useful in CGI "
00058                                        "scripts)\n");
00059   std::printf("-raw                   : raw mode, does not output MJPEG "
00060                                        "stream, but raw RGB data instead "
00061                                        "(3 bytes per pixel)\n");
00062   std::printf("-yuv                   : to be used with above raw mode, "
00063                                        "outputs frames in yv12 YUV format "
00064                                        "instead of RGB\n");
00065   std::printf("-sofps <framerate>     : to be used with above raw mode, "
00066                                        "stabilizes output framerate at the "
00067                                        "specified value\n");
00068   std::printf("\n");
00069   std::printf("Examples:\n");
00070   std::printf("cat file1.mxg file2.mxg | %s > file.mjpg\n", progname);
00071   std::printf("curl 'http://<camera_ip>/control/faststream.jpg?stream=MxPEG' "
00072               "| %s -s MOBOTIX_Fast_Serverpush -o file.mjpg\n", progname);
00073   std::printf("C:\\> type file1.mxg | %s > file.mjpg\n", progname);
00074   std::printf("\n"); 
00075 }
00076 
00077 
00078 void process_command_args(int argc, char **argv,
00079                           bool *show_usage,
00080                           const char **mime_separator,
00081                           const char **stream_filename,
00082                           const char **out_filename,
00083                           bool *raw,
00084                           bool *yuv,
00085                           float *sofs)                  {
00086 
00087   int arg_i;
00088   
00089   *show_usage      = false;
00090   *mime_separator  = 0;
00091   *stream_filename = 0;
00092   *out_filename    = 0;
00093   *raw             = false;
00094   *yuv             = false;
00095   *sofs            = -1.0f;
00096   
00097   arg_i = 1;
00098   while(arg_i < argc) {
00099 
00100     if(   !std::strcmp(argv[arg_i], "-h")
00101        || !std::strcmp(argv[arg_i], "--help")) {
00102       *show_usage = true;
00103       arg_i++;
00104     }
00105     else if(!std::strcmp(argv[arg_i], "-s")) {
00106       if(arg_i + 1 < argc) {
00107         *mime_separator = argv[arg_i + 1];
00108         arg_i += 2;
00109       }
00110       else {
00111         *show_usage = true;
00112       }
00113     }
00114     else if(!std::strcmp(argv[arg_i], "-f")) {
00115       if(arg_i + 1 < argc) {
00116         *stream_filename = argv[arg_i + 1];
00117         arg_i += 2;
00118       }
00119       else {
00120         *show_usage = true;
00121       }
00122     }
00123     else if(!std::strcmp(argv[arg_i], "-o")) {
00124       if(arg_i + 1 < argc) {
00125         *out_filename = argv[arg_i + 1];
00126         arg_i += 2;
00127       }
00128       else {
00129         *show_usage = true;
00130       }
00131     }
00132     else if(!std::strcmp(argv[arg_i], "-raw")) {
00133       *raw = true;
00134       arg_i ++;
00135     }
00136     else if(!std::strcmp(argv[arg_i], "-yuv")) {
00137       *yuv = true;
00138       arg_i ++;
00139     }
00140     else if(!std::strcmp(argv[arg_i], "-sofps")) {
00141       if(arg_i + 1 < argc) {
00142         *sofs = std::atof(argv[arg_i + 1]);
00143         if(*sofs < .01f)    *sofs =    .01f;
00144         if(*sofs > 1000.0f) *sofs = 1000.0f;
00145         arg_i += 2;
00146       }
00147       else {
00148         *show_usage = true;
00149       }
00150     }
00151     else {
00152       *show_usage = true;
00153     }
00154     
00155     if(*show_usage) break;
00156   }
00157 }
00158 
00159 
00160 
00161 int main(int argc, char **argv) {
00162 
00163   bool show_usage;
00164   const char *mime_separator;
00165   const char *stream_filename;
00166   const char *out_filename;
00167   const char *progname;
00168   bool raw;
00169   bool yuv;
00170   float sofs;
00171   mxcpcFramewiseMxPEGDecoder *decoder;
00172   mxcpcStreamFile *stream_file;
00173   mxcpcMJPEGWriter *writer;
00174   mxcpcMxPEGRawFrameDumper *frame_dumper;
00175   mxcpcBinaryFileWriter *raw_writer;
00176   mxcpcTime da_time;
00177   int cycle_time, time_left, timeout;
00178   
00179   progname = "mxg2mjpg";
00180   
00181   // process command args...
00182   process_command_args(argc, argv,
00183                        &show_usage, 
00184                        &mime_separator, 
00185                        &stream_filename, 
00186                        &out_filename,
00187                        &raw,
00188                        &yuv,
00189                        &sofs);
00190   if(show_usage) {
00191     print_usage(progname);
00192     std::exit(0);
00193   }
00194 
00195   // ok, we actually have some work to do...
00196   
00197   // we don't have use for mxcpc status messages...
00198   mxcpc::setStatusMessageHandler(new mxcpcDevNullStatusMessageHandler());
00199   
00200   // open input streamfile...
00201   if(stream_filename) 
00202    stream_file = new mxcpcStreamFile(stream_filename);
00203   else
00204    stream_file = new mxcpcStreamFile(STDIN_FILENO);
00205   
00206   // open output...
00207   writer     = 0;   // suppress compiler warnings...
00208   raw_writer = 0;
00209   if(!raw) {
00210     if(out_filename)
00211      writer = new mxcpcMJPEGWriter(out_filename, mime_separator);
00212     else
00213      writer = new mxcpcMJPEGWriter(STDOUT_FILENO, mime_separator);
00214   }
00215   else {
00216     if(out_filename)
00217      raw_writer = new mxcpcBinaryFileWriter(out_filename);
00218     else
00219      raw_writer = new mxcpcBinaryFileWriter(STDOUT_FILENO);
00220   }
00221   
00222   // set up decoder configuration...
00223   if(!raw) {
00224     decoder = new mxcpcFramewiseMxPEGDecoder(
00225                     stream_file,
00226                     new mxcpcDefaultMxPEGDecoderBackEnd(),
00227                     new mxcpcFramewiseMxPEGScanToJPEGConverterSoftwareOnly(
00228                          writer
00229                         )
00230                   );
00231   }
00232   else {
00233     frame_dumper = new mxcpcMxPEGRawFrameDumper(raw_writer, yuv);
00234     decoder = new mxcpcFramewiseMxPEGDecoder(
00235                     stream_file,
00236                     frame_dumper,
00237                     new mxcpcFramewiseMxPEGScanDecoderSoftwareOnly()
00238                   );
00239   }
00240   
00241   // process stream data...
00242   if(raw & sofs > 0.0f) {
00243   
00244     cycle_time = (int)(1000.0f / sofs);
00245     time_left  = 0;
00246     
00247     frame_dumper->setExplicitDumpModeEnabled(true);
00248     
00249     while(decoder->sourceStillUp()) {
00250       
00251       // check time...
00252       time_left -= da_time.elapsed();
00253       
00254       // dump due frames...
00255       while(time_left <= 0) {
00256         frame_dumper->dumpFrame();
00257         time_left += cycle_time;
00258       }
00259       
00260       // determine timeout so we get wakened in time for the next frame to 
00261       // dump...
00262       timeout = time_left;
00263       if(timeout < 10)   timeout = 10;
00264       if(timeout > 1000) timeout = 1000;   // don't block longer than a second
00265       stream_file->setTimedBlockModeEnabled(true, timeout);
00266       
00267       // decode or block until timeout...
00268       decoder->decode(2048);
00269     }
00270   
00271   }
00272   else {
00273     while(decoder->sourceStillUp()) 
00274      decoder->decode(2048); 
00275   }
00276   
00277   // close files, clean up and and exit...
00278   delete decoder;
00279   mxcpc::setStatusMessageHandler(0);
00280   std::exit(0);
00281 }
00282 

Generated on Mon Jan 30 15:13:08 2006 for mxcpc by  doxygen 1.4.4