static int ape_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { AVFrame *frame = data; const uint8_t *buf = avpkt->data; APEContext *s = avctx->priv_data; uint8_t *sample8; int16_t *sample16; int32_t *sample24; int i, ch, ret; int blockstodecode; /* this should never be negative, but bad things will happen if it is, so check it just to make sure. */ av_assert0(s->samples >= 0); if(!s->samples){ uint32_t nblocks, offset; int buf_size; if (!avpkt->size) { *got_frame_ptr = 0; return 0; } if (avpkt->size < 8) { av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); return AVERROR_INVALIDDATA; } buf_size = avpkt->size & ~3; if (buf_size != avpkt->size) { av_log(avctx, AV_LOG_WARNING, "packet size is not a multiple of 4. " "extra bytes at the end will be skipped.\n"); } if (s->fileversion < 3950) // previous versions overread two bytes buf_size += 2; av_fast_malloc(&s->data, &s->data_size, buf_size); if (!s->data) return AVERROR(ENOMEM); s->dsp.bswap_buf((uint32_t*)s->data, (const uint32_t*)buf, buf_size >> 2); memset(s->data + (buf_size & ~3), 0, buf_size & 3); s->ptr = s->data; s->data_end = s->data + buf_size; nblocks = bytestream_get_be32(&s->ptr); offset = bytestream_get_be32(&s->ptr); if (s->fileversion >= 3900) { if (offset > 3) { av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n"); s->data = NULL; return AVERROR_INVALIDDATA; } if (s->data_end - s->ptr < offset) { av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); return AVERROR_INVALIDDATA; } s->ptr += offset; } else { if ((ret = init_get_bits8(&s->gb, s->ptr, s->data_end - s->ptr)) < 0) return ret; if (s->fileversion > 3800) skip_bits_long(&s->gb, offset * 8); else skip_bits_long(&s->gb, offset); } if (!nblocks || nblocks > INT_MAX) { av_log(avctx, AV_LOG_ERROR, "Invalid sample count: %u.\n", nblocks); return AVERROR_INVALIDDATA; } s->samples = nblocks; /* Initialize the frame decoder */ if (init_frame_decoder(s) < 0) { av_log(avctx, AV_LOG_ERROR, "Error reading frame header\n"); return AVERROR_INVALIDDATA; } } if (!s->data) { *got_frame_ptr = 0; return avpkt->size; } blockstodecode = FFMIN(s->blocks_per_loop, s->samples); // for old files coefficients were not interleaved, // so we need to decode all of them at once if (s->fileversion < 3930) blockstodecode = s->samples; /* reallocate decoded sample buffer if needed */ av_fast_malloc(&s->decoded_buffer, &s->decoded_size, 2 * FFALIGN(blockstodecode, 8) * sizeof(*s->decoded_buffer)); if (!s->decoded_buffer) return AVERROR(ENOMEM); memset(s->decoded_buffer, 0, s->decoded_size); s->decoded[0] = s->decoded_buffer; s->decoded[1] = s->decoded_buffer + FFALIGN(blockstodecode, 8); /* get output buffer */ frame->nb_samples = blockstodecode; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; s->error=0; if ((s->channels == 1) || (s->frameflags & APE_FRAMECODE_PSEUDO_STEREO)) ape_unpack_mono(s, blockstodecode); else ape_unpack_stereo(s, blockstodecode); emms_c(); if (s->error) { s->samples=0; av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n"); return AVERROR_INVALIDDATA; } switch (s->bps) { case 8: for (ch = 0; ch < s->channels; ch++) { sample8 = (uint8_t *)frame->data[ch]; for (i = 0; i < blockstodecode; i++) *sample8++ = (s->decoded[ch][i] + 0x80) & 0xff; } break; case 16: for (ch = 0; ch < s->channels; ch++) { sample16 = (int16_t *)frame->data[ch]; for (i = 0; i < blockstodecode; i++) *sample16++ = s->decoded[ch][i]; } break; case 24: for (ch = 0; ch < s->channels; ch++) { sample24 = (int32_t *)frame->data[ch]; for (i = 0; i < blockstodecode; i++) *sample24++ = s->decoded[ch][i] << 8; } break; } s->samples -= blockstodecode; *got_frame_ptr = 1; return !s->samples ? avpkt->size : 0; }