This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 57708daf619c1de0ea25366ef11e527f292acd55 Author: James Almer <[email protected]> AuthorDate: Thu Jun 4 14:51:57 2026 -0300 Commit: James Almer <[email protected]> CommitDate: Sat Jul 11 19:32:17 2026 -0300 avcodec/dca_core: export downmix matrix coefficients $ ./ffmpeg -downmix stereo -i $fate-suite/dts/dcadec-suite/core_51_24_48_768_1.dtshd -y native.wav Before: $ ./ffmpeg -i $fate-suite/dts/dcadec-suite/core_51_24_48_768_1.dtshd -af aresample,aformat=channel_layouts=stereo -y swr.wav [...] [Parsed_aresample_0] [SWR] Using fltp internally between filters [Parsed_aresample_0] [SWR] Matrix coefficients: [Parsed_aresample_0] [SWR] FL: FL:0.414214 FR:0.000000 FC:0.292893 LFE:0.000000 SL:0.292893 SR:0.000000 [Parsed_aresample_0] [SWR] FR: FL:0.000000 FR:0.414214 FC:0.292893 LFE:0.000000 SL:0.000000 SR:0.292893 [Parsed_aresample_0] ch:6 chl:5.1(side) fmt:fltp r:48000Hz -> ch:2 chl:stereo fmt:s16 r:48000Hz [...] $ tests/tiny_psnr.exe native.wav swr.wav s16 stddev:18907.06 PSNR: 10.80 MAXDIFF:51590 bytes: 8192/ 8192 After: $ ./ffmpeg -i $fate-suite/dts/dcadec-suite/core_51_24_48_768_1.dtshd -af aresample,aformat=channel_layouts=stereo -y swr.wav [...] [Parsed_aresample_0] [SWR] Using fltp internally between filters [Parsed_aresample_0] [SWR] Custom matrix coefficients: [Parsed_aresample_0] [SWR] FL: FL:-0.100006 FR:0.000000 FC:0.000000 LFE:0.000000 SL:-0.707092 SR:0.000000 [Parsed_aresample_0] [SWR] FR: FL:0.000000 FR:-0.100006 FC:0.000000 LFE:0.000000 SL:0.000000 SR:-0.707092 [Parsed_aresample_0] ch:6 chl:5.1(side) fmt:fltp r:48000Hz -> ch:2 chl:stereo fmt:s16 r:48000Hz [...] $ tests/tiny_psnr.exe native.wav swr.wav stddev: 0.02 PSNR:129.44 MAXDIFF: 1 bytes: 8192/ 8192 Signed-off-by: James Almer <[email protected]> --- libavcodec/dca_core.c | 11 +++++++ libavcodec/dcadec.c | 79 ++++++++++++++++++++++++++++++++++++++++++++------- libavcodec/dcadec.h | 3 ++ tests/fate/dca.mak | 5 +++- 4 files changed, 87 insertions(+), 11 deletions(-) diff --git a/libavcodec/dca_core.c b/libavcodec/dca_core.c index cb1f7b7bbf..8383358b97 100644 --- a/libavcodec/dca_core.c +++ b/libavcodec/dca_core.c @@ -2384,6 +2384,17 @@ int ff_dca_core_filter_frame(DCACoreDecoder *s, AVFrame *frame) else avctx->bit_rate = 0; + if (s->request_mask == s->ch_mask && s->prim_dmix_embedded && + !s->sumdiff_front && !s->sumdiff_surround && + !(s->ext_audio_mask & (DCA_CSS_XXCH | DCA_CSS_XCH | DCA_EXSS_XXCH)) && + s->audio_mode >= DCA_AMODE_2F2R && (s->prim_dmix_type == DCA_DMIX_TYPE_LoRo || + s->prim_dmix_type == DCA_DMIX_TYPE_LtRt)) { + ret = ff_dca_export_downmix_matrix(avctx, frame, s->prim_dmix_type, s->ch_mask, + s->prim_dmix_coeff); + if (ret < 0) + return ret; + } + if (s->audio_mode == DCA_AMODE_STEREO_TOTAL || (s->request_mask != s->ch_mask && s->prim_dmix_type == DCA_DMIX_TYPE_LtRt)) matrix_encoding = AV_MATRIX_ENCODING_DOLBY; diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c index 7fbd2c6e3f..55308abfd1 100644 --- a/libavcodec/dcadec.c +++ b/libavcodec/dcadec.c @@ -21,10 +21,12 @@ #include "libavutil/mem.h" #include "libavutil/opt.h" #include "libavutil/channel_layout.h" +#include "libavutil/downmix_info.h" #include "libavutil/thread.h" #include "codec_internal.h" #include "dcadec.h" +#include "dcadata.h" #include "dcahuff.h" #include "dca_syncwords.h" #include "profiles.h" @@ -32,18 +34,19 @@ #define MIN_PACKET_SIZE 16 #define MAX_PACKET_SIZE 0x104000 -int ff_dca_set_channel_layout(AVCodecContext *avctx, int *ch_remap, int dca_mask) -{ - static const uint8_t dca2wav_norm[28] = { - 2, 0, 1, 9, 10, 3, 8, 4, 5, 9, 10, 6, 7, 12, - 13, 14, 3, 6, 7, 11, 12, 14, 16, 15, 17, 8, 4, 5, - }; - static const uint8_t dca2wav_wide[28] = { - 2, 0, 1, 4, 5, 3, 8, 4, 5, 9, 10, 6, 7, 12, - 13, 14, 3, 6, 7, 11, 12, 14, 16, 15, 17, 8, 4, 5, - }; +static const uint8_t dca2wav_norm[28] = { + 2, 0, 1, 9, 10, 3, 8, 4, 5, 9, 10, 6, 7, 12, + 13, 14, 3, 6, 7, 11, 12, 14, 16, 15, 17, 8, 4, 5, +}; + +static const uint8_t dca2wav_wide[28] = { + 2, 0, 1, 4, 5, 3, 8, 4, 5, 9, 10, 6, 7, 12, + 13, 14, 3, 6, 7, 11, 12, 14, 16, 15, 17, 8, 4, 5, +}; +int ff_dca_set_channel_layout(AVCodecContext *avctx, int *ch_remap, int dca_mask) +{ DCAContext *s = avctx->priv_data; int dca_ch, wav_ch, nchannels = 0; @@ -156,6 +159,62 @@ void ff_dca_downmix_to_stereo_float(AVFloatDSPContext *fdsp, float **samples, } } +int ff_dca_export_downmix_matrix(AVCodecContext *avctx, AVFrame *frame, + enum DCADownMixType downmix_type, + int output_mask, const int *coeff_l) +{ + enum AVDownmixType dmix_type = (downmix_type == DCA_DMIX_TYPE_LoRo) ? + AV_DOWNMIX_TYPE_LORO : AV_DOWNMIX_TYPE_LTRT; + size_t size; + AVDownmixMatrix *dm = av_downmix_matrix_alloc(dmix_type, av_popcount(output_mask), &size); + const int *coeff_r = coeff_l + av_popcount(output_mask); + const double scale = 1.0 / (1 << 15); + AVDownmixCoeff *matrix_l, *matrix_r; + const uint8_t *dca2wav; + + if (!dm) + return AVERROR(ENOMEM); + + if (output_mask == DCA_SPEAKER_LAYOUT_7POINT0_WIDE || + output_mask == DCA_SPEAKER_LAYOUT_7POINT1_WIDE) + dca2wav = dca2wav_wide; + else + dca2wav = dca2wav_norm; + + matrix_l = av_downmix_matrix_coeff(dm, 0, 0); + matrix_r = av_downmix_matrix_coeff(dm, 1, 0); + + for (int i = 0; i <= av_log2(output_mask); i++) { + if (!(output_mask & (1U << i))) + continue; + + int idx = av_channel_layout_index_from_channel(&avctx->ch_layout, dca2wav[i]); + av_assert0(idx >= 0); + + if (*coeff_l) + matrix_l[idx] = *coeff_l * scale; + + if (*coeff_r) + matrix_r[idx] = *coeff_r * scale; + + coeff_l++; + coeff_r++; + } + + AVBufferRef *buf = av_buffer_create((uint8_t *)dm, size, NULL, NULL, 0); + if (!buf) { + av_free(dm); + return AVERROR(ENOMEM); + } + + if (!av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_DOWNMIX_MATRIX, buf)) { + av_buffer_unref(&buf); + return AVERROR(ENOMEM); + } + + return 0; +} + static int dcadec_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt) { diff --git a/libavcodec/dcadec.h b/libavcodec/dcadec.h index 0ff28dd4d1..b54eeb99d5 100644 --- a/libavcodec/dcadec.h +++ b/libavcodec/dcadec.h @@ -80,6 +80,9 @@ void ff_dca_downmix_to_stereo_fixed(DCADSPContext *dcadsp, int32_t **samples, int *coeff_l, int nsamples, int ch_mask); void ff_dca_downmix_to_stereo_float(AVFloatDSPContext *fdsp, float **samples, int *coeff_l, int nsamples, int ch_mask); +int ff_dca_export_downmix_matrix(AVCodecContext *avctx, AVFrame *frame, + enum DCADownMixType downmix_type, + int output_mask, const int *coeff_l); static inline int ff_dca_check_crc(AVCodecContext *avctx, GetBitContext *s, int p1, int p2) diff --git a/tests/fate/dca.mak b/tests/fate/dca.mak index 609f924aa3..e083d6fd28 100644 --- a/tests/fate/dca.mak +++ b/tests/fate/dca.mak @@ -39,10 +39,13 @@ $(foreach N,$(DCADEC_SUITE_LOSSLESS_24),$(eval $(call FATE_DCADEC_LOSSLESS_SUITE $(foreach N,$(DCADEC_SUITE_LOSSY),$(eval $(call FATE_DCADEC_LOSSY_SUITE,$(N)))) # lossy downmix tests -FATE_DCADEC_LOSSY += fate-dca-core_51_24_48_768_1-dmix_2 +FATE_DCADEC_LOSSY += fate-dca-core_51_24_48_768_1-dmix_2 fate-dca-core_51_24_48_768_1-dmix_2_matrix fate-dca-core_51_24_48_768_1-dmix_2: CMD = ffmpeg -downmix stereo -flags2 skip_manual -i $(TARGET_SAMPLES)/dts/dcadec-suite/core_51_24_48_768_1.dtshd -f f32le -af aresample - fate-dca-core_51_24_48_768_1-dmix_2: REF = $(SAMPLES)/dts/dcadec-suite/core_51_24_48_768_1-dmix_2.f32 +fate-dca-core_51_24_48_768_1-dmix_2_matrix: CMD = ffmpeg -flags2 skip_manual -i $(TARGET_SAMPLES)/dts/dcadec-suite/core_51_24_48_768_1.dtshd -f f32le -af aresample,aformat=channel_layouts=stereo - +fate-dca-core_51_24_48_768_1-dmix_2_matrix: REF = $(SAMPLES)/dts/dcadec-suite/core_51_24_48_768_1-dmix_2.f32 + FATE_DCADEC_LOSSY += fate-dca-x96_xxch_71_24_96_3840-dmix_2 fate-dca-x96_xxch_71_24_96_3840-dmix_2: CMD = ffmpeg -downmix stereo -flags2 skip_manual -i $(TARGET_SAMPLES)/dts/dcadec-suite/x96_xxch_71_24_96_3840.dtshd -f f32le -af aresample - # intentionally uses the dmix_6 reference because the sample does not contain stereo downmix coefficients _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
