| @@ -74,7 +74,12 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) · 73 unmodified lines |
| 74 | 74 | return AVERROR(EINVAL); |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | | − if (s->block_size & (s->block_size - 1)) { |
| 77 | + /* |
| 78 | + * AMV's block size has to match that of the corresponding video |
| 79 | + * stream. Relax the POT requirement. |
| 80 | + */ |
| 81 | + if (avctx->codec->id != AV_CODEC_ID_ADPCM_IMA_AMV && |
| 82 | + (s->block_size & (s->block_size - 1))) { |
| 78 | 83 | av_log(avctx, AV_LOG_ERROR, "block size must be power of 2\n"); |
| 79 | 84 | return AVERROR(EINVAL); |
| 80 | 85 | } |
| @@ -161,6 +166,20 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) · 80 unmodified lines |
| 161 | 166 | avctx->frame_size = s->block_size * 2 / avctx->channels; |
| 162 | 167 | avctx->block_align = s->block_size; |
| 163 | 168 | break; |
| 169 | + case AV_CODEC_ID_ADPCM_IMA_AMV: |
| 170 | + if (avctx->sample_rate != 22050) { |
| 171 | + av_log(avctx, AV_LOG_ERROR, "Sample rate must be 22050\n"); |
| 172 | + return AVERROR(EINVAL); |
| 173 | + } |
| 174 | + |
| 175 | + if (avctx->channels != 1) { |
| 176 | + av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n"); |
| 177 | + return AVERROR(EINVAL); |
| 178 | + } |
| 179 | + |
| 180 | + avctx->frame_size = s->block_size; |
| 181 | + avctx->block_align = 8 + (FFALIGN(avctx->frame_size, 2) / 2); |
| 182 | + break; |
| 164 | 183 | case AV_CODEC_ID_ADPCM_IMA_APM: |
| 165 | 184 | avctx->frame_size = s->block_size * 2 / avctx->channels; |
| 166 | 185 | avctx->block_align = s->block_size; |
| @@ -338,6 +357,7 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, · 171 unmodified lines |
| 338 | 357 | nodes[0]->sample2 = c->sample2; |
| 339 | 358 | if (version == AV_CODEC_ID_ADPCM_IMA_WAV || |
| 340 | 359 | version == AV_CODEC_ID_ADPCM_IMA_QT || |
| 360 | + version == AV_CODEC_ID_ADPCM_IMA_AMV || |
| 341 | 361 | version == AV_CODEC_ID_ADPCM_SWF) |
| 342 | 362 | nodes[0]->sample1 = c->prev_sample; |
| 343 | 363 | if (version == AV_CODEC_ID_ADPCM_MS) |
| @@ -442,6 +462,7 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, · 98 unmodified lines |
| 442 | 462 | } |
| 443 | 463 | } else if (version == AV_CODEC_ID_ADPCM_IMA_WAV || |
| 444 | 464 | version == AV_CODEC_ID_ADPCM_IMA_QT || |
| 465 | + version == AV_CODEC_ID_ADPCM_IMA_AMV || |
| 445 | 466 | version == AV_CODEC_ID_ADPCM_SWF) { |
| 446 | 467 | #define LOOP_NODES(NAME, STEP_TABLE, STEP_INDEX)\ |
| 447 | 468 | const int predictor = nodes[j]->sample1;\ |
| @@ -834,6 +855,40 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, · 386 unmodified lines |
| 834 | 855 | flush_put_bits(&pb); |
| 835 | 856 | break; |
| 836 | 857 | } |
| 858 | + case AV_CODEC_ID_ADPCM_IMA_AMV: |
| 859 | + { |
| 860 | + av_assert0(avctx->channels == 1); |
| 861 | + |
| 862 | + c->status[0].prev_sample = *samples; |
| 863 | + bytestream_put_le16(&dst, c->status[0].prev_sample); |
| 864 | + bytestream_put_byte(&dst, c->status[0].step_index); |
| 865 | + bytestream_put_byte(&dst, 0); |
| 866 | + bytestream_put_le32(&dst, avctx->frame_size); |
| 867 | + |
| 868 | + if (avctx->trellis > 0) { |
| 869 | + n = frame->nb_samples >> 1; |
| 870 | + |
| 871 | + if (!(buf = av_malloc(2 * n))) |
| 872 | + return AVERROR(ENOMEM); |
| 873 | + |
| 874 | + adpcm_compress_trellis(avctx, samples, buf, &c->status[0], 2 * n, avctx->channels); |
| 875 | + for (i = 0; i < n; i++) |
| 876 | + bytestream_put_byte(&dst, (buf[2 * i] << 4) | buf[2 * i + 1]); |
| 877 | + |
| 878 | + samples += 2 * n; |
| 879 | + } else for (n = frame->nb_samples >> 1; n > 0; n--) { |
| 880 | + int nibble; |
| 881 | + nibble = adpcm_ima_compress_sample(&c->status[0], *samples++) << 4; |
| 882 | + nibble |= adpcm_ima_compress_sample(&c->status[0], *samples++) & 0x0F; |
| 883 | + bytestream_put_byte(&dst, nibble); |
| 884 | + } |
| 885 | + |
| 886 | + if (avctx->frame_size & 1) { |
| 887 | + int nibble = adpcm_ima_compress_sample(&c->status[0], *samples++) << 4; |
| 888 | + bytestream_put_byte(&dst, nibble); |
| 889 | + } |
| 890 | + break; |
| 891 | + } |
| 837 | 892 | case AV_CODEC_ID_ADPCM_ARGO: |
| 838 | 893 | { |
| 839 | 894 | PutBitContext pb; |
| @@ -927,6 +982,7 @@ AVCodec ff_ ## name_ ## _encoder = { \ · 87 unmodified lines |
| 927 | 982 | } |
| 928 | 983 | |
| 929 | 984 | ADPCM_ENCODER(AV_CODEC_ID_ADPCM_ARGO, adpcm_argo, sample_fmts_p, 0, "ADPCM Argonaut Games"); |
| 985 | +ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_AMV, adpcm_ima_amv, sample_fmts, 0, "ADPCM IMA AMV"); |
| 930 | 986 | ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_APM, adpcm_ima_apm, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Ubisoft APM"); |
| 931 | 987 | ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_ALP, adpcm_ima_alp, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA High Voltage Software ALP"); |
| 932 | 988 | ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, sample_fmts_p, 0, "ADPCM IMA QuickTime"); |