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>