📄 ctrl.c
字号:
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 + -