You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

864 lines
28 KiB

/*****************************************************************************
* parse.c: A52 parsing procedures
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: parse.c,v 1.2 2002/08/08 00:35:11 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
* Renaud Dartus <reno@videolan.org>
*
* 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, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <string.h> /* memset() */
#include <vlc/vlc.h>
#include <vlc/decoder.h>
#include "imdct.h"
#include "downmix.h"
#include "adec.h"
#include "internal.h" /* EXP_REUSE */
/* Misc LUT */
static const u16 nfchans[] = { 2, 1, 2, 3, 3, 4, 4, 5 };
struct frmsize_s
{
u16 bit_rate;
u16 frm_size[3];
};
static const struct frmsize_s frmsizecod_tbl[] =
{
{ 32 ,{64 ,69 ,96 } },
{ 32 ,{64 ,70 ,96 } },
{ 40 ,{80 ,87 ,120 } },
{ 40 ,{80 ,88 ,120 } },
{ 48 ,{96 ,104 ,144 } },
{ 48 ,{96 ,105 ,144 } },
{ 56 ,{112 ,121 ,168 } },
{ 56 ,{112 ,122 ,168 } },
{ 64 ,{128 ,139 ,192 } },
{ 64 ,{128 ,140 ,192 } },
{ 80 ,{160 ,174 ,240 } },
{ 80 ,{160 ,175 ,240 } },
{ 96 ,{192 ,208 ,288 } },
{ 96 ,{192 ,209 ,288 } },
{ 112 ,{224 ,243 ,336 } },
{ 112 ,{224 ,244 ,336 } },
{ 128 ,{256 ,278 ,384 } },
{ 128 ,{256 ,279 ,384 } },
{ 160 ,{320 ,348 ,480 } },
{ 160 ,{320 ,349 ,480 } },
{ 192 ,{384 ,417 ,576 } },
{ 192 ,{384 ,418 ,576 } },
{ 224 ,{448 ,487 ,672 } },
{ 224 ,{448 ,488 ,672 } },
{ 256 ,{512 ,557 ,768 } },
{ 256 ,{512 ,558 ,768 } },
{ 320 ,{640 ,696 ,960 } },
{ 320 ,{640 ,697 ,960 } },
{ 384 ,{768 ,835 ,1152 } },
{ 384 ,{768 ,836 ,1152 } },
{ 448 ,{896 ,975 ,1344 } },
{ 448 ,{896 ,976 ,1344 } },
{ 512 ,{1024 ,1114 ,1536 } },
{ 512 ,{1024 ,1115 ,1536 } },
{ 576 ,{1152 ,1253 ,1728 } },
{ 576 ,{1152 ,1254 ,1728 } },
{ 640 ,{1280 ,1393 ,1920 } },
{ 640 ,{1280 ,1394 ,1920 } }};
static const int fscod_tbl[] = {48000, 44100, 32000};
/* Some internal functions */
static void parse_bsi_stats (a52dec_t * p_a52dec);
static void parse_audblk_stats (a52dec_t * p_a52dec);
/* Parse a syncinfo structure */
int sync_frame (a52dec_t * p_a52dec, sync_info_t * p_sync_info)
{
p_a52dec->total_bits_read = 0;
p_a52dec->i_available = 0;
/* sync word - should be 0x0b77 */
RealignBits(&p_a52dec->bit_stream);
while( (ShowBits (&p_a52dec->bit_stream,16)) != 0x0b77 &&
(!p_a52dec->p_fifo->b_die) && (!p_a52dec->p_fifo->b_error))
{
RemoveBits (&p_a52dec->bit_stream,8);
p_a52dec->total_bits_read += 8;
}
RemoveBits (&p_a52dec->bit_stream,16);
p_a52dec->total_bits_read += 16;
/* Get crc1 - we don't actually use this data though */
GetBits (&p_a52dec->bit_stream,16);
/* Get the sampling rate */
p_a52dec->syncinfo.fscod = GetBits (&p_a52dec->bit_stream,2);
if (p_a52dec->syncinfo.fscod >= 3)
{
p_a52dec->total_bits_read += 34;
return 1;
}
/* Get the frame size code */
p_a52dec->syncinfo.frmsizecod = GetBits (&p_a52dec->bit_stream,6);
p_a52dec->total_bits_read += 40;
if (p_a52dec->syncinfo.frmsizecod >= 38)
{
return 1;
}
p_sync_info->bit_rate = frmsizecod_tbl[p_a52dec->syncinfo.frmsizecod].bit_rate;
p_a52dec->syncinfo.frame_size = frmsizecod_tbl[p_a52dec->syncinfo.frmsizecod].frm_size[p_a52dec->syncinfo.fscod];
p_sync_info->frame_size = 2 * p_a52dec->syncinfo.frame_size;
p_sync_info->sample_rate = fscod_tbl[p_a52dec->syncinfo.fscod];
return 0;
}
/*
* This routine fills a bsi struct from the A52 stream
*/
int parse_bsi (a52dec_t * p_a52dec)
{
/* Check the AC-3 version number */
p_a52dec->bsi.bsid = GetBits (&p_a52dec->bit_stream,5);
if (p_a52dec->bsi.bsid > 8)
{
return 1;
}
/* Get the audio service provided by the stream */
p_a52dec->bsi.bsmod = GetBits (&p_a52dec->bit_stream,3);
/* Get the audio coding mode (ie how many channels)*/
p_a52dec->bsi.acmod = GetBits (&p_a52dec->bit_stream,3);
/* Predecode the number of full bandwidth channels as we use this
* number a lot */
p_a52dec->bsi.nfchans = nfchans[p_a52dec->bsi.acmod];
/* If it is in use, get the centre channel mix level */
if ((p_a52dec->bsi.acmod & 0x1) && (p_a52dec->bsi.acmod != 0x1))
{
p_a52dec->bsi.cmixlev = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->total_bits_read += 2;
}
/* If it is in use, get the surround channel mix level */
if (p_a52dec->bsi.acmod & 0x4)
{
p_a52dec->bsi.surmixlev = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->total_bits_read += 2;
}
/* Get the dolby surround mode if in 2/0 mode */
if (p_a52dec->bsi.acmod == 0x2)
{
p_a52dec->bsi.dsurmod = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->total_bits_read += 2;
}
/* Is the low frequency effects channel on? */
p_a52dec->bsi.lfeon = GetBits (&p_a52dec->bit_stream,1);
/* Get the dialogue normalization level */
p_a52dec->bsi.dialnorm = GetBits (&p_a52dec->bit_stream,5);
/* Does compression gain exist? */
if ((p_a52dec->bsi.compre = GetBits (&p_a52dec->bit_stream,1)))
{
/* Get compression gain */
p_a52dec->bsi.compr = GetBits (&p_a52dec->bit_stream,8);
p_a52dec->total_bits_read += 8;
}
/* Does language code exist? */
if ((p_a52dec->bsi.langcode = GetBits (&p_a52dec->bit_stream,1)))
{
/* Get langauge code */
p_a52dec->bsi.langcod = GetBits (&p_a52dec->bit_stream,8);
p_a52dec->total_bits_read += 8;
}
/* Does audio production info exist? */
if ((p_a52dec->bsi.audprodie = GetBits (&p_a52dec->bit_stream,1)))
{
/* Get mix level */
p_a52dec->bsi.mixlevel = GetBits (&p_a52dec->bit_stream,5);
/* Get room type */
p_a52dec->bsi.roomtyp = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->total_bits_read += 7;
}
/* If we're in dual mono mode then get some extra info */
if (p_a52dec->bsi.acmod == 0)
{
/* Get the dialogue normalization level two */
p_a52dec->bsi.dialnorm2 = GetBits (&p_a52dec->bit_stream,5);
/* Does compression gain two exist? */
if ((p_a52dec->bsi.compr2e = GetBits (&p_a52dec->bit_stream,1)))
{
/* Get compression gain two */
p_a52dec->bsi.compr2 = GetBits (&p_a52dec->bit_stream,8);
p_a52dec->total_bits_read += 8;
}
/* Does language code two exist? */
if ((p_a52dec->bsi.langcod2e = GetBits (&p_a52dec->bit_stream,1)))
{
/* Get langauge code two */
p_a52dec->bsi.langcod2 = GetBits (&p_a52dec->bit_stream,8);
p_a52dec->total_bits_read += 8;
}
/* Does audio production info two exist? */
if ((p_a52dec->bsi.audprodi2e = GetBits (&p_a52dec->bit_stream,1)))
{
/* Get mix level two */
p_a52dec->bsi.mixlevel2 = GetBits (&p_a52dec->bit_stream,5);
/* Get room type two */
p_a52dec->bsi.roomtyp2 = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->total_bits_read += 7;
}
p_a52dec->total_bits_read += 8;
}
/* Get the copyright bit */
p_a52dec->bsi.copyrightb = GetBits (&p_a52dec->bit_stream,1);
/* Get the original bit */
p_a52dec->bsi.origbs = GetBits (&p_a52dec->bit_stream,1);
/* Does timecode one exist? */
if ((p_a52dec->bsi.timecod1e = GetBits (&p_a52dec->bit_stream,1)))
{
p_a52dec->bsi.timecod1 = GetBits (&p_a52dec->bit_stream,14);
p_a52dec->total_bits_read += 14;
}
/* Does timecode two exist? */
if ((p_a52dec->bsi.timecod2e = GetBits (&p_a52dec->bit_stream,1)))
{
p_a52dec->bsi.timecod2 = GetBits (&p_a52dec->bit_stream,14);
p_a52dec->total_bits_read += 14;
}
/* Does addition info exist? */
if ((p_a52dec->bsi.addbsie = GetBits (&p_a52dec->bit_stream,1)))
{
u32 i;
/* Get how much info is there */
p_a52dec->bsi.addbsil = GetBits (&p_a52dec->bit_stream,6);
/* Get the additional info */
for (i=0;i<(p_a52dec->bsi.addbsil + 1);i++)
{
p_a52dec->bsi.addbsi[i] = GetBits (&p_a52dec->bit_stream,8);
}
p_a52dec->total_bits_read += 6 + 8 * (p_a52dec->bsi.addbsil + 1);
}
p_a52dec->total_bits_read += 25;
parse_bsi_stats (p_a52dec);
return 0;
}
/* More pain inducing parsing */
int parse_audblk (a52dec_t * p_a52dec, int blknum)
{
int i, j;
for (i=0; i < p_a52dec->bsi.nfchans; i++)
{
/* Is this channel an interleaved 256 + 256 block ? */
p_a52dec->audblk.blksw[i] = GetBits (&p_a52dec->bit_stream,1);
}
for (i=0; i < p_a52dec->bsi.nfchans; i++)
{
/* Should we dither this channel? */
p_a52dec->audblk.dithflag[i] = GetBits (&p_a52dec->bit_stream,1);
}
/* Does dynamic range control exist? */
if ((p_a52dec->audblk.dynrnge = GetBits (&p_a52dec->bit_stream,1)))
{
/* Get dynamic range info */
p_a52dec->audblk.dynrng = GetBits (&p_a52dec->bit_stream,8);
p_a52dec->total_bits_read += 8;
}
/* If we're in dual mono mode then get the second channel DR info */
if (p_a52dec->bsi.acmod == 0)
{
/* Does dynamic range control two exist? */
if ((p_a52dec->audblk.dynrng2e = GetBits (&p_a52dec->bit_stream,1)))
{
/* Get dynamic range info */
p_a52dec->audblk.dynrng2 = GetBits (&p_a52dec->bit_stream,8);
p_a52dec->total_bits_read += 8;
}
p_a52dec->total_bits_read += 1;
}
/* Does coupling strategy exist? */
p_a52dec->audblk.cplstre = GetBits (&p_a52dec->bit_stream,1);
p_a52dec->total_bits_read += 2 + 2 * p_a52dec->bsi.nfchans;
if ((!blknum) && (!p_a52dec->audblk.cplstre))
{
return 1;
}
if (p_a52dec->audblk.cplstre)
{
/* Is coupling turned on? */
if ((p_a52dec->audblk.cplinu = GetBits (&p_a52dec->bit_stream,1)))
{
int nb_coupled_channels;
nb_coupled_channels = 0;
for (i=0; i < p_a52dec->bsi.nfchans; i++)
{
p_a52dec->audblk.chincpl[i] = GetBits (&p_a52dec->bit_stream,1);
if (p_a52dec->audblk.chincpl[i])
{
nb_coupled_channels++;
}
}
p_a52dec->total_bits_read += p_a52dec->bsi.nfchans;
if (nb_coupled_channels < 2)
{
return 1;
}
if (p_a52dec->bsi.acmod == 0x2)
{
p_a52dec->audblk.phsflginu = GetBits (&p_a52dec->bit_stream,1);
p_a52dec->total_bits_read += 1;
}
p_a52dec->audblk.cplbegf = GetBits (&p_a52dec->bit_stream,4);
p_a52dec->audblk.cplendf = GetBits (&p_a52dec->bit_stream,4);
p_a52dec->total_bits_read += 8;
if (p_a52dec->audblk.cplbegf > p_a52dec->audblk.cplendf + 2)
{
return 1;
}
p_a52dec->audblk.ncplsubnd = (p_a52dec->audblk.cplendf + 2) - p_a52dec->audblk.cplbegf + 1;
/* Calculate the start and end bins of the coupling channel */
p_a52dec->audblk.cplstrtmant = (p_a52dec->audblk.cplbegf * 12) + 37 ;
p_a52dec->audblk.cplendmant = ((p_a52dec->audblk.cplendf + 3) * 12) + 37;
/* The number of combined subbands is ncplsubnd minus each combined
* band */
p_a52dec->audblk.ncplbnd = p_a52dec->audblk.ncplsubnd;
for (i=1; i< p_a52dec->audblk.ncplsubnd; i++)
{
p_a52dec->audblk.cplbndstrc[i] = GetBits (&p_a52dec->bit_stream,1);
p_a52dec->audblk.ncplbnd -= p_a52dec->audblk.cplbndstrc[i];
}
p_a52dec->total_bits_read += p_a52dec->audblk.ncplsubnd - 1;
}
p_a52dec->total_bits_read += 1;
}
if (p_a52dec->audblk.cplinu)
{
/* Loop through all the channels and get their coupling co-ords */
for (i=0; i < p_a52dec->bsi.nfchans;i++)
{
if (!p_a52dec->audblk.chincpl[i])
{
continue;
}
/* Is there new coupling co-ordinate info? */
p_a52dec->audblk.cplcoe[i] = GetBits (&p_a52dec->bit_stream,1);
if ((!blknum) && (!p_a52dec->audblk.cplcoe[i]))
{
return 1;
}
if (p_a52dec->audblk.cplcoe[i])
{
p_a52dec->audblk.mstrcplco[i] = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->total_bits_read += 2;
for (j=0;j < p_a52dec->audblk.ncplbnd; j++)
{
p_a52dec->audblk.cplcoexp[i][j] = GetBits (&p_a52dec->bit_stream,4);
p_a52dec->audblk.cplcomant[i][j] = GetBits (&p_a52dec->bit_stream,4);
}
p_a52dec->total_bits_read += 8 * p_a52dec->audblk.ncplbnd;
}
}
p_a52dec->total_bits_read += p_a52dec->bsi.nfchans;
/* If we're in dual mono mode, there's going to be some phase info */
if ((p_a52dec->bsi.acmod == 0x2) && p_a52dec->audblk.phsflginu &&
(p_a52dec->audblk.cplcoe[0] || p_a52dec->audblk.cplcoe[1]))
{
for (j=0; j < p_a52dec->audblk.ncplbnd; j++)
{
p_a52dec->audblk.phsflg[j] = GetBits (&p_a52dec->bit_stream,1);
}
p_a52dec->total_bits_read += p_a52dec->audblk.ncplbnd;
}
}
/* If we're in dual mono mode, there may be a rematrix strategy */
if (p_a52dec->bsi.acmod == 0x2)
{
p_a52dec->audblk.rematstr = GetBits (&p_a52dec->bit_stream,1);
p_a52dec->total_bits_read += 1;
if ((!blknum) && (!p_a52dec->audblk.rematstr))
{
return 1;
}
if (p_a52dec->audblk.rematstr)
{
if (p_a52dec->audblk.cplinu == 0)
{
for (i = 0; i < 4; i++)
{
p_a52dec->audblk.rematflg[i] = GetBits (&p_a52dec->bit_stream,1);
}
p_a52dec->total_bits_read += 4;
}
if ((p_a52dec->audblk.cplbegf > 2) && p_a52dec->audblk.cplinu)
{
for (i = 0; i < 4; i++)
{
p_a52dec->audblk.rematflg[i] = GetBits (&p_a52dec->bit_stream,1);
}
p_a52dec->total_bits_read += 4;
}
if ((p_a52dec->audblk.cplbegf <= 2) && p_a52dec->audblk.cplinu)
{
for (i = 0; i < 3; i++)
{
p_a52dec->audblk.rematflg[i] = GetBits (&p_a52dec->bit_stream,1);
}
p_a52dec->total_bits_read += 3;
}
if ((p_a52dec->audblk.cplbegf == 0) && p_a52dec->audblk.cplinu)
{
for (i = 0; i < 2; i++)
{
p_a52dec->audblk.rematflg[i] = GetBits (&p_a52dec->bit_stream,1);
}
p_a52dec->total_bits_read += 2;
}
}
}
if (p_a52dec->audblk.cplinu)
{
/* Get the coupling channel exponent strategy */
p_a52dec->audblk.cplexpstr = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->total_bits_read += 2;
if ((!blknum) && (p_a52dec->audblk.cplexpstr == EXP_REUSE))
{
return 1;
}
if (p_a52dec->audblk.cplexpstr==0)
{
p_a52dec->audblk.ncplgrps = 0;
}
else
{
p_a52dec->audblk.ncplgrps = (p_a52dec->audblk.cplendmant - p_a52dec->audblk.cplstrtmant) /
(3 << (p_a52dec->audblk.cplexpstr-1));
}
}
for (i = 0; i < p_a52dec->bsi.nfchans; i++)
{
p_a52dec->audblk.chexpstr[i] = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->total_bits_read += 2;
if ((!blknum) && (p_a52dec->audblk.chexpstr[i] == EXP_REUSE))
{
return 1;
}
}
/* Get the exponent strategy for lfe channel */
if (p_a52dec->bsi.lfeon)
{
p_a52dec->audblk.lfeexpstr = GetBits (&p_a52dec->bit_stream,1);
p_a52dec->total_bits_read += 1;
if ((!blknum) && (p_a52dec->audblk.lfeexpstr == EXP_REUSE))
{
return 1;
}
}
/* Determine the bandwidths of all the fbw channels */
for (i = 0; i < p_a52dec->bsi.nfchans; i++)
{
u16 grp_size;
if (p_a52dec->audblk.chexpstr[i] != EXP_REUSE)
{
if (p_a52dec->audblk.cplinu && p_a52dec->audblk.chincpl[i])
{
p_a52dec->audblk.endmant[i] = p_a52dec->audblk.cplstrtmant;
}
else
{
p_a52dec->audblk.chbwcod[i] = GetBits (&p_a52dec->bit_stream,6);
p_a52dec->total_bits_read += 6;
if (p_a52dec->audblk.chbwcod[i] > 60)
{
return 1;
}
p_a52dec->audblk.endmant[i] = ((p_a52dec->audblk.chbwcod[i] + 12) * 3) + 37;
}
/* Calculate the number of exponent groups to fetch */
grp_size = 3 * (1 << (p_a52dec->audblk.chexpstr[i] - 1));
p_a52dec->audblk.nchgrps[i] = (p_a52dec->audblk.endmant[i] - 1 + (grp_size - 3)) / grp_size;
}
}
/* Get the coupling exponents if they exist */
if (p_a52dec->audblk.cplinu && (p_a52dec->audblk.cplexpstr != EXP_REUSE))
{
p_a52dec->audblk.cplabsexp = GetBits (&p_a52dec->bit_stream,4);
p_a52dec->total_bits_read += 4;
for (i=0; i< p_a52dec->audblk.ncplgrps;i++)
{
p_a52dec->audblk.cplexps[i] = GetBits (&p_a52dec->bit_stream,7);
p_a52dec->total_bits_read += 7;
if (p_a52dec->audblk.cplexps[i] >= 125)
{
return 1;
}
}
}
/* Get the fwb channel exponents */
for (i=0; i < p_a52dec->bsi.nfchans; i++)
{
if (p_a52dec->audblk.chexpstr[i] != EXP_REUSE)
{
p_a52dec->audblk.exps[i][0] = GetBits (&p_a52dec->bit_stream,4);
p_a52dec->total_bits_read += 4;
for (j=1; j<=p_a52dec->audblk.nchgrps[i];j++)
{
p_a52dec->audblk.exps[i][j] = GetBits (&p_a52dec->bit_stream,7);
p_a52dec->total_bits_read += 7;
if (p_a52dec->audblk.exps[i][j] >= 125)
{
return 1;
}
}
p_a52dec->audblk.gainrng[i] = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->total_bits_read += 2;
}
}
/* Get the lfe channel exponents */
if (p_a52dec->bsi.lfeon && (p_a52dec->audblk.lfeexpstr != EXP_REUSE))
{
p_a52dec->audblk.lfeexps[0] = GetBits (&p_a52dec->bit_stream,4);
p_a52dec->audblk.lfeexps[1] = GetBits (&p_a52dec->bit_stream,7);
p_a52dec->total_bits_read += 11;
if (p_a52dec->audblk.lfeexps[1] >= 125)
{
return 1;
}
p_a52dec->audblk.lfeexps[2] = GetBits (&p_a52dec->bit_stream,7);
p_a52dec->total_bits_read += 7;
if (p_a52dec->audblk.lfeexps[2] >= 125)
{
return 1;
}
}
/* Get the parametric bit allocation parameters */
p_a52dec->audblk.baie = GetBits (&p_a52dec->bit_stream,1);
p_a52dec->total_bits_read += 1;
if ((!blknum) && (!p_a52dec->audblk.baie))
{
return 1;
}
if (p_a52dec->audblk.baie)
{
p_a52dec->audblk.sdcycod = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->audblk.fdcycod = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->audblk.sgaincod = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->audblk.dbpbcod = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->audblk.floorcod = GetBits (&p_a52dec->bit_stream,3);
p_a52dec->total_bits_read += 11;
}
/* Get the SNR off set info if it exists */
p_a52dec->audblk.snroffste = GetBits (&p_a52dec->bit_stream,1);
if ((!blknum) && (!p_a52dec->audblk.snroffste))
{
return 1;
}
if (p_a52dec->audblk.snroffste)
{
p_a52dec->audblk.csnroffst = GetBits (&p_a52dec->bit_stream,6);
p_a52dec->total_bits_read += 6;
if (p_a52dec->audblk.cplinu)
{
p_a52dec->audblk.cplfsnroffst = GetBits (&p_a52dec->bit_stream,4);
p_a52dec->audblk.cplfgaincod = GetBits (&p_a52dec->bit_stream,3);
p_a52dec->total_bits_read += 7;
}
for (i = 0;i < p_a52dec->bsi.nfchans; i++)
{
p_a52dec->audblk.fsnroffst[i] = GetBits (&p_a52dec->bit_stream,4);
p_a52dec->audblk.fgaincod[i] = GetBits (&p_a52dec->bit_stream,3);
}
p_a52dec->total_bits_read += 7 * p_a52dec->bsi.nfchans;
if (p_a52dec->bsi.lfeon)
{
p_a52dec->audblk.lfefsnroffst = GetBits (&p_a52dec->bit_stream,4);
p_a52dec->audblk.lfefgaincod = GetBits (&p_a52dec->bit_stream,3);
p_a52dec->total_bits_read += 7;
}
}
/* Get coupling leakage info if it exists */
if (p_a52dec->audblk.cplinu)
{
p_a52dec->audblk.cplleake = GetBits (&p_a52dec->bit_stream,1);
p_a52dec->total_bits_read += 1;
if ((!blknum) && (!p_a52dec->audblk.cplleake))
{
return 1;
}
if (p_a52dec->audblk.cplleake)
{
p_a52dec->audblk.cplfleak = GetBits (&p_a52dec->bit_stream,3);
p_a52dec->audblk.cplsleak = GetBits (&p_a52dec->bit_stream,3);
p_a52dec->total_bits_read += 6;
}
}
/* Get the delta bit alloaction info */
p_a52dec->audblk.deltbaie = GetBits (&p_a52dec->bit_stream,1);
p_a52dec->total_bits_read += 1;
if (p_a52dec->audblk.deltbaie)
{
if (p_a52dec->audblk.cplinu)
{
p_a52dec->audblk.cpldeltbae = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->total_bits_read += 2;
if (p_a52dec->audblk.cpldeltbae == 3)
{
return 1;
}
}
for (i = 0;i < p_a52dec->bsi.nfchans; i++)
{
p_a52dec->audblk.deltbae[i] = GetBits (&p_a52dec->bit_stream,2);
p_a52dec->total_bits_read += 2;
if (p_a52dec->audblk.deltbae[i] == 3)
{
return 1;
}
}
if (p_a52dec->audblk.cplinu && (p_a52dec->audblk.cpldeltbae == DELTA_BIT_NEW))
{
p_a52dec->audblk.cpldeltnseg = GetBits (&p_a52dec->bit_stream,3);
for (i = 0;i < p_a52dec->audblk.cpldeltnseg + 1; i++)
{
p_a52dec->audblk.cpldeltoffst[i] = GetBits (&p_a52dec->bit_stream,5);
p_a52dec->audblk.cpldeltlen[i] = GetBits (&p_a52dec->bit_stream,4);
p_a52dec->audblk.cpldeltba[i] = GetBits (&p_a52dec->bit_stream,3);
}
p_a52dec->total_bits_read += 12 * (p_a52dec->audblk.cpldeltnseg + 1) + 3;
}
for (i = 0; i < p_a52dec->bsi.nfchans; i++)
{
if (p_a52dec->audblk.deltbae[i] == DELTA_BIT_NEW)
{
p_a52dec->audblk.deltnseg[i] = GetBits (&p_a52dec->bit_stream,3);
#if 0
if (p_a52dec->audblk.deltnseg[i] >= 8)
fprintf (stderr, "parse debug: p_a52dec->audblk.deltnseg[%i] == %i\n", i, p_a52dec->audblk.deltnseg[i]);
#endif
for (j = 0; j < p_a52dec->audblk.deltnseg[i] + 1; j++)
{
p_a52dec->audblk.deltoffst[i][j] = GetBits (&p_a52dec->bit_stream,5);
p_a52dec->audblk.deltlen[i][j] = GetBits (&p_a52dec->bit_stream,4);
p_a52dec->audblk.deltba[i][j] = GetBits (&p_a52dec->bit_stream,3);
}
p_a52dec->total_bits_read += 12 * (p_a52dec->audblk.deltnseg[i] + 1) + 3;
}
}
}
/* Check to see if there's any dummy info to get */
p_a52dec->audblk.skiple = GetBits (&p_a52dec->bit_stream,1);
p_a52dec->total_bits_read += 1;
if (p_a52dec->audblk.skiple)
{
p_a52dec->audblk.skipl = GetBits (&p_a52dec->bit_stream,9);
for (i = 0; i < p_a52dec->audblk.skipl ; i++)
{
GetBits (&p_a52dec->bit_stream,8);
}
p_a52dec->total_bits_read += 8 * p_a52dec->audblk.skipl + 9;
}
parse_audblk_stats(p_a52dec);
return 0;
}
void parse_auxdata (a52dec_t * p_a52dec)
{
int i;
int skip_length;
skip_length = (p_a52dec->syncinfo.frame_size * 16) - p_a52dec->total_bits_read - 17 - 1;
for (i = 0; i < skip_length; i++)
{
RemoveBits (&p_a52dec->bit_stream,1);
}
/* get the auxdata exists bit */
RemoveBits (&p_a52dec->bit_stream,1);
/* Skip the CRC reserved bit */
RemoveBits (&p_a52dec->bit_stream,1);
/* Get the crc */
RemoveBits (&p_a52dec->bit_stream,16);
}
static void parse_bsi_stats (a52dec_t * p_a52dec) /* Some stats */
{
#if 0
struct mixlev_s
{
float clev;
char *desc;
};
static const char *service_ids[8] =
{
"CM","ME","VI","HI",
"D", "C","E", "VO"
};
/*
static const struct mixlev_s cmixlev_tbl[4] =
{
{0.707, "(-3.0 dB)"}, {0.595, "(-4.5 dB)"},
{0.500, "(-6.0 dB)"}, {1.0, "Invalid"}
};
static const struct mixlev_s smixlev_tbl[4] =
{
{0.707, "(-3.0 dB)"}, {0.500, "(-6.0 dB)"},
{ 0.0, "off "}, { 1.0, "Invalid"}
};
*/
static int i=0;
if ( !i )
{
/* if ((p_a52dec->bsi.acmod & 0x1) && (p_a52dec->bsi.acmod != 0x1))
printf("CentreMixLevel %s ",cmixlev_tbl[p_a52dec->bsi.cmixlev].desc);
if (p_a52dec->bsi.acmod & 0x4)
printf("SurMixLevel %s",smixlev_tbl[p_a52dec->bsi.cmixlev].desc);
*/
intf_Msg ( "(a52dec_parsebsi) %s %d.%d Mode",
service_ids[p_a52dec->bsi.bsmod],
p_a52dec->bsi.nfchans,p_a52dec->bsi.lfeon);
}
i++;
if ( i > 100 )
i = 0;
#endif
}
static void parse_audblk_stats (a52dec_t * p_a52dec)
{
#if 0
char *exp_strat_tbl[4] = {"R ","D15 ","D25 ","D45 "};
u32 i;
intf_ErrMsg ("(a52dec_parseaudblk) ");
intf_ErrMsg ("%s ",p_a52dec->audblk.cplinu ? "cpl on" : "cpl off");
intf_ErrMsg ("%s ",p_a52dec->audblk.baie? "bai" : " ");
intf_ErrMsg ("%s ",p_a52dec->audblk.snroffste? "snroffst" : " ");
intf_ErrMsg ("%s ",p_a52dec->audblk.deltbaie? "deltba" : " ");
intf_ErrMsg ("%s ",p_a52dec->audblk.phsflginu? "phsflg" : " ");
intf_ErrMsg ("(%s %s %s %s %s) ",exp_strat_tbl[p_a52dec->audblk.chexpstr[0]],
exp_strat_tbl[p_a52dec->audblk.chexpstr[1]],exp_strat_tbl[p_a52dec->audblk.chexpstr[2]],
exp_strat_tbl[p_a52dec->audblk.chexpstr[3]],exp_strat_tbl[p_a52dec->audblk.chexpstr[4]]);
intf_ErrMsg ("[");
for(i=0;i<p_a52dec->bsi.nfchans;i++)
intf_ErrMsg ("%1d",p_a52dec->audblk.blksw[i]);
intf_ErrMsg ("]");
#endif
}