📄 tta.c
字号:
rice->sum1 = shift_16[k1];
}
static const int flt_set[3] = {10, 9, 10};
static void filter_init (fltst *fs, int shift) {
memset (fs, 0, sizeof(fltst));
fs->shift = shift;
fs->round = 1 << (shift - 1);
}
static __inline void memshl (register int *pA, register int *pB) {
*pA++ = *pB++;
*pA++ = *pB++;
*pA++ = *pB++;
*pA++ = *pB++;
*pA++ = *pB++;
*pA++ = *pB++;
*pA++ = *pB++;
*pA = *pB;
}
static __inline void hybrid_filter (fltst *fs, int *in) {
register int *pA = fs->dl;
register int *pB = fs->qm;
register int *pM = fs->dx;
register int sum = fs->round;
if (!fs->error) {
sum += *pA++ * *pB, pB++;
sum += *pA++ * *pB, pB++;
sum += *pA++ * *pB, pB++;
sum += *pA++ * *pB, pB++;
sum += *pA++ * *pB, pB++;
sum += *pA++ * *pB, pB++;
sum += *pA++ * *pB, pB++;
sum += *pA++ * *pB, pB++; pM += 8;
} else if (fs->error < 0) {
sum += *pA++ * (*pB -= *pM++), pB++;
sum += *pA++ * (*pB -= *pM++), pB++;
sum += *pA++ * (*pB -= *pM++), pB++;
sum += *pA++ * (*pB -= *pM++), pB++;
sum += *pA++ * (*pB -= *pM++), pB++;
sum += *pA++ * (*pB -= *pM++), pB++;
sum += *pA++ * (*pB -= *pM++), pB++;
sum += *pA++ * (*pB -= *pM++), pB++;
} else {
sum += *pA++ * (*pB += *pM++), pB++;
sum += *pA++ * (*pB += *pM++), pB++;
sum += *pA++ * (*pB += *pM++), pB++;
sum += *pA++ * (*pB += *pM++), pB++;
sum += *pA++ * (*pB += *pM++), pB++;
sum += *pA++ * (*pB += *pM++), pB++;
sum += *pA++ * (*pB += *pM++), pB++;
sum += *pA++ * (*pB += *pM++), pB++;
}
*(pM-0) = ((*(pA-1) >> 30) | 1) << 2;
*(pM-1) = ((*(pA-2) >> 30) | 1) << 1;
*(pM-2) = ((*(pA-3) >> 30) | 1) << 1;
*(pM-3) = ((*(pA-4) >> 30) | 1);
fs->error = *in;
*in += (sum >> fs->shift);
*pA = *in;
*(pA-1) = *(pA-0) - *(pA-1);
*(pA-2) = *(pA-1) - *(pA-2);
*(pA-3) = *(pA-2) - *(pA-3);
memshl (fs->dl, fs->dl + 1);
memshl (fs->dx, fs->dx + 1);
}
static void decoder_init(decoder *tta, int nch, int byte_size) {
int shift = flt_set[byte_size - 1];
int i;
for (i = 0; i < nch; i++) {
filter_init(&tta[i].fst, shift);
rice_init(&tta[i].rice, 10, 10);
tta[i].last = 0;
}
}
static int set_position (TTAstate *s,unsigned int pos) {
/*
unsigned int seek_pos;
if (pos >= fframes) return 0;
if (!st_state) {
ttainfo->STATE = FILE_ERROR;
return -1;
}
seek_pos = ttainfo->DATAPOS + seek_table[data_pos = pos];
if (fseek(ttainfo->HANDLE, seek_pos, SEEK_SET) < 0) {
ttainfo->STATE = READ_ERROR;
return -1;
}
*/
s->data_cur = 0;
s->framelen = 0;
// init bit reader
init_buffer_read(s);
return 0;
}
#define PREDICTOR1(x, k) ((int)((((uint64_t)x << k) - x) >> k))
#define DEC(x) (((x)&1)?(++(x)>>1):(-(x)>>1))
static int tta_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
{
TTAstate *s = avctx->priv_data;
unsigned int k, depth, unary, binary;
uint8_t *p = data;
int value, res;
int *prev = s->cache;
decoder *dec = s->tta;
s->src=buf;s->srcsize=buf_size;s->readsize=0;
for (res = 0; p < (uint8_t*)data + s->pcm_buffer_size;) {
fltst *fst = &dec->fst;
adapt *rice = &dec->rice;
int *last = &dec->last;
if (s->data_cur == s->framelen) {
//if (data_pos == fframes) break;
if (s->framelen && done_buffer_read(s)) {
if (set_position(s,s->data_pos))
return -1;
if (res)
break;
}
/*if (s->data_pos == fframes - 1 && lastlen)
framelen = lastlen;
else*/ s->framelen = s->FRAMELEN;
decoder_init(s->tta, avctx->channels, avctx->bits_per_sample>>3);
s->data_pos++; s->data_cur = 0;
}
// decode Rice unsigned
//GET_UNARY(unary);
unary = 0;
while (!(s->bit_cache ^ bit_mask[s->bit_count])) {
if (s->bitpos == s->iso_buffers_end) {
if (!read(s,s->isobuffers, 1, ISO_BUFFERS_SIZE)) {
s->STATE = READ_ERROR;
return -1; }
s->bitpos = s->isobuffers; }
unary += s->bit_count;
s->bit_cache = *s->bitpos++;
UPDATE_CRC32(s->bit_cache, s->frame_crc32);
s->bit_count = 8; }
while (s->bit_cache & 1) {
unary++;
s->bit_cache >>= 1;
s->bit_count--; }
s->bit_cache >>= 1;
s->bit_count--;
switch (unary) {
case 0: depth = 0; k = rice->k0; break;
default:
depth = 1; k = rice->k1;
unary--;
}
if (k) {
// GET_BINARY(binary, k);
while (s->bit_count < k) {
if (s->bitpos == s->iso_buffers_end) {
if (!read(s,s->isobuffers, 1, ISO_BUFFERS_SIZE)) {
s->STATE = READ_ERROR;
return -1; }
s->bitpos = s->isobuffers; }
UPDATE_CRC32(*s->bitpos, s->frame_crc32);
s->bit_cache |= *s->bitpos << s->bit_count;
s->bit_count += 8;
s->bitpos++; }
binary = s->bit_cache & bit_mask[k];
s->bit_cache >>= k;
s->bit_count -= k;
s->bit_cache &= bit_mask[s->bit_count];
value = (unary << k) + binary;
} else value = unary;
switch (depth) {
case 1:
rice->sum1 += value - (rice->sum1 >> 4);
if (rice->k1 > 0 && rice->sum1 < shift_16[rice->k1])
rice->k1--;
else if (rice->sum1 > shift_16[rice->k1 + 1])
rice->k1++;
value += bit_shift[rice->k0];
default:
rice->sum0 += value - (rice->sum0 >> 4);
if (rice->k0 > 0 && rice->sum0 < shift_16[rice->k0])
rice->k0--;
else if (rice->sum0 > shift_16[rice->k0 + 1])
rice->k0++;
}
value = DEC(value);
// decompress stage 1: adaptive hybrid filter
hybrid_filter(fst, &value);
// decompress stage 2: fixed order 1 prediction
switch (avctx->bits_per_sample>>3) {
case 1: value += PREDICTOR1(*last, 4); break; // bps 8
case 2: value += PREDICTOR1(*last, 5); break; // bps 16
case 3: value += PREDICTOR1(*last, 5); break; // bps 24
} *last = value;
// check for errors
if (FFABS(value) > s->maxvalue) {
unsigned int tail =
s->pcm_buffer_size / ((avctx->bits_per_sample>>3)* avctx->channels) - res;
memset(data, 0, s->pcm_buffer_size);
s->data_cur += tail; res += tail;
break;
}
if (dec < s->tta + (avctx->channels - 1)) {
*prev++ = value; dec++;
} else {
*prev = value;
if (avctx->channels > 1) {
int *r = prev - 1;
for (*prev += *r/2; r >= s->cache; r--)
*r = *(r + 1) - *r;
for (r = s->cache; r < prev; r++)
WRITE_BUFFER(r, (avctx->bits_per_sample>>3), p)
}
WRITE_BUFFER(prev, (avctx->bits_per_sample>>3), p)
prev = s->cache;
s->data_cur++; res++;
dec = s->tta;
}
}
*data_size=res*avctx->channels*(avctx->bits_per_sample>>3);
return s->readsize; //buf_size-s->srcsize;
}
static void tta_flush(AVCodecContext *avctx)
{
TTAstate *s = avctx->priv_data;
set_position(s,0);
}
AVCodec tta_decoder = {
"tta",
CODEC_TYPE_AUDIO,
CODEC_ID_TTA,
sizeof(TTAstate),
tta_decode_init,
NULL,
NULL,
tta_decode_frame,
0,
NULL,
tta_flush
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -