Browse Source

demux: xiph: use common replay gain parser

pull/177/head
Robert Stone 1 year ago
committed by Steve Lhomme
parent
commit
f1d0f4e2ad
  1. 64
      modules/codec/vorbis.c
  2. 5
      modules/demux/flac.c
  3. 45
      modules/demux/ogg.c
  4. 25
      modules/demux/xiph_metadata.c
  5. 4
      modules/demux/xiph_metadata.h

64
modules/codec/vorbis.c

@ -38,6 +38,7 @@
#include <vlc_aout.h>
#include <vlc_input_item.h>
#include <vlc_sout.h>
#include <vlc_replay_gain.h>
#include "../demux/xiph.h"
#include <ogg/ogg.h>
@ -405,6 +406,36 @@ static int ProcessHeaders( decoder_t *p_dec )
}
ParseVorbisComments( p_dec );
int i_ret = vlc_replay_gain_CopyFromMeta( &p_dec->fmt_out.audio_replay_gain, p_dec->p_description );
/* use replay gain if available; otherwise see vorbisgain(1) */
if( i_ret != VLC_SUCCESS && p_dec->p_description != NULL )
{
audio_replay_gain_t *p_arg = &p_dec->fmt_out.audio_replay_gain;
replay_gain_Reset( p_arg );
const char *track_gain = vlc_meta_GetExtra( p_dec->p_description, "RG_RADIO" );
if( track_gain )
{
p_arg->pb_gain[AUDIO_REPLAY_GAIN_TRACK] = true;
p_arg->pf_gain[AUDIO_REPLAY_GAIN_TRACK] = vlc_strtof_c( track_gain, NULL );
}
const char *track_peak = vlc_meta_GetExtra( p_dec->p_description, "RG_PEAK" );
if( track_peak )
{
p_arg->pb_peak[AUDIO_REPLAY_GAIN_TRACK] = true;
p_arg->pf_peak[AUDIO_REPLAY_GAIN_TRACK] = vlc_strtof_c( track_peak, NULL );
}
const char *album_gain = vlc_meta_GetExtra( p_dec->p_description, "RG_AUDIOPHILE" );
if( album_gain )
{
p_arg->pb_gain[AUDIO_REPLAY_GAIN_ALBUM] = true;
p_arg->pf_gain[AUDIO_REPLAY_GAIN_ALBUM] = vlc_strtof_c( album_gain, NULL );
}
}
/* The next packet in order is the codebooks header
* We need to watch out that this packet is not missing as a
* missing or corrupted header is fatal. */
@ -620,38 +651,7 @@ static void ParseVorbisComments( decoder_t *p_dec )
*psz_value = '\0';
psz_value++;
if( !strcasecmp( psz_name, "REPLAYGAIN_TRACK_GAIN" ) ||
!strcasecmp( psz_name, "RG_RADIO" ) )
{
audio_replay_gain_t *r = &p_dec->fmt_out.audio_replay_gain;
r->pb_gain[AUDIO_REPLAY_GAIN_TRACK] = true;
r->pf_gain[AUDIO_REPLAY_GAIN_TRACK] = vlc_atof_c( psz_value );
}
else if( !strcasecmp( psz_name, "REPLAYGAIN_TRACK_PEAK" ) ||
!strcasecmp( psz_name, "RG_PEAK" ) )
{
audio_replay_gain_t *r = &p_dec->fmt_out.audio_replay_gain;
r->pb_peak[AUDIO_REPLAY_GAIN_TRACK] = true;
r->pf_peak[AUDIO_REPLAY_GAIN_TRACK] = vlc_atof_c( psz_value );
}
else if( !strcasecmp( psz_name, "REPLAYGAIN_ALBUM_GAIN" ) ||
!strcasecmp( psz_name, "RG_AUDIOPHILE" ) )
{
audio_replay_gain_t *r = &p_dec->fmt_out.audio_replay_gain;
r->pb_gain[AUDIO_REPLAY_GAIN_ALBUM] = true;
r->pf_gain[AUDIO_REPLAY_GAIN_ALBUM] = vlc_atof_c( psz_value );
}
else if( !strcasecmp( psz_name, "REPLAYGAIN_ALBUM_PEAK" ) )
{
audio_replay_gain_t *r = &p_dec->fmt_out.audio_replay_gain;
r->pb_peak[AUDIO_REPLAY_GAIN_ALBUM] = true;
r->pf_peak[AUDIO_REPLAY_GAIN_ALBUM] = vlc_atof_c( psz_value );
}
else if( !strcasecmp( psz_name, "METADATA_BLOCK_PICTURE" ) )
if( !strcasecmp( psz_name, "METADATA_BLOCK_PICTURE" ) )
{ /* Do nothing, for now */ }
else
{

5
modules/demux/flac.c

@ -36,6 +36,7 @@
#include <vlc_input.h> /* vlc_input_attachment, vlc_seekpoint */
#include <vlc_codec.h> /* decoder_t */
#include <vlc_charset.h> /* EnsureUTF8 */
#include <vlc_replay_gain.h>
#include <assert.h>
#include <limits.h>
@ -744,6 +745,8 @@ static int ParseHeaders( demux_t *p_demux, es_format_t *p_fmt )
i_peek = vlc_stream_Peek( p_demux->s, &p_peek, 4+i_len );
if( i_peek == 4+i_len )
ParseComment( p_demux, p_peek, i_peek );
vlc_replay_gain_CopyFromMeta( &p_fmt->audio_replay_gain, p_sys->p_meta );
}
else if( i_type == META_PICTURE )
{
@ -818,7 +821,7 @@ static void ParseComment( demux_t *p_demux, const uint8_t *p_data, size_t i_data
vorbis_ParseComment( NULL, &p_sys->p_meta, &p_data[4], i_data - 4,
&p_sys->i_attachments, &p_sys->attachments,
&p_sys->i_cover_score, &p_sys->i_cover_idx,
&p_sys->i_title_seekpoints, &p_sys->pp_title_seekpoints, NULL, NULL );
&p_sys->i_title_seekpoints, &p_sys->pp_title_seekpoints );
}
static void ParsePicture( demux_t *p_demux, const uint8_t *p_data, size_t i_data )

45
modules/demux/ogg.c

@ -39,6 +39,7 @@
#include <vlc_demux.h>
#include <vlc_meta.h>
#include <vlc_input.h>
#include <vlc_replay_gain.h>
#include <ogg/ogg.h>
@ -2569,18 +2570,12 @@ static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
demux_sys_t *p_ogg = p_demux->p_sys;
int i_cover_score = 0;
int i_cover_idx = 0;
float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
{
pf_replay_gain[i] = 0;
pf_replay_peak[i] = 0;
}
vorbis_ParseComment( p_fmt, &p_ogg->p_meta, p_headers, i_headers,
&p_ogg->i_attachments, &p_ogg->attachments,
&i_cover_score, &i_cover_idx,
&p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
&pf_replay_gain, &pf_replay_peak );
&p_ogg->i_seekpoints, &p_ogg->pp_seekpoints );
if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
{
char psz_url[128];
@ -2589,19 +2584,33 @@ static void Ogg_ExtractComments( demux_t *p_demux, es_format_t *p_fmt,
vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
}
for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
int i_ret = vlc_replay_gain_CopyFromMeta( &p_fmt->audio_replay_gain, p_ogg->p_meta );
/* use replay gain if available; otherwise use IETF RFC7845 §5.2.1 */
if( i_ret != VLC_SUCCESS && p_ogg->p_meta != NULL )
{
if ( pf_replay_gain[i] != 0 )
audio_replay_gain_t *p_arg = &p_fmt->audio_replay_gain;
replay_gain_Reset( p_arg );
const char *track_gain = vlc_meta_GetExtra( p_ogg->p_meta, "R128_TRACK_GAIN" );
if( track_gain )
{
p_fmt->audio_replay_gain.pb_gain[i] = true;
p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
p_arg->pb_gain[AUDIO_REPLAY_GAIN_TRACK] = true;
p_arg->pf_gain[AUDIO_REPLAY_GAIN_TRACK] = vlc_strtof_c( track_gain, NULL ) / 256.f;
}
if ( pf_replay_peak[i] != 0 )
const char *album_gain = vlc_meta_GetExtra( p_ogg->p_meta, "R128_ALBUM_GAIN" );
if( album_gain )
{
p_arg->pb_gain[AUDIO_REPLAY_GAIN_ALBUM] = true;
p_arg->pf_gain[AUDIO_REPLAY_GAIN_ALBUM] = vlc_strtof_c( album_gain, NULL ) / 256.f;
}
if( track_gain || album_gain )
{
p_fmt->audio_replay_gain.pb_peak[i] = true;
p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
/* EBU R128 uses -23 LUFS as the reference level */
p_arg->pb_reference_loudness = true;
p_arg->pf_reference_loudness = -23.f;
}
}

25
modules/demux/xiph_metadata.c

@ -327,9 +327,7 @@ void vorbis_ParseComment( es_format_t *p_fmt, vlc_meta_t **pp_meta,
const uint8_t *p_data, size_t i_data,
int *i_attachments, input_attachment_t ***attachments,
int *i_cover_score, int *i_cover_idx,
int *i_seekpoint, seekpoint_t ***ppp_seekpoint,
float (* ppf_replay_gain)[AUDIO_REPLAY_GAIN_MAX],
float (* ppf_replay_peak)[AUDIO_REPLAY_GAIN_MAX] )
int *i_seekpoint, seekpoint_t ***ppp_seekpoint )
{
if( i_data < 8 )
return;
@ -465,27 +463,6 @@ void vorbis_ParseComment( es_format_t *p_fmt, vlc_meta_t **pp_meta,
*i_attachments, *attachments, p_attachment );
}
}
else if ( ppf_replay_gain && ppf_replay_peak && !strncmp(psz_comment, "REPLAYGAIN_", 11) )
{
char *p = strchr( psz_comment, '=' );
if (!p) goto next_comment;
if ( !strncasecmp(psz_comment, "REPLAYGAIN_TRACK_GAIN=", 22) )
{
(*ppf_replay_gain)[AUDIO_REPLAY_GAIN_TRACK] = vlc_atof_c( ++p );
}
else if ( !strncasecmp(psz_comment, "REPLAYGAIN_ALBUM_GAIN=", 22) )
{
(*ppf_replay_gain)[AUDIO_REPLAY_GAIN_ALBUM] = vlc_atof_c( ++p );
}
else if ( !strncasecmp(psz_comment, "REPLAYGAIN_ALBUM_PEAK=", 22) )
{
(*ppf_replay_peak)[AUDIO_REPLAY_GAIN_ALBUM] = vlc_atof_c( ++p );
}
else if ( !strncasecmp(psz_comment, "REPLAYGAIN_TRACK_PEAK=", 22) )
{
(*ppf_replay_peak)[AUDIO_REPLAY_GAIN_TRACK] = vlc_atof_c( ++p );
}
}
else if( !strncasecmp(psz_comment, "CHAPTER", 7) )
{
unsigned int i_chapt;

4
modules/demux/xiph_metadata.h

@ -35,9 +35,7 @@ void vorbis_ParseComment( es_format_t *p_fmt, vlc_meta_t **pp_meta,
const uint8_t *p_data, size_t i_data,
int *i_attachments, input_attachment_t ***attachments,
int *i_cover_score, int *i_cover_idx,
int *i_seekpoint, seekpoint_t ***ppp_seekpoint,
float (* ppf_replay_gain)[AUDIO_REPLAY_GAIN_MAX],
float (* ppf_replay_peak)[AUDIO_REPLAY_GAIN_MAX] );
int *i_seekpoint, seekpoint_t ***ppp_seekpoint );
static const struct {
const char *psz_tag;

Loading…
Cancel
Save