History

avcodec: add ADPCM IMA XBOX decoder

Paul B Mahol committed 2 years ago

Commit c3083b31 parent 095f8039 files · +61 −2Browse files

Unified · Split

9 files
  1. Changelog +1 −0
  2. doc/general_contents.texi +1 −0
  3. libavcodec/Makefile +1 −0
  4. libavcodec/adpcm.c +41 −0
  5. libavcodec/allcodecs.c +1 −0
  6. libavcodec/codec_desc.c +7 −0
  7. libavcodec/codec_id.h +1 −0
  8. libavcodec/utils.c +6 −0
  9. libavcodec/version.h +2 −2
Changelog+1−0
@@ -7,6 +7,7 @@ version <next>: · 6 unmodified lines
77 - RealVideo 6.0 decoder
88 - OpenMAX encoders deprecated
99 - libx265 alpha layer encoding
10+- ADPCM IMA Xbox decoder
1011
1112 version 7.1:
1213 - Raw Captions with Time (RCWT) closed caption demuxer
doc/general_contents.texi+1−0
@@ -1233,6 +1233,7 @@ following image formats are supported: · 1232 unmodified lines
12331233 @item ADPCM IMA Duck DK4 @tab @tab X
12341234 @tab Used in some Sega Saturn console games.
12351235 @item ADPCM IMA Radical @tab @tab X
1236+@item ADPCM IMA Xbox @tab @tab X
12361237 @item ADPCM Microsoft @tab X @tab X
12371238 @item ADPCM MS IMA @tab X @tab X
12381239 @item ADPCM Nintendo Gamecube AFC @tab @tab X
libavcodec/Makefile+1−0
@@ -977,6 +977,7 @@ OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER) += adpcm.o adpcm_data.o · 976 unmodified lines
977977 OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER) += adpcmenc.o adpcm_data.o
978978 OBJS-$(CONFIG_ADPCM_IMA_WS_DECODER) += adpcm.o adpcm_data.o
979979 OBJS-$(CONFIG_ADPCM_IMA_WS_ENCODER) += adpcmenc.o adpcm_data.o
980+OBJS-$(CONFIG_ADPCM_IMA_XBOX_DECODER) += adpcm.o adpcm_data.o
980981 OBJS-$(CONFIG_ADPCM_MS_DECODER) += adpcm.o adpcm_data.o
981982 OBJS-$(CONFIG_ADPCM_MS_ENCODER) += adpcmenc.o adpcm_data.o
982983 OBJS-$(CONFIG_ADPCM_MTAF_DECODER) += adpcm.o adpcm_data.o
libavcodec/adpcm.c+41−0
@@ -307,6 +307,10 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) · 306 unmodified lines
307307 avctx->block_align != 17 * avctx->ch_layout.nb_channels)
308308 return AVERROR_INVALIDDATA;
309309 break;
310+ case AV_CODEC_ID_ADPCM_IMA_XBOX:
311+ if (avctx->bits_per_coded_sample != 4)
312+ return AVERROR_INVALIDDATA;
313+ break;
310314 case AV_CODEC_ID_ADPCM_ZORK:
311315 if (avctx->bits_per_coded_sample != 8)
312316 return AVERROR_INVALIDDATA;
@@ -321,6 +325,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) · 8 unmodified lines
321325 case AV_CODEC_ID_ADPCM_IMA_DAT4:
322326 case AV_CODEC_ID_ADPCM_IMA_QT:
323327 case AV_CODEC_ID_ADPCM_IMA_WAV:
328+ case AV_CODEC_ID_ADPCM_IMA_XBOX:
324329 case AV_CODEC_ID_ADPCM_4XM:
325330 case AV_CODEC_ID_ADPCM_XA:
326331 case AV_CODEC_ID_ADPCM_XMD:
@@ -979,6 +984,15 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, · 652 unmodified lines
979984 return AVERROR_INVALIDDATA;
980985 nb_samples = 1 + (buf_size - 4 * ch) / (bsize * ch) * bsamples;
981986 ) /* End of CASE */
987+ CASE(ADPCM_IMA_XBOX,
988+ int bsize = ff_adpcm_ima_block_sizes[avctx->bits_per_coded_sample - 2];
989+ int bsamples = ff_adpcm_ima_block_samples[avctx->bits_per_coded_sample - 2];
990+ if (avctx->block_align > 0)
991+ buf_size = FFMIN(buf_size, avctx->block_align);
992+ if (buf_size < 4 * ch)
993+ return AVERROR_INVALIDDATA;
994+ nb_samples = (buf_size - 4 * ch) / (bsize * ch) * bsamples + 1;
995+ ) /* End of CASE */
982996 case AV_CODEC_ID_ADPCM_MS:
983997 if (avctx->block_align > 0)
984998 buf_size = FFMIN(buf_size, avctx->block_align);
@@ -1197,6 +1211,32 @@ static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame, · 212 unmodified lines
11971211 }
11981212 }
11991213 ) /* End of CASE */
1214+ CASE(ADPCM_IMA_XBOX,
1215+ for (int i = 0; i < channels; i++) {
1216+ ADPCMChannelStatus *cs = &c->status[i];
1217+ cs->predictor = samples_p[i][0] = sign_extend(bytestream2_get_le16u(&gb), 16);
1218+
1219+ cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16);
1220+ if (cs->step_index > 88u) {
1221+ av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n",
1222+ i, cs->step_index);
1223+ return AVERROR_INVALIDDATA;
1224+ }
1225+ }
1226+
1227+ for (int n = 0; n < (nb_samples-1) / 8; n++) {
1228+ for (int i = 0; i < channels; i++) {
1229+ ADPCMChannelStatus *cs = &c->status[i];
1230+ samples = &samples_p[i][1 + n * 8];
1231+ for (int m = 0; m < 8; m += 2) {
1232+ int v = bytestream2_get_byteu(&gb);
1233+ samples[m ] = adpcm_ima_expand_nibble(cs, v & 0x0F, 3);
1234+ samples[m + 1] = adpcm_ima_expand_nibble(cs, v >> 4 , 3);
1235+ }
1236+ }
1237+ }
1238+ frame->nb_samples--;
1239+ ) /* End of CASE */
12001240 CASE(ADPCM_4XM,
12011241 for (int i = 0; i < channels; i++)
12021242 c->status[i].predictor = sign_extend(bytestream2_get_le16u(&gb), 16);
@@ -2404,6 +2444,7 @@ ADPCM_DECODER(ADPCM_IMA_SMJPEG, sample_fmts_s16, adpcm_ima_smjpeg, "ADPCM IMA · 1201 unmodified lines
24042444 ADPCM_DECODER(ADPCM_IMA_ALP, sample_fmts_s16, adpcm_ima_alp, "ADPCM IMA High Voltage Software ALP")
24052445 ADPCM_DECODER(ADPCM_IMA_WAV, sample_fmts_s16p, adpcm_ima_wav, "ADPCM IMA WAV")
24062446 ADPCM_DECODER(ADPCM_IMA_WS, sample_fmts_both, adpcm_ima_ws, "ADPCM IMA Westwood")
2447+ADPCM_DECODER(ADPCM_IMA_XBOX, sample_fmts_s16p, adpcm_ima_xbox, "ADPCM IMA Xbox")
24072448 ADPCM_DECODER(ADPCM_MS, sample_fmts_both, adpcm_ms, "ADPCM Microsoft")
24082449 ADPCM_DECODER(ADPCM_MTAF, sample_fmts_s16p, adpcm_mtaf, "ADPCM MTAF")
24092450 ADPCM_DECODER(ADPCM_PSX, sample_fmts_s16p, adpcm_psx, "ADPCM Playstation")
libavcodec/allcodecs.c+1−0
@@ -686,6 +686,7 @@ extern const FFCodec ff_adpcm_ima_wav_encoder; · 685 unmodified lines
686686 extern const FFCodec ff_adpcm_ima_wav_decoder;
687687 extern const FFCodec ff_adpcm_ima_ws_encoder;
688688 extern const FFCodec ff_adpcm_ima_ws_decoder;
689+extern const FFCodec ff_adpcm_ima_xbox_decoder;
689690 extern const FFCodec ff_adpcm_ms_encoder;
690691 extern const FFCodec ff_adpcm_ms_decoder;
691692 extern const FFCodec ff_adpcm_mtaf_decoder;
libavcodec/codec_desc.c+7−0
@@ -2597,6 +2597,13 @@ static const AVCodecDescriptor codec_descriptors[] = { · 2596 unmodified lines
25972597 .long_name = NULL_IF_CONFIG_SMALL("ADPCM Konami XMD"),
25982598 .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
25992599 },
2600+ {
2601+ .id = AV_CODEC_ID_ADPCM_IMA_XBOX,
2602+ .type = AVMEDIA_TYPE_AUDIO,
2603+ .name = "adpcm_ima_xbox",
2604+ .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Xbox"),
2605+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
2606+ },
26002607
26012608 /* AMR */
26022609 {
libavcodec/codec_id.h+1−0
@@ -422,6 +422,7 @@ enum AVCodecID { · 421 unmodified lines
422422 AV_CODEC_ID_ADPCM_IMA_MOFLEX,
423423 AV_CODEC_ID_ADPCM_IMA_ACORN,
424424 AV_CODEC_ID_ADPCM_XMD,
425+ AV_CODEC_ID_ADPCM_IMA_XBOX,
425426
426427 /* AMR */
427428 AV_CODEC_ID_AMR_NB = 0x12000,
libavcodec/utils.c+6−0
@@ -558,6 +558,7 @@ int av_get_bits_per_sample(enum AVCodecID codec_id) · 557 unmodified lines
558558 return 3;
559559 case AV_CODEC_ID_ADPCM_SBPRO_4:
560560 case AV_CODEC_ID_ADPCM_IMA_WAV:
561+ case AV_CODEC_ID_ADPCM_IMA_XBOX:
561562 case AV_CODEC_ID_ADPCM_IMA_QT:
562563 case AV_CODEC_ID_ADPCM_SWF:
563564 case AV_CODEC_ID_ADPCM_MS:
@@ -720,6 +721,11 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, · 156 unmodified lines
720721 int blocks = frame_bytes / ba;
721722 int64_t tmp = 0;
722723 switch (id) {
724+ case AV_CODEC_ID_ADPCM_IMA_XBOX:
725+ if (bps != 4)
726+ return 0;
727+ tmp = blocks * ((ba - 4 * ch) / (bps * ch) * 8);
728+ break;
723729 case AV_CODEC_ID_ADPCM_IMA_WAV:
724730 if (bps < 2 || bps > 5)
725731 return 0;
libavcodec/version.h+2−2
@@ -29,8 +29,8 @@ · 28 unmodified lines
2929
3030 #include "version_major.h"
3131
32−#define LIBAVCODEC_VERSION_MINOR 27
33−#define LIBAVCODEC_VERSION_MICRO 101
32+#define LIBAVCODEC_VERSION_MINOR 28
33+#define LIBAVCODEC_VERSION_MICRO 100
3434
3535 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
3636 LIBAVCODEC_VERSION_MINOR, \

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