/* * ISO 13818 stream multiplexer * Copyright (C) 2001 Convergence Integrated Media GmbH Berlin * Author: Oskar Schirmer (oskar@convergence.de) */ /* * Module: Descref * Purpose: Put descriptor data into map stream buffers. */ #include "global.h" #include "error.h" static mapreference mapref; static int din; void alloc_descriptor (stream_descr *s, int sourceid, int programnumber, byte version) { if (s != NULL) { warn (LINF,"Alloc Descriptor",EDES,1,version,sourceid); mapref.sourceid = sourceid; mapref.programnumber = programnumber; mapref.version = version; memset (&mapref.elemdnew,0,sizeof(mapref.elemdnew)); din = s->data.in; while (list_free (s->data) < 2*(sizeof(mapreference) + MAX_PSI_SIZE) + 1) { list_incr (s->ctrl.out,s->ctrl,1); s->data.out = s->ctrl.ptr[s->ctrl.out].index; } if (list_freeinend (s->data) < sizeof(mapreference) + MAX_PSI_SIZE) { din = 0; } s->ctrl.ptr[s->ctrl.in].index = din; s->ctrl.ptr[s->ctrl.in].length = sizeof(mapreference); din += sizeof(mapreference); } } int put_descriptor (file_descr *f, stream_descr *s, int index, int *infolen) { byte t, l; if ((t = f->data.ptr[index]) >= NUMBER_ELEMD) { warn (LWAR,"Bad Descriptor Tag",EDES,2,1,t); *infolen = -1; return (index); } warn (LINF,"Put Descriptor",EDES,2,0,t); list_incr (index,f->data,1); l = f->data.ptr[index]; if ((*infolen -= (l + 2)) >= 0) { if (s != NULL) { mapref.elemdnew[t] = &s->data.ptr[din]; s->ctrl.ptr[s->ctrl.in].length += (l + 2); s->data.ptr[din++] = t; s->data.ptr[din++] = l; while (l > 0) { list_incr (index,f->data,1); s->data.ptr[din++] = f->data.ptr[index]; l -= 1; } list_incr (index,f->data,1); } else { list_incr (index,f->data,l+1); } } return (index); } byte *put_descriptor_s (byte *d, stream_descr *s, int *infolen) { byte t, l; if ((t = *d++) >= NUMBER_ELEMD) { warn (LWAR,"Bad Descriptor Tag",EDES,3,1,t); *infolen = -1; return (d); } warn (LINF,"Put Descriptor",EDES,3,0,t); l = *d++; if ((*infolen -= (l + 2)) >= 0) { if (s != NULL) { mapref.elemdnew[t] = &s->data.ptr[din]; s->ctrl.ptr[s->ctrl.in].length += (l + 2); s->data.ptr[din++] = t; s->data.ptr[din++] = l; while (l > 0) { s->data.ptr[din++] = *d++; l -= 1; } } else { d += l; } } return (d); } void finish_descriptor (stream_descr *s) { if (s != NULL) { warn (LINF,"Finish Descriptor",EDES,4, s->fdescr->sequence,s->ctrl.ptr[s->ctrl.in].length); memcpy (&s->data.ptr[s->ctrl.ptr[s->ctrl.in].index],&mapref,sizeof(mapref)); s->data.in = din; warn (LDEB,"Sequence",EDES,4,1,s->fdescr->sequence); s->ctrl.ptr[s->ctrl.in].sequence = s->fdescr->sequence++; list_incr (s->ctrl.in,s->ctrl,1); if (s->ctrl.out == s->ctrl.in) { list_incr (s->ctrl.out,s->ctrl,1); s->data.out = s->ctrl.ptr[s->ctrl.out].index; } } } static void save_mapreference (mapreference *map, byte *dscr, int size, stream_descr *s) { int i; warn (LINF,"Save Mapref",EDES,5,0,size); s->version = map->version; /* ... = map->programnumber */ memcpy (&s->elemdescr[0],dscr,size); i = NUMBER_ELEMD; while (--i >= 0) { if (map->elemdnew[i] == NULL) { s->elemdvld[i] = NULL; } else { s->elemdvld[i] = map->elemdnew[i] + ((&s->elemdescr[0]) - dscr); } } } void validate_mapref (stream_descr *m) { stream_descr *s; int l; mapreference *pmapref; pmapref = (mapreference *)&m->data.ptr[m->data.out]; if (m->sourceid == pmapref->sourceid) { s = m; } else { switch (m->fdescr->content) { case ct_program: s = m->fdescr->u.ps.stream[pmapref->sourceid]; break; case ct_transport: s = m->fdescr->u.ts.stream[pmapref->sourceid]; break; default: warn (LERR,"Mapref NULL",EDES,6,1,m->fdescr->content); s = NULL; break; } } if (s != NULL) { if (s->version != pmapref->version) { /* { int i; i = m->ctrl.out; fprintf(stderr,"m=(p=%08x,i=%d,o=%d,m=%d)\n",(int)m->ctrl.ptr,m->ctrl.in,m->ctrl.out,m->ctrl.mask); while (i != m->ctrl.in) { fprintf(stderr,"m[%d]=(i=%d,l=%d,s=%d,t=%d)\n",i,m->ctrl.ptr[i].index,m->ctrl.ptr[i].length,m->ctrl.ptr[i].sequence,m->ctrl.ptr[i].time.push); list_incr (i,m->ctrl,1); } } warn (LERR,"CP",EDES,6,s,m); warn (LERR,"CP",EDES,6,m->data.in,m->data.out); warn (LERR,"CP",EDES,6,pmapref->sourceid,42); warn (LERR,"CP",EDES,6,m->sourceid,m->ctrl.in); warn (LERR,"CP",EDES,6,s->version,m->ctrl.out); warn (LERR,"CP",EDES,6,pmapref->version,m->ctrl.ptr[m->ctrl.out].sequence); warn (LERR,"CP",EDES,6,m->ctrl.ptr[m->ctrl.out].index,m->ctrl.ptr[m->ctrl.out].length); */ save_mapreference (pmapref, &m->data.ptr[m->data.out+sizeof(mapreference)], m->ctrl.ptr[m->ctrl.out].length-sizeof(mapreference),s); if (s->isamap) { warn (LDEB,"Mapref isamap",EDES,6,3,pmapref->sourceid); /* must do something, if input program is related to output prog */ } else { s->u.d.mention = TRUE; l = s->u.d.progs; while (--l >= 0) { s->u.d.pdescr[l]->changed = TRUE; } } } } else { warn (LDEB,"Mapref NULL",EDES,6,2,pmapref->sourceid); } list_incr (m->ctrl.out,m->ctrl,1); m->data.out = m->ctrl.ptr[m->ctrl.out].index; }