From 6f9006c9b9753f47733ea17f803a63ea5a1500ef Mon Sep 17 00:00:00 2001 From: Julien Moutte Date: Tue, 7 May 2013 15:00:05 +0200 Subject: [PATCH] riff: Manually calculate bitrate of ADPCM streams Some ADPCM encoding tools like Oxelon generate WAV files with wrong format header declaring an invalid bitrate. As wavparse uses the average bitrate to calculate timestamps and duration the decoder can be confused by receiving timestamps completely out of sync with the decoded samples. ADPCM is a CBR audio codec so we can calculate the average bitrate instead of trusting the format header. https://bugzilla.gnome.org/show_bug.cgi?id=636245 --- gst-libs/gst/riff/riff-media.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/riff/riff-media.c b/gst-libs/gst/riff/riff-media.c index 008727fc3c..2a0d6ed83b 100644 --- a/gst-libs/gst/riff/riff-media.c +++ b/gst-libs/gst/riff/riff-media.c @@ -1217,6 +1217,19 @@ gst_riff_create_audio_caps (guint16 codec_id, break; case GST_RIFF_WAVE_FORMAT_ADPCM: + if (strf != NULL) { + /* Many encoding tools create a wrong bitrate information in the 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 * 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", + strf->av_bps); + } + } caps = gst_caps_new_simple ("audio/x-adpcm", "layout", G_TYPE_STRING, "microsoft", NULL); if (codec_name) @@ -1325,7 +1338,19 @@ gst_riff_create_audio_caps (guint16 codec_id, goto unknown; case GST_RIFF_WAVE_FORMAT_DVI_ADPCM: - rate_max = 48000; + if (strf != NULL) { + /* Many encoding tools create a wrong bitrate information in the + * 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; + 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", + strf->av_bps); + } + } caps = gst_caps_new_simple ("audio/x-adpcm", "layout", G_TYPE_STRING, "dvi", NULL); if (codec_name)