Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH] avcodec/wmaprodec: add xma raw frame decoder (PR #20266)
@ 2025-08-17  8:49 Isaac Marovitz via ffmpeg-devel
  0 siblings, 0 replies; only message in thread
From: Isaac Marovitz via ffmpeg-devel @ 2025-08-17  8:49 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Isaac Marovitz

PR #20266 opened by Isaac Marovitz (IsaacMarovitz)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20266
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20266.patch

packets need to be handled externally
useful for hardware decoder emulation

Co-authored-by: Joel Linn <jl@conductive.de>
Signed-off-by: Isaac Marovitz <isaacryu@icloud.com>


From cc9a634af5b87ab0313fdfe84837532cd6750bb1 Mon Sep 17 00:00:00 2001
From: Isaac Marovitz <isaacryu@icloud.com>
Date: Sun, 6 Jul 2025 13:23:15 +0100
Subject: [PATCH] avcodec/wmaprodec: add xma raw frame decoder

packets need to be handled externally
useful for hardware decoder emulation

Co-authored-by: Joel Linn <jl@conductive.de>
Signed-off-by: Isaac Marovitz <isaacryu@icloud.com>
---
 configure                 |  1 +
 doc/APIchanges            |  3 ++
 doc/general_contents.texi |  2 +
 libavcodec/Makefile       |  1 +
 libavcodec/allcodecs.c    |  1 +
 libavcodec/codec_desc.c   |  7 ++++
 libavcodec/codec_id.h     |  1 +
 libavcodec/version.h      |  2 +-
 libavcodec/wmaprodec.c    | 88 +++++++++++++++++++++++++++++++++++++++
 9 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index e1809a3e58..ea70294559 100755
--- a/configure
+++ b/configure
@@ -3179,6 +3179,7 @@ wmv3_decoder_select="vc1_decoder"
 wmv3image_decoder_select="wmv3_decoder"
 xma1_decoder_select="wmapro_decoder"
 xma2_decoder_select="wmapro_decoder"
+xmaframes_decoder_select="wmapro_decoder"
 ylc_decoder_select="bswapdsp"
 zerocodec_decoder_select="inflate_wrapper"
 zlib_decoder_select="inflate_wrapper"
diff --git a/doc/APIchanges b/doc/APIchanges
index 1ed8337d04..0e88b10a31 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2025-03-28
 
 API changes, most recent first:
 
+2025-08-17 - xxxxxxxxxx - lavc 62.13.100 - codec_id.h
+  Add AV_CODEC_ID_XMAFRAMES.
+
 2025-07-29 - 1c85a3832af - lavc 62.10.100 - smpte_436m.h
   Add a new public header smpte_436m.h with API for
   manipulating AV_CODEC_ID_SMPTE_436M_ANC data.
diff --git a/doc/general_contents.texi b/doc/general_contents.texi
index b9dab580f1..f194a72de2 100644
--- a/doc/general_contents.texi
+++ b/doc/general_contents.texi
@@ -770,6 +770,8 @@ library:
     @tab Audio format used on the PS3.
 @item xWMA                      @tab   @tab X
     @tab Microsoft audio container used by XAudio 2.
+@item XMA Frames                @tab   @tab X
+    @tab Microsoft audio format used in Xbox 360 games.
 @item eXtended BINary text (XBIN) @tab @tab X
 @item YUV4MPEG pipe             @tab X @tab X
 @item Psygnosis YOP             @tab   @tab X
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index fb22541f8d..7dc034907a 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -860,6 +860,7 @@ OBJS-$(CONFIG_XFACE_ENCODER)           += xfaceenc.o xface.o
 OBJS-$(CONFIG_XL_DECODER)              += xl.o
 OBJS-$(CONFIG_XMA1_DECODER)            += wmaprodec.o wma.o wma_common.o
 OBJS-$(CONFIG_XMA2_DECODER)            += wmaprodec.o wma.o wma_common.o
+OBJS-$(CONFIG_XMAFRAMES_DECODER)       += wmaprodec.o wma.o wma_common.o
 OBJS-$(CONFIG_XPM_DECODER)             += xpmdec.o
 OBJS-$(CONFIG_XSUB_DECODER)            += xsubdec.o
 OBJS-$(CONFIG_XSUB_ENCODER)            += xsubenc.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index f5ec2e01e8..a55dbb036e 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -558,6 +558,7 @@ extern const FFCodec ff_wmavoice_decoder;
 extern const FFCodec ff_ws_snd1_decoder;
 extern const FFCodec ff_xma1_decoder;
 extern const FFCodec ff_xma2_decoder;
+extern const FFCodec ff_xmaframes_decoder;
 
 /* PCM codecs */
 extern const FFCodec ff_pcm_alaw_encoder;
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index a065556e51..1f819cb136 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -3306,6 +3306,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .long_name = NULL_IF_CONFIG_SMALL("Xbox Media Audio 2"),
         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
     },
