/* * ISO 13818 stream multiplexer * Copyright (C) 2001 Convergence Integrated Media GmbH Berlin * Author: Oskar Schirmer (oskar@convergence.de) */ /* * Module: Splice * Purpose: Service functions for specific Splice* modules * * This module provides functions needed for splicing * which are independent from the splice type. */ #include "global.h" #include "error.h" #include "splice.h" #include "input.h" #include "pes.h" /* Connect a stream with a target program. * programnb denotes the program to connect, * stream is the stream to connect, * all further parameters are as with input_openstream. * If stream is NULL, open a stream first. * Add the stream to the programs list of streams and vice versa. * Precondition: f!=NULL * Return: the changed stream on success, the unchanged "stream" otherwise */ stream_descr *connect_streamprog (file_descr *f, int programnb, int sourceid, int streamid, int streamtype, stream_descr *stream, stream_descr *mapstream, boolean mention) { stream_descr *s; prog_descr *p; if (stream == NULL) { s = input_openstream (f,sourceid,streamid<0?-streamid:streamid, streamtype,sd_data,mapstream); } else { if (streamid < 0) { streamid = -streamid; warn (LWAR,"Cannot refind sid",EINP,14,1,streamid); } s = stream; } if (s != NULL) { p = splice_openprog (programnb); if (p != NULL) { if (input_addprog (s,p)) { if (splice_addstream (p,s,streamid>=0) > 0) { /* if (p->pcr_pid < 0) { if (xxx) { p->pcr_pid = s->u.d.pid; s->u.d.has_clockref = TRUE; s->u.d.next_clockref = msec_now () - MAX_MSEC_PCRDIST; } } */ s->endaction = ENDSTR_WAIT; s->u.d.mention = mention; return (s); } input_delprog (s,p); } if (p->streams <= 0) { splice_closeprog (p); } } if (stream == NULL) { input_closestream (s); } } return (stream); } /* Unlink a stream from a target program. * If the stream comes out to be in no program then, close it. * This function may be used only, if the program in question will either * be non-empty after the call, or will be closed by the calling function. * Precondition: s!=NULL, p!=NULL */ void unlink_streamprog (stream_descr *s, prog_descr *p) { splice_delstream (p,s); input_delprog (s,p); if (s->u.d.progs <= 0) { file_descr *f; f = s->fdescr; input_closestream (s); input_closefileifunused (f); } } /* Remove a stream from a target program. * Close stream and/or program, if not contained in another program or stream. * Precondition: s!=NULL, p!=NULL, s is stream in target program p */ void remove_streamprog (stream_descr *s, prog_descr *p) { if (p->streams > 1) { unlink_streamprog (s,p); } else { splice_closeprog (p); } } /* Find the right stream in a program * Precondition: p!=NULL * Return: stream, if found, NULL otherwise */ stream_descr *get_streamprog (prog_descr *p, int streamid) { int i; i = p->streams; while (--i >= 0) { stream_descr *s; s = p->stream[i]; if (s->stream_id == streamid) { return (s); } } return (NULL); } /* Find a free stream ID in a program that is equivalent to the given stream id * Precondition: p!=NULL * Return: Free ID, if found; given sid otherwise. */ int splice_findfreestreamid (prog_descr *p, int sid) { int s0, s, n; s0 = sid; if ((sid >= PES_CODE_AUDIO) && (sid < (PES_CODE_AUDIO+PES_NUMB_AUDIO))) { s = PES_CODE_AUDIO; n = PES_NUMB_AUDIO; } else if ((sid >= PES_CODE_VIDEO) && (sid < (PES_CODE_VIDEO+PES_NUMB_VIDEO))) { s = PES_CODE_VIDEO; n = PES_NUMB_VIDEO; } else { s = sid; n = 1; } while (--n >= 0) { int i; i = p->streams; while ((--i >= 0) && (p->stream[i]->stream_id != s0)) { } if (i < 0) { warn (LIMP,"Found SID free",EINP,15,sid,s0); return (s0); } s0 = s; s += 1; } warn (LIMP,"Found SID",EINP,15,sid,sid); return (sid); } /* Check if there is a source pcr stream in a target program * Precondition: p!=NULL * Return: pcr-stream, if found; NULL otherwise. */ stream_descr *splice_findpcrstream (prog_descr *p) { int i; pmt_descr *pmt; warn (LIMP,"Find PCR Stream",EINP,13,0,p->program_number); i = p->streams; while (--i >= 0) { if (p->stream[i]->fdescr->content == ct_transport) { pmt = p->stream[i]->fdescr->u.ts.pat; while (pmt != NULL) { if (pmt->pcr_pid == p->stream[i]->sourceid) { warn (LIMP,"Found PCR Stream",EINP,13,1,p->stream[i]->sourceid); return (p->stream[i]); } pmt = pmt->next; } } } return (NULL); }