Annotation of multiplexer/splice.c, revision 1.6
1.1 oskar 1: /*
2: * ISO 13818 stream multiplexer
3: * Copyright (C) 2001 Convergence Integrated Media GmbH Berlin
4: * Author: Oskar Schirmer (oskar@convergence.de)
5: */
6:
7: /*
8: * Module: Splice
9: * Purpose: Service functions for specific Splice* modules
10: *
11: * This module provides functions needed for splicing
12: * which are independent from the splice type.
13: */
14:
15: #include "global.h"
16: #include "error.h"
17: #include "splice.h"
18: #include "input.h"
19: #include "pes.h"
1.6 ! oskar 20: #include "descref.h"
1.1 oskar 21:
1.5 oskar 22: t_msec next_psi_periodic;
23: t_msec psi_frequency_msec;
24: boolean psi_frequency_changed;
25:
26: boolean configuration_on;
27: boolean configuration_changed;
28: const char *configuration_total = "Conf: progs: %d\n";
29:
30: boolean splice_init (void)
31: {
32: psi_frequency_msec = 0;
33: psi_frequency_changed = FALSE;
34: configuration_on = FALSE;
35: return (splice_specific_init ());
36: }
37:
1.2 oskar 38: /* Connect a stream with a target program.
39: * programnb denotes the program to connect,
40: * stream is the stream to connect,
41: * all further parameters are as with input_openstream.
42: * If stream is NULL, open a stream first.
43: * Add the stream to the programs list of streams and vice versa.
44: * Precondition: f!=NULL
45: * Return: the changed stream on success, the unchanged "stream" otherwise
46: */
1.1 oskar 47: stream_descr *connect_streamprog (file_descr *f,
48: int programnb,
49: int sourceid,
50: int streamid,
51: int streamtype,
52: stream_descr *stream,
53: stream_descr *mapstream,
54: boolean mention)
55: {
56: stream_descr *s;
57: prog_descr *p;
58: if (stream == NULL) {
59: s = input_openstream (f,sourceid,streamid<0?-streamid:streamid,
1.3 oskar 60: streamtype,sd_data,mapstream);
1.1 oskar 61: } else {
62: if (streamid < 0) {
63: streamid = -streamid;
1.4 oskar 64: warn (LWAR,"Cannot refind sid",ESPC,1,1,streamid);
1.1 oskar 65: }
66: s = stream;
67: }
68: if (s != NULL) {
69: p = splice_openprog (programnb);
70: if (p != NULL) {
71: if (input_addprog (s,p)) {
72: if (splice_addstream (p,s,streamid>=0) > 0) {
73: /*
74: if (p->pcr_pid < 0) {
75: if (xxx) {
76: p->pcr_pid = s->u.d.pid;
77: s->u.d.has_clockref = TRUE;
78: s->u.d.next_clockref = msec_now () - MAX_MSEC_PCRDIST;
79: }
80: }
81: */
82: s->endaction = ENDSTR_WAIT;
83: s->u.d.mention = mention;
84: return (s);
85: }
86: input_delprog (s,p);
87: }
88: if (p->streams <= 0) {
89: splice_closeprog (p);
90: }
91: }
92: if (stream == NULL) {
93: input_closestream (s);
94: }
95: }
96: return (stream);
97: }
1.2 oskar 98:
99: /* Unlink a stream from a target program.
100: * If the stream comes out to be in no program then, close it.
101: * This function may be used only, if the program in question will either
102: * be non-empty after the call, or will be closed by the calling function.
103: * Precondition: s!=NULL, p!=NULL
104: */
1.1 oskar 105: void unlink_streamprog (stream_descr *s,
106: prog_descr *p)
107: {
108: splice_delstream (p,s);
109: input_delprog (s,p);
110: if (s->u.d.progs <= 0) {
111: file_descr *f;
112: f = s->fdescr;
113: input_closestream (s);
114: input_closefileifunused (f);
115: }
116: }
1.2 oskar 117:
118: /* Remove a stream from a target program.
119: * Close stream and/or program, if not contained in another program or stream.
1.5 oskar 120: * The input file is no longer automatic, because we do manual changes here.
1.2 oskar 121: * Precondition: s!=NULL, p!=NULL, s is stream in target program p
122: */
1.1 oskar 123: void remove_streamprog (stream_descr *s,
124: prog_descr *p)
125: {
1.5 oskar 126: s->fdescr->automatic = FALSE;
1.2 oskar 127: if (p->streams > 1) {
128: unlink_streamprog (s,p);
129: } else {
130: splice_closeprog (p);
1.1 oskar 131: }
132: }
133:
1.2 oskar 134: /* Find the right stream in a program
135: * Precondition: p!=NULL
136: * Return: stream, if found, NULL otherwise
137: */
1.1 oskar 138: stream_descr *get_streamprog (prog_descr *p,
139: int streamid)
140: {
141: int i;
142: i = p->streams;
143: while (--i >= 0) {
144: stream_descr *s;
145: s = p->stream[i];
146: if (s->stream_id == streamid) {
147: return (s);
148: }
149: }
150: return (NULL);
151: }
152:
1.2 oskar 153: /* Find a free stream ID in a program that is equivalent to the given stream id
154: * Precondition: p!=NULL
155: * Return: Free ID, if found; given sid otherwise.
156: */
1.1 oskar 157: int splice_findfreestreamid (prog_descr *p,
158: int sid)
159: {
1.2 oskar 160: int s0, s, n;
161: s0 = sid;
1.1 oskar 162: if ((sid >= PES_CODE_AUDIO)
163: && (sid < (PES_CODE_AUDIO+PES_NUMB_AUDIO))) {
164: s = PES_CODE_AUDIO;
1.2 oskar 165: n = PES_NUMB_AUDIO;
1.1 oskar 166: } else if ((sid >= PES_CODE_VIDEO)
167: && (sid < (PES_CODE_VIDEO+PES_NUMB_VIDEO))) {
168: s = PES_CODE_VIDEO;
1.2 oskar 169: n = PES_NUMB_VIDEO;
1.1 oskar 170: } else {
171: s = sid;
1.2 oskar 172: n = 1;
1.1 oskar 173: }
174: while (--n >= 0) {
175: int i;
176: i = p->streams;
177: while ((--i >= 0)
1.2 oskar 178: && (p->stream[i]->stream_id != s0)) {
1.1 oskar 179: }
180: if (i < 0) {
1.4 oskar 181: warn (LIMP,"Found SID free",ESPC,2,sid,s0);
1.2 oskar 182: return (s0);
1.1 oskar 183: }
1.2 oskar 184: s0 = s;
1.1 oskar 185: s += 1;
186: }
1.4 oskar 187: warn (LIMP,"Found SID",ESPC,2,sid,sid);
1.2 oskar 188: return (sid);
1.1 oskar 189: }
190:
1.2 oskar 191: /* Check if there is a source pcr stream in a target program
192: * Precondition: p!=NULL
193: * Return: pcr-stream, if found; NULL otherwise.
194: */
1.1 oskar 195: stream_descr *splice_findpcrstream (prog_descr *p)
196: {
197: int i;
198: pmt_descr *pmt;
1.4 oskar 199: warn (LIMP,"Find PCR Stream",ESPC,3,0,p->program_number);
1.1 oskar 200: i = p->streams;
201: while (--i >= 0) {
202: if (p->stream[i]->fdescr->content == ct_transport) {
203: pmt = p->stream[i]->fdescr->u.ts.pat;
204: while (pmt != NULL) {
205: if (pmt->pcr_pid == p->stream[i]->sourceid) {
1.4 oskar 206: warn (LIMP,"Found PCR Stream",ESPC,3,1,p->stream[i]->sourceid);
1.1 oskar 207: return (p->stream[i]);
208: }
209: pmt = pmt->next;
210: }
211: }
212: }
213: return (NULL);
1.5 oskar 214: }
215:
216: /* Print configuration for one program
217: * Precondition: p!=NULL
218: */
219: void splice_one_configuration (prog_descr *p)
220: {
1.6 ! oskar 221: int i, s;
! 222: stump_descr *st;
1.5 oskar 223: i = p->streams;
1.6 ! oskar 224: s = 0;
! 225: st = p->stump;
! 226: while (st != NULL) {
! 227: s += 1;
! 228: st = st->next;
! 229: }
! 230: fprintf (stderr, "Conf: prog:%04X pmt:%04hX pcr:%04hX streams:%2d",
! 231: p->program_number, p->pmt_pid, p->pcr_pid, i+s);
! 232: if (s > 0) {
! 233: fprintf (stderr, " (%d)", s);
! 234: }
! 235: fprintf (stderr, "\n");
1.5 oskar 236: while (--i >= 0) {
237: stream_descr *s;
238: s = p->stream[i];
1.6 ! oskar 239: fprintf (stderr, "Conf: stream:%04hX type:%02X sid:%02X "
1.5 oskar 240: "file:%d source:%04hX num:%2d name:%s\n",
1.6 ! oskar 241: s->u.d.pid, s->stream_type, s->stream_id,
1.5 oskar 242: s->fdescr->content, s->sourceid, s->fdescr->filerefnum, s->fdescr->name);
1.6 ! oskar 243: }
! 244: st = p->stump;
! 245: while (st != NULL) {
! 246: fprintf (stderr, "Conf: stream:%04hX type:%02X\n",
! 247: st->pid, st->stream_type);
! 248: st = st->next;
1.5 oskar 249: }
250: }
251:
252: void splice_set_configuration (boolean on)
253: {
254: configuration_on = on;
255: configuration_changed = TRUE;
1.1 oskar 256: }
257:
LinuxTV legacy CVS <linuxtv.org/cvs>