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
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
|
|
}
|
|
|
|
|