X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Ftwinvq.c;h=a4c1e938e01a8d91de40626fac55c73c7dbcad3e;hb=42b9150b0d4f0a130c1d93dc991fd5412743a8cf;hp=67bc16088e10476904d38354f788d81ddf861636;hpb=4bf2e7c5f1c0ad3997fd7c9859c16db8e4e16df6;p=ffmpeg diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index 67bc16088e1..a4c1e938e01 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -19,10 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/channel_layout.h" +#include "libavutil/float_dsp.h" #include "avcodec.h" #include "get_bits.h" -#include "dsputil.h" #include "fft.h" +#include "internal.h" #include "lsp.h" #include "sinewin.h" @@ -174,8 +176,7 @@ static const ModeTab mode_44_48 = { typedef struct TwinContext { AVCodecContext *avctx; - AVFrame frame; - DSPContext dsp; + AVFloatDSPContext fdsp; FFTContext mdct_ctx[3]; const ModeTab *mtab; @@ -646,11 +647,10 @@ static void imdct_and_window(TwinContext *tctx, enum FrameType ftype, int wtype, mdct->imdct_half(mdct, buf1 + bsize*j, in + bsize*j); - tctx->dsp.vector_fmul_window(out2, - prev_buf + (bsize-wsize)/2, - buf1 + bsize*j, - ff_sine_windows[av_log2(wsize)], - wsize/2); + tctx->fdsp.vector_fmul_window(out2, prev_buf + (bsize-wsize) / 2, + buf1 + bsize * j, + ff_sine_windows[av_log2(wsize)], + wsize / 2); out2 += wsize; memcpy(out2, buf1 + bsize*j + wsize/2, (bsize - wsize/2)*sizeof(float)); @@ -664,7 +664,7 @@ static void imdct_and_window(TwinContext *tctx, enum FrameType ftype, int wtype, } static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype, - float *out) + float **out) { const ModeTab *mtab = tctx->mtab; int size1, size2; @@ -683,24 +683,15 @@ static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype, size2 = tctx->last_block_pos[0]; size1 = mtab->size - size2; - if (tctx->avctx->channels == 2) { - tctx->dsp.butterflies_float_interleave(out, prev_buf, - &prev_buf[2*mtab->size], - size1); - - out += 2 * size1; - - tctx->dsp.butterflies_float_interleave(out, tctx->curr_frame, - &tctx->curr_frame[2*mtab->size], - size2); - } else { - memcpy(out, prev_buf, size1 * sizeof(*out)); - out += size1; + memcpy(&out[0][0 ], prev_buf, size1 * sizeof(out[0][0])); + memcpy(&out[0][size1], tctx->curr_frame, size2 * sizeof(out[0][0])); - memcpy(out, tctx->curr_frame, size2 * sizeof(*out)); + if (tctx->avctx->channels == 2) { + memcpy(&out[1][0], &prev_buf[2*mtab->size], size1 * sizeof(out[1][0])); + memcpy(&out[1][size1], &tctx->curr_frame[2*mtab->size], size2 * sizeof(out[1][0])); + tctx->fdsp.butterflies_float(out[0], out[1], mtab->size); } - } static void dec_bark_env(TwinContext *tctx, const uint8_t *in, int use_hist, @@ -787,8 +778,8 @@ static void read_and_decode_spectrum(TwinContext *tctx, GetBitContext *gb, dec_bark_env(tctx, bark1[i][j], bark_use_hist[i][j], i, tctx->tmp_buf, gain[sub*i+j], ftype); - tctx->dsp.vector_fmul(chunk + block_size*j, chunk + block_size*j, tctx->tmp_buf, - block_size); + tctx->fdsp.vector_fmul(chunk + block_size*j, chunk + block_size*j, + tctx->tmp_buf, block_size); } @@ -809,7 +800,7 @@ static void read_and_decode_spectrum(TwinContext *tctx, GetBitContext *gb, dec_lpc_spectrum_inv(tctx, lsp, ftype, tctx->tmp_buf); for (j = 0; j < mtab->fmode[ftype].sub; j++) { - tctx->dsp.vector_fmul(chunk, chunk, tctx->tmp_buf, block_size); + tctx->fdsp.vector_fmul(chunk, chunk, tctx->tmp_buf, block_size); chunk += block_size; } } @@ -818,12 +809,13 @@ static void read_and_decode_spectrum(TwinContext *tctx, GetBitContext *gb, static int twin_decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { + AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; TwinContext *tctx = avctx->priv_data; GetBitContext gb; const ModeTab *mtab = tctx->mtab; - float *out = NULL; + float **out = NULL; enum FrameType ftype; int window_type, ret; static const enum FrameType wtype_to_ftype_table[] = { @@ -839,12 +831,12 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data, /* get output buffer */ if (tctx->discarded_packets >= 2) { - tctx->frame.nb_samples = mtab->size; - if ((ret = avctx->get_buffer(avctx, &tctx->frame)) < 0) { + frame->nb_samples = mtab->size; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - out = (float *)tctx->frame.data[0]; + out = (float **)frame->extended_data; } init_get_bits(&gb, buf, buf_size * 8); @@ -870,8 +862,7 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data, return buf_size; } - *got_frame_ptr = 1; - *(AVFrame *)data = tctx->frame;; + *got_frame_ptr = 1; return buf_size; } @@ -1117,7 +1108,7 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) int isampf, ibps; tctx->avctx = avctx; - avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; if (!avctx->extradata || avctx->extradata_size < 12) { av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n"); @@ -1126,6 +1117,11 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) avctx->channels = AV_RB32(avctx->extradata ) + 1; avctx->bit_rate = AV_RB32(avctx->extradata + 4) * 1000; isampf = AV_RB32(avctx->extradata + 8); + + if (isampf < 8 || isampf > 44) { + av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate\n"); + return AVERROR_INVALIDDATA; + } switch (isampf) { case 44: avctx->sample_rate = 44100; break; case 22: avctx->sample_rate = 22050; break; @@ -1133,11 +1129,14 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) default: avctx->sample_rate = isampf * 1000; break; } - if (avctx->channels > CHANNELS_MAX) { + if (avctx->channels <= 0 || avctx->channels > CHANNELS_MAX) { av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n", avctx->channels); return -1; } + avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO : + AV_CH_LAYOUT_STEREO; + ibps = avctx->bit_rate / (1000 * avctx->channels); switch ((isampf << 8) + ibps) { @@ -1155,7 +1154,7 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) return -1; } - ff_dsputil_init(&tctx->dsp, avctx); + avpriv_float_dsp_init(&tctx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); if ((ret = init_mdct_win(tctx))) { av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n"); twin_decode_close(avctx); @@ -1165,20 +1164,19 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) memset_float(tctx->bark_hist[0][0], 0.1, FF_ARRAY_ELEMS(tctx->bark_hist)); - avcodec_get_frame_defaults(&tctx->frame); - avctx->coded_frame = &tctx->frame; - return 0; } AVCodec ff_twinvq_decoder = { .name = "twinvq", .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_TWINVQ, + .id = AV_CODEC_ID_TWINVQ, .priv_data_size = sizeof(TwinContext), .init = twin_decode_init, .close = twin_decode_close, .decode = twin_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("VQF TwinVQ"), + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_NONE }, };