riff-media: fix MS and DVI ADPCM av_bps calculations

Align the calculations for the number of samples per block with the
calculations in adpcmdec.

For MS ADPCM we have in adpcmdec:

       samples = (blocksize - 7 * dec->channels) * 2 + 2 * dec->channels;
       outsize = 2 * samples;
       outbuf = gst_buffer_new_and_alloc (outsize);

This gives us the total output byte size in 16 bits samples. To get back
to the samples, dividing by the channels and 2, we get the right samples per
block as:

       int spb = ((strf->blockalign / strf->channels) - 7) * 2 + 2;

Which we can then use to calculate the bitrate in riff-media.

A similar calculation for DVI ADPCM is needed to get the right bitrate
in all cases.

Tested with the sample in https://bugzilla.gnome.org/show_bug.cgi?id=636245
and another (failing before this patch) sample.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9082>
This commit is contained in:
Wim Taymans 2025-05-26 19:00:36 +02:00
parent 581e72a23e
commit 4417183bae

View File

@ -1342,8 +1342,9 @@ gst_riff_create_audio_caps (guint16 codec_id,
* so either we calculate the bitrate or mark it as invalid as this
* would probably confuse timing */
strf->av_bps = 0;
if (strf->channels != 0 && strf->rate != 0 && strf->blockalign != 0) {
int spb = ((strf->blockalign - strf->channels * 7) / 2) * 2;
if (strf->channels != 0 && strf->rate != 0 && strf->blockalign != 0 &&
(strf->blockalign / strf->channels) >= 7) {
int spb = ((strf->blockalign / strf->channels) - 7) * 2 + 2;
strf->av_bps =
gst_util_uint64_scale_int (strf->rate, strf->blockalign, spb);
GST_DEBUG ("fixing av_bps to calculated value %d of MS ADPCM",
@ -1464,8 +1465,9 @@ gst_riff_create_audio_caps (guint16 codec_id,
* header, so either we calculate the bitrate or mark it as invalid
* as this would probably confuse timing */
strf->av_bps = 0;
if (strf->channels != 0 && strf->rate != 0 && strf->blockalign != 0) {
int spb = ((strf->blockalign - strf->channels * 4) / 2) * 2;
if (strf->channels != 0 && strf->rate != 0 && strf->blockalign != 0 &&
(strf->blockalign / strf->channels) >= 4) {
int spb = ((strf->blockalign / strf->channels) - 4) * 2 + 1;
strf->av_bps =
gst_util_uint64_scale_int (strf->rate, strf->blockalign, spb);
GST_DEBUG ("fixing av_bps to calculated value %d of IMA DVI ADPCM",