/*
* 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;
}
LinuxTV legacy CVS <linuxtv.org/cvs>