[MPlayer-cvslog] r37934 - in trunk/libmpdemux: demux_audio.c demux_lavf.c demuxer.h

ib subversion at mplayerhq.hu
Wed Apr 26 14:59:24 EEST 2017


Author: ib
Date: Wed Apr 26 14:59:24 2017
New Revision: 37934

Log:
Add a DEMUXER_CTRL to get the ReplayGain.

For -demuxer lavf retrieve the information from the stream's side data,
otherwise determine it by directly analyzing the stream's Lame header.

Return 10x the adjustment (as stored in the Lame header).

Modified:
   trunk/libmpdemux/demux_audio.c
   trunk/libmpdemux/demux_lavf.c
   trunk/libmpdemux/demuxer.h

Modified: trunk/libmpdemux/demux_audio.c
==============================================================================
--- trunk/libmpdemux/demux_audio.c	Thu Apr 20 23:59:57 2017	(r37933)
+++ trunk/libmpdemux/demux_audio.c	Wed Apr 26 14:59:24 2017	(r37934)
@@ -45,6 +45,7 @@
 typedef struct da_priv {
   int frmt;
   double next_pts;
+  int r_gain;
 } da_priv_t;
 
 //! rather arbitrary value for maximum length of wav-format headers
@@ -285,7 +286,7 @@ static void skip_flac_metadata(demuxer_t
  *
  * @return 0 (error or no variable bitrate mode) or number of frames
  */
-static unsigned int mp3_vbr_frames(stream_t *s, off_t off) {
+static unsigned int mp3_vbr_frames(stream_t *s, off_t off, da_priv_t *priv) {
   static const int xing_offset[2][2] = {{32, 17}, {17, 9}};
   unsigned int data;
   unsigned char hdr[4];
@@ -317,7 +318,25 @@ static unsigned int mp3_vbr_frames(strea
       data = stream_read_dword(s);
 
       if (data & 0x1)                   // frames field is present
-        return stream_read_dword(s);    // frames
+        data = stream_read_dword(s);    // frames
+
+      if (stream_skip(s, 108)) {
+        unsigned int dword = stream_read_dword(s);
+
+        if (dword == MKBETAG('L','A','M','E') && stream_skip(s, 11)) {
+          uint16_t word = stream_read_word(s);
+
+          /* Radio ReplayGain */
+          if ((word >> 13) == 1) {
+            priv->r_gain = word & 0x1ff;
+
+            if ((word >> 9) & 1)
+              priv->r_gain = -priv->r_gain;
+          }
+        }
+      }
+
+      return data;
     }
 
     /* VBRI (at fixed position: 32 bytes after header) */
@@ -436,6 +455,9 @@ static int demux_audio_open(demuxer_t* d
 
   sh_audio = new_sh_audio(demuxer,0, NULL);
 
+  priv = malloc(sizeof(da_priv_t));
+  priv->r_gain = INT32_MIN;
+
   switch(frmt) {
   case MP3:
     sh_audio->format = (mp3_found->mpa_layer < 3 ? 0x50 : 0x55);
@@ -453,7 +475,7 @@ static int demux_audio_open(demuxer_t* d
     sh_audio->wf->nBlockAlign = mp3_found->mpa_spf;
     sh_audio->wf->wBitsPerSample = 16;
     sh_audio->wf->cbSize = 0;
-    duration = (double) mp3_vbr_frames(s, demuxer->movi_start) * mp3_found->mpa_spf / mp3_found->mp3_freq;
+    duration = (double) mp3_vbr_frames(s, demuxer->movi_start, priv) * mp3_found->mpa_spf / mp3_found->mp3_freq;
     free(mp3_found);
     mp3_found = NULL;
     if(demuxer->movi_end && (s->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK) {
@@ -645,7 +667,6 @@ static int demux_audio_open(demuxer_t* d
 	    } break;
   }
 
-  priv = malloc(sizeof(da_priv_t));
   priv->frmt = frmt;
   priv->next_pts = 0;
   demuxer->priv = priv;
@@ -836,6 +857,11 @@ static int demux_audio_control(demuxer_t
     	    *((int *)arg)=(int)( (priv->next_pts*100)  / audio_length);
 	    return DEMUXER_CTRL_OK;
 
+	case DEMUXER_CTRL_GET_REPLAY_GAIN:
+	    if (priv->r_gain == INT32_MIN) return DEMUXER_CTRL_DONTKNOW;
+	    *((int *)arg) = priv->r_gain;
+	    return DEMUXER_CTRL_OK;
+
 	default:
 	    return DEMUXER_CTRL_NOTIMPL;
     }

Modified: trunk/libmpdemux/demux_lavf.c
==============================================================================
--- trunk/libmpdemux/demux_lavf.c	Thu Apr 20 23:59:57 2017	(r37933)
+++ trunk/libmpdemux/demux_lavf.c	Wed Apr 26 14:59:24 2017	(r37934)
@@ -42,6 +42,7 @@
 #include "libavutil/avstring.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
+#include "libavutil/replaygain.h"
 
 #include "mp_taglists.h"
 
@@ -80,6 +81,7 @@ typedef struct lavf_priv {
     int cur_program;
     int nb_streams_last;
     int use_lavf_netstream;
+    int r_gain;
 }lavf_priv_t;
 
 static int mp_read(void *opaque, uint8_t *buf, int size) {
@@ -155,8 +157,10 @@ static int lavf_check_file(demuxer_t *de
     int read_size = INITIAL_PROBE_SIZE;
     int score;
 
-    if(!demuxer->priv)
+    if(!demuxer->priv) {
         demuxer->priv=calloc(sizeof(lavf_priv_t),1);
+        ((lavf_priv_t *)demuxer->priv)->r_gain = INT32_MIN;
+    }
     priv= demuxer->priv;
 
     init_avformat();
@@ -358,6 +362,14 @@ static void handle_stream(demuxer_t *dem
             }
             if (demuxer->audio->id != i)
                 st->discard= AVDISCARD_ALL;
+            if (priv->audio_streams == 0) {
+                int rg_size;
+                AVReplayGain *rg = (AVReplayGain*)av_stream_get_side_data(st, AV_PKT_DATA_REPLAYGAIN, &rg_size);
+                if (rg && rg_size >= sizeof(*rg)) {
+                    priv->r_gain = rg->track_gain / 10000;
+                }
+            } else
+                priv->r_gain = INT32_MIN;
             stream_id = priv->audio_streams++;
             break;
         }
@@ -903,6 +915,11 @@ redo:
             priv->cur_program = prog->progid = program->id;
             return DEMUXER_CTRL_OK;
         }
+        case DEMUXER_CTRL_GET_REPLAY_GAIN:
+            if (priv->r_gain == INT32_MIN)
+                return DEMUXER_CTRL_DONTKNOW;
+            *((int *)arg) = priv->r_gain;
+            return DEMUXER_CTRL_OK;
 	default:
 	    return DEMUXER_CTRL_NOTIMPL;
     }

Modified: trunk/libmpdemux/demuxer.h
==============================================================================
--- trunk/libmpdemux/demuxer.h	Thu Apr 20 23:59:57 2017	(r37933)
+++ trunk/libmpdemux/demuxer.h	Wed Apr 26 14:59:24 2017	(r37934)
@@ -110,6 +110,7 @@
 #define DEMUXER_CTRL_SWITCH_VIDEO 14
 #define DEMUXER_CTRL_IDENTIFY_PROGRAM 15
 #define DEMUXER_CTRL_CORRECT_PTS 16
+#define DEMUXER_CTRL_GET_REPLAY_GAIN 17    // returns 10x the adjustment
 
 #define SEEK_ABSOLUTE (1 << 0)
 #define SEEK_FACTOR   (1 << 1)


More information about the MPlayer-cvslog mailing list