+ if (header_size > 0)
+ return (buf_size - header_size) * 2 / ch;
+
+ /* more complex formats */
+ switch (avctx->codec->id) {
+ case AV_CODEC_ID_ADPCM_EA:
+ has_coded_samples = 1;
+ *coded_samples = bytestream2_get_le32(gb);
+ *coded_samples -= *coded_samples % 28;
+ nb_samples = (buf_size - 12) / 30 * 28;
+ break;
+ case AV_CODEC_ID_ADPCM_IMA_EA_EACS:
+ has_coded_samples = 1;
+ *coded_samples = bytestream2_get_le32(gb);
+ nb_samples = (buf_size - (4 + 8 * ch)) * 2 / ch;
+ break;
+ case AV_CODEC_ID_ADPCM_EA_MAXIS_XA:
+ nb_samples = (buf_size - ch) / ch * 2;
+ break;
+ case AV_CODEC_ID_ADPCM_EA_R1:
+ case AV_CODEC_ID_ADPCM_EA_R2:
+ case AV_CODEC_ID_ADPCM_EA_R3:
+ /* maximum number of samples */
+ /* has internal offsets and a per-frame switch to signal raw 16-bit */
+ has_coded_samples = 1;
+ switch (avctx->codec->id) {
+ case AV_CODEC_ID_ADPCM_EA_R1:
+ header_size = 4 + 9 * ch;
+ *coded_samples = bytestream2_get_le32(gb);
+ break;
+ case AV_CODEC_ID_ADPCM_EA_R2:
+ header_size = 4 + 5 * ch;
+ *coded_samples = bytestream2_get_le32(gb);
+ break;
+ case AV_CODEC_ID_ADPCM_EA_R3:
+ header_size = 4 + 5 * ch;
+ *coded_samples = bytestream2_get_be32(gb);
+ break;
+ }
+ *coded_samples -= *coded_samples % 28;
+ nb_samples = (buf_size - header_size) * 2 / ch;
+ nb_samples -= nb_samples % 28;
+ break;
+ case AV_CODEC_ID_ADPCM_IMA_DK3:
+ if (avctx->block_align > 0)
+ buf_size = FFMIN(buf_size, avctx->block_align);
+ nb_samples = ((buf_size - 16) * 2 / 3 * 4) / ch;
+ break;
+ case AV_CODEC_ID_ADPCM_IMA_DK4:
+ if (avctx->block_align > 0)
+ buf_size = FFMIN(buf_size, avctx->block_align);
+ nb_samples = 1 + (buf_size - 4 * ch) * 2 / ch;
+ break;
+ case AV_CODEC_ID_ADPCM_IMA_WAV:
+ if (avctx->block_align > 0)
+ buf_size = FFMIN(buf_size, avctx->block_align);
+ nb_samples = 1 + (buf_size - 4 * ch) / (4 * ch) * 8;
+ break;
+ case AV_CODEC_ID_ADPCM_MS:
+ if (avctx->block_align > 0)
+ buf_size = FFMIN(buf_size, avctx->block_align);
+ nb_samples = 2 + (buf_size - 7 * ch) * 2 / ch;
+ break;
+ case AV_CODEC_ID_ADPCM_SBPRO_2:
+ case AV_CODEC_ID_ADPCM_SBPRO_3:
+ case AV_CODEC_ID_ADPCM_SBPRO_4:
+ {
+ int samples_per_byte;
+ switch (avctx->codec->id) {
+ case AV_CODEC_ID_ADPCM_SBPRO_2: samples_per_byte = 4; break;
+ case AV_CODEC_ID_ADPCM_SBPRO_3: samples_per_byte = 3; break;
+ case AV_CODEC_ID_ADPCM_SBPRO_4: samples_per_byte = 2; break;
+ }
+ if (!s->status[0].step_index) {
+ nb_samples++;
+ buf_size -= ch;
+ }
+ nb_samples += buf_size * samples_per_byte / ch;
+ break;
+ }
+ case AV_CODEC_ID_ADPCM_SWF:
+ {
+ int buf_bits = buf_size * 8 - 2;
+ int nbits = (bytestream2_get_byte(gb) >> 6) + 2;
+ int block_hdr_size = 22 * ch;
+ int block_size = block_hdr_size + nbits * ch * 4095;
+ int nblocks = buf_bits / block_size;
+ int bits_left = buf_bits - nblocks * block_size;
+ nb_samples = nblocks * 4096;
+ if (bits_left >= block_hdr_size)
+ nb_samples += 1 + (bits_left - block_hdr_size) / (nbits * ch);
+ break;
+ }
+ case AV_CODEC_ID_ADPCM_THP:
+ has_coded_samples = 1;
+ bytestream2_skip(gb, 4); // channel size
+ *coded_samples = bytestream2_get_be32(gb);
+ *coded_samples -= *coded_samples % 14;
+ nb_samples = (buf_size - 80) / (8 * ch) * 14;
+ break;
+ case AV_CODEC_ID_ADPCM_XA:
+ nb_samples = (buf_size / 128) * 224 / ch;
+ break;
+ }
+
+ /* validate coded sample count */
+ if (has_coded_samples && (*coded_samples <= 0 || *coded_samples > nb_samples))
+ return AVERROR_INVALIDDATA;