Annotation of multiplexer/splitpes.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:  Split PES
        !             9:  * Purpose: Split a packetized elementary stream.
        !            10:  *
        !            11:  * This module examines a packetized elementary stream and copies the
        !            12:  * packets to the input stream buffer. Some of the service functions
        !            13:  * provided are also used by module Split PS due to similarity of the
        !            14:  * format.
        !            15:  */
        !            16: 
        !            17: #include "global.h"
        !            18: #include "error.h"
        !            19: #include "pes.h"
        !            20: #include "splitpes.h"
        !            21: #include "input.h"
        !            22: 
        !            23: int guess_streamtype (int streamid)
        !            24: {
        !            25:   if ((streamid >= PES_CODE_AUDIO)
        !            26:    && (streamid < PES_CODE_AUDIO + PES_NUMB_AUDIO)) {
        !            27:     return (PES_STRTYP_AUDIO13818);
        !            28:   }
        !            29:   if ((streamid >= PES_CODE_VIDEO)
        !            30:    && (streamid < PES_CODE_VIDEO + PES_NUMB_VIDEO)) {
        !            31:     return (PES_STRTYP_VIDEO13818);
        !            32:   }
        !            33:   switch (streamid) {
        !            34:     case PES_CODE_PRIVATE1:
        !            35:     case PES_CODE_PRIVATE2:
        !            36:       return (PES_STRTYP_PRIVATDATA);
        !            37:     case PES_CODE_DSMCC:
        !            38:       return (PES_STRTYP_DSMCC);
        !            39:     case PES_CODE_ITU222A:
        !            40:     case PES_CODE_ITU222B:
        !            41:     case PES_CODE_ITU222C:
        !            42:     case PES_CODE_ITU222D:
        !            43:     case PES_CODE_ITU222E:
        !            44:       return (PES_STRTYP_ITUH222);
        !            45:     case PES_CODE_ISO13522:
        !            46:       return (PES_STRTYP_MHEG13522);
        !            47:     default:
        !            48:       return (0); 
        !            49:   }
        !            50: }
        !            51: 
        !            52: boolean pes_skip_to_prefix (file_descr *f)
        !            53: {
        !            54:   unsigned int p;
        !            55:   int i, l, k;
        !            56:   boolean r = FALSE;
        !            57:   l = k = list_size (f->data);
        !            58:   i = f->data.out;
        !            59:   p = 2;
        !            60:   while ((l > 0)
        !            61:       && ((p != 0x000001) || (r = TRUE, FALSE))) {
        !            62:     p = ((p & 0x0000FFFF) << 8) | f->data.ptr[i];
        !            63:     list_incr (i,f->data,1);
        !            64:     l -= 1;
        !            65:   }
        !            66:   k = k - l - PES_SYNC_SIZE;
        !            67:   if (k > 0) {
        !            68:     warn (LWAR,"Skipped",EPES,1,1,k);
        !            69:     f->skipped += k; /* evaluate: skip > good and skip > CONST -> bad */
        !            70:     f->total += k;
        !            71:     list_incr (f->data.out,f->data,k);
        !            72:   }
        !            73:   return (r);
        !            74: }
        !            75: 
        !            76: int pes_stream_id (refr_data *d)
        !            77: {
        !            78:   int i;
        !            79:   i = d->out;
        !            80:   list_incr (i,*d,PES_STREAM_ID);
        !            81:   warn (LINF,"Stream Id",EPES,2,1,d->ptr[i]);
        !            82:   return (d->ptr[i]);
        !            83: }
        !            84: 
        !            85: int pes_packet_length (refr_data *d)
        !            86: { /* special case len = 0: to do 2.4.3.7 */
        !            87: #define MAX_PACKETSIZE_PROCESSABLE \
        !            88:     (mmin((MAX_DATA_RAWB-HIGHWATER_IN),(MAX_DATA_INB/2)) - PES_HEADER_SIZE)
        !            89:   int i, l;
        !            90:   i = d->out;
        !            91:   list_incr (i,*d,PES_PACKET_LENGTH);
        !            92:   l = d->ptr[i] << 8;
        !            93:   list_incr (i,*d,1);
        !            94:   l = l | d->ptr[i];
        !            95:   if (l > MAX_PACKETSIZE_PROCESSABLE) {
        !            96:     warn (LWAR,"Packet too large",EPES,3,2,l);
        !            97:     l = MAX_PACKETSIZE_PROCESSABLE;
        !            98:   }
        !            99:   warn (LINF,"Packet Length",EPES,3,1,l);
        !           100:   return (l);
        !           101: }
        !           102: 
        !           103: int pes_transfer (refr_data *src,
        !           104:     refr_data *dst,
        !           105:     int size)
        !           106: {
        !           107:   int l, r;
        !           108:   if (size > list_freeinend (*dst)) {
        !           109:     dst->in = 0;
        !           110:   }
        !           111:   r = dst->in;
        !           112:   while (size > 0) {
        !           113:     l = MAX_DATA_RAWB - src->out;
        !           114:     if (l > size) {
        !           115:       l = size;
        !           116:     }
        !           117:     memcpy (&dst->ptr[dst->in],&src->ptr[src->out],l);
        !           118:     list_incr (dst->in,*dst,l);
        !           119:     list_incr (src->out,*src,l);
        !           120:     warn (LDEB,"Transfer",EPES,4,1,l);
        !           121:     size -= l;
        !           122:   }
        !           123:   return (r);
        !           124: }
        !           125: 
        !           126: boolean split_pes (file_descr *f)
        !           127: {
        !           128:   int l, p, q;
        !           129:   stream_descr *s;
        !           130:   ctrl_buffer *c;
        !           131:   warn (LDEB,"Split PES",EPES,0,0,f);
        !           132:   if (pes_skip_to_prefix (f)) {
        !           133:     l = list_size (f->data);
        !           134:     if (l >= PES_HDCODE_SIZE) {
        !           135:       p = pes_stream_id (&f->data);
        !           136:       if (p >= PES_LOWEST_SID) {
        !           137:         if (f->u.pes.stream == NULL) {
        !           138:           if (f->automatic) {
        !           139:             f->u.pes.stream = connect_streamprog (f,f->auto_programnb,
        !           140:                 p,-p,guess_streamtype(p),NULL,NULL,FALSE);
        !           141:             if (f->u.pes.stream == NULL) {
        !           142:               f->automatic = FALSE;
        !           143:               return (FALSE);
        !           144:             }
        !           145:           } else {
        !           146:             if (list_free (f->data) < HIGHWATER_IN) {
        !           147:               if (!S_ISREG(f->stat.st_mode)) {
        !           148:                 f->skipped += PES_SYNC_SIZE;
        !           149:                 f->total += PES_SYNC_SIZE;
        !           150:                 list_incr (f->data.out,f->data,PES_SYNC_SIZE);
        !           151:                 return (TRUE);
        !           152:               }
        !           153:             }
        !           154:             return (FALSE);
        !           155:           }
        !           156:         }
        !           157:         s = f->u.pes.stream;
        !           158:         if (l >= PES_HEADER_SIZE) {
        !           159:           q = pes_packet_length (&f->data);
        !           160:           q += PES_HEADER_SIZE;
        !           161:           if (l >= q) {
        !           162:             if (p == s->stream_id) {
        !           163:               if (list_free (s->data) >= 2*q-1) {
        !           164:                 c = &s->ctrl.ptr[s->ctrl.in];
        !           165:                 c->length = q;
        !           166:                 f->payload += q;
        !           167:                 f->total += q;
        !           168:                 c->index = pes_transfer (&f->data,&s->data,q);
        !           169:                 warn (LDEB,"Sequence",EPES,0,1,f->sequence);
        !           170:                 c->sequence = f->sequence++;
        !           171:                 c->scramble = 0;
        !           172:                 c->time.read = msec_now ();
        !           173:                 if (S_ISREG (f->stat.st_mode)) {
        !           174:                   c->time.push = c->time.read; /* wrong, but how ? */
        !           175:                 } else {
        !           176:                   c->time.push = c->time.read; /* enough ? */
        !           177:                 }
        !           178:                 c->pcr.valid = FALSE;
        !           179:                 c->opcr.valid = FALSE;
        !           180:                 list_incr (s->ctrl.in,s->ctrl,1);
        !           181:                 return (TRUE);
        !           182:               }
        !           183:             } else {
        !           184:               warn (LDEB,"Dropped PES Packet",EPES,0,p,q);
        !           185:               f->skipped += q;
        !           186:               f->total += q;
        !           187:               list_incr (f->data.out,f->data,q);
        !           188:               return (TRUE);
        !           189:             }
        !           190:           }
        !           191:         }
        !           192:       } else {
        !           193:         warn (LWAR,"Unknown PES Packet",EPES,0,2,p);
        !           194:         f->skipped += PES_SYNC_SIZE;
        !           195:         f->total += PES_SYNC_SIZE;
        !           196:         list_incr (f->data.out,f->data,PES_SYNC_SIZE);
        !           197:         return (TRUE);
        !           198:       }
        !           199:     }
        !           200:   }
        !           201:   return (FALSE);
        !           202: }
        !           203: 

LinuxTV legacy CVS <linuxtv.org/cvs>