---
 libavformat/mp3dec.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index 1ab5159..e33f524 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -132,7 +132,17 @@ static void read_xing_toc(AVFormatContext *s, int64_t 
filesize, int64_t duration
 static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st,
                                MPADecodeHeader *c, uint32_t spf)
 {
+#define LAST_BITS(k, n) ((k) & ((1 << (n)) - 1))
+#define MIDDLE_BITS(k, m, n) LAST_BITS((k) >> (m), ((n) - (m)))
+
+    float f;
     uint32_t v;
+
+    char version[10];
+
+    uint32_t peak   = 0;
+    int32_t  r_gain = INT32_MIN, a_gain = INT32_MIN;
+
     MP3DecContext *mp3 = s->priv_data;
     const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
 
@@ -152,6 +162,53 @@ static void mp3_parse_info_tag(AVFormatContext *s, 
AVStream *st,
                                        (AVRational){spf, c->sample_rate},
                                        st->time_base));
     }
+
+    avio_skip(s->pb, 3);
+
+    /* VBR quality */
+    avio_r8(s->pb);
+
+    /* Encoder short version string */
+    avio_get_str(s->pb, 9, version, 10);
+
+    /* Info Tag revision + VBR method */
+    avio_r8(s->pb);
+
+    /* Lowpass filter value */
+    avio_r8(s->pb);
+
+    /* ReplayGain peak */
+    v = avio_rb32(s->pb);
+    f = (v << 5) / (float) (1 << 28);
+
+    if (f > 0)
+        peak = f * 100000;
+
+    v = avio_rb16(s->pb);
+
+    /* Radio ReplayGain */
+    if (MIDDLE_BITS(v, 13, 15) == 1) {
+        f = MIDDLE_BITS(v, 0, 8) / 10.f;
+
+        if (v & (1 << 9))
+            r_gain = f * -100000;
+        else
+            r_gain = f *  100000;
+    }
+
+    v = avio_rb16(s->pb);
+
+    /* Audiophile ReplayGain */
+    if (MIDDLE_BITS(v, 13, 15) == 2) {
+        f = MIDDLE_BITS(v, 0, 8) / 10.f;
+
+        if (v & (1 << 9))
+            a_gain = f * -100000;
+        else
+            a_gain = f *  100000;
+    }
+
+    ff_replaygain_export_raw(st, r_gain, peak, a_gain, 0);
 }
 
 static void mp3_parse_vbri_tag(AVFormatContext *s, AVStream *st, int64_t base)
-- 
1.9.1

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to