Annotation of multiplexer/splitpes.c, revision 1.3

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

LinuxTV legacy CVS <linuxtv.org/cvs>