mpeg2player.cc
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:10k
- /*
- File: mpeg2player.cc
- Description:
- MPEG 2 Transport Stream Player invokes a Demultiplexer object
- which has its own thread of execution. The main program just
- waits until the demultiplexer has finished.
- Created: April 1996, Alex Theo de Jong, NIST
- */
- #define RELEASE "0.6 October 1999"
- #include "athread.hh"
- #include <stdio.h>
- #include <stdlib.h>
- #include <String.h>
- #include <fstream.h>
- #include <sys/time.h>
- #include <sys/errno.h>
- #ifdef IRIX
- #include <dmedia/audio.h>
- #endif
- #ifdef SOLARIS
- #include <sys/audioio.h>
- #endif
- #include "error.hh"
- #include "debug.hh"
- #include "util.hh"
- #include "network.hh"
- #include "sync.hh"
- #include "mpeg2const.hh"
- #include "mpeg2buff.hh"
- #include "mpeg2audio.hh"
- #include "mpeg2video.hh"
- #include "mpeg2demux.hh"
- // socket to read from by demultiplexor
- SocketMulti* sock=0;
- // Globals for arguments of audio/video
- const int arg_max=20;
- int audio_argc=0;
- char** audio_argv=0;
- int video_argc=0;
- char** video_argv=0;
- // Default parameters
- unsigned int asap = 4000;
- int time_stamp_qsize = 10000;
- int frame_stamp_qsize = 1000;
- unsigned int MPEG2_TS_Packet_size = 188;
- int aal_pdu_size = 2*MPEG2_TS_Packet_size;
- unsigned int vc = 60; // Virtual Circuit (VP Vitual Path = 0)
- int vstream = 0; // -1=Select first ID in stream, 0, 1, ... = stream ID
- int astream = 0; // -1=Select first ID in stream, 0, 1, ... = stream ID
- int audio = 2; // 0==Off, 1=MPEG, 2=AC3
- int video = 1; // 0= OFF, 1=MPEG-1 2=DVD Mode
- int synchro_on = 1;
- int quiet_on = 0;
- int frame_rate = 0;
- int audio_buffer_size = 102400; // The length of these buffers should not matter
- int video_buffer_size = 1024000; // for sync purposes they only need to be big enough
- /*
- Assuming 6 Mbps, 0.7 sec (700 msec) between PCR fields which needs to
- be buffered.
- 6000000 x 0.7 = 4200000 Bits
- Assume 20 % audio, 80 % video (NB. no overhead is counted):
- audio buffer = 0.2 x 4200000 = 840000 bits = 105000 Bytes ~ 102400 Bytes
- video buffer = 0.8 x 4200000 = 3360000 bits = 420000 Bytes ~ 512000 Bytes
- */
- void usage(const char* name){
- msg("usage: "); msg(name); message(" <options>n");
- message("options:");
- message("t-f <s>ttFilename <s>");
- message("t-nt <n>ttNetwork ASAP <n>");
- #ifdef FORE_ATM
- message("t-vc nttVitual Circuit (VC), Vitual Path (VP) is 0");
- #endif
- message("t-m <n>ttMapping of <n> MPEG packets per sdu");
- message("t-vstream <n>tSelect video stream <n> for playing");
- message("t-astream <n>tSelect audio stream <n> for playing");
- message("t-mpegttSelect mpeg audio for playing -- default is AC3");
- message("t-qttQuiet");
- message("t-fq <n>ttQueue size for frame time stamps");
- message("t-tq <n>ttQueue size for time stamps");
- message("t-ab <n>ttAudio buffer size (in KBytes)");
- message("t-vb <n>ttVideo buffer size (in KBytes)");
- message("t-vobttDVD playing mode");
- message("t-nattNo audio");
- message("t-uttuh=Headphones, us=Internal Speaker, ul=Line out");
- message("t-lttOnly decode left channel audio");
- message("t-rttOnly decode right channel audio");
- message("t-nvttNo video");
- message("t-fr nttNumber of frames per second (will result in B-frame skipping)")
- // message("t-c nttChunk size of buffer reading for video");
- // NOTE: be careful when using sychronization
- message("t-ns <n>ttNo synchronization of audio and video");
- message("");
- message("tVOB File Player Version 0.6n");
- message("tbased on");
- message("tMPEG 2 Transport Stream Player");
- msg("tVersion 1.2, November 1996");
- message("tAlex Theo de Jong (e-mail: alex.dejong@nist.gov)");
- message("tMulti-Media and Digital Video Group");
- message("tNational Institute of Standards and Technology");
- message("tGaithersburg, Md, U.S.A.");
- message("Original Audio Player code by:");
- message("tTobias Bading");
- message("tBerlin University of Technology, Germany");
- message("Original Video Player code by:");
- message("tMPEG Software Simulation Group &");
- message("tStefan Eckart");
- message("tFraunhofer-Institut fuer Festkoerpertechnologie, Germany");
- }
- int main(int argc, char** argv){
- String filename;
- Mpeg2Demux* mpeg2demux=0;
- // Create space for `arg_max' arguments for audio and video
- video_argv=new char*[arg_max];
- video_argv[video_argc++]=strdup("mpeg2player"); // parent
- video_argv[video_argc++]=strdup("buffer"); // "filename"
- String displayname("-d");
- displayname+="MPEG 2 Player, ";
- displayname+=RELEASE;
- video_argv[video_argc++]=strdup(displayname.chars()); // Display title
- audio_argv=new char*[arg_max];
- audio_argv[audio_argc++]=strdup("mpeg2player"); // parent
- audio_argv[audio_argc++]=strdup("buffer"); // "filename"
- // Check/parse arguments
- if (argc<3){
- usage(argv[0]);
- exit(0);
- }
- else {
- for (int i=1; i<argc; i++){
- if (strcmp(argv[i], "-f") == 0 && (i+1)<argc) filename=argv[++i];
- // General options
- else if (strcmp(argv[i], "-vstream")==0 && (i+1)<argc) vstream=atoi(argv[++i]);
- else if (strcmp(argv[i], "-astream")==0 && (i+1)<argc) astream=atoi(argv[++i]);
- else if (strcmp(argv[i], "-nt")==0 && (i+1)<argc) asap=(unsigned int) atoi(argv[++i]);
- #ifdef FORE_ATM
- else if (strcmp(argv[i], "-vc")==0 && (i+1)<argc) vc=atoi(argv[++i]);
- #endif
- else if (strcmp(argv[i], "-m")==0 && (i+1)<argc)
- aal_pdu_size=atoi(argv[++i])*MPEG2_TS_Packet_size;
- else if (strcmp(argv[i], "-vob")==0) { MPEG2_TS_Packet_size = 0x800; aal_pdu_size = 0x20000;video=2;}
- else if (strcmp(argv[i], "-na")==0) audio=0;
- else if (strcmp(argv[i], "-ab")==0 && (i+1)<argc) audio_buffer_size=(atoi(argv[++i])*1024);
- else if (strcmp(argv[i], "-nv")==0) video=0;
- else if (strcmp(argv[i], "-vb")==0&& (i+1)<argc) video_buffer_size=(atoi(argv[++i])*1024);
- else if (strcmp(argv[i], "-ns")==0) synchro_on=0;
- else if (strcmp(argv[i], "-fq")==0 && (i+1)<argc) frame_stamp_qsize=atoi(argv[++i]);
- else if (strcmp(argv[i], "-tq")==0 && (i+1)<argc) time_stamp_qsize=atoi(argv[++i]);
- else if (strcmp(argv[i], "-q")==0) quiet_on=1;
- else if (strcmp(argv[i], "-mpeg")==0) audio=1;
- // Video Options
- else if (strcmp(argv[i], "-fr")==0 && (i+1)<argc){
- char* arg=new char[5];
- sprintf(arg, "-f%s", argv[++i]);
- frame_rate=atoi(argv[i]);
- video_argv[video_argc++]=arg;
- }
- else if (strcmp(argv[i], "-c")==0 && (i+1)<argc){
- char* arg=new char[5];
- sprintf(arg, "-c%s", argv[++i]);
- video_argv[video_argc++]=arg;
- }
- // Audio Options
- else if (strcmp(argv[i], "-uh")==0) audio_argv[audio_argc++]=strdup(argv[i]);
- else if (strcmp(argv[i], "-ul")==0) audio_argv[audio_argc++]=strdup(argv[i]);
- else if (strcmp(argv[i], "-us")==0) audio_argv[audio_argc++]=strdup(argv[i]);
- else if (strcmp(argv[i], "-l")==0) audio_argv[audio_argc++]=strdup(argv[i]);
- else if (strcmp(argv[i], "-r")==0) audio_argv[audio_argc++]=strdup(argv[i]);
- else {
- msg("unknown argument `"); msg(argv[i]); message("' - ignored");
- }
- }
- }
- if (quiet_on){
- audio_argv[audio_argc++]=strdup("-q");
- video_argv[video_argc++]=strdup("-q");
- }
- // show options
- message("---------------------------------------------");
- msg("Verbosettttt"); if (!quiet_on){ message("On"); } else { message("Off"); }
- msg("Filettttt");
- if (filename.length()){
- message(filename.chars());
- }
- else {
- msg("asap "); message(itoa(asap));
- #ifdef FORE_ATM
- msg("VPI/VCIttttt0/"); message(itoa(vc));
- #endif
- }
- msg("SDU sizetttt"); message(itoa(aal_pdu_size));
- msg("Video Stream IDtttt"); message(itoa(vstream));
- msg("Audio Stream IDtttt"); message(itoa(astream));
- msg("Frame ratetttt"); if (frame_rate){ message(itoa(frame_rate)); } else { message("-"); }
- msg("Audiottttt");
- if (audio){
- if (audio==2) {
- message("AC3");
- } else {
- message("MPEG");
- }
- msg("Audio buffertttt"); message(itoa(audio_buffer_size));
- msg("Audio Time Stamp bufferttt"); message(itoa(frame_stamp_qsize));
- }
- else { message("Off"); }
- msg("Videottttt");
- if (video){
- message("On");
- msg("Video buffertttt"); message(itoa(video_buffer_size));
- msg("Video Time Stamp bufferttt"); message(itoa(frame_stamp_qsize));
- }
- else { message("Off"); }
- msg("Sync audio/videottt");
- if (synchro_on){
- message("On");
- msg("Time Stamp bufferttt"); message(itoa(time_stamp_qsize));
- }
- else { message("Off"); }
- message("---------------------------------------------");
- video_argv[video_argc]=0; // termintate last arg with a 0
- audio_argv[audio_argc]=0; // termintate last arg with a 0
- // Actual MPEG player
- message("Start MPEG 2 Playern");
-
- if (filename.length()){
- // create a file socket
- sock=new SocketMulti(filename.chars());
- mpeg2demux=new Mpeg2Demux(aal_pdu_size, vstream, astream, audio, video, synchro_on, quiet_on);
-
- // the demultiplexer starts the players too!
-
- #if (defined(SOLARIS) || defined(IRIX) ) // only with NATIVE Solaris Threads and Irix
- char* c=new char[50];
- do {
- msg("Type 'q' to quit: ");
- athr_yield();
- cin >> c;
- switch(c[0]){
- case '0' :
- case '1' :
- case '2' : mpeg2demux->select(atoi(&c[0])); break;
- case 'p' :
- case 'P' : mpeg2demux->pause(); break;
- case 'r' :
- case 'R' : mpeg2demux->resume(); break;
- case 'q' :
- case 'Q' : {
- mpeg2demux->resume();
- mpeg2demux->stop();
- } break;
- default : break;
- }
- }
- while (c[0]!='q' && c[0]!='Q');
- delete c;
- #endif // without pthreads
- }
- else {
- // a multi socket wait for 4 ports: tcpip, tcpipatm, atmspans, and atmpvc
- sock=new SocketMulti(asap, aal_pdu_size, vc);
-
- mpeg2demux=new Mpeg2Demux(aal_pdu_size, vstream, astream, audio, video, synchro_on, quiet_on);
- }
- // wait for demux to finish before deleting stuff!!!
- while (!mpeg2demux->done()){
- sleep(2);
- // athr_yield();
- }
- // finish up;
- delete mpeg2demux;
- int j;
- for (j=0; j<audio_argc; j++)
- delete audio_argv[j];
- for (j=0; j<video_argc; j++)
- delete video_argv[j];
- delete audio_argv;
- delete video_argv;
- if (sock){
- sock->close();
- delete sock;
- }
- message("nMPEG 2 Player Finishedn");
- exit(0);
- }