📄 ctrl.c
字号:
/* If any stream is 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) state = 0; else state = 1; if(stream_id == MPEG2_PRIVATE_STREAM_1) { if(state) { if((subtype == (0x80 | (ac3_audio_stream & 0x7))) && (ac3_audio_stream >= 0) && (ac3_audio_stream < 8)) { return 1; } } else { /* dvd, it's an ac3 stream ok */ if((subtype >= 0x80) && (subtype < 0x88)) { return 1; } } if(state) { if((subtype == (0x88 | (dts_audio_stream & 0x7))) && (dts_audio_stream >= 0) && (dts_audio_stream < 8)) { return 1; } } else { /* dvd, it's an dts stream ok */ if((subtype >= 0x88) && (subtype < 0x90)) { return 1; } } if(state) { if((subtype == (0xA0 | (lpcm_audio_stream & 0x7))) && (lpcm_audio_stream >= 0) && (lpcm_audio_stream < 8)) { return 1; } } else { /* dvd, it's an lpcm stream ok */ if((subtype >= 0xA0) && (subtype < 0xA8)) { return 1; } } if(state) { if((subtype == (0x20 | (subpicture_stream & 0x1f))) && (subpicture_stream >= 0)) { return 1; } } else { /* dvd, it's a spu stream ok */ if(((subtype & 0xf0) == 0x20) || ((subtype & 0xf0) == 0x90)) { return 1; } } } if(state) { if((stream_id == (0xc0 | (mpeg_audio_stream & 0x1f))) && (mpeg_audio_stream >= 0)) { return 1; } } else { /* dvd, mpeg audio stream ok */ if(((stream_id & 0xf0) == 0xc0) || ((stream_id & 0xf0) == 0xd0)) { return 1; } } if(state) { if((stream_id == (0xe0 | (mpeg_video_stream & 0x0f))) && (mpeg_video_stream >= 0)) { return 1; } } else { /* dvd, video stream ok */ if((stream_id & 0xf0) == 0xe0) { return 1; } } if(state) { if((stream_id == MPEG2_PRIVATE_STREAM_2) && (nav_stream >= 0)) { // nav return 1; } } else { /* dvd, nav stream ok */ if(stream_id == MPEG2_PRIVATE_STREAM_2) { // nav packs return 1; } } return 0; }int create_msgq(void){ if((msgqid = msgget(IPC_PRIVATE, IPC_CREAT | 0600)) == -1) { perror("*ctrl: msgget ipc_creat failed"); exit(1); } return 0;} void destroy_msgq(void){ if(msgctl(msgqid, IPC_RMID, NULL) != 0) { perror("*ctrl: msgctl ipc_rmid failed"); } msgqid = -1;}int get_buffer(int size, shm_bufinfo_t *bufinfo){ int shmid; /* This also creates the image buffers that will be sent to attached * from the X server if we use Xv. So we need to make sure that it * has permissions to attach / read it. */ if((shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0644)) == -1) { perror("*ctrl: get_buffer, shmget failed"); return -1; } add_q_shmid(shmid); bufinfo->shmid = shmid; bufinfo->size = size; return 0;} int create_q(int nr_of_elems, int buf_shmid, MsgEventClient_t writer, MsgEventClient_t reader){ int shmid; char *shmaddr; q_head_t *q_head; q_elem_t *q_elems; int n; if((shmid = shmget(IPC_PRIVATE, sizeof(q_head_t) + nr_of_elems*sizeof(q_elem_t), IPC_CREAT | 0600)) == -1) { perror("*ctrl: create_q, shmget failed"); return -1; } if((shmaddr = shmat(shmid, NULL, SHM_SHARE_MMU)) == (void *)-1) { perror("*ctrl: create_q, shmat failed"); if(shmctl(shmid, IPC_RMID, NULL) != 0) { perror("*ctrl: create_q, shmctl ipc_rmid faild"); } return -1; } add_q_shmid(shmid); q_head = (q_head_t *)shmaddr; q_head->data_buf_shmid = buf_shmid; q_head->nr_of_qelems = nr_of_elems; q_head->write_nr = 0; q_head->read_nr = 0; q_head->writer = writer; q_head->reader = reader; q_head->writer_requests_notification = 0; q_head->reader_requests_notification = 0; q_head->qid = shmid; /* to get a unique id for the q */ q_elems = (q_elem_t *)(shmaddr+sizeof(q_head_t)); for(n = 0; n < nr_of_elems; n++) { q_elems[n].in_use = 0; } if(shmdt(shmaddr) != 0) { perror("*ctrl: create_q, shmdt failed"); } return shmid;}int create_ctrl_data(void){ int shmid; char *shmaddr; ctrl_time_t *ctrl_time; int n; int nr_of_offsets = 32; if((shmid = shmget(IPC_PRIVATE, sizeof(ctrl_data_t)+ nr_of_offsets*sizeof(ctrl_time_t), IPC_CREAT | 0600)) == -1) { perror("*ctrl: create_ctrl_data, shmget failed"); return -1; } if((shmaddr = shmat(shmid, NULL, SHM_SHARE_MMU)) == (void *)-1) { perror("*ctrl: create_ctrl_data, shmat failed"); if(shmctl(shmid, IPC_RMID, NULL) == -1) { perror("*ctrl: create_ctrl_data, shmctl ipc_rmid"); } return -1; } add_q_shmid(shmid); ctrl_data = (ctrl_data_t *)shmaddr; ctrl_data->mode = MODE_STOP; ctrl_data->sync_master = SYNC_NONE; ctrl_data->speed = 1.0; ctrl_time = (ctrl_time_t *)(shmaddr+sizeof(ctrl_data_t)); for(n = 0; n < nr_of_offsets; n++) { ctrl_time[n].offset_valid = OFFSET_NOT_VALID; } return shmid;}int *shm_ids = NULL;int nr_shmids = 0;void add_q_shmid(int shmid){ nr_shmids++; if((shm_ids = (int *)realloc(shm_ids, sizeof(int)*nr_shmids)) == NULL) { perror("*ctrl: add_q_shmid, realloc failed"); nr_shmids--; return; } shm_ids[nr_shmids-1] = shmid; }void remove_q_shmid(int shmid){ int n; for(n = 0; n < nr_shmids; n++) { if(shm_ids[n] == shmid) { DNOTE("removing shmid: %d\n", shm_ids[n]); if(shmctl(shm_ids[n], IPC_RMID, NULL) == -1) { perror("ipc_rmid"); } shm_ids[n] = -1; } }}void remove_q_shm(void){ int n; for(n = 0; n < nr_shmids; n++) { if(shm_ids[n] != -1) { DNOTE("removing shmid: %d\n", shm_ids[n]); if(shmctl(shm_ids[n], IPC_RMID, NULL) == -1) { perror("ctrl: ipc_rmid"); } } } nr_shmids = 0; free(shm_ids); shm_ids = NULL; }void cleanup_and_exit(void){ remove_q_shm(); destroy_msgq(); NOTE("%s", "exiting\n"); exit(0);}void int_handler(int sig){ /* send quit msg to demuxer and decoders * (and wait for ack? (timeout)) * * remove all shared memory segments * * remove all msqqueues * * exit */ int n; pid_t pid; DNOTE("Caught signal %d, cleaning up\n", sig); for(n = 0; n < num_pids; n++) { if((pid = pidlist[n].pid) != -1) { child_killed = 1; DNOTE("killing child: %ld %s\n", (long)pid, pidlist[n].name); kill(pid, SIGINT); } if(!child_killed) { DNOTE("%s", "All children dead\n"); child_killed = 1; } }}/* FreeBSD compatibility where are these defined on freebsd if at all? */#ifndef CLD_EXITED/* from /usr/include/sys/siginfo.h on solaris */#define CLD_EXITED 1 /* child has exited */#define CLD_KILLED 2 /* child was killed */#define CLD_DUMPED 3 /* child has coredumped */#define CLD_TRAPPED 4 /* traced child has stopped */#define CLD_STOPPED 5 /* child has stopped on signal */#define CLD_CONTINUED 6 /* stopped child has continued */#endif#ifndef WCONTINUED #define WCONTINUED 0#define WIFCONTINUED(x) 0#endifvoid sigchld_handler(int sig, siginfo_t *info, void* context){ /* * */ int stat_loc; int died = 0; pid_t wpid, pid; char *name; #if defined(SA_SIGINFO) if(info->si_signo != SIGCHLD) { ERROR("sigchldhandler got signal %d\n", info->si_signo); return; } if(info->si_errno) { DNOTE("error: %s\n", strerror(info->si_errno)); } //DNOTE("si_code: %d\n", info->si_code); //DNOTE("si_pid: %ld\n", (long)info->si_pid); if((name = get_pid_name(info->si_pid)) == NULL) { name = "?"; } switch(info->si_code) { case CLD_STOPPED: DNOTE("child: %ld stopped (%s)\n", (long)info->si_pid, name); break; case CLD_CONTINUED: DNOTE("child: %ld continued (%s)\n", (long)info->si_pid, name); break; case CLD_KILLED: DNOTE("child: %ld killed (%s)\n", (long)info->si_pid, name); died = 1; break; case CLD_DUMPED: DNOTE("child: %ld dumped (%s)\n", (long)info->si_pid, name); died = 1; break; case CLD_TRAPPED: DNOTE("child: %ld trapped (%s)\n", (long)info->si_pid, name); died = 1; break; case CLD_EXITED: DNOTE("child: %ld exited with %d (%s)\n", (long)info->si_pid, info->si_status, name); died = 1; break;#if defined(SI_NOINFO) // Solaris only case SI_NOINFO: DNOTE("pid %ld, sigchld: no info (%s)\n", (long)info->si_pid, name); break;#endif default: DNOTE("pid %ld, unknown sigchld si_code: %d (%s)\n", (long)info->si_pid, info->si_code, name); break; } wpid = info->si_pid;#else /* defined(SA_SIGINFO) */ wpid = -1;#endif while(1) { if((pid = waitpid(wpid, &stat_loc, WCONTINUED | WUNTRACED)) == -1) { perror("ctrl: waitpid failed"); switch(errno) { case EINTR: continue; default: return; } } break; } if((name = get_pid_name(pid)) == NULL) { name = "?"; } if(WIFEXITED(stat_loc)) { died = 1; DNOTE("pid: %ld exited with status: %d (%s)\n", (long)pid, WEXITSTATUS(stat_loc), name); } else if(WIFSIGNALED(stat_loc)) { died = 1; DNOTE("pid: %ld terminated on signal: %d (%s)\n", (long)pid, WTERMSIG(stat_loc), name); } else if(WIFSTOPPED(stat_loc)) { DNOTE("pid: %ld stopped on signal: %d (%s)\n", (long)pid, WSTOPSIG(stat_loc), name); } else if(WIFCONTINUED(stat_loc)) { DNOTE("pid: %ld continued (%s)\n", (long)pid, name); } else { DNOTE("pid: %ld (%s)\n", (long)pid, name); } if(died) { int n; if(!remove_from_pidlist(pid)) { DNOTE("%s", "pid died before registering\n"); } for(n = 0; n < num_pids; n++) { if((pid = pidlist[n].pid) != -1) { child_killed = 1; //DNOTE("killing child: %ld %s\n", (long)pid, pidlist[n].name); kill(pid, SIGINT); } } if(!child_killed) { DNOTE("%s", "all children dead\n"); child_killed = 2; } }}void slay_children(void){ int n; pid_t pid; for(n = 0; n < num_pids; n++) { if((pid = pidlist[n].pid) != -1) { child_killed = 2; DNOTE("slaying child: %ld %s\n", (long)pid, pidlist[n].name); kill(pid, SIGKILL); } } if(!child_killed) { DNOTE("%s", "No children left in pidlist\n"); child_killed = 2; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -