| @@ -74,7 +74,9 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) · 73 unmodified lines |
| 74 | 74 | return AVERROR(EINVAL); |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | | − if (avctx->trellis && avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_SSI) { |
| 77 | + if (avctx->trellis && |
| 78 | + (avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_SSI || |
| 79 | + avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_APM)) { |
| 78 | 80 | /* |
| 79 | 81 | * The current trellis implementation doesn't work for extended |
| 80 | 82 | * runs of samples without periodic resets. Disallow it. |
| @@ -145,6 +147,14 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) · 64 unmodified lines |
| 145 | 147 | avctx->frame_size = BLKSIZE * 2 / avctx->channels; |
| 146 | 148 | avctx->block_align = BLKSIZE; |
| 147 | 149 | break; |
| 150 | + case AV_CODEC_ID_ADPCM_IMA_APM: |
| 151 | + avctx->frame_size = BLKSIZE * 2 / avctx->channels; |
| 152 | + avctx->block_align = BLKSIZE; |
| 153 | + |
| 154 | + if (!(avctx->extradata = av_mallocz(28 + AV_INPUT_BUFFER_PADDING_SIZE))) |
| 155 | + return AVERROR(ENOMEM); |
| 156 | + avctx->extradata_size = 28; |
| 157 | + break; |
| 148 | 158 | default: |
| 149 | 159 | return AVERROR(EINVAL); |
| 150 | 160 | } |
| @@ -486,7 +496,8 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, · 335 unmodified lines |
| 486 | 496 | |
| 487 | 497 | if (avctx->codec_id == AV_CODEC_ID_ADPCM_SWF) |
| 488 | 498 | pkt_size = (2 + avctx->channels * (22 + 4 * (frame->nb_samples - 1)) + 7) / 8; |
| 489 | | − else if (avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_SSI) |
| 499 | + else if (avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_SSI || |
| 500 | + avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_APM) |
| 490 | 501 | pkt_size = (frame->nb_samples * avctx->channels) / 2; |
| 491 | 502 | else |
| 492 | 503 | pkt_size = avctx->block_align; |
| @@ -711,6 +722,24 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, · 218 unmodified lines |
| 711 | 722 | *dst++ = nibble; |
| 712 | 723 | } |
| 713 | 724 | break; |
| 725 | + case AV_CODEC_ID_ADPCM_IMA_APM: |
| 726 | + { |
| 727 | + PutBitContext pb; |
| 728 | + init_put_bits(&pb, dst, pkt_size); |
| 729 | + |
| 730 | + av_assert0(avctx->trellis == 0); |
| 731 | + |
| 732 | + for (n = frame->nb_samples / 2; n > 0; n--) { |
| 733 | + for (ch = 0; ch < avctx->channels; ch++) { |
| 734 | + put_bits(&pb, 4, adpcm_ima_qt_compress_sample(c->status + ch, *samples++)); |
| 735 | + put_bits(&pb, 4, adpcm_ima_qt_compress_sample(c->status + ch, samples[st])); |
| 736 | + } |
| 737 | + samples += avctx->channels; |
| 738 | + } |
| 739 | + |
| 740 | + flush_put_bits(&pb); |
| 741 | + break; |
| 742 | + } |
| 714 | 743 | default: |
| 715 | 744 | return AVERROR(EINVAL); |
| 716 | 745 | } |
| @@ -743,6 +772,7 @@ AVCodec ff_ ## name_ ## _encoder = { \ · 26 unmodified lines |
| 743 | 772 | .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \ |
| 744 | 773 | } |
| 745 | 774 | |
| 775 | +ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_APM, adpcm_ima_apm, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Ubisoft APM"); |
| 746 | 776 | ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, sample_fmts_p, 0, "ADPCM IMA QuickTime"); |
| 747 | 777 | ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_SSI, adpcm_ima_ssi, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Simon & Schuster Interactive"); |
| 748 | 778 | ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav, sample_fmts_p, 0, "ADPCM IMA WAV"); |