/*
* FLAC (Free Lossless Audio Codec) decoder
* @author Alex Beregszaszi
*
* For more information on the FLAC format, visit:
* http://flac.sourceforge.net/
*
* This decoder can be used in 1 of 2 ways: Either raw FLAC data can be fed
* through, starting from the initial 'fLaC' signature; or by passing the
* 34-byte streaminfo structure through avctx->extradata[_size] followed
* by data starting with the 0xFFF8 marker.
*/
#include <limits.h>
#include <stdio.h>
#include <assert.h>
#include "flacdec.h"
#define AV_RB8(x) (((const unsigned char*)(x))[0])
#define AV_RB32(x) \
(((unsigned int)((const unsigned char*)(x))[0] << 24) | \
(((const unsigned char*)(x))[1] << 16) | \
(((const unsigned char*)(x))[2] << 8) | \
((const unsigned char*)(x))[3])
#define AV_RB24(x) \
((((const unsigned char*)(x))[0] << 16) | \
(((const unsigned char*)(x))[1] << 8) | \
((const unsigned char*)(x))[2])
#define AV_RL32(x) \
(((unsigned int)((const unsigned char*)(x))[3] << 24) | \
(((const unsigned char*)(x))[2] << 16) | \
(((const unsigned char*)(x))[1] << 8) | \
((const unsigned char*)(x))[0])
static void allocate_buffers(FLACContext *s);
static const int sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 };
const int ff_flac_sample_rate_table[16] =
{ 0,
88200, 176400, 192000,
8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
0, 0, 0, 0 };
const int ff_flac_blocksize_table[16] = {
0, 192, 576<<0, 576<<1, 576<<2, 576<<3, 0, 0,
256<<0, 256<<1, 256<<2, 256<<3, 256<<4, 256<<5, 256<<6, 256<<7
};
static const unsigned char table_crc8[256] = {
0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,
0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3
};
int my_bui_clz(unsigned int a)
{
int i;
unsigned int tmp_index = 1 << 31;
if(a == 0)
return 31;
for(i=0;i<32;i++)
{
if((a & tmp_index)==tmp_index)
return i;
else tmp_index = tmp_index >> 1;
}
}
static long long int get_utf8(GetBitContext *gb)
{
long long int val;
GET_UTF8(val, get_bits(gb, 8), return -1;)
return val;
}
static void dump_headers(AVCodecContext *avctx, FLACStreaminfo *s)
{
printf("Max Blocksize: %d\n", s->max_blocksize);
printf("Max Framesize: %d\n", s->max_framesize);
printf("Samplerate: %d\n", s->samplerate);
printf("Channels: %d\n", s->channels);
printf("Bits: %d\n", s->bps);
}
void ff_flac_parse_streaminfo(AVCodecContext *avctx, FLACStreaminfo *s,const unsigned char *buffer)
{
GetBitContext gb;
init_get_bits(&gb, buffer, FLAC_STREAMINFO_SIZE*8);
skip_bits(&gb, 16); /* skip min blocksize */
s->max_blocksize = get_bits(&gb, 16);
if (s->max_blocksize < FLAC_MIN_BLOCKSIZE) {
printf("AV_LOG_WARNING : invalid max blocksize: %d\n",s->max_blocksize);
s->max_blocksize = 16;
}
skip_bits(&gb, 24); /* skip min frame size */
s->max_framesize = get_bits_long(&gb, 24);
s->samplerate = get_bits_long(&gb, 20);
s->channels = get_bits(&gb, 3) + 1;
s->bps = get_bits(&gb, 5) + 1;
avctx->channels = s->channels;
avctx->sample_rate = s->samplerate;
avctx->bits_per_raw_sample = s->bps;
s->samples = get_bits_long(&gb, 32) << 4;
s->samples |= get_bits(&gb, 4);
skip_bits_long(&gb, 64); /* md5 sum */
skip_bits_long(&gb, 64); /* md5 sum */
dump_headers(avctx, s);
}
int ff_flac_get_max_frame_size(int blocksize, int ch, int bps)
{
/* Technically, there is no limit to FLAC frame size, but an encoder
should not write a frame that is larger than if verbatim encoding mode
were to be used. */
int count;
count = 16; /* frame header */
count += ch * ((7+bps+7)/8); /* subframe headers */
if (ch == 2) {
/* for stereo, need to account for using decorrelation */
count += (( 2*bps+1) * blocksize + 7) / 8;
} else {
count += ( ch*bps * blocksize + 7) / 8;
}
count += 2; /* frame footer */
return count;
}
int ff_flac_is_extradata_valid(AVCodecContext *avctx,
enum FLACExtradataFormat *format,
unsigned char **streaminfo_start)
{
if (!avctx->extradata || avctx->extradata_size < FLAC_STREAMINFO_SIZE) {
printf("extradata NULL or too small.\n");
return 0;
}
if (AV_RL32(avctx->extradata) != MKTAG('f','L','a','C')) {
/** extradata contains STREAMINFO only */
if (avctx->extradata_size != FLAC_STREAMINFO_SIZE) {
printf("extradata contains bytes too many.\n");
}
*format = FLAC_EXTRADATA_FORMAT_STREAMINFO;
*streaminfo_start = avctx->extradata;
} else {
if (avctx->extradata_size < 8+FLAC_STREAMINFO_SIZE) {
printf("extradata too small.\n");
return 0;
}
*format = FLAC_EXTRADATA_FORMAT_FULL_HEADER;
*streaminfo_start = &avctx->extradata[8];
}
return 1;
}
int flac_decode_init(AVCodecContext *avctx)
{
enum FLACExtradataFormat format;
unsigned char *streaminfo;
FLACContext *s = avctx->priv_data;
s->avctx = avctx;
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
/** for now, the raw FLAC header is allowed to be passed to the decoder as
frame data instead of extradata. */
if (!avctx->extradata)
return 0;
printf("it is init\n");
if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo))
return -1;
/** initialize based on the demuxer-supplied streamdata header */
ff_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo);
if (s->bps > 16)
avctx->sample_fmt = AV_SAMPLE_FMT_S32;
else
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
allocate_buffers(s);
s->got_streaminfo = 1;
return 0;
}
static void allocate_buffers(FLACContext *s)
{
int i;
assert(s->max_blocksize);
for (i = 0; i < s->channels; i++) {
s->decoded[i] = malloc(sizeof(int)*s->max_blocksize);
}
}
static unsigned int bytestream_get_byte(const unsigned char **b)
{
(*b) += 1;
return AV_RB8(*b - 1);
}
static unsigned int bytestream_get_be24(const unsigned char **b)
{
(*b) += 3;
return AV_RB24(*b - 3);
}
void ff_flac_parse_block_header(const unsigned char *block_header,
int *last, int *type, int *size)
{
int tm