📄 input.c
字号:
*/static void input_closefile (file_descr *f){ int i; if (f->handle >= 0) { close (f->handle); } list_release (f->data); free (f->name); switch (f->content) { case ct_transport: releasechain (pmt_descr,f->u.ts.pat); releasechain (pmt_descr,f->u.ts.newpat); releasechain (tsauto_descr,f->u.ts.tsauto); releasechain (tssi_descr,f->u.ts.tssi); break; default: break; } i = in_files; while (--i >= 0) { if (inf[i] == f) { inf[i] = inf[--in_files]; in_openfiles[f->content] -= 1; warn (LDEB,"Close file",EINP,11,1,in_files); free (f); return; } } warn (LERR,"Close lost file",EINP,11,2,in_files); free (f);}/* Close a file if there are no more data streams open. * If so, close any map streams. * Precondition: f!=NULL */void input_closefileifunused (file_descr *f){ int i; stream_descr *s; if (f->openstreams[sd_data] <= 0) { if (f->openstreams[sd_unparsedsi] > 0) { switch (f->content) { case ct_transport: i = MAX_STRPERTS; while ((f->openstreams[sd_unparsedsi] > 0) && (--i >= 0)) { s = ts_file_stream (f,i); if ((s != NULL) && (s->streamdata == sd_unparsedsi) && (s->endaction == ENDSTR_CLOSE) && (list_empty (s->ctrl))) { input_closestream (ts_file_stream (f,i)); } } break; default: break; } } if (f->openstreams[sd_unparsedsi] <= 0) { if (f->openstreams[sd_map] > 0) { switch (f->content) { case ct_program: i = MAX_STRPERPS; while (--i >= 0) { if (f->u.ps.stream[i] != NULL) { input_closestream (f->u.ps.stream[i]); } } break; case ct_transport: i = MAX_STRPERTS; while (--i >= 0) { s = ts_file_stream (f,i); if ((s != NULL) && (s->streamdata == sd_map)) { input_closestream (ts_file_stream (f,i)); } } break; default: warn (LERR,"unexpected map",EINP,12,1,f->content); break; } } input_closefile (f); } }}/* Add a target program to a stream's list of programs that contain it. * Precondition: s!=NULL, p!=NULL, p not in s->u.d.pdescr[*] * Postcondition: p in s->u.d.pdescr[*] not more than once. * Return: TRUE if successful, FALSE otherwise. */boolean input_addprog (stream_descr *s, prog_descr *p){ if (s->u.d.progs < MAX_PRGFORSTR) { s->u.d.pdescr[s->u.d.progs++] = p; warn (LDEB,"Add prog",EINP,10,2,s->u.d.progs); return (TRUE); } warn (LERR,"Max add prog",EINP,10,1,s->u.d.progs); return (FALSE);}/* Delete a target program from a stream's list of programs that contain it. * Precondition: s!=NULL, p!=NULL, p in s->u.d.pdescr[*] not more than once. * Postcondition: p not in s->u.d.pdescr[*] * Return: TRUE if successful, FALSE otherwise. */boolean input_delprog (stream_descr *s, prog_descr *p){ int i; i = s->u.d.progs; while (--i >= 0) { if (s->u.d.pdescr[i] == p) { s->u.d.pdescr[i] = s->u.d.pdescr[--(s->u.d.progs)]; warn (LDEB,"Del prog",EINP,9,2,i); return (TRUE); } } warn (LERR,"Del lost prog",EINP,9,1,s->u.d.progs); return (FALSE);}/* Open a stream in a file. Allocate and initialize it. * sourceid is the stream's ID in the source file. * streamid is the PES packet stream id. * streamtype is the stream type according to ISO 13818-1 table 2-29. * isamap is TRUE for a map stream, FALSE for data stream. * mapstream is the superior correlated map stream. * Precondition: f!=NULL * Return: stream if successful, NULL otherwise */stream_descr *input_openstream (file_descr *f, int sourceid, int streamid, int streamtype, streamdata_type streamdata, stream_descr *mapstream){ stream_descr *s; warn (LIMP,"Open stream",EINP,5,sourceid,streamid); if (in_streams < MAX_INSTREAM) { switch (streamdata) { case sd_data: s = unionalloc (stream_descr,d); break; case sd_map: s = unionalloc (stream_descr,m); break; case sd_unparsedsi: s = unionalloc (stream_descr,usi); break; default: s = NULL; break; } if ((s != NULL) && ((s->autodescr = malloc (sizeof (descr_descr))) != NULL) && ((s->manudescr = malloc (sizeof (descr_descr))) != NULL)) { if (list_create (s->ctrl,MAX_CTRL_INB)) { if ((streamdata == sd_map) ? list_create (s->data,MAX_DATA_INBPSI) : streamtype_isvideo (streamtype) ? list_create (s->data,MAX_DATA_INBV) : streamtype_isaudio (streamtype) ? list_create (s->data,MAX_DATA_INBA) : list_create (s->data,MAX_DATA_INB)) { s->streamdata = streamdata; switch (streamdata) { case sd_data: s->u.d.mapstream = mapstream; s->u.d.discontinuity = FALSE; s->u.d.trigger = FALSE; s->u.d.mention = FALSE; s->u.d.has_clockref = FALSE; s->u.d.has_opcr = FALSE; s->u.d.conv.base = 0; s->u.d.conv.msec = 0; s->u.d.progs = 0; f->openstreams[streamdata] += 1; in_openstreams[streamdata] += 1; break; case sd_map: s->u.m.msectime = 0; s->u.m.conv.base = 0; s->u.m.conv.msec = 0; s->u.m.psi_length = 0; f->openstreams[streamdata] += 1; in_openstreams[streamdata] += 1; break; case sd_unparsedsi: f->openstreams[streamdata] += 1; in_openstreams[streamdata] += 1; break; default: break; } s->ctrl.ptr[0].length = 0; s->ctrl.ptr[0].pcr.valid = FALSE; s->ctrl.ptr[0].opcr.valid = FALSE; s->fdescr = f; s->sourceid = sourceid; s->stream_id = streamid; s->stream_type = streamtype; s->version = 0xFF; s->conticnt = 0; s->endaction = ENDSTR_WAIT; clear_descrdescr (s->autodescr); clear_descrdescr (s->manudescr); ins[in_streams++] = s; return (s); } list_release (s->ctrl); } free (s); } else { warn (LERR,"Alloc fail",EINP,5,1,in_streams); } } else { warn (LERR,"Max stream open",EINP,5,2,in_streams); } return (NULL);}/* End a stream, if opportune. * Check all target programs this stream is in, close those that * do not contain another stream from the same file that is still running. * Note, that the stream stays open if there is at least one other stream * from the same file, that is still running together with it in a program. * Precondition: s!=NULL */void input_endstream (stream_descr *s){ int q, i; prog_descr *p; stream_descr *t; q = s->u.d.progs; while (--q >= 0) { p = s->u.d.pdescr[q]; i = p->streams; while (--i >= 0) { t = p->stream[i]; if ((!list_empty (t->ctrl)) && (t->u.d.trigger) && (t->fdescr == s->fdescr)) { break; } } if (i < 0) { splice_closeprog (p); } }}/* End a stream. * Unlink it from all target programs, no matter what is left therein. * Precondition: s!=NULL */void input_endstreamkill (stream_descr *s){ int i; i = s->u.d.progs; while (--i >= 0) { prog_descr *p; p = s->u.d.pdescr[i]; if (p->streams > 1) { unlink_streamprog (s,p); } else { splice_closeprog (p); } }}/* Close a stream. * Release all structures. If this is the only data stream related to the * corresponding map stream, close the map stream, too. * Precondition: s!=NULL */void input_closestream (stream_descr *s){ int i; warn (LIMP,"Close stream",EINP,6,0,s->sourceid); switch (s->fdescr->content) { case ct_packetized: s->fdescr->u.pes.stream = NULL; break; case ct_program: s->fdescr->u.ps.stream[s->sourceid] = NULL; break; case ct_transport: ts_file_stream (s->fdescr,s->sourceid) = NULL; break; default: warn (LERR,"Unknown contents",EINP,6,2,s->fdescr->content); break; } s->fdescr->openstreams[s->streamdata] -= 1; if (s->streamdata == sd_data) { switch (s->fdescr->content) { case ct_transport: if (s->u.d.mapstream != ts_file_stream (s->fdescr,0)) { i = MAX_STRPERTS; while ((--i >= 0) && ((ts_file_stream (s->fdescr,i) == NULL) || (ts_file_stream (s->fdescr,i)->streamdata != sd_data) || (ts_file_stream (s->fdescr,i)->u.d.mapstream != s->u.d.mapstream))) { } if (i < 0) { if (s->u.d.mapstream->endaction == ENDSTR_CLOSE) { input_closestream (s->u.d.mapstream); } } } break; default: break; } } i = in_streams; while (--i >= 0) { if (ins[i] == s) { ins[i] = ins[--in_streams]; in_openstreams[s->streamdata] -= 1; break; } } if (i < 0) { warn (LERR,"Close lost stream",EINP,6,1,in_streams); } list_release (s->data); list_release (s->ctrl); free (s->manudescr); free (s->autodescr); free (s);}/* Split data from raw input buffers to PES data stream buffers. * Return: TRUE, if something was processed, FALSE if no data/space available */boolean split_something (void){ int i; boolean r = FALSE; warn (LDEB,"Split some",EINP,7,0,in_files); i = in_files; while (--i >= 0) { switch (inf[i]->content) { case ct_packetized: if (split_pes (inf[i])) { r = TRUE; } break; case ct_program: if (split_ps (inf[i])) { r = TRUE; } break; case ct_transport: if (split_ts (inf[i])) { r = TRUE; } break; default: warn (LERR,"Unknown contents",EINP,7,3,inf[i]->content); /* error ? */ break; } } return (r);}/* Check all files of type ct_transport for --si ranges. * Return: higher bound of range, if match is found, -1 otherwise */int input_tssiinafilerange (int pid){ int i; i = in_files; while (--i >= 0) { warn (LDEB,"TSSI in file",EINP,14,-1,inf[i]->content); if (inf[i]->content == ct_transport) { int h; h = split_unparsedsi (inf[i],pid); if (h >= 0) { warn (LDEB,"TSSI in file",EINP,14,pid,h); return (h); } } } warn (LDEB,"TSSI in file",EINP,14,pid,-1); return (-1);}/* Determine the appropriate file for a given handle * Return: file, if found, NULL otherwise */file_descr *input_filehandle (int handle){ int i; i = in_files; while (--i >= 0) { if (inf[i]->handle == handle) { return (inf[i]); } } return (NULL);}/* Check whether there is a pair of filerefnum and filename among the open * files, that fits the criteria. * Precondition: filename!=NULL or filerefnum>=0 * Return: file, if found, NULL otherwise */file_descr *input_filereferenced (int filerefnum, char *filename){ int i; file_descr *f; i = in_files; while (--i >= 0) { f = inf[i]; if ((filename == NULL) ? (filerefnum == f->filerefnum) : ((!strcmp (filename, f->name)) && ((filerefnum < 0) || (filerefnum == f->filerefnum)))) { return (f); } } return (NULL);}/* Mark a file to be stopped. * If stopped, the file will be handled as if eof was encountered, the * next time there is data to be read from it. * Precondition: f!=NULL */void input_stopfile (file_descr *f){ f->stopfile = TRUE;}/* Read some data from the file into the raw buffer. * On eof or f->stopfile, end the file, or handle repeatitions or append, * if applicable. * Precondition: poll has stated data or error for the file */void input_something (file_descr *f, boolean readable){ int l, m; if (f != NULL) { if (f->handle >= 0) { warn (LDEB,"Something",EINP,0,1,f); if (readable && !f->stopfile) { l = list_freeinend (f->data); if (l > MAX_READ_IN) { l = MAX_READ_IN; } m = list_free (f->data); if (l > m) { l = m; } l = read (f->handle,&f->data.ptr[f->data.in],l); } else { l = 0; } warn (LDEB,"Some Read",EINP,0,2,l); if (l > 0) { list_incr (f->data.in,f->data,l); } else if (l == 0) { f->stopfile = FALSE; if (f->repeatitions != 0) { if (f->repeatitions > 0) { f->repeatitions -= 1; } if (lseek (f->handle,0,SEEK_CUR) > 255) { lseek (f->handle,0,SEEK_SET); warn (LIMP,"End Repeat",EINP,0,4,f); } else { warn (LWAR,"Repeat fail",EINP,0,5,f); } } else if (f->append_name != NULL) { free (f->name); f->name = f->append_name; f->append_name = NULL; if (f->append_filerefnum >= 0) { f->filerefnum = f->append_filerefnum; } close (f->handle); if ((f->handle = open (f->name,O_RDONLY)) >= 0) { struct stat stat; if (fstat (f->handle,&stat) == 0) { f->st_mode = stat.st_mode; if (!S_ISREG (f->st_mode)) { timed_io = TRUE; if (f->append_repeatitions != 0) { warn (LWAR,"Cannot repeat nonregular file", EINP,0,9,f->append_repeatitions); } f->repeatitions = 0; } else { f->repeatitions = f->append_repeatitions; } configuration_changed = TRUE; warn (LIMP,"End Append",EINP,0,f->repeatitions,f); } else { warn (LWAR,"Append fail",EINP,0,7,f); input_endfile (f); } } else { warn (LWAR,"Append fail",EINP,0,8,f); input_endfile (f); } } else { input_endfile (f); } } else { /* read error */ } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -