History

avcodec: add adpcm_argo encoder

Zane van Iperen committed 6 years ago

Commit 62da99e1 parent 5d1e1dd7 files · +91 −3Browse files

Unified · Split

7 files
  1. Changelog +1 −0
  2. doc/general.texi +1 −1
  3. libavcodec/Makefile +1 −0
  4. libavcodec/adpcmenc.c +85 −1
  5. libavcodec/allcodecs.c +1 −0
  6. libavcodec/utils.c +1 −0
  7. libavcodec/version.h +1 −1
Changelog+1−0
@@ -11,6 +11,7 @@ version <next>: · 10 unmodified lines
1111 - Rayman 2 APM muxer
1212 - AV1 encoding support SVT-AV1
1313 - Cineform HD encoder
14+- ADPCM Argonaut Games encoder
1415
1516
1617 version 4.3:
doc/general.texi+1−1
@@ -1098,7 +1098,7 @@ following image formats are supported: · 1097 unmodified lines
10981098 @item ACELP.KELVIN @tab @tab X
10991099 @item ADPCM 4X Movie @tab @tab X
11001100 @item APDCM Yamaha AICA @tab @tab X
1101−@item ADPCM Argonaut Games @tab @tab X
1101+@item ADPCM Argonaut Games @tab X @tab X
11021102 @item ADPCM CDROM XA @tab @tab X
11031103 @item ADPCM Creative Technology @tab @tab X
11041104 @tab 16 -> 4, 8 -> 4, 8 -> 3, 8 -> 2
libavcodec/Makefile+1−0
@@ -837,6 +837,7 @@ OBJS-$(CONFIG_ADPCM_AFC_DECODER) += adpcm.o adpcm_data.o · 836 unmodified lines
837837 OBJS-$(CONFIG_ADPCM_AGM_DECODER) += adpcm.o adpcm_data.o
838838 OBJS-$(CONFIG_ADPCM_AICA_DECODER) += adpcm.o adpcm_data.o
839839 OBJS-$(CONFIG_ADPCM_ARGO_DECODER) += adpcm.o adpcm_data.o
840+OBJS-$(CONFIG_ADPCM_ARGO_ENCODER) += adpcm.o adpcmenc.o
840841 OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o adpcm_data.o
841842 OBJS-$(CONFIG_ADPCM_DTK_DECODER) += adpcm.o adpcm_data.o
842843 OBJS-$(CONFIG_ADPCM_EA_DECODER) += adpcm.o adpcm_data.o
libavcodec/adpcmenc.c+85−1
@@ -78,7 +78,8 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) · 77 unmodified lines
7878 }
7979
8080 if (avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_SSI ||
81− avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_APM) {
81+ avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_APM ||
82+ avctx->codec->id == AV_CODEC_ID_ADPCM_ARGO) {
8283 /*
8384 * The current trellis implementation doesn't work for extended
8485 * runs of samples without periodic resets. Disallow it.
@@ -156,6 +157,10 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) · 71 unmodified lines
156157 return AVERROR(ENOMEM);
157158 avctx->extradata_size = 28;
158159 break;
160+ case AV_CODEC_ID_ADPCM_ARGO:
161+ avctx->frame_size = 32;
162+ avctx->block_align = 17 * avctx->channels;
163+ break;
159164 default:
160165 return AVERROR(EINVAL);
161166 }
@@ -481,6 +486,46 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, · 319 unmodified lines
481486 c->idelta = nodes[0]->step;
482487 }
483488
489+static inline int adpcm_argo_compress_nibble(const ADPCMChannelStatus *cs, int16_t s,
490+ int shift, int flag)
491+{
492+ int nibble;
493+
494+ if (flag)
495+ nibble = 4 * s - 8 * cs->sample1 + 4 * cs->sample2;
496+ else
497+ nibble = 4 * s - 4 * cs->sample1;
498+
499+ return (nibble >> shift) & 0x0F;
500+}
501+
502+static int64_t adpcm_argo_compress_block(ADPCMChannelStatus *cs, PutBitContext *pb,
503+ const int16_t *samples, int nsamples,
504+ int shift, int flag)
505+{
506+ int64_t error = 0;
507+
508+ if (pb) {
509+ put_bits(pb, 4, shift - 2);
510+ put_bits(pb, 1, 0);
511+ put_bits(pb, 1, !!flag);
512+ put_bits(pb, 2, 0);
513+ }
514+
515+ for (int n = 0; n < nsamples; n++) {
516+ /* Compress the nibble, then expand it to see how much precision we've lost. */
517+ int nibble = adpcm_argo_compress_nibble(cs, samples[n], shift, flag);
518+ int16_t sample = ff_adpcm_argo_expand_nibble(cs, nibble, shift, flag);
519+
520+ error += abs(samples[n] - sample);
521+
522+ if (pb)
523+ put_bits(pb, 4, nibble);
524+ }
525+
526+ return error;
527+}
528+
484529 static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
485530 const AVFrame *frame, int *got_packet_ptr)
486531 {
@@ -741,6 +786,44 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, · 254 unmodified lines
741786 flush_put_bits(&pb);
742787 break;
743788 }
789+ case AV_CODEC_ID_ADPCM_ARGO:
790+ {
791+ PutBitContext pb;
792+ init_put_bits(&pb, dst, pkt_size);
793+
794+ av_assert0(frame->nb_samples == 32);
795+
796+ for (ch = 0; ch < avctx->channels; ch++) {
797+ int64_t error = INT64_MAX, tmperr = INT64_MAX;
798+ int shift = 2, flag = 0;
799+ int saved1 = c->status[ch].sample1;
800+ int saved2 = c->status[ch].sample2;
801+
802+ /* Find the optimal coefficients, bail early if we find a perfect result. */
803+ for (int s = 2; s < 18 && tmperr != 0; s++) {
804+ for (int f = 0; f < 2 && tmperr != 0; f++) {
805+ c->status[ch].sample1 = saved1;
806+ c->status[ch].sample2 = saved2;
807+ tmperr = adpcm_argo_compress_block(c->status + ch, NULL, samples_p[ch],
808+ frame->nb_samples, s, f);
809+ if (tmperr < error) {
810+ shift = s;
811+ flag = f;
812+ error = tmperr;
813+ }
814+ }
815+ }
816+
817+ /* Now actually do the encode. */
818+ c->status[ch].sample1 = saved1;
819+ c->status[ch].sample2 = saved2;
820+ adpcm_argo_compress_block(c->status + ch, &pb, samples_p[ch],
821+ frame->nb_samples, shift, flag);
822+ }
823+
824+ flush_put_bits(&pb);
825+ break;
826+ }
744827 default:
745828 return AVERROR(EINVAL);
746829 }
@@ -773,6 +856,7 @@ AVCodec ff_ ## name_ ## _encoder = { \ · 26 unmodified lines
773856 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \
774857 }
775858
859+ADPCM_ENCODER(AV_CODEC_ID_ADPCM_ARGO, adpcm_argo, sample_fmts_p, 0, "ADPCM Argonaut Games");
776860 ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_APM, adpcm_ima_apm, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Ubisoft APM");
777861 ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, sample_fmts_p, 0, "ADPCM IMA QuickTime");
778862 ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_SSI, adpcm_ima_ssi, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Simon & Schuster Interactive");
libavcodec/allcodecs.c+1−0
@@ -591,6 +591,7 @@ extern AVCodec ff_adpcm_afc_decoder; · 590 unmodified lines
591591 extern AVCodec ff_adpcm_agm_decoder;
592592 extern AVCodec ff_adpcm_aica_decoder;
593593 extern AVCodec ff_adpcm_argo_decoder;
594+extern AVCodec ff_adpcm_argo_encoder;
594595 extern AVCodec ff_adpcm_ct_decoder;
595596 extern AVCodec ff_adpcm_dtk_decoder;
596597 extern AVCodec ff_adpcm_ea_decoder;
libavcodec/utils.c+1−0
@@ -1479,6 +1479,7 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id) · 1478 unmodified lines
14791479 switch (codec_id) {
14801480 case AV_CODEC_ID_8SVX_EXP:
14811481 case AV_CODEC_ID_8SVX_FIB:
1482+ case AV_CODEC_ID_ADPCM_ARGO:
14821483 case AV_CODEC_ID_ADPCM_CT:
14831484 case AV_CODEC_ID_ADPCM_IMA_APC:
14841485 case AV_CODEC_ID_ADPCM_IMA_APM:
libavcodec/version.h+1−1
@@ -28,7 +28,7 @@ · 27 unmodified lines
2828 #include "libavutil/version.h"
2929
3030 #define LIBAVCODEC_VERSION_MAJOR 58
31−#define LIBAVCODEC_VERSION_MINOR 99
31+#define LIBAVCODEC_VERSION_MINOR 100
3232 #define LIBAVCODEC_VERSION_MICRO 100
3333
3434 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \

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