File:  [DVB] / multiplexer / descref.c
Revision 1.1: download - view: text, annotated - select for diffs
Mon Mar 19 20:52:34 2001 UTC (23 years, 2 months ago) by oskar
Branches: MAIN
CVS tags: HEAD
Multiplexer, first archived version.
New feature: --badtiming (see --help)

/*
 * 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>