History

avcodec: add adpcm_ima_amv encoder

Fixes ticket #747.

Zane van Iperen committed 6 years ago

Commit 555f5c11 parent 8903cb34 files · +60 −2Browse files

Unified · Split

4 files
  1. doc/general_contents.texi +1 −1
  2. libavcodec/adpcmenc.c +57 −1
  3. libavcodec/allcodecs.c +1 −0
  4. libavcodec/utils.c +1 −0
doc/general_contents.texi+1−1
@@ -1106,7 +1106,7 @@ following image formats are supported: · 1105 unmodified lines
1106@item ADPCM Electronic Arts XAS @tab @tab X1106@item ADPCM Electronic Arts XAS @tab @tab X
1107@item ADPCM G.722 @tab X @tab X1107@item ADPCM G.722 @tab X @tab X
1108@item ADPCM G.726 @tab X @tab X1108@item ADPCM G.726 @tab X @tab X
1109@item ADPCM IMA AMV @tab @tab X1109@item ADPCM IMA AMV @tab X @tab X
1110 @tab Used in AMV files1110 @tab Used in AMV files
1111@item ADPCM IMA Cunning Developments @tab @tab X1111@item ADPCM IMA Cunning Developments @tab @tab X
1112@item ADPCM IMA Electronic Arts EACS @tab @tab X1112@item ADPCM IMA Electronic Arts EACS @tab @tab X
libavcodec/adpcmenc.c+57−1
@@ -74,7 +74,12 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) · 73 unmodified lines
74 return AVERROR(EINVAL);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 av_log(avctx, AV_LOG_ERROR, "block size must be power of 2\n");83 av_log(avctx, AV_LOG_ERROR, "block size must be power of 2\n");
79 return AVERROR(EINVAL);84 return AVERROR(EINVAL);
80 }85 }
@@ -161,6 +166,20 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) · 80 unmodified lines
161 avctx->frame_size = s->block_size * 2 / avctx->channels;166 avctx->frame_size = s->block_size * 2 / avctx->channels;
162 avctx->block_align = s->block_size;167 avctx->block_align = s->block_size;
163 break;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 case AV_CODEC_ID_ADPCM_IMA_APM:183 case AV_CODEC_ID_ADPCM_IMA_APM:
165 avctx->frame_size = s->block_size * 2 / avctx->channels;184 avctx->frame_size = s->block_size * 2 / avctx->channels;
166 avctx->block_align = s->block_size;185 avctx->block_align = s->block_size;
@@ -338,6 +357,7 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, · 171 unmodified lines
338 nodes[0]->sample2 = c->sample2;357 nodes[0]->sample2 = c->sample2;
339 if (version == AV_CODEC_ID_ADPCM_IMA_WAV ||358 if (version == AV_CODEC_ID_ADPCM_IMA_WAV ||
340 version == AV_CODEC_ID_ADPCM_IMA_QT ||359 version == AV_CODEC_ID_ADPCM_IMA_QT ||
360 version == AV_CODEC_ID_ADPCM_IMA_AMV ||
341 version == AV_CODEC_ID_ADPCM_SWF)361 version == AV_CODEC_ID_ADPCM_SWF)
342 nodes[0]->sample1 = c->prev_sample;362 nodes[0]->sample1 = c->prev_sample;
343 if (version == AV_CODEC_ID_ADPCM_MS)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 } else if (version == AV_CODEC_ID_ADPCM_IMA_WAV ||463 } else if (version == AV_CODEC_ID_ADPCM_IMA_WAV ||
444 version == AV_CODEC_ID_ADPCM_IMA_QT ||464 version == AV_CODEC_ID_ADPCM_IMA_QT ||
465 version == AV_CODEC_ID_ADPCM_IMA_AMV ||
445 version == AV_CODEC_ID_ADPCM_SWF) {466 version == AV_CODEC_ID_ADPCM_SWF) {
446#define LOOP_NODES(NAME, STEP_TABLE, STEP_INDEX)\467#define LOOP_NODES(NAME, STEP_TABLE, STEP_INDEX)\
447 const int predictor = nodes[j]->sample1;\468 const int predictor = nodes[j]->sample1;\
@@ -834,6 +855,40 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, · 386 unmodified lines
834 flush_put_bits(&pb);855 flush_put_bits(&pb);
835 break;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 case AV_CODEC_ID_ADPCM_ARGO:892 case AV_CODEC_ID_ADPCM_ARGO:
838 {893 {
839 PutBitContext pb;894 PutBitContext pb;
@@ -927,6 +982,7 @@ AVCodec ff_ ## name_ ## _encoder = { \ · 87 unmodified lines
927}982}
928 983
929ADPCM_ENCODER(AV_CODEC_ID_ADPCM_ARGO, adpcm_argo, sample_fmts_p, 0, "ADPCM Argonaut Games");984ADPCM_ENCODER(AV_CODEC_ID_ADPCM_ARGO, adpcm_argo, sample_fmts_p, 0, "ADPCM Argonaut Games");
985ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_AMV, adpcm_ima_amv, sample_fmts, 0, "ADPCM IMA AMV");
930ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_APM, adpcm_ima_apm, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Ubisoft APM");986ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_APM, adpcm_ima_apm, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Ubisoft APM");
931ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_ALP, adpcm_ima_alp, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA High Voltage Software ALP");987ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_ALP, adpcm_ima_alp, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA High Voltage Software ALP");
932ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, sample_fmts_p, 0, "ADPCM IMA QuickTime");988ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, sample_fmts_p, 0, "ADPCM IMA QuickTime");
libavcodec/allcodecs.c+1−0
@@ -614,6 +614,7 @@ extern AVCodec ff_adpcm_g726_decoder; · 613 unmodified lines
614extern AVCodec ff_adpcm_g726le_encoder;614extern AVCodec ff_adpcm_g726le_encoder;
615extern AVCodec ff_adpcm_g726le_decoder;615extern AVCodec ff_adpcm_g726le_decoder;
616extern AVCodec ff_adpcm_ima_amv_decoder;616extern AVCodec ff_adpcm_ima_amv_decoder;
617extern AVCodec ff_adpcm_ima_amv_encoder;
617extern AVCodec ff_adpcm_ima_alp_decoder;618extern AVCodec ff_adpcm_ima_alp_decoder;
618extern AVCodec ff_adpcm_ima_alp_encoder;619extern AVCodec ff_adpcm_ima_alp_encoder;
619extern AVCodec ff_adpcm_ima_apc_decoder;620extern AVCodec ff_adpcm_ima_apc_decoder;
libavcodec/utils.c+1−0
@@ -1491,6 +1491,7 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id) · 1490 unmodified lines
1491 case AV_CODEC_ID_ADPCM_ARGO:1491 case AV_CODEC_ID_ADPCM_ARGO:
1492 case AV_CODEC_ID_ADPCM_CT:1492 case AV_CODEC_ID_ADPCM_CT:
1493 case AV_CODEC_ID_ADPCM_IMA_ALP:1493 case AV_CODEC_ID_ADPCM_IMA_ALP:
1494 case AV_CODEC_ID_ADPCM_IMA_AMV:
1494 case AV_CODEC_ID_ADPCM_IMA_APC:1495 case AV_CODEC_ID_ADPCM_IMA_APC:
1495 case AV_CODEC_ID_ADPCM_IMA_APM:1496 case AV_CODEC_ID_ADPCM_IMA_APM:
1496 case AV_CODEC_ID_ADPCM_IMA_EA_SEAD:1497 case AV_CODEC_ID_ADPCM_IMA_EA_SEAD:

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t