mirror of https://github.com/mpv-player/mpv
af_lavcac3enc: fix A/V sync
The filter can buffer singificant amounts of audio. (The proper fix is making the filter chain PTS-aware.)
This commit is contained in:
parent
74a73752c2
commit
30f5ba9422
|
@ -156,6 +156,13 @@ static void uninit(struct af_instance* af)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void update_delay(struct af_instance *af)
|
||||||
|
{
|
||||||
|
af_ac3enc_t *s = af->priv;
|
||||||
|
af->delay = ((s->pending ? s->pending->samples : 0) + s->input->samples) /
|
||||||
|
(double)s->input->rate;
|
||||||
|
}
|
||||||
|
|
||||||
static int filter_frame(struct af_instance *af, struct mp_audio *audio)
|
static int filter_frame(struct af_instance *af, struct mp_audio *audio)
|
||||||
{
|
{
|
||||||
af_ac3enc_t *s = af->priv;
|
af_ac3enc_t *s = af->priv;
|
||||||
|
@ -166,6 +173,7 @@ static int filter_frame(struct af_instance *af, struct mp_audio *audio)
|
||||||
|
|
||||||
talloc_free(s->pending);
|
talloc_free(s->pending);
|
||||||
s->pending = audio;
|
s->pending = audio;
|
||||||
|
update_delay(af);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,22 +185,27 @@ static void swap_16(uint16_t *ptr, size_t size)
|
||||||
|
|
||||||
// Copy data from input frame to encode frame (because libavcodec wants a full
|
// Copy data from input frame to encode frame (because libavcodec wants a full
|
||||||
// AC3 frame for encoding, while filter input frames can be smaller or larger).
|
// AC3 frame for encoding, while filter input frames can be smaller or larger).
|
||||||
// Return true if the
|
// Return true if the frame is complete.
|
||||||
static bool fill_buffer(af_ac3enc_t *s)
|
static bool fill_buffer(struct af_instance *af)
|
||||||
{
|
{
|
||||||
|
af_ac3enc_t *s = af->priv;
|
||||||
|
|
||||||
|
af->delay = 0;
|
||||||
|
|
||||||
if (s->pending) {
|
if (s->pending) {
|
||||||
int copy = MPMIN(s->in_samples - s->input->samples, s->pending->samples);
|
int copy = MPMIN(s->in_samples - s->input->samples, s->pending->samples);
|
||||||
s->input->samples += copy;
|
s->input->samples += copy;
|
||||||
mp_audio_copy(s->input, s->input->samples - copy, s->pending, 0, copy);
|
mp_audio_copy(s->input, s->input->samples - copy, s->pending, 0, copy);
|
||||||
mp_audio_skip_samples(s->pending, copy);
|
mp_audio_skip_samples(s->pending, copy);
|
||||||
}
|
}
|
||||||
|
update_delay(af);
|
||||||
return s->input->samples >= s->in_samples;
|
return s->input->samples >= s->in_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int filter_out(struct af_instance *af)
|
static int filter_out(struct af_instance *af)
|
||||||
{
|
{
|
||||||
af_ac3enc_t *s = af->priv;
|
af_ac3enc_t *s = af->priv;
|
||||||
if (!fill_buffer(s))
|
if (!fill_buffer(af))
|
||||||
return 0; // need more input
|
return 0; // need more input
|
||||||
|
|
||||||
AVFrame *frame = av_frame_alloc();
|
AVFrame *frame = av_frame_alloc();
|
||||||
|
@ -256,6 +269,7 @@ static int filter_out(struct af_instance *af)
|
||||||
swap_16((uint16_t *)(buf + header_len), s->pkt.size / 2);
|
swap_16((uint16_t *)(buf + header_len), s->pkt.size / 2);
|
||||||
out->samples = frame_size / out->sstride;
|
out->samples = frame_size / out->sstride;
|
||||||
af_add_output_frame(af, out);
|
af_add_output_frame(af, out);
|
||||||
|
update_delay(af);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue