Annotation of multiplexer/splicets.c, revision 1.1

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 TS
        !             9:  * Purpose: Generate transport stream.
        !            10:  *
        !            11:  * This module generates from the available input stream data (as
        !            12:  * seperated by the split functions) the complete output stream.
        !            13:  * It provides functions to handle programs for the resulting stream,
        !            14:  * as these are output format dependent. Further, it accepts PSI data
        !            15:  * just in time, validating it not earlier than with the arrival of
        !            16:  * the corresponding payload at this stage.
        !            17:  */
        !            18: 
        !            19: #include "global.h"
        !            20: #include "crc.h"
        !            21: #include "error.h"
        !            22: #include "input.h"
        !            23: #include "output.h"
        !            24: #include "descref.h"
        !            25: #include "pes.h"
        !            26: #include "ts.h"
        !            27: #include "splice.h"
        !            28: #include "splicets.h"
        !            29: 
        !            30: const boolean splice_multipleprograms = TRUE;
        !            31: 
        !            32: static boolean changed_pat;
        !            33: static int pat_section;
        !            34: static const int last_patsection = 0;
        !            35: static byte nextpat_version;
        !            36: static byte pat_conticnt;
        !            37: 
        !            38: static int transportstreamid;
        !            39: 
        !            40: static int psi_size;
        !            41: static int psi_done;
        !            42: static byte psi_data [MAX_PSI_SIZE];
        !            43: 
        !            44: static byte unit_start;
        !            45: static byte *conticnt;
        !            46: static int psi_pid;
        !            47: 
        !            48: static int progs;
        !            49: static prog_descr *prog [MAX_OUTPROG];
        !            50: 
        !            51: static int nextpid;
        !            52: static stream_descr *outs [MAX_STRPERTS];
        !            53: 
        !            54: static int next_psi_periodic;
        !            55: static int psi_frequency_msec;
        !            56: static boolean psi_frequency_changed;
        !            57: 
        !            58: boolean splice_init (void)
        !            59: {
        !            60:   progs = 0;
        !            61:   nextpid = 0;
        !            62:   memset (outs,0,sizeof(outs));
        !            63:   changed_pat = TRUE;
        !            64:   pat_section = 0;
        !            65:   nextpat_version = 0;
        !            66:   pat_conticnt = 0;
        !            67:   psi_size = psi_done = 0;
        !            68:   unit_start = TS_UNIT_START;
        !            69:   transportstreamid = 0x4227;
        !            70:   psi_frequency_msec = 0;
        !            71:   psi_frequency_changed = FALSE;
        !            72:   return (TRUE);
        !            73: }
        !            74: 
        !            75: void splice_settransportstreamid (int tsid)
        !            76: {
        !            77:   transportstreamid = tsid;
        !            78: }
        !            79: 
        !            80: void splice_setpsifrequency (int freq)
        !            81: {
        !            82:   psi_frequency_msec = freq;
        !            83:   psi_frequency_changed = TRUE;
        !            84: }
        !            85: 
        !            86: static prog_descr *openprog (int programnb)
        !            87: {
        !            88:   int i;
        !            89:   i = progs;
        !            90:   while (--i >= 0) {
        !            91:     if (prog[i]->program_number == programnb) {
        !            92:       return (prog[i]);
        !            93:     }
        !            94:   }
        !            95:   return (NULL);
        !            96: }
        !            97: 
        !            98: static int findapid (stream_descr *s)
        !            99: {
        !           100:   boolean ok = TRUE;
        !           101:   do {
        !           102:     if ((nextpid < TS_PID_LOWEST) || (nextpid >= TS_PID_HIGHEST)) {
        !           103:       if (!ok) {
        !           104:         warn (LERR,"No PID found",ETSC,2,1,0);
        !           105:         return (0);
        !           106:       }
        !           107:       ok = FALSE;
        !           108:       nextpid = TS_PID_LOWEST;
        !           109:     } else {
        !           110:       nextpid += 1;
        !           111:     }
        !           112:   } while (outs[nextpid] != NULL);
        !           113:   outs[nextpid] = s;
        !           114:   warn (LDEB,"Next PID",ETSC,2,2,nextpid);
        !           115:   return (nextpid);
        !           116: }
        !           117: 
        !           118: prog_descr *splice_openprog (int programnb)
        !           119: {
        !           120:   prog_descr *p;
        !           121:   int pid;
        !           122:   warn (LIMP,"Open prog",ETSC,1,0,programnb);
        !           123:   p = openprog (programnb);
        !           124:   if (p == NULL) {
        !           125:     if (progs < MAX_OUTPROG) {
        !           126:       if ((pid = findapid (PMT_STREAM)) > 0) {
        !           127:         if ((p = malloc(sizeof(prog_descr))) != NULL) {
        !           128:           p->program_number = programnb;
        !           129:           p->pcr_pid = -1;
        !           130:           p->pmt_pid = pid;
        !           131:           p->map_sequence = -1;
        !           132:           p->pmt_conticnt = 0;
        !           133:           p->pmt_version = 0;
        !           134:           p->changed = TRUE;
        !           135:           p->pat_section = 0; /* more ? */
        !           136:           p->streams = 0;
        !           137:           prog[progs++] = p;
        !           138:           changed_pat = TRUE;
        !           139:         } else {
        !           140:           outs[pid] = NULL;
        !           141:           warn (LERR,"Open prog",ETSC,1,1,0);
        !           142:         }
        !           143:       }
        !           144:     } else {
        !           145:       warn (LERR,"Max prog open",ETSC,1,2,0);
        !           146:     }
        !           147:   }
        !           148:   return (p);
        !           149: }
        !           150: 
        !           151: void splice_closeprog (prog_descr *p)
        !           152: {
        !           153:   int i, n;
        !           154:   stream_descr *s;
        !           155:   file_descr *f;
        !           156:   warn (LIMP,"Close prog",ETSC,3,0,p->program_number);
        !           157:   while (p->streams > 0) {
        !           158:     s = p->stream[0];
        !           159:     input_delprog (s,p);
        !           160:     splice_delstream (p,s);
        !           161:     if (s->u.d.progs == 0) {
        !           162:       f = s->fdescr;
        !           163:       input_closestream (s);
        !           164:       input_closefileifunused (f);
        !           165:     }
        !           166:   }
        !           167:   n = -1;
        !           168:   if (p->pmt_pid >= 0) {
        !           169:     i = progs;
        !           170:     while (--i >= 0) {
        !           171:       if (prog[i]->pmt_pid == p->pmt_pid) {
        !           172:         n += 1;
        !           173:       }
        !           174:     }
        !           175:   }
        !           176:   i = progs;
        !           177:   while (--i >= 0) {
        !           178:     if (prog[i] == p) {
        !           179:       prog[i] = prog[--progs];
        !           180:       if (n == 0) {
        !           181:         outs[p->pmt_pid] = NULL;
        !           182:       }
        !           183:       free (p);
        !           184:       changed_pat = TRUE;
        !           185:       return;
        !           186:     }
        !           187:   }
        !           188:   warn (LERR,"Close lost prog",ETSC,3,1,progs);
        !           189: }
        !           190: 
        !           191: boolean splice_emptyprog (prog_descr *p)
        !           192: {
        !           193:   return (p->streams == 0);
        !           194: }
        !           195: 
        !           196: int splice_addstream (prog_descr *p,
        !           197:     stream_descr *s,
        !           198:     boolean force_sid)
        !           199: {
        !           200:   int pid = 0;
        !           201:   warn (LIMP,"Add stream",ETSC,4,force_sid,s->stream_id);
        !           202:   if (p->streams < MAX_STRPERPRG) {
        !           203:     if ((pid = findapid (s)) > 0) {
        !           204:       if (!force_sid) {
        !           205:         s->stream_id = input_findfreestreamid (p,s->stream_id);
        !           206:       }
        !           207:       p->stream[p->streams++] = s;
        !           208:       p->changed = TRUE;
        !           209:       s->u.d.pid = pid;
        !           210:     }
        !           211:   }
        !           212:   return (pid);
        !           213: }
        !           214: 
        !           215: boolean splice_delstream (prog_descr *p,
        !           216:     stream_descr *s)
        !           217: {
        !           218:   int i;
        !           219:   warn (LIMP,"Del stream",ETSC,5,0,s->u.d.pid);
        !           220:   i = p->streams;
        !           221:   while (--i >= 0) {
        !           222:     if (p->stream[i] == s) {
        !           223:       outs[s->u.d.pid] = NULL;
        !           224:       p->stream[i] = p->stream[--(p->streams)];
        !           225:       p->changed = TRUE;
        !           226:       if (p->pcr_pid == s->u.d.pid) {
        !           227:         p->pcr_pid = -1;
        !           228:       }
        !           229:       s->u.d.pid = 0;
        !           230:       return (TRUE);
        !           231:     }
        !           232:   }
        !           233:   warn (LERR,"Del lost stream",ETSC,5,1,p->streams);
        !           234:   return (FALSE);
        !           235: }
        !           236: 
        !           237: static int make_patsection (int section,
        !           238:     byte *dest)
        !           239: {
        !           240:   int i;
        !           241:   byte *d;
        !           242:   d = dest;
        !           243:   *d++ = TS_TABLEID_PAT;
        !           244:   d += 2;
        !           245:   *d++ = transportstreamid >> 8;
        !           246:   *d++ = (byte)transportstreamid;
        !           247:   *d++ = 0xC0 | 0x01 | (nextpat_version << 1);
        !           248:   *d++ = section;
        !           249:   *d++ = last_patsection;
        !           250:   i = progs;
        !           251:   while (--i >= 0) {
        !           252:     if (prog[i]->pat_section == section) {
        !           253:       int x;
        !           254:       x = prog[i]->program_number;
        !           255:       *d++ = (x >> 8);
        !           256:       *d++ = x;
        !           257:       x = prog[i]->pmt_pid;
        !           258:       *d++ = 0xE0 | (x >> 8);
        !           259:       *d++ = x;
        !           260:     }
        !           261:   }
        !           262:   i = d + CRC_SIZE - dest - TS_TRANSPORTID;
        !           263:   dest[TS_SECTIONLEN] = 0xB0 | (i >> 8);
        !           264:   dest[TS_SECTIONLEN+1] = i;
        !           265:   crc32_calc (dest,i + TS_TRANSPORTID - CRC_SIZE,d);
        !           266:   return (i + TS_TRANSPORTID);
        !           267: }
        !           268: 
        !           269: static int make_pmtsection (stream_descr *s,
        !           270:     prog_descr *p,
        !           271:     byte *dest)
        !           272: {
        !           273:   int i;
        !           274:   byte *d;
        !           275:   p->changed = FALSE;
        !           276:   d = dest;
        !           277:   *d++ = TS_TABLEID_PMT;
        !           278:   d += 2;
        !           279:   i = p->program_number;
        !           280:   *d++ = (i >> 8);
        !           281:   *d++ = i;
        !           282:   *d++ = 0xC0 | 0x01 | (p->pmt_version << 1);
        !           283:   p->pmt_version = (p->pmt_version+1) & 0x1F;
        !           284:   *d++ = 0;
        !           285:   *d++ = 0;
        !           286:   if (p->pcr_pid < 0) {
        !           287:     stream_descr *pcrs;
        !           288:     pcrs = input_findpcrstream (p);
        !           289:     if (pcrs == NULL) {
        !           290:       pcrs = s;
        !           291:     }
        !           292:     pcrs->u.d.has_clockref = TRUE;
        !           293:     pcrs->u.d.next_clockref = msec_now () - MAX_MSEC_PCRDIST;
        !           294:     p->pcr_pid = pcrs->u.d.pid;
        !           295:   }
        !           296:   i = p->pcr_pid;
        !           297:   *d++ = 0xE0 | (i >> 8);
        !           298:   *d++ = i;
        !           299:   d += 2;
        !           300:   i = NUMBER_ELEMD;
        !           301:   while (--i > 0) {
        !           302:     if (s->fdescr->content == ct_program) {
        !           303:       byte *y;
        !           304:       y = s->fdescr->u.ps.stream[0]->elemdvld[i]; /* this one ? why ? */
        !           305:       if (y != NULL) {
        !           306:         memcpy (d,y,y[1]+2);
        !           307:         d += y[1]+2;
        !           308:       }
        !           309:     }
        !           310:   }
        !           311:   i = d - dest - (TS_PMT_PILEN+2);
        !           312:   dest[TS_PMT_PILEN] = 0xF0 | (i >> 8);
        !           313:   dest[TS_PMT_PILEN+1] = i;
        !           314:   i = p->streams;
        !           315:   while (--i >= 0) {
        !           316:     if (p->stream[i]->u.d.mention) {
        !           317:       int x;
        !           318:       byte *e;
        !           319:       *d++ = p->stream[i]->stream_type;
        !           320:       x = p->stream[i]->u.d.pid;
        !           321:       *d++ = 0xE0 | (x >> 8);
        !           322:       *d++ = x;
        !           323:       d += 2;
        !           324:       e = d;
        !           325:       x = NUMBER_ELEMD;
        !           326:       while (--x > 0) {
        !           327:         byte *y;
        !           328:         y = p->stream[i]->elemdvld[x];
        !           329:         if (y != NULL) {
        !           330:           memcpy (d,y,y[1]+2);
        !           331:           d += y[1]+2;
        !           332:         }
        !           333:       }
        !           334:       x = d - e;
        !           335:       *--e = x;
        !           336:       *--e = 0xF0 | (x >> 8);
        !           337:     }
        !           338:   }
        !           339:   i = d + CRC_SIZE - dest - TS_TRANSPORTID;
        !           340:   dest[TS_SECTIONLEN] = 0xB0 | (i >> 8);
        !           341:   dest[TS_SECTIONLEN+1] = i;
        !           342:   crc32_calc (dest,i + TS_TRANSPORTID - CRC_SIZE,d);
        !           343:   return (i + TS_TRANSPORTID);
        !           344: }
        !           345: 
        !           346: void process_finish (void)
        !           347: {
        !           348:   warn (LIMP,"Finish",ETSC,6,0,0);
        !           349: }
        !           350: 
        !           351: stream_descr *process_something (stream_descr *s)
        !           352: {
        !           353:   byte *d;
        !           354:   int pid;
        !           355:   byte scramble;
        !           356:   ctrl_buffer *c;
        !           357:   int l, f, k;
        !           358:   int privdata;
        !           359:   int adapt_ext_len;
        !           360:   int now;
        !           361:   byte adapt_field_ctrl;
        !           362:   byte adapt_flags1, adapt_flags2;
        !           363:   warn (LDEB,"Splice TS",ETSC,0,0,s->ctrl.out);
        !           364:   if (s->isamap) {
        !           365:     validate_mapref (s);
        !           366:     return (NULL);
        !           367:   }
        !           368:   c = &s->ctrl.ptr[s->ctrl.out];
        !           369:   if (psi_size > 0) {
        !           370:     pid = psi_pid;
        !           371:     scramble = 0;
        !           372:     k = psi_size;
        !           373:   } else {
        !           374:     if (unit_start != 0) {
        !           375:       now = msec_now ();
        !           376:       if ((psi_frequency_changed)
        !           377:        || ((psi_frequency_msec > 0)
        !           378:         && ((next_psi_periodic - now) <= 0))) {
        !           379:         changed_pat = TRUE;
        !           380:         l = progs;
        !           381:         while (--l >= 0) {
        !           382:           prog[l]->changed = TRUE;
        !           383:         }
        !           384:         psi_frequency_changed = FALSE;
        !           385:         next_psi_periodic = now + psi_frequency_msec;
        !           386:       }
        !           387:       if (changed_pat) {
        !           388:         psi_pid = TS_PID_PAT;
        !           389:         conticnt = &pat_conticnt;
        !           390:         psi_data[0] = 0;
        !           391:         psi_size = make_patsection (pat_section,&psi_data[1]) + 1;
        !           392:         if (pat_section >= last_patsection) {
        !           393:           changed_pat = FALSE;
        !           394:           nextpat_version = (nextpat_version+1) & 0x1F;
        !           395:           pat_section = 0;
        !           396:         } else {
        !           397:           pat_section += 1;
        !           398:         }
        !           399:         psi_done = 0;
        !           400:         pid = psi_pid;
        !           401:         scramble = 0;
        !           402:         k = psi_size;
        !           403:       } else {
        !           404:         l = s->u.d.progs;
        !           405:         while (--l >= 0) {
        !           406:           if (s->u.d.pdescr[l]->changed) {
        !           407:             f = s->u.d.pdescr[l]->streams;
        !           408:             while ((--f >= 0)
        !           409:                 && (!s->u.d.pdescr[l]->stream[f]->u.d.mention)) {
        !           410:             }
        !           411:             if (f >= 0) {
        !           412:               psi_pid = s->u.d.pdescr[l]->pmt_pid;
        !           413:               conticnt = &s->u.d.pdescr[l]->pmt_conticnt;
        !           414:               psi_data[0] = 0;
        !           415:               psi_size = make_pmtsection (s,s->u.d.pdescr[l],&psi_data[1]) + 1;
        !           416:               psi_done = 0;
        !           417:               pid = psi_pid;
        !           418:               scramble = 0;
        !           419:               k = psi_size;
        !           420:               break;
        !           421:             }
        !           422:           }
        !           423:         }
        !           424:         if (l < 0) {
        !           425:           s->data.ptr[c->index+PES_STREAM_ID] = s->stream_id;
        !           426:           conticnt = &s->conticnt;
        !           427:           pid = s->u.d.pid;
        !           428:           scramble = c->scramble;
        !           429:           k = c->length;
        !           430:         }
        !           431:       }
        !           432:     } else {
        !           433:       pid = s->u.d.pid;
        !           434:       scramble = c->scramble;
        !           435:       k = c->length;
        !           436:     }
        !           437:   }
        !           438:   d = output_pushdata (TS_PACKET_SIZE,c->time.push + s->u.d.delta);
        !           439:   if (d == NULL) {
        !           440:     return (s);
        !           441:   }
        !           442:   adapt_ext_len = 1;
        !           443:   adapt_flags2 = 0;
        !           444:   adapt_flags1 = 0;
        !           445:   f = TS_PACKET_SIZE - TS_PACKET_HEADSIZE;
        !           446:   if ((psi_size <= 0)
        !           447:    && (s->u.d.discontinuity)) { /* o, not for contents, but PCR-disco ? */
        !           448:     s->u.d.discontinuity = FALSE;
        !           449:     adapt_flags1 |= TS_ADAPT_DISCONTI;
        !           450:   }
        !           451:   if (0) {
        !           452:     adapt_flags1 |= TS_ADAPT_RANDOMAC;
        !           453:   }
        !           454:   if (0) {
        !           455:     adapt_flags1 |= TS_ADAPT_PRIORITY;
        !           456:   }
        !           457:   if ((psi_size <= 0)
        !           458:    && (s->u.d.has_clockref)
        !           459:    && ((c->pcr.valid)
        !           460:     || (s->u.d.next_clockref - (c->time.push + s->u.d.delta) <= 0))) {
        !           461: /*
        !           462: fprintf (stderr,"n=%10d, p=%10d, (now %10d)\n",
        !           463: s->u.d.next_clockref,
        !           464: c->time.push + s->delta,
        !           465: msec_now ());
        !           466: */
        !           467:     adapt_flags1 |= TS_ADAPT_PCRFLAG;
        !           468:     f -= 6;
        !           469:   }
        !           470:   if ((psi_size <= 0)
        !           471:    && (c->opcr.valid)) {
        !           472:     adapt_flags1 |= TS_ADAPT_OPCRFLAG;
        !           473:     f -= 6;
        !           474:   }
        !           475:   if (0) {
        !           476:     adapt_flags1 |= TS_ADAPT_SPLICING;
        !           477:     f -= 1;
        !           478:   }
        !           479:   if (0) {
        !           480:     adapt_flags1 |= TS_ADAPT_TPRIVATE;
        !           481:     privdata = 0;
        !           482:     f -= (privdata + 1);
        !           483:   }
        !           484:   if (0) {
        !           485:     adapt_flags2 |= TS_ADAPT_LTWFLAG;
        !           486:     adapt_ext_len += 2;
        !           487:   }
        !           488:   if (0) {
        !           489:     adapt_flags2 |= TS_ADAPT_PIECEWRF;
        !           490:     adapt_ext_len += 3;
        !           491:   }
        !           492:   if (0) {
        !           493:     adapt_flags2 |= TS_ADAPT_SEAMLESS;
        !           494:     adapt_ext_len += 5;
        !           495:   }
        !           496:   if (adapt_flags2 != 0) {
        !           497:     adapt_flags1 |= TS_ADAPT_EXTENSIO;
        !           498:     f -= adapt_ext_len;
        !           499:   }
        !           500:   if (adapt_flags1 != 0) {
        !           501:     f -= 2;
        !           502:   }
        !           503:   if (k < f) {
        !           504:     l = k;
        !           505:     if (adapt_flags1 == 0) {
        !           506:       f -= 1;
        !           507:       if (f > l) {
        !           508:         f -= 1;
        !           509:       }
        !           510:     }
        !           511:     adapt_field_ctrl = TS_AFC_BOTH;
        !           512:   } else {
        !           513:     l = f;
        !           514:     if (f == 0) {
        !           515:       adapt_field_ctrl = TS_AFC_ADAPT;
        !           516:     } else if (adapt_flags1 == 0) {
        !           517:       adapt_field_ctrl = TS_AFC_PAYLD;
        !           518:     } else {
        !           519:       adapt_field_ctrl = TS_AFC_BOTH;
        !           520:     }
        !           521:   }
        !           522:   *d++ = TS_SYNC_BYTE;
        !           523:   warn (LSEC,"Splice unitstart",ETSC,0,1,unit_start);
        !           524:   warn (LSEC,"Splice PID",ETSC,0,2,pid);
        !           525:   *d++ = (0 << 7) /* transport_error_indicator */
        !           526:        | unit_start
        !           527:        | (0 << 5) /* transport_priority */
        !           528:        | (pid >> 8);
        !           529:   *d++ = pid;
        !           530:   *d++ = (scramble << 6)
        !           531:        | adapt_field_ctrl
        !           532:        | *conticnt;
        !           533:   warn (LSEC,"Splice continuity cnt",ETSC,0,3,*conticnt);
        !           534:   if (adapt_field_ctrl & TS_AFC_PAYLD) {
        !           535:     *conticnt = (*conticnt+1) & 0x0F;
        !           536:   }
        !           537:   if (adapt_field_ctrl & TS_AFC_ADAPT) {
        !           538:     if ((*d++ = (TS_PACKET_SIZE - TS_PACKET_FLAGS1) - l) != 0) {
        !           539:       *d++ = adapt_flags1;
        !           540:       if (adapt_flags1 & TS_ADAPT_PCRFLAG) {
        !           541:         clockref pcr;
        !           542:         msec2clockref (c->time.push + s->u.d.delta,pcr);
        !           543:         *d++ = (pcr.base >> 25) | (pcr.ba33 << 7);
        !           544:         *d++ = pcr.base >> 17;
        !           545:         *d++ = pcr.base >> 9;
        !           546:         *d++ = pcr.base >> 1;
        !           547:         *d++ = (pcr.base << 7) | (pcr.ext >> 8) | 0x7E;
        !           548:         *d++ = pcr.ext;
        !           549:         s->u.d.next_clockref =
        !           550:           (c->time.push + s->u.d.delta) + MAX_MSEC_PCRDIST * 8/10;
        !           551:         c->pcr.valid = FALSE;
        !           552:       }
        !           553:       if (adapt_flags1 & TS_ADAPT_OPCRFLAG) {
        !           554:         *d++ = (c->opcr.base >> 25) | (c->opcr.ba33 << 7);
        !           555:         *d++ = c->opcr.base >> 17;
        !           556:         *d++ = c->opcr.base >> 9;
        !           557:         *d++ = c->opcr.base >> 1;
        !           558:         *d++ = (c->opcr.base << 7) | (c->opcr.ext >> 8) | 0x7E;
        !           559:         *d++ = c->opcr.ext;
        !           560:         c->opcr.valid = FALSE;
        !           561:       }
        !           562:       if (adapt_flags1 & TS_ADAPT_SPLICING) {
        !           563:       }
        !           564:       if (adapt_flags1 & TS_ADAPT_TPRIVATE) {
        !           565:       }
        !           566:       if (adapt_flags1 & TS_ADAPT_EXTENSIO) {
        !           567:         *d++ = adapt_ext_len;
        !           568:         *d++ = adapt_flags2 | 0x1F;
        !           569:         if (adapt_flags2 & TS_ADAPT_LTWFLAG) {
        !           570:         }
        !           571:         if (adapt_flags2 & TS_ADAPT_PIECEWRF) {
        !           572:         }
        !           573:         if (adapt_flags2 & TS_ADAPT_SEAMLESS) {
        !           574:         }
        !           575:       }
        !           576:     }
        !           577:     if (f > l) {
        !           578:       warn (LSEC,"Splice padding",ETSC,0,4,f-l);
        !           579:       memset (d,-1,f-l);
        !           580:       d += (f-l);
        !           581:     }
        !           582:   }
        !           583:   if (l > 0) {
        !           584:     if (psi_size > 0) {
        !           585:       memcpy (d,&psi_data[psi_done],l);
        !           586:       if (l < psi_size) {
        !           587:         warn (LSEC,"Splice PSI Data",ETSC,0,s->stream_id,l);
        !           588:         psi_done += l;
        !           589:         psi_size -= l;
        !           590:         unit_start = 0;
        !           591:       } else {
        !           592:         warn (LINF,"Splice PSI Done",ETSC,0,s->stream_id,l);
        !           593:         psi_done = psi_size = 0;
        !           594:         unit_start = TS_UNIT_START;
        !           595:       }
        !           596:     } else {
        !           597:       memcpy (d,&s->data.ptr[c->index],l);
        !           598:       if (l < c->length) {
        !           599:         warn (LSEC,"Splice Data",ETSC,0,s->stream_id,l);
        !           600:         c->length -= l;
        !           601:         s->data.out = (c->index += l);
        !           602:         unit_start = 0;
        !           603:       } else {
        !           604:         warn (LINF,"Splice Done",ETSC,0,s->stream_id,l);
        !           605:         list_incr (s->ctrl.out,s->ctrl,1);
        !           606:         if (list_empty (s->ctrl)) {
        !           607:           s->data.out = s->data.in;
        !           608:         } else {
        !           609:           s->data.out = s->ctrl.ptr[s->ctrl.out].index;
        !           610:         }
        !           611:         s = NULL;
        !           612:         unit_start = TS_UNIT_START;
        !           613:       }
        !           614:     }
        !           615:   }
        !           616:   return (s);
        !           617: }
        !           618: 

LinuxTV legacy CVS <linuxtv.org/cvs>