+    {
+        .id        = AV_CODEC_ID_XMAFRAMES,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "xmaframes",
+        .long_name = NULL_IF_CONFIG_SMALL("Xbox Media Audio raw frames"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+    },
     {
         .id        = AV_CODEC_ID_DST,
         .type      = AVMEDIA_TYPE_AUDIO,
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index c4842e61ff..7dfa0052b6 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -604,6 +604,7 @@ enum AVCodecID {
     AV_CODEC_ID_SMPTE_2038,
     AV_CODEC_ID_LCEVC,
     AV_CODEC_ID_SMPTE_436M_ANC,
+    AV_CODEC_ID_XMAFRAMES,
 
 
     AV_CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it
diff --git a/libavcodec/version.h b/libavcodec/version.h
index da2264a097..755c90bbc1 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
 
 #include "version_major.h"
 
-#define LIBAVCODEC_VERSION_MINOR  12
+#define LIBAVCODEC_VERSION_MINOR  13
 #define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c
index d87ed0433e..6cd81ce5ce 100644
--- a/libavcodec/wmaprodec.c
+++ b/libavcodec/wmaprodec.c
@@ -400,6 +400,11 @@ static av_cold int decode_init(WMAProDecodeCtx *s, AVCodecContext *avctx, int nu
         s->bits_per_sample = 16;
         channel_mask       = 0; /* would need to aggregate from all streams */
         s->nb_channels     = edata_ptr[8 + 20*num_stream + 17]; /* nth stream config */
+    } else if (avctx->codec_id == AV_CODEC_ID_XMAFRAMES) {
+        s->decode_flags    = 0x10d6;
+        s->bits_per_sample = 16;
+        channel_mask       = 0;
+        s->nb_channels     = avctx->ch_layout.nb_channels;
     } else if (avctx->codec_id == AV_CODEC_ID_WMAPRO && avctx->extradata_size >= 18) {
         s->decode_flags    = AV_RL16(edata_ptr+14);
         channel_mask       = AV_RL32(edata_ptr+2);
@@ -2082,6 +2087,74 @@ static void xma_flush(AVCodecContext *avctx)
     s->flushed = 0;
 }
 
+static av_cold int xmaframes_decode_init(AVCodecContext* avctx)
+{
+    WMAProDecodeCtx *s = avctx->priv_data;
+
+    avctx->block_align = 2048;
+
+    return decode_init(s, avctx, 0);
+}
+
+static av_cold int xmaframes_decode_end(AVCodecContext* avctx)
+{
+    WMAProDecodeCtx *s = avctx->priv_data;
+
+    decode_end(s);
+
+    return 0;
+}
+
+static int xmaframes_decode_packet(AVCodecContext *avctx, AVFrame *frame,
+                                   int *got_frame_ptr, AVPacket *avpkt)
+{
+    WMAProDecodeCtx *s = avctx->priv_data;
+    GetBitContext* gb = &s->gb;
+    int ret, xma_frame_len = 0;
+    uint8_t padding_start, padding_end = 0;
+
+    if (avpkt->size < 3) {
+        av_log(avctx, AV_LOG_ERROR, "XMA Frame is to small, %d bytes\n", avpkt->size);
+        return AVERROR_INVALIDDATA;
+    }
+
+    s->buf_bit_size = avpkt->size << 3;
+    init_get_bits(gb, avpkt->data, s->buf_bit_size);
+
+    /** get padding sizes from first byte */
+    padding_start = get_bits(gb, 3);
+    padding_end = get_bits(gb, 3);
+    skip_bits(gb, 2);
+
+    /** move bit reader to start of xma frame */
+    skip_bits(gb, padding_start);
+
+
+    /** validate buffer size */
+    xma_frame_len = show_bits(gb, s->log2_frame_size);
+    if (s->buf_bit_size !=
+        8 + padding_start + xma_frame_len + padding_end) {
+        av_log(avctx, AV_LOG_ERROR, "XMA Frame sizing incorrent: \n"
+                                    "   s->buf_bit_size != (8 + padding_start + xma_frame_len + padding_end)\n"
+                                    "=> %d != 8 + (%d + %d + %d)\n",
+               s->buf_bit_size, padding_start, xma_frame_len, padding_end);
+        return AVERROR_INVALIDDATA;
+    }
+
+    save_bits(s, gb, xma_frame_len, 0);
+
+    /** get output buffer */
+    frame->nb_samples = s->samples_per_frame;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
+        s->packet_loss = 1;
+        return 0;
+    }
+
+    decode_frame(s, frame, got_frame_ptr);
+
+    return avpkt->size;
+}
+
 /**
  *@brief wmapro decoder
  */
@@ -2129,3 +2202,18 @@ const FFCodec ff_xma2_decoder = {
     CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP),
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
 };
+
+const FFCodec ff_xmaframes_decoder = {
+    .p.name         = "xmaframes",
+    CODEC_LONG_NAME("Xbox Media Audio raw frames"),
+    .p.type         = AVMEDIA_TYPE_AUDIO,
+    .p.id           = AV_CODEC_ID_XMAFRAMES,
+    .priv_data_size = sizeof(WMAProDecodeCtx),
+    .init           = xmaframes_decode_init,
+    .close          = xmaframes_decode_end,
+    FF_CODEC_DECODE_CB(xmaframes_decode_packet),
+    .flush          = wmapro_flush,
+    .p.capabilities = AV_CODEC_CAP_DR1,
+    CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP),
+    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
+};
-- 
2.49.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2025-08-17  8:49 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-08-17  8:49 [FFmpeg-devel] [PATCH] avcodec/wmaprodec: add xma raw frame decoder (PR #20266) Isaac Marovitz via ffmpeg-devel

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git