File:
[DVB] /
multiplexer /
descref.c
Revision
1.10:
download - view:
text,
annotated -
select for diffs
Thu Jun 17 22:04:07 2004 UTC (19 years, 11 months ago) by
oskar
Branches:
MAIN
CVS tags:
version-1-1-7,
version-1-1-6,
version-1-1-5,
version-1-1-4,
version-1-1-3,
version-1-1-2,
version-1-1-1,
version-1-1-0,
version-1-0-8,
version-1-0-7,
version-1-0-6,
version-1-0-5,
version-1-0-4,
version-1-0-3,
version-1-0-2,
HEAD
ignore sigpipe
/*
* ISO 13818 stream multiplexer
* Copyright (C) 2001 Convergence Integrated Media GmbH Berlin
* Author: Oskar Schirmer (schirmer@scara.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Module: Descref
* Purpose: Put descriptor data into map stream buffers.
*/
#include "global.h"
#include "error.h"
#include "splitts.h"
static mapreference mapref;
static int din;
/* Start descriptor processing into a map stream s.
* The descriptor functions are to be used always in the
* sequence "alloc, put...put, finish"
* Postcondition: din==InputIndex, enough free space for PSI.
*/
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);
}
}
/* Scan a descriptor and put it into the map stream s.
* Source is raw data from file f.
* Decrease infolen^ by number of bytes processed, or set to -1 on error.
* Precondition: as thru alloc_descriptor
* Return: index increased by number of bytes processed.
*/
int put_descriptor (file_descr *f,
stream_descr *s,
int index,
int *infolen)
{
byte t, l;
t = f->data.ptr[index];
#if (NUMBER_DESCR < 0x100)
if (t >= NUMBER_DESCR) {
warn (LWAR,"Bad Descriptor Tag",EDES,2,1,t);
*infolen = -1;
return (index);
}
#endif
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);
}
/* Scan a descriptor and put it into the map stream s.
* Source is direct data from byte pointer d.
* Decrease infolen^ by number of bytes processed, or set to -1 on error.
* Precondition: as thru alloc_descriptor
* Return: byte pointer d increased by number of bytes processed.
*/
byte *put_descriptor_s (byte *d,
stream_descr *s,
int *infolen)
{
byte t, l;
t = *d++;
#if (NUMBER_DESCR < 0x100)
if (t >= NUMBER_DESCR) {
warn (LWAR,"Bad Descriptor Tag",EDES,3,1,t);
*infolen = -1;
return (d);
}
#endif
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);
}
/* Finish the collection of descriptors into the map stream s.
*/
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;
}
}
}
/* Save a set of descriptors map with a stream s,
* including both the references and the raw data.
*/
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->autodescr->data[0],dscr,size);
i = NUMBER_DESCR;
while (--i >= 0) {
if (map->elemdnew[i] == NULL) {
s->autodescr->refx[i] = NULL;
} else {
s->autodescr->refx[i] =
map->elemdnew[i] + ((&s->autodescr->data[0]) - dscr);
}
}
}
/* Take a set of descriptors from map stream m,
* determine the right stream to put the descriptors into
* (either the map stream itself, or a related data stream),
* save the descriptors into that stream.
*/
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 = ts_file_stream (m->fdescr,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) {
save_mapreference (pmapref,
&m->data.ptr[m->data.out+sizeof(mapreference)],
m->ctrl.ptr[m->ctrl.out].length-sizeof(mapreference),s);
if (s->streamdata != sd_data) {
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]->unchanged = TRUE;
/* check this: changed in which cases ? */
}
}
}
} 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;
}
/* Clear a descriptor struct
*/
void clear_descrdescr (descr_descr *dd)
{
memset (dd,0,sizeof(descr_descr));
}
LinuxTV legacy CVS <linuxtv.org/cvs>