/*
* 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"
t_msec next_psi_periodic;
t_msec psi_frequency_msec;
boolean psi_frequency_changed;
boolean configuration_on;
boolean configuration_changed;
const char *configuration_total = "Conf: progs: %d\n";
boolean splice_init (void)
{
psi_frequency_msec = 0;
psi_frequency_changed = FALSE;
configuration_on = FALSE;
return (splice_specific_init ());
}
/* 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",ESPC,1,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.
* The input file is no longer automatic, because we do manual changes here.
* Precondition: s!=NULL, p!=NULL, s is stream in target program p
*/
void remove_streamprog (stream_descr *s,
prog_descr *p)
{
s->fdescr->automatic = FALSE;
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",ESPC,2,sid,s0);
return (s0);
}
s0 = s;
s += 1;
}
warn (LIMP,"Found SID",ESPC,2,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",ESPC,3,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",ESPC,3,1,p->stream[i]->sourceid);
return (p->stream[i]);
}
pmt = pmt->next;
}
}
}
return (NULL);
}
/* Print configuration for one program
* Precondition: p!=NULL
*/
void splice_one_configuration (prog_descr *p)
{
int i;
i = p->streams;
fprintf (stderr, "Conf: prog:%04X pmt:%04hX pcr:%04hX streams:%2d\n",
p->program_number, p->pmt_pid, p->pcr_pid, i);
while (--i >= 0) {
stream_descr *s;
s = p->stream[i];
fprintf (stderr, "Conf: stream:%04hX sid:%02X type:%02X "
"file:%d source:%04hX num:%2d name:%s\n",
s->u.d.pid, s->stream_id, s->stream_type,
s->fdescr->content, s->sourceid, s->fdescr->filerefnum, s->fdescr->name);
}
}
void splice_set_configuration (boolean on)
{
configuration_on = on;
configuration_changed = TRUE;
}
LinuxTV legacy CVS <linuxtv.org/cvs>