mpeg2player.cc
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:10k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /*
  2.    File: mpeg2player.cc
  3.    Description:
  4.    MPEG 2 Transport Stream Player invokes a Demultiplexer object
  5.    which has its own thread of execution. The main program just
  6.    waits until the demultiplexer has finished.
  7.    Created: April 1996, Alex Theo de Jong, NIST
  8. */
  9. #define RELEASE "0.6  October 1999"
  10. #include "athread.hh"
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <String.h>
  14. #include <fstream.h>
  15. #include <sys/time.h>
  16. #include <sys/errno.h>
  17. #ifdef IRIX
  18. #include <dmedia/audio.h>
  19. #endif
  20. #ifdef SOLARIS
  21. #include <sys/audioio.h>
  22. #endif
  23. #include "error.hh"
  24. #include "debug.hh"
  25. #include "util.hh"
  26. #include "network.hh"
  27. #include "sync.hh"
  28. #include "mpeg2const.hh"
  29. #include "mpeg2buff.hh"
  30. #include "mpeg2audio.hh"
  31. #include "mpeg2video.hh"
  32. #include "mpeg2demux.hh"
  33. // socket to read from by demultiplexor
  34. SocketMulti* sock=0;
  35. // Globals for arguments of audio/video
  36. const int arg_max=20;
  37. int audio_argc=0;
  38. char** audio_argv=0;
  39. int video_argc=0;
  40. char** video_argv=0;
  41. // Default parameters
  42. unsigned int asap     = 4000;
  43. int time_stamp_qsize  = 10000;
  44. int frame_stamp_qsize = 1000;
  45. unsigned int MPEG2_TS_Packet_size = 188;
  46. int aal_pdu_size      = 2*MPEG2_TS_Packet_size;
  47. unsigned int vc       = 60; // Virtual Circuit (VP Vitual Path = 0)
  48. int vstream            = 0; // -1=Select first ID in stream, 0, 1, ... = stream ID
  49. int astream            = 0; // -1=Select first ID in stream, 0, 1, ... = stream ID
  50. int audio             = 2;  // 0==Off, 1=MPEG, 2=AC3 
  51. int video             = 1;  // 0= OFF, 1=MPEG-1 2=DVD Mode
  52. int synchro_on        = 1;
  53. int quiet_on          = 0;
  54. int frame_rate        = 0;
  55. int audio_buffer_size = 102400; // The length of these buffers should not matter
  56. int video_buffer_size = 1024000; // for sync purposes  they only need to be big enough
  57. /*
  58.    Assuming 6 Mbps, 0.7 sec (700 msec) between PCR fields which needs to 
  59.    be buffered. 
  60.    6000000 x 0.7 = 4200000 Bits
  61.    Assume 20 % audio, 80 % video (NB. no overhead is counted):
  62.    audio buffer = 0.2 x 4200000 =  840000 bits = 105000 Bytes ~ 102400 Bytes
  63.    video buffer = 0.8 x 4200000 = 3360000 bits = 420000 Bytes ~ 512000 Bytes
  64. */
  65. void usage(const char* name){
  66.   msg("usage: "); msg(name); message(" <options>n");
  67.   message("options:");
  68.   message("t-f <s>ttFilename <s>");
  69.   message("t-nt <n>ttNetwork ASAP <n>");
  70. #ifdef FORE_ATM
  71.   message("t-vc nttVitual Circuit (VC), Vitual Path (VP) is 0");
  72. #endif
  73.   message("t-m <n>ttMapping of <n> MPEG packets per sdu");
  74.   message("t-vstream <n>tSelect video stream <n> for playing");
  75.   message("t-astream <n>tSelect audio stream <n> for playing");
  76.   message("t-mpegttSelect mpeg audio  for playing -- default is AC3");
  77.   message("t-qttQuiet");
  78.   message("t-fq <n>ttQueue size for frame time stamps");
  79.   message("t-tq <n>ttQueue size for time stamps");
  80.   message("t-ab <n>ttAudio buffer size (in KBytes)");
  81.   message("t-vb <n>ttVideo buffer size (in KBytes)");
  82.   message("t-vobttDVD playing mode");
  83.   message("t-nattNo audio");
  84.   message("t-uttuh=Headphones, us=Internal Speaker, ul=Line out");
  85.   message("t-lttOnly decode left channel audio");
  86.   message("t-rttOnly decode right channel audio");
  87.   message("t-nvttNo video");
  88.   message("t-fr nttNumber of frames per second (will result in B-frame skipping)")
  89. //  message("t-c nttChunk size of buffer reading for video");
  90. //  NOTE: be careful when using sychronization
  91.   message("t-ns <n>ttNo synchronization of audio and video");
  92.   message("");
  93.   message("tVOB File Player Version 0.6n");
  94.   message("tbased on");
  95.   message("tMPEG 2 Transport Stream Player");
  96.   msg("tVersion 1.2, November 1996"); 
  97.   message("tAlex Theo de Jong (e-mail: alex.dejong@nist.gov)");
  98.   message("tMulti-Media and Digital Video Group");
  99.   message("tNational Institute of Standards and Technology");
  100.   message("tGaithersburg, Md, U.S.A.");
  101.   message("Original Audio Player code by:");
  102.   message("tTobias Bading");
  103.   message("tBerlin University of Technology, Germany");
  104.   message("Original Video Player code by:");
  105.   message("tMPEG Software Simulation Group    &");
  106.   message("tStefan Eckart");
  107.   message("tFraunhofer-Institut fuer Festkoerpertechnologie, Germany");
  108. }
  109. int main(int argc, char** argv){
  110.   String filename;
  111.   Mpeg2Demux* mpeg2demux=0;
  112.   // Create space for `arg_max' arguments for audio and video
  113.   video_argv=new char*[arg_max];
  114.   video_argv[video_argc++]=strdup("mpeg2player");     // parent
  115.   video_argv[video_argc++]=strdup("buffer");          // "filename"
  116.   String displayname("-d");
  117.   displayname+="MPEG 2 Player, ";
  118.   displayname+=RELEASE;
  119.   video_argv[video_argc++]=strdup(displayname.chars());  // Display title
  120.   audio_argv=new char*[arg_max];
  121.   audio_argv[audio_argc++]=strdup("mpeg2player");     // parent
  122.   audio_argv[audio_argc++]=strdup("buffer");          // "filename"
  123.   // Check/parse arguments
  124.   if (argc<3){
  125.     usage(argv[0]);
  126.     exit(0);
  127.   }
  128.   else {
  129.     for (int i=1; i<argc; i++){
  130.       if (strcmp(argv[i], "-f") == 0 && (i+1)<argc) filename=argv[++i];
  131. // General options
  132.       else if (strcmp(argv[i], "-vstream")==0 && (i+1)<argc) vstream=atoi(argv[++i]);
  133.       else if (strcmp(argv[i], "-astream")==0 && (i+1)<argc) astream=atoi(argv[++i]);
  134.       else if (strcmp(argv[i], "-nt")==0 && (i+1)<argc) asap=(unsigned int) atoi(argv[++i]);
  135. #ifdef FORE_ATM
  136.       else if (strcmp(argv[i], "-vc")==0 && (i+1)<argc) vc=atoi(argv[++i]);
  137. #endif
  138.       else if (strcmp(argv[i], "-m")==0 && (i+1)<argc)
  139.         aal_pdu_size=atoi(argv[++i])*MPEG2_TS_Packet_size;
  140.       else if (strcmp(argv[i], "-vob")==0) { MPEG2_TS_Packet_size = 0x800; aal_pdu_size = 0x20000;video=2;}
  141.       else if (strcmp(argv[i], "-na")==0) audio=0;
  142.       else if (strcmp(argv[i], "-ab")==0 && (i+1)<argc) audio_buffer_size=(atoi(argv[++i])*1024);
  143.       else if (strcmp(argv[i], "-nv")==0) video=0;
  144.       else if (strcmp(argv[i], "-vb")==0&& (i+1)<argc) video_buffer_size=(atoi(argv[++i])*1024);
  145.       else if (strcmp(argv[i], "-ns")==0) synchro_on=0;
  146.       else if (strcmp(argv[i], "-fq")==0 && (i+1)<argc) frame_stamp_qsize=atoi(argv[++i]);
  147.       else if (strcmp(argv[i], "-tq")==0 && (i+1)<argc) time_stamp_qsize=atoi(argv[++i]);
  148.       else if (strcmp(argv[i], "-q")==0) quiet_on=1;
  149.       else if (strcmp(argv[i], "-mpeg")==0) audio=1;
  150. // Video Options
  151.       else if (strcmp(argv[i], "-fr")==0 && (i+1)<argc){
  152.         char* arg=new char[5];
  153.         sprintf(arg, "-f%s", argv[++i]);
  154.         frame_rate=atoi(argv[i]);
  155.         video_argv[video_argc++]=arg;
  156.       }
  157.       else if (strcmp(argv[i], "-c")==0 && (i+1)<argc){
  158.         char* arg=new char[5];
  159.         sprintf(arg, "-c%s", argv[++i]);
  160.         video_argv[video_argc++]=arg;
  161.       }
  162. // Audio Options
  163.       else if (strcmp(argv[i], "-uh")==0) audio_argv[audio_argc++]=strdup(argv[i]);
  164.       else if (strcmp(argv[i], "-ul")==0) audio_argv[audio_argc++]=strdup(argv[i]);
  165.       else if (strcmp(argv[i], "-us")==0) audio_argv[audio_argc++]=strdup(argv[i]);
  166.       else if (strcmp(argv[i], "-l")==0) audio_argv[audio_argc++]=strdup(argv[i]);
  167.       else if (strcmp(argv[i], "-r")==0) audio_argv[audio_argc++]=strdup(argv[i]);
  168.       else {
  169.         msg("unknown argument `"); msg(argv[i]); message("' - ignored");
  170.       }
  171.     }
  172.   }
  173.   if (quiet_on){
  174.     audio_argv[audio_argc++]=strdup("-q");
  175.     video_argv[video_argc++]=strdup("-q");
  176.   }
  177.   // show options
  178.   message("---------------------------------------------");
  179.   msg("Verbosettttt"); if (!quiet_on){ message("On"); } else { message("Off"); }
  180.   msg("Filettttt"); 
  181.   if (filename.length()){ 
  182.     message(filename.chars()); 
  183.   }
  184.   else {
  185.     msg("asap "); message(itoa(asap)); 
  186. #ifdef FORE_ATM
  187.     msg("VPI/VCIttttt0/"); message(itoa(vc)); 
  188. #endif
  189.   }
  190.   msg("SDU sizetttt"); message(itoa(aal_pdu_size));
  191.   msg("Video Stream IDtttt"); message(itoa(vstream));
  192.   msg("Audio Stream IDtttt"); message(itoa(astream));
  193.   msg("Frame ratetttt"); if (frame_rate){ message(itoa(frame_rate)); } else { message("-"); }
  194.   msg("Audiottttt"); 
  195.   if (audio){
  196.     if (audio==2) {
  197.       message("AC3");
  198.     } else {
  199.       message("MPEG");
  200.     }
  201.     msg("Audio buffertttt"); message(itoa(audio_buffer_size));
  202.     msg("Audio Time Stamp bufferttt"); message(itoa(frame_stamp_qsize));
  203.   }
  204.   else { message("Off"); }
  205.   msg("Videottttt");
  206.   if (video){
  207.     message("On");
  208.     msg("Video buffertttt"); message(itoa(video_buffer_size));
  209.     msg("Video Time Stamp bufferttt"); message(itoa(frame_stamp_qsize));
  210.   }
  211.   else { message("Off"); }
  212.   msg("Sync audio/videottt");
  213.   if (synchro_on){
  214.     message("On");
  215.     msg("Time Stamp bufferttt"); message(itoa(time_stamp_qsize));
  216.   }
  217.   else { message("Off"); }
  218.   message("---------------------------------------------");
  219.   video_argv[video_argc]=0;  // termintate last arg with a 0
  220.   audio_argv[audio_argc]=0;  // termintate last arg with a 0
  221.   // Actual MPEG player
  222.   message("Start MPEG 2 Playern");
  223.   
  224.   if (filename.length()){
  225.     // create a file socket
  226.     sock=new SocketMulti(filename.chars());
  227.     mpeg2demux=new Mpeg2Demux(aal_pdu_size, vstream, astream, audio, video, synchro_on, quiet_on);
  228.     
  229.     // the demultiplexer starts the players too!
  230.     
  231. #if (defined(SOLARIS) || defined(IRIX) ) // only with NATIVE Solaris Threads and Irix
  232.     char* c=new char[50];
  233.     do {
  234.       msg("Type 'q' to quit: ");
  235.       athr_yield();
  236.       cin >> c;
  237.       switch(c[0]){
  238.       case '0' :
  239.       case '1' :
  240.       case '2' : mpeg2demux->select(atoi(&c[0])); break;
  241.       case 'p' :
  242.       case 'P' : mpeg2demux->pause();  break;
  243.       case 'r' :
  244.       case 'R' : mpeg2demux->resume(); break;
  245.       case 'q' :
  246.       case 'Q' : {
  247.         mpeg2demux->resume();
  248.         mpeg2demux->stop();
  249.       } break;
  250.       default  : break;
  251.       }
  252.     }
  253.     while (c[0]!='q' && c[0]!='Q');
  254.     delete c;
  255. #endif // without pthreads
  256.   }
  257.   else {
  258.     // a multi socket wait for 4 ports: tcpip, tcpipatm, atmspans, and atmpvc
  259.     sock=new SocketMulti(asap, aal_pdu_size, vc); 
  260.     
  261.     mpeg2demux=new Mpeg2Demux(aal_pdu_size, vstream, astream, audio, video, synchro_on, quiet_on);
  262.   }
  263.   // wait for demux to finish before deleting stuff!!!
  264.   while (!mpeg2demux->done()){
  265.     sleep(2);
  266. //    athr_yield();
  267.   }
  268.   // finish up; 
  269.   delete mpeg2demux;
  270.   int j;
  271.   for (j=0; j<audio_argc; j++) 
  272.     delete audio_argv[j];
  273.   for (j=0; j<video_argc; j++) 
  274.     delete video_argv[j];
  275.   delete audio_argv;
  276.   delete video_argv;
  277.   if (sock){
  278.     sock->close();
  279.     delete sock;
  280.   }
  281.   message("nMPEG 2 Player Finishedn");
  282.   exit(0);
  283. }