X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fatrac3.c;h=6dec6a3abe113882ad49e022776bc47ee44bf538;hb=467879eb54526d187847bbbd32723500ab0ab330;hp=ab14910e28f3db3a054a6120b23f058af805da00;hpb=5e76b8bb760e1d81e5a23552e94c4173b6a625d1;p=ffmpeg diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index ab14910e28f..6dec6a3abe1 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -49,6 +49,8 @@ #define JOINT_STEREO 0x12 #define STEREO 0x2 +#define SAMPLES_PER_FRAME 1024 +#define MDCT_SIZE 512 /* These structures are needed to store the parsed gain control data. */ typedef struct { @@ -71,12 +73,12 @@ typedef struct { int bandsCoded; int numComponents; tonal_component components[64]; - float prevFrame[1024]; + float prevFrame[SAMPLES_PER_FRAME]; int gcBlkSwitch; gain_block gainBlock[2]; - DECLARE_ALIGNED(32, float, spectrum)[1024]; - DECLARE_ALIGNED(32, float, IMDCT_buf)[1024]; + DECLARE_ALIGNED(32, float, spectrum)[SAMPLES_PER_FRAME]; + DECLARE_ALIGNED(32, float, IMDCT_buf)[SAMPLES_PER_FRAME]; float delayBuf1[46]; ///mdct_ctx.imdct_calc(&q->mdct_ctx,pOutput,pInput); /* Perform windowing on the output. */ - dsp.vector_fmul(pOutput, pOutput, mdct_window, 512); + dsp.vector_fmul(pOutput, pOutput, mdct_window, MDCT_SIZE); } @@ -194,7 +197,7 @@ static int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){ } -static av_cold void init_atrac3_transforms(ATRAC3Context *q) { +static av_cold int init_atrac3_transforms(ATRAC3Context *q, int is_float) { float enc_window[256]; int i; @@ -210,7 +213,7 @@ static av_cold void init_atrac3_transforms(ATRAC3Context *q) { } /* Initialize the MDCT transform. */ - ff_mdct_init(&q->mdct_ctx, 9, 1, 1.0 / 32768); + return ff_mdct_init(&q->mdct_ctx, 9, 1, is_float ? 1.0 / 32768 : 1.0); } /** @@ -344,7 +347,7 @@ static int decodeSpectrum (GetBitContext *gb, float *pOut) /* Clear the subbands that were not coded. */ first = subbandTab[cnt]; - memset(pOut+first, 0, (1024 - first) * sizeof(float)); + memset(pOut+first, 0, (SAMPLES_PER_FRAME - first) * sizeof(float)); return numSubbands; } @@ -374,7 +377,7 @@ static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent coding_mode_selector = get_bits(gb,2); if (coding_mode_selector == 2) - return -1; + return AVERROR_INVALIDDATA; coding_mode = coding_mode_selector & 1; @@ -386,7 +389,7 @@ static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent quant_step_index = get_bits(gb,3); if (quant_step_index <= 1) - return -1; + return AVERROR_INVALIDDATA; if (coding_mode_selector == 3) coding_mode = get_bits1(gb); @@ -400,7 +403,7 @@ static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent for (k=0; kIMDCT_buf, 0, 512 * sizeof(float)); /* gain compensation and overlapping */ - gainCompensateAndOverlap (pSnd->IMDCT_buf, &(pSnd->prevFrame[band*256]), &(pOut[band*256]), - &((pSnd->gainBlock[1 - (pSnd->gcBlkSwitch)]).gBlock[band]), - &((pSnd->gainBlock[pSnd->gcBlkSwitch]).gBlock[band])); + gainCompensateAndOverlap(pSnd->IMDCT_buf, &pSnd->prevFrame[band * 256], + &pOut[band * 256], + &pSnd->gainBlock[1 - pSnd->gcBlkSwitch].gBlock[band], + &pSnd->gainBlock[ pSnd->gcBlkSwitch].gBlock[band]); } /* Swap the gain control buffers for the next frame. */ @@ -724,7 +728,7 @@ static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_ */ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, - float *out_samples) + float **out_samples) { int result, i; float *p1, *p2, *p3, *p4; @@ -736,9 +740,9 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, /* decode Sound Unit 1 */ init_get_bits(&q->gb,databuf,q->bits_per_frame); - result = decodeChannelSoundUnit(q,&q->gb, q->pUnits, out_samples, 0, JOINT_STEREO); + result = decodeChannelSoundUnit(q,&q->gb, q->pUnits, out_samples[0], 0, JOINT_STEREO); if (result != 0) - return (result); + return result; /* Framedata of the su2 in the joint-stereo mode is encoded in * reverse byte order so we need to swap it first. */ @@ -758,7 +762,7 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, ptr1 = q->decoded_bytes_buffer; for (i = 4; *ptr1 == 0xF8; i++, ptr1++) { if (i >= q->bytes_per_frame) - return -1; + return AVERROR_INVALIDDATA; } @@ -777,14 +781,14 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, } /* Decode Sound Unit 2. */ - result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[1], &out_samples[1024], 1, JOINT_STEREO); + result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[1], out_samples[1], 1, JOINT_STEREO); if (result != 0) - return (result); + return result; /* Reconstruct the channel coefficients. */ - reverseMatrixing(out_samples, &out_samples[1024], q->matrix_coeff_index_prev, q->matrix_coeff_index_now); + reverseMatrixing(out_samples[0], out_samples[1], q->matrix_coeff_index_prev, q->matrix_coeff_index_now); - channelWeighting(out_samples, &out_samples[1024], q->weighting_delay); + channelWeighting(out_samples[0], out_samples[1], q->weighting_delay); } else { /* normal stereo mode or mono */ @@ -792,24 +796,25 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, for (i=0 ; ichannels ; i++) { /* Set the bitstream reader at the start of a channel sound unit. */ - init_get_bits(&q->gb, databuf+((i*q->bytes_per_frame)/q->channels), (q->bits_per_frame)/q->channels); + init_get_bits(&q->gb, + databuf + i * q->bytes_per_frame / q->channels, + q->bits_per_frame / q->channels); - result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[i], &out_samples[i*1024], i, q->codingMode); + result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[i], out_samples[i], i, q->codingMode); if (result != 0) - return (result); + return result; } } /* Apply the iQMF synthesis filter. */ - p1 = out_samples; for (i=0 ; ichannels ; i++) { + p1 = out_samples[i]; p2= p1+256; p3= p2+256; p4= p3+256; atrac_iqmf (p1, p2, 256, p1, q->pUnits[i].delayBuf1, q->tempBuf); atrac_iqmf (p4, p3, 256, p3, q->pUnits[i].delayBuf2, q->tempBuf); atrac_iqmf (p1, p3, 512, p1, q->pUnits[i].delayBuf3, q->tempBuf); - p1 +=1024; } return 0; @@ -822,22 +827,31 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, * @param avctx pointer to the AVCodecContext */ -static int atrac3_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) { +static int atrac3_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; ATRAC3Context *q = avctx->priv_data; - int result = 0; + int result; const uint8_t* databuf; - float *samples = data; + float *samples_flt; + int16_t *samples_s16; if (buf_size < avctx->block_align) { av_log(avctx, AV_LOG_ERROR, "Frame too small (%d bytes). Truncated file?\n", buf_size); - *data_size = 0; - return buf_size; + return AVERROR_INVALIDDATA; + } + + /* get output buffer */ + q->frame.nb_samples = SAMPLES_PER_FRAME; + if ((result = avctx->get_buffer(avctx, &q->frame)) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return result; } + samples_flt = (float *)q->frame.data[0]; + samples_s16 = (int16_t *)q->frame.data[0]; /* Check if we need to descramble and what buffer to pass on. */ if (q->scrambled_stream) { @@ -847,19 +861,29 @@ static int atrac3_decode_frame(AVCodecContext *avctx, databuf = buf; } - result = decodeFrame(q, databuf, q->channels == 2 ? q->outSamples[0] : samples); + if (q->channels == 1 && avctx->sample_fmt == AV_SAMPLE_FMT_FLT) + result = decodeFrame(q, databuf, &samples_flt); + else + result = decodeFrame(q, databuf, q->outSamples); if (result != 0) { av_log(NULL,AV_LOG_ERROR,"Frame decoding error!\n"); - return -1; + return result; } /* interleave */ - if (q->channels == 2) { - q->fmt_conv.float_interleave(samples, (const float **)q->outSamples, - 1024, 2); + if (q->channels == 2 && avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { + q->fmt_conv.float_interleave(samples_flt, + (const float **)q->outSamples, + SAMPLES_PER_FRAME, 2); + } else if (avctx->sample_fmt == AV_SAMPLE_FMT_S16) { + q->fmt_conv.float_to_int16_interleave(samples_s16, + (const float **)q->outSamples, + SAMPLES_PER_FRAME, q->channels); } - *data_size = 1024 * q->channels * av_get_bytes_per_sample(avctx->sample_fmt); + + *got_frame_ptr = 1; + *(AVFrame *)data = q->frame; return avctx->block_align; } @@ -873,7 +897,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx, static av_cold int atrac3_decode_init(AVCodecContext *avctx) { - int i; + int i, ret; const uint8_t *edata_ptr = avctx->extradata; ATRAC3Context *q = avctx->priv_data; static VLC_TYPE atrac3_vlc_table[4096][2]; @@ -897,7 +921,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) av_log(avctx,AV_LOG_DEBUG,"[12-13] %d\n",bytestream_get_le16(&edata_ptr)); //Unknown always 0 /* setup */ - q->samples_per_frame = 1024 * q->channels; + q->samples_per_frame = SAMPLES_PER_FRAME * q->channels; q->atrac3version = 4; q->delay = 0x88E; if (q->codingMode) @@ -910,7 +934,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) if ((q->bytes_per_frame == 96*q->channels*q->frame_factor) || (q->bytes_per_frame == 152*q->channels*q->frame_factor) || (q->bytes_per_frame == 192*q->channels*q->frame_factor)) { } else { av_log(avctx,AV_LOG_ERROR,"Unknown frame/channel/frame_factor configuration %d/%d/%d\n", q->bytes_per_frame, q->channels, q->frame_factor); - return -1; + return AVERROR_INVALIDDATA; } } else if (avctx->extradata_size == 10) { @@ -930,17 +954,17 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) if (q->atrac3version != 4) { av_log(avctx,AV_LOG_ERROR,"Version %d != 4.\n",q->atrac3version); - return -1; + return AVERROR_INVALIDDATA; } - if (q->samples_per_frame != 1024 && q->samples_per_frame != 2048) { + if (q->samples_per_frame != SAMPLES_PER_FRAME && q->samples_per_frame != SAMPLES_PER_FRAME*2) { av_log(avctx,AV_LOG_ERROR,"Unknown amount of samples per frame %d.\n",q->samples_per_frame); - return -1; + return AVERROR_INVALIDDATA; } if (q->delay != 0x88E) { av_log(avctx,AV_LOG_ERROR,"Unknown amount of delay %x != 0x88E.\n",q->delay); - return -1; + return AVERROR_INVALIDDATA; } if (q->codingMode == STEREO) { @@ -949,17 +973,17 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) av_log(avctx,AV_LOG_DEBUG,"Joint stereo detected.\n"); } else { av_log(avctx,AV_LOG_ERROR,"Unknown channel coding mode %x!\n",q->codingMode); - return -1; + return AVERROR_INVALIDDATA; } if (avctx->channels <= 0 || avctx->channels > 2 /*|| ((avctx->channels * 1024) != q->samples_per_frame)*/) { av_log(avctx,AV_LOG_ERROR,"Channel configuration error!\n"); - return -1; + return AVERROR(EINVAL); } if(avctx->block_align >= UINT_MAX/2) - return -1; + return AVERROR(EINVAL); /* Pad the data buffer with FF_INPUT_BUFFER_PADDING_SIZE, * this is for the bitstream reader. */ @@ -979,7 +1003,16 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) vlcs_initialized = 1; } - init_atrac3_transforms(q); + if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + else + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + + if ((ret = init_atrac3_transforms(q, avctx->sample_fmt == AV_SAMPLE_FMT_FLT))) { + av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n"); + av_freep(&q->decoded_bytes_buffer); + return ret; + } atrac_generate_tables(); @@ -1009,20 +1042,22 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) q->pUnits = av_mallocz(sizeof(channel_unit)*q->channels); if (!q->pUnits) { - av_free(q->decoded_bytes_buffer); + atrac3_decode_close(avctx); return AVERROR(ENOMEM); } - if (avctx->channels > 1) { - q->outSamples[0] = av_mallocz(1024 * 2 * sizeof(*q->outSamples[0])); - q->outSamples[1] = q->outSamples[0] + 1024; + if (avctx->channels > 1 || avctx->sample_fmt == AV_SAMPLE_FMT_S16) { + q->outSamples[0] = av_mallocz(SAMPLES_PER_FRAME * avctx->channels * sizeof(*q->outSamples[0])); + q->outSamples[1] = q->outSamples[0] + SAMPLES_PER_FRAME; if (!q->outSamples[0]) { atrac3_decode_close(avctx); return AVERROR(ENOMEM); } } - avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + avcodec_get_frame_defaults(&q->frame); + avctx->coded_frame = &q->frame; + return 0; } @@ -1036,5 +1071,6 @@ AVCodec ff_atrac3_decoder = .init = atrac3_decode_init, .close = atrac3_decode_close, .decode = atrac3_decode_frame, + .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Atrac 3 (Adaptive TRansform Acoustic Coding 3)"), };