From c046c7392fe5e0c8fac0f605631aa4ef491f2a5a Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Mon, 8 Oct 2007 18:30:11 +0000 Subject: [PATCH] Es out now takes care of settings the audio replay gain from meta data if the demuxer has not set them. Added a demux2 control DEMUX_HAS_UNSUPPORTED_META. A demuxer should return true only when the format support extra meta data (id3/ap2/...) but it does not read them itself. The input will then call a "meta reader" (demuxer modifications on the way). --- include/vlc_demux.h | 1 + src/input/demux.c | 1 + src/input/es_out.c | 23 ++++++++++++++ src/input/input.c | 76 ++++++++++++++++++++++++++++++++++++++------- 4 files changed, 90 insertions(+), 11 deletions(-) diff --git a/include/vlc_demux.h b/include/vlc_demux.h index 4d9b57980f..b098fc36a8 100644 --- a/include/vlc_demux.h +++ b/include/vlc_demux.h @@ -118,6 +118,7 @@ enum demux_query_e /* Meta data */ DEMUX_GET_META, /* arg1= vlc_meta_t ** res=can fail */ + DEMUX_HAS_UNSUPPORTED_META, /* arg1= vlc_bool_t * res can fail */ /* Attachments */ DEMUX_GET_ATTACHMENTS, /* arg1=input_attachment_t***, int* res=can fail */ diff --git a/src/input/demux.c b/src/input/demux.c index 50613df838..1c168eb5fa 100644 --- a/src/input/demux.c +++ b/src/input/demux.c @@ -267,6 +267,7 @@ int demux2_vaControlHelper( stream_t *s, case DEMUX_GET_FPS: case DEMUX_GET_META: + case DEMUX_HAS_UNSUPPORTED_META: case DEMUX_SET_NEXT_DEMUX_TIME: case DEMUX_GET_TITLE_INFO: case DEMUX_SET_GROUP: diff --git a/src/input/es_out.c b/src/input/es_out.c index 94382ffd9f..ecf7d8963e 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -886,8 +886,31 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt ) switch( fmt->i_cat ) { case AUDIO_ES: + { + audio_replay_gain_t rg; + es->i_channel = p_sys->i_audio; + + vlc_mutex_lock( &p_input->p->input.p_item->lock ); + memset( &rg, 0, sizeof(rg) ); + vlc_audio_replay_gain_MergeFromMeta( &rg, p_input->p->input.p_item->p_meta ); + vlc_mutex_unlock( &p_input->p->input.p_item->lock ); + + for( i = 0; i < AUDIO_REPLAY_GAIN_MAX; i++ ) + { + if( !es->fmt.audio_replay_gain.pb_peak[i] ) + { + es->fmt.audio_replay_gain.pb_peak[i] = rg.pb_peak[i]; + es->fmt.audio_replay_gain.pf_peak[i] = rg.pf_peak[i]; + } + if( !es->fmt.audio_replay_gain.pb_gain[i] ) + { + es->fmt.audio_replay_gain.pb_gain[i] = rg.pb_gain[i]; + es->fmt.audio_replay_gain.pf_gain[i] = rg.pf_gain[i]; + } + } break; + } case VIDEO_ES: es->i_channel = p_sys->i_video; diff --git a/src/input/input.c b/src/input/input.c index 0dc6b14e99..139f82734f 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -75,7 +75,6 @@ static int InputSourceInit( input_thread_t *, input_source_t *, static void InputSourceClean( input_source_t * ); /* TODO */ //static void InputGetAttachments( input_thread_t *, input_source_t * ); - static void SlaveDemux( input_thread_t *p_input ); static void SlaveSeek( input_thread_t *p_input ); @@ -85,6 +84,10 @@ static void InputUpdateMeta( input_thread_t *p_input, vlc_meta_t *p_meta ); static sout_instance_t *SoutFind( vlc_object_t *p_parent, input_item_t *p_item, vlc_bool_t * ); static void SoutKeep( sout_instance_t * ); +static void DemuxMeta( input_thread_t *p_input, vlc_meta_t *p_meta, demux_t *p_demux ); +static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_attachment, + int i_new, input_attachment_t **pp_new ); + /***************************************************************************** * This function creates a new input, and returns a pointer * to its description. On error, it returns NULL. @@ -1163,7 +1166,7 @@ static int Init( input_thread_t * p_input ) InputMetaUser( p_input, p_meta ); /* Get meta data from master input */ - demux2_Control( p_input->p->input.p_demux, DEMUX_GET_META, p_meta ); + DemuxMeta( p_input, p_meta, p_input->p->input.p_demux ); /* Access_file does not give any meta, and there are no slave */ if( !p_input->b_preparsing ) @@ -1175,8 +1178,7 @@ static int Init( input_thread_t * p_input ) /* Get meta data from slave input */ for( i = 0; i < p_input->p->i_slave; i++ ) { - demux2_Control( p_input->p->slave[i]->p_demux, - DEMUX_GET_META, p_meta ); + DemuxMeta( p_input, p_meta, p_input->p->slave[i]->p_demux ); if( p_input->p->slave[i]->p_access ) { access2_Control( p_input->p->slave[i]->p_access, @@ -2357,14 +2359,9 @@ static int InputSourceInit( input_thread_t *p_input, if( !demux2_Control( in->p_demux, DEMUX_GET_ATTACHMENTS, &attachment, &i_attachment ) ) { - int i; vlc_mutex_lock( &p_input->p->input.p_item->lock ); - p_input->p->attachment = realloc( p_input->p->attachment, - sizeof(input_attachment_t**) * ( p_input->p->i_attachment + i_attachment ) ); - for( i = 0; i < i_attachment; i++ ) - p_input->p->attachment[p_input->p->i_attachment++] = attachment[i]; - if( attachment ) - free( attachment ); + AppendAttachment( &p_input->p->i_attachment, &p_input->p->attachment, + i_attachment, attachment ); vlc_mutex_unlock( &p_input->p->input.p_item->lock ); } } @@ -2629,6 +2626,63 @@ static inline vlc_bool_t IsValidAccess( const char *psz ) return VLC_FALSE; } +static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_attachment, + int i_new, input_attachment_t **pp_new ) +{ + int i_attachment = *pi_attachment; + input_attachment_t **attachment = *ppp_attachment; + int i; + + attachment = realloc( attachment, + sizeof(input_attachment_t**) * ( i_attachment + i_new ) ); + for( i = 0; i < i_new; i++ ) + attachment[i_attachment++] = pp_new[i]; + if( pp_new ) + free( pp_new ); + + /* */ + *pi_attachment = i_attachment; + *ppp_attachment = attachment; +} + +static void DemuxMeta( input_thread_t *p_input, vlc_meta_t *p_meta, demux_t *p_demux ) +{ + vlc_bool_t b_bool; + module_t *p_id3; + + demux2_Control( p_demux, DEMUX_GET_META, p_meta ); + if( demux2_Control( p_demux, DEMUX_HAS_UNSUPPORTED_META, &b_bool ) ) + return; + if( !b_bool ) + return; + + p_demux->p_private = malloc( sizeof( demux_meta_t ) ); + if(! p_demux->p_private ) + return; + + p_id3 = module_Need( p_demux, "meta reader", NULL, 0 ); + if( p_id3 ) + { + demux_meta_t *p_demux_meta = (demux_meta_t *)p_demux->p_private; + + if( p_demux_meta->p_meta ) + { + vlc_meta_Merge( p_meta, p_demux_meta->p_meta ); + vlc_meta_Delete( p_demux_meta->p_meta ); + } + + if( p_demux_meta->i_attachments > 0 ) + { + vlc_mutex_lock( &p_input->p->input.p_item->lock ); + AppendAttachment( &p_input->p->i_attachment, &p_input->p->attachment, + p_demux_meta->i_attachments, p_demux_meta->attachments ); + vlc_mutex_unlock( &p_input->p->input.p_item->lock ); + } + module_Unneed( p_demux, p_id3 ); + } + free( p_demux->p_private ); +} + /***************************************************************************** * MRLSplit: parse the access, demux and url part of the -- 2.39.2