⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 programstream.c

📁 基于linux的DVD播放器程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    perror(infilename);    exit(1);  }    strcpy(cur_filename, infilename);  rv = fstat(infilefd, &statbuf);  if (rv == -1) {    perror("fstat");    exit(1);  }  disk_buf = (uint8_t *)mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, infilefd, 0);  close(infilefd);  if(disk_buf == MAP_FAILED) {    perror("mmap");    exit(1);  }  infilelen = statbuf.st_size;#ifdef HAVE_MADVISE  rv = madvise(disk_buf, infilelen, MADV_SEQUENTIAL);  if(rv == -1) {    perror("madvise");    exit(1);  }#endif  DPRINTF(1, "All mmap systems ok!\n");  new_file++;}char *stream_opts[] = {#define OPT_STREAM_NR    0  "nr",#define OPT_FILE         1  "file",#define OPT_SUBID        2  "subid",  NULL};int attach_ctrl_shm(int shmid){  char *shmaddr;    if(shmid >= 0) {    if((shmaddr = shmat(shmid, NULL, SHM_SHARE_MMU)) == (void *)-1) {      perror("demux: attach_ctrl_data(), shmat()");      return -1;    }        ctrl_data_shmid = shmid;    ctrl_data = (ctrl_data_t*)shmaddr;    ctrl_time = (ctrl_time_t *)(shmaddr+sizeof(ctrl_data_t));  }        return 0;}int main(int argc, char **argv){  int c, rv;   struct sigaction sig;  char *options;  char *opt_value;  int stream_nr;  int subid;  char *file;  uint8_t stream_id;  int lost_sync = 1;    program_name = argv[0];  GET_DLEVEL();  init_id_reg(STREAM_DISCARD);    /* Parse command line options */  while ((c = getopt(argc, argv, "v:a:s:i:d:m:o:p:h?")) != EOF) {    switch (c) {    case 'v':      stream_nr = -1;      file = NULL;      options = optarg;      while (*options != '\0') {	switch(getsubopt(&options, stream_opts, &opt_value)) {	case OPT_STREAM_NR:	  if(opt_value == NULL) {	    exit(1);	  }	  	  stream_nr = atoi(opt_value);	  break;	case OPT_FILE:	  if(opt_value == NULL) {	    exit(1);	  }	  	  file = opt_value;	  break;	default:	  fprintf(stderr, "*demux: Unknown suboption\n");	  exit(1);	  break;	}      }            if((stream_nr == -1)) {	fprintf(stderr, "*demux: Missing suboptions\n");	exit(1);      }             if((stream_nr < 0) && (stream_nr > 0xf)) {	fprintf(stderr, "*demux: Invalid stream nr\n");	exit(1);      }            stream_id = (0xe0 | stream_nr);            if(file != NULL) {	video_file = fopen(file,"w");	if(!video_file) {	  perror(optarg);	  exit(1);	}	id_add(stream_id, 0, STREAM_DECODE, -1, NULL, video_file);	      } else {	fprintf(stderr, "Video stream %d disabled\n", stream_nr);		id_add(stream_id, 0, STREAM_DISCARD, -1, NULL, NULL);      }		        break;    case 'p':      stream_nr = -1;      file = NULL;      subid = -1;      options = optarg;      while (*options != '\0') {	switch(getsubopt(&options, stream_opts, &opt_value)) {	case OPT_SUBID:	  if(opt_value == NULL) {	    exit(1);	  }	  subid = strtol(opt_value, NULL, 0);	  break;	case OPT_STREAM_NR:	  if(opt_value == NULL) {	    exit(1);	  }	  	  stream_nr = atoi(opt_value);	  break;	case OPT_FILE:	  if(opt_value == NULL) {	    exit(1);	  }	  	  file = opt_value;	  break;	default:	  fprintf(stderr, "*demux: Unknown suboption\n");	  exit(1);	  break;	}      }                  if((subid == -1)) {	fprintf(stderr, "*demux: Missing suboptions\n");	exit(1);      } else if(subid < 0 || subid > 0xff) {	fprintf(stderr, "*demux: subid out of range\n");	exit(1);      }      if((stream_nr == -1)) {	fprintf(stderr, "*demux: Missing suboptions\n");	exit(1);      }             if(!(stream_nr < subid) || (subid | stream_nr) > 0xff) {	fprintf(stderr, "*demux: subid/stream_nr combination invalid\n");	exit(1);      }      stream_id = (subid | stream_nr);            if(file != NULL) {	ps1_file = fopen(file,"w");	if(!ps1_file) {	  perror(optarg);	  exit(1);	}	id_add(MPEG2_PRIVATE_STREAM_1, stream_id, STREAM_DECODE, -1, NULL, ps1_file);	      } else {	fprintf(stderr, "Private stream 1 subid %d disabled\n", stream_nr);		id_add(MPEG2_PRIVATE_STREAM_1, stream_id, STREAM_DISCARD, -1, NULL, NULL);      }      break;    case 'a':      stream_nr = -1;      file = NULL;      options = optarg;      while (*options != '\0') {	switch(getsubopt(&options, stream_opts, &opt_value)) {	case OPT_STREAM_NR:	  if(opt_value == NULL) {	    exit(1);	  }	  	  stream_nr = atoi(opt_value);	  break;	case OPT_FILE:	  if(opt_value == NULL) {	    exit(1);	  }	  	  file = opt_value;	  break;	default:	  fprintf(stderr, "*demux: Unknown suboption\n");	  exit(1);	  break;	}      }            if((stream_nr == -1)) {	fprintf(stderr, "*demux: Missing suboptions\n");	exit(1);      }             if((stream_nr < 0) && (stream_nr > 0xf)) {	fprintf(stderr, "*demux: Invalid stream nr\n");	exit(1);      }            stream_id = (0xc0 | stream_nr);            if(file != NULL) {	audio_file = fopen(file,"w");	if(!audio_file) {	  perror(optarg);	  exit(1);	}	id_add(stream_id, 0, STREAM_DECODE, -1, NULL, audio_file);	      } else {	fprintf(stderr, "Audio stream %d disabled\n", stream_nr);		id_add(stream_id, 0, STREAM_DISCARD, -1, NULL, NULL);      }		        break;    case 's':      stream_nr = -1;      file = NULL;      options = optarg;      while (*options != '\0') {	switch(getsubopt(&options, stream_opts, &opt_value)) {	case OPT_STREAM_NR:	  if(opt_value == NULL) {	    exit(1);	  }	  	  stream_nr = atoi(opt_value);	  break;	case OPT_FILE:	  if(opt_value == NULL) {	    exit(1);	  }	  	  file = opt_value;	  break;	default:	  fprintf(stderr, "*demux: Unknown suboption: %s\n", options);	  exit(1);	  break;	}      }            if((stream_nr == -1)) {	fprintf(stderr, "*demux: Missing suboptions\n");	exit(1);      }             if((stream_nr < 0) && (stream_nr > 0x1f)) {	fprintf(stderr, "*demux: Invalid stream nr\n");	exit(1);      }            stream_id = (0x20 | stream_nr);            if(file != NULL) {	subtitle_file = fopen(file,"w");	if(!subtitle_file) {	  perror(optarg);	  exit(1);	}	id_add(MPEG2_PRIVATE_STREAM_1, stream_id, STREAM_DECODE, -1, NULL, subtitle_file);	      } else {	fprintf(stderr, "Subtitle stream %d disabled\n", stream_nr);		id_add(MPEG2_PRIVATE_STREAM_1, stream_id, STREAM_DISCARD, -1, NULL, NULL);      }      break;    case 'd':      debug = atoi(optarg);      break;    case 'm':      msgqid = atoi(optarg);      break;    case 'o':      offs = atoi(optarg);      break;    case 'h':    case '?':      usage();      return 1;    }  }  if(msgqid == -1) {    if(argc - optind != 1){      usage();      return 1;    }  }  if(msgqid != -1) {    MsgEvent_t regev;    int fileopen = 0;    init_id_reg(STREAM_DISCARD);    // get a handle    if((msgq = MsgOpen(msgqid)) == NULL) {      FATAL("%s", "Couldn't get message q\n");      exit(1);    }#if DEBUG    fprintf(stderr, "demux: msgq opened, clientnr: %ld\n", msgq->mtype);#endif        // register with the resource manager and tell what we can do    regev.type = MsgEventQRegister;    regev.registercaps.capabilities = DEMUX_MPEG1 | DEMUX_MPEG2_PS;    if(MsgSendEvent(msgq, CLIENT_RESOURCE_MANAGER, &regev, 0) == -1) {      fprintf(stderr, "demux: register\n");    }#if DEBUG    fprintf(stderr, "demux: sent register\n");#endif        /* wait for load_file command */    //get_next_demux_q();        while(!fileopen) {      if(MsgNextEvent(msgq, &regev) != -1) {	switch(regev.type) {	case MsgEventQChangeFile:#if DEBUG	  fprintf(stderr, "demux: got changefile\n");#endif	  loadinputfile(regev.changefile.filename);	  fileopen = 1;	  break;	case MsgEventQCtrlData:#if DEBUG	  fprintf(stderr, "demux: got ctrldata\n");#endif	  attach_ctrl_shm(regev.ctrldata.shmid);	  break;	case MsgEventQDemuxDVDRoot:#if DEBUG	  fprintf(stderr, "demux: got dvd root\n");#endif	  handle_events(&regev);	  fileopen = 1;	  break;	default:	  handle_events(&regev);	/*	  fprintf(stderr, "demux: msg not wanted %d, from %ld\n",	  regev.type, regev.any.client);	*/	  break;	}      }    }    //fprintf(stderr, "demux: file opened\n");    get_buffer(4*1024*1024);  } else {    loadinputfile(argv[optind]);  }  // Setup signal handler for SEGV, to detect that we ran   // out of file without a test.    sig.sa_handler = segvhandler;  sig.sa_flags = 0;  rv = sigaction(SIGSEGV, &sig, NULL);  if(rv == -1) {    perror("*demux: sighandler");    exit(1);  }  #if DEBUG  fprintf(stderr, "demux: get next demux q\n");#endif  if(msgqid != -1) {    get_next_demux_q();  }  if(off_from != -1) {    //fprintf(stderr, "demux: off_from pack\n");    offs = off_from;    bits_left = 64;    off_from = -1;      GETBITS(32, "skip1");      GETBITS(32, "skip2");  } else {    fprintf(stderr, "*demux: internal error1\n");    exit(1);  }  while(1) {    //    fprintf(stderr, "Searching for Program Stream\n");    if(nextbits(32) == MPEG2_PS_PACK_START_CODE) {      if(!synced) {	synced = 1;#if DEBUG	fprintf(stderr, "demux: Found Program Stream\n");#endif      }      MPEG2_program_stream();      lost_sync = 1;    } else if(nextbits(32) == MPEG2_VS_SEQUENCE_HEADER_CODE) {      fprintf(stderr, "demux: Found Video Sequence Header, "	      "seems to be an Elementary Stream (video)\n");      lost_sync = 1;    }    GETBITS(8, "resync");    DPRINTF(1, "resyncing");    if(lost_sync) {      lost_sync = 0;      WARNING("%s", "Lost sync, resyncing\n");    }  }}static void handle_events(MsgEvent_t *ev){    switch(ev->type) {  case MsgEventQNotify:    DPRINTF(1, "demux: got notify\n");    break;  case MsgEventQChangeFile:    DPRINTF(1, "demux: change file: %s\n", ev->changefile.filename);    add_to_demux_q(ev);    break;  case MsgEventQGntStreamBuf:    DPRINTF(1, "demux: got stream %x, %x buffer \n",	    ev->gntstreambuf.stream_id,	    ev->gntstreambuf.subtype);    attach_decoder_buffer(ev->gntstreambuf.stream_id,			  ev->gntstreambuf.subtype,			  ev->gntstreambuf.q_shmid);        break;  case MsgEventQPlayCtrl:    add_to_demux_q(ev);    break;  case MsgEventQDemuxStream:    if(ev->demuxstream.stream_id != MPEG2_PRIVATE_STREAM_1) {      id_reg[ev->demuxstream.stream_id].state = STREAM_DECODE;    } else {      id_reg_ps1[ev->demuxstream.subtype].state = STREAM_DECODE;    }    break;  case MsgEventQDemuxStreamChange:    switch_to_stream(ev->demuxstream.stream_id, ev->demuxstream.subtype);    break;  case MsgEventQDemuxStreamChange2:    switch_from_to_stream(ev->demuxstreamchange2.old_stream_id,			  ev->demuxstreamchange2.old_subtype,			  ev->demuxstreamchange2.new_stream_id,			  ev->demuxstreamchange2.new_subtype);    break;  case MsgEventQDemuxDefault:    init_id_reg(ev->demuxdefault.state);    break;  case MsgEventQDemuxDVD:    add_to_demux_q(ev);    break;  case MsgEventQDemuxDVDRoot:    add_to_demux_q(ev);    break;  default:#if DEBUG    fprintf(stderr, "demux: unrecognized command: %d\n", ev->type);#endif    break;  }}int register_id(uint8_t id, int subtype){  MsgEvent_t ev;    data_buf_head_t *data_buf_head;  int qsize;    if(msgqid != -1) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -