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>