summaryrefslogtreecommitdiff
path: root/libavcodec/adpcm.c
diff options
context:
space:
mode:
authorZane van Iperen <zane@zanevaniperen.com>2020-09-12 22:02:26 +1000
committerZane van Iperen <zane@zanevaniperen.com>2020-09-19 15:34:25 +1000
commit9eabe9c4b53365426eddbcdef91f07254f102ae2 (patch)
tree3408f6dd5895bb4400cab86c5bc4596463ec280f /libavcodec/adpcm.c
parent624f6df19f79f319faf19718c24a9471fa36f61c (diff)
downloadffmpeg-9eabe9c4b53365426eddbcdef91f07254f102ae2.tar.gz
avcodec/adpcm_argo: support decoding multiple frames
Increases decode speed significantly. Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
Diffstat (limited to 'libavcodec/adpcm.c')
-rw-r--r--libavcodec/adpcm.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index e409a3aa6a..14be1f4f88 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -181,7 +181,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx)
c->vqa_version = AV_RL16(avctx->extradata);
break;
case AV_CODEC_ID_ADPCM_ARGO:
- if (avctx->bits_per_coded_sample != 4)
+ if (avctx->bits_per_coded_sample != 4 || avctx->block_align != 17 * avctx->channels)
return AVERROR_INVALIDDATA;
break;
case AV_CODEC_ID_ADPCM_ZORK:
@@ -745,11 +745,6 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
return 0;
nb_samples = 64;
break;
- case AV_CODEC_ID_ADPCM_ARGO:
- if (buf_size < 17 * ch)
- return 0;
- nb_samples = 32;
- break;
/* simple 4-bit adpcm */
case AV_CODEC_ID_ADPCM_CT:
case AV_CODEC_ID_ADPCM_IMA_APC:
@@ -922,6 +917,9 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
case AV_CODEC_ID_ADPCM_PSX:
nb_samples = buf_size / (16 * ch) * 28;
break;
+ case AV_CODEC_ID_ADPCM_ARGO:
+ nb_samples = buf_size / avctx->block_align * 32;
+ break;
case AV_CODEC_ID_ADPCM_ZORK:
nb_samples = buf_size / ch;
break;
@@ -2023,22 +2021,24 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
* Each block relies on the previous two samples of each channel.
* They should be 0 initially.
*/
+ for (int block = 0; block < avpkt->size / avctx->block_align; block++) {
for (channel = 0; channel < avctx->channels; channel++) {
int control, shift;
- samples = samples_p[channel];
+ samples = samples_p[channel] + block * 32;
cs = c->status + channel;
/* Get the control byte and decode the samples, 2 at a time. */
control = bytestream2_get_byteu(&gb);
shift = (control >> 4) + 2;
- for (n = 0; n < nb_samples / 2; n++) {
+ for (n = 0; n < 16; n++) {
int sample = bytestream2_get_byteu(&gb);
*samples++ = ff_adpcm_argo_expand_nibble(cs, sample >> 4, shift, control & 0x04);
*samples++ = ff_adpcm_argo_expand_nibble(cs, sample >> 0, shift, control & 0x04);
}
}
+ }
break;
case AV_CODEC_ID_ADPCM_ZORK:
if (!c->has_status) {