+ case AV_CODEC_ID_ADPCM_IMA_APM:
+ {
+ PutBitContext pb;
+ init_put_bits(&pb, dst, pkt_size);
+
+ av_assert0(avctx->trellis == 0);
+
+ for (n = frame->nb_samples / 2; n > 0; n--) {
+ for (ch = 0; ch < avctx->channels; ch++) {
+ put_bits(&pb, 4, adpcm_ima_qt_compress_sample(c->status + ch, *samples++));
+ put_bits(&pb, 4, adpcm_ima_qt_compress_sample(c->status + ch, samples[st]));
+ }
+ samples += avctx->channels;
+ }
+
+ flush_put_bits(&pb);
+ break;
+ }
+ case AV_CODEC_ID_ADPCM_IMA_AMV:
+ {
+ av_assert0(avctx->channels == 1);
+
+ c->status[0].prev_sample = *samples;
+ bytestream_put_le16(&dst, c->status[0].prev_sample);
+ bytestream_put_byte(&dst, c->status[0].step_index);
+ bytestream_put_byte(&dst, 0);
+ bytestream_put_le32(&dst, avctx->frame_size);
+
+ if (avctx->trellis > 0) {
+ n = frame->nb_samples >> 1;
+
+ if (!(buf = av_malloc(2 * n)))
+ return AVERROR(ENOMEM);
+
+ adpcm_compress_trellis(avctx, samples, buf, &c->status[0], 2 * n, avctx->channels);
+ for (i = 0; i < n; i++)
+ bytestream_put_byte(&dst, (buf[2 * i] << 4) | buf[2 * i + 1]);
+
+ samples += 2 * n;
+ av_free(buf);
+ } else for (n = frame->nb_samples >> 1; n > 0; n--) {
+ int nibble;
+ nibble = adpcm_ima_compress_sample(&c->status[0], *samples++) << 4;
+ nibble |= adpcm_ima_compress_sample(&c->status[0], *samples++) & 0x0F;
+ bytestream_put_byte(&dst, nibble);
+ }
+
+ if (avctx->frame_size & 1) {
+ int nibble = adpcm_ima_compress_sample(&c->status[0], *samples++) << 4;
+ bytestream_put_byte(&dst, nibble);
+ }
+ break;
+ }
+ case AV_CODEC_ID_ADPCM_ARGO:
+ {
+ PutBitContext pb;
+ init_put_bits(&pb, dst, pkt_size);
+
+ av_assert0(frame->nb_samples == 32);
+
+ for (ch = 0; ch < avctx->channels; ch++) {
+ int64_t error = INT64_MAX, tmperr = INT64_MAX;
+ int shift = 2, flag = 0;
+ int saved1 = c->status[ch].sample1;
+ int saved2 = c->status[ch].sample2;
+
+ /* Find the optimal coefficients, bail early if we find a perfect result. */
+ for (int s = 2; s < 18 && tmperr != 0; s++) {
+ for (int f = 0; f < 2 && tmperr != 0; f++) {
+ c->status[ch].sample1 = saved1;
+ c->status[ch].sample2 = saved2;
+ tmperr = adpcm_argo_compress_block(c->status + ch, NULL, samples_p[ch],
+ frame->nb_samples, s, f);
+ if (tmperr < error) {
+ shift = s;
+ flag = f;
+ error = tmperr;
+ }
+ }
+ }
+
+ /* Now actually do the encode. */
+ c->status[ch].sample1 = saved1;
+ c->status[ch].sample2 = saved2;
+ adpcm_argo_compress_block(c->status + ch, &pb, samples_p[ch],
+ frame->nb_samples, shift, flag);
+ }
+
+ flush_put_bits(&pb);
+ break;
+ }