|
|
|
@ -48,20 +48,6 @@ |
|
|
|
|
static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len); |
|
|
|
|
|
|
|
|
|
#ifdef TRACE |
|
|
|
|
static void dump_shorts(WMACodecContext *s, const char *name, const short *tab, int n) |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
tprintf(s->avctx, "%s[%d]:\n", name, n); |
|
|
|
|
for(i=0;i<n;i++) { |
|
|
|
|
if ((i & 7) == 0) |
|
|
|
|
tprintf(s->avctx, "%4d: ", i); |
|
|
|
|
tprintf(s->avctx, " %5d.0", tab[i]); |
|
|
|
|
if ((i & 7) == 7) |
|
|
|
|
tprintf(s->avctx, "\n"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void dump_floats(WMACodecContext *s, const char *name, int prec, const float *tab, int n) |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
@ -105,7 +91,7 @@ static int wma_decode_init(AVCodecContext * avctx) |
|
|
|
|
|
|
|
|
|
/* init MDCT */ |
|
|
|
|
for(i = 0; i < s->nb_block_sizes; i++) |
|
|
|
|
ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 1, 1.0); |
|
|
|
|
ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 1, 1.0 / 32768.0); |
|
|
|
|
|
|
|
|
|
if (s->use_noise_coding) { |
|
|
|
|
init_vlc(&s->hgain_vlc, HGAINVLCBITS, sizeof(ff_wma_hgain_huffbits), |
|
|
|
@ -121,7 +107,7 @@ static int wma_decode_init(AVCodecContext * avctx) |
|
|
|
|
wma_lsp_to_curve_init(s, s->frame_len); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
avctx->sample_fmt = AV_SAMPLE_FMT_S16; |
|
|
|
|
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; |
|
|
|
|
|
|
|
|
|
avcodec_get_frame_defaults(&s->frame); |
|
|
|
|
avctx->coded_frame = &s->frame; |
|
|
|
@ -762,10 +748,10 @@ next: |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* decode a frame of frame_len samples */ |
|
|
|
|
static int wma_decode_frame(WMACodecContext *s, int16_t *samples) |
|
|
|
|
static int wma_decode_frame(WMACodecContext *s, float **samples, |
|
|
|
|
int samples_offset) |
|
|
|
|
{ |
|
|
|
|
int ret, n, ch, incr; |
|
|
|
|
const float *output[MAX_CHANNELS]; |
|
|
|
|
int ret, ch; |
|
|
|
|
|
|
|
|
|
#ifdef TRACE |
|
|
|
|
tprintf(s->avctx, "***decode_frame: %d size=%d\n", s->frame_count++, s->frame_len); |
|
|
|
@ -782,20 +768,19 @@ static int wma_decode_frame(WMACodecContext *s, int16_t *samples) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* convert frame to integer */ |
|
|
|
|
n = s->frame_len; |
|
|
|
|
incr = s->nb_channels; |
|
|
|
|
for (ch = 0; ch < MAX_CHANNELS; ch++) |
|
|
|
|
output[ch] = s->frame_out[ch]; |
|
|
|
|
s->fmt_conv.float_to_int16_interleave(samples, output, n, incr); |
|
|
|
|
for (ch = 0; ch < incr; ch++) { |
|
|
|
|
for (ch = 0; ch < s->nb_channels; ch++) { |
|
|
|
|
/* copy current block to output */ |
|
|
|
|
memcpy(samples[ch] + samples_offset, s->frame_out[ch], |
|
|
|
|
s->frame_len * sizeof(*s->frame_out[ch])); |
|
|
|
|
/* prepare for next block */ |
|
|
|
|
memmove(&s->frame_out[ch][0], &s->frame_out[ch][n], n * sizeof(float)); |
|
|
|
|
} |
|
|
|
|
memmove(&s->frame_out[ch][0], &s->frame_out[ch][s->frame_len], |
|
|
|
|
s->frame_len * sizeof(*s->frame_out[ch])); |
|
|
|
|
|
|
|
|
|
#ifdef TRACE |
|
|
|
|
dump_shorts(s, "samples", samples, n * s->nb_channels); |
|
|
|
|
dump_floats(s, "samples", 6, samples[ch] + samples_offset, s->frame_len); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -807,7 +792,8 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, |
|
|
|
|
WMACodecContext *s = avctx->priv_data; |
|
|
|
|
int nb_frames, bit_offset, i, pos, len, ret; |
|
|
|
|
uint8_t *q; |
|
|
|
|
int16_t *samples; |
|
|
|
|
float **samples; |
|
|
|
|
int samples_offset; |
|
|
|
|
|
|
|
|
|
tprintf(avctx, "***decode_superframe:\n"); |
|
|
|
|
|
|
|
|
@ -839,7 +825,8 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, |
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
samples = (int16_t *)s->frame.data[0]; |
|
|
|
|
samples = (float **)s->frame.extended_data; |
|
|
|
|
samples_offset = 0; |
|
|
|
|
|
|
|
|
|
if (s->use_bit_reservoir) { |
|
|
|
|
bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3); |
|
|
|
@ -873,9 +860,9 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, |
|
|
|
|
skip_bits(&s->gb, s->last_bitoffset); |
|
|
|
|
/* this frame is stored in the last superframe and in the
|
|
|
|
|
current one */ |
|
|
|
|
if (wma_decode_frame(s, samples) < 0) |
|
|
|
|
if (wma_decode_frame(s, samples, samples_offset) < 0) |
|
|
|
|
goto fail; |
|
|
|
|
samples += s->nb_channels * s->frame_len; |
|
|
|
|
samples_offset += s->frame_len; |
|
|
|
|
nb_frames--; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -890,9 +877,9 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, |
|
|
|
|
|
|
|
|
|
s->reset_block_lengths = 1; |
|
|
|
|
for(i=0;i<nb_frames;i++) { |
|
|
|
|
if (wma_decode_frame(s, samples) < 0) |
|
|
|
|
if (wma_decode_frame(s, samples, samples_offset) < 0) |
|
|
|
|
goto fail; |
|
|
|
|
samples += s->nb_channels * s->frame_len; |
|
|
|
|
samples_offset += s->frame_len; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* we copy the end of the frame in the last frame buffer */ |
|
|
|
@ -908,9 +895,9 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, |
|
|
|
|
memcpy(s->last_superframe, buf + pos, len); |
|
|
|
|
} else { |
|
|
|
|
/* single frame decode */ |
|
|
|
|
if (wma_decode_frame(s, samples) < 0) |
|
|
|
|
if (wma_decode_frame(s, samples, samples_offset) < 0) |
|
|
|
|
goto fail; |
|
|
|
|
samples += s->nb_channels * s->frame_len; |
|
|
|
|
samples_offset += s->frame_len; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
av_dlog(s->avctx, "%d %d %d %d outbytes:%td eaten:%d\n", |
|
|
|
@ -946,6 +933,8 @@ AVCodec ff_wmav1_decoder = { |
|
|
|
|
.flush = flush, |
|
|
|
|
.capabilities = CODEC_CAP_DR1, |
|
|
|
|
.long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), |
|
|
|
|
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, |
|
|
|
|
AV_SAMPLE_FMT_NONE }, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
AVCodec ff_wmav2_decoder = { |
|
|
|
@ -959,4 +948,6 @@ AVCodec ff_wmav2_decoder = { |
|
|
|
|
.flush = flush, |
|
|
|
|
.capabilities = CODEC_CAP_DR1, |
|
|
|
|
.long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), |
|
|
|
|
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, |
|
|
|
|
AV_SAMPLE_FMT_NONE }, |
|
|
|
|
}; |
|
|
|
|