Browse Source

input: propagate aout latency to the player

And handle video delay directly from here.
Thomas Guillem 4 years ago
committed by Alexandre Janniaux
parent
commit
a3bddd70fc
  1. 6
      modules/audio_output/coreaudio_common.c
  2. 2
      src/audio_output/aout_internal.h
  3. 14
      src/audio_output/dec.c
  4. 9
      src/input/decoder.c
  5. 2
      src/input/decoder.h
  6. 20
      src/input/es_out.c
  7. 3
      src/input/input_internal.h
  8. 20
      src/player/input.c

6
modules/audio_output/coreaudio_common.c

@ -179,7 +179,7 @@ ca_Render(audio_output_t *p_aout, uint64_t host_time,
{
/* Write silence to reach the first play date */
vlc_tick_t silence_ticks = p_sys->first_play_date - end_ticks
- GetLatency(p_aout) + bytes_ticks;
+ bytes_ticks;
if (silence_ticks > 0)
{
tocopy = TicksToBytes(p_sys, silence_ticks);
@ -219,7 +219,9 @@ ca_Render(audio_output_t *p_aout, uint64_t host_time,
{
p_sys->timing_report_last_written_bytes = 0;
vlc_tick_t pos_ticks = BytesToTicks(p_sys, p_sys->i_total_bytes);
aout_TimingReport(p_aout, end_ticks + GetLatency(p_aout), pos_ticks);
const vlc_tick_t latency_ticks = GetLatency(p_aout);
aout_LatencyReport(p_aout, latency_ticks);
aout_TimingReport(p_aout, end_ticks, pos_ticks);
}
else
p_sys->timing_report_last_written_bytes += tocopy;

2
src/audio_output/aout_internal.h

@ -139,6 +139,8 @@ struct vlc_aout_stream_cfg
struct vlc_clock_t *clock;
const char *str_id;
const audio_replay_gain_t *replay_gain;
void (*on_new_latency_cb)(vlc_tick_t tick, void *data);
void *cb_data;
};
vlc_aout_stream *vlc_aout_stream_New(audio_output_t *p_aout,

14
src/audio_output/dec.c

@ -100,6 +100,9 @@ struct vlc_aout_stream
atomic_uint buffers_lost;
atomic_uint buffers_played;
_Atomic vlc_tick_t latency;
vlc_tick_t last_latency;
void (*on_new_latency_cb)(vlc_tick_t tick, void *data);
void *cb_data;
};
static inline aout_owner_t *aout_stream_owner(vlc_aout_stream *stream)
@ -167,6 +170,7 @@ static void stream_Discontinuity(vlc_aout_stream *stream)
stream->timing.audio_ts = VLC_TICK_INVALID;
vlc_mutex_unlock(&stream->timing.lock);
stream->timing.played_samples = 0;
stream->last_latency = VLC_TICK_INVALID;
}
static void stream_Reset(vlc_aout_stream *stream)
@ -254,6 +258,9 @@ vlc_aout_stream * vlc_aout_stream_New(audio_output_t *p_aout,
return NULL;
stream->instance = aout_instance(p_aout);
stream->on_new_latency_cb = cfg->on_new_latency_cb;
stream->cb_data = cfg->cb_data;
stream->volume = NULL;
if (!owner->bitexact)
stream->volume = aout_volume_New (p_aout, cfg->replay_gain);
@ -671,6 +678,13 @@ static void stream_Synchronize(vlc_aout_stream *stream, vlc_tick_t system_now,
void vlc_aout_stream_NotifyLatency(vlc_aout_stream *stream, vlc_tick_t latency)
{
if (stream->last_latency == latency)
return;
stream->last_latency = latency;
if (stream->on_new_latency_cb != NULL)
stream->on_new_latency_cb(latency, stream->cb_data);
atomic_store_explicit(&stream->latency, latency, memory_order_relaxed);
}

9
src/input/decoder.c

@ -392,6 +392,13 @@ static bool aout_replaygain_changed( const audio_replay_gain_t *a,
return false;
}
static void
OnNewAudioLatency(vlc_tick_t latency, void *data)
{
vlc_input_decoder_t *p_owner = data;
decoder_Notify(p_owner, on_new_audio_latency, latency);
}
static int ModuleThread_UpdateAudioFormat( decoder_t *p_dec )
{
vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
@ -455,6 +462,8 @@ static int ModuleThread_UpdateAudioFormat( decoder_t *p_dec )
.clock = p_owner->p_clock,
.str_id = p_owner->psz_id,
.replay_gain = &p_dec->fmt_out.audio_replay_gain,
.on_new_latency_cb = OnNewAudioLatency,
.cb_data = p_owner,
};
p_astream = vlc_aout_stream_New( p_aout, &cfg );
if( p_astream == NULL )

2
src/input/decoder.h

@ -57,6 +57,8 @@ struct vlc_input_decoder_callbacks {
void (*on_vout_frame_displayed)(vlc_input_decoder_t *decoder,
vout_thread_t *vout, vlc_tick_t pts,
void *userdata);
void (*on_new_audio_latency)(vlc_input_decoder_t *decoder, vlc_tick_t latency,
void *userdata);
/* requests */
int (*get_attachments)(vlc_input_decoder_t *decoder,

20
src/input/es_out.c

@ -535,6 +535,25 @@ decoder_on_new_audio_stats(vlc_input_decoder_t *decoder, unsigned decoded, unsig
atomic_store_explicit(&stats->audio_latency, latency, memory_order_relaxed);
}
static void
decoder_on_new_audio_latency(vlc_input_decoder_t *decoder, vlc_tick_t latency,
void *userdata)
{
(void) decoder;
es_out_id_t *id = userdata;
es_out_t *out = id->out;
es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
if (p_sys->p_input == NULL)
return;
input_SendEvent(p_sys->p_input, &(struct vlc_input_event) {
.type = INPUT_EVENT_AOUT_LATENCY,
.latency = latency,
});
}
static int
decoder_get_attachments(vlc_input_decoder_t *decoder,
input_attachment_t ***ppp_attachment,
@ -601,6 +620,7 @@ static const struct vlc_input_decoder_callbacks decoder_cbs = {
.on_new_video_sk_stats = decoder_on_new_video_sk_stats,
.on_new_audio_stats = decoder_on_new_audio_stats,
.on_new_decoder_stats = decoder_on_new_decoder_stats,
.on_new_audio_latency = decoder_on_new_audio_latency,
.get_attachments = decoder_get_attachments,
};

3
src/input/input_internal.h

@ -153,6 +153,7 @@ typedef enum input_event_type_e
INPUT_EVENT_BUFFER_CLEARED = 0x1000,
INPUT_EVENT_VOUT_FRAME_DISPLAYED,
INPUT_EVENT_VOUT_CAPTIONS_TO_DISPLAY,
INPUT_EVENT_AOUT_LATENCY,
} input_event_type_e;
#define VLC_INPUT_CAPABILITIES_SEEKABLE (1<<0)
@ -328,6 +329,8 @@ struct vlc_input_event
float subs_fps;
/* INPUT_EVENT_THUMBNAIL_READY */
picture_t *thumbnail;
/* INPUT_EVENT_AOUT_LATENCY */
vlc_tick_t latency;
};
};

20
src/player/input.c

@ -723,6 +723,23 @@ vlc_player_input_HandleVoutEvent(struct vlc_player_input *input,
}
}
static void
vlc_player_input_HandleAoutLatency(struct vlc_player_input *input,
vlc_tick_t latency)
{
msg_Dbg(input->player, "adjusting video delay: %" PRId64, latency);
enum es_format_category_e cats[] = { VIDEO_ES, SPU_ES };
for (size_t i = 0; i < ARRAY_SIZE(cats); ++i)
{
enum es_format_category_e cat = cats[i];
vlc_tick_t delay = input->cat_delays[cat] + latency;
const input_control_param_t param = { .cat_delay = { cat, delay } };
input_ControlPush(input->thread, INPUT_CONTROL_SET_CATEGORY_DELAY, &param);
}
}
static void
input_thread_Events(input_thread_t *input_thread,
const struct vlc_input_event *event, void *user_data)
@ -908,6 +925,9 @@ input_thread_Events(input_thread_t *input_thread,
case INPUT_EVENT_VOUT_CAPTIONS_TO_DISPLAY:
vlc_player_vout_SendEvent(player, on_captions_to_display, event->captions.vout, event->captions.p_cc, event->captions.i_cc);
break;
case INPUT_EVENT_AOUT_LATENCY:
vlc_player_input_HandleAoutLatency(input, event->latency);
break;
default:
break;
}

Loading…
Cancel
Save