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
11- Rayman 2 APM muxer11- Rayman 2 APM muxer
12- AV1 encoding support SVT-AV112- AV1 encoding support SVT-AV1
13- Cineform HD encoder13- Cineform HD encoder
14- ADPCM Argonaut Games encoder
14 15
15 16
16version 4.3:17version 4.3:
doc/general.texi+1−1
@@ -1098,7 +1098,7 @@ following image formats are supported: · 1097 unmodified lines
1098@item ACELP.KELVIN @tab @tab X1098@item ACELP.KELVIN @tab @tab X
1099@item ADPCM 4X Movie @tab @tab X1099@item ADPCM 4X Movie @tab @tab X
1100@item APDCM Yamaha AICA @tab @tab X1100@item APDCM Yamaha AICA @tab @tab X
1101@item ADPCM Argonaut Games @tab @tab X1101@item ADPCM Argonaut Games @tab X @tab X
1102@item ADPCM CDROM XA @tab @tab X1102@item ADPCM CDROM XA @tab @tab X
1103@item ADPCM Creative Technology @tab @tab X1103@item ADPCM Creative Technology @tab @tab X
1104 @tab 16 -> 4, 8 -> 4, 8 -> 3, 8 -> 21104 @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
837OBJS-$(CONFIG_ADPCM_AGM_DECODER) += adpcm.o adpcm_data.o837OBJS-$(CONFIG_ADPCM_AGM_DECODER) += adpcm.o adpcm_data.o
838OBJS-$(CONFIG_ADPCM_AICA_DECODER) += adpcm.o adpcm_data.o838OBJS-$(CONFIG_ADPCM_AICA_DECODER) += adpcm.o adpcm_data.o
839OBJS-$(CONFIG_ADPCM_ARGO_DECODER) += adpcm.o adpcm_data.o839OBJS-$(CONFIG_ADPCM_ARGO_DECODER) += adpcm.o adpcm_data.o
840OBJS-$(CONFIG_ADPCM_ARGO_ENCODER) += adpcm.o adpcmenc.o
840OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o adpcm_data.o841OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o adpcm_data.o
841OBJS-$(CONFIG_ADPCM_DTK_DECODER) += adpcm.o adpcm_data.o842OBJS-$(CONFIG_ADPCM_DTK_DECODER) += adpcm.o adpcm_data.o
842OBJS-$(CONFIG_ADPCM_EA_DECODER) += adpcm.o adpcm_data.o843OBJS-$(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
78 }78 }
79 79
80 if (avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_SSI ||80 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) {
82 /*83 /*
83 * The current trellis implementation doesn't work for extended84 * The current trellis implementation doesn't work for extended
84 * runs of samples without periodic resets. Disallow it.85 * runs of samples without periodic resets. Disallow it.
@@ -156,6 +157,10 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) · 71 unmodified lines
156 return AVERROR(ENOMEM);157 return AVERROR(ENOMEM);
157 avctx->extradata_size = 28;158 avctx->extradata_size = 28;
158 break;159 break;
160 case AV_CODEC_ID_ADPCM_ARGO:
161 avctx->frame_size = 32;
162 avctx->block_align = 17 * avctx->channels;
163 break;
159 default:164 default:
160 return AVERROR(EINVAL);165 return AVERROR(EINVAL);
161 }166 }
@@ -481,6 +486,46 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, · 319 unmodified lines
481 c->idelta = nodes[0]->step;486 c->idelta = nodes[0]->step;
482}487}
483 488
489static 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
502static 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
484static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,529static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
485 const AVFrame *frame, int *got_packet_ptr)530 const AVFrame *frame, int *got_packet_ptr)
486{531{
@@ -741,6 +786,44 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, · 254 unmodified lines
741 flush_put_bits(&pb);786 flush_put_bits(&pb);
742 break;787 break;
743 }788 }
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 }
744 default:827 default:
745 return AVERROR(EINVAL);828 return AVERROR(EINVAL);
746 }829 }
@@ -773,6 +856,7 @@ AVCodec ff_ ## name_ ## _encoder = { \ · 26 unmodified lines
773 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \856 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \
774}857}
775 858
859ADPCM_ENCODER(AV_CODEC_ID_ADPCM_ARGO, adpcm_argo, sample_fmts_p, 0, "ADPCM Argonaut Games");
776ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_APM, adpcm_ima_apm, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Ubisoft APM");860ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_APM, adpcm_ima_apm, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Ubisoft APM");
777ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, sample_fmts_p, 0, "ADPCM IMA QuickTime");861ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, sample_fmts_p, 0, "ADPCM IMA QuickTime");
778ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_SSI, adpcm_ima_ssi, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Simon & Schuster Interactive");862ADPCM_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
591extern AVCodec ff_adpcm_agm_decoder;591extern AVCodec ff_adpcm_agm_decoder;
592extern AVCodec ff_adpcm_aica_decoder;592extern AVCodec ff_adpcm_aica_decoder;
593extern AVCodec ff_adpcm_argo_decoder;593extern AVCodec ff_adpcm_argo_decoder;
594extern AVCodec ff_adpcm_argo_encoder;
594extern AVCodec ff_adpcm_ct_decoder;595extern AVCodec ff_adpcm_ct_decoder;
595extern AVCodec ff_adpcm_dtk_decoder;596extern AVCodec ff_adpcm_dtk_decoder;
596extern AVCodec ff_adpcm_ea_decoder;597extern 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
1479 switch (codec_id) {1479 switch (codec_id) {
1480 case AV_CODEC_ID_8SVX_EXP:1480 case AV_CODEC_ID_8SVX_EXP:
1481 case AV_CODEC_ID_8SVX_FIB:1481 case AV_CODEC_ID_8SVX_FIB:
1482 case AV_CODEC_ID_ADPCM_ARGO:
1482 case AV_CODEC_ID_ADPCM_CT:1483 case AV_CODEC_ID_ADPCM_CT:
1483 case AV_CODEC_ID_ADPCM_IMA_APC:1484 case AV_CODEC_ID_ADPCM_IMA_APC:
1484 case AV_CODEC_ID_ADPCM_IMA_APM:1485 case AV_CODEC_ID_ADPCM_IMA_APM:
libavcodec/version.h+1−1
@@ -28,7 +28,7 @@ · 27 unmodified lines
28#include "libavutil/version.h"28#include "libavutil/version.h"
29 29
30#define LIBAVCODEC_VERSION_MAJOR 5830#define LIBAVCODEC_VERSION_MAJOR 58
31#define LIBAVCODEC_VERSION_MINOR 9931#define LIBAVCODEC_VERSION_MINOR 100
32#define LIBAVCODEC_VERSION_MICRO 10032#define LIBAVCODEC_VERSION_MICRO 100
33 33
34#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \34#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