Annotation of multiplexer/splice.c, revision 1.5

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

LinuxTV legacy CVS <linuxtv.org/cvs>