📄 parse.c
字号:
/*
* parse.c
*
* Copyright (C) Aaron Holtzman - May 1999
*
* This file is part of ac3dec, a free Dolby AC-3 stream decoder.
*
* ac3dec 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, or (at your option)
* any later version.
*
* ac3dec 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
#include <stdlib.h>
#include <stdio.h>
#include "ac3.h"
#include "ac3_internal.h"
#include "bitstream.h"
#include "stats.h"
#include "debug.h"
#include "crc.h"
#include "parse.h"
/* Misc LUT */
static const uint_16 nfchans[8] = {2,1,2,3,3,4,4,5};
struct frmsize_s
{
uint_16 bit_rate;
uint_16 frm_size[3];
};
static const struct frmsize_s frmsizecod_tbl[64] =
{
{ 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 } }
};
/* Parse a syncinfo structure, minus the sync word */
void
parse_syncinfo(syncinfo_t *syncinfo)
{
uint_32 tmp = 0;
uint_16 sync_word = 0;
uint_32 time_out = 1<<16;
//
// Find a ac3 sync frame. Time out if we read 64k without finding
// one.
//
while(time_out--)
{
sync_word = (sync_word << 8) + bitstream_get_byte();
if(sync_word == 0x0b77)
break;
}
//
// We need to read in the entire syncinfo struct (0x0b77 + 24 bits)
// in order to determine how big the frame is
//
tmp = (tmp << 8) + bitstream_get_byte();
tmp = (tmp << 8) + bitstream_get_byte();
tmp = (tmp << 8) + bitstream_get_byte();
// Get the sampling rate
syncinfo->fscod = (tmp >> 6) & 0x3;
if(syncinfo->fscod == 3)
{
//invalid sampling rate code
error_flag = 1;
return;
}
else if(syncinfo->fscod == 2)
syncinfo->sampling_rate = 32000;
else if(syncinfo->fscod == 1)
syncinfo->sampling_rate = 44100;
else
syncinfo->sampling_rate = 48000;
// Get the frame size code
syncinfo->frmsizecod = tmp & 0x3f;
// Calculate the frame size and bitrate
syncinfo->frame_size =
frmsizecod_tbl[syncinfo->frmsizecod].frm_size[syncinfo->fscod];
syncinfo->bit_rate = frmsizecod_tbl[syncinfo->frmsizecod].bit_rate;
// Buffer the entire syncframe
bitstream_buffer_frame(syncinfo->frame_size * 2 - 5);
// Check the crc over the entire frame
crc_init();
crc_process_byte(tmp>>16);
crc_process_byte((tmp>>8) & 0xff);
crc_process_byte(tmp & 0xff);
crc_process_frame(bitstream_get_buffer_start(),syncinfo->frame_size * 2 - 5);
if(!crc_validate())
{
error_flag = 1;
fprintf(stderr,"** CRC failed - skipping frame **\n");
return;
}
stats_print_syncinfo(syncinfo);
}
/*
* This routine fills a bsi struct from the AC3 stream
*/
void
parse_bsi(bsi_t *bsi)
{
uint_32 i;
/* Check the AC-3 version number */
bsi->bsid = bitstream_get(5);
/* Get the audio service provided by the steram */
bsi->bsmod = bitstream_get(3);
/* Get the audio coding mode (ie how many channels)*/
bsi->acmod = bitstream_get(3);
/* Predecode the number of full bandwidth channels as we use this
* number a lot */
bsi->nfchans = nfchans[bsi->acmod];
/* If it is in use, get the centre channel mix level */
if ((bsi->acmod & 0x1) && (bsi->acmod != 0x1))
bsi->cmixlev = bitstream_get(2);
/* If it is in use, get the surround channel mix level */
if (bsi->acmod & 0x4)
bsi->surmixlev = bitstream_get(2);
/* Get the dolby surround mode if in 2/0 mode */
if(bsi->acmod == 0x2)
bsi->dsurmod= bitstream_get(2);
/* Is the low frequency effects channel on? */
bsi->lfeon = bitstream_get(1);
/* Get the dialogue normalization level */
bsi->dialnorm = bitstream_get(5);
/* Does compression gain exist? */
bsi->compre = bitstream_get(1);
if (bsi->compre)
{
/* Get compression gain */
bsi->compr = bitstream_get(8);
}
/* Does language code exist? */
bsi->langcode = bitstream_get(1);
if (bsi->langcode)
{
/* Get langauge code */
bsi->langcod = bitstream_get(8);
}
/* Does audio production info exist? */
bsi->audprodie = bitstream_get(1);
if (bsi->audprodie)
{
/* Get mix level */
bsi->mixlevel = bitstream_get(5);
/* Get room type */
bsi->roomtyp = bitstream_get(2);
}
/* If we're in dual mono mode then get some extra info */
if (bsi->acmod ==0)
{
/* Get the dialogue normalization level two */
bsi->dialnorm2 = bitstream_get(5);
/* Does compression gain two exist? */
bsi->compr2e = bitstream_get(1);
if (bsi->compr2e)
{
/* Get compression gain two */
bsi->compr2 = bitstream_get(8);
}
/* Does language code two exist? */
bsi->langcod2e = bitstream_get(1);
if (bsi->langcod2e)
{
/* Get langauge code two */
bsi->langcod2 = bitstream_get(8);
}
/* Does audio production info two exist? */
bsi->audprodi2e = bitstream_get(1);
if (bsi->audprodi2e)
{
/* Get mix level two */
bsi->mixlevel2 = bitstream_get(5);
/* Get room type two */
bsi->roomtyp2 = bitstream_get(2);
}
}
/* Get the copyright bit */
bsi->copyrightb = bitstream_get(1);
/* Get the original bit */
bsi->origbs = bitstream_get(1);
/* Does timecode one exist? */
bsi->timecod1e = bitstream_get(1);
if(bsi->timecod1e)
bsi->timecod1 = bitstream_get(14);
/* Does timecode two exist? */
bsi->timecod2e = bitstream_get(1);
if(bsi->timecod2e)
bsi->timecod2 = bitstream_get(14);
/* Does addition info exist? */
bsi->addbsie = bitstream_get(1);
if(bsi->addbsie)
{
/* Get how much info is there */
bsi->addbsil = bitstream_get(6);
/* Get the additional info */
for(i=0;i<(bsi->addbsil + 1);i++)
bsi->addbsi[i] = bitstream_get(8);
}
stats_print_bsi(bsi);
}
/* More pain inducing parsing */
void
parse_audblk(bsi_t *bsi,audblk_t *audblk)
{
int i,j;
for (i=0;i < bsi->nfchans; i++)
{
/* Is this channel an interleaved 256 + 256 block ? */
audblk->blksw[i] = bitstream_get(1);
}
for (i=0;i < bsi->nfchans; i++)
{
/* Should we dither this channel? */
audblk->dithflag[i] = bitstream_get(1);
}
/* Does dynamic range control exist? */
audblk->dynrnge = bitstream_get(1);
if (audblk->dynrnge)
{
/* Get dynamic range info */
audblk->dynrng = bitstream_get(8);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -