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

📄 ctrl.c

📁 基于linux的DVD播放器程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	  if(child_killed) {	    cleanup();	  }	  if(MsgNextEventInterruptible(q, &r_ev) == -1) {	    switch(errno) {	    case EINTR:	      continue;	      break;	    }	  }	  handle_events(q, &r_ev);	}		// we now have a decoder running ready to decode the stream		// send ctrl_data shm: let client know where the timebase	// data is#if DEBUG	DNOTE("sending ctrldata\n");#endif	s_ev.type = MsgEventQCtrlData;	s_ev.ctrldata.shmid = ctrl_data_shmid;		MsgSendEvent(q, rcpt, &s_ev, 0);		// at this point we know both reader and writer client	// for the buffer.		// lets create the buffer		shmid = create_q(ev->reqstreambuf.nr_of_elems,			 ev->reqstreambuf.data_buf_shmid,			 ev->reqstreambuf.client,			 rcpt);			// let the writer know which streambuffer to connect to	s_ev.type = MsgEventQGntStreamBuf;	s_ev.gntstreambuf.q_shmid = shmid;	s_ev.gntstreambuf.stream_id =	  ev->reqstreambuf.stream_id; 	s_ev.gntstreambuf.subtype =	  ev->reqstreambuf.subtype; 		MsgSendEvent(q, ev->reqstreambuf.client, &s_ev, 0);		// connect the streambuf  to the reader		s_ev.type = MsgEventQDecodeStreamBuf;	s_ev.decodestreambuf.q_shmid = shmid;	s_ev.decodestreambuf.stream_id =	  ev->reqstreambuf.stream_id;	s_ev.decodestreambuf.subtype = 	  ev->reqstreambuf.subtype;		MsgSendEvent(q, rcpt, &s_ev, 0);	      } else {	// we don't want this stream	// respond with the shmid set to -1		s_ev.type = MsgEventQGntStreamBuf;	s_ev.gntstreambuf.q_shmid = -1;	s_ev.gntstreambuf.stream_id =	  ev->reqstreambuf.stream_id; 	s_ev.gntstreambuf.subtype =	  ev->reqstreambuf.subtype; 		MsgSendEvent(q, ev->reqstreambuf.client, &s_ev, 0);      }    }    break;  case MsgEventQReqPicBuf:    {      int shmid;      cap_state_t state;#if DEBUG      DNOTE("_new pic q\n");#endif      // check if we have a decoder            //TODO check which decoder handles the stream and start it      //if there isn't already one running that is free to use      // TODO clean up logic/functions            //TODO hmm start here or have decoder request cap first or      //      if(!search_capabilities(VIDEO_OUTPUT, &rcpt, NULL, NULL)) {		DNOTE("%s", "registered VO|SPU started\n");	register_capabilities(0,			      VIDEO_OUTPUT | DECODE_DVD_SPU,			      CAP_started);		init_decoder(msgqid_str, getenv("DVDP_VIDEO_OUT"));	//DNOTE("started video_out\n");      }      while(!search_capabilities(VIDEO_OUTPUT, &rcpt, NULL, &state) ||	    (state != CAP_running)) {	if(child_killed) {	  cleanup();	}	if(MsgNextEventInterruptible(q, &r_ev) == -1) {	  switch(errno) {	  case EINTR:	    continue;	    break;	  }	}	handle_events(q, &r_ev);      }      DNOTE("%s", "got capability video_out\n");            // we now have a decoder running ready to decode the stream            // send ctrl_data shm: let client know where the timebase      // data is#if DEBUG      DNOTE("sending ctrldata\n");#endif      s_ev.type = MsgEventQCtrlData;      s_ev.ctrldata.shmid = ctrl_data_shmid;	      MsgSendEvent(q, rcpt, &s_ev, 0);	      // at this point we know both reader and writer client      // for the buffer.            // lets create the buffer	      shmid = create_q(ev->reqpicbuf.nr_of_elems,		       ev->reqpicbuf.data_buf_shmid,		       ev->reqpicbuf.client,		       rcpt);                  // let the writer know which picbuffer to connect to      s_ev.type = MsgEventQGntPicBuf;      s_ev.gntpicbuf.q_shmid = shmid;      #if DEBUG      DNOTE("create_q, q_shmid: %d picture_buf_shmid: %d\n",	    shmid,  ev->reqpicbuf.data_buf_shmid);#endif            MsgSendEvent(q, ev->reqpicbuf.client, &s_ev, 0);            // connect the picbuf  to the reader            s_ev.type = MsgEventQAttachQ;      s_ev.attachq.q_shmid = shmid;            MsgSendEvent(q, rcpt, &s_ev, 0);	    }    break;  case MsgEventQSpeed:    {      clocktime_t rt;            clocktime_get(&rt);#if DEBUG      DNOTE("_MsgEventQSpeed\n");      DNOTE("speed: %.2f\n", ev->speed.speed);#endif      ctrl_data->speed = ev->speed.speed;                  // send speed event to syncmasters      {	// TODO get decoders that do sync...	//	if(search_capabilities(DECODE_AC3_AUDIO, &rcpt, NULL, NULL)) {	  	  MsgSendEvent(q, rcpt, ev, 0);	  	}	if(search_capabilities(VIDEO_OUTPUT, &rcpt, NULL, NULL)) {	  	  MsgSendEvent(q, rcpt, ev, 0);	  	}      }    }    break;  default:    WARNING("handle_events: notice, msgtype %d not handled\n",	    ev->type);    break;  }}int main(int argc, char *argv[]){  struct sigaction sig;  int c;  MsgEventQ_t q;  MsgEvent_t ev;    for(c = strlen(argv[0])-1; c > 0; c--) {    if(argv[0][c] == '/') {      c++;      break;    }  }  program_name = &argv[0][c];  GET_DLEVEL();  memset(&sig, 0, sizeof(struct sigaction));  sig.sa_handler = int_handler;  sig.sa_flags = 0;  if(sigaction(SIGINT, &sig, NULL) == -1) {    perror("ctrl: failed to set sigaction SIGINT handler");  }#if defined(SA_SIGINFO)  sig.sa_sigaction = sigchld_handler;  sig.sa_flags = SA_SIGINFO;#else  sig.sa_handler = (sig_t)sigchld_handler;#endif  if(sigaction(SIGCHLD, &sig, NULL) == -1) {    perror("ctrl: failed to set sigaction SIGCHL handler");  }      //"na:v:s:m:f:r:o:p:d:u:t:h?"  while((c = getopt(argc, argv,"u:h?" )) != EOF) {    switch(c) {#if 0    case 'a':      ac3_audio_stream = atoi(optarg);      break;    case 't':      dts_audio_stream = atoi(optarg);      break;    case 'm':      mpeg_audio_stream = atoi(optarg);      break;    case 'p':      lpcm_audio_stream = atoi(optarg);      break;    case 'v':      mpeg_video_stream = atoi(optarg);      break;    case 's':      subpicture_stream = atoi(optarg);      break;    case 'n':      nav_stream = 1;      break;    case 'f':      framerate = optarg;      break;    case 'r':      output_bufs = optarg;      break;    case 'o':      file_offset = optarg;      break;    case 'd':      videodecode_debug = optarg;      break;          case 'D':      demux_debug = optarg;      break;      #endif    case 'u':      ui = optarg;      break;    case 'h':    case '?':      usage();      return 1;      break;    }  }    if(argc - optind > 1){    usage();    return 1;  }    if(argc - optind == 1){    input_file = argv[optind];  } else {    input_file = NULL;  }    /* Print the version info so that we get it with bug reports. */  NOTE("%s %s\n", PACKAGE, VERSION);    ctrl_data_shmid = create_ctrl_data();    /* create msgq */    create_msgq();  sprintf(msgqid_str, "%d", msgqid);  #if DEBUG  DNOTE("msgid: %d\n", msgqid);    {    struct msqid_ds msgqinfo;        msgctl(msgqid, IPC_STAT, &msgqinfo);        DNOTE("max_bytes: %ld\n", (long)msgqinfo.msg_qbytes);  }#endif  q.msqid = msgqid;  q.mtype = CLIENT_RESOURCE_MANAGER;  if(ui != NULL) {    MsgEventClient_t ui_client;    if(!strcmp("cli", ui)) {      request_capability(&q, UI_DVD_CLI, &ui_client, NULL);    } else if(!strcmp("gui", ui)) {      request_capability(&q, UI_DVD_GUI, &ui_client, NULL);    } else {      FATAL("%s", "no ui specified\n");      cleanup_and_exit();    }  }    /* If any streams are specified on the commadline, dexmux only those */  /*  if((ac3_audio_stream & mpeg_audio_stream & lpcm_audio_stream &      dts_audio_stream & mpeg_video_stream & subpicture_stream &      nav_stream) == -1) {    ev.demuxdefault.state = 1;  } else {    ev.demuxdefault.state = 0;  }    MsgSendEvent(&q, rcpt, &ev, 0);  */  while(1){    if(child_killed) {      cleanup();    }    if(MsgNextEventInterruptible(&q, &ev) == -1) {      switch(errno) {      case EINTR:	continue;	break;      }    }    handle_events(&q, &ev);  }      return 0;}int init_decoder(char *msgqid_str, char *decoderstr){  pid_t pid;  char *eargv[16];  char *decode_name;  char *decode_path = decoderstr;  int n;    if(decode_path == NULL) {    ERROR("%s", "init_decoder(): decoder not set\n");    return -1;  }    if((decode_name = strrchr(decode_path, '/')+1) == NULL) {    decode_name = decode_path;  }  if(decode_name > &decode_path[strlen(decode_path)]) {    ERROR("%s", "init_decoder(): illegal file name?\n");    return -1;  }    //DNOTE("init_decoder(): %s\n", decode_name);  //starting_decoder = 1;  /* fork/exec decoder */    switch(pid = fork()) {  case 0:    /* child process */    n = 0;    eargv[n++] = decode_name;    eargv[n++] = "-m";    eargv[n++] = msgqid_str;    /* TODO fix for different decoders     if(output_bufs != NULL) {      eargv[n++] = "-r";      eargv[n++] = output_bufs;    }    if(framerate != NULL) {      eargv[n++] = "-f";      eargv[n++] = framerate;    }    if(videodecode_debug != NULL) {      eargv[n++] = "-d";      eargv[n++] = videodecode_debug;    }    */    // FIXME Very high Hack value    if(!strcmp(decoderstr, getenv("DVDP_CLI_UI")) ||       !strcmp(decoderstr, getenv("DVDP_UI"))) {      eargv[n++] = input_file;    }             eargv[n++] = NULL;        if(execv(decode_path, eargv) == -1) {      FATAL("init_decoder(): path: %s\n", decode_path);      perror("execv");    }    exit(1);    break;  case -1:    /* fork failed */    perror("fork");    break;  default:    /* parent process */    break;  }  if(pid != -1) {    add_to_pidlist(pid, decoderstr);  }    DNOTE("Started %s with pid %ld\n", decoderstr, (long)pid);  //  starting_decoder = 0;  return pid;}typedef struct {  pid_t pid;  char *name;} pidname_t;pidname_t *pidlist = NULL;int num_pids = 0;void add_to_pidlist(pid_t pid, char *name){  int n;  for(n = 0; n < num_pids; n++) {    if(pidlist[n].pid == -1) {      pidlist[n].pid = pid;      pidlist[n].name = strdup(name);      return;    }  }  num_pids++;  pidlist = realloc(pidlist, num_pids*sizeof(pidname_t));  pidlist[num_pids-1].pid = pid;  pidlist[num_pids-1].name = strdup(name);}int remove_from_pidlist(pid_t pid){  int n;  for(n = 0; n < num_pids; n++) {    if(pidlist[n].pid == pid) {      pidlist[n].pid = -1;      free(pidlist[n].name);      pidlist[n].name = NULL;      return 1;    }  }    return 0;}char *get_pid_name(pid_t pid){  int n;  if(pid != -1) {    for(n = 0; n < num_pids; n++) {      if(pid == pidlist[n].pid) {	return pidlist[n].name;      }    }  }  return NULL;}  /** * @todo fix how to decide which streams to decode * * -u <gui name>     starts with gui name * filename  which file to play * -v #n     decode video stream #n * -a #n     decode ac3 audio stream #n * -m #n     decode mpeg audio stream #n * -d #n     decode dts audio stream #n * -p #n     decode pcm audio stream #n * -n        decode mpeg private stream 2 (dvd nav data) * -s #n     decode dvd subpicture stream #n * -dvd      start with dvdgui and vm *  */int register_stream(uint8_t stream_id, uint8_t subtype){  int state;

⌨️ 快捷键说明

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