summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Moutte <julien@moutte.net>2013-05-07 15:00:05 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2013-05-07 15:02:19 +0200
commit5ae7d8b47cbf9c6e93e613fea54f6d7313057339 (patch)
treefca37740fe612f0e63c13cc4f95381c2969611fa
parent1ee667a266ad8c00e302c8444d074ebcde1622ba (diff)
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
-rw-r--r--gst-libs/gst/riff/riff-media.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/gst-libs/gst/riff/riff-media.c b/gst-libs/gst/riff/riff-media.c
index 94101ab54..d0054d95c 100644
--- a/gst-libs/gst/riff/riff-media.c
+++ b/gst-libs/gst/riff/riff-media.c
@@ -1212,6 +1212,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)
@@ -1320,7 +1333,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)